/**************************************************************
 * 
 * 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_vcl.hxx"

#include <tools/debug.hxx>

#include <vcl/svapp.hxx>
#include <vcl/settings.hxx>
#include <vcl/event.hxx>
#include <vcl/scrbar.hxx>
#include <vcl/help.hxx>
#include <vcl/lstbox.h>
#include <vcl/unohelp.hxx>
#include <vcl/i18nhelp.hxx>

#include <ilstbox.hxx>
#include <controldata.hxx>
#include <svdata.hxx>

#include <com/sun/star/i18n/XCollator.hpp>
#include <com/sun/star/accessibility/XAccessible.hpp>
#include <com/sun/star/accessibility/AccessibleRole.hpp>

#define MULTILINE_ENTRY_DRAW_FLAGS ( TEXT_DRAW_WORDBREAK | TEXT_DRAW_MULTILINE | TEXT_DRAW_VCENTER )

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

// =======================================================================

void ImplInitFieldSettings( Window* pWin, sal_Bool bFont, sal_Bool bForeground, sal_Bool bBackground )
{
	const StyleSettings& rStyleSettings = pWin->GetSettings().GetStyleSettings();

	if ( bFont )
	{
		Font aFont = rStyleSettings.GetFieldFont();
		if ( pWin->IsControlFont() )
			aFont.Merge( pWin->GetControlFont() );
		pWin->SetZoomedPointFont( aFont );
	}

	if ( bFont || bForeground )
	{
		Color aTextColor = rStyleSettings.GetFieldTextColor();
		if ( pWin->IsControlForeground() )
			aTextColor = pWin->GetControlForeground();
		pWin->SetTextColor( aTextColor );
	}

	if ( bBackground )
	{
		if( pWin->IsControlBackground() )
			pWin->SetBackground( pWin->GetControlBackground() );
		else
			pWin->SetBackground( rStyleSettings.GetFieldColor() );
	}
}

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

void ImplInitDropDownButton( PushButton* pButton )
{
	if ( pButton->GetSettings().GetStyleSettings().GetOptions() & STYLE_OPTION_SPINUPDOWN )
		pButton->SetSymbol( SYMBOL_SPIN_UPDOWN );
	else
		pButton->SetSymbol( SYMBOL_SPIN_DOWN );

	if ( pButton->IsNativeControlSupported(CTRL_LISTBOX, PART_ENTIRE_CONTROL)
			&& ! pButton->IsNativeControlSupported(CTRL_LISTBOX, PART_BUTTON_DOWN) )
		pButton->SetBackground();
}

// =======================================================================

ImplEntryList::ImplEntryList( Window* pWindow )
{
    mpWindow = pWindow;
	mnLastSelected = LISTBOX_ENTRY_NOTFOUND;
	mnSelectionAnchor = LISTBOX_ENTRY_NOTFOUND;
	mnImages = 0;
	mbCallSelectionChangedHdl = sal_True;

	mnMRUCount = 0;
	mnMaxMRUCount = 0;
}

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

ImplEntryList::~ImplEntryList()
{
	Clear();
}

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

void ImplEntryList::Clear()
{
	mnImages = 0;
	for ( sal_uInt16 n = GetEntryCount(); n; )
	{
		ImplEntryType* pImplEntry = GetEntry( --n );
		delete pImplEntry;
	}
	List::Clear();
}

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

void ImplEntryList::SelectEntry( sal_uInt16 nPos, sal_Bool bSelect )
{
	ImplEntryType* pImplEntry = GetEntry( nPos );
	if ( pImplEntry &&
	   ( pImplEntry->mbIsSelected != bSelect ) &&
	   ( (pImplEntry->mnFlags & LISTBOX_ENTRY_FLAG_DISABLE_SELECTION) == 0  ) )
	{
		pImplEntry->mbIsSelected = bSelect;
		if ( mbCallSelectionChangedHdl )
			maSelectionChangedHdl.Call( (void*)sal_IntPtr(nPos) );
	}
}

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

uno::Reference< i18n::XCollator > ImplGetCollator (lang::Locale &rLocale)
{
	static uno::Reference< i18n::XCollator > xCollator;
	if ( !xCollator.is() )
		xCollator = vcl::unohelper::CreateCollator();
	if( xCollator.is() )
		xCollator->loadDefaultCollator (rLocale, 0);

	return xCollator;
}

sal_uInt16 ImplEntryList::InsertEntry( sal_uInt16 nPos, ImplEntryType* pNewEntry, sal_Bool bSort )
{
	if ( !!pNewEntry->maImage )
		mnImages++;

	if ( !bSort || !Count() )
	{
		Insert( pNewEntry, nPos );
	}
	else
	{
		lang::Locale aLocale = Application::GetSettings().GetLocale();
		uno::Reference< i18n::XCollator > xCollator = ImplGetCollator(aLocale);

		const XubString& rStr = pNewEntry->maStr;
		sal_uLong nLow, nHigh, nMid;

		nHigh = Count();

		ImplEntryType* pTemp = GetEntry( (sal_uInt16)(nHigh-1) );

		try
		{
			// XXX even though XCollator::compareString returns a sal_Int32 the only
			// defined values are {-1, 0, 1} which is compatible with StringCompare
			StringCompare eComp = xCollator.is() ?
				(StringCompare)xCollator->compareString (rStr, pTemp->maStr)
				: COMPARE_EQUAL;

			// Schnelles Einfuegen bei sortierten Daten
			if ( eComp != COMPARE_LESS )
			{
				Insert( pNewEntry, LIST_APPEND );
			}
			else
			{
				nLow  = mnMRUCount;
				pTemp = (ImplEntryType*)GetEntry( (sal_uInt16)nLow );

				eComp = (StringCompare)xCollator->compareString (rStr, pTemp->maStr);
				if ( eComp != COMPARE_GREATER )
				{
					Insert( pNewEntry, (sal_uLong)0 );
				}
				else
				{
					// Binaeres Suchen
					nHigh--;
					do
					{
						nMid = (nLow + nHigh) / 2;
						pTemp = (ImplEntryType*)GetObject( nMid );

						eComp = (StringCompare)xCollator->compareString (rStr, pTemp->maStr);

						if ( eComp == COMPARE_LESS )
							nHigh = nMid-1;
						else
						{
							if ( eComp == COMPARE_GREATER )
								nLow = nMid + 1;
							else
								break;
						}
					}
					while ( nLow <= nHigh );

					if ( eComp != COMPARE_LESS )
						nMid++;

					Insert( pNewEntry, nMid );
				}
			}
		}
		catch (uno::RuntimeException& )
		{
			// XXX this is arguable, if the exception occured because pNewEntry is
			// garbage you wouldn't insert it. If the exception occured because the
			// Collator implementation is garbage then give the user a chance to see
			// his stuff
			Insert( pNewEntry, (sal_uLong)0 );
		}

	}

	return (sal_uInt16)GetPos( pNewEntry );
}

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

void ImplEntryList::RemoveEntry( sal_uInt16 nPos )
{
	ImplEntryType* pImplEntry = (ImplEntryType*)List::Remove( nPos );
	if ( pImplEntry )
	{
		if ( !!pImplEntry->maImage )
			mnImages--;

		delete pImplEntry;
	}
}

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

sal_uInt16 ImplEntryList::FindEntry( const XubString& rString, sal_Bool bSearchMRUArea ) const
{
    sal_uInt16 nEntries = GetEntryCount();
    for ( sal_uInt16 n = bSearchMRUArea ? 0 : GetMRUCount(); n < nEntries; n++ )
	{
		ImplEntryType* pImplEntry = GetEntry( n );
        String aComp( vcl::I18nHelper::filterFormattingChars( pImplEntry->maStr ) );
        if ( aComp == rString )
            return n;
    }
    return LISTBOX_ENTRY_NOTFOUND;
}

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

sal_uInt16 ImplEntryList::FindMatchingEntry( const XubString& rStr, sal_uInt16 nStart, sal_Bool bForward, sal_Bool bLazy ) const
{
	sal_uInt16	nPos = LISTBOX_ENTRY_NOTFOUND;
	sal_uInt16	nEntryCount = GetEntryCount();
	if ( !bForward )
		nStart++;	// wird sofort dekrementiert

    const vcl::I18nHelper& rI18nHelper = mpWindow->GetSettings().GetLocaleI18nHelper();
    for ( sal_uInt16 n = nStart; bForward ? ( n < nEntryCount ) : n; )
	{
		if ( !bForward )
			n--;

		ImplEntryType* pImplEntry = GetEntry( n );
        sal_Bool bMatch = bLazy ? rI18nHelper.MatchString( rStr, pImplEntry->maStr ) != 0 : ( rStr.Match( pImplEntry->maStr ) == STRING_MATCH );
		if ( bMatch )
		{
			nPos = n;
			break;
		}

		if ( bForward )
			n++;
	}

    return nPos;
}

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

sal_uInt16 ImplEntryList::FindEntry( const void* pData ) const
{
	sal_uInt16 nPos = LISTBOX_ENTRY_NOTFOUND;
	for ( sal_uInt16 n = GetEntryCount(); n; )
	{
		ImplEntryType* pImplEntry = GetEntry( --n );
		if ( pImplEntry->mpUserData == pData )
		{
			nPos = n;
			break;
		}
	}
	return nPos;
}

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

long ImplEntryList::GetAddedHeight( sal_uInt16 i_nEndIndex, sal_uInt16 i_nBeginIndex, long i_nBeginHeight ) const
{
    long nHeight = i_nBeginHeight;
    sal_uInt16 nStart = i_nEndIndex > i_nBeginIndex ? i_nBeginIndex : i_nEndIndex;
    sal_uInt16 nStop  = i_nEndIndex > i_nBeginIndex ? i_nEndIndex : i_nBeginIndex;
    sal_uInt16 nEntryCount = GetEntryCount();
    if( nStop != LISTBOX_ENTRY_NOTFOUND && nEntryCount != 0 )
    {
        // sanity check
        if( nStop > nEntryCount-1 )
            nStop = nEntryCount-1;
        if( nStart > nEntryCount-1 )
            nStart = nEntryCount-1;
        
        sal_uInt16 nIndex = nStart;
        while( nIndex != LISTBOX_ENTRY_NOTFOUND && nIndex < nStop )
        {
            nHeight += GetEntryPtr( nIndex )-> mnHeight;
            nIndex++;
        }
    }
    else
        nHeight = 0;
    return i_nEndIndex > i_nBeginIndex ? nHeight : -nHeight;
}

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

long ImplEntryList::GetEntryHeight( sal_uInt16 nPos ) const
{
	ImplEntryType* pImplEntry = GetEntry( nPos );
	return pImplEntry ? pImplEntry->mnHeight : 0;
}

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

XubString ImplEntryList::GetEntryText( sal_uInt16 nPos ) const
{
	XubString aEntryText;
	ImplEntryType* pImplEntry = GetEntry( nPos );
	if ( pImplEntry )
		aEntryText = pImplEntry->maStr;
	return aEntryText;
}

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

sal_Bool ImplEntryList::HasEntryImage( sal_uInt16 nPos ) const
{
	sal_Bool bImage = sal_False;
	ImplEntryType* pImplEntry = (ImplEntryType*)List::GetObject( nPos );
	if ( pImplEntry )
		bImage = !!pImplEntry->maImage;
	return bImage;
}

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

Image ImplEntryList::GetEntryImage( sal_uInt16 nPos ) const
{
	Image aImage;
	ImplEntryType* pImplEntry = (ImplEntryType*)List::GetObject( nPos );
	if ( pImplEntry )
		aImage = pImplEntry->maImage;
	return aImage;
}

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

void ImplEntryList::SetEntryData( sal_uInt16 nPos, void* pNewData )
{
	ImplEntryType* pImplEntry = (ImplEntryType*)List::GetObject( nPos );
	if ( pImplEntry )
		pImplEntry->mpUserData = pNewData;
}

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

void* ImplEntryList::GetEntryData( sal_uInt16 nPos ) const
{
	ImplEntryType* pImplEntry = (ImplEntryType*)List::GetObject( nPos );
	return pImplEntry ? pImplEntry->mpUserData : NULL;
}

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

void ImplEntryList::SetEntryFlags( sal_uInt16 nPos, long nFlags )
{
	ImplEntryType* pImplEntry = (ImplEntryType*)List::GetObject( nPos );
	if ( pImplEntry )
		pImplEntry->mnFlags = nFlags;
}

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

long ImplEntryList::GetEntryFlags( sal_uInt16 nPos ) const
{
	ImplEntryType* pImplEntry = (ImplEntryType*)List::GetObject( nPos );
	return pImplEntry ? pImplEntry->mnFlags : 0;
}

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

sal_uInt16 ImplEntryList::GetSelectEntryCount() const
{
	sal_uInt16 nSelCount = 0;
	for ( sal_uInt16 n = GetEntryCount(); n; )
	{
		ImplEntryType* pImplEntry = GetEntry( --n );
		if ( pImplEntry->mbIsSelected )
			nSelCount++;
	}
	return nSelCount;
}

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

XubString ImplEntryList::GetSelectEntry( sal_uInt16 nIndex ) const
{
	return GetEntryText( GetSelectEntryPos( nIndex ) );
}

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

sal_uInt16 ImplEntryList::GetSelectEntryPos( sal_uInt16 nIndex ) const
{
	sal_uInt16 nSelEntryPos = LISTBOX_ENTRY_NOTFOUND;
	sal_uInt16 nSel = 0;
	sal_uInt16 nEntryCount = GetEntryCount();

	for ( sal_uInt16 n = 0; n < nEntryCount; n++ )
	{
		ImplEntryType* pImplEntry = GetEntry( n );
		if ( pImplEntry->mbIsSelected )
		{
			if ( nSel == nIndex )
			{
				nSelEntryPos = n;
				break;
			}
			nSel++;
		}
	}

	return nSelEntryPos;
}

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

sal_Bool ImplEntryList::IsEntrySelected( const XubString& rStr ) const
{
	return IsEntryPosSelected( FindEntry( rStr ) );
}

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

sal_Bool ImplEntryList::IsEntryPosSelected( sal_uInt16 nIndex ) const
{
	ImplEntryType* pImplEntry = GetEntry( nIndex );
	return pImplEntry ? pImplEntry->mbIsSelected : sal_False;
}

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

bool ImplEntryList::IsEntrySelectable( sal_uInt16 nPos ) const
{
	ImplEntryType* pImplEntry = GetEntry( nPos );
	return pImplEntry ? ((pImplEntry->mnFlags & LISTBOX_ENTRY_FLAG_DISABLE_SELECTION) == 0) : true;
}

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

sal_uInt16 ImplEntryList::FindFirstSelectable( sal_uInt16 nPos, bool bForward /* = true */ )
{
	if( IsEntrySelectable( nPos ) )
		return nPos;

	if( bForward )
	{
		for( nPos = nPos + 1; nPos < GetEntryCount(); nPos++ )
		{
			if( IsEntrySelectable( nPos ) )
				return nPos;
		}
	}
	else
	{
		while( nPos )
		{
			nPos--;
			if( IsEntrySelectable( nPos ) )
				return nPos;
		}
	}

	return LISTBOX_ENTRY_NOTFOUND;
}

