/**************************************************************
 * 
 * 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 <vcl/svapp.hxx>
#ifndef GCC
#endif

class TabBar;

// #102891# -----------------------

#include <svtools/svlbox.hxx>
#include <svtools/svlbitm.hxx>
#include <svtools/svtreebx.hxx>
#include <tools/diagnose_ex.h>
#include <svimpbox.hxx>
#include <unotools/accessiblestatesethelper.hxx>
#include <com/sun/star/accessibility/AccessibleStateType.hpp>
#include <com/sun/star/awt/XWindowPeer.hpp>


using namespace ::com::sun::star::accessibility;

/*
	Bugs/ToDo

	- Berechnung Rectangle beim Inplace-Editing (Bug bei manchen Fonts)
	- SetSpaceBetweenEntries: Offset wird in SetEntryHeight nicht
	  beruecksichtigt
*/

#define TREEFLAG_FIXEDHEIGHT		0x0010


DBG_NAME(SvTreeListBox)

#define SV_LBOX_DEFAULT_INDENT_PIXEL 20

SvTreeListBox::SvTreeListBox( Window* pParent, WinBits nWinStyle )
	: SvLBox( pParent, nWinStyle )
{
	DBG_CTOR(SvTreeListBox,0);
	InitTreeView();

	SetSublistOpenWithLeftRight();
}

SvTreeListBox::SvTreeListBox( Window* pParent , const ResId& rResId )
	: SvLBox( pParent,rResId )
{
	DBG_CTOR(SvTreeListBox,0);

	InitTreeView();
	Resize();

	SetSublistOpenWithLeftRight();
}

void SvTreeListBox::InitTreeView()
{
	DBG_CHKTHIS(SvTreeListBox,0);
    pCheckButtonData = NULL;
    pEdEntry = NULL;
    pEdItem = NULL;
	nEntryHeight = 0;
    pEdCtrl = NULL;
	nFirstSelTab = 0;
	nLastSelTab = 0;
	nFocusWidth = -1;

	Link* pLink = new Link( LINK(this,SvTreeListBox, DefaultCompare) );
    pLBoxImpl->m_pLink = pLink;

	nTreeFlags = TREEFLAG_RECALCTABS;
	nIndent = SV_LBOX_DEFAULT_INDENT_PIXEL;
	nEntryHeightOffs = SV_ENTRYHEIGHTOFFS_PIXEL;
	pImp = new SvImpLBox( this, GetModel(), GetStyle() );

	aContextBmpMode = SVLISTENTRYFLAG_EXPANDED;
	nContextBmpWidthMax = 0;
	SetFont( GetFont() );
	SetSpaceBetweenEntries( 0 );
	SetLineColor();
	InitSettings( sal_True, sal_True, sal_True );
	ImplInitStyle();
	SetTabs();
}


SvTreeListBox::~SvTreeListBox()
{
	DBG_DTOR(SvTreeListBox,0);
	pImp->CallEventListeners( VCLEVENT_OBJECT_DYING );
	delete pImp;
    delete pLBoxImpl->m_pLink;
	ClearTabList();
}

void SvTreeListBox::SetExtendedWinBits( ExtendedWinBits _nBits )
{
    pImp->SetExtendedWindowBits( _nBits );
}

ExtendedWinBits SvTreeListBox::GetExtendedWinBits() const
{
    return pImp->GetExtendedWindowBits();
}

void SvTreeListBox::SetModel( SvLBoxTreeList* pNewModel )
{
	DBG_CHKTHIS(SvTreeListBox,0);
	pImp->SetModel( pNewModel );
	SvLBox::SetModel( pNewModel );
}

void SvTreeListBox::DisconnectFromModel()
{
	DBG_CHKTHIS(SvTreeListBox,0);
	SvLBox::DisconnectFromModel();
	pImp->SetModel( GetModel() );
}


sal_uInt16 SvTreeListBox::IsA()
{
	DBG_CHKTHIS(SvTreeListBox,0);
	return SV_LISTBOX_ID_TREEBOX;
}

void SvTreeListBox::SetSublistOpenWithReturn( sal_Bool b )
{
	pImp->bSubLstOpRet = b;
}

sal_Bool SvTreeListBox::IsSublistOpenWithReturn() const
{
	return pImp->bSubLstOpRet;
}

void SvTreeListBox::SetSublistOpenWithLeftRight( sal_Bool b )
{
	pImp->bSubLstOpLR = b;
}

sal_Bool SvTreeListBox::IsSublistOpenWithLeftRight() const
{
	return pImp->bSubLstOpLR;
}

void SvTreeListBox::Resize()
{
	DBG_CHKTHIS(SvTreeListBox,0);
	if( IsEditingActive() )
		EndEditing( sal_True );
	SvLBox::Resize();
	pImp->Resize();
	nFocusWidth = -1;
	pImp->ShowCursor( sal_False );
	pImp->ShowCursor( sal_True );
}

/* Faelle:

   A) Entries haben Bitmaps
	   0. Keine Buttons
	   1. Node-Buttons (optional auch an Root-Items)
	   2. Node-Buttons (optional auch an Root-Items) + CheckButton
	   3. CheckButton
   B) Entries haben keine Bitmaps  (->ueber WindowBits wg. D&D !!!!!!)
	   0. Keine Buttons
	   1. Node-Buttons (optional auch an Root-Items)
	   2. Node-Buttons (optional auch an Root-Items) + CheckButton
	   3. CheckButton
*/

#define NO_BUTTONS              0
#define NODE_BUTTONS            1
#define NODE_AND_CHECK_BUTTONS  2
#define CHECK_BUTTONS           3

#define TABFLAGS_TEXT (SV_LBOXTAB_DYNAMIC |        \
                       SV_LBOXTAB_ADJUST_LEFT |    \
                       SV_LBOXTAB_EDITABLE |       \
                       SV_LBOXTAB_SHOW_SELECTION)

#define TABFLAGS_CONTEXTBMP (SV_LBOXTAB_DYNAMIC | SV_LBOXTAB_ADJUST_CENTER)

#define TABFLAGS_CHECKBTN (SV_LBOXTAB_DYNAMIC |        \
                           SV_LBOXTAB_ADJUST_CENTER |  \
                           SV_LBOXTAB_PUSHABLE)

#define TAB_STARTPOS	2

// bei Aenderungen GetTextOffset beruecksichtigen
void SvTreeListBox::SetTabs()
{
	DBG_CHKTHIS(SvTreeListBox,0);
	if( IsEditingActive() )
		EndEditing( sal_True );
	nTreeFlags &= (~TREEFLAG_RECALCTABS);
	nFocusWidth = -1;
    const WinBits nStyle( GetStyle() );
	sal_Bool bHasButtons = (nStyle & WB_HASBUTTONS)!=0;
	sal_Bool bHasButtonsAtRoot = (nStyle & (WB_HASLINESATROOT |
											  WB_HASBUTTONSATROOT))!=0;
	long nStartPos = TAB_STARTPOS;
	long nNodeWidthPixel = GetExpandedNodeBmp().GetSizePixel().Width();

	long nCheckWidth = 0;
	if( nTreeFlags & TREEFLAG_CHKBTN )
		nCheckWidth = pCheckButtonData->aBmps[0].GetSizePixel().Width();
	long nCheckWidthDIV2 = nCheckWidth / 2;

	long nContextWidth = nContextBmpWidthMax;
	long nContextWidthDIV2 = nContextWidth / 2;

	ClearTabList();

	int nCase = NO_BUTTONS;
	if( !(nTreeFlags & TREEFLAG_CHKBTN) )
	{
		if( bHasButtons )
			nCase = NODE_BUTTONS;
	}
	else
	{
		if( bHasButtons )
			nCase = NODE_AND_CHECK_BUTTONS;
		 else
			nCase = CHECK_BUTTONS;
	}

	switch( nCase )
	{
		case NO_BUTTONS :
			nStartPos += nContextWidthDIV2;  // wg. Zentrierung
			AddTab( nStartPos, TABFLAGS_CONTEXTBMP );
			nStartPos += nContextWidthDIV2;  // rechter Rand der Context-Bmp
			// Abstand setzen nur wenn Bitmaps da
			if( nContextBmpWidthMax )
				nStartPos += 5; // Abstand Context-Bmp - Text
			AddTab( nStartPos, TABFLAGS_TEXT );
			break;

		case NODE_BUTTONS :
			if( bHasButtonsAtRoot )
				nStartPos += ( nIndent + (nNodeWidthPixel/2) );
			else
				nStartPos += nContextWidthDIV2;
			AddTab( nStartPos, TABFLAGS_CONTEXTBMP );
			nStartPos += nContextWidthDIV2;  // rechter Rand der Context-Bmp
			// Abstand setzen nur wenn Bitmaps da
			if( nContextBmpWidthMax )
				nStartPos += 5; // Abstand Context-Bmp - Text
			AddTab( nStartPos, TABFLAGS_TEXT );
			break;

		case NODE_AND_CHECK_BUTTONS :
			if( bHasButtonsAtRoot )
				nStartPos += ( nIndent + nNodeWidthPixel );
			else
				nStartPos += nCheckWidthDIV2;
			AddTab( nStartPos, TABFLAGS_CHECKBTN );
			nStartPos += nCheckWidthDIV2;  // rechter Rand des CheckButtons
			nStartPos += 3;  // Abstand CheckButton Context-Bmp
			nStartPos += nContextWidthDIV2;  // Mitte der Context-Bmp
			AddTab( nStartPos, TABFLAGS_CONTEXTBMP );
			nStartPos += nContextWidthDIV2;  // rechter Rand der Context-Bmp
			// Abstand setzen nur wenn Bitmaps da
			if( nContextBmpWidthMax )
				nStartPos += 5; // Abstand Context-Bmp - Text
			AddTab( nStartPos, TABFLAGS_TEXT );
			break;

		case CHECK_BUTTONS :
			nStartPos += nCheckWidthDIV2;
			AddTab( nStartPos, TABFLAGS_CHECKBTN );
			nStartPos += nCheckWidthDIV2;  // rechter Rand CheckButton
			nStartPos += 3;  // Abstand CheckButton Context-Bmp
			nStartPos += nContextWidthDIV2;  // Mitte der Context-Bmp
			AddTab( nStartPos, TABFLAGS_CONTEXTBMP );
			nStartPos += nContextWidthDIV2;  // rechter Rand der Context-Bmp
			// Abstand setzen nur wenn Bitmaps da
			if( nContextBmpWidthMax )
				nStartPos += 5; // Abstand Context-Bmp - Text
			AddTab( nStartPos, TABFLAGS_TEXT );
			break;
	}
	pImp->NotifyTabsChanged();
}

void SvTreeListBox::InitEntry( SvLBoxEntry* pEntry,
  const XubString& aStr, const Image& aCollEntryBmp, const Image& aExpEntryBmp,
  SvLBoxButtonKind eButtonKind)
{
	DBG_CHKTHIS(SvTreeListBox,0);
	SvLBoxButton* pButton;
	SvLBoxString* pString;
	SvLBoxContextBmp* pContextBmp;

	if( nTreeFlags & TREEFLAG_CHKBTN )
	{
		pButton= new SvLBoxButton( pEntry,eButtonKind,0,pCheckButtonData );
		pEntry->AddItem( pButton );
	}

	pContextBmp= new SvLBoxContextBmp( pEntry,0, aCollEntryBmp,aExpEntryBmp,
									 aContextBmpMode );
	pEntry->AddItem( pContextBmp );

	pString = new SvLBoxString( pEntry, 0, aStr );
	pEntry->AddItem( pString );
}

String SvTreeListBox::GetEntryText(SvLBoxEntry* pEntry) const
{
	DBG_CHKTHIS(SvTreeListBox,0);
	DBG_ASSERT( pEntry, "SvTreeListBox::GetEntryText(): no entry" );
	SvLBoxString* pItem = (SvLBoxString*)(pEntry->GetFirstItem(SV_ITEM_ID_LBOXSTRING));
	DBG_ASSERT( pEntry, "SvTreeListBox::GetEntryText(): item not found" );
	return pItem->GetText();
}

String SvTreeListBox::SearchEntryText( SvLBoxEntry* pEntry ) const
{
	DBG_CHKTHIS(SvTreeListBox,0);
	DBG_ASSERT( pEntry, "SvTreeListBox::SearchEntryText(): no entry" );
	String sRet;
	sal_uInt16 nCount = pEntry->ItemCount();
	sal_uInt16 nCur = 0;
	SvLBoxItem* pItem;
	while( nCur < nCount )
	{
		pItem = pEntry->GetItem( nCur );
		if ( pItem->IsA() == SV_ITEM_ID_LBOXSTRING &&
			 static_cast<SvLBoxString*>( pItem )->GetText().Len() > 0 )
		{
			sRet = static_cast<SvLBoxString*>( pItem )->GetText();
			break;
		}
		nCur++;
	}
	return sRet;
}

