/**************************************************************
 * 
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 * 
 *   http://www.apache.org/licenses/LICENSE-2.0
 * 
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied.  See the License for the
 * specific language governing permissions and limitations
 * under the License.
 * 
 *************************************************************/



// MARKER(update_precomp.py): autogen include statement, do not remove
#include "precompiled_svtools.hxx"

#define _SVTREEBX_CXX
#include <tools/debug.hxx>
#include <com/sun/star/lang/XServiceInfo.hpp>
#include <com/sun/star/lang/DisposedException.hpp>
#include <com/sun/star/view/SelectionType.hpp>
#include <toolkit/helper/property.hxx>
#include <toolkit/helper/vclunohelper.hxx>

#include <com/sun/star/awt/tree/XMutableTreeNode.hpp>
#include <treecontrolpeer.hxx>
#include <comphelper/processfactory.hxx>

#include <rtl/ref.hxx>
#include <vcl/graph.hxx>
#include <svtools/svtreebx.hxx>

#include <map>

using ::rtl::OUString;
using namespace ::com::sun::star;
using namespace ::com::sun::star::uno;
using namespace ::com::sun::star::lang;
using namespace ::com::sun::star::awt::tree;
using namespace ::com::sun::star::beans;
using namespace ::com::sun::star::view;
using namespace ::com::sun::star::container;
using namespace ::com::sun::star::util;
using namespace ::com::sun::star::graphic;

#define O(x) OUString( RTL_CONSTASCII_USTRINGPARAM(x) )

struct LockGuard
{
public:
	LockGuard( sal_Int32& rLock )
	: mrLock( rLock )
	{
		rLock++;
	}

	~LockGuard()
	{
		mrLock--;
	}

	sal_Int32& mrLock;
};

// --------------------------------------------------------------------

class ImplGraphicItem : public SvLBoxBmp
{
public:
	ImplGraphicItem( SvLBoxEntry* pEntry, sal_uInt16 nFlags, Image& aImage ) : SvLBoxBmp( pEntry, nFlags, aImage ) {}

	OUString msGraphicURL;
};

// --------------------------------------------------------------------

class ImplContextGraphicItem : public SvLBoxContextBmp
{
public:
	ImplContextGraphicItem( SvLBoxEntry* pEntry,sal_uInt16 nFlags,Image& rI1,Image& rI2, sal_uInt16 nEntryFlagsBmp1)
		: SvLBoxContextBmp( pEntry, nFlags, rI1, rI2, nEntryFlagsBmp1 ) {}

	OUString msExpandedGraphicURL;
	OUString msCollapsedGraphicURL;
};

// --------------------------------------------------------------------

class UnoTreeListBoxImpl : public SvTreeListBox
{
public:
	UnoTreeListBoxImpl( TreeControlPeer* pPeer, Window* pParent, WinBits nWinStyle );
	~UnoTreeListBoxImpl();

	sal_uInt32 insert( SvLBoxEntry* pEntry,SvLBoxEntry* pParent,sal_uLong nPos=LIST_APPEND );

	virtual void	RequestingChilds( SvLBoxEntry* pParent );

	virtual sal_Bool	EditingEntry( SvLBoxEntry* pEntry, Selection& );
	virtual sal_Bool	EditedEntry( SvLBoxEntry* pEntry, const XubString& rNewText );

	DECL_LINK( OnSelectionChangeHdl, UnoTreeListBoxImpl* );
	DECL_LINK( OnExpandingHdl, UnoTreeListBoxImpl* );
	DECL_LINK( OnExpandedHdl, UnoTreeListBoxImpl* );

private:
	rtl::Reference< TreeControlPeer > mxPeer;
};

// --------------------------------------------------------------------

class SVT_DLLPUBLIC UnoTreeListItem : public SvLBoxItem
{
public:
					UnoTreeListItem( SvLBoxEntry* );
					UnoTreeListItem();
	virtual			~UnoTreeListItem();
	virtual sal_uInt16	IsA();
	void			InitViewData( SvLBox*,SvLBoxEntry*,SvViewDataItem* );
	OUString		GetText() const;
	void 			SetText( const OUString& rText );
	Image			GetImage() const;
	void			SetImage( const Image& rImage );
	OUString		GetGraphicURL() const;
	void			SetGraphicURL( const OUString& rGraphicURL );
	void			Paint( const Point&, SvLBox& rDev, sal_uInt16 nFlags,SvLBoxEntry* );
	SvLBoxItem* 	Create() const;
	void 			Clone( SvLBoxItem* pSource );

private:
	OUString		maText;
	OUString		maGraphicURL;
	Image			maImage;
};

// --------------------------------------------------------------------

class UnoTreeListEntry : public SvLBoxEntry
{
public:
	UnoTreeListEntry( const Reference< XTreeNode >& xNode, TreeControlPeer* pPeer );
	virtual ~UnoTreeListEntry();

	Reference< XTreeNode > mxNode;
	TreeControlPeer* mpPeer;
};

// --------------------------------------------------------------------

class TreeNodeMap : public std::map< Reference< XTreeNode >, UnoTreeListEntry* >
{
};

// --------------------------------------------------------------------

TreeControlPeer::TreeControlPeer()
: maSelectionListeners( *this )
, maTreeExpansionListeners( *this )
, maTreeEditListeners( *this )
, mpTreeImpl( 0 )
, mnEditLock( 0 )
, mpTreeNodeMap( 0 )
{
}

// --------------------------------------------------------------------

TreeControlPeer::~TreeControlPeer()
{
	if( mpTreeImpl )
		mpTreeImpl->Clear();
	delete mpTreeNodeMap;
}

// --------------------------------------------------------------------

void TreeControlPeer::addEntry( UnoTreeListEntry* pEntry )
{
	if( pEntry && pEntry->mxNode.is() )
	{
		if( !mpTreeNodeMap )
		{
			mpTreeNodeMap = new TreeNodeMap();
		}

		(*mpTreeNodeMap)[ pEntry->mxNode ] = pEntry;
	}
}

// --------------------------------------------------------------------

void TreeControlPeer::removeEntry( UnoTreeListEntry* pEntry )
{
	if( mpTreeNodeMap && pEntry && pEntry->mxNode.is() )
	{
		TreeNodeMap::iterator aIter( mpTreeNodeMap->find( pEntry->mxNode ) );
		if( aIter != mpTreeNodeMap->end() )
        {
			mpTreeNodeMap->erase( aIter );
        }
	}
}

// --------------------------------------------------------------------

UnoTreeListEntry* TreeControlPeer::getEntry( const Reference< XTreeNode >& xNode, bool bThrow /* = true */ ) throw( IllegalArgumentException )
{
	if( mpTreeNodeMap )
	{
		TreeNodeMap::iterator aIter( mpTreeNodeMap->find( xNode ) );
		if( aIter != mpTreeNodeMap->end() )
			return (*aIter).second;
	}

	if( bThrow )
		throw IllegalArgumentException();

	return 0;
}

// --------------------------------------------------------------------

Window* TreeControlPeer::createVclControl( Window* pParent, sal_Int64 nWinStyle )
{
	mpTreeImpl = new UnoTreeListBoxImpl( this, pParent, nWinStyle );
	return mpTreeImpl;
}

// --------------------------------------------------------------------

/** called from the UnoTreeListBoxImpl when it gets deleted */
void TreeControlPeer::disposeControl()
{
	delete mpTreeNodeMap;
	mpTreeNodeMap = 0;
	mpTreeImpl = 0;
}

// --------------------------------------------------------------------