// =======================================================================

ImplListBoxWindow::ImplListBoxWindow( Window* pParent, WinBits nWinStyle ) :
	Control( pParent, 0 ),
    maQuickSelectionEngine( *this )
{
	mpEntryList 		= new ImplEntryList( this );

	mnTop				= 0;
	mnLeft				= 0;
	mnBorder			= 1;
	mnSelectModifier	= 0;
	mnUserDrawEntry 	= LISTBOX_ENTRY_NOTFOUND;
	mbTrack 			= false;
	mbImgsDiffSz		= false;
	mbTravelSelect		= false;
	mbTrackingSelect	= false;
	mbSelectionChanged	= false;
	mbMouseMoveSelect	= false;
	mbMulti 			= false;
	mbStackMode 		= false;
	mbGrabFocus 		= false;
	mbUserDrawEnabled	= false;
	mbInUserDraw		= false;
	mbReadOnly			= false;
    mbHasFocusRect      = false;
    mbRight             = ( nWinStyle & WB_RIGHT );
    mbCenter            = ( nWinStyle & WB_CENTER );
	mbSimpleMode		= ( nWinStyle & WB_SIMPLEMODE );
	mbSort				= ( nWinStyle & WB_SORT );
    mbEdgeBlending      = false;

	// pb: #106948# explicit mirroring for calc
	mbMirroring			= false;

	mnCurrentPos			= LISTBOX_ENTRY_NOTFOUND;
	mnTrackingSaveSelection = LISTBOX_ENTRY_NOTFOUND;
	mnSeparatorPos			= LISTBOX_ENTRY_NOTFOUND;
	meProminentType         = PROMINENT_TOP;

	SetLineColor();
	SetTextFillColor();
	SetBackground( Wallpaper( GetSettings().GetStyleSettings().GetFieldColor() ) );

	ImplInitSettings( sal_True, sal_True, sal_True );
	ImplCalcMetrics();
}

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

ImplListBoxWindow::~ImplListBoxWindow()
{
	delete mpEntryList;
}

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

void ImplListBoxWindow::ImplInitSettings( sal_Bool bFont, sal_Bool bForeground, sal_Bool bBackground )
{
	ImplInitFieldSettings( this, bFont, bForeground, bBackground );
}

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

void ImplListBoxWindow::ImplCalcMetrics()
{
	mnMaxWidth		= 0;
	mnMaxTxtWidth	= 0;
	mnMaxImgWidth	= 0;
	mnMaxImgTxtWidth= 0;
	mnMaxImgHeight	= 0;

	mnTextHeight = (sal_uInt16)GetTextHeight();
	mnMaxTxtHeight = mnTextHeight + mnBorder;
	mnMaxHeight = mnMaxTxtHeight;

	if ( maUserItemSize.Height() > mnMaxHeight )
		mnMaxHeight = (sal_uInt16) maUserItemSize.Height();
	if ( maUserItemSize.Width() > mnMaxWidth )
		mnMaxWidth= (sal_uInt16) maUserItemSize.Width();

	for ( sal_uInt16 n = mpEntryList->GetEntryCount(); n; )
	{
		ImplEntryType* pEntry = mpEntryList->GetMutableEntryPtr( --n );
		ImplUpdateEntryMetrics( *pEntry );
	}

    if( mnCurrentPos != LISTBOX_ENTRY_NOTFOUND )
    {
        Size aSz( GetOutputSizePixel().Width(), mpEntryList->GetEntryPtr( mnCurrentPos )->mnHeight );
        maFocusRect.SetSize( aSz );
    }
}

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

void ImplListBoxWindow::Clear()
{
	mpEntryList->Clear();

	mnMaxHeight 	= mnMaxTxtHeight;
	mnMaxWidth		= 0;
	mnMaxTxtWidth	= 0;
	mnMaxImgTxtWidth= 0;
	mnMaxImgWidth	= 0;
	mnMaxImgHeight	= 0;
	mnTop			= 0;
	mnLeft			= 0;
	mbImgsDiffSz	= false;
    ImplClearLayoutData();

    mnCurrentPos = LISTBOX_ENTRY_NOTFOUND;
    maQuickSelectionEngine.Reset();

	Invalidate();
}

void ImplListBoxWindow::SetUserItemSize( const Size& rSz )
{
    ImplClearLayoutData();
	maUserItemSize = rSz;
	ImplCalcMetrics();
}

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

struct ImplEntryMetrics
{
	sal_Bool	bText;
	sal_Bool	bImage;
	long	nEntryWidth;
	long	nEntryHeight;
	long	nTextWidth;
	long	nImgWidth;
	long	nImgHeight;
};

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

void ImplListBoxWindow::ImplUpdateEntryMetrics( ImplEntryType& rEntry )
{
	ImplEntryMetrics aMetrics;
	aMetrics.bText = rEntry.maStr.Len() ? sal_True : sal_False;
	aMetrics.bImage = !!rEntry.maImage;
	aMetrics.nEntryWidth = 0;
	aMetrics.nEntryHeight = 0;
	aMetrics.nTextWidth = 0;
	aMetrics.nImgWidth = 0;
	aMetrics.nImgHeight = 0;

	if ( aMetrics.bText )
	{
        if( (rEntry.mnFlags & LISTBOX_ENTRY_FLAG_MULTILINE) )
        {
            // multiline case
            Size aCurSize( PixelToLogic( GetSizePixel() ) );
            // set the current size to a large number
            // GetTextRect should shrink it to the actual size
            aCurSize.Height() = 0x7fffff;
            Rectangle aTextRect( Point( 0, 0 ), aCurSize );
            aTextRect = GetTextRect( aTextRect, rEntry.maStr, TEXT_DRAW_WORDBREAK | TEXT_DRAW_MULTILINE );
            aMetrics.nTextWidth = aTextRect.GetWidth();
            if( aMetrics.nTextWidth > mnMaxTxtWidth )
                mnMaxTxtWidth = aMetrics.nTextWidth;
            aMetrics.nEntryWidth = mnMaxTxtWidth;
            aMetrics.nEntryHeight = aTextRect.GetHeight() + mnBorder;
        }
        else
        {
            // normal single line case
            aMetrics.nTextWidth = (sal_uInt16)GetTextWidth( rEntry.maStr );
            if( aMetrics.nTextWidth > mnMaxTxtWidth )
                mnMaxTxtWidth = aMetrics.nTextWidth;
            aMetrics.nEntryWidth = mnMaxTxtWidth;
            aMetrics.nEntryHeight = mnTextHeight + mnBorder;
        }
	}
	if ( aMetrics.bImage )
	{
		Size aImgSz = rEntry.maImage.GetSizePixel();
		aMetrics.nImgWidth	= (sal_uInt16) CalcZoom( aImgSz.Width() );
		aMetrics.nImgHeight = (sal_uInt16) CalcZoom( aImgSz.Height() );

        if( mnMaxImgWidth && ( aMetrics.nImgWidth != mnMaxImgWidth ) )
            mbImgsDiffSz = true;
        else if ( mnMaxImgHeight && ( aMetrics.nImgHeight != mnMaxImgHeight ) )
            mbImgsDiffSz = true;

        if( aMetrics.nImgWidth > mnMaxImgWidth )
            mnMaxImgWidth = aMetrics.nImgWidth;
        if( aMetrics.nImgHeight > mnMaxImgHeight )
            mnMaxImgHeight = aMetrics.nImgHeight;

        mnMaxImgTxtWidth = Max( mnMaxImgTxtWidth, aMetrics.nTextWidth );
        aMetrics.nEntryHeight = Max( aMetrics.nImgHeight, aMetrics.nEntryHeight );
            
	}
	if ( IsUserDrawEnabled() || aMetrics.bImage )
	{
		aMetrics.nEntryWidth = Max( aMetrics.nImgWidth, maUserItemSize.Width() );
		if ( aMetrics.bText )
			aMetrics.nEntryWidth += aMetrics.nTextWidth + IMG_TXT_DISTANCE;
		aMetrics.nEntryHeight = Max( Max( mnMaxImgHeight, maUserItemSize.Height() ) + 2,
                                     aMetrics.nEntryHeight );
	}

    if ( !aMetrics.bText && !aMetrics.bImage && !IsUserDrawEnabled() )
    {
        // entries which have no (aka an empty) text, and no image, and are not user-drawn, should be
        // shown nonetheless
        aMetrics.nEntryHeight = mnTextHeight + mnBorder;
    }

    if ( aMetrics.nEntryWidth > mnMaxWidth )
        mnMaxWidth = aMetrics.nEntryWidth;
    if ( aMetrics.nEntryHeight > mnMaxHeight )
        mnMaxHeight = aMetrics.nEntryHeight;
    
    rEntry.mnHeight = aMetrics.nEntryHeight;
}

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

void ImplListBoxWindow::ImplCallSelect()
{
	if ( !IsTravelSelect() && GetEntryList()->GetMaxMRUCount() )
	{
		// Insert the selected entry as MRU, if not allready first MRU
		sal_uInt16 nSelected = GetEntryList()->GetSelectEntryPos( 0 );
		sal_uInt16 nMRUCount = GetEntryList()->GetMRUCount();
		String aSelected = GetEntryList()->GetEntryText( nSelected );
		sal_uInt16 nFirstMatchingEntryPos = GetEntryList()->FindEntry( aSelected, sal_True );
		if ( nFirstMatchingEntryPos || !nMRUCount )
		{
			sal_Bool bSelectNewEntry = sal_False;
			if ( nFirstMatchingEntryPos < nMRUCount )
			{
				RemoveEntry( nFirstMatchingEntryPos );
				nMRUCount--;
				if ( nFirstMatchingEntryPos == nSelected )
					bSelectNewEntry = sal_True;
			}
			else if ( nMRUCount == GetEntryList()->GetMaxMRUCount() )
			{
				RemoveEntry( nMRUCount - 1 );
				nMRUCount--;
			}

            ImplClearLayoutData();

			ImplEntryType* pNewEntry = new ImplEntryType( aSelected );
			pNewEntry->mbIsSelected = bSelectNewEntry;
			GetEntryList()->InsertEntry( 0, pNewEntry, sal_False );
            ImplUpdateEntryMetrics( *pNewEntry );
			GetEntryList()->SetMRUCount( ++nMRUCount );
			SetSeparatorPos( nMRUCount ? nMRUCount-1 : 0 );
			maMRUChangedHdl.Call( NULL );
		}
	}

	maSelectHdl.Call( NULL );
	mbSelectionChanged = false;
}

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

sal_uInt16 ImplListBoxWindow::InsertEntry( sal_uInt16 nPos, ImplEntryType* pNewEntry )
{
    ImplClearLayoutData();
	sal_uInt16 nNewPos = mpEntryList->InsertEntry( nPos, pNewEntry, mbSort );

    if( (GetStyle() & WB_WORDBREAK) )
        pNewEntry->mnFlags |= LISTBOX_ENTRY_FLAG_MULTILINE;
    
	ImplUpdateEntryMetrics( *pNewEntry );
	return nNewPos;
}

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

void ImplListBoxWindow::RemoveEntry( sal_uInt16 nPos )
{
    ImplClearLayoutData();
	mpEntryList->RemoveEntry( nPos );
    if( mnCurrentPos >= mpEntryList->GetEntryCount() )
        mnCurrentPos = LISTBOX_ENTRY_NOTFOUND;
	ImplCalcMetrics();
}

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

void ImplListBoxWindow::SetEntryFlags( sal_uInt16 nPos, long nFlags )
{
	mpEntryList->SetEntryFlags( nPos, nFlags );
    ImplEntryType* pEntry = mpEntryList->GetMutableEntryPtr( nPos );
    if( pEntry )
        ImplUpdateEntryMetrics( *pEntry );
}

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

void ImplListBoxWindow::ImplShowFocusRect()
{
    if ( mbHasFocusRect )
        HideFocus();
    ShowFocus( maFocusRect );
    mbHasFocusRect = true;
}

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

void ImplListBoxWindow::ImplHideFocusRect()
{
    if ( mbHasFocusRect )
    {
        HideFocus();
        mbHasFocusRect = false;
    }
}


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

sal_uInt16 ImplListBoxWindow::GetEntryPosForPoint( const Point& rPoint ) const
{
    long nY = mnBorder;
    
    sal_uInt16 nSelect = mnTop;
    const ImplEntryType* pEntry = mpEntryList->GetEntryPtr( nSelect );
    while( pEntry && rPoint.Y() > pEntry->mnHeight + nY )
    {
        nY += pEntry->mnHeight;
        pEntry = mpEntryList->GetEntryPtr( ++nSelect );
    }
    if( pEntry == NULL )
        nSelect = LISTBOX_ENTRY_NOTFOUND;

    return nSelect;
}

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

sal_Bool ImplListBoxWindow::IsVisible( sal_uInt16 i_nEntry ) const
{
    sal_Bool bRet = sal_False;
    
    if( i_nEntry >= mnTop )
    {
        if( mpEntryList->GetAddedHeight( i_nEntry, mnTop ) <
            PixelToLogic( GetSizePixel() ).Height() )
        {
            bRet = sal_True;
        }
    }
    
    return bRet;
}

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