const Image& SvTreeListBox::GetExpandedEntryBmp(SvLBoxEntry* pEntry, BmpColorMode _eMode) const
{
	DBG_CHKTHIS(SvTreeListBox,0);
	DBG_ASSERT(pEntry,"Entry?");
	SvLBoxContextBmp* pItem = (SvLBoxContextBmp*)(pEntry->GetFirstItem(SV_ITEM_ID_LBOXCONTEXTBMP));
	DBG_ASSERT(pItem,"GetContextBmp:Item not found");
	return pItem->GetBitmap2( _eMode );
}

const Image& SvTreeListBox::GetCollapsedEntryBmp( SvLBoxEntry* pEntry, BmpColorMode _eMode ) const
{
	DBG_CHKTHIS(SvTreeListBox,0);
	DBG_ASSERT(pEntry,"Entry?");
	SvLBoxContextBmp* pItem = (SvLBoxContextBmp*)(pEntry->GetFirstItem(SV_ITEM_ID_LBOXCONTEXTBMP));
	DBG_ASSERT(pItem,"GetContextBmp:Item not found");
	return pItem->GetBitmap1( _eMode );
}

IMPL_LINK_INLINE_START( SvTreeListBox, CheckButtonClick, SvLBoxButtonData *, pData )
{
	DBG_CHKTHIS(SvTreeListBox,0);
	pHdlEntry = pData->GetActEntry();
	CheckButtonHdl();
	return 0;
}
IMPL_LINK_INLINE_END( SvTreeListBox, CheckButtonClick, SvLBoxButtonData *, pData )

SvLBoxEntry* SvTreeListBox::InsertEntry( const XubString& aText,SvLBoxEntry* pParent,
									 sal_Bool bChildsOnDemand, sal_uLong nPos, void* pUser,
                                     SvLBoxButtonKind eButtonKind )
{
	DBG_CHKTHIS(SvTreeListBox,0);
	nTreeFlags |= TREEFLAG_MANINS;

	const Image& rDefExpBmp = pImp->GetDefaultEntryExpBmp( );
	const Image& rDefColBmp = pImp->GetDefaultEntryColBmp( );

	aCurInsertedExpBmp = rDefExpBmp;
	aCurInsertedColBmp = rDefColBmp;

	SvLBoxEntry* pEntry = CreateEntry();
	pEntry->SetUserData( pUser );
	InitEntry( pEntry, aText, rDefColBmp, rDefExpBmp, eButtonKind );
	pEntry->EnableChildsOnDemand( bChildsOnDemand );

    // Add the HC versions of the default images
    SvLBoxContextBmp* pBmpItem = static_cast< SvLBoxContextBmp* >( pEntry->GetFirstItem( SV_ITEM_ID_LBOXCONTEXTBMP ) );
    if( pBmpItem )
    {
        pBmpItem->SetBitmap1( pImp->GetDefaultEntryColBmp( BMP_COLOR_HIGHCONTRAST ), BMP_COLOR_HIGHCONTRAST );
        pBmpItem->SetBitmap2( pImp->GetDefaultEntryExpBmp( BMP_COLOR_HIGHCONTRAST ), BMP_COLOR_HIGHCONTRAST );
    }

	if( !pParent )
		SvLBox::Insert( pEntry, nPos );
	else
		SvLBox::Insert( pEntry, pParent, nPos );

	aPrevInsertedExpBmp = rDefExpBmp;
	aPrevInsertedColBmp = rDefColBmp;

	nTreeFlags &= (~TREEFLAG_MANINS);

	return pEntry;
}

SvLBoxEntry* SvTreeListBox::InsertEntry( const XubString& aText,
	const Image& aExpEntryBmp, const Image& aCollEntryBmp,
	SvLBoxEntry* pParent, sal_Bool bChildsOnDemand, sal_uLong nPos, void* pUser,
    SvLBoxButtonKind eButtonKind )
{
	DBG_CHKTHIS(SvTreeListBox,0);
	nTreeFlags |= TREEFLAG_MANINS;

	aCurInsertedExpBmp = aExpEntryBmp;
	aCurInsertedColBmp = aCollEntryBmp;

	SvLBoxEntry* pEntry = CreateEntry();
	pEntry->SetUserData( pUser );
	InitEntry( pEntry, aText, aCollEntryBmp, aExpEntryBmp, eButtonKind );

	pEntry->EnableChildsOnDemand( bChildsOnDemand );

	if( !pParent )
		SvLBox::Insert( pEntry, nPos );
	else
		SvLBox::Insert( pEntry, pParent, nPos );

	aPrevInsertedExpBmp = aExpEntryBmp;
	aPrevInsertedColBmp = aCollEntryBmp;

	nTreeFlags &= (~TREEFLAG_MANINS);

	return pEntry;
}

void SvTreeListBox::SetEntryText( SvLBoxEntry* pEntry, const XubString& aStr)
{
	DBG_CHKTHIS(SvTreeListBox,0);
	SvLBoxString* pItem = (SvLBoxString*)(pEntry->GetFirstItem(SV_ITEM_ID_LBOXSTRING));
	DBG_ASSERT(pItem,"SetText:Item not found");
	pItem->SetText( pEntry, aStr );
	pItem->InitViewData( this, pEntry, 0 );
	GetModel()->InvalidateEntry( pEntry );
}

void SvTreeListBox::SetExpandedEntryBmp( SvLBoxEntry* pEntry, const Image& aBmp, BmpColorMode _eMode )
{
	DBG_CHKTHIS(SvTreeListBox,0);
	SvLBoxContextBmp* pItem = (SvLBoxContextBmp*)(pEntry->GetFirstItem(SV_ITEM_ID_LBOXCONTEXTBMP));

	DBG_ASSERT(pItem,"SetExpBmp:Item not found");
	pItem->SetBitmap2( aBmp, _eMode );

	GetModel()->InvalidateEntry( pEntry );
	SetEntryHeight( pEntry );
	Size aSize = aBmp.GetSizePixel();
	// #97680# ---------------
	short nWidth = pImp->UpdateContextBmpWidthVector( pEntry, (short)aSize.Width() );
	if( nWidth > nContextBmpWidthMax )
	{
		nContextBmpWidthMax = nWidth;
		SetTabs();
	}
}

void SvTreeListBox::SetCollapsedEntryBmp(SvLBoxEntry* pEntry,const Image& aBmp, BmpColorMode _eMode )
{
	DBG_CHKTHIS(SvTreeListBox,0);
	SvLBoxContextBmp* pItem = (SvLBoxContextBmp*)(pEntry->GetFirstItem(SV_ITEM_ID_LBOXCONTEXTBMP));

	DBG_ASSERT(pItem,"SetExpBmp:Item not found");
	pItem->SetBitmap1( aBmp, _eMode );

	GetModel()->InvalidateEntry( pEntry );
	SetEntryHeight( pEntry );
	Size aSize = aBmp.GetSizePixel();
	// #97680# -----------
	short nWidth = pImp->UpdateContextBmpWidthVector( pEntry, (short)aSize.Width() );
	if( nWidth > nContextBmpWidthMax )
	{
		nContextBmpWidthMax = nWidth;
		SetTabs();
	}
}

void SvTreeListBox::ImpEntryInserted( SvLBoxEntry* pEntry )
{
	DBG_CHKTHIS(SvTreeListBox,0);

	SvLBoxEntry* pParent = (SvLBoxEntry*)pModel->GetParent( pEntry );
	if( pParent )
	{
		sal_uInt16 nFlags = pParent->GetFlags();
		nFlags &= ~SV_ENTRYFLAG_NO_NODEBMP;
		pParent->SetFlags( nFlags );
	}

	if(!((nTreeFlags & TREEFLAG_MANINS) &&
		 (aPrevInsertedExpBmp == aCurInsertedExpBmp)  &&
		 (aPrevInsertedColBmp == aCurInsertedColBmp) ))
	{
		Size aSize = GetCollapsedEntryBmp( pEntry ).GetSizePixel();
		if( aSize.Width() > nContextBmpWidthMax )
		{
			nContextBmpWidthMax = (short)aSize.Width();
			nTreeFlags |= TREEFLAG_RECALCTABS;
		}
		aSize = GetExpandedEntryBmp( pEntry ).GetSizePixel();
		if( aSize.Width() > nContextBmpWidthMax )
		{
			nContextBmpWidthMax = (short)aSize.Width();
			nTreeFlags |= TREEFLAG_RECALCTABS;
		}
	}
	SetEntryHeight( (SvLBoxEntry*)pEntry );
}



void SvTreeListBox::SetCheckButtonState( SvLBoxEntry* pEntry, SvButtonState eState)
{
	DBG_CHKTHIS(SvTreeListBox,0);
	if( nTreeFlags & TREEFLAG_CHKBTN )
	{
		SvLBoxButton* pItem = (SvLBoxButton*)(pEntry->GetFirstItem(SV_ITEM_ID_LBOXBUTTON));
		if(!(pItem && pItem->CheckModification()))
			return ;
		switch( eState )
		{
			case SV_BUTTON_CHECKED:
				pItem->SetStateChecked();
				break;

			case SV_BUTTON_UNCHECKED:
				pItem->SetStateUnchecked();
				break;

			case SV_BUTTON_TRISTATE:
				pItem->SetStateTristate();
				break;
		}
		InvalidateEntry( pEntry );
	}
}

SvButtonState SvTreeListBox::GetCheckButtonState( SvLBoxEntry* pEntry ) const
{
	DBG_CHKTHIS(SvTreeListBox,0);
	SvButtonState eState = SV_BUTTON_UNCHECKED;
	if( nTreeFlags & TREEFLAG_CHKBTN )
	{
		SvLBoxButton* pItem = (SvLBoxButton*)(pEntry->GetFirstItem(SV_ITEM_ID_LBOXBUTTON));
		if(!pItem)
			return SV_BUTTON_TRISTATE;
		sal_uInt16 nButtonFlags = pItem->GetButtonFlags();
		eState = pCheckButtonData->ConvertToButtonState( nButtonFlags );
	}
	return eState;
}

void SvTreeListBox::CheckButtonHdl()
{
	DBG_CHKTHIS(SvTreeListBox,0);
	aCheckButtonHdl.Call( this );
	if ( pCheckButtonData )
		pImp->CallEventListeners( VCLEVENT_CHECKBOX_TOGGLE, (void*)pCheckButtonData->GetActEntry() );
}

// *********************************************************************
// *********************************************************************

//
//  TODO: Momentan werden die Daten so geklont, dass sie dem
//  Standard-TreeView-Format entsprechen. Hier sollte eigentlich
//  das Model als Referenz dienen. Dies fuehrt dazu, dass
//  SvLBoxEntry::Clone _nicht_ gerufen wird, sondern nur dessen
//  Basisklasse SvListEntry
//

SvLBoxEntry* SvTreeListBox::CloneEntry( SvLBoxEntry* pSource )
{
	DBG_CHKTHIS(SvTreeListBox,0);
	XubString aStr;
	Image aCollEntryBmp;
	Image aExpEntryBmp;
    SvLBoxButtonKind eButtonKind = SvLBoxButtonKind_enabledCheckbox;

	SvLBoxString* pStringItem = (SvLBoxString*)(pSource->GetFirstItem(SV_ITEM_ID_LBOXSTRING));
	if( pStringItem )
		aStr = pStringItem->GetText();
	SvLBoxContextBmp* pBmpItem = (SvLBoxContextBmp*)(pSource->GetFirstItem(SV_ITEM_ID_LBOXCONTEXTBMP));
	if( pBmpItem )
	{
		aCollEntryBmp = pBmpItem->GetBitmap1( BMP_COLOR_NORMAL );
		aExpEntryBmp  = pBmpItem->GetBitmap2( BMP_COLOR_NORMAL );
	}
    SvLBoxButton* pButtonItem = (SvLBoxButton*)(pSource->GetFirstItem(SV_ITEM_ID_LBOXBUTTON));
    if( pButtonItem )
        eButtonKind = pButtonItem->GetKind();
	SvLBoxEntry* pClone = CreateEntry();
	InitEntry( pClone, aStr, aCollEntryBmp, aExpEntryBmp, eButtonKind );
	pClone->SvListEntry::Clone( pSource );
	pClone->EnableChildsOnDemand( pSource->HasChildsOnDemand() );
	pClone->SetUserData( pSource->GetUserData() );

	if ( pBmpItem )
	{
		SvLBoxContextBmp* pCloneBitmap = static_cast< SvLBoxContextBmp* >( pClone->GetFirstItem( SV_ITEM_ID_LBOXCONTEXTBMP ) );
		if ( pCloneBitmap )
		{
			pCloneBitmap->SetBitmap1( pBmpItem->GetBitmap1( BMP_COLOR_HIGHCONTRAST ), BMP_COLOR_HIGHCONTRAST );
			pCloneBitmap->SetBitmap2( pBmpItem->GetBitmap2( BMP_COLOR_HIGHCONTRAST ), BMP_COLOR_HIGHCONTRAST );
		}
	}

	return pClone;
}

