mirror of
https://github.com/mozilla/gecko-dev.git
synced 2025-05-13 17:07:01 +00:00
More support for column sorting.
This commit is contained in:
parent
3dbf66b81d
commit
a23baf95a7
@ -20,6 +20,37 @@
|
||||
This file provides the implementation for the sort service manager.
|
||||
*/
|
||||
|
||||
#include "nsCOMPtr.h"
|
||||
#include "nsCRT.h"
|
||||
#include "nsIAtom.h"
|
||||
#include "nsIContent.h"
|
||||
#include "nsIDOMElement.h"
|
||||
#include "nsIDOMElementObserver.h"
|
||||
#include "nsIDOMNode.h"
|
||||
#include "nsIDOMNodeObserver.h"
|
||||
#include "nsIDocument.h"
|
||||
#include "nsINameSpaceManager.h"
|
||||
#include "nsIRDFContentModelBuilder.h"
|
||||
#include "nsIRDFCursor.h"
|
||||
#include "nsIRDFCompositeDataSource.h"
|
||||
#include "nsIRDFDocument.h"
|
||||
#include "nsIRDFNode.h"
|
||||
#include "nsIRDFObserver.h"
|
||||
#include "nsIRDFService.h"
|
||||
#include "nsIServiceManager.h"
|
||||
#include "nsINameSpaceManager.h"
|
||||
#include "nsIServiceManager.h"
|
||||
#include "nsISupportsArray.h"
|
||||
#include "nsIURL.h"
|
||||
#include "nsLayoutCID.h"
|
||||
#include "nsRDFCID.h"
|
||||
#include "nsRDFContentUtils.h"
|
||||
#include "nsString.h"
|
||||
#include "rdf.h"
|
||||
#include "rdfutil.h"
|
||||
|
||||
#include "nsVoidArray.h"
|
||||
#include "rdf_qsort.h"
|
||||
#include "nsIAtom.h"
|
||||
#include "nsIXULSortService.h"
|
||||
#include "nsString.h"
|
||||
@ -42,8 +73,11 @@
|
||||
|
||||
#include "nsIDOMNode.h"
|
||||
#include "nsIDOMElement.h"
|
||||
#include "nsIRDFContentModelBuilder.h"
|
||||
|
||||
#include "nsIRDFContentModelBuilder.h"
|
||||
#include "nsIRDFCompositeDataSource.h"
|
||||
#include "nsIRDFNode.h"
|
||||
#include "nsIRDFService.h"
|
||||
#include "rdf.h"
|
||||
|
||||
|
||||
@ -62,6 +96,11 @@ static NS_DEFINE_IID(kITextContentIID, NS_ITEXT_CONTENT_IID);
|
||||
static NS_DEFINE_IID(kIDomNodeIID, NS_IDOMNODE_IID);
|
||||
static NS_DEFINE_IID(kIDomElementIID, NS_IDOMELEMENT_IID);
|
||||
|
||||
static NS_DEFINE_CID(kRDFServiceCID, NS_RDFSERVICE_CID);
|
||||
static NS_DEFINE_IID(kIRDFServiceIID, NS_IRDFSERVICE_IID);
|
||||
static NS_DEFINE_IID(kIRDFResourceIID, NS_IRDFRESOURCE_IID);
|
||||
static NS_DEFINE_IID(kIRDFLiteralIID, NS_IRDFLITERAL_IID);
|
||||
|
||||
// XXX This is sure to change. Copied from mozilla/layout/xul/content/src/nsXULAtoms.cpp
|
||||
static const char kXULNameSpaceURI[]
|
||||
= "http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul";
|
||||
@ -91,16 +130,25 @@ private:
|
||||
static nsIAtom *kTreeItemAtom;
|
||||
static nsIAtom *kResourceAtom;
|
||||
static nsIAtom *kTreeContentsGeneratedAtom;
|
||||
static nsIAtom *kNameAtom;
|
||||
static nsIAtom *kSortAtom;
|
||||
static nsIAtom *kSortDirectionAtom;
|
||||
static nsIAtom *kIdAtom;
|
||||
static nsIAtom *kNaturalOrderPosAtom;
|
||||
|
||||
static PRInt32 kNameSpaceID_XUL;
|
||||
static PRInt32 kNameSpaceID_RDF;
|
||||
|
||||
static nsIRDFService *gRDFService;
|
||||
|
||||
nsresult FindTreeElement(nsIContent* aElement,nsIContent** aTreeElement);
|
||||
nsresult FindTreeBodyElement(nsIContent *tree, nsIContent **treeBody);
|
||||
nsresult GetSortColumnIndex(nsIContent *tree, nsString sortResource, PRInt32 *colIndex);
|
||||
nsresult GetSortColumnIndex(nsIContent *tree, nsString sortResource, nsString sortDirection, PRInt32 *colIndex);
|
||||
nsresult GetSortColumnInfo(nsIContent *tree, nsString &sortResource, nsString &sortDirection);
|
||||
nsresult GetTreeCell(nsIContent *node, PRInt32 colIndex, nsIContent **cell);
|
||||
nsresult GetTreeCellValue(nsIContent *node, nsString & value);
|
||||
nsresult RemoveAllChildren(nsIContent *node);
|
||||
nsresult SortTreeChildren(nsIContent *container, PRInt32 colIndex, PRInt32 indentLevel);
|
||||
nsresult SortTreeChildren(nsIContent *container, PRInt32 colIndex, nsString sortDirection, PRInt32 indentLevel);
|
||||
nsresult PrintTreeChildren(nsIContent *container, PRInt32 colIndex, PRInt32 indentLevel);
|
||||
|
||||
public:
|
||||
@ -111,12 +159,16 @@ public:
|
||||
NS_DECL_ISUPPORTS
|
||||
|
||||
// nsISortService
|
||||
NS_IMETHOD DoSort(nsIDOMNode* node, const nsString& sortResource);
|
||||
NS_IMETHOD DoSort(nsIDOMNode* node, const nsString& sortResource, const nsString& sortDirection);
|
||||
NS_IMETHOD OpenContainer(nsIRDFCompositeDataSource *db, nsIContent *container, nsIRDFResource **flatArray,
|
||||
PRInt32 numElements, PRInt32 elementSize);
|
||||
};
|
||||
|
||||
nsIXULSortService* XULSortServiceImpl::gXULSortService = nsnull;
|
||||
nsrefcnt XULSortServiceImpl::gRefCnt = 0;
|
||||
|
||||
nsIRDFService *XULSortServiceImpl::gRDFService = nsnull;
|
||||
|
||||
nsIAtom* XULSortServiceImpl::kTreeAtom;
|
||||
nsIAtom* XULSortServiceImpl::kTreeBodyAtom;
|
||||
nsIAtom* XULSortServiceImpl::kTreeCellAtom;
|
||||
@ -125,6 +177,12 @@ nsIAtom* XULSortServiceImpl::kTreeColAtom;
|
||||
nsIAtom* XULSortServiceImpl::kTreeItemAtom;
|
||||
nsIAtom* XULSortServiceImpl::kResourceAtom;
|
||||
nsIAtom* XULSortServiceImpl::kTreeContentsGeneratedAtom;
|
||||
nsIAtom* XULSortServiceImpl::kNameAtom;
|
||||
nsIAtom* XULSortServiceImpl::kSortAtom;
|
||||
nsIAtom* XULSortServiceImpl::kSortDirectionAtom;
|
||||
nsIAtom* XULSortServiceImpl::kIdAtom;
|
||||
nsIAtom* XULSortServiceImpl::kNaturalOrderPosAtom;
|
||||
|
||||
PRInt32 XULSortServiceImpl::kNameSpaceID_XUL;
|
||||
PRInt32 XULSortServiceImpl::kNameSpaceID_RDF;
|
||||
|
||||
@ -143,9 +201,19 @@ XULSortServiceImpl::XULSortServiceImpl(void)
|
||||
kTreeItemAtom = NS_NewAtom("treeitem");
|
||||
kResourceAtom = NS_NewAtom("resource");
|
||||
kTreeContentsGeneratedAtom = NS_NewAtom("treecontentsgenerated");
|
||||
kNameAtom = NS_NewAtom("Name");
|
||||
kSortAtom = NS_NewAtom("sortActive");
|
||||
kSortDirectionAtom = NS_NewAtom("sortDirection");
|
||||
kIdAtom = NS_NewAtom("id");
|
||||
kNaturalOrderPosAtom = NS_NewAtom("pos");
|
||||
|
||||
nsresult rv;
|
||||
|
||||
if (NS_FAILED(rv = nsServiceManager::GetService(kRDFServiceCID,
|
||||
kIRDFServiceIID, (nsISupports**) &gRDFService)))
|
||||
{
|
||||
NS_ERROR("couldn't create rdf service");
|
||||
}
|
||||
// Register the XUL and RDF namespaces: these'll just retrieve
|
||||
// the IDs if they've already been registered by someone else.
|
||||
nsINameSpaceManager* mgr;
|
||||
@ -192,7 +260,14 @@ XULSortServiceImpl::~XULSortServiceImpl(void)
|
||||
NS_RELEASE(kTreeItemAtom);
|
||||
NS_RELEASE(kResourceAtom);
|
||||
NS_RELEASE(kTreeContentsGeneratedAtom);
|
||||
NS_RELEASE(kNameAtom);
|
||||
NS_RELEASE(kSortAtom);
|
||||
NS_RELEASE(kSortDirectionAtom);
|
||||
NS_RELEASE(kIdAtom);
|
||||
NS_RELEASE(kNaturalOrderPosAtom);
|
||||
|
||||
nsServiceManager::ReleaseService(kRDFServiceCID, gRDFService);
|
||||
gRDFService = nsnull;
|
||||
nsServiceManager::ReleaseService(kXULSortServiceCID, gXULSortService);
|
||||
gXULSortService = nsnull;
|
||||
}
|
||||
@ -289,14 +364,14 @@ XULSortServiceImpl::FindTreeBodyElement(nsIContent *tree, nsIContent **treeBody)
|
||||
}
|
||||
|
||||
nsresult
|
||||
XULSortServiceImpl::GetSortColumnIndex(nsIContent *tree, nsString sortResource, PRInt32 *colIndex)
|
||||
XULSortServiceImpl::GetSortColumnIndex(nsIContent *tree, nsString sortResource, nsString sortDirection, PRInt32 *sortColIndex)
|
||||
{
|
||||
PRBool found = PR_FALSE;
|
||||
PRInt32 childIndex = 0, numChildren = 0, nameSpaceID;
|
||||
PRInt32 childIndex, colIndex = 0, numChildren, nameSpaceID;
|
||||
nsCOMPtr<nsIContent> child;
|
||||
nsresult rv;
|
||||
|
||||
*colIndex = 0;
|
||||
*sortColIndex = 0;
|
||||
if (NS_FAILED(rv = tree->ChildCount(numChildren))) return(rv);
|
||||
for (childIndex=0; childIndex<numChildren; childIndex++)
|
||||
{
|
||||
@ -316,11 +391,64 @@ XULSortServiceImpl::GetSortColumnIndex(nsIContent *tree, nsString sortResource,
|
||||
{
|
||||
if (colResource == sortResource)
|
||||
{
|
||||
nsString trueStr("true");
|
||||
child->SetAttribute(kNameSpaceID_None, kSortAtom, trueStr, PR_TRUE);
|
||||
child->SetAttribute(kNameSpaceID_None, kSortDirectionAtom, sortDirection, PR_TRUE);
|
||||
*sortColIndex = colIndex;
|
||||
found = PR_TRUE;
|
||||
// Note: don't break, want to set/unset attribs on ALL sort columns
|
||||
// break;
|
||||
}
|
||||
else
|
||||
{
|
||||
nsString falseStr("false");
|
||||
child->SetAttribute(kNameSpaceID_None, kSortAtom, falseStr, PR_TRUE);
|
||||
child->SetAttribute(kNameSpaceID_None, kSortDirectionAtom, sortDirection, PR_TRUE);
|
||||
}
|
||||
}
|
||||
++colIndex;
|
||||
}
|
||||
}
|
||||
}
|
||||
return((found == PR_TRUE) ? NS_OK : NS_ERROR_FAILURE);
|
||||
}
|
||||
|
||||
nsresult
|
||||
XULSortServiceImpl::GetSortColumnInfo(nsIContent *tree, nsString &sortResource, nsString &sortDirection)
|
||||
{
|
||||
nsCOMPtr<nsIContent> child;
|
||||
PRBool found = PR_FALSE;
|
||||
PRInt32 childIndex, numChildren, nameSpaceID;
|
||||
nsresult rv;
|
||||
|
||||
if (NS_FAILED(rv = tree->ChildCount(numChildren))) return(rv);
|
||||
for (childIndex=0; childIndex<numChildren; childIndex++)
|
||||
{
|
||||
if (NS_FAILED(rv = tree->ChildAt(childIndex, *getter_AddRefs(child)))) return(rv);
|
||||
if (NS_FAILED(rv = child->GetNameSpaceID(nameSpaceID))) return(rv);
|
||||
if (nameSpaceID == kNameSpaceID_XUL)
|
||||
{
|
||||
nsCOMPtr<nsIAtom> tag;
|
||||
|
||||
if (NS_FAILED(rv = child->GetTag(*getter_AddRefs(tag))))
|
||||
return rv;
|
||||
if (tag.get() == kTreeColAtom)
|
||||
{
|
||||
nsString value;
|
||||
if (NS_OK == child->GetAttribute(kNameSpaceID_None, kSortAtom, value))
|
||||
{
|
||||
if (value.Equals("true"))
|
||||
{
|
||||
if (NS_OK == child->GetAttribute(kNameSpaceID_RDF, kResourceAtom, sortResource))
|
||||
{
|
||||
if (NS_OK == child->GetAttribute(kNameSpaceID_None, kSortDirectionAtom, sortDirection))
|
||||
{
|
||||
found = PR_TRUE;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
++(*colIndex);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -376,17 +504,8 @@ XULSortServiceImpl::GetTreeCellValue(nsIContent *node, nsString & val)
|
||||
{
|
||||
if (NS_FAILED(rv = node->ChildAt(childIndex, *getter_AddRefs(child)))) break;;
|
||||
if (NS_FAILED(rv = child->GetNameSpaceID(nameSpaceID))) break;
|
||||
if (nameSpaceID == kNameSpaceID_XUL)
|
||||
{
|
||||
nsCOMPtr<nsIAtom> tag;
|
||||
|
||||
if (NS_FAILED(rv = child->GetTag(*getter_AddRefs(tag))))
|
||||
return rv;
|
||||
nsString tagName;
|
||||
tag->ToString(tagName);
|
||||
printf("Child #%d: tagName='%s'\n", childIndex, tagName.ToNewCString());
|
||||
}
|
||||
else if (nameSpaceID != kNameSpaceID_XUL)
|
||||
// XXX is this the correct way to get text? Probably not...
|
||||
if (nameSpaceID != kNameSpaceID_XUL)
|
||||
{
|
||||
nsITextContent *text = nsnull;
|
||||
if (NS_SUCCEEDED(rv = child->QueryInterface(kITextContentIID, (void **)&text)))
|
||||
@ -426,13 +545,82 @@ XULSortServiceImpl::RemoveAllChildren(nsIContent *container)
|
||||
}
|
||||
|
||||
|
||||
|
||||
typedef struct _sortStruct {
|
||||
nsIRDFCompositeDataSource *db;
|
||||
nsIRDFResource *sortProperty;
|
||||
PRBool descendingSort;
|
||||
PRBool naturalOrderSort;
|
||||
} sortStruct, *sortPtr;
|
||||
|
||||
|
||||
|
||||
int openSortCallback(const void *data1, const void *data2, void *sortData);
|
||||
int inplaceSortCallback(const void *data1, const void *data2, void *sortData);
|
||||
|
||||
|
||||
|
||||
int
|
||||
openSortCallback(const void *data1, const void *data2, void *sortData)
|
||||
{
|
||||
int sortOrder = 0;
|
||||
nsresult rv;
|
||||
|
||||
nsIRDFNode *node1, *node2;
|
||||
node1 = *(nsIRDFNode **)data1;
|
||||
node2 = *(nsIRDFNode **)data2;
|
||||
_sortStruct *sortPtr = (_sortStruct *)sortData;
|
||||
|
||||
nsIRDFResource *res1;
|
||||
nsIRDFResource *res2;
|
||||
const PRUnichar *uniStr1 = nsnull;
|
||||
const PRUnichar *uniStr2 = nsnull;
|
||||
|
||||
if (NS_SUCCEEDED(node1->QueryInterface(kIRDFResourceIID, (void **) &res1)))
|
||||
{
|
||||
nsIRDFNode *nodeVal1;
|
||||
if (NS_SUCCEEDED(rv = sortPtr->db->GetTarget(res1, sortPtr->sortProperty, PR_TRUE, &nodeVal1)))
|
||||
{
|
||||
nsIRDFLiteral *literal1;
|
||||
if (NS_SUCCEEDED(nodeVal1->QueryInterface(kIRDFLiteralIID, (void **) &literal1)))
|
||||
{
|
||||
literal1->GetValue(&uniStr1);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (NS_SUCCEEDED(node2->QueryInterface(kIRDFResourceIID, (void **) &res2)))
|
||||
{
|
||||
nsIRDFNode *nodeVal2;
|
||||
if (NS_SUCCEEDED(rv = sortPtr->db->GetTarget(res2, sortPtr->sortProperty, PR_TRUE, &nodeVal2)))
|
||||
{
|
||||
nsIRDFLiteral *literal2;
|
||||
if (NS_SUCCEEDED(nodeVal2->QueryInterface(kIRDFLiteralIID, (void **) &literal2)))
|
||||
{
|
||||
literal2->GetValue(&uniStr2);
|
||||
}
|
||||
}
|
||||
}
|
||||
if ((uniStr1 != nsnull) && (uniStr2 != nsnull))
|
||||
{
|
||||
nsAutoString str1(uniStr1), str2(uniStr2);
|
||||
sortOrder = (int)str1.Compare(str2, PR_TRUE);
|
||||
if (sortPtr->descendingSort == PR_TRUE)
|
||||
{
|
||||
sortOrder = -sortOrder;
|
||||
}
|
||||
}
|
||||
else if ((uniStr1 != nsnull) && (uniStr2 == nsnull))
|
||||
{
|
||||
sortOrder = -1;
|
||||
}
|
||||
else
|
||||
{
|
||||
sortOrder = 1;
|
||||
}
|
||||
return(sortOrder);
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
inplaceSortCallback(const void *data1, const void *data2, void *sortData)
|
||||
{
|
||||
@ -452,14 +640,30 @@ inplaceSortCallback(const void *data1, const void *data2, void *sortData)
|
||||
return(sortOrder);
|
||||
}
|
||||
|
||||
|
||||
|
||||
nsresult
|
||||
XULSortServiceImpl::SortTreeChildren(nsIContent *container, PRInt32 colIndex, PRInt32 indentLevel)
|
||||
XULSortServiceImpl::SortTreeChildren(nsIContent *container, PRInt32 colIndex, nsString sortDirection, PRInt32 indentLevel)
|
||||
{
|
||||
PRInt32 childIndex = 0, numChildren = 0, nameSpaceID;
|
||||
nsCOMPtr<nsIContent> child;
|
||||
nsresult rv;
|
||||
nsVoidArray *childArray;
|
||||
|
||||
_sortStruct sortInfo;
|
||||
|
||||
if (sortDirection.Equals("natural"))
|
||||
{
|
||||
sortInfo.naturalOrderSort = PR_TRUE;
|
||||
sortInfo.descendingSort = PR_FALSE;
|
||||
}
|
||||
else
|
||||
{
|
||||
sortInfo.naturalOrderSort = PR_FALSE;;
|
||||
if (sortDirection.Equals("ascending")) sortInfo.descendingSort = PR_FALSE;
|
||||
else if (sortDirection.Equals("descending")) sortInfo.descendingSort = PR_TRUE;
|
||||
}
|
||||
|
||||
if (NS_FAILED(rv = container->ChildCount(numChildren))) return(rv);
|
||||
|
||||
if ((childArray = new nsVoidArray()) == nsnull) return (NS_ERROR_OUT_OF_MEMORY);
|
||||
@ -474,8 +678,9 @@ XULSortServiceImpl::SortTreeChildren(nsIContent *container, PRInt32 colIndex, PR
|
||||
if (NS_FAILED(rv = child->GetTag(*getter_AddRefs(tag)))) return rv;
|
||||
if (tag.get() == kTreeItemAtom)
|
||||
{
|
||||
PRBool found = PR_FALSE;
|
||||
nsIContent *cell;
|
||||
if (NS_SUCCEEDED(rv = GetTreeCell(child, colIndex, &cell)))
|
||||
if ((indentLevel == 0) && (NS_SUCCEEDED(rv = GetTreeCell(child, colIndex, &cell))))
|
||||
{
|
||||
if (cell)
|
||||
{
|
||||
@ -484,10 +689,54 @@ XULSortServiceImpl::SortTreeChildren(nsIContent *container, PRInt32 colIndex, PR
|
||||
{
|
||||
// hack: always append cell value 1st as
|
||||
// that's what sort callback expects
|
||||
|
||||
if (sortInfo.naturalOrderSort == PR_TRUE)
|
||||
{
|
||||
// ???????????????????
|
||||
|
||||
// XXX: note memory leak!
|
||||
childArray->AppendElement(val.ToNewCString());
|
||||
childArray->AppendElement(child);
|
||||
}
|
||||
else
|
||||
{
|
||||
// XXX: note memory leak!
|
||||
childArray->AppendElement(val.ToNewCString());
|
||||
childArray->AppendElement(child);
|
||||
}
|
||||
found = PR_TRUE;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (found == PR_FALSE)
|
||||
{
|
||||
// hack: always append cell value 1st as
|
||||
// that's what sort callback expects
|
||||
|
||||
PRBool foundValue = PR_FALSE;
|
||||
if (sortInfo.naturalOrderSort == PR_TRUE)
|
||||
{
|
||||
nsString pos;
|
||||
if (NS_OK == child->GetAttribute(kNameSpaceID_None, kNaturalOrderPosAtom, pos))
|
||||
{
|
||||
// XXX: note memory leak!
|
||||
childArray->AppendElement(pos.ToNewCString());
|
||||
childArray->AppendElement(child);
|
||||
foundValue = PR_TRUE;
|
||||
}
|
||||
}
|
||||
if (foundValue == PR_FALSE)
|
||||
{
|
||||
nsString name;
|
||||
if (NS_OK == child->GetAttribute(kNameSpaceID_None, kNameAtom, name))
|
||||
{
|
||||
// XXX: note memory leak!
|
||||
childArray->AppendElement(name.ToNewCString());
|
||||
childArray->AppendElement(child);
|
||||
foundValue = PR_TRUE;
|
||||
}
|
||||
}
|
||||
found = PR_TRUE;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -498,10 +747,6 @@ XULSortServiceImpl::SortTreeChildren(nsIContent *container, PRInt32 colIndex, PR
|
||||
nsIContent ** flatArray = new nsIContent*[numElements];
|
||||
if (flatArray)
|
||||
{
|
||||
_sortStruct sortInfo;
|
||||
|
||||
sortInfo.descendingSort = PR_TRUE;
|
||||
|
||||
// flatten array of resources, sort them, then add as tree elements
|
||||
unsigned long loop;
|
||||
for (loop=0; loop<numElements; loop++)
|
||||
@ -523,11 +768,82 @@ XULSortServiceImpl::SortTreeChildren(nsIContent *container, PRInt32 colIndex, PR
|
||||
{
|
||||
container->InsertChildAt((nsIContent *)flatArray[loop+1], numChildren++, PR_TRUE);
|
||||
}
|
||||
|
||||
// recurse on grandchildren
|
||||
|
||||
for (loop=0; loop<numElements; loop+=2)
|
||||
{
|
||||
container = (nsIContent *)flatArray[loop+1];
|
||||
|
||||
PRBool canHaveKids = PR_FALSE;
|
||||
if (NS_FAILED(rv = container->CanContainChildren(canHaveKids))) continue;
|
||||
if (canHaveKids == PR_FALSE) continue;
|
||||
|
||||
if (NS_FAILED(rv = container->ChildCount(numChildren))) continue;
|
||||
for (childIndex=0; childIndex<numChildren; childIndex++)
|
||||
{
|
||||
if (NS_FAILED(rv = container->ChildAt(childIndex, *getter_AddRefs(child))))
|
||||
continue;
|
||||
if (NS_FAILED(rv = child->GetNameSpaceID(nameSpaceID))) continue;
|
||||
if (nameSpaceID == kNameSpaceID_XUL)
|
||||
{
|
||||
nsCOMPtr<nsIAtom> tag;
|
||||
if (NS_FAILED(rv = child->GetTag(*getter_AddRefs(tag))))
|
||||
continue;
|
||||
if (tag.get() == kTreeChildrenAtom)
|
||||
{
|
||||
SortTreeChildren(child, colIndex, sortDirection, indentLevel+1);
|
||||
}
|
||||
}
|
||||
delete(childArray);
|
||||
return(rv);
|
||||
}
|
||||
}
|
||||
delete [] flatArray;
|
||||
flatArray = nsnull;
|
||||
}
|
||||
}
|
||||
return(NS_OK);
|
||||
}
|
||||
|
||||
|
||||
|
||||
NS_IMETHODIMP
|
||||
XULSortServiceImpl::OpenContainer(nsIRDFCompositeDataSource *db, nsIContent *container,
|
||||
nsIRDFResource **flatArray, PRInt32 numElements, PRInt32 elementSize)
|
||||
{
|
||||
nsresult rv;
|
||||
nsIContent *treeNode;
|
||||
nsString sortResource, sortDirection;
|
||||
_sortStruct sortInfo;
|
||||
|
||||
// get sorting info (property to sort on, direction to sort, etc)
|
||||
|
||||
if (NS_FAILED(rv = FindTreeElement(container, &treeNode))) return(rv);
|
||||
|
||||
sortInfo.db = db;
|
||||
if (NS_FAILED(rv = GetSortColumnInfo(treeNode, sortResource, sortDirection))) return(rv);
|
||||
char *uri = sortResource.ToNewCString();
|
||||
if (NS_FAILED(rv = gRDFService->GetResource(uri, &sortInfo.sortProperty))) return(rv);
|
||||
delete [] uri;
|
||||
if (sortDirection.Equals("natural"))
|
||||
{
|
||||
sortInfo.naturalOrderSort = PR_TRUE;
|
||||
sortInfo.descendingSort = PR_FALSE;
|
||||
// no need to sort for natural order
|
||||
}
|
||||
else
|
||||
{
|
||||
sortInfo.naturalOrderSort = PR_FALSE;
|
||||
if (sortDirection.Equals("descending"))
|
||||
sortInfo.descendingSort = PR_TRUE;
|
||||
else
|
||||
sortInfo.descendingSort = PR_FALSE;
|
||||
rdf_qsort((void *)flatArray, numElements, elementSize, openSortCallback, (void *)&sortInfo);
|
||||
}
|
||||
|
||||
return(NS_OK);
|
||||
}
|
||||
|
||||
|
||||
|
||||
nsresult
|
||||
XULSortServiceImpl::PrintTreeChildren(nsIContent *container, PRInt32 colIndex, PRInt32 indentLevel)
|
||||
@ -605,38 +921,22 @@ XULSortServiceImpl::PrintTreeChildren(nsIContent *container, PRInt32 colIndex, P
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
XULSortServiceImpl::DoSort(nsIDOMNode* node, const nsString& sortResource)
|
||||
XULSortServiceImpl::DoSort(nsIDOMNode* node, const nsString& sortResource,
|
||||
const nsString& sortDirection)
|
||||
{
|
||||
printf("XULSortServiceImpl::DoSort entered!!!\n");
|
||||
|
||||
PRInt32 childIndex, colIndex, numChildren, treeBodyIndex;
|
||||
nsIContent *child, *contentNode, *treeNode, *treeBody, *treeParent;
|
||||
PRInt32 colIndex, treeBodyIndex;
|
||||
nsIContent *contentNode, *treeNode, *treeBody, *treeParent;
|
||||
nsresult rv;
|
||||
|
||||
if (NS_FAILED(rv = node->QueryInterface(kIContentIID, (void**)&contentNode))) return(rv);
|
||||
printf("Success converting dom node to content node.\n");
|
||||
|
||||
if (NS_FAILED(rv = FindTreeElement(contentNode, &treeNode))) return(rv);
|
||||
printf("found tree element\n");
|
||||
|
||||
if (NS_FAILED(rv = GetSortColumnIndex(treeNode, sortResource, &colIndex))) return(rv);
|
||||
printf("Sort column index is %d.\n", (int)colIndex);
|
||||
|
||||
if (NS_FAILED(rv = GetSortColumnIndex(treeNode, sortResource, sortDirection, &colIndex))) return(rv);
|
||||
if (NS_FAILED(rv = FindTreeBodyElement(treeNode, &treeBody))) return(rv);
|
||||
printf("Found tree body.\n");
|
||||
|
||||
if (NS_FAILED(rv = treeBody->GetParent(treeParent))) return(rv);
|
||||
printf("Found tree parent.\n");
|
||||
|
||||
if (NS_FAILED(rv = treeParent->IndexOf(treeBody, treeBodyIndex))) return(rv);
|
||||
printf("Found index of tree body in tree parent.\n");
|
||||
|
||||
if (NS_FAILED(rv = treeParent->RemoveChildAt(treeBodyIndex, PR_TRUE))) return(rv);
|
||||
printf("Removed tree body from parent.\n");
|
||||
|
||||
if (NS_SUCCEEDED(rv = SortTreeChildren(treeBody, colIndex, 0)))
|
||||
if (NS_SUCCEEDED(rv = SortTreeChildren(treeBody, colIndex, sortDirection, 0)))
|
||||
{
|
||||
printf("Tree sorted.\n");
|
||||
}
|
||||
|
||||
if (NS_SUCCEEDED(rv = treeBody->UnsetAttribute(kNameSpaceID_None,
|
||||
@ -649,17 +949,18 @@ XULSortServiceImpl::DoSort(nsIDOMNode* node, const nsString& sortResource)
|
||||
}
|
||||
|
||||
if (NS_FAILED(rv = treeParent->AppendChildTo(treeBody, PR_TRUE))) return(rv);
|
||||
printf("Added tree body back into parent.\n");
|
||||
|
||||
#if 0
|
||||
if (NS_FAILED(rv = PrintTreeChildren(treeBody, colIndex, 0))) return(rv);
|
||||
printf("Tree printed.\nDone.\n");
|
||||
#endif
|
||||
return(NS_OK);
|
||||
}
|
||||
|
||||
|
||||
|
||||
nsresult
|
||||
NS_NewXULSortService(nsIXULSortService** mgr)
|
||||
{
|
||||
return XULSortServiceImpl::GetSortService(mgr);
|
||||
}
|
||||
|
||||
|
@ -40,7 +40,9 @@ class nsIXULSortService : public nsISupports {
|
||||
public:
|
||||
static const nsIID& IID() { static nsIID iid = NS_IXULSORTSERVICE_IID; return iid; }
|
||||
|
||||
NS_IMETHOD DoSort(nsIDOMNode* node, const nsString& sortResource) = 0;
|
||||
NS_IMETHOD DoSort(nsIDOMNode* node, const nsString& sortResource, const nsString& sortDirection) = 0;
|
||||
NS_IMETHOD OpenContainer(nsIRDFCompositeDataSource *db, nsIContent *container,
|
||||
nsIRDFResource **flatArray, PRInt32 numElements, PRInt32 elementSize) = 0;
|
||||
};
|
||||
|
||||
|
||||
|
@ -80,7 +80,7 @@
|
||||
#include "rdfutil.h"
|
||||
|
||||
#include "nsVoidArray.h"
|
||||
#include "rdf_qsort.h"
|
||||
#include "nsIXULSortService.h"
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
@ -107,6 +107,9 @@ static NS_DEFINE_IID(kISupportsIID, NS_ISUPPORTS_IID);
|
||||
static NS_DEFINE_CID(kNameSpaceManagerCID, NS_NAMESPACEMANAGER_CID);
|
||||
static NS_DEFINE_CID(kRDFServiceCID, NS_RDFSERVICE_CID);
|
||||
|
||||
static NS_DEFINE_IID(kXULSortServiceCID, NS_XULSORTSERVICE_CID);
|
||||
static NS_DEFINE_IID(kIXULSortServiceIID, NS_IXULSORTSERVICE_IID);
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
class RDFTreeBuilderImpl : public nsIRDFContentModelBuilder,
|
||||
@ -139,6 +142,7 @@ private:
|
||||
static nsIAtom* kTreeIndentationAtom;
|
||||
static nsIAtom* kTreeItemAtom;
|
||||
static nsIAtom* kContainmentAtom;
|
||||
static nsIAtom* kNaturalOrderPosAtom;
|
||||
|
||||
static PRInt32 kNameSpaceID_RDF;
|
||||
static PRInt32 kNameSpaceID_XUL;
|
||||
@ -201,7 +205,8 @@ public:
|
||||
nsresult
|
||||
AddTreeRow(nsIContent* aTreeItemElement,
|
||||
nsIRDFResource* aProperty,
|
||||
nsIRDFResource* aValue);
|
||||
nsIRDFResource* aValue,
|
||||
PRInt32 naturalOrderPos);
|
||||
|
||||
nsresult
|
||||
EnsureCell(nsIContent* aTreeItemElement, PRInt32 aIndex, nsIContent** aCellElement);
|
||||
@ -282,6 +287,7 @@ nsIAtom* RDFTreeBuilderImpl::kTreeIconAtom;
|
||||
nsIAtom* RDFTreeBuilderImpl::kTreeIndentationAtom;
|
||||
nsIAtom* RDFTreeBuilderImpl::kTreeItemAtom;
|
||||
nsIAtom* RDFTreeBuilderImpl::kContainmentAtom;
|
||||
nsIAtom* RDFTreeBuilderImpl::kNaturalOrderPosAtom;
|
||||
|
||||
PRInt32 RDFTreeBuilderImpl::kNameSpaceID_RDF;
|
||||
PRInt32 RDFTreeBuilderImpl::kNameSpaceID_XUL;
|
||||
@ -339,6 +345,7 @@ RDFTreeBuilderImpl::RDFTreeBuilderImpl(void)
|
||||
kTreeIndentationAtom = NS_NewAtom("treeindentation");
|
||||
kTreeItemAtom = NS_NewAtom("treeitem");
|
||||
kContainmentAtom = NS_NewAtom("containment");
|
||||
kNaturalOrderPosAtom = NS_NewAtom("pos");
|
||||
|
||||
nsresult rv;
|
||||
|
||||
@ -421,7 +428,7 @@ RDFTreeBuilderImpl::~RDFTreeBuilderImpl(void)
|
||||
NS_RELEASE(kTreeIndentationAtom);
|
||||
NS_RELEASE(kTreeItemAtom);
|
||||
NS_RELEASE(kContainmentAtom);
|
||||
|
||||
NS_RELEASE(kNaturalOrderPosAtom);
|
||||
NS_RELEASE(kNC_Title);
|
||||
NS_RELEASE(kNC_Column);
|
||||
|
||||
@ -591,76 +598,6 @@ RDFTreeBuilderImpl::SetRootContent(nsIContent* aElement)
|
||||
}
|
||||
|
||||
|
||||
typedef struct _sortStruct {
|
||||
nsIRDFCompositeDataSource *db;
|
||||
nsIRDFResource *sortProperty;
|
||||
PRBool descendingSort;
|
||||
} sortStruct, *sortPtr;
|
||||
|
||||
|
||||
int rdfSortCallback(const void *data1, const void *data2, void *data);
|
||||
|
||||
|
||||
int
|
||||
rdfSortCallback(const void *data1, const void *data2, void *sortData)
|
||||
{
|
||||
int sortOrder = 0;
|
||||
nsresult rv;
|
||||
|
||||
nsIRDFNode *node1, *node2;
|
||||
node1 = *(nsIRDFNode **)data1;
|
||||
node2 = *(nsIRDFNode **)data2;
|
||||
_sortStruct *sortPtr = (_sortStruct *)sortData;
|
||||
|
||||
nsIRDFResource *res1;
|
||||
nsIRDFResource *res2;
|
||||
const PRUnichar *uniStr1 = nsnull;
|
||||
const PRUnichar *uniStr2 = nsnull;
|
||||
|
||||
if (NS_SUCCEEDED(node1->QueryInterface(kIRDFResourceIID, (void **) &res1)))
|
||||
{
|
||||
nsIRDFNode *nodeVal1;
|
||||
if (NS_SUCCEEDED(rv = sortPtr->db->GetTarget(res1, sortPtr->sortProperty, PR_TRUE, &nodeVal1)))
|
||||
{
|
||||
nsIRDFLiteral *literal1;
|
||||
if (NS_SUCCEEDED(nodeVal1->QueryInterface(kIRDFLiteralIID, (void **) &literal1)))
|
||||
{
|
||||
literal1->GetValue(&uniStr1);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (NS_SUCCEEDED(node2->QueryInterface(kIRDFResourceIID, (void **) &res2)))
|
||||
{
|
||||
nsIRDFNode *nodeVal2;
|
||||
if (NS_SUCCEEDED(rv = sortPtr->db->GetTarget(res2, sortPtr->sortProperty, PR_TRUE, &nodeVal2)))
|
||||
{
|
||||
nsIRDFLiteral *literal2;
|
||||
if (NS_SUCCEEDED(nodeVal2->QueryInterface(kIRDFLiteralIID, (void **) &literal2)))
|
||||
{
|
||||
literal2->GetValue(&uniStr2);
|
||||
}
|
||||
}
|
||||
}
|
||||
if ((uniStr1 != nsnull) && (uniStr2 != nsnull))
|
||||
{
|
||||
nsAutoString str1(uniStr1), str2(uniStr2);
|
||||
sortOrder = (int)str1.Compare(str2, PR_TRUE);
|
||||
if (sortPtr->descendingSort == PR_TRUE)
|
||||
{
|
||||
sortOrder = -sortOrder;
|
||||
}
|
||||
}
|
||||
else if ((uniStr1 != nsnull) && (uniStr2 == nsnull))
|
||||
{
|
||||
sortOrder = -1;
|
||||
}
|
||||
else
|
||||
{
|
||||
sortOrder = 1;
|
||||
}
|
||||
return(sortOrder);
|
||||
}
|
||||
|
||||
|
||||
NS_IMETHODIMP
|
||||
RDFTreeBuilderImpl::CreateContents(nsIContent* aElement)
|
||||
@ -761,11 +698,6 @@ RDFTreeBuilderImpl::CreateContents(nsIContent* aElement)
|
||||
due to sort callback implementation */
|
||||
tempArray->AppendElement(valueResource);
|
||||
tempArray->AppendElement(property);
|
||||
/* if (NS_FAILED(rv = AddTreeRow(aElement, property, valueResource))) {
|
||||
NS_ERROR("unable to create tree row");
|
||||
return rv;
|
||||
}
|
||||
*/
|
||||
}
|
||||
else {
|
||||
if (NS_FAILED(rv = SetCellValue(aElement, property, value))) {
|
||||
@ -780,41 +712,33 @@ RDFTreeBuilderImpl::CreateContents(nsIContent* aElement)
|
||||
unsigned long numElements = tempArray->Count();
|
||||
if (numElements > 0)
|
||||
{
|
||||
nsIRDFResource ** flatArray = (nsIRDFResource **)malloc(numElements * sizeof(void *));
|
||||
nsIRDFResource ** flatArray = new nsIRDFResource *[numElements];
|
||||
if (flatArray)
|
||||
{
|
||||
_sortStruct sortInfo;
|
||||
|
||||
// get sorting info (property to sort on, direction to sort, etc)
|
||||
|
||||
// XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
|
||||
// XXX Note: currently hardcoded; should get from DOM, or... ?
|
||||
// XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
|
||||
|
||||
sortInfo.db = mDB;
|
||||
sortInfo.descendingSort = PR_FALSE;
|
||||
if (NS_FAILED(rv = gRDFService->GetResource("http://home.netscape.com/NC-rdf#Name", &sortInfo.sortProperty)))
|
||||
{
|
||||
NS_ERROR("unable to create gSortProperty resource");
|
||||
return rv;
|
||||
}
|
||||
|
||||
// flatten array of resources, sort them, then add as tree elements
|
||||
unsigned long loop;
|
||||
|
||||
for (loop=0; loop<numElements; loop++)
|
||||
flatArray[loop] = (nsIRDFResource *)tempArray->ElementAt(loop);
|
||||
rdf_qsort((void *)flatArray, numElements/2, 2 * sizeof(void *), rdfSortCallback, (void *)&sortInfo);
|
||||
|
||||
nsIXULSortService *gXULSortService = nsnull;
|
||||
|
||||
nsresult rv = nsServiceManager::GetService(kXULSortServiceCID,
|
||||
kIXULSortServiceIID, (nsISupports**) &gXULSortService);
|
||||
if (nsnull != gXULSortService)
|
||||
{
|
||||
gXULSortService->OpenContainer(mDB, aElement, flatArray, numElements/2, 2*sizeof(nsIRDFResource *));
|
||||
nsServiceManager::ReleaseService(kXULSortServiceCID, gXULSortService);
|
||||
}
|
||||
|
||||
for (loop=0; loop<numElements; loop+=2)
|
||||
{
|
||||
if (NS_FAILED(rv = AddTreeRow(aElement,
|
||||
(nsIRDFResource *)flatArray[loop+1],
|
||||
(nsIRDFResource *)flatArray[loop])))
|
||||
if (NS_FAILED(rv = AddTreeRow(aElement, flatArray[loop+1], flatArray[loop], loop+1)))
|
||||
{
|
||||
NS_ERROR("unable to create tree row");
|
||||
}
|
||||
}
|
||||
free(flatArray);
|
||||
delete [] flatArray;
|
||||
}
|
||||
}
|
||||
delete tempArray;
|
||||
@ -888,7 +812,7 @@ RDFTreeBuilderImpl::OnAssert(nsIRDFResource* aSubject,
|
||||
contentsGenerated.EqualsIgnoreCase("true")) {
|
||||
// Okay, it's a "live" element, so go ahead and append the new
|
||||
// child to this node.
|
||||
if (NS_FAILED(rv = AddTreeRow(element, aPredicate, resource))) {
|
||||
if (NS_FAILED(rv = AddTreeRow(element, aPredicate, resource, 0))) {
|
||||
NS_ERROR("unable to create new tree row");
|
||||
return rv;
|
||||
}
|
||||
@ -1318,7 +1242,8 @@ RDFTreeBuilderImpl::EnsureElementHasGenericChild(nsIContent* parent,
|
||||
nsresult
|
||||
RDFTreeBuilderImpl::AddTreeRow(nsIContent* aElement,
|
||||
nsIRDFResource* aProperty,
|
||||
nsIRDFResource* aValue)
|
||||
nsIRDFResource* aValue,
|
||||
PRInt32 naturalOrderPos)
|
||||
{
|
||||
// If it's a tree property, then we need to add the new child
|
||||
// element to a special "children" element in the parent. The
|
||||
@ -1446,6 +1371,17 @@ RDFTreeBuilderImpl::AddTreeRow(nsIContent* aElement,
|
||||
}
|
||||
|
||||
treeItem->SetAttribute(nameSpaceID, tag, s, PR_FALSE);
|
||||
|
||||
if (naturalOrderPos > 0)
|
||||
{
|
||||
nsAutoString pos, zero("0");;
|
||||
pos.Append(naturalOrderPos, 10);
|
||||
if (pos.Length() < 4)
|
||||
{
|
||||
pos.Insert(zero, 0, 4-pos.Length());
|
||||
}
|
||||
treeItem->SetAttribute(kNameSpaceID_None, kNaturalOrderPosAtom, pos, PR_FALSE);
|
||||
}
|
||||
}
|
||||
|
||||
if (NS_FAILED(rv) && (rv != NS_ERROR_RDF_CURSOR_EMPTY)) {
|
||||
|
@ -20,6 +20,37 @@
|
||||
This file provides the implementation for the sort service manager.
|
||||
*/
|
||||
|
||||
#include "nsCOMPtr.h"
|
||||
#include "nsCRT.h"
|
||||
#include "nsIAtom.h"
|
||||
#include "nsIContent.h"
|
||||
#include "nsIDOMElement.h"
|
||||
#include "nsIDOMElementObserver.h"
|
||||
#include "nsIDOMNode.h"
|
||||
#include "nsIDOMNodeObserver.h"
|
||||
#include "nsIDocument.h"
|
||||
#include "nsINameSpaceManager.h"
|
||||
#include "nsIRDFContentModelBuilder.h"
|
||||
#include "nsIRDFCursor.h"
|
||||
#include "nsIRDFCompositeDataSource.h"
|
||||
#include "nsIRDFDocument.h"
|
||||
#include "nsIRDFNode.h"
|
||||
#include "nsIRDFObserver.h"
|
||||
#include "nsIRDFService.h"
|
||||
#include "nsIServiceManager.h"
|
||||
#include "nsINameSpaceManager.h"
|
||||
#include "nsIServiceManager.h"
|
||||
#include "nsISupportsArray.h"
|
||||
#include "nsIURL.h"
|
||||
#include "nsLayoutCID.h"
|
||||
#include "nsRDFCID.h"
|
||||
#include "nsRDFContentUtils.h"
|
||||
#include "nsString.h"
|
||||
#include "rdf.h"
|
||||
#include "rdfutil.h"
|
||||
|
||||
#include "nsVoidArray.h"
|
||||
#include "rdf_qsort.h"
|
||||
#include "nsIAtom.h"
|
||||
#include "nsIXULSortService.h"
|
||||
#include "nsString.h"
|
||||
@ -42,8 +73,11 @@
|
||||
|
||||
#include "nsIDOMNode.h"
|
||||
#include "nsIDOMElement.h"
|
||||
#include "nsIRDFContentModelBuilder.h"
|
||||
|
||||
#include "nsIRDFContentModelBuilder.h"
|
||||
#include "nsIRDFCompositeDataSource.h"
|
||||
#include "nsIRDFNode.h"
|
||||
#include "nsIRDFService.h"
|
||||
#include "rdf.h"
|
||||
|
||||
|
||||
@ -62,6 +96,11 @@ static NS_DEFINE_IID(kITextContentIID, NS_ITEXT_CONTENT_IID);
|
||||
static NS_DEFINE_IID(kIDomNodeIID, NS_IDOMNODE_IID);
|
||||
static NS_DEFINE_IID(kIDomElementIID, NS_IDOMELEMENT_IID);
|
||||
|
||||
static NS_DEFINE_CID(kRDFServiceCID, NS_RDFSERVICE_CID);
|
||||
static NS_DEFINE_IID(kIRDFServiceIID, NS_IRDFSERVICE_IID);
|
||||
static NS_DEFINE_IID(kIRDFResourceIID, NS_IRDFRESOURCE_IID);
|
||||
static NS_DEFINE_IID(kIRDFLiteralIID, NS_IRDFLITERAL_IID);
|
||||
|
||||
// XXX This is sure to change. Copied from mozilla/layout/xul/content/src/nsXULAtoms.cpp
|
||||
static const char kXULNameSpaceURI[]
|
||||
= "http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul";
|
||||
@ -91,16 +130,25 @@ private:
|
||||
static nsIAtom *kTreeItemAtom;
|
||||
static nsIAtom *kResourceAtom;
|
||||
static nsIAtom *kTreeContentsGeneratedAtom;
|
||||
static nsIAtom *kNameAtom;
|
||||
static nsIAtom *kSortAtom;
|
||||
static nsIAtom *kSortDirectionAtom;
|
||||
static nsIAtom *kIdAtom;
|
||||
static nsIAtom *kNaturalOrderPosAtom;
|
||||
|
||||
static PRInt32 kNameSpaceID_XUL;
|
||||
static PRInt32 kNameSpaceID_RDF;
|
||||
|
||||
static nsIRDFService *gRDFService;
|
||||
|
||||
nsresult FindTreeElement(nsIContent* aElement,nsIContent** aTreeElement);
|
||||
nsresult FindTreeBodyElement(nsIContent *tree, nsIContent **treeBody);
|
||||
nsresult GetSortColumnIndex(nsIContent *tree, nsString sortResource, PRInt32 *colIndex);
|
||||
nsresult GetSortColumnIndex(nsIContent *tree, nsString sortResource, nsString sortDirection, PRInt32 *colIndex);
|
||||
nsresult GetSortColumnInfo(nsIContent *tree, nsString &sortResource, nsString &sortDirection);
|
||||
nsresult GetTreeCell(nsIContent *node, PRInt32 colIndex, nsIContent **cell);
|
||||
nsresult GetTreeCellValue(nsIContent *node, nsString & value);
|
||||
nsresult RemoveAllChildren(nsIContent *node);
|
||||
nsresult SortTreeChildren(nsIContent *container, PRInt32 colIndex, PRInt32 indentLevel);
|
||||
nsresult SortTreeChildren(nsIContent *container, PRInt32 colIndex, nsString sortDirection, PRInt32 indentLevel);
|
||||
nsresult PrintTreeChildren(nsIContent *container, PRInt32 colIndex, PRInt32 indentLevel);
|
||||
|
||||
public:
|
||||
@ -111,12 +159,16 @@ public:
|
||||
NS_DECL_ISUPPORTS
|
||||
|
||||
// nsISortService
|
||||
NS_IMETHOD DoSort(nsIDOMNode* node, const nsString& sortResource);
|
||||
NS_IMETHOD DoSort(nsIDOMNode* node, const nsString& sortResource, const nsString& sortDirection);
|
||||
NS_IMETHOD OpenContainer(nsIRDFCompositeDataSource *db, nsIContent *container, nsIRDFResource **flatArray,
|
||||
PRInt32 numElements, PRInt32 elementSize);
|
||||
};
|
||||
|
||||
nsIXULSortService* XULSortServiceImpl::gXULSortService = nsnull;
|
||||
nsrefcnt XULSortServiceImpl::gRefCnt = 0;
|
||||
|
||||
nsIRDFService *XULSortServiceImpl::gRDFService = nsnull;
|
||||
|
||||
nsIAtom* XULSortServiceImpl::kTreeAtom;
|
||||
nsIAtom* XULSortServiceImpl::kTreeBodyAtom;
|
||||
nsIAtom* XULSortServiceImpl::kTreeCellAtom;
|
||||
@ -125,6 +177,12 @@ nsIAtom* XULSortServiceImpl::kTreeColAtom;
|
||||
nsIAtom* XULSortServiceImpl::kTreeItemAtom;
|
||||
nsIAtom* XULSortServiceImpl::kResourceAtom;
|
||||
nsIAtom* XULSortServiceImpl::kTreeContentsGeneratedAtom;
|
||||
nsIAtom* XULSortServiceImpl::kNameAtom;
|
||||
nsIAtom* XULSortServiceImpl::kSortAtom;
|
||||
nsIAtom* XULSortServiceImpl::kSortDirectionAtom;
|
||||
nsIAtom* XULSortServiceImpl::kIdAtom;
|
||||
nsIAtom* XULSortServiceImpl::kNaturalOrderPosAtom;
|
||||
|
||||
PRInt32 XULSortServiceImpl::kNameSpaceID_XUL;
|
||||
PRInt32 XULSortServiceImpl::kNameSpaceID_RDF;
|
||||
|
||||
@ -143,9 +201,19 @@ XULSortServiceImpl::XULSortServiceImpl(void)
|
||||
kTreeItemAtom = NS_NewAtom("treeitem");
|
||||
kResourceAtom = NS_NewAtom("resource");
|
||||
kTreeContentsGeneratedAtom = NS_NewAtom("treecontentsgenerated");
|
||||
kNameAtom = NS_NewAtom("Name");
|
||||
kSortAtom = NS_NewAtom("sortActive");
|
||||
kSortDirectionAtom = NS_NewAtom("sortDirection");
|
||||
kIdAtom = NS_NewAtom("id");
|
||||
kNaturalOrderPosAtom = NS_NewAtom("pos");
|
||||
|
||||
nsresult rv;
|
||||
|
||||
if (NS_FAILED(rv = nsServiceManager::GetService(kRDFServiceCID,
|
||||
kIRDFServiceIID, (nsISupports**) &gRDFService)))
|
||||
{
|
||||
NS_ERROR("couldn't create rdf service");
|
||||
}
|
||||
// Register the XUL and RDF namespaces: these'll just retrieve
|
||||
// the IDs if they've already been registered by someone else.
|
||||
nsINameSpaceManager* mgr;
|
||||
@ -192,7 +260,14 @@ XULSortServiceImpl::~XULSortServiceImpl(void)
|
||||
NS_RELEASE(kTreeItemAtom);
|
||||
NS_RELEASE(kResourceAtom);
|
||||
NS_RELEASE(kTreeContentsGeneratedAtom);
|
||||
NS_RELEASE(kNameAtom);
|
||||
NS_RELEASE(kSortAtom);
|
||||
NS_RELEASE(kSortDirectionAtom);
|
||||
NS_RELEASE(kIdAtom);
|
||||
NS_RELEASE(kNaturalOrderPosAtom);
|
||||
|
||||
nsServiceManager::ReleaseService(kRDFServiceCID, gRDFService);
|
||||
gRDFService = nsnull;
|
||||
nsServiceManager::ReleaseService(kXULSortServiceCID, gXULSortService);
|
||||
gXULSortService = nsnull;
|
||||
}
|
||||
@ -289,14 +364,14 @@ XULSortServiceImpl::FindTreeBodyElement(nsIContent *tree, nsIContent **treeBody)
|
||||
}
|
||||
|
||||
nsresult
|
||||
XULSortServiceImpl::GetSortColumnIndex(nsIContent *tree, nsString sortResource, PRInt32 *colIndex)
|
||||
XULSortServiceImpl::GetSortColumnIndex(nsIContent *tree, nsString sortResource, nsString sortDirection, PRInt32 *sortColIndex)
|
||||
{
|
||||
PRBool found = PR_FALSE;
|
||||
PRInt32 childIndex = 0, numChildren = 0, nameSpaceID;
|
||||
PRInt32 childIndex, colIndex = 0, numChildren, nameSpaceID;
|
||||
nsCOMPtr<nsIContent> child;
|
||||
nsresult rv;
|
||||
|
||||
*colIndex = 0;
|
||||
*sortColIndex = 0;
|
||||
if (NS_FAILED(rv = tree->ChildCount(numChildren))) return(rv);
|
||||
for (childIndex=0; childIndex<numChildren; childIndex++)
|
||||
{
|
||||
@ -316,11 +391,64 @@ XULSortServiceImpl::GetSortColumnIndex(nsIContent *tree, nsString sortResource,
|
||||
{
|
||||
if (colResource == sortResource)
|
||||
{
|
||||
nsString trueStr("true");
|
||||
child->SetAttribute(kNameSpaceID_None, kSortAtom, trueStr, PR_TRUE);
|
||||
child->SetAttribute(kNameSpaceID_None, kSortDirectionAtom, sortDirection, PR_TRUE);
|
||||
*sortColIndex = colIndex;
|
||||
found = PR_TRUE;
|
||||
// Note: don't break, want to set/unset attribs on ALL sort columns
|
||||
// break;
|
||||
}
|
||||
else
|
||||
{
|
||||
nsString falseStr("false");
|
||||
child->SetAttribute(kNameSpaceID_None, kSortAtom, falseStr, PR_TRUE);
|
||||
child->SetAttribute(kNameSpaceID_None, kSortDirectionAtom, sortDirection, PR_TRUE);
|
||||
}
|
||||
}
|
||||
++colIndex;
|
||||
}
|
||||
}
|
||||
}
|
||||
return((found == PR_TRUE) ? NS_OK : NS_ERROR_FAILURE);
|
||||
}
|
||||
|
||||
nsresult
|
||||
XULSortServiceImpl::GetSortColumnInfo(nsIContent *tree, nsString &sortResource, nsString &sortDirection)
|
||||
{
|
||||
nsCOMPtr<nsIContent> child;
|
||||
PRBool found = PR_FALSE;
|
||||
PRInt32 childIndex, numChildren, nameSpaceID;
|
||||
nsresult rv;
|
||||
|
||||
if (NS_FAILED(rv = tree->ChildCount(numChildren))) return(rv);
|
||||
for (childIndex=0; childIndex<numChildren; childIndex++)
|
||||
{
|
||||
if (NS_FAILED(rv = tree->ChildAt(childIndex, *getter_AddRefs(child)))) return(rv);
|
||||
if (NS_FAILED(rv = child->GetNameSpaceID(nameSpaceID))) return(rv);
|
||||
if (nameSpaceID == kNameSpaceID_XUL)
|
||||
{
|
||||
nsCOMPtr<nsIAtom> tag;
|
||||
|
||||
if (NS_FAILED(rv = child->GetTag(*getter_AddRefs(tag))))
|
||||
return rv;
|
||||
if (tag.get() == kTreeColAtom)
|
||||
{
|
||||
nsString value;
|
||||
if (NS_OK == child->GetAttribute(kNameSpaceID_None, kSortAtom, value))
|
||||
{
|
||||
if (value.Equals("true"))
|
||||
{
|
||||
if (NS_OK == child->GetAttribute(kNameSpaceID_RDF, kResourceAtom, sortResource))
|
||||
{
|
||||
if (NS_OK == child->GetAttribute(kNameSpaceID_None, kSortDirectionAtom, sortDirection))
|
||||
{
|
||||
found = PR_TRUE;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
++(*colIndex);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -376,17 +504,8 @@ XULSortServiceImpl::GetTreeCellValue(nsIContent *node, nsString & val)
|
||||
{
|
||||
if (NS_FAILED(rv = node->ChildAt(childIndex, *getter_AddRefs(child)))) break;;
|
||||
if (NS_FAILED(rv = child->GetNameSpaceID(nameSpaceID))) break;
|
||||
if (nameSpaceID == kNameSpaceID_XUL)
|
||||
{
|
||||
nsCOMPtr<nsIAtom> tag;
|
||||
|
||||
if (NS_FAILED(rv = child->GetTag(*getter_AddRefs(tag))))
|
||||
return rv;
|
||||
nsString tagName;
|
||||
tag->ToString(tagName);
|
||||
printf("Child #%d: tagName='%s'\n", childIndex, tagName.ToNewCString());
|
||||
}
|
||||
else if (nameSpaceID != kNameSpaceID_XUL)
|
||||
// XXX is this the correct way to get text? Probably not...
|
||||
if (nameSpaceID != kNameSpaceID_XUL)
|
||||
{
|
||||
nsITextContent *text = nsnull;
|
||||
if (NS_SUCCEEDED(rv = child->QueryInterface(kITextContentIID, (void **)&text)))
|
||||
@ -426,13 +545,82 @@ XULSortServiceImpl::RemoveAllChildren(nsIContent *container)
|
||||
}
|
||||
|
||||
|
||||
|
||||
typedef struct _sortStruct {
|
||||
nsIRDFCompositeDataSource *db;
|
||||
nsIRDFResource *sortProperty;
|
||||
PRBool descendingSort;
|
||||
PRBool naturalOrderSort;
|
||||
} sortStruct, *sortPtr;
|
||||
|
||||
|
||||
|
||||
int openSortCallback(const void *data1, const void *data2, void *sortData);
|
||||
int inplaceSortCallback(const void *data1, const void *data2, void *sortData);
|
||||
|
||||
|
||||
|
||||
int
|
||||
openSortCallback(const void *data1, const void *data2, void *sortData)
|
||||
{
|
||||
int sortOrder = 0;
|
||||
nsresult rv;
|
||||
|
||||
nsIRDFNode *node1, *node2;
|
||||
node1 = *(nsIRDFNode **)data1;
|
||||
node2 = *(nsIRDFNode **)data2;
|
||||
_sortStruct *sortPtr = (_sortStruct *)sortData;
|
||||
|
||||
nsIRDFResource *res1;
|
||||
nsIRDFResource *res2;
|
||||
const PRUnichar *uniStr1 = nsnull;
|
||||
const PRUnichar *uniStr2 = nsnull;
|
||||
|
||||
if (NS_SUCCEEDED(node1->QueryInterface(kIRDFResourceIID, (void **) &res1)))
|
||||
{
|
||||
nsIRDFNode *nodeVal1;
|
||||
if (NS_SUCCEEDED(rv = sortPtr->db->GetTarget(res1, sortPtr->sortProperty, PR_TRUE, &nodeVal1)))
|
||||
{
|
||||
nsIRDFLiteral *literal1;
|
||||
if (NS_SUCCEEDED(nodeVal1->QueryInterface(kIRDFLiteralIID, (void **) &literal1)))
|
||||
{
|
||||
literal1->GetValue(&uniStr1);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (NS_SUCCEEDED(node2->QueryInterface(kIRDFResourceIID, (void **) &res2)))
|
||||
{
|
||||
nsIRDFNode *nodeVal2;
|
||||
if (NS_SUCCEEDED(rv = sortPtr->db->GetTarget(res2, sortPtr->sortProperty, PR_TRUE, &nodeVal2)))
|
||||
{
|
||||
nsIRDFLiteral *literal2;
|
||||
if (NS_SUCCEEDED(nodeVal2->QueryInterface(kIRDFLiteralIID, (void **) &literal2)))
|
||||
{
|
||||
literal2->GetValue(&uniStr2);
|
||||
}
|
||||
}
|
||||
}
|
||||
if ((uniStr1 != nsnull) && (uniStr2 != nsnull))
|
||||
{
|
||||
nsAutoString str1(uniStr1), str2(uniStr2);
|
||||
sortOrder = (int)str1.Compare(str2, PR_TRUE);
|
||||
if (sortPtr->descendingSort == PR_TRUE)
|
||||
{
|
||||
sortOrder = -sortOrder;
|
||||
}
|
||||
}
|
||||
else if ((uniStr1 != nsnull) && (uniStr2 == nsnull))
|
||||
{
|
||||
sortOrder = -1;
|
||||
}
|
||||
else
|
||||
{
|
||||
sortOrder = 1;
|
||||
}
|
||||
return(sortOrder);
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
inplaceSortCallback(const void *data1, const void *data2, void *sortData)
|
||||
{
|
||||
@ -452,14 +640,30 @@ inplaceSortCallback(const void *data1, const void *data2, void *sortData)
|
||||
return(sortOrder);
|
||||
}
|
||||
|
||||
|
||||
|
||||
nsresult
|
||||
XULSortServiceImpl::SortTreeChildren(nsIContent *container, PRInt32 colIndex, PRInt32 indentLevel)
|
||||
XULSortServiceImpl::SortTreeChildren(nsIContent *container, PRInt32 colIndex, nsString sortDirection, PRInt32 indentLevel)
|
||||
{
|
||||
PRInt32 childIndex = 0, numChildren = 0, nameSpaceID;
|
||||
nsCOMPtr<nsIContent> child;
|
||||
nsresult rv;
|
||||
nsVoidArray *childArray;
|
||||
|
||||
_sortStruct sortInfo;
|
||||
|
||||
if (sortDirection.Equals("natural"))
|
||||
{
|
||||
sortInfo.naturalOrderSort = PR_TRUE;
|
||||
sortInfo.descendingSort = PR_FALSE;
|
||||
}
|
||||
else
|
||||
{
|
||||
sortInfo.naturalOrderSort = PR_FALSE;;
|
||||
if (sortDirection.Equals("ascending")) sortInfo.descendingSort = PR_FALSE;
|
||||
else if (sortDirection.Equals("descending")) sortInfo.descendingSort = PR_TRUE;
|
||||
}
|
||||
|
||||
if (NS_FAILED(rv = container->ChildCount(numChildren))) return(rv);
|
||||
|
||||
if ((childArray = new nsVoidArray()) == nsnull) return (NS_ERROR_OUT_OF_MEMORY);
|
||||
@ -474,8 +678,9 @@ XULSortServiceImpl::SortTreeChildren(nsIContent *container, PRInt32 colIndex, PR
|
||||
if (NS_FAILED(rv = child->GetTag(*getter_AddRefs(tag)))) return rv;
|
||||
if (tag.get() == kTreeItemAtom)
|
||||
{
|
||||
PRBool found = PR_FALSE;
|
||||
nsIContent *cell;
|
||||
if (NS_SUCCEEDED(rv = GetTreeCell(child, colIndex, &cell)))
|
||||
if ((indentLevel == 0) && (NS_SUCCEEDED(rv = GetTreeCell(child, colIndex, &cell))))
|
||||
{
|
||||
if (cell)
|
||||
{
|
||||
@ -484,10 +689,54 @@ XULSortServiceImpl::SortTreeChildren(nsIContent *container, PRInt32 colIndex, PR
|
||||
{
|
||||
// hack: always append cell value 1st as
|
||||
// that's what sort callback expects
|
||||
|
||||
if (sortInfo.naturalOrderSort == PR_TRUE)
|
||||
{
|
||||
// ???????????????????
|
||||
|
||||
// XXX: note memory leak!
|
||||
childArray->AppendElement(val.ToNewCString());
|
||||
childArray->AppendElement(child);
|
||||
}
|
||||
else
|
||||
{
|
||||
// XXX: note memory leak!
|
||||
childArray->AppendElement(val.ToNewCString());
|
||||
childArray->AppendElement(child);
|
||||
}
|
||||
found = PR_TRUE;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (found == PR_FALSE)
|
||||
{
|
||||
// hack: always append cell value 1st as
|
||||
// that's what sort callback expects
|
||||
|
||||
PRBool foundValue = PR_FALSE;
|
||||
if (sortInfo.naturalOrderSort == PR_TRUE)
|
||||
{
|
||||
nsString pos;
|
||||
if (NS_OK == child->GetAttribute(kNameSpaceID_None, kNaturalOrderPosAtom, pos))
|
||||
{
|
||||
// XXX: note memory leak!
|
||||
childArray->AppendElement(pos.ToNewCString());
|
||||
childArray->AppendElement(child);
|
||||
foundValue = PR_TRUE;
|
||||
}
|
||||
}
|
||||
if (foundValue == PR_FALSE)
|
||||
{
|
||||
nsString name;
|
||||
if (NS_OK == child->GetAttribute(kNameSpaceID_None, kNameAtom, name))
|
||||
{
|
||||
// XXX: note memory leak!
|
||||
childArray->AppendElement(name.ToNewCString());
|
||||
childArray->AppendElement(child);
|
||||
foundValue = PR_TRUE;
|
||||
}
|
||||
}
|
||||
found = PR_TRUE;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -498,10 +747,6 @@ XULSortServiceImpl::SortTreeChildren(nsIContent *container, PRInt32 colIndex, PR
|
||||
nsIContent ** flatArray = new nsIContent*[numElements];
|
||||
if (flatArray)
|
||||
{
|
||||
_sortStruct sortInfo;
|
||||
|
||||
sortInfo.descendingSort = PR_TRUE;
|
||||
|
||||
// flatten array of resources, sort them, then add as tree elements
|
||||
unsigned long loop;
|
||||
for (loop=0; loop<numElements; loop++)
|
||||
@ -523,11 +768,82 @@ XULSortServiceImpl::SortTreeChildren(nsIContent *container, PRInt32 colIndex, PR
|
||||
{
|
||||
container->InsertChildAt((nsIContent *)flatArray[loop+1], numChildren++, PR_TRUE);
|
||||
}
|
||||
|
||||
// recurse on grandchildren
|
||||
|
||||
for (loop=0; loop<numElements; loop+=2)
|
||||
{
|
||||
container = (nsIContent *)flatArray[loop+1];
|
||||
|
||||
PRBool canHaveKids = PR_FALSE;
|
||||
if (NS_FAILED(rv = container->CanContainChildren(canHaveKids))) continue;
|
||||
if (canHaveKids == PR_FALSE) continue;
|
||||
|
||||
if (NS_FAILED(rv = container->ChildCount(numChildren))) continue;
|
||||
for (childIndex=0; childIndex<numChildren; childIndex++)
|
||||
{
|
||||
if (NS_FAILED(rv = container->ChildAt(childIndex, *getter_AddRefs(child))))
|
||||
continue;
|
||||
if (NS_FAILED(rv = child->GetNameSpaceID(nameSpaceID))) continue;
|
||||
if (nameSpaceID == kNameSpaceID_XUL)
|
||||
{
|
||||
nsCOMPtr<nsIAtom> tag;
|
||||
if (NS_FAILED(rv = child->GetTag(*getter_AddRefs(tag))))
|
||||
continue;
|
||||
if (tag.get() == kTreeChildrenAtom)
|
||||
{
|
||||
SortTreeChildren(child, colIndex, sortDirection, indentLevel+1);
|
||||
}
|
||||
}
|
||||
delete(childArray);
|
||||
return(rv);
|
||||
}
|
||||
}
|
||||
delete [] flatArray;
|
||||
flatArray = nsnull;
|
||||
}
|
||||
}
|
||||
return(NS_OK);
|
||||
}
|
||||
|
||||
|
||||
|
||||
NS_IMETHODIMP
|
||||
XULSortServiceImpl::OpenContainer(nsIRDFCompositeDataSource *db, nsIContent *container,
|
||||
nsIRDFResource **flatArray, PRInt32 numElements, PRInt32 elementSize)
|
||||
{
|
||||
nsresult rv;
|
||||
nsIContent *treeNode;
|
||||
nsString sortResource, sortDirection;
|
||||
_sortStruct sortInfo;
|
||||
|
||||
// get sorting info (property to sort on, direction to sort, etc)
|
||||
|
||||
if (NS_FAILED(rv = FindTreeElement(container, &treeNode))) return(rv);
|
||||
|
||||
sortInfo.db = db;
|
||||
if (NS_FAILED(rv = GetSortColumnInfo(treeNode, sortResource, sortDirection))) return(rv);
|
||||
char *uri = sortResource.ToNewCString();
|
||||
if (NS_FAILED(rv = gRDFService->GetResource(uri, &sortInfo.sortProperty))) return(rv);
|
||||
delete [] uri;
|
||||
if (sortDirection.Equals("natural"))
|
||||
{
|
||||
sortInfo.naturalOrderSort = PR_TRUE;
|
||||
sortInfo.descendingSort = PR_FALSE;
|
||||
// no need to sort for natural order
|
||||
}
|
||||
else
|
||||
{
|
||||
sortInfo.naturalOrderSort = PR_FALSE;
|
||||
if (sortDirection.Equals("descending"))
|
||||
sortInfo.descendingSort = PR_TRUE;
|
||||
else
|
||||
sortInfo.descendingSort = PR_FALSE;
|
||||
rdf_qsort((void *)flatArray, numElements, elementSize, openSortCallback, (void *)&sortInfo);
|
||||
}
|
||||
|
||||
return(NS_OK);
|
||||
}
|
||||
|
||||
|
||||
|
||||
nsresult
|
||||
XULSortServiceImpl::PrintTreeChildren(nsIContent *container, PRInt32 colIndex, PRInt32 indentLevel)
|
||||
@ -605,38 +921,22 @@ XULSortServiceImpl::PrintTreeChildren(nsIContent *container, PRInt32 colIndex, P
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
XULSortServiceImpl::DoSort(nsIDOMNode* node, const nsString& sortResource)
|
||||
XULSortServiceImpl::DoSort(nsIDOMNode* node, const nsString& sortResource,
|
||||
const nsString& sortDirection)
|
||||
{
|
||||
printf("XULSortServiceImpl::DoSort entered!!!\n");
|
||||
|
||||
PRInt32 childIndex, colIndex, numChildren, treeBodyIndex;
|
||||
nsIContent *child, *contentNode, *treeNode, *treeBody, *treeParent;
|
||||
PRInt32 colIndex, treeBodyIndex;
|
||||
nsIContent *contentNode, *treeNode, *treeBody, *treeParent;
|
||||
nsresult rv;
|
||||
|
||||
if (NS_FAILED(rv = node->QueryInterface(kIContentIID, (void**)&contentNode))) return(rv);
|
||||
printf("Success converting dom node to content node.\n");
|
||||
|
||||
if (NS_FAILED(rv = FindTreeElement(contentNode, &treeNode))) return(rv);
|
||||
printf("found tree element\n");
|
||||
|
||||
if (NS_FAILED(rv = GetSortColumnIndex(treeNode, sortResource, &colIndex))) return(rv);
|
||||
printf("Sort column index is %d.\n", (int)colIndex);
|
||||
|
||||
if (NS_FAILED(rv = GetSortColumnIndex(treeNode, sortResource, sortDirection, &colIndex))) return(rv);
|
||||
if (NS_FAILED(rv = FindTreeBodyElement(treeNode, &treeBody))) return(rv);
|
||||
printf("Found tree body.\n");
|
||||
|
||||
if (NS_FAILED(rv = treeBody->GetParent(treeParent))) return(rv);
|
||||
printf("Found tree parent.\n");
|
||||
|
||||
if (NS_FAILED(rv = treeParent->IndexOf(treeBody, treeBodyIndex))) return(rv);
|
||||
printf("Found index of tree body in tree parent.\n");
|
||||
|
||||
if (NS_FAILED(rv = treeParent->RemoveChildAt(treeBodyIndex, PR_TRUE))) return(rv);
|
||||
printf("Removed tree body from parent.\n");
|
||||
|
||||
if (NS_SUCCEEDED(rv = SortTreeChildren(treeBody, colIndex, 0)))
|
||||
if (NS_SUCCEEDED(rv = SortTreeChildren(treeBody, colIndex, sortDirection, 0)))
|
||||
{
|
||||
printf("Tree sorted.\n");
|
||||
}
|
||||
|
||||
if (NS_SUCCEEDED(rv = treeBody->UnsetAttribute(kNameSpaceID_None,
|
||||
@ -649,17 +949,18 @@ XULSortServiceImpl::DoSort(nsIDOMNode* node, const nsString& sortResource)
|
||||
}
|
||||
|
||||
if (NS_FAILED(rv = treeParent->AppendChildTo(treeBody, PR_TRUE))) return(rv);
|
||||
printf("Added tree body back into parent.\n");
|
||||
|
||||
#if 0
|
||||
if (NS_FAILED(rv = PrintTreeChildren(treeBody, colIndex, 0))) return(rv);
|
||||
printf("Tree printed.\nDone.\n");
|
||||
#endif
|
||||
return(NS_OK);
|
||||
}
|
||||
|
||||
|
||||
|
||||
nsresult
|
||||
NS_NewXULSortService(nsIXULSortService** mgr)
|
||||
{
|
||||
return XULSortServiceImpl::GetSortService(mgr);
|
||||
}
|
||||
|
||||
|
@ -8,19 +8,30 @@
|
||||
|
||||
<html:script>
|
||||
|
||||
function doSort(node)
|
||||
function doSort(sortColName)
|
||||
{
|
||||
var node = document.getElementById(sortColName);
|
||||
// determine column resource to sort on
|
||||
var sortResource = node.getAttribute('resource');
|
||||
if (!node) return(false);
|
||||
dump("Sort on '" + sortResource + "' column.\n");
|
||||
|
||||
var sortDirection="ascending";
|
||||
var isSortActive = node.getAttribute('sortActive');
|
||||
if (isSortActive == "true")
|
||||
{
|
||||
var currentDirection = node.getAttribute('sortDirection');
|
||||
if (currentDirection == "ascending")
|
||||
sortDirection = "descending";
|
||||
else if (currentDirection == "descending")
|
||||
sortDirection = "natural";
|
||||
else sortDirection = "ascending";
|
||||
}
|
||||
dump("Sort on '" + sortResource + "' column in '" + sortDirection + "' order.\n");
|
||||
|
||||
// get RDF Core service
|
||||
var rdfCore = XPAppCoresManager.Find("RDFCore");
|
||||
if (!rdfCore)
|
||||
{
|
||||
dump(" *** error: RDFCore not found.\n");
|
||||
|
||||
rdfCore = new RDFCore();
|
||||
if (!rdfCore)
|
||||
{
|
||||
@ -38,7 +49,7 @@ function doSort(node)
|
||||
|
||||
// sort!!!
|
||||
dump("About to sort...\n");
|
||||
rdfCore.doSort(node, sortResource, "ascending");
|
||||
rdfCore.doSort(node, sortResource, sortDirection);
|
||||
dump("Sort done.\n");
|
||||
|
||||
return(false);
|
||||
@ -47,15 +58,15 @@ function doSort(node)
|
||||
</html:script>
|
||||
|
||||
<xul:tree datasources="rdf:files rdf:bookmarks rdf:mail">
|
||||
<xul:treecol rdf:resource="http://home.netscape.com/NC-rdf#Name"/>
|
||||
<xul:treecol rdf:resource="http://home.netscape.com/NC-rdf#URL"/>
|
||||
<xul:treecol rdf:resource="http://home.netscape.com/WEB-rdf#LastModifiedDate"/>
|
||||
<xul:treecol id="NameColumn" rdf:resource="http://home.netscape.com/NC-rdf#Name"/>
|
||||
<xul:treecol id="URLColumn" rdf:resource="http://home.netscape.com/NC-rdf#URL"/>
|
||||
<xul:treecol id="LastModColumn" rdf:resource="http://home.netscape.com/WEB-rdf#LastModifiedDate"/>
|
||||
|
||||
<xul:treehead>
|
||||
<xul:treeitem>
|
||||
<xul:treecell resource='http://home.netscape.com/NC-rdf#Name' onclick="return doSort(this);">Name</xul:treecell>
|
||||
<xul:treecell resource='http://home.netscape.com/NC-rdf#URL' onclick="return doSort(this);">URL</xul:treecell>
|
||||
<xul:treecell resource='http://home.netscape.com/WEB-rdf#LastModifiedDate' onclick="return doSort(this);">Last Modified</xul:treecell>
|
||||
<xul:treecell resource='http://home.netscape.com/NC-rdf#Name' onclick="return doSort('NameColumn');">Name</xul:treecell>
|
||||
<xul:treecell resource='http://home.netscape.com/NC-rdf#URL' onclick="return doSort('URLColumn');">URL</xul:treecell>
|
||||
<xul:treecell resource='http://home.netscape.com/WEB-rdf#LastModifiedDate' onclick="return doSort('LastModColumn');">Last Modified</xul:treecell>
|
||||
</xul:treeitem>
|
||||
</xul:treehead>
|
||||
|
||||
|
@ -6,5 +6,5 @@ interface RDFCore : BaseAppCore
|
||||
|
||||
void RDFCore();
|
||||
|
||||
void doSort(in Node node, in DOMString sortResource);
|
||||
void doSort(in Node node, in DOMString sortResource, in DOMString sortDirection);
|
||||
};
|
||||
|
@ -35,17 +35,17 @@ class nsIDOMRDFCore : public nsIDOMBaseAppCore {
|
||||
public:
|
||||
static const nsIID& GetIID() { static nsIID iid = NS_IDOMRDFCORE_IID; return iid; }
|
||||
|
||||
NS_IMETHOD DoSort(nsIDOMNode* aNode, const nsString& aSortResource)=0;
|
||||
NS_IMETHOD DoSort(nsIDOMNode* aNode, const nsString& aSortResource, const nsString& aSortDirection)=0;
|
||||
};
|
||||
|
||||
|
||||
#define NS_DECL_IDOMRDFCORE \
|
||||
NS_IMETHOD DoSort(nsIDOMNode* aNode, const nsString& aSortResource); \
|
||||
NS_IMETHOD DoSort(nsIDOMNode* aNode, const nsString& aSortResource, const nsString& aSortDirection); \
|
||||
|
||||
|
||||
|
||||
#define NS_FORWARD_IDOMRDFCORE(_to) \
|
||||
NS_IMETHOD DoSort(nsIDOMNode* aNode, const nsString& aSortResource) { return _to##DoSort(aNode, aSortResource); } \
|
||||
NS_IMETHOD DoSort(nsIDOMNode* aNode, const nsString& aSortResource, const nsString& aSortDirection) { return _to##DoSort(aNode, aSortResource, aSortDirection); } \
|
||||
|
||||
|
||||
extern "C" NS_DOM nsresult NS_InitRDFCoreClass(nsIScriptContext *aContext, void **aPrototype);
|
||||
|
@ -140,6 +140,7 @@ RDFCoreDoSort(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval
|
||||
JSBool rBool = JS_FALSE;
|
||||
nsIDOMNodePtr b0;
|
||||
nsAutoString b1;
|
||||
nsAutoString b2;
|
||||
|
||||
*rval = JSVAL_NULL;
|
||||
|
||||
@ -148,7 +149,7 @@ RDFCoreDoSort(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval
|
||||
return JS_TRUE;
|
||||
}
|
||||
|
||||
if (argc >= 2) {
|
||||
if (argc >= 3) {
|
||||
|
||||
if (JS_FALSE == nsJSUtils::nsConvertJSValToObject((nsISupports **)&b0,
|
||||
kINodeIID,
|
||||
@ -160,14 +161,16 @@ RDFCoreDoSort(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval
|
||||
|
||||
nsJSUtils::nsConvertJSValToString(b1, cx, argv[1]);
|
||||
|
||||
if (NS_OK != nativeThis->DoSort(b0, b1)) {
|
||||
nsJSUtils::nsConvertJSValToString(b2, cx, argv[2]);
|
||||
|
||||
if (NS_OK != nativeThis->DoSort(b0, b1, b2)) {
|
||||
return JS_FALSE;
|
||||
}
|
||||
|
||||
*rval = JSVAL_VOID;
|
||||
}
|
||||
else {
|
||||
JS_ReportError(cx, "Function doSort requires 2 parameters");
|
||||
JS_ReportError(cx, "Function doSort requires 3 parameters");
|
||||
return JS_FALSE;
|
||||
}
|
||||
|
||||
@ -207,7 +210,7 @@ static JSPropertySpec RDFCoreProperties[] =
|
||||
//
|
||||
static JSFunctionSpec RDFCoreMethods[] =
|
||||
{
|
||||
{"doSort", RDFCoreDoSort, 2},
|
||||
{"doSort", RDFCoreDoSort, 3},
|
||||
{0}
|
||||
};
|
||||
|
||||
|
@ -132,7 +132,8 @@ nsRDFCore::Init(const nsString& aId)
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsRDFCore::DoSort(nsIDOMNode* node, const nsString& sortResource)
|
||||
nsRDFCore::DoSort(nsIDOMNode* node, const nsString& sortResource,
|
||||
const nsString &sortDirection)
|
||||
{
|
||||
printf(" ***** nsRDFCore::DoSort entered!!! *****\n");
|
||||
|
||||
@ -146,6 +147,7 @@ nsRDFCore::DoSort(nsIDOMNode* node, const nsString& sortResource)
|
||||
printf("-- Sort \n");
|
||||
printf("----------------------------\n");
|
||||
printf("Column: %s \n", sortResource.ToNewCString());
|
||||
printf("Direction: %s \n", sortDirection.ToNewCString());
|
||||
printf("----------------------------\n");
|
||||
|
||||
nsIXULSortService *gXULSortService = nsnull;
|
||||
@ -156,7 +158,7 @@ nsRDFCore::DoSort(nsIDOMNode* node, const nsString& sortResource)
|
||||
{
|
||||
printf("\n******** YES, we got kXULSortServiceCID\n\n");
|
||||
|
||||
gXULSortService->DoSort(node, sortResource);
|
||||
gXULSortService->DoSort(node, sortResource, sortDirection);
|
||||
nsServiceManager::ReleaseService(kXULSortServiceCID, gXULSortService);
|
||||
}
|
||||
else printf("\n******** unable to obtain kXULSortServiceCID\n\n");
|
||||
|
@ -49,7 +49,7 @@ class nsRDFCore : public nsBaseAppCore,
|
||||
NS_IMETHOD GetId(nsString& aId) { return nsBaseAppCore::GetId(aId); }
|
||||
NS_IMETHOD SetDocumentCharset(const nsString& aCharset) { return nsBaseAppCore::SetDocumentCharset(aCharset); }
|
||||
|
||||
NS_IMETHOD DoSort(nsIDOMNode* node, const nsString& sortResource);
|
||||
NS_IMETHOD DoSort(nsIDOMNode* node, const nsString& sortResource, const nsString& sortDirection);
|
||||
|
||||
protected:
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user