sal_uInt16 ImplListBoxWindow::GetLastVisibleEntry() const
{
    sal_uInt16 nPos = mnTop;
    long nWindowHeight = GetSizePixel().Height();
    sal_uInt16 nCount = mpEntryList->GetEntryCount();
    long nDiff;
    for( nDiff = 0; nDiff < nWindowHeight && nPos < nCount; nDiff = mpEntryList->GetAddedHeight( nPos, mnTop ) )
        nPos++;
    
    if( nDiff > nWindowHeight && nPos > mnTop )
        nPos--;
    
    if( nPos >= nCount )
        nPos = nCount-1;
    
    return nPos;
}

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

void ImplListBoxWindow::MouseButtonDown( const MouseEvent& rMEvt )
{
	mbMouseMoveSelect = false;	// Nur bis zum ersten MouseButtonDown
    maQuickSelectionEngine.Reset();

	if ( !IsReadOnly() )
	{
		if( rMEvt.GetClicks() == 1 )
		{
			sal_uInt16 nSelect = GetEntryPosForPoint( rMEvt.GetPosPixel() );
			if( nSelect != LISTBOX_ENTRY_NOTFOUND )
			{
				if ( !mbMulti && GetEntryList()->GetSelectEntryCount() )
					mnTrackingSaveSelection = GetEntryList()->GetSelectEntryPos( 0 );
				else
					mnTrackingSaveSelection = LISTBOX_ENTRY_NOTFOUND;

				mnCurrentPos = nSelect;
				mbTrackingSelect = true;
				SelectEntries( nSelect, LET_MBDOWN, rMEvt.IsShift(), rMEvt.IsMod1() );
				mbTrackingSelect = false;
				if ( mbGrabFocus )
					GrabFocus();

				StartTracking( STARTTRACK_SCROLLREPEAT );
			}
		}
		if( rMEvt.GetClicks() == 2 )
		{
			maDoubleClickHdl.Call( this );
		}
	}
	else // if ( mbGrabFocus )
	{
		GrabFocus();
	}
}

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

void ImplListBoxWindow::MouseMove( const MouseEvent& rMEvt )
{
    if ( rMEvt.IsLeaveWindow() )
    {
		if ( mbStackMode && IsMouseMoveSelect() && IsReallyVisible() )
		{
			if ( rMEvt.GetPosPixel().Y() < 0 )
			{
				DeselectAll();
				mnCurrentPos = LISTBOX_ENTRY_NOTFOUND;
                SetTopEntry( 0 );
				if ( mbStackMode ) // #87072#, #92323#
				{
					mbTravelSelect = true;
					mnSelectModifier = rMEvt.GetModifier();
					ImplCallSelect();
					mbTravelSelect = false;
				}

			}
		}
    }
    else if ( ( ( !mbMulti && IsMouseMoveSelect() ) || mbStackMode ) && mpEntryList->GetEntryCount() )
	{
		Point aPoint;
		Rectangle aRect( aPoint, GetOutputSizePixel() );
		if( aRect.IsInside( rMEvt.GetPosPixel() ) )
		{
			if ( IsMouseMoveSelect() )
			{
				sal_uInt16 nSelect = GetEntryPosForPoint( rMEvt.GetPosPixel() );
                if( nSelect == LISTBOX_ENTRY_NOTFOUND )
                    nSelect = mpEntryList->GetEntryCount() - 1;
				nSelect = Min( nSelect, GetLastVisibleEntry() );
				nSelect = Min( nSelect, (sal_uInt16) ( mpEntryList->GetEntryCount() - 1 ) );
				// Select only visible Entries with MouseMove, otherwise Tracking...
				if ( IsVisible( nSelect ) && 
					mpEntryList->IsEntrySelectable( nSelect ) &&
					( ( nSelect != mnCurrentPos ) || !GetEntryList()->GetSelectEntryCount() || ( nSelect != GetEntryList()->GetSelectEntryPos( 0 ) ) ) )
				{
					mbTrackingSelect = true;
					if ( SelectEntries( nSelect, LET_TRACKING, sal_False, sal_False ) )
		            {
                        if ( mbStackMode ) // #87072#
                        {
			                mbTravelSelect = true;
			                mnSelectModifier = rMEvt.GetModifier();
			                ImplCallSelect();
			                mbTravelSelect = false;
                        }
		            }
					mbTrackingSelect = false;
				}
			}

			// Falls der DD-Button gedrueckt wurde und jemand mit gedrueckter
			// Maustaste in die ListBox faehrt...
			if ( rMEvt.IsLeft() && !rMEvt.IsSynthetic() )
			{
				if ( !mbMulti && GetEntryList()->GetSelectEntryCount() )
					mnTrackingSaveSelection = GetEntryList()->GetSelectEntryPos( 0 );
				else
					mnTrackingSaveSelection = LISTBOX_ENTRY_NOTFOUND;

				if ( mbStackMode && ( mpEntryList->GetSelectionAnchor() == LISTBOX_ENTRY_NOTFOUND ) )
					mpEntryList->SetSelectionAnchor( 0 );

				StartTracking( STARTTRACK_SCROLLREPEAT );
			}
		}
	}
}

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

void ImplListBoxWindow::DeselectAll()
{
	while ( GetEntryList()->GetSelectEntryCount() )
	{
		sal_uInt16 nS = GetEntryList()->GetSelectEntryPos( 0 );
		SelectEntry( nS, sal_False );
	}
}

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

void ImplListBoxWindow::SelectEntry( sal_uInt16 nPos, sal_Bool bSelect )
{
	if( (mpEntryList->IsEntryPosSelected( nPos ) != bSelect) && mpEntryList->IsEntrySelectable( nPos ) )
	{
		ImplHideFocusRect();
		if( bSelect )
		{
			if( !mbMulti )
			{
				// Selektierten Eintrag deselektieren
				sal_uInt16 nDeselect = GetEntryList()->GetSelectEntryPos( 0 );
				if( nDeselect != LISTBOX_ENTRY_NOTFOUND )
				{
					//SelectEntryPos( nDeselect, sal_False );
					GetEntryList()->SelectEntry( nDeselect, sal_False );
					if ( IsUpdateMode() && IsReallyVisible() )
						ImplPaint( nDeselect, sal_True );
				}
			}
			mpEntryList->SelectEntry( nPos, sal_True );
			mnCurrentPos = nPos;
			if ( ( nPos != LISTBOX_ENTRY_NOTFOUND ) && IsUpdateMode() )
			{
				ImplPaint( nPos );
				if ( !IsVisible( nPos ) )
                {
                    ImplClearLayoutData();
                    sal_uInt16 nVisibleEntries = GetLastVisibleEntry()-mnTop;
                    if ( !nVisibleEntries || !IsReallyVisible() || ( nPos < GetTopEntry() ) )
                    {
                        Resize();
					    ShowProminentEntry( nPos );
                    }
                    else
                    {
                        ShowProminentEntry( nPos );
                    }
                }
			}
		}
		else
		{
			mpEntryList->SelectEntry( nPos, sal_False );
			ImplPaint( nPos, sal_True );
		}
		mbSelectionChanged = true;
	}
}

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

sal_Bool ImplListBoxWindow::SelectEntries( sal_uInt16 nSelect, LB_EVENT_TYPE eLET, sal_Bool bShift, sal_Bool bCtrl )
{
	sal_Bool bFocusChanged = sal_False;
	sal_Bool bSelectionChanged = sal_False;

	if( IsEnabled() && mpEntryList->IsEntrySelectable( nSelect ) )
	{
		// Hier (Single-ListBox) kann nur ein Eintrag deselektiert werden
		if( !mbMulti )
		{
			sal_uInt16 nDeselect = mpEntryList->GetSelectEntryPos( 0 );
			if( nSelect != nDeselect )
			{
				SelectEntry( nSelect, sal_True );
				mpEntryList->SetLastSelected( nSelect );
				bFocusChanged = sal_True;
				bSelectionChanged = sal_True;
			}
		}
		// MultiListBox ohne Modifier
		else if( mbSimpleMode && !bCtrl && !bShift )
		{
			sal_uInt16 nEntryCount = mpEntryList->GetEntryCount();
			for ( sal_uInt16 nPos = 0; nPos < nEntryCount; nPos++ )
			{
				sal_Bool bSelect = nPos == nSelect;
				if ( mpEntryList->IsEntryPosSelected( nPos ) != bSelect )
				{
					SelectEntry( nPos, bSelect );
					bFocusChanged = sal_True;
					bSelectionChanged = sal_True;
				}
			}
			mpEntryList->SetLastSelected( nSelect );
			mpEntryList->SetSelectionAnchor( nSelect );
		}
		// MultiListBox nur mit CTRL/SHIFT oder nicht im SimpleMode
		else if( ( !mbSimpleMode /* && !bShift */ ) || ( (mbSimpleMode && ( bCtrl || bShift )) || mbStackMode ) )
		{
			// Space fuer Selektionswechsel
			if( !bShift && ( ( eLET == LET_KEYSPACE ) || ( eLET == LET_MBDOWN ) ) )
			{
				sal_Bool bSelect = ( mbStackMode && IsMouseMoveSelect() ) ? sal_True : !mpEntryList->IsEntryPosSelected( nSelect );
				if ( mbStackMode )
				{
					sal_uInt16 n;
					if ( bSelect )
					{
						// All entries before nSelect must be selected...
						for ( n = 0; n < nSelect; n++ )
							SelectEntry( n, sal_True );
					}
					if ( !bSelect )
					{
						for ( n = nSelect+1; n < mpEntryList->GetEntryCount(); n++ )
							SelectEntry( n, sal_False );
					}
				}
				SelectEntry( nSelect, bSelect );
				mpEntryList->SetLastSelected( nSelect );
				mpEntryList->SetSelectionAnchor( mbStackMode ? 0 : nSelect );
				if ( !mpEntryList->IsEntryPosSelected( nSelect ) )
					mpEntryList->SetSelectionAnchor( LISTBOX_ENTRY_NOTFOUND );
				bFocusChanged = sal_True;
				bSelectionChanged = sal_True;
			}
			else if( ( ( eLET == LET_TRACKING ) && ( nSelect != mnCurrentPos ) ) ||
					 ( (bShift||mbStackMode) && ( ( eLET == LET_KEYMOVE ) || ( eLET == LET_MBDOWN ) ) ) )
			{
				mnCurrentPos = nSelect;
				bFocusChanged = sal_True;

				sal_uInt16 nAnchor = mpEntryList->GetSelectionAnchor();
				if( ( nAnchor == LISTBOX_ENTRY_NOTFOUND ) && ( mpEntryList->GetSelectEntryCount() || mbStackMode ) )
				{
					nAnchor = mbStackMode ? 0 : mpEntryList->GetSelectEntryPos( mpEntryList->GetSelectEntryCount() - 1 );
				}
				if( nAnchor != LISTBOX_ENTRY_NOTFOUND )
				{
					// Alle Eintraege vom Anchor bis nSelect muessen selektiert sein
					sal_uInt16 nStart = Min( nSelect, nAnchor );
					sal_uInt16 nEnd = Max( nSelect, nAnchor );
					for ( sal_uInt16 n = nStart; n <= nEnd; n++ )
					{
						if ( !mpEntryList->IsEntryPosSelected( n ) )
						{
							SelectEntry( n, sal_True );
							bSelectionChanged = sal_True;
						}
					}

					// Ggf. muss noch was deselektiert werden...
					sal_uInt16 nLast = mpEntryList->GetLastSelected();
					if ( nLast != LISTBOX_ENTRY_NOTFOUND )
					{
						if ( ( nLast > nSelect ) && ( nLast > nAnchor ) )
						{
							for ( sal_uInt16 n = nSelect+1; n <= nLast; n++ )
							{
								if ( mpEntryList->IsEntryPosSelected( n ) )
								{
									SelectEntry( n, sal_False );
									bSelectionChanged = sal_True;
								}
							}
						}
						else if ( ( nLast < nSelect ) && ( nLast < nAnchor ) )
						{
							for ( sal_uInt16 n = nLast; n < nSelect; n++ )
							{
								if ( mpEntryList->IsEntryPosSelected( n ) )
								{
									SelectEntry( n, sal_False );
									bSelectionChanged = sal_True;
								}
							}
						}
					}
					mpEntryList->SetLastSelected( nSelect );
				}
			}
			else if( eLET != LET_TRACKING )
			{
				ImplHideFocusRect();
				ImplPaint( nSelect, sal_True );
				bFocusChanged = sal_True;
			}
		}
		else if( bShift )
		{
			bFocusChanged = sal_True;
		}

		if( bSelectionChanged )
			mbSelectionChanged = true;

		if( bFocusChanged )
		{
            long nHeightDiff = mpEntryList->GetAddedHeight( nSelect, mnTop, 0 );
			maFocusRect.SetPos( Point( 0, nHeightDiff ) );
            Size aSz( maFocusRect.GetWidth(),
                      mpEntryList->GetEntryHeight( nSelect ) );
            maFocusRect.SetSize( aSz );
			if( HasFocus() )
				ImplShowFocusRect();
		}
        ImplClearLayoutData();
	}
	return bSelectionChanged;
}

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