// *********************************************************************
// *********************************************************************


void SvTreeListBox::ShowExpandBitmapOnCursor( sal_Bool bYes )
{
	DBG_CHKTHIS(SvTreeListBox,0);
	if( bYes )
		aContextBmpMode = SVLISTENTRYFLAG_FOCUSED;
	else
		aContextBmpMode = SVLISTENTRYFLAG_EXPANDED;
}

void SvTreeListBox::SetIndent( short nNewIndent )
{
	DBG_CHKTHIS(SvTreeListBox,0);
	nIndent = nNewIndent;
	SetTabs();
	if( IsUpdateMode() )
		Invalidate();
}

const Image& SvTreeListBox::GetDefaultExpandedEntryBmp( BmpColorMode _eMode ) const
{
	return pImp->GetDefaultEntryExpBmp( _eMode );
}

const Image& SvTreeListBox::GetDefaultCollapsedEntryBmp( BmpColorMode _eMode ) const
{
	return pImp->GetDefaultEntryColBmp( _eMode );
}

void SvTreeListBox::SetDefaultExpandedEntryBmp( const Image& aBmp, BmpColorMode _eMode )
{
	DBG_CHKTHIS(SvTreeListBox,0);
	Size aSize = aBmp.GetSizePixel();
	if( aSize.Width() > nContextBmpWidthMax )
		nContextBmpWidthMax = (short)aSize.Width();
	SetTabs();

	pImp->SetDefaultEntryExpBmp( aBmp, _eMode );
}

void SvTreeListBox::SetDefaultCollapsedEntryBmp( const Image& aBmp, BmpColorMode _eMode )
{
	DBG_CHKTHIS(SvTreeListBox,0);
	Size aSize = aBmp.GetSizePixel();
	if( aSize.Width() > nContextBmpWidthMax )
		nContextBmpWidthMax = (short)aSize.Width();
	SetTabs();

	pImp->SetDefaultEntryColBmp( aBmp, _eMode );
}

void SvTreeListBox::EnableCheckButton( SvLBoxButtonData* pData )
{
	DBG_CHKTHIS(SvTreeListBox,0);
	DBG_ASSERT(!GetEntryCount(),"EnableCheckButton: Entry count != 0");
	if( !pData )
		nTreeFlags &= (~TREEFLAG_CHKBTN);
	else
	{
		SetCheckButtonData( pData );
		nTreeFlags |= TREEFLAG_CHKBTN;
		pData->SetLink( LINK(this, SvTreeListBox, CheckButtonClick));
	}

	SetTabs();
	if( IsUpdateMode() )
		Invalidate();
}

void SvTreeListBox::SetCheckButtonData( SvLBoxButtonData* pData )
{
	DBG_CHKTHIS(SvTreeListBox,0);
	if ( pData )
		pCheckButtonData = pData;
}

const Image& SvTreeListBox::GetDefaultExpandedNodeImage( BmpColorMode _eMode )
{
	return SvImpLBox::GetDefaultExpandedNodeImage( _eMode );
}

const Image& SvTreeListBox::GetDefaultCollapsedNodeImage( BmpColorMode _eMode )
{
	return SvImpLBox::GetDefaultCollapsedNodeImage( _eMode );
}

void SvTreeListBox::SetNodeBitmaps( const Image& rCollapsedNodeBmp, const Image& rExpandedNodeBmp, BmpColorMode _eMode )
{
	DBG_CHKTHIS(SvTreeListBox,0);
	SetExpandedNodeBmp( rExpandedNodeBmp, _eMode );
	SetCollapsedNodeBmp( rCollapsedNodeBmp, _eMode );
	SetTabs();
}

void SvTreeListBox::SetDontKnowNodeBitmap( const Image& rDontKnowBmp, BmpColorMode _eMode )
{
	pImp->SetDontKnowNodeBmp( rDontKnowBmp, _eMode );
}

sal_Bool SvTreeListBox::EditingEntry( SvLBoxEntry*, Selection& )
{
	DBG_CHKTHIS(SvTreeListBox,0);
	return sal_True;
}

sal_Bool SvTreeListBox::EditedEntry( SvLBoxEntry* /*pEntry*/,const XubString& /*rNewText*/)
{
	DBG_CHKTHIS(SvTreeListBox,0);
	return sal_True;
}

void SvTreeListBox::EnableInplaceEditing( sal_Bool bOn )
{
	DBG_CHKTHIS(SvTreeListBox,0);
	SvLBox::EnableInplaceEditing( bOn );
}

void SvTreeListBox::KeyInput( const KeyEvent& rKEvt )
{
	DBG_CHKTHIS(SvTreeListBox,0);
	// unter OS/2 bekommen wir auch beim Editieren Key-Up/Down
	if( IsEditingActive() )
		return;

	nImpFlags |= SVLBOX_IS_TRAVELSELECT;

#ifdef OVDEBUG
	sal_uInt16 nCode = rKEvt.GetKeyCode().GetCode();
	switch ( nCode )
	{
		case KEY_F1:
		{
			SvLBoxEntry* pEntry = First();
			pEntry = NextVisible( pEntry );
			SetEntryText( pEntry, "SetEntryText" );
			Sound::Beep();
		}
		break;
	}
#endif

	if( !pImp->KeyInput( rKEvt ) )
		SvLBox::KeyInput( rKEvt );

	nImpFlags &= ~SVLBOX_IS_TRAVELSELECT;
}

void SvTreeListBox::RequestingChilds( SvLBoxEntry* pParent )
{
	DBG_CHKTHIS(SvTreeListBox,0);
	if( !pParent->HasChilds() )
		InsertEntry( String::CreateFromAscii("<dummy>"), pParent, sal_False, LIST_APPEND );
}

void SvTreeListBox::GetFocus()
{
	DBG_CHKTHIS(SvTreeListBox,0);
	pImp->GetFocus();
	SvLBox::GetFocus();

	SvLBoxEntry* pEntry = FirstSelected();
	if ( pEntry )
		pImp->CallEventListeners( VCLEVENT_LISTBOX_SELECT, pEntry );

}

void SvTreeListBox::LoseFocus()
{
	DBG_CHKTHIS(SvTreeListBox,0);
	pImp->LoseFocus();
	SvLBox::LoseFocus();
}

void SvTreeListBox::ModelHasCleared()
{
	DBG_CHKTHIS(SvTreeListBox,0);
	pImp->pCursor = 0; //sonst Absturz beim Inplace-Editieren im GetFocus
	delete pEdCtrl;
    pEdCtrl = NULL;
	pImp->Clear();
	nFocusWidth = -1;

	nContextBmpWidthMax = 0;
	SetDefaultExpandedEntryBmp( GetDefaultExpandedEntryBmp() );
	SetDefaultCollapsedEntryBmp( GetDefaultCollapsedEntryBmp() );

	if( !(nTreeFlags & TREEFLAG_FIXEDHEIGHT ))
		nEntryHeight = 0;
	AdjustEntryHeight( GetFont() );
	AdjustEntryHeight( GetDefaultExpandedEntryBmp() );
	AdjustEntryHeight( GetDefaultCollapsedEntryBmp() );

	SvLBox::ModelHasCleared();
//	if( IsUpdateMode() )
//		Invalidate();
}

void SvTreeListBox::ShowTargetEmphasis( SvLBoxEntry* pEntry, sal_Bool /* bShow  */ )
{
	DBG_CHKTHIS(SvTreeListBox,0);
	pImp->PaintDDCursor( pEntry );
}

void SvTreeListBox::ScrollOutputArea( short nDeltaEntries )
{
	DBG_CHKTHIS(SvTreeListBox,0);
	if( !nDeltaEntries || !pImp->aVerSBar.IsVisible() )
		return;

	long nThumb = pImp->aVerSBar.GetThumbPos();
	long nMax = pImp->aVerSBar.GetRange().Max();

	NotifyBeginScroll();
	if( nDeltaEntries < 0 )
	{
		// das Fenster nach oben verschieben
		nDeltaEntries *= -1;
		long nVis = pImp->aVerSBar.GetVisibleSize();
		long nTemp = nThumb + nVis;
		if( nDeltaEntries > (nMax - nTemp) )
			nDeltaEntries = (short)(nMax - nTemp);
		pImp->PageDown( (sal_uInt16)nDeltaEntries );
	}
	else
	{
		if( nDeltaEntries > nThumb )
			nDeltaEntries = (short)nThumb;
		pImp->PageUp( (sal_uInt16)nDeltaEntries );
	}
	pImp->SyncVerThumb();
	NotifyEndScroll();
}

void SvTreeListBox::SetSelectionMode( SelectionMode eSelectMode )
{
	DBG_CHKTHIS(SvTreeListBox,0);
	SvLBox::SetSelectionMode( eSelectMode );
	pImp->SetSelectionMode( eSelectMode );
}

void SvTreeListBox::SetDragDropMode( DragDropMode nDDMode )
{
	DBG_CHKTHIS(SvTreeListBox,0);
	SvLBox::SetDragDropMode( nDDMode );
	pImp->SetDragDropMode( nDDMode );
}

short SvTreeListBox::GetHeightOffset(const Image& rBmp, Size& aSizeLogic )
{
	DBG_CHKTHIS(SvTreeListBox,0);
	short nOffset = 0;
	aSizeLogic = rBmp.GetSizePixel();
	if( GetEntryHeight() > aSizeLogic.Height() )
		nOffset = ( GetEntryHeight() - (short)aSizeLogic.Height()) / 2;
	return nOffset;
}

short SvTreeListBox::GetHeightOffset(const Font& /* rFont */, Size& aSizeLogic )
{
	DBG_CHKTHIS(SvTreeListBox,0);
	short nOffset = 0;
	aSizeLogic = Size(GetTextWidth('X'), GetTextHeight());
	if( GetEntryHeight() > aSizeLogic.Height() )
		nOffset = ( GetEntryHeight() - (short)aSizeLogic.Height()) / 2;
	return nOffset;
}

void SvTreeListBox::SetEntryHeight( SvLBoxEntry* pEntry )
{
	DBG_CHKTHIS(SvTreeListBox,0);
	short nHeight, nHeightMax=0;
	sal_uInt16 nCount = pEntry->ItemCount();
	sal_uInt16 nCur = 0;
	SvViewDataEntry* pViewData = GetViewDataEntry( pEntry );
	while( nCur < nCount )
	{
		SvLBoxItem* pItem = pEntry->GetItem( nCur );
		nHeight = (short)(pItem->GetSize( pViewData, nCur ).Height());
		if( nHeight > nHeightMax )
			nHeightMax = nHeight;
		nCur++;
	}

	if( nHeightMax > nEntryHeight )
	{
		nEntryHeight = nHeightMax;
		SvLBox::SetFont( GetFont() );
		pImp->SetEntryHeight( nHeightMax );
	}
}

void SvTreeListBox::SetEntryHeight( short nHeight, sal_Bool bAlways )
{
	DBG_CHKTHIS(SvTreeListBox,0);

	if( bAlways || nHeight > nEntryHeight )
	{
		nEntryHeight = nHeight;
		if( nEntryHeight )
			nTreeFlags |= TREEFLAG_FIXEDHEIGHT;
		else
			nTreeFlags &= ~TREEFLAG_FIXEDHEIGHT;
		SvLBox::SetFont( GetFont() );
		pImp->SetEntryHeight( nHeight );
	}
}


void SvTreeListBox::AdjustEntryHeight( const Image& rBmp )
{
	DBG_CHKTHIS(SvTreeListBox,0);
	Size aSize;
	GetHeightOffset( rBmp, aSize );
	if( aSize.Height() > nEntryHeight )
	{
		nEntryHeight = (short)aSize.Height() + nEntryHeightOffs;
		pImp->SetEntryHeight( nEntryHeight );
	}
}