void TreeControlPeer::SetWindow( Window* pWindow )
{
	VCLXWindow::SetWindow( pWindow );
}

// --------------------------------------------------------------------

UnoTreeListEntry* TreeControlPeer::createEntry( const Reference< XTreeNode >& xNode, UnoTreeListEntry* pParent, sal_uLong nPos /* = LIST_APPEND */ )
{
	UnoTreeListEntry* pEntry = 0;
	if( mpTreeImpl )
	{
		Image aImage;
		pEntry = new UnoTreeListEntry( xNode, this );
		ImplContextGraphicItem* pContextBmp= new ImplContextGraphicItem( pEntry,0, aImage, aImage, SVLISTENTRYFLAG_EXPANDED );

		pEntry->AddItem( pContextBmp );

		UnoTreeListItem * pUnoItem = new UnoTreeListItem( pEntry );

		if( xNode->getNodeGraphicURL().getLength() )
		{
			pUnoItem->SetGraphicURL( xNode->getNodeGraphicURL() );
			Image aNodeImage;
			loadImage( xNode->getNodeGraphicURL(), aNodeImage );
			pUnoItem->SetImage( aNodeImage );
			mpTreeImpl->AdjustEntryHeight( aNodeImage );
		}

		pEntry->AddItem( pUnoItem );

		mpTreeImpl->insert( pEntry, pParent, nPos );

        if( msDefaultExpandedGraphicURL.getLength() )
			mpTreeImpl->SetExpandedEntryBmp( pEntry, maDefaultExpandedImage );

		if( msDefaultCollapsedGraphicURL.getLength() )
			mpTreeImpl->SetCollapsedEntryBmp( pEntry, maDefaultCollapsedImage );

		updateEntry( pEntry );
	}
	return pEntry;
}

// --------------------------------------------------------------------

bool TreeControlPeer::updateEntry( UnoTreeListEntry* pEntry )
{
	bool bChanged = false;
	if( pEntry && pEntry->mxNode.is() && mpTreeImpl )
	{
		const OUString aValue( getEntryString( pEntry->mxNode->getDisplayValue() ) );
		UnoTreeListItem* pUnoItem = dynamic_cast< UnoTreeListItem* >( pEntry->GetItem( 1 ) );
		if( pUnoItem )
		{
			if( aValue != pUnoItem->GetText() )
			{
				pUnoItem->SetText( aValue );
				bChanged = true;
			}

			if( pUnoItem->GetGraphicURL() != pEntry->mxNode->getNodeGraphicURL() )
			{
				Image aImage;
				if( loadImage( pEntry->mxNode->getNodeGraphicURL(), aImage ) )
				{
					pUnoItem->SetGraphicURL( pEntry->mxNode->getNodeGraphicURL() );
					pUnoItem->SetImage( aImage );
					mpTreeImpl->AdjustEntryHeight( aImage );
					bChanged = true;
				}
			}
		}

		if( (pEntry->mxNode->hasChildrenOnDemand() == sal_True) != (pEntry->HasChildsOnDemand() == sal_True) )
		{
			pEntry->EnableChildsOnDemand( pEntry->mxNode->hasChildrenOnDemand() ? sal_True : sal_False );
			bChanged = true;
		}

		ImplContextGraphicItem* pContextGraphicItem = dynamic_cast< ImplContextGraphicItem* >( pEntry->GetItem( 0 ) );
		if( pContextGraphicItem )
		{
			if( pContextGraphicItem->msExpandedGraphicURL != pEntry->mxNode->getExpandedGraphicURL() )
			{
				Image aImage;
				if(	loadImage( pEntry->mxNode->getExpandedGraphicURL(), aImage ) )
				{
					pContextGraphicItem->msExpandedGraphicURL = pEntry->mxNode->getExpandedGraphicURL();
					mpTreeImpl->SetExpandedEntryBmp( pEntry, aImage );
					bChanged = true;
				}
			}
			if( pContextGraphicItem->msCollapsedGraphicURL != pEntry->mxNode->getCollapsedGraphicURL() )
			{
				Image aImage;
				if(	loadImage( pEntry->mxNode->getCollapsedGraphicURL(), aImage ) )
				{
					pContextGraphicItem->msCollapsedGraphicURL = pEntry->mxNode->getCollapsedGraphicURL();
					mpTreeImpl->SetCollapsedEntryBmp( pEntry, aImage );
					bChanged = true;
				}
			}
		}

		if( bChanged )
			mpTreeImpl->GetModel()->InvalidateEntry( pEntry );
	}

	return bChanged;
}

// --------------------------------------------------------------------

void TreeControlPeer::onSelectionChanged()
{
	Reference< XInterface > xSource( static_cast< ::cppu::OWeakObject* >( this ) );
	EventObject aEvent( xSource );
	maSelectionListeners.selectionChanged( aEvent );
}

// --------------------------------------------------------------------

void TreeControlPeer::onRequestChildNodes( const Reference< XTreeNode >& xNode )
{
	try
	{
		Reference< XInterface > xSource( static_cast< ::cppu::OWeakObject* >( this ) );
		TreeExpansionEvent aEvent( xSource, xNode );
		maTreeExpansionListeners.requestChildNodes( aEvent );
	}
	catch( Exception& )
	{
	}
}

// --------------------------------------------------------------------

bool TreeControlPeer::onExpanding( const Reference< XTreeNode >& xNode, bool bExpanding )
{
	try
	{
		Reference< XInterface > xSource( static_cast< ::cppu::OWeakObject* >( this ) );
		TreeExpansionEvent aEvent( xSource, xNode );
		if( bExpanding )
		{
			maTreeExpansionListeners.treeExpanding( aEvent );
		}
		else
		{
			maTreeExpansionListeners.treeCollapsing( aEvent );
		}
	}
	catch( Exception& )
	{
		return false;
	}
	return true;
}

// --------------------------------------------------------------------

void TreeControlPeer::onExpanded( const Reference< XTreeNode >& xNode, bool bExpanding )
{
	try
	{
		Reference< XInterface > xSource( static_cast< ::cppu::OWeakObject* >( this ) );
		TreeExpansionEvent aEvent( xSource, xNode );

		if( bExpanding )
		{
			maTreeExpansionListeners.treeExpanded( aEvent );
		}
		else
		{
			maTreeExpansionListeners.treeCollapsed( aEvent );
		}
	}
	catch( Exception& )
	{
	}
}

// --------------------------------------------------------------------

void TreeControlPeer::fillTree( UnoTreeListBoxImpl& rTree, const Reference< XTreeDataModel >& xDataModel )
{
	rTree.Clear();

	if( xDataModel.is() )
	{
		Reference< XTreeNode > xRootNode( xDataModel->getRoot() );
		if( xRootNode.is() )
		{
			if( mbIsRootDisplayed )
			{
				addNode( rTree, xRootNode, 0 );
			}
			else
			{
				const sal_Int32 nChildCount = xRootNode->getChildCount();
				for( sal_Int32 nChild = 0; nChild < nChildCount; nChild++ )
					addNode( rTree, xRootNode->getChildAt( nChild ), 0 );
			}
		}
	}
}

// --------------------------------------------------------------------

void TreeControlPeer::addNode( UnoTreeListBoxImpl& rTree, const Reference< XTreeNode >& xNode, UnoTreeListEntry* pParentEntry )
{
	if( xNode.is() )
	{
		UnoTreeListEntry* pEntry = createEntry( xNode, pParentEntry, LIST_APPEND );
		const sal_Int32 nChildCount = xNode->getChildCount();
		for( sal_Int32 nChild = 0; nChild < nChildCount; nChild++ )
			addNode( rTree, xNode->getChildAt( nChild ), pEntry );
	}
}