void ImplListBoxWindow::Tracking( const TrackingEvent& rTEvt )
{
	Point aPoint;
	Rectangle aRect( aPoint, GetOutputSizePixel() );
	sal_Bool bInside = aRect.IsInside( rTEvt.GetMouseEvent().GetPosPixel() );

	if( rTEvt.IsTrackingCanceled() || rTEvt.IsTrackingEnded() ) // MouseButtonUp
	{
		if ( bInside && !rTEvt.IsTrackingCanceled() )
		{
			mnSelectModifier = rTEvt.GetMouseEvent().GetModifier();
			ImplCallSelect();
		}
		else
		{
			maCancelHdl.Call( NULL );
			if ( !mbMulti )
			{
				mbTrackingSelect = true;
				SelectEntry( mnTrackingSaveSelection, sal_True );
				mbTrackingSelect = false;
				if ( mnTrackingSaveSelection != LISTBOX_ENTRY_NOTFOUND )
				{
                    long nHeightDiff = mpEntryList->GetAddedHeight( mnCurrentPos, mnTop, 0 );
					maFocusRect.SetPos( Point( 0, nHeightDiff ) );
                    Size aSz( maFocusRect.GetWidth(),
                              mpEntryList->GetEntryHeight( mnCurrentPos ) );
                    maFocusRect.SetSize( aSz );
					ImplShowFocusRect();
				}
			}
		}

		mbTrack = false;
	}
	else
	{
		sal_Bool bTrackOrQuickClick = mbTrack;
		if( !mbTrack )
		{
			if ( bInside )
			{
				mbTrack = true;
			}

			// Folgender Fall tritt nur auf, wenn man ganz kurz die Maustaste drueckt
			if( rTEvt.IsTrackingEnded() && mbTrack )
			{
				bTrackOrQuickClick = sal_True;
				mbTrack = false;
			}
		}

		if( bTrackOrQuickClick )
		{
			MouseEvent aMEvt = rTEvt.GetMouseEvent();
			Point aPt( aMEvt.GetPosPixel() );
			sal_Bool bShift = aMEvt.IsShift();
			sal_Bool bCtrl	= aMEvt.IsMod1();

			sal_uInt16 nSelect = LISTBOX_ENTRY_NOTFOUND;
			if( aPt.Y() < 0 )
			{
                if ( mnCurrentPos != LISTBOX_ENTRY_NOTFOUND )
                {
				    nSelect = mnCurrentPos ? ( mnCurrentPos - 1 ) : 0;
				    if( nSelect < mnTop )
					    SetTopEntry( mnTop-1 );
                }
			}
			else if( aPt.Y() > GetOutputSizePixel().Height() )
			{
                if ( mnCurrentPos != LISTBOX_ENTRY_NOTFOUND )
                {
				    nSelect = Min(	(sal_uInt16)(mnCurrentPos+1), (sal_uInt16)(mpEntryList->GetEntryCount()-1) );
				    if( nSelect >= GetLastVisibleEntry() )
					    SetTopEntry( mnTop+1 );
                }
			}
			else
			{
				nSelect = (sal_uInt16) ( ( aPt.Y() + mnBorder ) / mnMaxHeight ) + (sal_uInt16) mnTop;
				nSelect = Min( nSelect, GetLastVisibleEntry() );
				nSelect = Min( nSelect, (sal_uInt16) ( mpEntryList->GetEntryCount() - 1 ) );
			}

			if ( bInside )
			{
				if ( ( nSelect != mnCurrentPos ) || !GetEntryList()->GetSelectEntryCount() )
				{
					mbTrackingSelect = true;
					if ( SelectEntries( nSelect, LET_TRACKING, bShift, bCtrl ) )
		            {
                        if ( mbStackMode ) // #87734# (#87072#)
                        {
			                mbTravelSelect = true;
			                mnSelectModifier = rTEvt.GetMouseEvent().GetModifier();
			                ImplCallSelect();
			                mbTravelSelect = false;
                        }
		            }
					mbTrackingSelect = false;
				}
			}
			else
			{
				if ( !mbMulti && GetEntryList()->GetSelectEntryCount() )
				{
					mbTrackingSelect = true;
					SelectEntry( GetEntryList()->GetSelectEntryPos( 0 ), sal_False );
					mbTrackingSelect = false;
				}
				else if ( mbStackMode )
                {
                    if ( ( rTEvt.GetMouseEvent().GetPosPixel().X() > 0 )  && ( rTEvt.GetMouseEvent().GetPosPixel().X() < aRect.Right() ) )
                    {
				        if ( ( rTEvt.GetMouseEvent().GetPosPixel().Y() < 0 ) || ( rTEvt.GetMouseEvent().GetPosPixel().Y() > GetOutputSizePixel().Height() ) )
				        {
                            sal_Bool bSelectionChanged = sal_False;
                            if ( ( rTEvt.GetMouseEvent().GetPosPixel().Y() < 0 )
                                   && !mnCurrentPos )
                            {
                                if ( mpEntryList->IsEntryPosSelected( 0 ) )
                                {
					                SelectEntry( 0, sal_False );
                                    bSelectionChanged = sal_True;
                                    nSelect = LISTBOX_ENTRY_NOTFOUND;

                                }
                            }
                            else
                            {
					            mbTrackingSelect = true;
                                bSelectionChanged = SelectEntries( nSelect, LET_TRACKING, bShift, bCtrl );
					            mbTrackingSelect = false;
                            }

                            if ( bSelectionChanged )
		                    {
                                mbSelectionChanged = true;
			                    mbTravelSelect = true;
			                    mnSelectModifier = rTEvt.GetMouseEvent().GetModifier();
			                    ImplCallSelect();
			                    mbTravelSelect = false;
		                    }
				        }
                    }
                }
			}
			mnCurrentPos = nSelect;
            if ( mnCurrentPos == LISTBOX_ENTRY_NOTFOUND )
            {
                ImplHideFocusRect();
            }
            else
            {
                long nHeightDiff = mpEntryList->GetAddedHeight( mnCurrentPos, mnTop, 0 );
				maFocusRect.SetPos( Point( 0, nHeightDiff ) );
                Size aSz( maFocusRect.GetWidth(), mpEntryList->GetEntryHeight( mnCurrentPos ) );
                maFocusRect.SetSize( aSz );
				ImplShowFocusRect();
            }
		}
	}
}


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

void ImplListBoxWindow::KeyInput( const KeyEvent& rKEvt )
{
	if( !ProcessKeyInput( rKEvt ) )
		Control::KeyInput( rKEvt );
}

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

#define IMPL_SELECT_NODIRECTION	0
#define IMPL_SELECT_UP			1
#define IMPL_SELECT_DOWN		2

sal_Bool ImplListBoxWindow::ProcessKeyInput( const KeyEvent& rKEvt )
{
	// zu selektierender Eintrag
	sal_uInt16 nSelect = LISTBOX_ENTRY_NOTFOUND;
	LB_EVENT_TYPE eLET = LET_KEYMOVE;

	KeyCode aKeyCode = rKEvt.GetKeyCode();

	sal_Bool bShift = aKeyCode.IsShift();
	sal_Bool bCtrl	= aKeyCode.IsMod1() || aKeyCode.IsMod3();
	sal_Bool bMod2 = aKeyCode.IsMod2();
	sal_Bool bDone = sal_False;

	switch( aKeyCode.GetCode() )
	{		
		case KEY_UP:
		{
			if ( IsReadOnly() )
			{
				if ( GetTopEntry() )
					SetTopEntry( GetTopEntry()-1 );
			}
			else if ( !bMod2 )
			{
				if( mnCurrentPos == LISTBOX_ENTRY_NOTFOUND )
				{
					nSelect = mpEntryList->FindFirstSelectable( 0, true );
				}
				else if ( mnCurrentPos )
				{
					// search first selectable above the current position
					nSelect = mpEntryList->FindFirstSelectable( mnCurrentPos - 1, false );
				}

				if( ( nSelect != LISTBOX_ENTRY_NOTFOUND ) && ( nSelect < mnTop ) )
					SetTopEntry( mnTop-1 );

				bDone = sal_True;
			}
            maQuickSelectionEngine.Reset();
		}
		break;

		case KEY_DOWN:
		{
			if ( IsReadOnly() )
			{
				SetTopEntry( GetTopEntry()+1 );
			}
			else if ( !bMod2 )
			{
				if( mnCurrentPos == LISTBOX_ENTRY_NOTFOUND )
				{
					nSelect = mpEntryList->FindFirstSelectable( 0, true );
				}
				else if ( (mnCurrentPos+1) < mpEntryList->GetEntryCount() )
				{
					// search first selectable below the current position
					nSelect = mpEntryList->FindFirstSelectable( mnCurrentPos + 1, true );
				}

				if( ( nSelect != LISTBOX_ENTRY_NOTFOUND ) && ( nSelect >= GetLastVisibleEntry() ) )
					SetTopEntry( mnTop+1 );

				bDone = sal_True;
			}
			maQuickSelectionEngine.Reset();
		}
		break;

		case KEY_PAGEUP:
		{
			if ( IsReadOnly() )
			{
                sal_uInt16 nCurVis = GetLastVisibleEntry() - mnTop +1;
				SetTopEntry( ( mnTop > nCurVis ) ?
								(mnTop-nCurVis) : 0 );
			}
			else if ( !bCtrl && !bMod2 )
			{
				if( mnCurrentPos == LISTBOX_ENTRY_NOTFOUND )
				{
					nSelect = mpEntryList->FindFirstSelectable( 0, true );
				}
				else if ( mnCurrentPos )
				{
					if( mnCurrentPos == mnTop )
                    {
                        sal_uInt16 nCurVis = GetLastVisibleEntry() - mnTop +1;
						SetTopEntry( ( mnTop > nCurVis ) ? ( mnTop-nCurVis+1 ) : 0 );
                    }
					
					// find first selectable starting from mnTop looking foreward
					nSelect = mpEntryList->FindFirstSelectable( mnTop, true );
				}
				bDone = sal_True;
			}
			maQuickSelectionEngine.Reset();
		}
		break;

		case KEY_PAGEDOWN:
		{
			if ( IsReadOnly() )
			{
				SetTopEntry( GetLastVisibleEntry() );
			}
			else if ( !bCtrl && !bMod2 )
			{
				if( mnCurrentPos == LISTBOX_ENTRY_NOTFOUND )
				{
					nSelect = mpEntryList->FindFirstSelectable( 0, true );
				}
				else if ( (mnCurrentPos+1) < mpEntryList->GetEntryCount() )
				{
					sal_uInt16 nCount = mpEntryList->GetEntryCount();
                    sal_uInt16 nCurVis = GetLastVisibleEntry() - mnTop;
					sal_uInt16 nTmp = Min( nCurVis, nCount );
					nTmp += mnTop - 1;
					if( mnCurrentPos == nTmp && mnCurrentPos != nCount - 1 )
					{
						long nTmp2 = Min( (long)(nCount-nCurVis), (long)((long)mnTop+(long)nCurVis-1) );
						nTmp2 = Max( (long)0 , nTmp2 );
						nTmp = (sal_uInt16)(nTmp2+(nCurVis-1) );
						SetTopEntry( (sal_uInt16)nTmp2 );
					}
					// find first selectable starting from nTmp looking backwards
					nSelect = mpEntryList->FindFirstSelectable( nTmp, false );
				}
				bDone = sal_True;
			}
			maQuickSelectionEngine.Reset();
		}
		break;

		case KEY_HOME:
		{
			if ( IsReadOnly() )
			{
				SetTopEntry( 0 );
			}
			else if ( !bCtrl && !bMod2 )
			{
				if ( mnCurrentPos )
				{
					nSelect = mpEntryList->FindFirstSelectable( mpEntryList->GetEntryCount() ? 0 : LISTBOX_ENTRY_NOTFOUND, true );
					if( mnTop != 0 )
						SetTopEntry( 0 );

					bDone = sal_True;
				}
			}
			maQuickSelectionEngine.Reset();
		}
		break;

		case KEY_END:
		{
			if ( IsReadOnly() )
			{
				SetTopEntry( 0xFFFF );
			}
			else if ( !bCtrl && !bMod2 )
			{
				if( mnCurrentPos == LISTBOX_ENTRY_NOTFOUND )
				{
					nSelect = mpEntryList->FindFirstSelectable( 0, true );
				}
				else if ( (mnCurrentPos+1) < mpEntryList->GetEntryCount() )
				{
					sal_uInt16 nCount = mpEntryList->GetEntryCount();
					nSelect = mpEntryList->FindFirstSelectable( nCount - 1, false );
                    sal_uInt16 nCurVis = GetLastVisibleEntry() - mnTop + 1;
					if( nCount > nCurVis )
						SetTopEntry( nCount - nCurVis );
				}
				bDone = sal_True;
			}
			maQuickSelectionEngine.Reset();
		}
		break;

		case KEY_LEFT:
		{
			if ( !bCtrl && !bMod2 )
			{
				ScrollHorz( -HORZ_SCROLL );
				bDone = sal_True;
			}
			maQuickSelectionEngine.Reset();
		}
		break;

		case KEY_RIGHT:
		{
			if ( !bCtrl && !bMod2 )
			{
				ScrollHorz( HORZ_SCROLL );
				bDone = sal_True;
			}
			maQuickSelectionEngine.Reset();
		}
		break;

		case KEY_RETURN:
		{
			if ( !bMod2 && !IsReadOnly() )
			{
				mnSelectModifier = rKEvt.GetKeyCode().GetModifier();
				ImplCallSelect();
				bDone = sal_False;	// RETURN nicht abfangen.
			}
			maQuickSelectionEngine.Reset();
		}
		break;

		case KEY_SPACE:
		{
			if ( !bMod2 && !IsReadOnly() )
			{
				if( mbMulti && ( !mbSimpleMode || ( mbSimpleMode && bCtrl && !bShift ) || mbStackMode ) )
				{
					nSelect = mnCurrentPos;
					eLET = LET_KEYSPACE;
				}
				bDone = sal_True;
			}
			maQuickSelectionEngine.Reset();
		}
		break;

		case KEY_A:
		{
			if( bCtrl && mbMulti )
			{
                // paint only once
                sal_Bool bUpdates = IsUpdateMode();
                SetUpdateMode( sal_False );

                sal_uInt16 nEntryCount = mpEntryList->GetEntryCount();                
                for( sal_uInt16 i = 0; i < nEntryCount; i++ )
                    SelectEntry( i, sal_True );
                
                // restore update mode
                SetUpdateMode( bUpdates );
                Invalidate();
                
                maQuickSelectionEngine.Reset();
                
				bDone = sal_True;
                break;
			}
		}
        // fall through intentional
		default:
		{
            if ( !IsReadOnly() )
            {
                bDone = maQuickSelectionEngine.HandleKeyEvent( rKEvt );
            }
  		}
        break;
	}

    if  (   ( nSelect != LISTBOX_ENTRY_NOTFOUND )
        &&  (   ( !mpEntryList->IsEntryPosSelected( nSelect ) )
            ||  ( eLET == LET_KEYSPACE )
            )
        )
	{
		DBG_ASSERT( !mpEntryList->IsEntryPosSelected( nSelect ) || mbMulti, "ImplListBox: Selecting same Entry" );
	    if( nSelect >= mpEntryList->GetEntryCount() )
            nSelect = mpEntryList->GetEntryCount()-1;
		mnCurrentPos = nSelect;
		if ( SelectEntries( nSelect, eLET, bShift, bCtrl ) )
		{
			mbTravelSelect = true;
			mnSelectModifier = rKEvt.GetKeyCode().GetModifier();
			ImplCallSelect();
			mbTravelSelect = false;
		}
	}

	return bDone;
}