void SvTreeListBox::AdjustEntryHeight( const Font& rFont )
{
	DBG_CHKTHIS(SvTreeListBox,0);
	Size aSize;
	GetHeightOffset( rFont, aSize );
	if( aSize.Height()  >  nEntryHeight )
	{
		nEntryHeight = (short)aSize.Height() + nEntryHeightOffs;
		pImp->SetEntryHeight( nEntryHeight );
	}
}

sal_Bool SvTreeListBox::Expand( SvLBoxEntry* pParent )
{
	DBG_CHKTHIS(SvTreeListBox,0);
	pHdlEntry = pParent;
	sal_Bool bExpanded = sal_False;
	sal_uInt16 nFlags;

	if( pParent->HasChildsOnDemand() )
		RequestingChilds( pParent );
	if( pParent->HasChilds() )
	{
		nImpFlags |= SVLBOX_IS_EXPANDING;
		if( ExpandingHdl() )
		{
			bExpanded = sal_True;
			SvListView::Expand( pParent );
			pImp->EntryExpanded( pParent );
			pHdlEntry = pParent;
			ExpandedHdl();
		}
		nFlags = pParent->GetFlags();
		nFlags &= ~SV_ENTRYFLAG_NO_NODEBMP;
		nFlags |= SV_ENTRYFLAG_HAD_CHILDREN;
		pParent->SetFlags( nFlags );
	}
	else
	{
		nFlags = pParent->GetFlags();
		nFlags |= SV_ENTRYFLAG_NO_NODEBMP;
		pParent->SetFlags( nFlags );
		GetModel()->InvalidateEntry( pParent ); // neu zeichnen
	}

    // --> OD 2009-04-01 #i92103#
    if ( bExpanded )
    {
        pImp->CallEventListeners( VCLEVENT_ITEM_EXPANDED, pParent );
    }
    // <--

    return bExpanded;
}

sal_Bool SvTreeListBox::Collapse( SvLBoxEntry* pParent )
{
	DBG_CHKTHIS(SvTreeListBox,0);
	nImpFlags &= ~SVLBOX_IS_EXPANDING;
	pHdlEntry = pParent;
	sal_Bool bCollapsed = sal_False;

	if(	ExpandingHdl() )
	{
		bCollapsed = sal_True;
		pImp->CollapsingEntry( pParent );
		SvListView::Collapse( pParent );
		pImp->EntryCollapsed( pParent );
		pHdlEntry = pParent;
		ExpandedHdl();
	}

    // --> OD 2009-04-01 #i92103#
    if ( bCollapsed )
    {
        pImp->CallEventListeners( VCLEVENT_ITEM_COLLAPSED, pParent );
    }
    // <--

    return bCollapsed;
}

sal_Bool SvTreeListBox::Select( SvLBoxEntry* pEntry, sal_Bool bSelect )
{
	DBG_CHKTHIS(SvTreeListBox,0);
	DBG_ASSERT(pEntry,"Select: Null-Ptr");
	sal_Bool bRetVal = SvListView::Select( pEntry, bSelect );
	DBG_ASSERT(IsSelected(pEntry)==bSelect,"Select failed");
	if( bRetVal )
	{
		pImp->EntrySelected( pEntry, bSelect );
		pHdlEntry = pEntry;
		if( bSelect )
		{
			SelectHdl();
			pImp->CallEventListeners( VCLEVENT_LISTBOX_SELECT, pEntry );
		}
		else
			DeselectHdl();
	}
	return bRetVal;
}

sal_uLong SvTreeListBox::SelectChilds( SvLBoxEntry* pParent, sal_Bool bSelect )
{
	DBG_CHKTHIS(SvTreeListBox,0);
	pImp->DestroyAnchor();
	sal_uLong nRet = 0;
	if( !pParent->HasChilds() )
		return 0;
	sal_uInt16 nRefDepth = pModel->GetDepth( pParent );
	SvLBoxEntry* pChild = FirstChild( pParent );
	do {
		nRet++;
		Select( pChild, bSelect );
		pChild = Next( pChild );
	} while( pChild && pModel->GetDepth( pChild ) > nRefDepth );
	return nRet;
}

void SvTreeListBox::SelectAll( sal_Bool bSelect, sal_Bool )
{
	DBG_CHKTHIS(SvTreeListBox,0);
	pImp->SelAllDestrAnch(
		bSelect,
		sal_True,		// Anker loeschen,
		sal_True );		// auch bei SINGLE_SELECTION den Cursor deselektieren
}

void SvTreeListBox::ModelHasInsertedTree( SvListEntry* pEntry )
{
	DBG_CHKTHIS(SvTreeListBox,0);
	sal_uInt16 nRefDepth = pModel->GetDepth( (SvLBoxEntry*)pEntry );
	SvLBoxEntry* pTmp = (SvLBoxEntry*)pEntry;
	do
	{
		ImpEntryInserted( pTmp );
		pTmp = Next( pTmp );
	} while( pTmp && nRefDepth < pModel->GetDepth( pTmp ) );
	pImp->TreeInserted( (SvLBoxEntry*)pEntry );
}

void SvTreeListBox::ModelHasInserted( SvListEntry* pEntry )
{
	DBG_CHKTHIS(SvTreeListBox,0);
	ImpEntryInserted( (SvLBoxEntry*)pEntry );
	pImp->EntryInserted( (SvLBoxEntry*)pEntry );
}

void SvTreeListBox::ModelIsMoving(SvListEntry* pSource,
										SvListEntry* /* pTargetParent */,
										sal_uLong /* nChildPos */ )
{
	DBG_CHKTHIS(SvTreeListBox,0);
	pImp->MovingEntry( (SvLBoxEntry*)pSource );
}

void SvTreeListBox::ModelHasMoved( SvListEntry* pSource )
{
	DBG_CHKTHIS(SvTreeListBox,0);
	pImp->EntryMoved( (SvLBoxEntry*)pSource );
}

void SvTreeListBox::ModelIsRemoving( SvListEntry* pEntry )
{
	DBG_CHKTHIS(SvTreeListBox,0);
	if(pEdEntry == pEntry)
		pEdEntry = NULL;

	pImp->RemovingEntry( (SvLBoxEntry*)pEntry );
	NotifyRemoving( (SvLBoxEntry*)pEntry );
}

void SvTreeListBox::ModelHasRemoved( SvListEntry* pEntry  )
{
	DBG_CHKTHIS(SvTreeListBox,0);
    if ( pEntry == pHdlEntry)
        pHdlEntry = NULL;
	pImp->EntryRemoved();
}

void SvTreeListBox::SetCollapsedNodeBmp( const Image& rBmp, BmpColorMode _eMode )
{
	DBG_CHKTHIS(SvTreeListBox,0);
	AdjustEntryHeight( rBmp );
	pImp->SetCollapsedNodeBmp( rBmp, _eMode );
}

void SvTreeListBox::SetExpandedNodeBmp( const Image& rBmp, BmpColorMode _eMode )
{
	DBG_CHKTHIS(SvTreeListBox,0);
	AdjustEntryHeight( rBmp );
	pImp->SetExpandedNodeBmp( rBmp, _eMode );
}


void SvTreeListBox::SetFont( const Font& rFont )
{
	DBG_CHKTHIS(SvTreeListBox,0);
	Font aTempFont( rFont );
	aTempFont.SetTransparent( sal_True );
	Control::SetFont( aTempFont );
	AdjustEntryHeight( aTempFont );
	// immer Invalidieren, sonst fallen wir
	// bei SetEntryHeight auf die Nase
	RecalcViewData();
}


void SvTreeListBox::Paint( const Rectangle& rRect )
{
	DBG_CHKTHIS(SvTreeListBox,0);
	SvLBox::Paint( rRect );
	if( nTreeFlags & TREEFLAG_RECALCTABS )
		SetTabs();
	pImp->Paint( rRect );
}

void SvTreeListBox::MouseButtonDown( const MouseEvent& rMEvt )
{
	DBG_CHKTHIS(SvTreeListBox,0);
	pImp->MouseButtonDown( rMEvt );
}

void SvTreeListBox::MouseButtonUp( const MouseEvent& rMEvt )
{
	DBG_CHKTHIS(SvTreeListBox,0);
	pImp->MouseButtonUp( rMEvt );
}

void SvTreeListBox::MouseMove( const MouseEvent& rMEvt )
{
	DBG_CHKTHIS(SvTreeListBox,0);
	pImp->MouseMove( rMEvt );
}


void SvTreeListBox::SetUpdateMode( sal_Bool bUpdate )
{
	DBG_CHKTHIS(SvTreeListBox,0);
	pImp->SetUpdateMode( bUpdate );
}

void SvTreeListBox::SetUpdateModeFast( sal_Bool bUpdate )
{
	DBG_CHKTHIS(SvTreeListBox,0);
	pImp->SetUpdateModeFast( bUpdate );
}

void SvTreeListBox::SetSpaceBetweenEntries( short nOffsLogic )
{
	DBG_CHKTHIS(SvTreeListBox,0);
	if( nOffsLogic != nEntryHeightOffs )
	{
		nEntryHeight = nEntryHeight - nEntryHeightOffs;
		nEntryHeightOffs = (short)nOffsLogic;
		nEntryHeight = nEntryHeight + nOffsLogic;
		AdjustEntryHeight( GetFont() );
		RecalcViewData();
		pImp->SetEntryHeight( nEntryHeight );
	}
}

void SvTreeListBox::SetCursor( SvLBoxEntry* pEntry, sal_Bool bForceNoSelect )
{
	DBG_CHKTHIS(SvTreeListBox,0);
	pImp->SetCursor(pEntry, bForceNoSelect);
}

void SvTreeListBox::SetCurEntry( SvLBoxEntry* pEntry )
{
	DBG_CHKTHIS(SvTreeListBox,0);
	pImp->SetCurEntry( pEntry );
}

Image SvTreeListBox::GetCollapsedNodeBmp( BmpColorMode _eMode ) const
{
	return pImp->GetCollapsedNodeBmp( _eMode );
}

Image SvTreeListBox::GetExpandedNodeBmp( BmpColorMode _eMode ) const
{
	return pImp->GetExpandedNodeBmp( _eMode );
}

Point SvTreeListBox::GetEntryPosition( SvLBoxEntry* pEntry ) const
{
	return pImp->GetEntryPosition( pEntry );
}

void SvTreeListBox::ShowEntry( SvLBoxEntry* pEntry )
{
	MakeVisible( pEntry );
}

void SvTreeListBox::MakeVisible( SvLBoxEntry* pEntry )
{
	pImp->MakeVisible(pEntry);
}

void SvTreeListBox::MakeVisible( SvLBoxEntry* pEntry, sal_Bool bMoveToTop )
{
	pImp->MakeVisible( pEntry, bMoveToTop );
}

void SvTreeListBox::ModelHasEntryInvalidated( SvListEntry* pEntry )
{
	DBG_CHKTHIS(SvTreeListBox,0);
	// die einzelnen Items des Entries reinitialisieren
	SvLBox::ModelHasEntryInvalidated( pEntry );
	// repainten
	pImp->InvalidateEntry( (SvLBoxEntry*)pEntry );
}

void SvTreeListBox::EditItemText( SvLBoxEntry* pEntry, SvLBoxString* pItem,
	const Selection& rSelection )
{
	DBG_CHKTHIS(SvTreeListBox,0);
	DBG_ASSERT(pEntry&&pItem,"EditItemText: Bad params");
	if( IsSelected( pEntry ))
	{
		pImp->ShowCursor( sal_False );
		SvListView::Select( pEntry, sal_False );
		PaintEntry( pEntry );
		SvListView::Select( pEntry, sal_True );
		pImp->ShowCursor( sal_True );
	}
	pEdEntry = pEntry;
	pEdItem = pItem;
	SvLBoxTab* pTab = GetTab( pEntry, pItem );
	DBG_ASSERT(pTab,"EditItemText:Tab not found");

	Size aItemSize( pItem->GetSize(this, pEntry) );
	Point aPos = GetEntryPosition( pEntry );
	aPos.Y() += ( nEntryHeight - aItemSize.Height() ) / 2;
	aPos.X() = GetTabPos( pEntry, pTab );
	long nOutputWidth = pImp->GetOutputSize().Width();
	Size aSize( nOutputWidth - aPos.X(), aItemSize.Height() );
	sal_uInt16 nPos = aTabs.GetPos( pTab );
	if( nPos+1 < aTabs.Count() )
	{
		SvLBoxTab* pRightTab = (SvLBoxTab*)aTabs.GetObject( nPos + 1 );
		long nRight = GetTabPos( pEntry, pRightTab );
		if( nRight <= nOutputWidth )
			aSize.Width() = nRight - aPos.X();
	}
	Point aOrigin( GetMapMode().GetOrigin() );
	aPos += aOrigin; // in Win-Koord umrechnen
	aSize.Width() -= aOrigin.X();
	Rectangle aRect( aPos, aSize );
#ifdef OS2
	// Platz lassen fuer WB_BORDER
	aRect.Left() -= 2;
	aRect.Top() -= 3;
	aRect.Bottom() += 3;
#endif
	EditText( pItem->GetText(), aRect, rSelection );
}