// --------------------------------------------------------------------

UnoTreeListBoxImpl& TreeControlPeer::getTreeListBoxOrThrow() const throw (RuntimeException )
{
	if( !mpTreeImpl )
		throw DisposedException();
	return *mpTreeImpl;
}

// --------------------------------------------------------------------

void TreeControlPeer::ChangeNodesSelection( const Any& rSelection, bool bSelect, bool bSetSelection ) throw( RuntimeException, IllegalArgumentException )
{
	::vos::OGuard aGuard( GetMutex() );

	UnoTreeListBoxImpl& rTree = getTreeListBoxOrThrow();

	Reference< XTreeNode > xTempNode;
	Sequence< XTreeNode > aTempSeq;

	const Reference< XTreeNode > *pNodes = 0;
	sal_Int32 nCount = 0;

	if( rSelection.hasValue() )
	{
		switch( rSelection.getValueTypeClass() )
		{
		case TypeClass_INTERFACE:
			{
				rSelection >>= xTempNode;
				if( xTempNode.is() )
				{
					nCount = 1;
					pNodes = &xTempNode;
				}
				break;
			}
		case TypeClass_SEQUENCE:
			{
				if( rSelection.getValueType() == ::getCppuType( (const Sequence< Reference< XTreeNode > > *) 0 ) )
				{
					const Sequence< Reference< XTreeNode > >& rSeq( *(const Sequence< Reference< XTreeNode > > *)rSelection.getValue() );
					nCount = rSeq.getLength();
					if( nCount )
						pNodes = rSeq.getConstArray();
				}
				break;
			}
		default:
			break;
		}

		if( nCount == 0 )
			throw IllegalArgumentException();
	}

	if( bSetSelection )
		rTree.SelectAll( sal_False );

	if( pNodes && nCount )
	{
		while( nCount-- )
		{
			UnoTreeListEntry* pEntry = getEntry( *pNodes++ );
			rTree.Select( pEntry, bSelect ? sal_True : sal_False );
		}
	}
}

// -------------------------------------------------------------------
// ::com::sun::star::view::XSelectionSupplier
// -------------------------------------------------------------------

sal_Bool SAL_CALL TreeControlPeer::select( const Any& rSelection ) throw (IllegalArgumentException, RuntimeException)
{
	::vos::OGuard aGuard( GetMutex() );
	ChangeNodesSelection( rSelection, true, true );
	return sal_True;
}

// -------------------------------------------------------------------

Any SAL_CALL TreeControlPeer::getSelection() throw (RuntimeException)
{
	::vos::OGuard aGuard( GetMutex() );

	UnoTreeListBoxImpl& rTree = getTreeListBoxOrThrow();

	Any aRet;

	sal_uLong nSelectionCount = rTree.GetSelectionCount();
	if( nSelectionCount == 1 )
	{
		UnoTreeListEntry* pEntry = dynamic_cast< UnoTreeListEntry* >( rTree.FirstSelected() );
		if( pEntry && pEntry->mxNode.is() )
			aRet <<= pEntry->mxNode;
	}
	else if( nSelectionCount > 1 )
	{
		Sequence< Reference< XTreeNode > > aSelection( nSelectionCount );
		Reference< XTreeNode >* pNodes = aSelection.getArray();
		UnoTreeListEntry* pEntry = dynamic_cast< UnoTreeListEntry* >( rTree.FirstSelected() );
		while( pEntry && nSelectionCount )
		{
			*pNodes++ = pEntry->mxNode;
			pEntry = dynamic_cast< UnoTreeListEntry* >( rTree.NextSelected( pEntry ) );
			--nSelectionCount;
		}

		OSL_ASSERT( (pEntry == 0) && (nSelectionCount == 0) );
		aRet <<= aSelection;
	}

	return aRet;
}

// -------------------------------------------------------------------

void SAL_CALL TreeControlPeer::addSelectionChangeListener( const Reference< XSelectionChangeListener >& xListener ) throw (RuntimeException)
{
	maSelectionListeners.addInterface( xListener );
}

// -------------------------------------------------------------------

void SAL_CALL TreeControlPeer::removeSelectionChangeListener( const Reference< XSelectionChangeListener >& xListener ) throw (RuntimeException)
{
	maSelectionListeners.addInterface( xListener );
}

// -------------------------------------------------------------------
// ::com::sun::star::view::XMultiSelectionSupplier
// -------------------------------------------------------------------

sal_Bool SAL_CALL TreeControlPeer::addSelection( const Any& rSelection ) throw (IllegalArgumentException, RuntimeException)
{
	ChangeNodesSelection( rSelection, true, false );
	return sal_True;
}

// -------------------------------------------------------------------

void SAL_CALL TreeControlPeer::removeSelection( const Any& rSelection ) throw (IllegalArgumentException, RuntimeException)
{
	ChangeNodesSelection( rSelection, false, false );
}

// -------------------------------------------------------------------

void SAL_CALL TreeControlPeer::clearSelection() throw (RuntimeException)
{
	::vos::OGuard aGuard( GetMutex() );
	getTreeListBoxOrThrow().SelectAll( sal_False );
}

// -------------------------------------------------------------------

sal_Int32 SAL_CALL TreeControlPeer::getSelectionCount() throw (RuntimeException)
{
	::vos::OGuard aGuard( GetMutex() );
	return getTreeListBoxOrThrow().GetSelectionCount();
}

// -------------------------------------------------------------------

class TreeSelectionEnumeration : public ::cppu::WeakImplHelper1< XEnumeration >
{
public:
	TreeSelectionEnumeration( std::list< Any >& rSelection );
    virtual ::sal_Bool SAL_CALL hasMoreElements() throw (RuntimeException);
    virtual Any SAL_CALL nextElement() throw (NoSuchElementException, WrappedTargetException, RuntimeException);

	std::list< Any > maSelection;
	std::list< Any >::iterator maIter;
};

// -------------------------------------------------------------------

TreeSelectionEnumeration::TreeSelectionEnumeration( std::list< Any >& rSelection )
{
	maSelection.swap( rSelection );
	maIter = maSelection.begin();
}

// -------------------------------------------------------------------

::sal_Bool SAL_CALL TreeSelectionEnumeration::hasMoreElements() throw (RuntimeException)
{
	return maIter != maSelection.end();
}

// -------------------------------------------------------------------

Any SAL_CALL TreeSelectionEnumeration::nextElement() throw (NoSuchElementException, WrappedTargetException, RuntimeException)
{
	if( maIter == maSelection.end() )
		throw NoSuchElementException();

	return (*maIter++);
}

// -------------------------------------------------------------------

Reference< XEnumeration > SAL_CALL TreeControlPeer::createSelectionEnumeration() throw (RuntimeException)
{
	::vos::OGuard aGuard( GetMutex() );

	UnoTreeListBoxImpl& rTree = getTreeListBoxOrThrow();
	
	sal_uInt32 nSelectionCount = rTree.GetSelectionCount();
	std::list< Any > aSelection( nSelectionCount );

	UnoTreeListEntry* pEntry = dynamic_cast< UnoTreeListEntry* >( rTree.FirstSelected() );
	while( pEntry && nSelectionCount )
	{
		aSelection.push_back( Any( pEntry->mxNode ) );
		pEntry = dynamic_cast< UnoTreeListEntry* >( rTree.NextSelected( pEntry ) );
		--nSelectionCount;
	}

	OSL_ASSERT( (pEntry == 0) && (nSelectionCount == 0) );

	return Reference< XEnumeration >( new TreeSelectionEnumeration( aSelection ) );
}