// -----------------------------------------------------------------------
namespace
{
    static ::vcl::StringEntryIdentifier lcl_getEntry( const ImplEntryList& _rList, sal_uInt16 _nPos, String& _out_entryText )
    {
        OSL_PRECOND( ( _nPos != LISTBOX_ENTRY_NOTFOUND ), "lcl_getEntry: invalid position!" );
        sal_uInt16 nEntryCount( _rList.GetEntryCount() );
        if ( _nPos >= nEntryCount )
            _nPos = 0;
        _out_entryText = _rList.GetEntryText( _nPos );

        // ::vcl::StringEntryIdentifier does not allow for 0 values, but our position is 0-based
        // => normalize
        return reinterpret_cast< ::vcl::StringEntryIdentifier >( _nPos + 1 );
    }

    static sal_uInt16 lcl_getEntryPos( ::vcl::StringEntryIdentifier _entry )
    {
        // our pos is 0-based, but StringEntryIdentifier does not allow for a NULL
        return static_cast< sal_uInt16 >( reinterpret_cast< sal_Int64 >( _entry ) ) - 1;
    }
}

// -----------------------------------------------------------------------
::vcl::StringEntryIdentifier ImplListBoxWindow::CurrentEntry( String& _out_entryText ) const
{
    return lcl_getEntry( *GetEntryList(), ( mnCurrentPos == LISTBOX_ENTRY_NOTFOUND ) ? 0 : mnCurrentPos + 1, _out_entryText );
}

// -----------------------------------------------------------------------
::vcl::StringEntryIdentifier ImplListBoxWindow::NextEntry( ::vcl::StringEntryIdentifier _currentEntry, String& _out_entryText ) const
{
    sal_uInt16 nNextPos = lcl_getEntryPos( _currentEntry ) + 1;
    return lcl_getEntry( *GetEntryList(), nNextPos, _out_entryText );
}

// -----------------------------------------------------------------------
void ImplListBoxWindow::SelectEntry( ::vcl::StringEntryIdentifier _entry )
{
    sal_uInt16 nSelect = lcl_getEntryPos( _entry );
    if ( mpEntryList->IsEntryPosSelected( nSelect ) )
    {
        // ignore that. This method is a callback from the QuickSelectionEngine, which means the user attempted
        // to select the given entry by typing its starting letters. No need to act.
        return;
    }

    // normalize
    OSL_ENSURE( nSelect < mpEntryList->GetEntryCount(), "ImplListBoxWindow::SelectEntry: how that?" );
    if( nSelect >= mpEntryList->GetEntryCount() )
        nSelect = mpEntryList->GetEntryCount()-1;

    // make visible
    ShowProminentEntry( nSelect );

    // actually select
    mnCurrentPos = nSelect;
	if ( SelectEntries( nSelect, LET_KEYMOVE, sal_False, sal_False ) )
	{
		mbTravelSelect = true;
		mnSelectModifier = 0;
		ImplCallSelect();
		mbTravelSelect = false;
	}
}

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

void ImplListBoxWindow::ImplPaint( sal_uInt16 nPos, sal_Bool bErase, bool bLayout )
{
	const StyleSettings& rStyleSettings = GetSettings().GetStyleSettings();
    
    const ImplEntryType* pEntry = mpEntryList->GetEntryPtr( nPos );
    if( ! pEntry )
        return;

	long nWidth  = GetOutputSizePixel().Width();
	long nY = mpEntryList->GetAddedHeight( nPos, mnTop );
	Rectangle aRect( Point( 0, nY ), Size( nWidth, pEntry->mnHeight ) );

    if( ! bLayout )
    {
        if( mpEntryList->IsEntryPosSelected( nPos ) )
        {
            SetTextColor( !IsEnabled() ? rStyleSettings.GetDisableColor() : rStyleSettings.GetHighlightTextColor() );
            SetFillColor( rStyleSettings.GetHighlightColor() );
            SetTextFillColor( rStyleSettings.GetHighlightColor() );
            DrawRect( aRect );
        }
        else
        {
            ImplInitSettings( sal_False, sal_True, sal_False );
            if( !IsEnabled() )
                SetTextColor( rStyleSettings.GetDisableColor() );
            SetTextFillColor();
            if( bErase )
                Erase( aRect );
        }
    }

    if ( IsUserDrawEnabled() )
    {
        mbInUserDraw = true;
		mnUserDrawEntry = nPos;
		aRect.Left() -= mnLeft;
		if ( nPos < GetEntryList()->GetMRUCount() )
			nPos = GetEntryList()->FindEntry( GetEntryList()->GetEntryText( nPos ) );
		nPos = sal::static_int_cast<sal_uInt16>(nPos - GetEntryList()->GetMRUCount());
		UserDrawEvent aUDEvt( this, aRect, nPos, 0 );
		maUserDrawHdl.Call( &aUDEvt );
		mbInUserDraw = false;
	}
	else
	{
		DrawEntry( nPos, sal_True, sal_True, sal_False, bLayout );
	}
}

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

void ImplListBoxWindow::DrawEntry( sal_uInt16 nPos, sal_Bool bDrawImage, sal_Bool bDrawText, sal_Bool bDrawTextAtImagePos, bool bLayout )
{
    const ImplEntryType* pEntry = mpEntryList->GetEntryPtr( nPos );
    if( ! pEntry )
        return; 
    
	// Bei Aenderungen in dieser Methode ggf. auch ImplWin::DrawEntry() anpassen.

	if ( mbInUserDraw )
		nPos = mnUserDrawEntry; // real entry, not the matching entry from MRU

    long nY = mpEntryList->GetAddedHeight( nPos, mnTop );
	Size aImgSz;

	if( bDrawImage && mpEntryList->HasImages() && !bLayout )
	{
		Image aImage = mpEntryList->GetEntryImage( nPos );
		if( !!aImage )
		{
            aImgSz = aImage.GetSizePixel();
			Point aPtImg( mnBorder - mnLeft, nY + ( ( pEntry->mnHeight - aImgSz.Height() ) / 2 ) );

			// pb: #106948# explicit mirroring for calc
			if ( mbMirroring )
				// right aligned
				aPtImg.X() = mnMaxWidth + mnBorder - aImgSz.Width() - mnLeft;

			if ( !IsZoom() )
			{
				DrawImage( aPtImg, aImage );
			}
			else
			{
				aImgSz.Width() = CalcZoom( aImgSz.Width() );
				aImgSz.Height() = CalcZoom( aImgSz.Height() );
				DrawImage( aPtImg, aImgSz, aImage );
			}

            const StyleSettings& rStyleSettings = Application::GetSettings().GetStyleSettings();
            const sal_uInt16 nEdgeBlendingPercent(GetEdgeBlending() ? rStyleSettings.GetEdgeBlending() : 0);

            if(nEdgeBlendingPercent && aImgSz.Width() && aImgSz.Height())
            {
                const Color& rTopLeft(rStyleSettings.GetEdgeBlendingTopLeftColor());
                const Color& rBottomRight(rStyleSettings.GetEdgeBlendingBottomRightColor());
                const sal_uInt8 nAlpha((nEdgeBlendingPercent * 255) / 100);
                const BitmapEx aBlendFrame(createBlendFrame(aImgSz, nAlpha, rTopLeft, rBottomRight));

                if(!aBlendFrame.IsEmpty())
                {
                    DrawBitmapEx(aPtImg, aBlendFrame);
                }
            }
		}
	}

	if( bDrawText )
	{
        MetricVector* pVector = bLayout ? &mpControlData->mpLayoutData->m_aUnicodeBoundRects : NULL;
        String* pDisplayText = bLayout ? &mpControlData->mpLayoutData->m_aDisplayText : NULL;
		XubString aStr( mpEntryList->GetEntryText( nPos ) );
		if ( aStr.Len() )
		{
            long nMaxWidth = Max( static_cast< long >( mnMaxWidth ),
                                  GetOutputSizePixel().Width() - 2*mnBorder );
            // a multiline entry should only be as wide a the window
            if( (pEntry->mnFlags & LISTBOX_ENTRY_FLAG_MULTILINE) )
                nMaxWidth = GetOutputSizePixel().Width() - 2*mnBorder;

            Rectangle aTextRect( Point( mnBorder - mnLeft, nY ),
                                 Size( nMaxWidth, pEntry->mnHeight ) );

            if( !bDrawTextAtImagePos && ( mpEntryList->HasEntryImage(nPos) || IsUserDrawEnabled() ) )
			{
				long nImageWidth = Max( mnMaxImgWidth, maUserItemSize.Width() );
                aTextRect.Left() += nImageWidth + IMG_TXT_DISTANCE;
			}

            if( bLayout )
                mpControlData->mpLayoutData->m_aLineIndices.push_back( mpControlData->mpLayoutData->m_aDisplayText.Len() );

			// pb: #106948# explicit mirroring for calc
			if ( mbMirroring )
			{
				// right aligned
                aTextRect.Left() = nMaxWidth + mnBorder - GetTextWidth( aStr ) - mnLeft;
				if ( aImgSz.Width() > 0 )
					aTextRect.Left() -= ( aImgSz.Width() + IMG_TXT_DISTANCE );
			}

            sal_uInt16 nDrawStyle = ImplGetTextStyle();
            if( (pEntry->mnFlags & LISTBOX_ENTRY_FLAG_MULTILINE) )
                nDrawStyle |= MULTILINE_ENTRY_DRAW_FLAGS;
            if( (pEntry->mnFlags & LISTBOX_ENTRY_FLAG_DRAW_DISABLED) )
                nDrawStyle |= TEXT_DRAW_DISABLE;
            
            DrawText( aTextRect, aStr, nDrawStyle, pVector, pDisplayText );
		}
	}

    if( !bLayout )
    {
        if ( ( mnSeparatorPos != LISTBOX_ENTRY_NOTFOUND ) &&
             ( ( nPos == mnSeparatorPos ) || ( nPos == mnSeparatorPos+1 ) ) )
        {
            Color aOldLineColor( GetLineColor() );
            SetLineColor( ( GetBackground().GetColor() != COL_LIGHTGRAY ) ? COL_LIGHTGRAY : COL_GRAY );
            Point aStartPos( 0, nY );
            if ( nPos == mnSeparatorPos )
                aStartPos.Y() += pEntry->mnHeight-1;
            Point aEndPos( aStartPos );
            aEndPos.X() = GetOutputSizePixel().Width();
            DrawLine( aStartPos, aEndPos );
            SetLineColor( aOldLineColor );
        }
    }
}

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

void ImplListBoxWindow::FillLayoutData() const
{
    mpControlData->mpLayoutData = new vcl::ControlLayoutData();
    const_cast<ImplListBoxWindow*>(this)->
        ImplDoPaint( Rectangle( Point( 0, 0 ), GetOutputSize() ), true );
}

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

void ImplListBoxWindow::ImplDoPaint( const Rectangle& rRect, bool bLayout )
{
	sal_uInt16 nCount = mpEntryList->GetEntryCount();

    sal_Bool bShowFocusRect = mbHasFocusRect;
    if ( mbHasFocusRect && ! bLayout )
        ImplHideFocusRect();

	long nY = 0; // + mnBorder;
	long nHeight = GetOutputSizePixel().Height();// - mnMaxHeight + mnBorder;

	for( sal_uInt16 i = (sal_uInt16)mnTop; i < nCount && nY < nHeight + mnMaxHeight; i++ )
	{
        const ImplEntryType* pEntry = mpEntryList->GetEntryPtr( i );
		if( nY + pEntry->mnHeight >= rRect.Top() &&
			nY <= rRect.Bottom() + mnMaxHeight )
		{
			ImplPaint( i, sal_False, bLayout );
		}
		nY += pEntry->mnHeight;
	}

    long nHeightDiff = mpEntryList->GetAddedHeight( mnCurrentPos, mnTop, 0 );
	maFocusRect.SetPos( Point( 0, nHeightDiff ) );
    Size aSz( maFocusRect.GetWidth(), mpEntryList->GetEntryHeight( mnCurrentPos ) );
    maFocusRect.SetSize( aSz );
	if( HasFocus() && bShowFocusRect && !bLayout )
		ImplShowFocusRect();
}

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

void ImplListBoxWindow::Paint( const Rectangle& rRect )
{
    ImplDoPaint( rRect );
}

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

sal_uInt16 ImplListBoxWindow::GetDisplayLineCount() const
{
    // FIXME: LISTBOX_ENTRY_FLAG_MULTILINE
    
	sal_uInt16 nCount = mpEntryList->GetEntryCount();
	long nHeight = GetOutputSizePixel().Height();// - mnMaxHeight + mnBorder;
    sal_uInt16 nEntries = static_cast< sal_uInt16 >( ( nHeight + mnMaxHeight - 1 ) / mnMaxHeight );
    if( nEntries > nCount-mnTop )
        nEntries = nCount-mnTop;

    return nEntries;
}

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

void ImplListBoxWindow::Resize()
{
    Control::Resize();

    sal_Bool bShowFocusRect = mbHasFocusRect;
    if ( bShowFocusRect )
        ImplHideFocusRect();

    if( mnCurrentPos != LISTBOX_ENTRY_NOTFOUND )
    {
        Size aSz( GetOutputSizePixel().Width(), mpEntryList->GetEntryHeight( mnCurrentPos ) );
        maFocusRect.SetSize( aSz );
    }

    if ( bShowFocusRect )
        ImplShowFocusRect();

    ImplClearLayoutData();
}

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

void ImplListBoxWindow::GetFocus()
{
	sal_uInt16 nPos = mnCurrentPos;
	if ( nPos == LISTBOX_ENTRY_NOTFOUND )
		nPos = 0;
    long nHeightDiff = mpEntryList->GetAddedHeight( nPos, mnTop, 0 );
	maFocusRect.SetPos( Point( 0, nHeightDiff ) );
    Size aSz( maFocusRect.GetWidth(), mpEntryList->GetEntryHeight( nPos ) );
    maFocusRect.SetSize( aSz );
	ImplShowFocusRect();
	Control::GetFocus();
}

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

void ImplListBoxWindow::LoseFocus()
{
	ImplHideFocusRect();
	Control::LoseFocus();
}

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