void SvTreeListBox::CancelEditing()
{
	DBG_CHKTHIS(SvTreeListBox,0);
	SvLBox::CancelTextEditing();
}

void SvTreeListBox::EditEntry( SvLBoxEntry* pEntry )
{
    pImp->aEditClickPos = Point( -1, -1 );
    ImplEditEntry( pEntry );
}

void SvTreeListBox::ImplEditEntry( SvLBoxEntry* pEntry )
{
	DBG_CHKTHIS(SvTreeListBox,0);
	if( IsEditingActive() )
		EndEditing();
	if( !pEntry )
		pEntry = GetCurEntry();
	if( pEntry )
	{
		long nClickX = pImp->aEditClickPos.X();
		bool bIsMouseTriggered = nClickX >= 0;

		SvLBoxString* pItem = NULL;
		sal_uInt16 nCount = pEntry->ItemCount();
		for( sal_uInt16 i = 0 ; i < nCount ; i++ )
		{
			SvLBoxItem* pTmpItem = pEntry->GetItem( i );
			if( pTmpItem->IsA() != SV_ITEM_ID_LBOXSTRING )
				continue;

			SvLBoxTab* pTab = GetTab( pEntry, pTmpItem );
			long nTabPos = pTab->GetPos();
			long nNextTabPos = -1;
			if( i < nCount - 1 )
			{
				SvLBoxItem* pNextItem = pEntry->GetItem( i + 1 );
				SvLBoxTab* pNextTab = GetTab( pEntry, pNextItem );
				nNextTabPos = pNextTab->GetPos();
			}

			if( pTab && pTab->IsEditable() )
			{
				if( !bIsMouseTriggered || (nClickX > nTabPos && (nNextTabPos == -1 || nClickX < nNextTabPos ) ) )
				{
					pItem = static_cast<SvLBoxString*>( pTmpItem );
					break;
				}
			}
		}

		Selection aSel( SELECTION_MIN, SELECTION_MAX );
		if( pItem && EditingEntry( pEntry, aSel ) )
		{
			SelectAll( sal_False );
			MakeVisible( pEntry );
			EditItemText( pEntry, pItem, aSel );
		}
	}
}

sal_Bool SvTreeListBox::AreChildrenTransient() const
{
    return pImp->AreChildrenTransient();
}

void SvTreeListBox::SetChildrenNotTransient()
{
    pImp->SetChildrenNotTransient();
}

void SvTreeListBox::EditedText( const XubString& rStr )

{
	DBG_CHKTHIS(SvTreeListBox,0);
	if(pEdEntry) // we have to check if this entry is null that means that it is removed while editing
	{
		Point aPos = GetEntryPosition( pEdEntry );
		if( EditedEntry( pEdEntry, rStr ) )
		{
			((SvLBoxString*)pEdItem)->SetText( pEdEntry, rStr );
			pModel->InvalidateEntry( pEdEntry );
		}
		//if( GetSelectionMode() == SINGLE_SELECTION )
		//{
		if( GetSelectionCount() == 0 )
			Select( pEdEntry );
		if( GetSelectionMode() == MULTIPLE_SELECTION && !GetCurEntry() )
			SetCurEntry( pEdEntry );
		//}
	}
}

void SvTreeListBox::EditingRequest( SvLBoxEntry* pEntry, SvLBoxItem* pItem,
									const Point& )
{
	DBG_CHKTHIS(SvTreeListBox,0);
	if( IsEditingActive() )
		EndEditing();
	if( pItem->IsA() == SV_ITEM_ID_LBOXSTRING )
	{
		Selection aSel( SELECTION_MIN, SELECTION_MAX );
		if( EditingEntry( pEntry, aSel ) )
		{
			SelectAll( sal_False );
			EditItemText( pEntry, (SvLBoxString*)pItem, aSel );
		}
	}
}



SvLBoxEntry* SvTreeListBox::GetDropTarget( const Point& rPos )
{
	DBG_CHKTHIS(SvTreeListBox,0);
	// Scrollen
	if( rPos.Y() < 12 )
	{
		SvLBox::ImplShowTargetEmphasis( SvLBox::pTargetEntry, sal_False );
		ScrollOutputArea( +1 );
	}
	else
	{
		Size aSize( pImp->GetOutputSize() );
		if( rPos.Y() > aSize.Height() - 12 )
		{
			SvLBox::ImplShowTargetEmphasis( SvLBox::pTargetEntry, sal_False );
			ScrollOutputArea( -1 );
		}
	}

	SvLBoxEntry* pTarget = pImp->GetEntry( rPos );
	// bei Droppen in leere Flaeche -> den letzten Eintrag nehmen
	if( !pTarget )
		return (SvLBoxEntry*)LastVisible();
	else if( (GetDragDropMode() & SV_DRAGDROP_ENABLE_TOP) &&
			 pTarget == First() && rPos.Y() < 6 )
		return 0;

	return pTarget;
}


SvLBoxEntry* SvTreeListBox::GetEntry( const Point& rPos, sal_Bool bHit ) const
{
	DBG_CHKTHIS(SvTreeListBox,0);
	SvLBoxEntry* pEntry = pImp->GetEntry( rPos );
	if( pEntry && bHit )
	{
		long nLine = pImp->GetEntryLine( pEntry );
		if( !(pImp->EntryReallyHit( pEntry, rPos, nLine)) )
			return 0;
	}
	return pEntry;
}

SvLBoxEntry* SvTreeListBox::GetCurEntry() const
{
	DBG_CHKTHIS(SvTreeListBox,0);
	return pImp->GetCurEntry();
}

void SvTreeListBox::ImplInitStyle()
{
	DBG_CHKTHIS(SvTreeListBox,0);

    const WinBits nWindowStyle = GetStyle();

	nTreeFlags |= TREEFLAG_RECALCTABS;
	if( nWindowStyle & WB_SORT )
	{
		GetModel()->SetSortMode( SortAscending );
		GetModel()->SetCompareHdl( LINK(this,SvTreeListBox,DefaultCompare));
	}
	else
	{
		GetModel()->SetSortMode( SortNone );
		GetModel()->SetCompareHdl( Link() );
	}
	pImp->SetStyle( nWindowStyle );
	pImp->Resize();
	Invalidate();
}

void SvTreeListBox::PaintEntry( SvLBoxEntry* pEntry )
{
	DBG_CHKTHIS(SvTreeListBox,0);
	DBG_ASSERT(pEntry,"PaintEntry:No Entry");
	if( pEntry )
		pImp->PaintEntry( pEntry );
}

void SvTreeListBox::InvalidateEntry( SvLBoxEntry* pEntry )
{
	DBG_CHKTHIS(SvTreeListBox,0);
	DBG_ASSERT(pEntry,"InvalidateEntry:No Entry");
	if( pEntry )
	{
		GetModel()->InvalidateEntry( pEntry );
	//	pImp->InvalidateEntry( pEntry );
	}
}


long SvTreeListBox::PaintEntry(SvLBoxEntry* pEntry,long nLine,sal_uInt16 nTabFlags)
{
	return PaintEntry1(pEntry,nLine,nTabFlags);
}

#define SV_TAB_BORDER 8