// -------------------------------------------------------------------

Reference< XEnumeration > SAL_CALL TreeControlPeer::createReverseSelectionEnumeration() throw (RuntimeException)
{
	::vos::OGuard aGuard( GetMutex() );

	UnoTreeListBoxImpl& rTree = getTreeListBoxOrThrow();
	
	sal_uInt32 nSelectionCount = rTree.GetSelectionCount();
	std::list< Any > aSelection;

	UnoTreeListEntry* pEntry = dynamic_cast< UnoTreeListEntry* >( rTree.FirstSelected() );
	while( pEntry && nSelectionCount )
	{
		aSelection.push_front( Any( pEntry->mxNode ) );
		pEntry = dynamic_cast< UnoTreeListEntry* >( rTree.NextSelected( pEntry ) );
		--nSelectionCount;
	}

	OSL_ASSERT( (pEntry == 0) && (nSelectionCount == 0) );

	return Reference< XEnumeration >( new TreeSelectionEnumeration( aSelection ) );
}

// --------------------------------------------------------------------
// ::com::sun::star::awt::XTreeControl
// --------------------------------------------------------------------

OUString SAL_CALL TreeControlPeer::getDefaultExpandedGraphicURL() throw (::com::sun::star::uno::RuntimeException)
{
	::vos::OGuard aGuard( GetMutex() );
	return msDefaultExpandedGraphicURL;
}

// --------------------------------------------------------------------

void SAL_CALL TreeControlPeer::setDefaultExpandedGraphicURL( const ::rtl::OUString& sDefaultExpandedGraphicURL ) throw (::com::sun::star::uno::RuntimeException)
{
	::vos::OGuard aGuard( GetMutex() );
	if( msDefaultExpandedGraphicURL != sDefaultExpandedGraphicURL )
	{
		if( sDefaultExpandedGraphicURL.getLength() )
			loadImage( sDefaultExpandedGraphicURL, maDefaultExpandedImage );
		else
			maDefaultExpandedImage = Image();

		UnoTreeListBoxImpl& rTree = getTreeListBoxOrThrow();

		SvLBoxEntry* pEntry = rTree.First();
		while( pEntry )
		{
			ImplContextGraphicItem* pContextGraphicItem = dynamic_cast< ImplContextGraphicItem* >( pEntry->GetItem( 0 ) );
			if( pContextGraphicItem )
			{
				if( pContextGraphicItem->msExpandedGraphicURL.getLength() == 0 )
					rTree.SetExpandedEntryBmp( pEntry, maDefaultExpandedImage );
			}
			pEntry = rTree.Next( pEntry );
		}

		msDefaultExpandedGraphicURL = sDefaultExpandedGraphicURL;
	}
}

// --------------------------------------------------------------------

OUString SAL_CALL TreeControlPeer::getDefaultCollapsedGraphicURL() throw (::com::sun::star::uno::RuntimeException)
{
	::vos::OGuard aGuard( GetMutex() );
	return msDefaultCollapsedGraphicURL;
}

// --------------------------------------------------------------------

void SAL_CALL TreeControlPeer::setDefaultCollapsedGraphicURL( const ::rtl::OUString& sDefaultCollapsedGraphicURL ) throw (::com::sun::star::uno::RuntimeException)
{
	::vos::OGuard aGuard( GetMutex() );
	if( msDefaultCollapsedGraphicURL != sDefaultCollapsedGraphicURL )
	{
		if( sDefaultCollapsedGraphicURL.getLength() )
			loadImage( sDefaultCollapsedGraphicURL, maDefaultCollapsedImage );
		else
			maDefaultCollapsedImage = Image();

		UnoTreeListBoxImpl& rTree = getTreeListBoxOrThrow();

		SvLBoxEntry* pEntry = rTree.First();
		while( pEntry )
		{
			ImplContextGraphicItem* pContextGraphicItem = dynamic_cast< ImplContextGraphicItem* >( pEntry->GetItem( 0 ) );
			if( pContextGraphicItem )
			{
				if( pContextGraphicItem->msCollapsedGraphicURL.getLength() == 0 )
					rTree.SetCollapsedEntryBmp( pEntry, maDefaultCollapsedImage );
			}
			pEntry = rTree.Next( pEntry );
		}

		msDefaultCollapsedGraphicURL = sDefaultCollapsedGraphicURL;
	}
}

// --------------------------------------------------------------------

sal_Bool SAL_CALL TreeControlPeer::isNodeExpanded( const Reference< XTreeNode >& xNode ) throw (RuntimeException, IllegalArgumentException)
{
	::vos::OGuard aGuard( GetMutex() );

	UnoTreeListBoxImpl& rTree = getTreeListBoxOrThrow();
	UnoTreeListEntry* pEntry = getEntry( xNode );
	return ( pEntry && rTree.IsExpanded( pEntry ) ) ? sal_True : sal_False;
}

// -------------------------------------------------------------------

sal_Bool SAL_CALL TreeControlPeer::isNodeCollapsed( const Reference< XTreeNode >& xNode ) throw (RuntimeException, IllegalArgumentException)
{
	::vos::OGuard aGuard( GetMutex() );
	return !isNodeExpanded( xNode );
}

// -------------------------------------------------------------------

void SAL_CALL TreeControlPeer::makeNodeVisible( const Reference< XTreeNode >& xNode ) throw (RuntimeException, ExpandVetoException, IllegalArgumentException)
{
	::vos::OGuard aGuard( GetMutex() );

	UnoTreeListBoxImpl& rTree = getTreeListBoxOrThrow();
	UnoTreeListEntry* pEntry = getEntry( xNode );
	if( pEntry )
		rTree.MakeVisible( pEntry );
}

// -------------------------------------------------------------------

sal_Bool SAL_CALL TreeControlPeer::isNodeVisible( const Reference< XTreeNode >& xNode ) throw (RuntimeException, IllegalArgumentException)
{
	::vos::OGuard aGuard( GetMutex() );

	UnoTreeListBoxImpl& rTree = getTreeListBoxOrThrow();
	UnoTreeListEntry* pEntry = getEntry( xNode );
	return ( pEntry && rTree.IsEntryVisible( pEntry ) ) ? sal_True : sal_False;
}

// -------------------------------------------------------------------

void SAL_CALL TreeControlPeer::expandNode( const Reference< XTreeNode >& xNode ) throw (RuntimeException, ExpandVetoException, IllegalArgumentException)
{
	::vos::OGuard aGuard( GetMutex() );

	UnoTreeListBoxImpl& rTree = getTreeListBoxOrThrow();
	UnoTreeListEntry* pEntry = getEntry( xNode );
	if( pEntry )
		rTree.Expand( pEntry );
}

// -------------------------------------------------------------------

void SAL_CALL TreeControlPeer::collapseNode( const Reference< XTreeNode >& xNode ) throw (RuntimeException, ExpandVetoException, IllegalArgumentException)
{
	::vos::OGuard aGuard( GetMutex() );

	UnoTreeListBoxImpl& rTree = getTreeListBoxOrThrow();
	UnoTreeListEntry* pEntry = getEntry( xNode );
	if( pEntry )
		rTree.Collapse( pEntry );
}

// -------------------------------------------------------------------

void SAL_CALL TreeControlPeer::addTreeExpansionListener( const Reference< XTreeExpansionListener >& xListener ) throw (RuntimeException)
{
	maTreeExpansionListeners.addInterface( xListener );
}

