mulwidgets/muldatamodel/src/multree.cpp
author Pat Downey <patd@symbian.org>
Wed, 01 Sep 2010 12:23:18 +0100
branchRCL_3
changeset 26 0e9bb658ef58
parent 0 e83bab7cf002
permissions -rw-r--r--
Revert incorrect RCL_3 drop: Revision: 201033 Kit: 201035

/*
* Copyright (c) 2007-2008 Nokia Corporation and/or its subsidiary(-ies). 
* All rights reserved.
* This component and the accompanying materials are made available
* under the terms of "Eclipse Public License v1.0"
* which accompanies this distribution, and is available
* at the URL "http://www.eclipse.org/legal/epl-v10.html".
*
* Initial Contributors:
* Nokia Corporation - initial contribution.
*
* Contributors:
*
* Description:  MulTree Implementaiton
*
*/


#include "multree.h"

#include <stdexcept>

#include "mulassert.h"
#include "mulmodeldef.h"
#include "muldatapath.h"

namespace Alf
	{

// ============================ MEMBER FUNCTIONS ===============================

// -----------------------------------------------------------------------------
// AddNode
// -----------------------------------------------------------------------------
//
void MulTree::AddNode(const MulDataPath& aPath,int aIndex)
	{
	//Find parent node
	MulTreeNode* node = FindNode( aPath );
	
	//update index of other child
	for( int i = 0 ; i < node->ChildCount() ; i++ )
		{
		MulTreeNode* childNode = node->Child(i);
		int index = childNode->Index();
		if( childNode->Index() >= aIndex )
			{
			childNode->SetIndex( childNode->Index()+1 );
			}
		}	
	
	//insert node in to parent node
	std::auto_ptr<MulTreeNode> childNode( new (EMM) MulTreeNode(aIndex));
	node->InsertChild(childNode,aIndex);
	}

// -----------------------------------------------------------------------------
// RemoveNode
// -----------------------------------------------------------------------------
//
void MulTree::RemoveNode(const MulDataPath& aPath, int aIndex )
	{
	MulTreeNode* node = FindNode( aPath );
	node->RemoveChild(aIndex);
	
	//update index of other child
	for( int i = 0 ; i < node->ChildCount() ; i++ )
		{
		MulTreeNode* childNode = node->Child(i);
		int index = childNode->Index();
		if( childNode->Index() > aIndex )
			{
			childNode->SetIndex( childNode->Index()-1 );
			}
		}	
	}

// -----------------------------------------------------------------------------
// FindNode
// -----------------------------------------------------------------------------
//
MulTreeNode* MulTree::FindNode( const MulDataPath& aPath ) const
	{	
	MulTreeNode* currentNode = mRootNode.get();
	for( int i = 0; i < aPath.Depth() ;i++ )
		{
		int index = aPath[i];
		if( currentNode->HasChild() )
			{
			currentNode = FindChildNode( currentNode,index);
			}
		else
			{
			__MUL_ASSERT_DEBUG( false , KLInvalidArgument );
			}
		}
	return currentNode;
	}

// -----------------------------------------------------------------------------
// FindNode
// -----------------------------------------------------------------------------
//
MulTreeNode* MulTree::FindChildNode(MulTreeNode* aParentNode,int aIndex) const
	{
	MulTreeNode* currentNode = aParentNode;
	MulTreeNode* foundNode = NULL;
	int index = 0; 
	bool found(false);
	int childCount = currentNode->ChildCount();
	while( !found && index < childCount )
		{	
		MulTreeNode* childNode = currentNode->Child(index);
		if( aIndex == childNode->Index() )
			{
			found = true;
			foundNode = childNode;
			}
		index++;
		}
		
	if( found == false )
		{
		__MUL_ASSERT_DEBUG( false , KLInvalidArgument );
		}
		
	return foundNode;
	}

// -----------------------------------------------------------------------------
// FindNode
// -----------------------------------------------------------------------------
//
MulDataPath MulTree::FindNode( int aIndex ) const
	{	
	int absoluteIndex = -1;
	return FindNode( mRootNode.get(), absoluteIndex, aIndex );	
	}

// -----------------------------------------------------------------------------
// FindNode
// -----------------------------------------------------------------------------
//
MulDataPath MulTree::FindNode( MulTreeNode* aNode, int& aAbsoluteIndex, int aIndex ) const
	{	
	MulTreeNode* currentNode = aNode;
	if( currentNode->HasChild() )
		{
		for(int i = 0 ; i < currentNode->ChildCount() ; i++ )
			{
			aAbsoluteIndex++;
			MulTreeNode* childNode = currentNode->Child(i);
			
#ifdef _DEBUG
			bool hasChild = childNode->HasChild();
			int count = childNode->ChildCount();
			bool isExpanded = childNode->IsExpanded();
#endif //_DEBUG
			
			if( aAbsoluteIndex == aIndex )
				{
				MulDataPath path= Path(*childNode);
				path.SetIndex(i);
				return path;
				}
			 else if( childNode->HasChild() && childNode->IsExpanded() )
				{
				MulDataPath path = FindNode( childNode, aAbsoluteIndex , aIndex );
				if(path.Index() != KNotInitialized )
					{
					return path;
					}
				}			
			}
		}
	//__MUL_ASSERT_DEBUG( false , KLInvalidArgument );
	MulDataPath path;
	path.SetIndex(KNotInitialized);
	return path; 
	}

// -----------------------------------------------------------------------------
// Path
// -----------------------------------------------------------------------------
//
MulDataPath MulTree::Path(MulTreeNode& aNode) const
	{
	MulTreeNode* parentNode = aNode.Parent();
	std::vector<int> pathArray;
	while( parentNode && parentNode != mRootNode.get() )
		{
		int index = parentNode->Index();
		pathArray.push_back( parentNode->Index() );
		parentNode = parentNode->Parent();
		}
	
	int count = pathArray.size();
	
	MulDataPath path;
	for( int i= pathArray.size()- 1 ; i >=0 ; i-- )
		{
		path.Append( pathArray[i] );
		}
	pathArray.clear();
	return path;
	}

// -----------------------------------------------------------------------------
// NodeCount
// -----------------------------------------------------------------------------
//
int MulTree::NodeCount() const
	{
	int nodeCount =NodeCount( mRootNode.get() );
	return nodeCount;
	}

// -----------------------------------------------------------------------------
// NodeCount
// -----------------------------------------------------------------------------
//
int MulTree::NodeCount(MulTreeNode* aCurrentNode ) const
	{
	int nodeCount = 0;
	if(aCurrentNode->HasChild())
		{
		nodeCount = aCurrentNode->ChildCount();
		for(int i=0;i< aCurrentNode->ChildCount();i++)
			{
			nodeCount+= NodeCount(aCurrentNode->Child(i));
			}
		}
	return nodeCount;
	}

// -----------------------------------------------------------------------------
// ExpandedNodeCount
// -----------------------------------------------------------------------------
//
int MulTree::ExpandedNodeCount() const
	{
	int nodeCount = ExpandedNodeCount( mRootNode.get() );
	return nodeCount;
	}

// -----------------------------------------------------------------------------
// ExpandedNodeCount
// -----------------------------------------------------------------------------
//
int MulTree::ExpandedNodeCount(MulTreeNode* aCurrentNode ) const
	{
	int nodeCount = 0;
	if( aCurrentNode->HasChild() && aCurrentNode->IsExpanded() )
		{
		nodeCount = aCurrentNode->ChildCount();
		for( int i=0; i< aCurrentNode->ChildCount() ; i++ )
			{
			nodeCount+= ExpandedNodeCount( aCurrentNode->Child(i) );
			}
		}
	return nodeCount;
	}

// -----------------------------------------------------------------------------
// NodeIndex
// -----------------------------------------------------------------------------
//
int MulTree::NodeIndex( const MulDataPath& aPath, int aIndex ) const
	{
	MulDataPath path( aPath );
	path.SetIndex( aIndex );
	
	int absoluteIndex = -1;
	int index = NodeIndex( mRootNode.get(), path, absoluteIndex );
	
	return index;
	}

// -----------------------------------------------------------------------------
// NodeIndex
// -----------------------------------------------------------------------------
//
int MulTree::NodeIndex( MulTreeNode* aCurrentNode, const MulDataPath& aPath, int& aAbsoluteIndex ) const
	{	
	MulTreeNode* currentNode = aCurrentNode;
	if( currentNode->HasChild() )
		{
		for(int i = 0 ; i < currentNode->ChildCount() ; i++ )
			{
			aAbsoluteIndex++;
			MulTreeNode* childNode = currentNode->Child(i);
			
#ifdef _DEBUG
			bool hasChild = childNode->HasChild();
			int count = childNode->ChildCount();
			bool isExpanded = childNode->IsExpanded();
#endif //_DEBUG
			
			MulDataPath path = Path(*childNode);
			path.SetIndex(i);
			
			if( path.IsEqual(aPath) )
				{
				return aAbsoluteIndex;
				}
			 else if( childNode->HasChild() && childNode->IsExpanded() )
				{
				int index = NodeIndex( childNode, aPath, aAbsoluteIndex );
				if( index != KNotInitialized )
					{
					return index;
					}
				}			
			}
		}
	return KNotInitialized; 
	}
		
	} //namespace Alf
	
	//End of file