long SvTreeListBox::PaintEntry1(SvLBoxEntry* pEntry,long nLine,sal_uInt16 nTabFlags,
	sal_Bool bHasClipRegion )
{
	DBG_CHKTHIS(SvTreeListBox,0);

	Rectangle aRect; // multi purpose

	sal_Bool bHorSBar = pImp->HasHorScrollBar();
	PreparePaint( pEntry );

	// #97680# ------------------
	pImp->UpdateContextBmpWidthMax( pEntry );

	if( nTreeFlags & TREEFLAG_RECALCTABS )
		SetTabs();

	short nTempEntryHeight = GetEntryHeight();
	long nWidth = pImp->GetOutputSize().Width();

	// wurde innerhalb des PreparePaints die horizontale ScrollBar
	// angeschaltet? Wenn ja, muss die ClipRegion neu gesetzt werden
	if( !bHorSBar && pImp->HasHorScrollBar() )
		SetClipRegion( Region(pImp->GetClipRegionRect()) );

	Point aEntryPos( GetMapMode().GetOrigin() );
	aEntryPos.X() *= -1; // Umrechnung Dokumentkoord.
	long nMaxRight = nWidth + aEntryPos.X() - 1;

	Color aBackupTextColor( GetTextColor() );
    Font aBackupFont( GetFont() );
	Color aBackupColor = GetFillColor();

	bool bCurFontIsSel = false;
	sal_Bool bInUse = pEntry->HasInUseEmphasis();
	// wenn eine ClipRegion von aussen gesetzt wird, dann
	// diese nicht zuruecksetzen
    const WinBits nWindowStyle = GetStyle();
	const sal_Bool bResetClipRegion = !bHasClipRegion;
	const sal_Bool bHideSelection = ((nWindowStyle & WB_HIDESELECTION) && !HasFocus())!=0;
	const StyleSettings& rSettings = GetSettings().GetStyleSettings();

    Font aHighlightFont( GetFont() );
    const Color aHighlightTextColor( rSettings.GetHighlightTextColor() );
    aHighlightFont.SetColor( aHighlightTextColor );

	Size aRectSize( 0, nTempEntryHeight );

	if( !bHasClipRegion && nWindowStyle & WB_HSCROLL )
	{
		SetClipRegion( Region(pImp->GetClipRegionRect()) );
		bHasClipRegion = sal_True;
	}

	SvViewDataEntry* pViewDataEntry = GetViewDataEntry( pEntry );

	sal_uInt16 nTabCount = aTabs.Count();
	sal_uInt16 nItemCount = pEntry->ItemCount();
	sal_uInt16 nCurTab = 0;
	sal_uInt16 nCurItem = 0;

	while( nCurTab < nTabCount && nCurItem < nItemCount )
	{
		SvLBoxTab* pTab = (SvLBoxTab*)aTabs.GetObject( nCurTab );
		sal_uInt16 nNextTab = nCurTab + 1;
		SvLBoxTab* pNextTab = nNextTab < nTabCount ? (SvLBoxTab*)aTabs.GetObject(nNextTab) : 0;
		SvLBoxItem* pItem = nCurItem < nItemCount ? pEntry->GetItem(nCurItem) : 0;

		sal_uInt16 nFlags = pTab->nFlags;
		Size aSize( pItem->GetSize( pViewDataEntry, nCurItem ));
		long nTabPos = GetTabPos( pEntry, pTab );

		long nNextTabPos;
		if( pNextTab )
			nNextTabPos = GetTabPos( pEntry, pNextTab );
		else
		{
			nNextTabPos = nMaxRight;
			if( nTabPos > nMaxRight )
				nNextTabPos += 50;
		}

		long nX;
		if( pTab->nFlags & SV_LBOXTAB_ADJUST_RIGHT )
			//verhindern, das rechter Rand von der Tabtrennung abgeschnitten wird
			nX = nTabPos + pTab->CalcOffset(aSize.Width(), (nNextTabPos-SV_TAB_BORDER-1) -nTabPos);
		else
			nX = nTabPos + pTab->CalcOffset(aSize.Width(), nNextTabPos-nTabPos);

		if( nFlags & nTabFlags )
		{
			if( !bHasClipRegion && nX + aSize.Width() >= nMaxRight )
			{
				SetClipRegion( Region(pImp->GetClipRegionRect()) );
				bHasClipRegion = sal_True;
			}
			aEntryPos.X() = nX;
			aEntryPos.Y() = nLine;

			// Hintergrund-Muster & Farbe bestimmen

			Wallpaper aWallpaper = GetBackground();

			int bSelTab = nFlags & SV_LBOXTAB_SHOW_SELECTION;
			sal_uInt16 nItemType = pItem->IsA();

            if ( pViewDataEntry->IsSelected() && bSelTab && !pViewDataEntry->IsCursored() )
			{
                Color aNewWallColor = rSettings.GetHighlightColor();
                if ( !bInUse || nItemType != SV_ITEM_ID_LBOXCONTEXTBMP )
				{
					// if the face color is bright then the deactive color is also bright
					// -> so you can't see any deactive selection
                    if ( bHideSelection && !rSettings.GetFaceColor().IsBright() &&
                         aWallpaper.GetColor().IsBright() != rSettings.GetDeactiveColor().IsBright() )
                        aNewWallColor = rSettings.GetDeactiveColor();
					// set font color to highlight
                    if ( !bCurFontIsSel )
					{
						SetTextColor( aHighlightTextColor );
                        SetFont( aHighlightFont );
						bCurFontIsSel = true;
					}
				}
                aWallpaper.SetColor( aNewWallColor );
			}
			else  // keine Selektion
			{
				if( bInUse && nItemType == SV_ITEM_ID_LBOXCONTEXTBMP )
					aWallpaper.SetColor( rSettings.GetFieldColor() );
				else if( bCurFontIsSel )
				{
					bCurFontIsSel = false;
                    SetTextColor( aBackupTextColor );
                    SetFont( aBackupFont );
				}
			}

			// Hintergrund zeichnen
			if( !(nTreeFlags & TREEFLAG_USESEL))
			{
				// nur den Bereich zeichnen, den das Item einnimmt
				aRectSize.Width() = aSize.Width();
				aRect.SetPos( aEntryPos );
				aRect.SetSize( aRectSize );
			}
			else
			{
				// vom aktuellen bis zum naechsten Tab zeichnen
				if( nCurTab != 0 )
					aRect.Left() = nTabPos;
				else
					// beim nullten Tab immer ab Spalte 0 zeichnen
					// (sonst Probleme bei Tabs mit Zentrierung)
					aRect.Left() = 0;
				aRect.Top() = nLine;
				aRect.Bottom() = nLine + nTempEntryHeight - 1;
				if( pNextTab )
				{
					long nRight;
					nRight = GetTabPos(pEntry,pNextTab)-1;
					if( nRight > nMaxRight )
						nRight = nMaxRight;
					aRect.Right() = nRight;
				}
				else
					aRect.Right() = nMaxRight;
			}
			// bei anwenderdefinierter Selektion, die bei einer Tabposition
			// groesser 0 beginnt den Hintergrund des 0.ten Items nicht
			// fuellen, da sonst z.B. TablistBoxen mit Linien nicht
			// realisiert werden koennen.
			if( !(nCurTab==0 && (nTreeFlags & TREEFLAG_USESEL) && nFirstSelTab) )
			{
				SetFillColor( aWallpaper.GetColor() );
				// Bei kleinen hor. Resizes tritt dieser Fall auf
				if( aRect.Left() < aRect.Right() )
					DrawRect( aRect );
			}
			// Item zeichnen
			// vertikal zentrieren
			aEntryPos.Y() += ( nTempEntryHeight - aSize.Height() ) / 2;
			pItem->Paint( aEntryPos, *this, pViewDataEntry->GetFlags(), pEntry );

			// Trennungslinie zwischen Tabs
			if( pNextTab && pItem->IsA() == SV_ITEM_ID_LBOXSTRING &&
				// nicht am rechten Fensterrand!
				aRect.Right() < nMaxRight )
			{
				aRect.Left() = aRect.Right() - SV_TAB_BORDER;
				DrawRect( aRect );
			}

			SetFillColor( aBackupColor );
		}
		nCurItem++;
		nCurTab++;
	}
	if( pViewDataEntry->IsCursored() && !HasFocus() )
	{
		// Cursor-Emphasis
		SetFillColor();
		Color aOldLineColor = GetLineColor();
		SetLineColor( Color( COL_BLACK ) );
		aRect = GetFocusRect( pEntry, nLine );
		aRect.Top()++;
		aRect.Bottom()--;
		DrawRect( aRect );
		SetLineColor( aOldLineColor );
		SetFillColor( aBackupColor );
	}

	if( bCurFontIsSel )
    {
		SetTextColor( aBackupTextColor );
        SetFont( aBackupFont );
    }

	sal_uInt16 nFirstDynTabPos;
	SvLBoxTab* pFirstDynamicTab = GetFirstDynamicTab( nFirstDynTabPos );
	long nDynTabPos = GetTabPos( pEntry, pFirstDynamicTab );
	nDynTabPos += pImp->nNodeBmpTabDistance;
	nDynTabPos += pImp->nNodeBmpWidth / 2;
	nDynTabPos += 4; // 4 Pixel Reserve, damit die Node-Bitmap
					 // nicht zu nah am naechsten Tab steht

	if( (!(pEntry->GetFlags() & SV_ENTRYFLAG_NO_NODEBMP)) &&
		(nWindowStyle & WB_HASBUTTONS) && pFirstDynamicTab &&
		( pEntry->HasChilds() || pEntry->HasChildsOnDemand() ) )
	{
		// ersten festen Tab suchen, und pruefen ob die Node-Bitmap
		// in ihn hineinragt
		sal_uInt16 nNextTab = nFirstDynTabPos;
		SvLBoxTab* pNextTab;
		do
		{
			nNextTab++;
			pNextTab = nNextTab < nTabCount ? (SvLBoxTab*)aTabs.GetObject(nNextTab) : 0;
		} while( pNextTab && pNextTab->IsDynamic() );

		if( !pNextTab || (GetTabPos( pEntry, pNextTab ) > nDynTabPos) )
		{
			if((nWindowStyle & WB_HASBUTTONSATROOT) || pModel->GetDepth(pEntry) > 0)
			{
				Point aPos( GetTabPos(pEntry,pFirstDynamicTab), nLine );
				aPos.X() += pImp->nNodeBmpTabDistance;

				const Image* pImg = 0;
				BmpColorMode eBitmapMode = BMP_COLOR_NORMAL;
				if ( GetSettings().GetStyleSettings().GetHighContrastMode() )
					eBitmapMode = BMP_COLOR_HIGHCONTRAST;

				if( IsExpanded(pEntry) )
					pImg = &pImp->GetExpandedNodeBmp( eBitmapMode );
				else
				{
					if( (!pEntry->HasChilds()) && pEntry->HasChildsOnDemand() &&
						(!(pEntry->GetFlags() & SV_ENTRYFLAG_HAD_CHILDREN)) &&
						pImp->GetDontKnowNodeBmp().GetSizePixel().Width() )
						pImg = &pImp->GetDontKnowNodeBmp( eBitmapMode );
					else
						pImg = &pImp->GetCollapsedNodeBmp( eBitmapMode );
				}
				aPos.Y() += (nTempEntryHeight - pImg->GetSizePixel().Height()) / 2;

				sal_uInt16 nStyle = 0;
				if ( !IsEnabled() )
					nStyle |= IMAGE_DRAW_DISABLE;

				//native
				sal_Bool bNativeOK = sal_False;
				if ( IsNativeControlSupported( CTRL_LISTNODE, PART_ENTIRE_CONTROL) )
				{
					ImplControlValue	aControlValue;
					Rectangle           aCtrlRegion( aPos,  pImg->GetSizePixel() );
					ControlState		nState = 0;

					if ( IsEnabled() )	nState |= CTRL_STATE_ENABLED;

					if ( IsExpanded(pEntry) )
						aControlValue.setTristateVal( BUTTONVALUE_ON );//expanded node
					else
					{
						if( (!pEntry->HasChilds()) && pEntry->HasChildsOnDemand() &&
							(!(pEntry->GetFlags() & SV_ENTRYFLAG_HAD_CHILDREN)) &&
							pImp->GetDontKnowNodeBmp().GetSizePixel().Width() )
							aControlValue.setTristateVal( BUTTONVALUE_DONTKNOW );//dont know
						else
							aControlValue.setTristateVal( BUTTONVALUE_OFF );//collapsed node
					}

					bNativeOK = DrawNativeControl( CTRL_LISTNODE, PART_ENTIRE_CONTROL,
											aCtrlRegion, nState, aControlValue, rtl::OUString() );
				}

				if( !bNativeOK) {
				//non native
					DrawImage( aPos, *pImg ,nStyle);
				}
			}
		}
	}


	if( bHasClipRegion && bResetClipRegion )
		SetClipRegion();
	return 0; // nRowLen;
}

void SvTreeListBox::PreparePaint( SvLBoxEntry* )
{
}

Rectangle SvTreeListBox::GetFocusRect( SvLBoxEntry* pEntry, long nLine )
{
	DBG_CHKTHIS(SvTreeListBox,0);
	Size aSize;
	Rectangle aRect;
	aRect.Top() = nLine;
	aSize.Height() = GetEntryHeight();

	long nRealWidth = pImp->GetOutputSize().Width();
	nRealWidth -= GetMapMode().GetOrigin().X();

	sal_uInt16 nCurTab;
	SvLBoxTab* pTab = GetFirstTab( SV_LBOXTAB_SHOW_SELECTION, nCurTab );
	long nTabPos = 0;
	if( pTab )
		nTabPos = GetTabPos( pEntry, pTab );
	long nNextTabPos;
	if( pTab && nCurTab < aTabs.Count() - 1 )
	{
		SvLBoxTab* pNextTab = (SvLBoxTab*)aTabs.GetObject( nCurTab + 1 );
		nNextTabPos = GetTabPos( pEntry, pNextTab );
	}
	else
	{
		nNextTabPos = nRealWidth;
		if( nTabPos > nRealWidth )
			nNextTabPos += 50;
	}

	sal_Bool bUserSelection = (sal_Bool)( nTreeFlags & TREEFLAG_USESEL ) != 0;
	if( !bUserSelection )
	{
		if( pTab && nCurTab < pEntry->ItemCount() )
		{
			SvLBoxItem* pItem = pEntry->GetItem( nCurTab );
			aSize.Width() = pItem->GetSize( this, pEntry ).Width();
			if( !aSize.Width() )
				aSize.Width() = 15;
			long nX = nTabPos; //GetTabPos( pEntry, pTab );
			// Ausrichtung
			nX += pTab->CalcOffset( aSize.Width(), nNextTabPos - nTabPos );
			aRect.Left() = nX;
			// damit erster & letzter Buchstabe nicht angeknabbert werden
			aRect.SetSize( aSize );
			if( aRect.Left() > 0 )
				aRect.Left()--;
			aRect.Right()++;
		}
	}
	else
	{
		// wenn erster SelTab != 0, dann muessen wir auch rechnen
		if( nFocusWidth == -1 || nFirstSelTab )
		{
			sal_uInt16 nLastTab;
			SvLBoxTab* pLastTab = GetLastTab(SV_LBOXTAB_SHOW_SELECTION,nLastTab);
			nLastTab++;
			if( nLastTab < aTabs.Count() ) // gibts noch einen ?
				pLastTab = (SvLBoxTab*)aTabs.GetObject( nLastTab );
			else
				pLastTab = 0;  // ueber gesamte Breite selektieren
			aSize.Width() = pLastTab ? pLastTab->GetPos() : 0x0fffffff;
			nFocusWidth = (short)aSize.Width();
			if( pTab )
				nFocusWidth = nFocusWidth - (short)nTabPos; //pTab->GetPos();
		}
		else
		{
			aSize.Width() = nFocusWidth;
			if( pTab )
			{
				if( nCurTab )
					aSize.Width() += nTabPos;
				else
					aSize.Width() += pTab->GetPos(); // Tab0 immer ab ganz links
			}
		}
		// wenn Sel. beim nullten Tab anfaengt, dann ab Spalte 0 sel. zeichnen
		if( nCurTab != 0 )
		{
			aRect.Left() = nTabPos;
			aSize.Width() -= nTabPos;
		}
		aRect.SetSize( aSize );
	}
	// rechten Rand anpassen wg. Clipping
	if( aRect.Right() >= nRealWidth )
	{
		aRect.Right() = nRealWidth-1;
		nFocusWidth = (short)aRect.GetWidth();
	}
	return aRect;
}


long SvTreeListBox::GetTabPos( SvLBoxEntry* pEntry, SvLBoxTab* pTab)
{
	DBG_CHKTHIS(SvTreeListBox,0);
	DBG_ASSERT(pTab,"No Tab");
	long nPos = pTab->GetPos();
	if( pTab->IsDynamic() )
	{
		sal_uInt16 nDepth = pModel->GetDepth( pEntry );
		nDepth = nDepth * (sal_uInt16)nIndent;
		nPos += (long)nDepth;
	}
	return nPos;
}