// -------------------------------------------------------------------

void SAL_CALL TreeControlPeer::removeTreeExpansionListener( const Reference< XTreeExpansionListener >& xListener ) throw (RuntimeException)
{
	maTreeExpansionListeners.removeInterface( xListener );
}

// -------------------------------------------------------------------

Reference< XTreeNode > SAL_CALL TreeControlPeer::getNodeForLocation( sal_Int32 x, sal_Int32 y ) throw (RuntimeException)
{
	::vos::OGuard aGuard( GetMutex() );

	UnoTreeListBoxImpl& rTree = getTreeListBoxOrThrow();

	Reference< XTreeNode > xNode;

	const Point aPos( x, y );
	UnoTreeListEntry* pEntry = dynamic_cast< UnoTreeListEntry* >( rTree.GetEntry( aPos, sal_True ) );
	if( pEntry )
		xNode = pEntry->mxNode;

	return xNode;
}

// -------------------------------------------------------------------

Reference< XTreeNode > SAL_CALL TreeControlPeer::getClosestNodeForLocation( sal_Int32 x, sal_Int32 y ) throw (RuntimeException)
{
	::vos::OGuard aGuard( GetMutex() );

	UnoTreeListBoxImpl& rTree = getTreeListBoxOrThrow();

	Reference< XTreeNode > xNode;

	const Point aPos( x, y );
	UnoTreeListEntry* pEntry = dynamic_cast< UnoTreeListEntry* >( rTree.GetEntry( aPos, sal_True ) );
	if( pEntry )
		xNode = pEntry->mxNode;

	return xNode;
}

// -------------------------------------------------------------------

awt::Rectangle SAL_CALL TreeControlPeer::getNodeRect( const Reference< XTreeNode >& i_Node ) throw (IllegalArgumentException, RuntimeException)
{
	::vos::OGuard aGuard( GetMutex() );

	UnoTreeListBoxImpl& rTree = getTreeListBoxOrThrow();
	UnoTreeListEntry* pEntry = getEntry( i_Node, true );

    ::Rectangle aEntryRect( rTree.GetFocusRect( pEntry, rTree.GetEntryPosition( pEntry ).Y() ) );
    return VCLUnoHelper::ConvertToAWTRect( aEntryRect );
}

// -------------------------------------------------------------------

sal_Bool SAL_CALL TreeControlPeer::isEditing(  ) throw (RuntimeException)
{
	::vos::OGuard aGuard( GetMutex() );

	UnoTreeListBoxImpl& rTree = getTreeListBoxOrThrow();
	return rTree.IsEditingActive() ? sal_True : sal_False;
}

// -------------------------------------------------------------------

sal_Bool SAL_CALL TreeControlPeer::stopEditing() throw (RuntimeException)
{
	::vos::OGuard aGuard( GetMutex() );

	UnoTreeListBoxImpl& rTree = getTreeListBoxOrThrow();
	if( rTree.IsEditingActive() )
	{
		rTree.EndEditing(sal_False);
		return sal_True;
	}
	else
	{
		return sal_False;
	}
}

// -------------------------------------------------------------------

void SAL_CALL TreeControlPeer::cancelEditing(  ) throw (RuntimeException)
{
	::vos::OGuard aGuard( GetMutex() );

	UnoTreeListBoxImpl& rTree = getTreeListBoxOrThrow();
	rTree.EndEditing(sal_False);
}

// -------------------------------------------------------------------

void SAL_CALL TreeControlPeer::startEditingAtNode( const Reference< XTreeNode >& xNode ) throw (IllegalArgumentException, RuntimeException)
{
	::vos::OGuard aGuard( GetMutex() );

	UnoTreeListBoxImpl& rTree = getTreeListBoxOrThrow();
	UnoTreeListEntry* pEntry = getEntry( xNode );
	rTree.EditEntry( pEntry );
}

void SAL_CALL TreeControlPeer::addTreeEditListener( const Reference< XTreeEditListener >& xListener ) throw (RuntimeException)
{
	maTreeEditListeners.addInterface( xListener );
}

void SAL_CALL TreeControlPeer::removeTreeEditListener( const Reference< XTreeEditListener >& xListener ) throw (RuntimeException)
{
	maTreeEditListeners.removeInterface( xListener );
}

bool TreeControlPeer::onEditingEntry( UnoTreeListEntry* pEntry )
{
	if( mpTreeImpl && pEntry && pEntry->mxNode.is() && (maTreeEditListeners.getLength() > 0)  )
	{
		try
		{
			maTreeEditListeners.nodeEditing( pEntry->mxNode );
		}
		catch( VetoException& )
		{
			return false;
		}
		catch( Exception& )
		{
		}
	}
	return true;
}

bool TreeControlPeer::onEditedEntry( UnoTreeListEntry* pEntry, const XubString& rNewText )
{
	if( mpTreeImpl && pEntry && pEntry->mxNode.is() ) try
	{
		LockGuard aLockGuard( mnEditLock );
		const OUString aNewText( rNewText );
		if( maTreeEditListeners.getLength() > 0 )
		{
			maTreeEditListeners.nodeEdited( pEntry->mxNode, aNewText );
			return false;
		}
		else
		{
			Reference< XMutableTreeNode > xMutableNode( pEntry->mxNode, UNO_QUERY );
			if( xMutableNode.is() )
				xMutableNode->setDisplayValue( Any( aNewText ) );
			else
				return false;
		}

	}
	catch( Exception& )
	{
	}

	return true;
}

// --------------------------------------------------------------------
// ::com::sun::star::awt::tree::TreeDataModelListener
// --------------------------------------------------------------------

void SAL_CALL TreeControlPeer::treeNodesChanged( const ::com::sun::star::awt::tree::TreeDataModelEvent& rEvent ) throw (RuntimeException)
{
	::vos::OGuard aGuard( GetMutex() );

	if( mnEditLock != 0 )
		return;

	updateTree( rEvent, true );
}

void SAL_CALL TreeControlPeer::treeNodesInserted( const ::com::sun::star::awt::tree::TreeDataModelEvent& rEvent ) throw (RuntimeException)
{
	::vos::OGuard aGuard( GetMutex() );

	if( mnEditLock != 0 )
		return;

	updateTree( rEvent, true );
}

void SAL_CALL TreeControlPeer::treeNodesRemoved( const ::com::sun::star::awt::tree::TreeDataModelEvent& rEvent ) throw (RuntimeException)
{
	::vos::OGuard aGuard( GetMutex() );

	if( mnEditLock != 0 )
		return;

	updateTree( rEvent, true );
}

void SAL_CALL TreeControlPeer::treeStructureChanged( const ::com::sun::star::awt::tree::TreeDataModelEvent& rEvent ) throw (RuntimeException)
{
	::vos::OGuard aGuard( GetMutex() );

	if( mnEditLock != 0 )
		return;

	updateTree( rEvent, true );
}

void TreeControlPeer::updateTree( const ::com::sun::star::awt::tree::TreeDataModelEvent& rEvent, bool bRecursive )
{
	UnoTreeListBoxImpl& rTree = getTreeListBoxOrThrow();

	Sequence< Reference< XTreeNode > > Nodes;
	Reference< XTreeNode > xNode( rEvent.ParentNode );
	if( !xNode.is() && Nodes.getLength() )
	{
		xNode = Nodes[0];
	}

	if( xNode.is() )
		updateNode( rTree, xNode, bRecursive );
}