/*
void ImplListBoxWindow::RequestHelp( const HelpEvent& rHEvt )
{
	if ( rHEvt.GetMode() & HELPMODE_BALLOON )
		Help::ShowBalloon( this, rHEvt.GetMousePosPixel(), String() );

	Window::RequestHelp( rHEvt );
}
*/

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

void ImplListBoxWindow::SetTopEntry( sal_uInt16 nTop )
{
    if( mpEntryList->GetEntryCount() == 0 )
        return;
    
    long nWHeight = PixelToLogic( GetSizePixel() ).Height();
    
    sal_uInt16 nLastEntry = mpEntryList->GetEntryCount()-1;
    if( nTop > nLastEntry )
        nTop = nLastEntry;
    const ImplEntryType* pLast = mpEntryList->GetEntryPtr( nLastEntry );
    while( nTop > 0 && mpEntryList->GetAddedHeight( nLastEntry, nTop-1 ) + pLast->mnHeight <= nWHeight )
        nTop--;
    
	if ( nTop != mnTop )
	{
        ImplClearLayoutData();
		long nDiff = mpEntryList->GetAddedHeight( mnTop, nTop, 0 );
        Update();
		ImplHideFocusRect();
		mnTop = nTop;
		Scroll( 0, nDiff );
        Update();
		if( HasFocus() )
			ImplShowFocusRect();
		maScrollHdl.Call( this );
	}
}

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

void ImplListBoxWindow::ShowProminentEntry( sal_uInt16 nEntryPos )
{
    if( meProminentType == PROMINENT_MIDDLE )
    {
        sal_uInt16 nPos = nEntryPos;
        long nWHeight = PixelToLogic( GetSizePixel() ).Height();
        while( nEntryPos > 0 && mpEntryList->GetAddedHeight( nPos+1, nEntryPos ) < nWHeight/2 )
            nEntryPos--;
    }
    SetTopEntry( nEntryPos );
}

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

void ImplListBoxWindow::SetLeftIndent( long n )
{
	ScrollHorz( n - mnLeft );
}

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

void ImplListBoxWindow::ScrollHorz( long n )
{
	long nDiff = 0;
	if ( n > 0 )
	{
		long nWidth = GetOutputSizePixel().Width();
		if( ( mnMaxWidth - mnLeft + n ) > nWidth )
			nDiff = n;
	}
	else if ( n < 0 )
	{
		if( mnLeft )
		{
			long nAbs = -n;
			nDiff = - ( ( mnLeft > nAbs ) ? nAbs : mnLeft );
		}
	}

	if ( nDiff )
	{
        ImplClearLayoutData();
		mnLeft = sal::static_int_cast<sal_uInt16>(mnLeft + nDiff);
        Update();
		ImplHideFocusRect();
		Scroll( -nDiff, 0 );
        Update();
		if( HasFocus() )
			ImplShowFocusRect();
		maScrollHdl.Call( this );
	}
}

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

Size ImplListBoxWindow::CalcSize( sal_uInt16 nMaxLines ) const
{
    // FIXME: LISTBOX_ENTRY_FLAG_MULTILINE
    
	Size aSz;
//	sal_uInt16 nL = Min( nMaxLines, mpEntryList->GetEntryCount() );
	aSz.Height() =	nMaxLines * mnMaxHeight;
	aSz.Width() = mnMaxWidth + 2*mnBorder;
	return aSz;
}

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

Rectangle ImplListBoxWindow::GetBoundingRectangle( sal_uInt16 nItem ) const
{
    const ImplEntryType* pEntry = mpEntryList->GetEntryPtr( nItem );
    Size aSz( GetSizePixel().Width(), pEntry ? pEntry->mnHeight : GetEntryHeight() );
    long nY = mpEntryList->GetAddedHeight( nItem, GetTopEntry() ) - mpEntryList->GetAddedHeight( GetTopEntry() );
    Rectangle aRect( Point( 0, nY ), aSz );
    return aRect;
}


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

void ImplListBoxWindow::StateChanged( StateChangedType nType )
{
	Control::StateChanged( nType );

	if ( nType == STATE_CHANGE_ZOOM )
	{
		ImplInitSettings( sal_True, sal_False, sal_False );
		ImplCalcMetrics();
		Invalidate();
	}
	else if ( nType == STATE_CHANGE_UPDATEMODE )
	{
		if ( IsUpdateMode() && IsReallyVisible() )
			Invalidate();
	}
	else if ( nType == STATE_CHANGE_CONTROLFONT )
	{
		ImplInitSettings( sal_True, sal_False, sal_False );
		ImplCalcMetrics();
		Invalidate();
	}
	else if ( nType == STATE_CHANGE_CONTROLFOREGROUND )
	{
		ImplInitSettings( sal_False, sal_True, sal_False );
		Invalidate();
	}
	else if ( nType == STATE_CHANGE_CONTROLBACKGROUND )
	{
		ImplInitSettings( sal_False, sal_False, sal_True );
		Invalidate();
	}
    ImplClearLayoutData();
}

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

void ImplListBoxWindow::DataChanged( const DataChangedEvent& rDCEvt )
{
	Control::DataChanged( rDCEvt );

	if ( (rDCEvt.GetType() == DATACHANGED_FONTS) ||
		 (rDCEvt.GetType() == DATACHANGED_FONTSUBSTITUTION) ||
		 ((rDCEvt.GetType() == DATACHANGED_SETTINGS) &&
		  (rDCEvt.GetFlags() & SETTINGS_STYLE)) )
	{
        ImplClearLayoutData();
		ImplInitSettings( sal_True, sal_True, sal_True );
		ImplCalcMetrics();
		Invalidate();
	}
}

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

sal_uInt16 ImplListBoxWindow::ImplGetTextStyle() const
{
    sal_uInt16 nTextStyle = TEXT_DRAW_VCENTER;

    if ( mpEntryList->HasImages() )
        nTextStyle |= TEXT_DRAW_LEFT;
    else if ( mbCenter )
        nTextStyle |= TEXT_DRAW_CENTER;
    else if ( mbRight )
        nTextStyle |= TEXT_DRAW_RIGHT;
    else
        nTextStyle |= TEXT_DRAW_LEFT;

    return nTextStyle;
}

// =======================================================================

ImplListBox::ImplListBox( Window* pParent, WinBits nWinStyle ) :
	Control( pParent, nWinStyle ),
	maLBWindow( this, nWinStyle&(~WB_BORDER) )
{
    // for native widget rendering we must be able to detect this window type
    SetType( WINDOW_LISTBOXWINDOW );

	mpVScrollBar	= new ScrollBar( this, WB_VSCROLL | WB_DRAG );
	mpHScrollBar	= new ScrollBar( this, WB_HSCROLL | WB_DRAG );
	mpScrollBarBox	= new ScrollBarBox( this );

	Link aLink( LINK( this, ImplListBox, ScrollBarHdl ) );
	mpVScrollBar->SetScrollHdl( aLink );
	mpHScrollBar->SetScrollHdl( aLink );

	mbVScroll		= false;
	mbHScroll		= false;
	mbAutoHScroll	= ( nWinStyle & WB_AUTOHSCROLL );
    mbEdgeBlending  = false;

	maLBWindow.SetScrollHdl( LINK( this, ImplListBox, LBWindowScrolled ) );
	maLBWindow.SetMRUChangedHdl( LINK( this, ImplListBox, MRUChanged ) );
    maLBWindow.SetEdgeBlending(GetEdgeBlending());
	maLBWindow.Show();
}

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

ImplListBox::~ImplListBox()
{
	delete mpHScrollBar;
	delete mpVScrollBar;
	delete mpScrollBarBox;
}

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

void ImplListBox::Clear()
{
	maLBWindow.Clear();
	if ( GetEntryList()->GetMRUCount() )
	{
		maLBWindow.GetEntryList()->SetMRUCount( 0 );
		maLBWindow.SetSeparatorPos( LISTBOX_ENTRY_NOTFOUND );
	}
	mpVScrollBar->SetThumbPos( 0 );
	mpHScrollBar->SetThumbPos( 0 );
	StateChanged( STATE_CHANGE_DATA );
}

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

sal_uInt16 ImplListBox::InsertEntry( sal_uInt16 nPos, const XubString& rStr )
{
	ImplEntryType* pNewEntry = new ImplEntryType( rStr );
	sal_uInt16 nNewPos = maLBWindow.InsertEntry( nPos, pNewEntry );
	StateChanged( STATE_CHANGE_DATA );
	return nNewPos;
}

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

sal_uInt16 ImplListBox::InsertEntry( sal_uInt16 nPos, const Image& rImage )
{
	ImplEntryType* pNewEntry = new ImplEntryType( rImage );
	sal_uInt16 nNewPos = maLBWindow.InsertEntry( nPos, pNewEntry );
	StateChanged( STATE_CHANGE_DATA );
	return nNewPos;
}

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

sal_uInt16 ImplListBox::InsertEntry( sal_uInt16 nPos, const XubString& rStr, const Image& rImage )
{
	ImplEntryType* pNewEntry = new ImplEntryType( rStr, rImage );
	sal_uInt16 nNewPos = maLBWindow.InsertEntry( nPos, pNewEntry );
	StateChanged( STATE_CHANGE_DATA );
	return nNewPos;
}

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

void ImplListBox::RemoveEntry( sal_uInt16 nPos )
{
	maLBWindow.RemoveEntry( nPos );
	StateChanged( STATE_CHANGE_DATA );
}

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

void ImplListBox::SetEntryFlags( sal_uInt16 nPos, long nFlags )
{
	maLBWindow.SetEntryFlags( nPos, nFlags );
}

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

long ImplListBox::GetEntryFlags( sal_uInt16 nPos ) const
{
	return maLBWindow.GetEntryList()->GetEntryFlags( nPos );
}

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

void ImplListBox::SelectEntry( sal_uInt16 nPos, sal_Bool bSelect )
{
	maLBWindow.SelectEntry( nPos, bSelect );
}

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

void ImplListBox::SetNoSelection()
{
	maLBWindow.DeselectAll();
}

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

void ImplListBox::GetFocus()
{
	maLBWindow.GrabFocus();
}

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

Window* ImplListBox::GetPreferredKeyInputWindow()
{
    return &maLBWindow;
}

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

void ImplListBox::Resize()
{
    Control::Resize();
	ImplResizeControls();
	ImplCheckScrollBars();
}


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

IMPL_LINK( ImplListBox, MRUChanged, void*, EMPTYARG )
{
	StateChanged( STATE_CHANGE_DATA );
	return 1;
}

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

IMPL_LINK( ImplListBox, LBWindowScrolled, void*, EMPTYARG )
{
    long nSet = GetTopEntry();
    if( nSet > mpVScrollBar->GetRangeMax() )
        mpVScrollBar->SetRangeMax( GetEntryList()->GetEntryCount() );
	mpVScrollBar->SetThumbPos( GetTopEntry() );
	
	mpHScrollBar->SetThumbPos( GetLeftIndent() );

	maScrollHdl.Call( this );

	return 1;
}

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

IMPL_LINK( ImplListBox, ScrollBarHdl, ScrollBar*, pSB )
{
	sal_uInt16 nPos = (sal_uInt16) pSB->GetThumbPos();
	if( pSB == mpVScrollBar )
		SetTopEntry( nPos );
	else if( pSB == mpHScrollBar )
		SetLeftIndent( nPos );

	return 1;
}

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

void ImplListBox::ImplCheckScrollBars()
{
	sal_Bool bArrange = sal_False;

	Size aOutSz = GetOutputSizePixel();
	sal_uInt16 nEntries = GetEntryList()->GetEntryCount();
	sal_uInt16 nMaxVisEntries = (sal_uInt16) (aOutSz.Height() / GetEntryHeight());

	// vert. ScrollBar
	if( nEntries > nMaxVisEntries )
	{
		if( !mbVScroll )
			bArrange = sal_True;
		mbVScroll = true;

		// Ueberpruefung des rausgescrollten Bereichs
        if( GetEntryList()->GetSelectEntryCount() == 1 &&
            GetEntryList()->GetSelectEntryPos( 0 ) != LISTBOX_ENTRY_NOTFOUND )
		    ShowProminentEntry( GetEntryList()->GetSelectEntryPos( 0 ) );
		else
		    SetTopEntry( GetTopEntry() );	// MaxTop wird geprueft...
	}
	else
	{
		if( mbVScroll )
			bArrange = sal_True;
		mbVScroll = false;
		SetTopEntry( 0 );
	}

	// horz. ScrollBar
	if( mbAutoHScroll )
	{
		long nWidth = (sal_uInt16) aOutSz.Width();
		if ( mbVScroll )
			nWidth -= mpVScrollBar->GetSizePixel().Width();

		long nMaxWidth = GetMaxEntryWidth();
		if( nWidth < nMaxWidth )
		{
			if( !mbHScroll )
				bArrange = sal_True;
			mbHScroll = true;

			if ( !mbVScroll )	// ggf. brauchen wir jetzt doch einen
			{
				nMaxVisEntries = (sal_uInt16) ( ( aOutSz.Height() - mpHScrollBar->GetSizePixel().Height() ) / GetEntryHeight() );
				if( nEntries > nMaxVisEntries )
				{
					bArrange = sal_True;
					mbVScroll = true;

					// Ueberpruefung des rausgescrollten Bereichs
                    if( GetEntryList()->GetSelectEntryCount() == 1 &&
                        GetEntryList()->GetSelectEntryPos( 0 ) != LISTBOX_ENTRY_NOTFOUND )
                        ShowProminentEntry( GetEntryList()->GetSelectEntryPos( 0 ) );
                    else
                        SetTopEntry( GetTopEntry() );	// MaxTop wird geprueft...
				}
			}

			// Ueberpruefung des rausgescrollten Bereichs
			sal_uInt16 nMaxLI = (sal_uInt16) (nMaxWidth - nWidth);
			if ( nMaxLI < GetLeftIndent() )
				SetLeftIndent( nMaxLI );
		}
		else
		{
			if( mbHScroll )
				bArrange = sal_True;
			mbHScroll = false;
			SetLeftIndent( 0 );
		}
	}

	if( bArrange )
		ImplResizeControls();

	ImplInitScrollBars();
}

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