SvLBoxItem* SvTreeListBox::GetItem_Impl( SvLBoxEntry* pEntry, long nX,
	SvLBoxTab** ppTab, sal_uInt16 nEmptyWidth )
{
	DBG_CHKTHIS(SvTreeListBox,0);
	SvLBoxItem* pItemClicked = 0;
	sal_uInt16 nTabCount = aTabs.Count();
	sal_uInt16 nItemCount = pEntry->ItemCount();
	SvLBoxTab* pTab = (SvLBoxTab*)aTabs.GetObject(0);
	SvLBoxItem* pItem = pEntry->GetItem(0);
	sal_uInt16 nNextItem = 1;
	nX -= GetMapMode().GetOrigin().X();
	long nRealWidth = pImp->GetOutputSize().Width();
	nRealWidth -= GetMapMode().GetOrigin().X();

	while( 1 )
	{
		SvLBoxTab* pNextTab=nNextItem<nTabCount ? (SvLBoxTab*)aTabs.GetObject(nNextItem) : 0;
		long nStart = GetTabPos( pEntry, pTab );

		long nNextTabPos;
		if( pNextTab )
			nNextTabPos = GetTabPos( pEntry, pNextTab );
		else
		{
			nNextTabPos = nRealWidth;
			if( nStart > nRealWidth )
				nNextTabPos += 50;
		}

		Size aItemSize( pItem->GetSize(this, pEntry));
		nStart += pTab->CalcOffset( aItemSize.Width(), nNextTabPos - nStart );
		long nLen = aItemSize.Width();
		if( pNextTab )
		{
			long nTabWidth = GetTabPos( pEntry, pNextTab ) - nStart;
			if( nTabWidth < nLen )
				nLen = nTabWidth;
		}

		if( !nLen )
			nLen = nEmptyWidth;

		if( nX >= nStart && nX < (nStart+nLen ) )
		{
			pItemClicked = pItem;
			if( ppTab )
			{
				*ppTab = pTab;
				break;
			}
		}
		if( nNextItem >= nItemCount || nNextItem >= nTabCount)
			break;
		pTab = (SvLBoxTab*)aTabs.GetObject( nNextItem );
		pItem = pEntry->GetItem( nNextItem );
		nNextItem++;
	}
	return pItemClicked;
}

SvLBoxItem* SvTreeListBox::GetItem(SvLBoxEntry* pEntry,long nX,SvLBoxTab** ppTab)
{
	return GetItem_Impl( pEntry, nX, ppTab, 0 );
}

SvLBoxItem* SvTreeListBox::GetItem(SvLBoxEntry* pEntry,long nX )
{
	DBG_CHKTHIS(SvTreeListBox,0);
	SvLBoxTab* pDummyTab;
	return GetItem_Impl( pEntry, nX, &pDummyTab, 0 );
}

SvLBoxItem* SvTreeListBox::GetFirstDynamicItem( SvLBoxEntry* pEntry )
{
	DBG_CHKTHIS(SvTreeListBox,0);

	SvLBoxTab* pTab = (SvLBoxTab*)aTabs.GetObject(0);
	SvLBoxItem* pItem = pEntry->GetItem(0);
	sal_uInt16 nTabCount = aTabs.Count();

	sal_uInt16 nNext = 1;
	while ( !pTab->IsDynamic() && nNext < nTabCount )
	{
		pItem = pEntry->GetItem( nNext );
		pTab = (SvLBoxTab*)aTabs.GetObject( nNext );
		nNext++;
	}
	return pItem;
}

void SvTreeListBox::AddTab(long nTabPos,sal_uInt16 nFlags,void* pUserData )
{
	DBG_CHKTHIS(SvTreeListBox,0);
	nFocusWidth = -1;
	SvLBoxTab* pTab = new SvLBoxTab( nTabPos, nFlags );
	pTab->SetUserData( pUserData );
	aTabs.Insert( pTab, aTabs.Count() );
	if( nTreeFlags & TREEFLAG_USESEL )
	{
		sal_uInt16 nPos = aTabs.Count() - 1;
		if( nPos >= nFirstSelTab && nPos <= nLastSelTab )
			pTab->nFlags |= SV_LBOXTAB_SHOW_SELECTION;
		else
			// String-Items werden normalerweise immer selektiert
			// deshalb explizit ausschalten
			pTab->nFlags &= ~SV_LBOXTAB_SHOW_SELECTION;
	}
}



SvLBoxTab* SvTreeListBox::GetFirstDynamicTab( sal_uInt16& rPos ) const
{
	DBG_CHKTHIS(SvTreeListBox,0);
	sal_uInt16 nCurTab = 0;
	sal_uInt16 nTabCount = aTabs.Count();
	while( nCurTab < nTabCount )
	{
		SvLBoxTab* pTab = (SvLBoxTab*)aTabs.GetObject(nCurTab);
		if( pTab->nFlags & SV_LBOXTAB_DYNAMIC )
		{
			rPos = nCurTab;
			return pTab;
		}
		nCurTab++;
	}
	return 0;
}

SvLBoxTab* SvTreeListBox::GetFirstDynamicTab() const
{
	sal_uInt16 nDummy;
	return GetFirstDynamicTab( nDummy );
}

SvLBoxTab* SvTreeListBox::GetTab( SvLBoxEntry* pEntry, SvLBoxItem* pItem) const
{
	DBG_CHKTHIS(SvTreeListBox,0);
	sal_uInt16 nPos = pEntry->GetPos( pItem );
	return (SvLBoxTab*)aTabs.GetObject( nPos );
}

void SvTreeListBox::ClearTabList()
{
	DBG_CHKTHIS(SvTreeListBox,0);
	sal_uInt16 nTabCount = aTabs.Count();
	while( nTabCount )
	{
		nTabCount--;
		SvLBoxTab* pDelTab = (SvLBoxTab*)aTabs.GetObject( nTabCount );
		delete pDelTab;
	}
	aTabs.Remove(0,aTabs.Count());
}


Size SvTreeListBox::GetOutputSizePixel() const
{
	DBG_CHKTHIS(SvTreeListBox,0);
	Size aSize = pImp->GetOutputSize();
	return aSize;
}

void SvTreeListBox::NotifyBeginScroll()
{
	DBG_CHKTHIS(SvTreeListBox,0);
}

void SvTreeListBox::NotifyEndScroll()
{
	DBG_CHKTHIS(SvTreeListBox,0);
}

void SvTreeListBox::NotifyScrolling( long )
{
	DBG_CHKTHIS(SvTreeListBox,0);
}

void SvTreeListBox::NotifyScrolled()
{
	DBG_CHKTHIS(SvTreeListBox,0);
	aScrolledHdl.Call( this );
}

void SvTreeListBox::NotifyInvalidating()
{
	DBG_CHKTHIS(SvTreeListBox,0);
}

void SvTreeListBox::Invalidate( sal_uInt16 nInvalidateFlags )
{
	DBG_CHKTHIS(SvTreeListBox,0);
	if( nFocusWidth == -1 )
		// damit Control nicht nach dem Paint ein falsches FocusRect anzeigt
		pImp->RecalcFocusRect();
	NotifyInvalidating();
	SvLBox::Invalidate( nInvalidateFlags );
	pImp->Invalidate();
}

void SvTreeListBox::Invalidate( const Rectangle& rRect, sal_uInt16 nInvalidateFlags )
{
	DBG_CHKTHIS(SvTreeListBox,0);
	if( nFocusWidth == -1 )
		// damit Control nicht nach dem Paint ein falsches FocusRect anzeigt
		pImp->RecalcFocusRect();
	NotifyInvalidating();
	SvLBox::Invalidate( rRect, nInvalidateFlags );
}


void SvTreeListBox::SetHighlightRange( sal_uInt16 nStart, sal_uInt16 nEnd)
{
	DBG_CHKTHIS(SvTreeListBox,0);

	sal_uInt16 nTemp;
	nTreeFlags |= TREEFLAG_USESEL;
	if( nStart > nEnd )
	{
		nTemp = nStart;
		nStart = nEnd;
		nEnd = nTemp;
	}
	// alle Tabs markieren, die im Bereich liegen
	nTreeFlags |= TREEFLAG_RECALCTABS;
	nFirstSelTab = nStart;
	nLastSelTab = nEnd;
	pImp->RecalcFocusRect();
}

void SvTreeListBox::RemoveHighlightRange()
{
	DBG_CHKTHIS(SvTreeListBox,0);
	nTreeFlags &= (~TREEFLAG_USESEL);
	if( IsUpdateMode() )
		Invalidate();
}

sal_uLong SvTreeListBox::GetAscInsertionPos(SvLBoxEntry*,SvLBoxEntry*)
{
	return LIST_APPEND;
}

sal_uLong SvTreeListBox::GetDescInsertionPos(SvLBoxEntry*,SvLBoxEntry*)
{
	DBG_CHKTHIS(SvTreeListBox,0);
	return LIST_APPEND;
}

Region SvTreeListBox::GetDragRegion() const
{
	DBG_CHKTHIS(SvTreeListBox,0);
	Rectangle aRect;
	SvLBoxEntry* pEntry = GetCurEntry();
	if( pEntry )
	{
		Point aPos = GetEntryPosition( pEntry );
		aRect = ((SvTreeListBox*)this)->GetFocusRect( pEntry, aPos.Y() );
	}
	Region aRegion( aRect );
	return aRegion;
}


void SvTreeListBox::Command( const CommandEvent& rCEvt )
{
	DBG_CHKTHIS(SvTreeListBox,0);
    // FIXME gnumake2 resync to DEV300_m84
	pImp->Command( rCEvt );
}


void SvTreeListBox::RemoveParentKeepChilds( SvLBoxEntry* pParent )
{
	DBG_CHKTHIS(SvTreeListBox,0);
	DBG_ASSERT(pParent,"RemoveParentKeepChilds:No Parent");
	SvLBoxEntry* pNewParent = GetParent( pParent );
	if( pParent->HasChilds())
	{
		SvLBoxEntry* pChild = FirstChild( pParent );
		while( pChild )
		{
			pModel->Move( pChild, pNewParent, LIST_APPEND );
			pChild = FirstChild( pParent );
		}
	}
	pModel->Remove( pParent );
}

SvLBoxTab* SvTreeListBox::GetFirstTab( sal_uInt16 nFlagMask, sal_uInt16& rPos )
{
	sal_uInt16 nTabCount = aTabs.Count();
	for( sal_uInt16 nPos = 0; nPos < nTabCount; nPos++ )
	{
		SvLBoxTab* pTab = (SvLBoxTab*)aTabs.GetObject( nPos );
		if( (pTab->nFlags & nFlagMask) )
		{
			rPos = nPos;
			return pTab;
		}
	}
	rPos = 0xffff;
	return 0;
}

SvLBoxTab* SvTreeListBox::GetLastTab( sal_uInt16 nFlagMask, sal_uInt16& rTabPos )
{
	short nTabCount = (short)aTabs.Count();
	if( nTabCount )
	{
		for( short nPos = nTabCount-1; nPos >= 0; nPos-- )
		{
			SvLBoxTab* pTab = (SvLBoxTab*)aTabs.GetObject( (sal_uInt16)nPos );
			if( (pTab->nFlags & nFlagMask) )
			{
				rTabPos = (sal_uInt16)nPos;
				return pTab;
			}
		}
	}
	rTabPos = 0xffff;
	return 0;
}

void SvTreeListBox::SetAddMode( sal_Bool bAdd )
{
	pImp->SetAddMode( bAdd );
}

sal_Bool SvTreeListBox::IsAddMode() const
{
	return pImp->IsAddMode();
}

void SvTreeListBox::RequestHelp( const HelpEvent& rHEvt )
{
	if( !pImp->RequestHelp( rHEvt ) )
		SvLBox::RequestHelp( rHEvt );
}

void SvTreeListBox::CursorMoved( SvLBoxEntry* )
{
}

IMPL_LINK( SvTreeListBox, DefaultCompare, SvSortData*, pData )
{
	SvLBoxEntry* pLeft = (SvLBoxEntry*)(pData->pLeft );
	SvLBoxEntry* pRight = (SvLBoxEntry*)(pData->pRight );
	String aLeft( ((SvLBoxString*)(pLeft->GetFirstItem(SV_ITEM_ID_LBOXSTRING)))->GetText());
	String aRight( ((SvLBoxString*)(pRight->GetFirstItem(SV_ITEM_ID_LBOXSTRING)))->GetText());
	// #102891# ----------------
	pImp->UpdateIntlWrapper();
	return pImp->pIntlWrapper->getCaseCollator()->compareString( aLeft, aRight );
}