void TreeControlPeer::updateNode( UnoTreeListBoxImpl& rTree, const Reference< XTreeNode >& xNode, bool bRecursive )
{
	if( xNode.is() )
	{
		UnoTreeListEntry* pNodeEntry = getEntry( xNode, false );

		if( !pNodeEntry )
		{
			Reference< XTreeNode > xParentNode( xNode->getParent() );
			UnoTreeListEntry* pParentEntry = 0;
			sal_uLong nChild = LIST_APPEND;
			
			if( xParentNode.is() )
			{
				pParentEntry = getEntry( xParentNode  );
				nChild = xParentNode->getIndex( xNode );
			}

			pNodeEntry = createEntry( xNode, pParentEntry, nChild );
		}

		if( bRecursive )
			updateChildNodes( rTree, xNode, pNodeEntry );
	}
}

void TreeControlPeer::updateChildNodes( UnoTreeListBoxImpl& rTree, const Reference< XTreeNode >& xParentNode, UnoTreeListEntry* pParentEntry )
{
	if( xParentNode.is() && pParentEntry )
	{
		UnoTreeListEntry* pCurrentChild = dynamic_cast< UnoTreeListEntry* >( rTree.FirstChild( pParentEntry ) );

		const sal_Int32 nChildCount = xParentNode->getChildCount();
		for( sal_Int32 nChild = 0; nChild < nChildCount; nChild++ )
		{
			Reference< XTreeNode > xNode( xParentNode->getChildAt( nChild ) );
			if( !pCurrentChild || ( pCurrentChild->mxNode != xNode ) )
			{
				UnoTreeListEntry* pNodeEntry = getEntry( xNode, false );
				if( pNodeEntry == 0 )
				{
					// child node is not yet part of the tree, add it
					pCurrentChild = createEntry( xNode, pParentEntry, nChild );
				}
				else if( pNodeEntry != pCurrentChild )
				{
					// node is already part of the tree, but not on the correct position
					rTree.GetModel()->Move( pNodeEntry, pParentEntry, nChild );
					pCurrentChild = pNodeEntry;
					updateEntry( pCurrentChild );
				}
			}
			else
			{
				// child node has entry and entry is equal to current entry,
				// so no structural changes happened
				updateEntry( pCurrentChild );
			}

			pCurrentChild = dynamic_cast< UnoTreeListEntry* >( rTree.NextSibling( pCurrentChild ) );
		}

		// check if we have entries without nodes left, we need to remove them
		while( pCurrentChild )
		{
			UnoTreeListEntry* pNextChild = dynamic_cast< UnoTreeListEntry* >( rTree.NextSibling( pCurrentChild ) );
			rTree.GetModel()->Remove( pCurrentChild );
			pCurrentChild = pNextChild;
		}
	}
}

OUString TreeControlPeer::getEntryString( const Any& rValue )
{
	OUString sValue;
	if( rValue.hasValue() )
	{
		switch( rValue.getValueTypeClass() )
		{
		case TypeClass_SHORT:
		case TypeClass_LONG:
			{
				sal_Int32 nValue = 0;
				if( rValue >>= nValue )
					sValue = OUString::valueOf( nValue );
				break;
			}
		case TypeClass_BYTE:
		case TypeClass_UNSIGNED_SHORT:
		case TypeClass_UNSIGNED_LONG:
			{
				sal_uInt32 nValue = 0;
				if( rValue >>= nValue )
					sValue = OUString::valueOf( (sal_Int64)nValue );
				break;
			}
		case TypeClass_HYPER:
			{
				sal_Int64 nValue = 0;
				if( rValue >>= nValue )
					sValue = OUString::valueOf( nValue );
				break;
			}
		case TypeClass_UNSIGNED_HYPER:
			{
				sal_uInt64 nValue = 0;
				if( rValue >>= nValue )
					sValue = OUString::valueOf( (sal_Int64)nValue );
				break;
			}
		case TypeClass_FLOAT:
		case TypeClass_DOUBLE:
			{
				double fValue = 0.0;
				if( rValue >>= fValue )
					sValue = OUString::valueOf( fValue );
				break;
			}
		case TypeClass_STRING:
			rValue >>= sValue;
			break;
	/*
		case TypeClass_INTERFACE:
			// @todo
			break;
		case TypeClass_SEQUENCE:
			{
				Sequence< Any > aValues;
				if( aValue >>= aValues )
				{
					updateEntry( SvLBoxEntry& rEntry, aValues );
					return;
				}
			}
			break;
	*/
		default:
			break;
		}
	}
	return sValue;
}

// XEventListener
void SAL_CALL TreeControlPeer::disposing( const ::com::sun::star::lang::EventObject& ) throw(::com::sun::star::uno::RuntimeException)
{
	// model is disposed, so we clear our tree
	::vos::OGuard aGuard( GetMutex() );
	UnoTreeListBoxImpl& rTree = getTreeListBoxOrThrow();
	rTree.Clear();
	mxDataModel.clear();
}