void ImplListBox::ImplInitScrollBars()
{
	Size aOutSz = maLBWindow.GetOutputSizePixel();

	if ( mbVScroll )
	{
		sal_uInt16 nEntries = GetEntryList()->GetEntryCount();
		sal_uInt16 nVisEntries = (sal_uInt16) (aOutSz.Height() / GetEntryHeight());
		mpVScrollBar->SetRangeMax( nEntries );
		mpVScrollBar->SetVisibleSize( nVisEntries );
		mpVScrollBar->SetPageSize( nVisEntries - 1 );
	}

	if ( mbHScroll )
	{
		mpHScrollBar->SetRangeMax( GetMaxEntryWidth() + HORZ_SCROLL );
		mpHScrollBar->SetVisibleSize( (sal_uInt16)aOutSz.Width() );
		mpHScrollBar->SetLineSize( HORZ_SCROLL );
		mpHScrollBar->SetPageSize( aOutSz.Width() - HORZ_SCROLL );
	}
}

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

void ImplListBox::ImplResizeControls()
{
	// Hier werden die Controls nur angeordnet, ob die Scrollbars
	// sichtbar sein sollen wird bereits in ImplCheckScrollBars ermittelt.

	Size aOutSz = GetOutputSizePixel();
	long nSBWidth = GetSettings().GetStyleSettings().GetScrollBarSize();
	nSBWidth = CalcZoom( nSBWidth );

	Size aInnerSz( aOutSz );
	if ( mbVScroll )
		aInnerSz.Width() -= nSBWidth;
	if ( mbHScroll )
		aInnerSz.Height() -= nSBWidth;

	// pb: #106948# explicit mirroring for calc
	// Scrollbar on left or right side?
	sal_Bool bMirroring = maLBWindow.IsMirroring();
	Point aWinPos( bMirroring && mbVScroll ? nSBWidth : 0, 0 );
	maLBWindow.SetPosSizePixel( aWinPos, aInnerSz );

	// ScrollBarBox
	if( mbVScroll && mbHScroll )
	{
		Point aBoxPos( bMirroring ? 0 : aInnerSz.Width(), aInnerSz.Height() );
		mpScrollBarBox->SetPosSizePixel( aBoxPos, Size( nSBWidth, nSBWidth ) );
		mpScrollBarBox->Show();
	}
	else
	{
		mpScrollBarBox->Hide();
	}

	// vert. ScrollBar
	if( mbVScroll )
	{
		// Scrollbar on left or right side?
		Point aVPos( bMirroring ? 0 : aOutSz.Width() - nSBWidth, 0 );
		mpVScrollBar->SetPosSizePixel( aVPos, Size( nSBWidth, aInnerSz.Height() ) );
		mpVScrollBar->Show();
	}
	else
	{
		mpVScrollBar->Hide();
        // #107254# Don't reset top entry after resize, but check for max top entry
		SetTopEntry( GetTopEntry() );
	}

	// horz. ScrollBar
	if( mbHScroll )
	{
		Point aHPos( ( bMirroring && mbVScroll ) ? nSBWidth : 0, aOutSz.Height() - nSBWidth );
		mpHScrollBar->SetPosSizePixel( aHPos, Size( aInnerSz.Width(), nSBWidth ) );
		mpHScrollBar->Show();
	}
	else
	{
		mpHScrollBar->Hide();
		SetLeftIndent( 0 );
	}
}

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

void ImplListBox::StateChanged( StateChangedType nType )
{
	if ( nType == STATE_CHANGE_INITSHOW )
	{
		ImplCheckScrollBars();
	}
	else if ( ( nType == STATE_CHANGE_UPDATEMODE ) || ( nType == STATE_CHANGE_DATA ) )
	{
		sal_Bool bUpdate = IsUpdateMode();
		maLBWindow.SetUpdateMode( bUpdate );
//		mpHScrollBar->SetUpdateMode( bUpdate );
//		mpVScrollBar->SetUpdateMode( bUpdate );
		if ( bUpdate && IsReallyVisible() )
			ImplCheckScrollBars();
	}
	else if( nType == STATE_CHANGE_ENABLE )
	{
		mpHScrollBar->Enable( IsEnabled() );
		mpVScrollBar->Enable( IsEnabled() );
		mpScrollBarBox->Enable( IsEnabled() );
		Invalidate();
	}
	else if ( nType == STATE_CHANGE_ZOOM )
	{
		maLBWindow.SetZoom( GetZoom() );
		Resize();
	}
	else if ( nType == STATE_CHANGE_CONTROLFONT )
	{
		maLBWindow.SetControlFont( GetControlFont() );
	}
	else if ( nType == STATE_CHANGE_CONTROLFOREGROUND )
	{
		maLBWindow.SetControlForeground( GetControlForeground() );
	}
	else if ( nType == STATE_CHANGE_CONTROLBACKGROUND )
	{
		maLBWindow.SetControlBackground( GetControlBackground() );
	}
    else if( nType == STATE_CHANGE_MIRRORING )
    {
        maLBWindow.EnableRTL( IsRTLEnabled() );
        mpHScrollBar->EnableRTL( IsRTLEnabled() );
        mpVScrollBar->EnableRTL( IsRTLEnabled() );
        ImplResizeControls();
    }

	Control::StateChanged( nType );
}

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

void ImplListBox::DataChanged( const DataChangedEvent& rDCEvt )
{
//	if ( (rDCEvt.GetType() == DATACHANGED_SETTINGS) &&
//		 (rDCEvt.GetFlags() & SETTINGS_STYLE) )
//	{
//		maLBWindow.SetSettings( GetSettings() );
//		Resize();
//	}
//	else
		Control::DataChanged( rDCEvt );
}

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

long ImplListBox::Notify( NotifyEvent& rNEvt )
{
	long nDone = 0;
	if ( rNEvt.GetType() == EVENT_COMMAND )
	{
		const CommandEvent& rCEvt = *rNEvt.GetCommandEvent();
		if ( rCEvt.GetCommand() == COMMAND_WHEEL )
		{
			const CommandWheelData* pData = rCEvt.GetWheelData();
			if( !pData->GetModifier() && ( pData->GetMode() == COMMAND_WHEEL_SCROLL ) )
			{
				nDone = HandleScrollCommand( rCEvt, mpHScrollBar, mpVScrollBar );
			}
		}
	}

	return nDone ? nDone : Window::Notify( rNEvt );
}

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

const Wallpaper& ImplListBox::GetDisplayBackground() const
{
    return maLBWindow.GetDisplayBackground();
}

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

sal_Bool ImplListBox::HandleWheelAsCursorTravel( const CommandEvent& rCEvt )
{
	sal_Bool bDone = sal_False;
	if ( rCEvt.GetCommand() == COMMAND_WHEEL )
	{
		const CommandWheelData* pData = rCEvt.GetWheelData();
		if( !pData->GetModifier() && ( pData->GetMode() == COMMAND_WHEEL_SCROLL ) )
		{
			sal_uInt16 nKey = ( pData->GetDelta() < 0 ) ? KEY_DOWN : KEY_UP;
			KeyEvent aKeyEvent( 0, KeyCode( nKey ) );
			bDone = ProcessKeyInput( aKeyEvent );
		}
	}
	return bDone;
}

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

void ImplListBox::SetMRUEntries( const XubString& rEntries, xub_Unicode cSep )
{
	sal_Bool bChanges = GetEntryList()->GetMRUCount() ? sal_True : sal_False;

	// Remove old MRU entries
	for ( sal_uInt16 n = GetEntryList()->GetMRUCount();n; )
		maLBWindow.RemoveEntry( --n );

	sal_uInt16 nMRUCount = 0;
	sal_uInt16 nEntries = rEntries.GetTokenCount( cSep );
	for ( sal_uInt16 nEntry = 0; nEntry < nEntries; nEntry++ )
	{
		XubString aEntry = rEntries.GetToken( nEntry, cSep );
		// Accept only existing entries
		if ( GetEntryList()->FindEntry( aEntry ) != LISTBOX_ENTRY_NOTFOUND )
		{
			ImplEntryType* pNewEntry = new ImplEntryType( aEntry );
			maLBWindow.GetEntryList()->InsertEntry( nMRUCount++, pNewEntry, sal_False );
			bChanges = sal_True;
		}
	}

	if ( bChanges )
	{
		maLBWindow.GetEntryList()->SetMRUCount( nMRUCount );
		SetSeparatorPos( nMRUCount ? nMRUCount-1 : 0 );
		StateChanged( STATE_CHANGE_DATA );
	}
}

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

XubString ImplListBox::GetMRUEntries( xub_Unicode cSep ) const
{
	String aEntries;
	for ( sal_uInt16 n = 0; n < GetEntryList()->GetMRUCount(); n++ )
	{
		aEntries += GetEntryList()->GetEntryText( n );
		if( n < ( GetEntryList()->GetMRUCount() - 1 ) )
			aEntries += cSep;
	}
	return aEntries;
}

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

void ImplListBox::SetEdgeBlending(bool bNew) 
{ 
    if(mbEdgeBlending != bNew)
    {
        mbEdgeBlending = bNew; 
        maLBWindow.SetEdgeBlending(GetEdgeBlending());
    }
}

// =======================================================================

ImplWin::ImplWin( Window* pParent, WinBits nWinStyle ) :
	Control ( pParent, nWinStyle )
{
	if ( IsNativeControlSupported(CTRL_LISTBOX, PART_ENTIRE_CONTROL)
			&& ! IsNativeControlSupported(CTRL_LISTBOX, PART_BUTTON_DOWN) )
		SetBackground();
	else
		SetBackground( Wallpaper( GetSettings().GetStyleSettings().GetFieldColor() ) );

	mbInUserDraw = false;
	mbUserDrawEnabled = false;
    mbEdgeBlending = false;
	mnItemPos = LISTBOX_ENTRY_NOTFOUND;
}

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

sal_Bool ImplWin::SetModeImage( const Image& rImage, BmpColorMode eMode )
{
    if( eMode == BMP_COLOR_NORMAL )
        SetImage( rImage );
    else if( eMode == BMP_COLOR_HIGHCONTRAST )
		maImageHC = rImage;
    else
        return sal_False;
    return sal_True;
}

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

const Image& ImplWin::GetModeImage( BmpColorMode eMode ) const
{
    if( eMode == BMP_COLOR_HIGHCONTRAST )
        return maImageHC;
    else
        return maImage;
}

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

void ImplWin::MBDown()
{
	if( IsEnabled() )
		maMBDownHdl.Call( this );
}

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

void ImplWin::MouseButtonDown( const MouseEvent& )
{
	if( IsEnabled() )
	{
//		Control::MouseButtonDown( rMEvt );
		MBDown();
	}
}

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

void ImplWin::FillLayoutData() const
{
    mpControlData->mpLayoutData = new vcl::ControlLayoutData();
    const_cast<ImplWin*>(this)->ImplDraw( true );
}

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

long ImplWin::PreNotify( NotifyEvent& rNEvt )
{
    long nDone = 0;
    const MouseEvent* pMouseEvt = NULL;

    if( (rNEvt.GetType() == EVENT_MOUSEMOVE) && (pMouseEvt = rNEvt.GetMouseEvent()) != NULL )
    {
        if( pMouseEvt->IsEnterWindow() || pMouseEvt->IsLeaveWindow() )
        {
            // trigger redraw as mouse over state has changed
            if ( IsNativeControlSupported(CTRL_LISTBOX, PART_ENTIRE_CONTROL)
			&& ! IsNativeControlSupported(CTRL_LISTBOX, PART_BUTTON_DOWN) )
            {
                GetParent()->GetWindow( WINDOW_BORDER )->Invalidate( INVALIDATE_NOERASE );
                GetParent()->GetWindow( WINDOW_BORDER )->Update();
            }
        }
    }

    return nDone ? nDone : Control::PreNotify(rNEvt);
}

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

void ImplWin::ImplDraw( bool bLayout )
{
	const StyleSettings& rStyleSettings = GetSettings().GetStyleSettings();

    sal_Bool bNativeOK = sal_False;

    if( ! bLayout )
    {
        ControlState nState = CTRL_STATE_ENABLED;
        if ( IsNativeControlSupported(CTRL_LISTBOX, PART_ENTIRE_CONTROL)
			&& IsNativeControlSupported(CTRL_LISTBOX, HAS_BACKGROUND_TEXTURE) )
        {
	        // Repaint the (focused) area similarly to
	        // ImplSmallBorderWindowView::DrawWindow() in
	        // vcl/source/window/brdwin.cxx
	        Window *pWin = GetParent();

	        ImplControlValue aControlValue;
	        if ( !pWin->IsEnabled() )
		    nState &= ~CTRL_STATE_ENABLED;
	        if ( pWin->HasFocus() )
		    nState |= CTRL_STATE_FOCUSED;
    	    
	        // The listbox is painted over the entire control including the
	        // border, but ImplWin does not contain the border => correction
	        // needed.
	        sal_Int32 nLeft, nTop, nRight, nBottom;
	        pWin->GetBorder( nLeft, nTop, nRight, nBottom );
	        Point aPoint( -nLeft, -nTop );
	        Rectangle aCtrlRegion( aPoint - GetPosPixel(), pWin->GetSizePixel() );

            sal_Bool bMouseOver = sal_False;
            if( GetParent() )
            {
                Window *pChild = GetParent()->GetWindow( WINDOW_FIRSTCHILD );
                while( pChild && (bMouseOver = pChild->IsMouseOver()) == sal_False )
                    pChild = pChild->GetWindow( WINDOW_NEXT );
            }
    	    
            if( bMouseOver )
                nState |= CTRL_STATE_ROLLOVER;
            
            // if parent has no border, then nobody has drawn the background
            // since no border window exists. so draw it here.
            WinBits nParentStyle = pWin->GetStyle();
            if( ! (nParentStyle & WB_BORDER) || (nParentStyle & WB_NOBORDER) )
            {
                Rectangle aParentRect( Point( 0, 0 ), pWin->GetSizePixel() );
                pWin->DrawNativeControl( CTRL_LISTBOX, PART_ENTIRE_CONTROL, aParentRect,
                                         nState, aControlValue, rtl::OUString() );
            }
            
	        bNativeOK = DrawNativeControl( CTRL_LISTBOX, PART_ENTIRE_CONTROL, aCtrlRegion, nState,
		        aControlValue, rtl::OUString() );
	    }

        if( IsEnabled() )
        {
            if( HasFocus() )
            {
                SetTextColor( rStyleSettings.GetHighlightTextColor() );
                SetFillColor( rStyleSettings.GetHighlightColor() );
                DrawRect( maFocusRect );
            }
            else
            {
                Color aColor;
                if( bNativeOK && (nState & CTRL_STATE_ROLLOVER) )
                    aColor = rStyleSettings.GetFieldRolloverTextColor();
                else
                    aColor = rStyleSettings.GetFieldTextColor();
                if( IsControlForeground() )
                    aColor = GetControlForeground();
                SetTextColor( aColor );
		        if ( !bNativeOK )
		            Erase( maFocusRect );
            }
        }
        else // Disabled
        {
            SetTextColor( rStyleSettings.GetDisableColor() );
	        if ( !bNativeOK )
		        Erase( maFocusRect );
        }
    }

	if ( IsUserDrawEnabled() )
	{
		mbInUserDraw = true;
		UserDrawEvent aUDEvt( this, maFocusRect, mnItemPos, 0 );
		maUserDrawHdl.Call( &aUDEvt );
		mbInUserDraw = false;
	}
	else
	{
		DrawEntry( sal_True, sal_True, sal_False, bLayout );
	}
}

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

