nsAutoString	pos; if (NS_FAILED(rv = child->GetAttribute(kNameSpaceID_None, kNaturalOrderPosAtom, pos)) || (rv != NS_CONTENT_ATTR_HAS_VALUE)) { nsAutoString	zero("0000"); pos = ""; pos.Append(childIndex+1, 10); if (pos.Length() < 4) { pos.Insert(zero, 0, 4-pos.Length()); } child->SetAttribute(kNameSpaceID_None, kNaturalOrderPosAtom, pos, PR_FALSE); }
XULSortServiceImpl::SortTreeChildren(nsIContent *container, PRInt32 colIndex, sortPtr sortInfo){	PRInt32			childIndex = 0, numChildren = 0, nameSpaceID;        nsCOMPtr<nsIContent>	child;	nsresult		rv;	if (NS_FAILED(rv = container->ChildCount(numChildren)))	return(rv);	nsCOMPtr<nsISupportsArray> childArray;	rv = NS_NewISupportsArray(getter_AddRefs(childArray));	if (NS_FAILED(rv))	return(rv);	for (childIndex=0; childIndex<numChildren; childIndex++)	{		if (NS_FAILED(rv = container->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;			if (tag.get() == kTreeItemAtom)			{				childArray->AppendElement(child);								// if no pos is specified, set one				nsAutoString	pos;				if (NS_FAILED(rv = child->GetAttribute(kNameSpaceID_None, kNaturalOrderPosAtom, pos))					|| (rv != NS_CONTENT_ATTR_HAS_VALUE))				{					nsAutoString	zero("0000");					pos = "";					pos.Append(childIndex+1, 10);					if (pos.Length() < 4)					{						pos.Insert(zero, 0, 4-pos.Length()); 					}					child->SetAttribute(kNameSpaceID_None, kNaturalOrderPosAtom, pos, PR_FALSE);				}			}		}	}	PRUint32 cnt = 0;	rv = childArray->Count(&cnt);	NS_ASSERTION(NS_SUCCEEDED(rv), "Count failed");	PRUint32 numElements = cnt;	if (numElements > 0)	{		nsIContent ** flatArray = new nsIContent*[numElements];		if (flatArray)		{			// flatten array of resources, sort them, then add as tree elements			PRUint32	loop;		        for (loop=0; loop<numElements; loop++)		        {				flatArray[loop] = (nsIContent *)childArray->ElementAt(loop);			}			/* smart sorting (sort within separators) on name column */			if (sortInfo->sortProperty.get() == kNC_Name)			{				PRUint32	startIndex=0;				for (loop=0; loop<numElements; loop++)				{					nsAutoString	type;					if (NS_SUCCEEDED(rv = flatArray[loop]->GetAttribute(kNameSpaceID_None, kRDF_type, type))						&& (rv == NS_CONTENT_ATTR_HAS_VALUE))					{						if (type.EqualsIgnoreCase(kURINC_BookmarkSeparator))						{							if (loop > startIndex+1)							{								NS_QuickSort((void *)&flatArray[startIndex], loop-startIndex, sizeof(nsIContent *),									inplaceSortCallback, (void *)sortInfo);								startIndex = loop+1;							}						}					}				}				if (loop > startIndex+1)				{					NS_QuickSort((void *)&flatArray[startIndex], loop-startIndex, sizeof(nsIContent *),						inplaceSortCallback, (void *)sortInfo);					startIndex = loop+1;				}			}			else			{				NS_QuickSort((void *)flatArray, numElements, sizeof(nsIContent *),					inplaceSortCallback, (void *)sortInfo);			}			// Bug 6665. This is a hack to "addref" the resources			// before we remove them from the content model. This			// keeps them from getting released, which causes			// performance problems for some datasources.			for (loop = 0; loop < numElements; loop++)			{				nsIRDFResource	*resource;				gXULUtils->GetElementResource(flatArray[loop], &resource);				// Note that we don't release; see part deux below...			}			RemoveAllChildren(container);						// insert sorted children						numChildren = 0;			for (loop=0; loop<numElements; loop++)			{				container->InsertChildAt((nsIContent *)flatArray[loop], numChildren++, PR_FALSE);			}			// Bug 6665, part deux. The Big Hack.			for (loop = 0; loop < numElements; loop++)			{				nsIRDFResource	*resource;				gXULUtils->GetElementResource(flatArray[loop], &resource);				nsrefcnt	refcnt;				NS_RELEASE2(resource, refcnt);				NS_RELEASE(resource);			}			// recurse on grandchildren			for (loop=0; loop<numElements; loop++)			{				container =  (nsIContent *)flatArray[loop];				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, sortInfo);						}					}				}			}			delete [] flatArray;			flatArray = nsnull;		}	}	rv = childArray->Count(&cnt);	if (NS_FAILED(rv)) return rv;	for (int i = cnt - 1; i >= 0; i--)	{		childArray->RemoveElementAt(i);	}	return(NS_OK);}