void TreeControlPeer::onChangeDataModel( UnoTreeListBoxImpl& rTree, const Reference< XTreeDataModel >& xDataModel )
{
	if( xDataModel.is() && (mxDataModel == xDataModel) )
		return; // do nothing

	Reference< XTreeDataModelListener > xListener( this );

	if( mxDataModel.is() )
		mxDataModel->removeTreeDataModelListener( xListener );

	if( !xDataModel.is() )
	{
		static const OUString aSN( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.awt.tree.DefaultTreeDataModel" ) );
		Reference< XMultiServiceFactory > xORB( ::comphelper::getProcessServiceFactory() );
		if( xORB.is() )
		{
			mxDataModel.query( xORB->createInstance( aSN ) );
		}
	}

	mxDataModel = xDataModel;

	fillTree( rTree, mxDataModel );

	if( mxDataModel.is() )
		mxDataModel->addTreeDataModelListener( xListener );
}

// --------------------------------------------------------------------
// ::com::sun::star::awt::XLayoutConstrains
// --------------------------------------------------------------------

::com::sun::star::awt::Size TreeControlPeer::getMinimumSize() throw(RuntimeException)
{
	::vos::OGuard aGuard( GetMutex() );

	::com::sun::star::awt::Size aSz;
/* todo
	MultiLineEdit* pEdit = (MultiLineEdit*) GetWindow();
	if ( pEdit )
		aSz = AWTSize(pEdit->CalcMinimumSize());
*/
	return aSz;
}

::com::sun::star::awt::Size TreeControlPeer::getPreferredSize() throw(RuntimeException)
{
	return getMinimumSize();
}

::com::sun::star::awt::Size TreeControlPeer::calcAdjustedSize( const ::com::sun::star::awt::Size& rNewSize ) throw(RuntimeException)
{
	::vos::OGuard aGuard( GetMutex() );

	::com::sun::star::awt::Size aSz = rNewSize;
/* todo
	MultiLineEdit* pEdit = (MultiLineEdit*) GetWindow();
	if ( pEdit )
		aSz = AWTSize(pEdit->CalcAdjustedSize( VCLSize(rNewSize )));
*/
	return aSz;
}

// --------------------------------------------------------------------
// ::com::sun::star::awt::XVclWindowPeer
// --------------------------------------------------------------------

void TreeControlPeer::setProperty( const ::rtl::OUString& PropertyName, const Any& aValue) throw(RuntimeException)
{
	::vos::OGuard aGuard( GetMutex() );

	UnoTreeListBoxImpl& rTree = getTreeListBoxOrThrow();

	switch( GetPropertyId( PropertyName ) )
	{
        case BASEPROPERTY_HIDEINACTIVESELECTION:
        {
            sal_Bool bEnabled = sal_False;
            if ( aValue >>= bEnabled )
            {
                WinBits nStyle = rTree.GetStyle();
                if ( bEnabled )
                    nStyle |= WB_HIDESELECTION;
                else
                    nStyle &= ~WB_HIDESELECTION;
                rTree.SetStyle( nStyle );
            }
        }
        break;

		case BASEPROPERTY_TREE_SELECTIONTYPE:
		{
			SelectionType eSelectionType;
			if( aValue >>= eSelectionType )
			{
				SelectionMode eSelMode;
				switch( eSelectionType )
				{
				case SelectionType_SINGLE:	eSelMode = SINGLE_SELECTION; break;
				case SelectionType_RANGE:	eSelMode = RANGE_SELECTION; break;
				case SelectionType_MULTI:	eSelMode = MULTIPLE_SELECTION; break;
	//			case SelectionType_NONE:		
				default:					eSelMode = NO_SELECTION; break;
				}
				if( rTree.GetSelectionMode() != eSelMode )
					rTree.SetSelectionMode( eSelMode );
			}
			break;
		}

		case BASEPROPERTY_TREE_DATAMODEL:			
			onChangeDataModel( rTree, Reference< XTreeDataModel >( aValue, UNO_QUERY ) );
			break;
		case BASEPROPERTY_ROW_HEIGHT:
		{
			sal_Int32 nHeight = 0;
			if( aValue >>= nHeight )
				rTree.SetEntryHeight( (short)nHeight );
			break;
		}
		case BASEPROPERTY_TREE_EDITABLE:
		{
			sal_Bool bEnabled = false;
			if( aValue >>= bEnabled )
				rTree.EnableInplaceEditing( bEnabled ? sal_True : sal_False );
			break;
		}
		case BASEPROPERTY_TREE_INVOKESSTOPNODEEDITING:
			break; // @todo
		case BASEPROPERTY_TREE_ROOTDISPLAYED:
        {
			sal_Bool bDisplayed = false;
			if( (aValue >>= bDisplayed) && ( bDisplayed != mbIsRootDisplayed) )
			{
				onChangeRootDisplayed(bDisplayed);
			}
			break;
        }
		case BASEPROPERTY_TREE_SHOWSHANDLES:
		{
			sal_Bool bEnabled = false;
			if( aValue >>= bEnabled )
			{
				WinBits nBits = rTree.GetStyle() & (~WB_HASLINES);
				if( bEnabled )
					nBits |= WB_HASLINES;
				if( nBits != rTree.GetStyle() )
					rTree.SetStyle( nBits );
			}
			break;
		}
		case BASEPROPERTY_TREE_SHOWSROOTHANDLES:
		{
			sal_Bool bEnabled = false;
			if( aValue >>= bEnabled )
			{
				WinBits nBits = rTree.GetStyle() & (~WB_HASLINESATROOT);
				if( bEnabled )
					nBits |= WB_HASLINESATROOT;
				if( nBits != rTree.GetStyle() )
					rTree.SetStyle( nBits );
			}
			break;
		}
		default:
		VCLXWindow::setProperty( PropertyName, aValue );
		break;
	}
}

Any TreeControlPeer::getProperty( const ::rtl::OUString& PropertyName ) throw(RuntimeException)
{
	::vos::OGuard aGuard( GetMutex() );

	const sal_uInt16 nPropId = GetPropertyId( PropertyName );
	if( (nPropId >= BASEPROPERTY_TREE_START) && (nPropId <= BASEPROPERTY_TREE_END) )
	{
		UnoTreeListBoxImpl& rTree = getTreeListBoxOrThrow();
		switch(nPropId)
		{
        case BASEPROPERTY_HIDEINACTIVESELECTION:
			return Any( ( rTree.GetStyle() & WB_HIDESELECTION ) != 0 ? sal_True : sal_False );

		case BASEPROPERTY_TREE_SELECTIONTYPE:
		{
			SelectionType eSelectionType;

			SelectionMode eSelMode = rTree.GetSelectionMode();
			switch( eSelMode )
			{
			case SINGLE_SELECTION:	eSelectionType = SelectionType_SINGLE; break;
			case RANGE_SELECTION:	eSelectionType = SelectionType_RANGE; break;
			case MULTIPLE_SELECTION:eSelectionType = SelectionType_MULTI; break;
//			case NO_SELECTION:		
			default:				eSelectionType = SelectionType_NONE; break;
			}
			return Any( eSelectionType );
		}
		case BASEPROPERTY_ROW_HEIGHT:
			return Any( (sal_Int32)rTree.GetEntryHeight() );
		case BASEPROPERTY_TREE_DATAMODEL:
			return Any( mxDataModel );
		case BASEPROPERTY_TREE_EDITABLE:
			return Any( rTree.IsInplaceEditingEnabled() ? sal_True : sal_False );
		case BASEPROPERTY_TREE_INVOKESSTOPNODEEDITING:
			return Any( sal_True ); // @todo
		case BASEPROPERTY_TREE_ROOTDISPLAYED:
			return Any( mbIsRootDisplayed );
		case BASEPROPERTY_TREE_SHOWSHANDLES:
			return Any( (rTree.GetStyle() & WB_HASLINES) != 0 ? sal_True : sal_False );
		case BASEPROPERTY_TREE_SHOWSROOTHANDLES:
			return Any( (rTree.GetStyle() & WB_HASLINESATROOT) != 0 ? sal_True : sal_False );
		}
	}
	return VCLXWindow::getProperty( PropertyName );
}

void TreeControlPeer::onChangeRootDisplayed( sal_Bool bIsRootDisplayed )
{
	if( mbIsRootDisplayed == bIsRootDisplayed )
		return;

	mbIsRootDisplayed = bIsRootDisplayed;

	UnoTreeListBoxImpl& rTree = getTreeListBoxOrThrow();

	if( rTree.GetEntryCount() == 0 )
		return;

	// todo
	fillTree( rTree, mxDataModel );
	if( mbIsRootDisplayed )
	{
	}
	else
	{
	}
}

bool TreeControlPeer::loadImage( const ::rtl::OUString& rURL, Image& rImage )
{
	if( !mxGraphicProvider.is() )
	{
		static const OUString aSN( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.graphic.GraphicProvider" ) );
		Reference< XMultiServiceFactory > xORB( ::comphelper::getProcessServiceFactory() );
		if( xORB.is() )
		{
			Reference< XInterface > x( xORB->createInstance( aSN ) );
			mxGraphicProvider.query( x );
			mxGraphicProvider = Reference< XGraphicProvider >( x, UNO_QUERY );
		}
	}

	if( mxGraphicProvider.is() ) try
	{
		::com::sun::star::beans::PropertyValues aProps( 1 );
		aProps[0].Name = OUString( RTL_CONSTASCII_USTRINGPARAM( "URL" ) );
		aProps[0].Value <<= rURL;

		Reference< XGraphic > xGraphic( mxGraphicProvider->queryGraphic( aProps ) );

		Graphic aGraphic( xGraphic );
		rImage = aGraphic.GetBitmapEx();
		return true;
	}
	catch( Exception& )
	{
	}

	return false;
}

// ====================================================================
// class UnoTreeListBoxImpl
// ====================================================================

UnoTreeListBoxImpl::UnoTreeListBoxImpl( TreeControlPeer* pPeer, Window* pParent, WinBits nWinStyle )
: SvTreeListBox( pParent, nWinStyle )
, mxPeer( pPeer )
{
	SetStyle( WB_BORDER | WB_HASLINES |WB_HASBUTTONS | WB_HASLINESATROOT | WB_HASBUTTONSATROOT | WB_HSCROLL );
	SetNodeDefaultImages();
	SetSelectHdl( LINK(this, UnoTreeListBoxImpl, OnSelectionChangeHdl) );
	SetDeselectHdl( LINK(this, UnoTreeListBoxImpl, OnSelectionChangeHdl) );

	SetExpandingHdl( LINK(this, UnoTreeListBoxImpl, OnExpandingHdl) );
	SetExpandedHdl( LINK(this, UnoTreeListBoxImpl, OnExpandedHdl) );

}

// --------------------------------------------------------------------

UnoTreeListBoxImpl::~UnoTreeListBoxImpl()
{
	if( mxPeer.is() )
		mxPeer->disposeControl();
}

// --------------------------------------------------------------------

IMPL_LINK( UnoTreeListBoxImpl, OnSelectionChangeHdl, UnoTreeListBoxImpl*, EMPTYARG )
{
	if( mxPeer.is() )
		mxPeer->onSelectionChanged();
	return 0;
}

// --------------------------------------------------------------------

IMPL_LINK(UnoTreeListBoxImpl, OnExpandingHdl, UnoTreeListBoxImpl*, EMPTYARG )
{
	UnoTreeListEntry* pEntry = dynamic_cast< UnoTreeListEntry* >( GetHdlEntry() );

	if( pEntry && mxPeer.is() )
	{
		return mxPeer->onExpanding( pEntry->mxNode, !IsExpanded( pEntry ) ) ? 1 : 0;
	}
	return 0;
}

// --------------------------------------------------------------------

IMPL_LINK(UnoTreeListBoxImpl, OnExpandedHdl, UnoTreeListBoxImpl*, EMPTYARG )
{
	UnoTreeListEntry* pEntry = dynamic_cast< UnoTreeListEntry* >( GetHdlEntry() );
	if( pEntry && mxPeer.is() )
	{
		mxPeer->onExpanded( pEntry->mxNode, IsExpanded( pEntry ) );
	}
	return 0;
}

// --------------------------------------------------------------------

sal_uInt32 UnoTreeListBoxImpl::insert( SvLBoxEntry* pEntry,SvLBoxEntry* pParent,sal_uLong nPos )
{
	if( pParent )
		return SvTreeListBox::Insert( pEntry, pParent, nPos );
	else
		return SvTreeListBox::Insert( pEntry, nPos );
}

// --------------------------------------------------------------------

void UnoTreeListBoxImpl::RequestingChilds( SvLBoxEntry* pParent )
{
	UnoTreeListEntry* pEntry = dynamic_cast< UnoTreeListEntry* >( pParent );
	if( pEntry && pEntry->mxNode.is() && mxPeer.is() )
		mxPeer->onRequestChildNodes( pEntry->mxNode );
}

// --------------------------------------------------------------------

sal_Bool UnoTreeListBoxImpl::EditingEntry( SvLBoxEntry* pEntry, Selection& )
{
	return mxPeer.is() ? mxPeer->onEditingEntry( dynamic_cast< UnoTreeListEntry* >( pEntry ) ) : false;
}

// --------------------------------------------------------------------

sal_Bool UnoTreeListBoxImpl::EditedEntry( SvLBoxEntry* pEntry, const XubString& rNewText )
{
	return mxPeer.is() ? mxPeer->onEditedEntry( dynamic_cast< UnoTreeListEntry* >( pEntry ), rNewText ) : false;
}

// ====================================================================
// class UnoTreeListItem
// ====================================================================

UnoTreeListItem::UnoTreeListItem( SvLBoxEntry* pEntry )
: SvLBoxItem( pEntry, 0 )
{
}

// --------------------------------------------------------------------

UnoTreeListItem::UnoTreeListItem()
: SvLBoxItem()
{
}

// --------------------------------------------------------------------

UnoTreeListItem::~UnoTreeListItem()
{
}

// --------------------------------------------------------------------

sal_uInt16 UnoTreeListItem::IsA()
{
	return SV_ITEM_ID_LBOXSTRING;
}

// --------------------------------------------------------------------

void UnoTreeListItem::Paint( const Point& rPos, SvLBox& rDev, sal_uInt16 /* nFlags */, SvLBoxEntry* _pEntry)
{
	Point aPos( rPos );
	if( _pEntry )
	{
		Size aSize( GetSize(&rDev,_pEntry) );
		if( !!maImage )
		{
			rDev.DrawImage( aPos, maImage, rDev.IsEnabled() ? 0 : IMAGE_DRAW_DISABLE );
			int nWidth = maImage.GetSizePixel().Width() + 6;
			aPos.X() += nWidth;
			aSize.Width() -= nWidth;
		}
		rDev.DrawText( Rectangle(aPos,aSize),maText, rDev.IsEnabled() ? 0 : TEXT_DRAW_DISABLE );
	}
	else
	{
		if( !!maImage )
		{
			rDev.DrawImage( aPos, maImage, rDev.IsEnabled() ? 0 : IMAGE_DRAW_DISABLE);
			aPos.X() += maImage.GetSizePixel().Width() + 6;
		}
		rDev.DrawText( aPos, maText);
	}
}

// --------------------------------------------------------------------

SvLBoxItem* UnoTreeListItem::Create() const
{
	return new UnoTreeListItem;
}

// --------------------------------------------------------------------

void UnoTreeListItem::Clone( SvLBoxItem* pSource )
{
	UnoTreeListItem* pSourceItem = dynamic_cast< UnoTreeListItem* >( pSource );
	if( pSourceItem )
	{
		maText = pSourceItem->maText;
		maImage = pSourceItem->maImage;
	}
}

// --------------------------------------------------------------------

OUString UnoTreeListItem::GetText() const
{
	return maText;
}

// --------------------------------------------------------------------

void UnoTreeListItem::SetText( const OUString& rText )
{
	maText = rText;
}

// --------------------------------------------------------------------

void UnoTreeListItem::SetImage( const Image& rImage )
{
	maImage = rImage;
}

// --------------------------------------------------------------------

OUString UnoTreeListItem::GetGraphicURL() const
{
	return maGraphicURL;
}

// --------------------------------------------------------------------

void UnoTreeListItem::SetGraphicURL( const OUString& rGraphicURL )
{
	maGraphicURL = rGraphicURL;
}

// --------------------------------------------------------------------

void UnoTreeListItem::InitViewData( SvLBox* pView,SvLBoxEntry* pEntry, SvViewDataItem* pViewData)
{
	if( !pViewData )
		pViewData = pView->GetViewDataItem( pEntry, this );

	pViewData->aSize = maImage.GetSizePixel();

	const Size aTextSize(pView->GetTextWidth( maText ), pView->GetTextHeight());
	if( pViewData->aSize.Width() )
	{
		pViewData->aSize.Width() += 6 + aTextSize.Width();
		if( pViewData->aSize.Height() < aTextSize.Height() )
			pViewData->aSize.Height() = aTextSize.Height();
	}
	else
	{
		pViewData->aSize = aTextSize;
	}
}

// --------------------------------------------------------------------

UnoTreeListEntry::UnoTreeListEntry( const Reference< XTreeNode >& xNode, TreeControlPeer* pPeer )
: SvLBoxEntry()
, mxNode( xNode )
, mpPeer( pPeer )
{
	if( mpPeer )
		mpPeer->addEntry( this );
}

// --------------------------------------------------------------------

UnoTreeListEntry::~UnoTreeListEntry()
{
	if( mpPeer )
		mpPeer->removeEntry( this );
}