void ImplWin::Paint( const Rectangle& )
{
    ImplDraw();
}

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

void ImplWin::DrawEntry( sal_Bool bDrawImage, sal_Bool bDrawText, sal_Bool bDrawTextAtImagePos, bool bLayout )
{
	long nBorder = 1;
	Size aOutSz = GetOutputSizePixel();

	sal_Bool bImage = !!maImage;
	if( bDrawImage && bImage && !bLayout )
	{
		sal_uInt16 nStyle = 0;
		Size aImgSz = maImage.GetSizePixel();
		Point aPtImg( nBorder, ( ( aOutSz.Height() - aImgSz.Height() ) / 2 ) );
        const StyleSettings& rStyleSettings = Application::GetSettings().GetStyleSettings();

		// check for HC mode
		Image *pImage = &maImage;

		if( !!maImageHC )
		{
			if( rStyleSettings.GetHighContrastMode() )
				pImage = &maImageHC;
		}

		if ( !IsZoom() )
		{
			DrawImage( aPtImg, *pImage, nStyle );
		}
		else
		{
			aImgSz.Width() = CalcZoom( aImgSz.Width() );
			aImgSz.Height() = CalcZoom( aImgSz.Height() );
			DrawImage( aPtImg, aImgSz, *pImage, nStyle );
		}

        const sal_uInt16 nEdgeBlendingPercent(GetEdgeBlending() ? rStyleSettings.GetEdgeBlending() : 0);

        if(nEdgeBlendingPercent)
        {
            const Color& rTopLeft(rStyleSettings.GetEdgeBlendingTopLeftColor());
            const Color& rBottomRight(rStyleSettings.GetEdgeBlendingBottomRightColor());
            const sal_uInt8 nAlpha((nEdgeBlendingPercent * 255) / 100);
            const BitmapEx aBlendFrame(createBlendFrame(aImgSz, nAlpha, rTopLeft, rBottomRight));

            if(!aBlendFrame.IsEmpty())
            {
                DrawBitmapEx(aPtImg, aBlendFrame);
            }
        }
	}

	if( bDrawText && maString.Len() )
	{
        sal_uInt16 nTextStyle = TEXT_DRAW_VCENTER;

        if ( bDrawImage && bImage && !bLayout )
            nTextStyle |= TEXT_DRAW_LEFT;
        else if ( GetStyle() & WB_CENTER )
            nTextStyle |= TEXT_DRAW_CENTER;
        else if ( GetStyle() & WB_RIGHT )
            nTextStyle |= TEXT_DRAW_RIGHT;
        else
            nTextStyle |= TEXT_DRAW_LEFT;

        Rectangle aTextRect( Point( nBorder, 0 ), Size( aOutSz.Width()-2*nBorder, aOutSz.Height() ) );

        if ( !bDrawTextAtImagePos && ( bImage || IsUserDrawEnabled() ) )
		{
			long nMaxWidth = Max( maImage.GetSizePixel().Width(), maUserItemSize.Width() );
			aTextRect.Left() += nMaxWidth + IMG_TXT_DISTANCE;
		}

        MetricVector* pVector = bLayout ? &mpControlData->mpLayoutData->m_aUnicodeBoundRects : NULL;
        String* pDisplayText = bLayout ? &mpControlData->mpLayoutData->m_aDisplayText : NULL;
		DrawText( aTextRect, maString, nTextStyle, pVector, pDisplayText );
	}

	if( HasFocus() && !bLayout )
		ShowFocus( maFocusRect );
}

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

void ImplWin::Resize()
{
    Control::Resize();
	maFocusRect.SetSize( GetOutputSizePixel() );
	Invalidate();
}

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

void ImplWin::GetFocus()
{
	ShowFocus( maFocusRect );
    if( ImplGetSVData()->maNWFData.mbNoFocusRects &&
        IsNativeWidgetEnabled() &&
        IsNativeControlSupported( CTRL_LISTBOX, PART_ENTIRE_CONTROL ) )
    {
        Window* pWin = GetParent()->GetWindow( WINDOW_BORDER );
        if( ! pWin )
            pWin = GetParent();
        pWin->Invalidate();
    }
    else
        Invalidate();
	Control::GetFocus();
}

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

void ImplWin::LoseFocus()
{
	HideFocus();
    if( ImplGetSVData()->maNWFData.mbNoFocusRects &&
        IsNativeWidgetEnabled() &&
        IsNativeControlSupported( CTRL_LISTBOX, PART_ENTIRE_CONTROL ) )
    {
        Window* pWin = GetParent()->GetWindow( WINDOW_BORDER );
        if( ! pWin )
            pWin = GetParent();
        pWin->Invalidate();
    }
    else
        Invalidate();
	Control::LoseFocus();
}

// =======================================================================

ImplBtn::ImplBtn( Window* pParent, WinBits nWinStyle ) :
	PushButton(  pParent, nWinStyle ),
	mbDown	( sal_False )
{
}

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

void ImplBtn::MBDown()
{
	if( IsEnabled() )
	   maMBDownHdl.Call( this );
}

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

void ImplBtn::MouseButtonDown( const MouseEvent& )
{
	//PushButton::MouseButtonDown( rMEvt );
	if( IsEnabled() )
	{
		MBDown();
		mbDown = sal_True;
	}
}

// =======================================================================

ImplListBoxFloatingWindow::ImplListBoxFloatingWindow( Window* pParent ) :
	FloatingWindow( pParent, WB_BORDER | WB_SYSTEMWINDOW | WB_NOSHADOW )    // no drop shadow for list boxes
{
	mpImplLB = NULL;
	mnDDLineCount = 0;
	mbAutoWidth = sal_False;

    mnPopupModeStartSaveSelection = LISTBOX_ENTRY_NOTFOUND;

	EnableSaveBackground();
    
    Window * pBorderWindow = ImplGetBorderWindow();
    if( pBorderWindow )
    {
        SetAccessibleRole(accessibility::AccessibleRole::PANEL);
        pBorderWindow->SetAccessibleRole(accessibility::AccessibleRole::WINDOW);
    }
    else
    {
        SetAccessibleRole(accessibility::AccessibleRole::WINDOW);
    }

}

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

long ImplListBoxFloatingWindow::PreNotify( NotifyEvent& rNEvt )
{
	if( rNEvt.GetType() == EVENT_LOSEFOCUS )
	{
		if( !GetParent()->HasChildPathFocus( sal_True ) )
			EndPopupMode();
	}

	return FloatingWindow::PreNotify( rNEvt );
}

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

void ImplListBoxFloatingWindow::SetPosSizePixel( long nX, long nY, long nWidth, long nHeight, sal_uInt16 nFlags )
{
	FloatingWindow::SetPosSizePixel( nX, nY, nWidth, nHeight, nFlags );

	// Fix #60890# ( MBA ): um auch im aufgeklappten Zustand der Listbox die Gr"o\se einfach zu einen
	// Aufruf von Resize() "andern zu k"onnen, wird die Position hier ggf. angepa\t
	if ( IsReallyVisible() && ( nFlags & WINDOW_POSSIZE_HEIGHT ) )
	{
		Point aPos = GetParent()->GetPosPixel();
		aPos = GetParent()->GetParent()->OutputToScreenPixel( aPos );

		if ( nFlags & WINDOW_POSSIZE_X )
			aPos.X() = nX;

		if ( nFlags & WINDOW_POSSIZE_Y )
			aPos.Y() = nY;

		sal_uInt16 nIndex;
		SetPosPixel( ImplCalcPos( this, Rectangle( aPos, GetParent()->GetSizePixel() ), FLOATWIN_POPUPMODE_DOWN, nIndex ) );
	}

//	if( !IsReallyVisible() )
	{
		// Die ImplListBox erhaelt kein Resize, weil nicht sichtbar.
		// Die Fenster muessen aber ein Resize() erhalten, damit die
		// Anzahl der sichtbaren Eintraege fuer PgUp/PgDown stimmt.
		// Die Anzahl kann auch nicht von List/Combobox berechnet werden,
		// weil hierfuer auch die ggf. vorhandene vertikale Scrollbar
		// beruecksichtigt werden muss.
		mpImplLB->SetSizePixel( GetOutputSizePixel() );
		((Window*)mpImplLB)->Resize();
		((Window*)mpImplLB->GetMainWindow())->Resize();
	}
}

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

void ImplListBoxFloatingWindow::Resize()
{
    mpImplLB->GetMainWindow()->ImplClearLayoutData();
    FloatingWindow::Resize();
}

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

Size ImplListBoxFloatingWindow::CalcFloatSize()
{
	Size aFloatSz( maPrefSz );

	sal_Int32 nLeft, nTop, nRight, nBottom;
	GetBorder( nLeft, nTop, nRight, nBottom );

	sal_uInt16 nLines = mpImplLB->GetEntryList()->GetEntryCount();
	if ( mnDDLineCount && ( nLines > mnDDLineCount ) )
		nLines = mnDDLineCount;

	Size aSz = mpImplLB->CalcSize( nLines );
	long nMaxHeight = aSz.Height() + nTop + nBottom;

	if ( mnDDLineCount )
		aFloatSz.Height() = nMaxHeight;

	if( mbAutoWidth )
	{
		// AutoSize erstmal nur fuer die Breite...

		aFloatSz.Width() = aSz.Width() + nLeft + nRight;
		aFloatSz.Width() += nRight; // etwas mehr Platz sieht besser aus...

		if ( ( aFloatSz.Height() < nMaxHeight ) || ( mnDDLineCount && ( mnDDLineCount < mpImplLB->GetEntryList()->GetEntryCount() ) ) )
		{
			// dann wird noch der vertikale Scrollbar benoetigt
			long nSBWidth = GetSettings().GetStyleSettings().GetScrollBarSize();
			aFloatSz.Width() += nSBWidth;
		}
	}

	if ( aFloatSz.Height() > nMaxHeight )
		aFloatSz.Height() = nMaxHeight;

	// Minimale Hoehe, falls Hoehe nicht auf Float-Hoehe eingestellt wurde.
	// Der Parent vom FloatWin muss die DropDown-Combo/Listbox sein.
	Size aParentSz = GetParent()->GetSizePixel();
	if( !mnDDLineCount && ( aFloatSz.Height() < aParentSz.Height() ) )
		aFloatSz.Height() = aParentSz.Height();

	// Nicht schmaler als der Parent werden...
	if( aFloatSz.Width() < aParentSz.Width() )
		aFloatSz.Width() = aParentSz.Width();

	// Hoehe auf Entries alignen...
	long nInnerHeight = aFloatSz.Height() - nTop - nBottom;
	long nEntryHeight = mpImplLB->GetEntryHeight();
	if ( nInnerHeight % nEntryHeight )
	{
		nInnerHeight /= nEntryHeight;
		nInnerHeight++;
		nInnerHeight *= nEntryHeight;
		aFloatSz.Height() = nInnerHeight + nTop + nBottom;
	}

	return aFloatSz;
}

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

void ImplListBoxFloatingWindow::StartFloat( sal_Bool bStartTracking )
{
	if( !IsInPopupMode() )
	{
		Size aFloatSz = CalcFloatSize();

		SetSizePixel( aFloatSz );
		mpImplLB->SetSizePixel( GetOutputSizePixel() );

		sal_uInt16 nPos = mpImplLB->GetEntryList()->GetSelectEntryPos( 0 );
        mnPopupModeStartSaveSelection = nPos;

        Size aSz = GetParent()->GetSizePixel();
		Point aPos = GetParent()->GetPosPixel();
		aPos = GetParent()->GetParent()->OutputToScreenPixel( aPos );
        // FIXME: this ugly hack is for Mac/Aqua
        // should be replaced by a real mechanism to place the float rectangle
        if( ImplGetSVData()->maNWFData.mbNoFocusRects &&
            GetParent()->IsNativeWidgetEnabled() )
        {
            sal_Int32 nLeft = 4, nTop = 4, nRight = 4, nBottom = 4;
            aPos.X() += nLeft;
            aPos.Y() += nTop;
            aSz.Width() -= nLeft + nRight;
            aSz.Height() -= nTop + nBottom;
        }
		Rectangle aRect( aPos, aSz );

        // check if the control's parent is un-mirrored which is the case for form controls in a mirrored UI
        // where the document is unmirrored
        // because StartPopupMode() expects a rectangle in mirrored coordinates we have to re-mirror
        if( GetParent()->GetParent()->ImplIsAntiparallel() )
            GetParent()->GetParent()->ImplReMirror( aRect );

		StartPopupMode( aRect, FLOATWIN_POPUPMODE_DOWN );

        if( nPos != LISTBOX_ENTRY_NOTFOUND )
            mpImplLB->ShowProminentEntry( nPos );

		if( bStartTracking )
			mpImplLB->GetMainWindow()->EnableMouseMoveSelect( sal_True );

		if ( mpImplLB->GetMainWindow()->IsGrabFocusAllowed() )
			mpImplLB->GetMainWindow()->GrabFocus();

        mpImplLB->GetMainWindow()->ImplClearLayoutData();
	}
}