void SvTreeListBox::ModelNotification( sal_uInt16 nActionId, SvListEntry* pEntry1,
						SvListEntry* pEntry2, sal_uLong nPos )
{
	if( nActionId == LISTACTION_CLEARING )
		CancelTextEditing();

	SvLBox::ModelNotification( nActionId, pEntry1, pEntry2, nPos );
	switch( nActionId )
	{
        case LISTACTION_INSERTED:
        {
            SvLBoxEntry* pEntry( dynamic_cast< SvLBoxEntry* >( pEntry1 ) );
            ENSURE_OR_BREAK( pEntry, "SvTreeListBox::ModelNotification: invalid entry!" );
            SvLBoxContextBmp* pBmpItem = static_cast< SvLBoxContextBmp* >( pEntry->GetFirstItem( SV_ITEM_ID_LBOXCONTEXTBMP ) );
            if ( !pBmpItem )
                break;
            const Image& rBitmap1( pBmpItem->GetBitmap1() );
            const Image& rBitmap2( pBmpItem->GetBitmap2() );
            short nMaxWidth = short( Max( rBitmap1.GetSizePixel().Width(), rBitmap2.GetSizePixel().Width() ) );
	        nMaxWidth = pImp->UpdateContextBmpWidthVector( pEntry, nMaxWidth );
	        if( nMaxWidth > nContextBmpWidthMax )
	        {
		        nContextBmpWidthMax = nMaxWidth;
		        SetTabs();
	        }
        }
        break;

		case LISTACTION_RESORTING:
			SetUpdateMode( sal_False );
			break;

		case LISTACTION_RESORTED:
			// nach Sortierung den ersten Eintrag anzeigen, dabei die
			// Selektion erhalten.
			MakeVisible( (SvLBoxEntry*)pModel->First(), sal_True );
			SetUpdateMode( sal_True );
			break;

		case LISTACTION_CLEARED:
			if( IsUpdateMode() )
				Update();
			break;
	}
}

// bei Aenderungen SetTabs beruecksichtigen
long SvTreeListBox::GetTextOffset() const
{
	DBG_CHKTHIS(SvTreeListBox,0);
    const WinBits nWindowStyle = GetStyle();
	sal_Bool bHasButtons = (nWindowStyle & WB_HASBUTTONS)!=0;
	sal_Bool bHasButtonsAtRoot = (nWindowStyle & (WB_HASLINESATROOT |
											  WB_HASBUTTONSATROOT))!=0;
	long nStartPos = TAB_STARTPOS;
	long nNodeWidthPixel = GetExpandedNodeBmp().GetSizePixel().Width();

	long nCheckWidth = 0;
	if( nTreeFlags & TREEFLAG_CHKBTN )
		nCheckWidth = pCheckButtonData->aBmps[0].GetSizePixel().Width();
	long nCheckWidthDIV2 = nCheckWidth / 2;

	long nContextWidth = nContextBmpWidthMax;
	long nContextWidthDIV2 = nContextWidth / 2;

	int nCase = NO_BUTTONS;
	if( !(nTreeFlags & TREEFLAG_CHKBTN) )
	{
		if( bHasButtons )
			nCase = NODE_BUTTONS;
	}
	else
	{
		if( bHasButtons )
			nCase = NODE_AND_CHECK_BUTTONS;
		 else
			nCase = CHECK_BUTTONS;
	}

	switch( nCase )
	{
		case NO_BUTTONS :
			nStartPos += nContextWidthDIV2;  // wg. Zentrierung
			nStartPos += nContextWidthDIV2;  // rechter Rand der Context-Bmp
			if( nContextBmpWidthMax )
				nStartPos += 5; // Abstand Context-Bmp - Text
			break;

		case NODE_BUTTONS :
			if( bHasButtonsAtRoot )
				nStartPos += ( nIndent + (nNodeWidthPixel/2) );
			else
				nStartPos += nContextWidthDIV2;
			nStartPos += nContextWidthDIV2;  // rechter Rand der Context-Bmp
			if( nContextBmpWidthMax )
				nStartPos += 5; // Abstand Context-Bmp - Text
			break;

		case NODE_AND_CHECK_BUTTONS :
			if( bHasButtonsAtRoot )
				nStartPos += ( nIndent + nNodeWidthPixel );
			else
				nStartPos += nCheckWidthDIV2;
			nStartPos += nCheckWidthDIV2;  // rechter Rand des CheckButtons
			nStartPos += 3;  // Abstand CheckButton Context-Bmp
			nStartPos += nContextWidthDIV2;  // Mitte der Context-Bmp
			nStartPos += nContextWidthDIV2;  // rechter Rand der Context-Bmp
			// Abstand setzen nur wenn Bitmaps da
			if( nContextBmpWidthMax )
				nStartPos += 5; // Abstand Context-Bmp - Text
			break;

		case CHECK_BUTTONS :
			nStartPos += nCheckWidthDIV2;
			nStartPos += nCheckWidthDIV2;  // rechter Rand CheckButton
			nStartPos += 3;  // Abstand CheckButton Context-Bmp
			nStartPos += nContextWidthDIV2;  // Mitte der Context-Bmp
			nStartPos += nContextWidthDIV2;  // rechter Rand der Context-Bmp
			if( nContextBmpWidthMax )
				nStartPos += 5; // Abstand Context-Bmp - Text
			break;
	}
	return nStartPos;
}

void SvTreeListBox::EndSelection()
{
	pImp->EndSelection();
}

sal_Bool SvTreeListBox::IsNodeButton( const Point& rPos ) const
{
	SvLBoxEntry* pEntry = GetEntry( rPos );
	if( pEntry )
		return pImp->IsNodeButton( rPos, pEntry );
	return sal_False;
}

void SvTreeListBox::RepaintScrollBars() const
{
	((SvTreeListBox*)this)->pImp->RepaintScrollBars();
}

ScrollBar *SvTreeListBox::GetVScroll()
{
	return &((SvTreeListBox*)this)->pImp->aVerSBar;
}

ScrollBar *SvTreeListBox::GetHScroll()
{
	return &((SvTreeListBox*)this)->pImp->aHorSBar;
}

void SvTreeListBox::EnableAsyncDrag( sal_Bool b )
{
	pImp->EnableAsyncDrag( b );
}

SvLBoxEntry* SvTreeListBox::GetFirstEntryInView() const
{
	Point aPos;
	return GetEntry( aPos );
}

SvLBoxEntry* SvTreeListBox::GetNextEntryInView(SvLBoxEntry* pEntry ) const
{
	SvLBoxEntry* pNext = (SvLBoxEntry*)NextVisible( pEntry );
	if( pNext )
	{
		Point aPos( GetEntryPosition(pNext) );
		const Size& rSize = pImp->GetOutputSize();
		if( aPos.Y() < 0 || aPos.Y() >= rSize.Height() )
			return 0;
	}
	return pNext;
}

void SvTreeListBox::ShowFocusRect( const SvLBoxEntry* pEntry )
{
	pImp->ShowFocusRect( pEntry );
}

void SvTreeListBox::SetTabBar( TabBar* pTabBar )
{
	pImp->SetTabBar( pTabBar );
}

void SvTreeListBox::DataChanged( const DataChangedEvent& rDCEvt )
{
	if( (rDCEvt.GetType()==DATACHANGED_SETTINGS) && (rDCEvt.GetFlags() & SETTINGS_STYLE) )
	{
		nEntryHeight = 0;	// _together_ with sal_True of 1. par (bFont) of InitSettings() a zero-height
							//	forces complete recalc of heights!
		InitSettings( sal_True, sal_True, sal_True );
		Invalidate();
	}
	else
		Control::DataChanged( rDCEvt );
}

void SvTreeListBox::StateChanged( StateChangedType i_nStateChange )
{
    SvLBox::StateChanged( i_nStateChange );
    if ( i_nStateChange == STATE_CHANGE_STYLE )
        ImplInitStyle();
}

void SvTreeListBox::InitSettings(sal_Bool bFont,sal_Bool bForeground,sal_Bool bBackground)
{
	const StyleSettings& rStyleSettings = GetSettings().GetStyleSettings();
	if( bFont )
	{
		Font aFont;
		aFont = rStyleSettings.GetFieldFont();
		aFont.SetColor( rStyleSettings.GetWindowTextColor() );
		SetPointFont( aFont );
        AdjustEntryHeight( aFont );
        RecalcViewData();
	}

	if( bForeground || bFont )
	{
		SetTextColor( rStyleSettings.GetFieldTextColor() );
		SetTextFillColor();
	}

	if( bBackground )
		SetBackground( rStyleSettings.GetFieldColor() );

	// always try to re-create default-SvLBoxButtonData
	if( pCheckButtonData && pCheckButtonData->HasDefaultImages() )
		pCheckButtonData->SetDefaultImages( this );
}

sal_Bool SvTreeListBox::IsCellFocusEnabled() const
{
	return pImp->IsCellFocusEnabled();
}

bool SvTreeListBox::SetCurrentTabPos( sal_uInt16 _nNewPos )
{
	return pImp->SetCurrentTabPos( _nNewPos );
}

sal_uInt16 SvTreeListBox::GetCurrentTabPos() const
{
	return pImp->GetCurrentTabPos();
}

void SvTreeListBox::InitStartEntry()
{
	if( !pImp->pStartEntry )
		pImp->pStartEntry = GetModel()->First();
}

void SvTreeListBox::CancelPendingEdit()
{
	if( pImp )
		pImp->CancelPendingEdit();
}

PopupMenu* SvTreeListBox::CreateContextMenu( void )
{
	return NULL;
}

void SvTreeListBox::ExcecuteContextMenuAction( sal_uInt16 )
{
	DBG_WARNING( "SvTreeListBox::ExcecuteContextMenuAction(): now there's happening nothing!" );
}

void SvTreeListBox::EnableContextMenuHandling( void )
{
	DBG_ASSERT( pImp, "-SvTreeListBox::EnableContextMenuHandling(): No implementation!" );

	pImp->bContextMenuHandling = sal_True;
}

void SvTreeListBox::EnableContextMenuHandling( sal_Bool b )
{
	DBG_ASSERT( pImp, "-SvTreeListBox::EnableContextMenuHandling(): No implementation!" );

	pImp->bContextMenuHandling = b;
}

sal_Bool SvTreeListBox::IsContextMenuHandlingEnabled( void ) const
{
	DBG_ASSERT( pImp, "-SvTreeListBox::IsContextMenuHandlingEnabled(): No implementation!" );

	return pImp->bContextMenuHandling;
}

void SvTreeListBox::EnableList( bool _bEnable )
{
    // call base class method
    Window::Enable( _bEnable != false );
    // then paint immediately
    Paint( Rectangle( Point(), GetSizePixel() ) );
}

::com::sun::star::uno::Reference< XAccessible > SvTreeListBox::CreateAccessible()
{
    Window* pParent = GetAccessibleParentWindow();
    DBG_ASSERT( pParent, "SvTreeListBox::CreateAccessible - accessible parent not found" );

    ::com::sun::star::uno::Reference< XAccessible > xAccessible;
    if ( pParent )
    {
        ::com::sun::star::uno::Reference< XAccessible > xAccParent = pParent->GetAccessible();
        if ( xAccParent.is() )
		{
			// need to be done here to get the vclxwindow later on in the accessbile
			::com::sun::star::uno::Reference< ::com::sun::star::awt::XWindowPeer > xTemp(GetComponentInterface());
            xAccessible = pImp->m_aFactoryAccess.getFactory().createAccessibleTreeListBox( *this, xAccParent );
		}
	}
    return xAccessible;
}

void SvTreeListBox::FillAccessibleEntryStateSet( SvLBoxEntry* pEntry, ::utl::AccessibleStateSetHelper& rStateSet ) const
{
	DBG_ASSERT( pEntry, "SvTreeListBox::FillAccessibleEntryStateSet: invalid entry" );

	if ( pEntry->HasChildsOnDemand() || pEntry->HasChilds() )
	{
		rStateSet.AddState( AccessibleStateType::EXPANDABLE );
		if ( IsExpanded( pEntry ) )
		    rStateSet.AddState( (sal_Int16)AccessibleStateType::EXPANDED );
	}

	if ( GetCheckButtonState( pEntry ) == SV_BUTTON_CHECKED )
		rStateSet.AddState( AccessibleStateType::CHECKED );
	if ( IsEntryVisible( pEntry ) )
		rStateSet.AddState( AccessibleStateType::VISIBLE );
	if ( IsSelected( pEntry ) )
		rStateSet.AddState( AccessibleStateType::SELECTED );
}

Rectangle SvTreeListBox::GetBoundingRect( SvLBoxEntry* pEntry )
{
	Point aPos = GetEntryPosition( pEntry );
	Rectangle aRect = GetFocusRect( pEntry, aPos.Y() );
	return aRect;
}

void SvTreeListBox::EnableCellFocus()
{
	pImp->EnableCellFocus();
}

void SvTreeListBox::CallImplEventListeners(sal_uLong nEvent, void* pData)
{
	CallEventListeners(nEvent, pData);
}

void SvTreeListBox::FillAccessibleStateSet( ::utl::AccessibleStateSetHelper& rStateSet ) const
{
      SvLBox::FillAccessibleStateSet( rStateSet );
}
