/**************************************************************
 * 
 * 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/rc.h"
#include "tools/debug.hxx"


#include "vcl/decoview.hxx"
#include "vcl/event.hxx"
#include "vcl/scrbar.hxx"
#include "vcl/button.hxx"
#include "vcl/edit.hxx"
#include "vcl/lstbox.hxx"
#include "vcl/combobox.hxx"

#include "svdata.hxx"
#include "controldata.hxx"
#include "subedit.hxx"
#include "ilstbox.hxx"
#include "dndevdis.hxx"

#include <com/sun/star/datatransfer/dnd/XDropTarget.hpp>

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

ListBox::ListBox( WindowType nType ) : Control( nType )
{
	ImplInitListBoxData();
}

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

ListBox::ListBox( Window* pParent, WinBits nStyle ) : Control( WINDOW_LISTBOX )
{
	ImplInitListBoxData();
	ImplInit( pParent, nStyle );
}

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

ListBox::ListBox( Window* pParent, const ResId& rResId ) :
	Control( WINDOW_LISTBOX )
{
	ImplInitListBoxData();
	rResId.SetRT( RSC_LISTBOX );
	WinBits nStyle = ImplInitRes( rResId );
	ImplInit( pParent, nStyle );
	ImplLoadRes( rResId );

	if ( !(nStyle & WB_HIDE ) )
		Show();
}

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

ListBox::~ListBox()
{
    //#109201#
    ImplCallEventListeners( VCLEVENT_OBJECT_DYING );

    delete mpImplLB;

	// Beim zerstoeren des FloatWins macht TH ein GrabFocus auf den Parent,
	// also diese ListBox => PreNotify()...
	mpImplLB = NULL;

	delete mpFloatWin;
	delete mpImplWin;
	delete mpBtn;
}

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

void ListBox::ImplInitListBoxData()
{
	mpFloatWin		= NULL;
	mpImplWin		= NULL;
	mpBtn			= NULL;

	mnDDHeight		= 0;
	mbDDAutoSize	= sal_True;
	mnSaveValue 	= LISTBOX_ENTRY_NOTFOUND;
    mnLineCount     = 0;
}

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

void ListBox::ImplInit( Window* pParent, WinBits nStyle )
{
	nStyle = ImplInitStyle( nStyle );
	if ( !(nStyle & WB_NOBORDER) && ( nStyle & WB_DROPDOWN ) )
		nStyle |= WB_BORDER;

	Control::ImplInit( pParent, nStyle, NULL );
	SetBackground();

    ::com::sun::star::uno::Reference< ::com::sun::star::datatransfer::dnd::XDropTargetListener> xDrop = new DNDEventDispatcher(this);

	if( nStyle & WB_DROPDOWN )
	{
        sal_Int32 nLeft, nTop, nRight, nBottom;
        GetBorder( nLeft, nTop, nRight, nBottom );
        mnDDHeight = (sal_uInt16)(GetTextHeight() + nTop + nBottom + 4);

        if( IsNativeWidgetEnabled() &&
            IsNativeControlSupported( CTRL_LISTBOX, PART_ENTIRE_CONTROL ) )
        {
                ImplControlValue aControlValue;
                Rectangle aCtrlRegion( Point( 0, 0 ), Size( 20, mnDDHeight ) );
                Rectangle aBoundingRgn( aCtrlRegion );
                Rectangle aContentRgn( aCtrlRegion );
                if( GetNativeControlRegion( CTRL_LISTBOX, PART_ENTIRE_CONTROL, aCtrlRegion,
                                            CTRL_STATE_ENABLED, aControlValue, rtl::OUString(),
                                            aBoundingRgn, aContentRgn ) )
                {
                    sal_Int32 nHeight = aBoundingRgn.GetHeight();
                    if( nHeight > mnDDHeight )
                        mnDDHeight = static_cast<sal_uInt16>(nHeight);
                }
        }

		mpFloatWin = new ImplListBoxFloatingWindow( this );
		mpFloatWin->SetAutoWidth( sal_True );
		mpFloatWin->SetPopupModeEndHdl( LINK( this, ListBox, ImplPopupModeEndHdl ) );
        mpFloatWin->GetDropTarget()->addDropTargetListener(xDrop);

		mpImplWin = new ImplWin( this, (nStyle & (WB_LEFT|WB_RIGHT|WB_CENTER))|WB_NOBORDER );
		mpImplWin->SetMBDownHdl( LINK( this, ListBox, ImplClickBtnHdl ) );
		mpImplWin->SetUserDrawHdl( LINK( this, ListBox, ImplUserDrawHdl ) );
		mpImplWin->Show();
        mpImplWin->GetDropTarget()->addDropTargetListener(xDrop);

		mpBtn = new ImplBtn( this, WB_NOLIGHTBORDER | WB_RECTSTYLE );
		ImplInitDropDownButton( mpBtn );
		mpBtn->SetMBDownHdl( LINK( this, ListBox, ImplClickBtnHdl ) );
		mpBtn->Show();
        mpBtn->GetDropTarget()->addDropTargetListener(xDrop);

	}

	Window* pLBParent = this;
	if ( mpFloatWin )
		pLBParent = mpFloatWin;
	mpImplLB = new ImplListBox( pLBParent, nStyle&(~WB_BORDER) );
	mpImplLB->SetSelectHdl( LINK( this, ListBox, ImplSelectHdl ) );
	mpImplLB->SetScrollHdl( LINK( this, ListBox, ImplScrollHdl ) );
	mpImplLB->SetCancelHdl( LINK( this, ListBox, ImplCancelHdl ) );
	mpImplLB->SetDoubleClickHdl( LINK( this, ListBox, ImplDoubleClickHdl ) );
	mpImplLB->SetUserDrawHdl( LINK( this, ListBox, ImplUserDrawHdl ) );
	mpImplLB->SetPosPixel( Point() );
	mpImplLB->Show();
    
    mpImplLB->GetDropTarget()->addDropTargetListener(xDrop);
    mpImplLB->SetDropTraget(xDrop);

	if ( mpFloatWin )
	{
		mpFloatWin->SetImplListBox( mpImplLB );
		mpImplLB->SetSelectionChangedHdl( LINK( this, ListBox, ImplSelectionChangedHdl ) );
	}
	else
		mpImplLB->GetMainWindow()->AllowGrabFocus( sal_True );

	SetCompoundControl( sal_True );
}

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

WinBits ListBox::ImplInitStyle( WinBits nStyle )
{
	if ( !(nStyle & WB_NOTABSTOP) )
		nStyle |= WB_TABSTOP;
	if ( !(nStyle & WB_NOGROUP) )
		nStyle |= WB_GROUP;
	return nStyle;
}

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

void ListBox::ImplLoadRes( const ResId& rResId )
{
	Control::ImplLoadRes( rResId );

	sal_uInt16 nSelPos = ReadShortRes();
	sal_uInt16 nNumber = sal::static_int_cast<sal_uInt16>(ReadLongRes());

	for( sal_uInt16 i = 0; i < nNumber; i++ )
	{
		sal_uInt16 nPos = InsertEntry( ReadStringRes(), LISTBOX_APPEND );

		long nId = ReadLongRes();
		if( nId )
			SetEntryData( nPos, (void *)nId );	// ID als UserData
	}

	if( nSelPos < nNumber )
		SelectEntryPos( nSelPos );
}

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

IMPL_LINK( ListBox, ImplSelectHdl, void*, EMPTYARG )
{
	sal_Bool bPopup = IsInDropDown();
	if( IsDropDownBox() )
	{
		if( !mpImplLB->IsTravelSelect() )
		{
			mpFloatWin->EndPopupMode();
			mpImplWin->GrabFocus();
		}

		mpImplWin->SetItemPos( GetSelectEntryPos() );
		mpImplWin->SetString( GetSelectEntry() );
		if( mpImplLB->GetEntryList()->HasImages() )
		{
			Image aImage = mpImplLB->GetEntryList()->GetEntryImage( GetSelectEntryPos() );
			mpImplWin->SetImage( aImage );
		}
		mpImplWin->Invalidate();
	}

	if ( ( !IsTravelSelect() || mpImplLB->IsSelectionChanged() ) || ( bPopup && !IsMultiSelectionEnabled() ) )
		Select();

	return 1;
}

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

IMPL_LINK( ListBox, ImplScrollHdl, void*, EMPTYARG )
{
    ImplCallEventListeners( VCLEVENT_LISTBOX_SCROLLED );
	return 1;
}

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

IMPL_LINK( ListBox, ImplCancelHdl, void*, EMPTYARG )
{
	if( IsInDropDown() )
		mpFloatWin->EndPopupMode();

	return 1;
}

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

IMPL_LINK( ListBox, ImplSelectionChangedHdl, void*, n )
{
	if ( !mpImplLB->IsTrackingSelect() )
	{
		sal_uInt16 nChanged = (sal_uInt16)(sal_uLong)n;
		const ImplEntryList* pEntryList = mpImplLB->GetEntryList();
		if ( pEntryList->IsEntryPosSelected( nChanged ) )
		{
			// Sollte mal ein ImplPaintEntry werden...
			if ( nChanged < pEntryList->GetMRUCount() )
				nChanged = pEntryList->FindEntry( pEntryList->GetEntryText( nChanged ) );
			mpImplWin->SetItemPos( nChanged );
			mpImplWin->SetString( mpImplLB->GetEntryList()->GetEntryText( nChanged ) );
			if( mpImplLB->GetEntryList()->HasImages() )
			{
				Image aImage = mpImplLB->GetEntryList()->GetEntryImage( nChanged );
				mpImplWin->SetImage( aImage );
			}
		}
		else
		{
			mpImplWin->SetItemPos( LISTBOX_ENTRY_NOTFOUND );
			mpImplWin->SetString( ImplGetSVEmptyStr() );
			Image aImage;
			mpImplWin->SetImage( aImage );
		}
		mpImplWin->Invalidate();
	}
	return 1;
}

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

IMPL_LINK( ListBox, ImplDoubleClickHdl, void*, EMPTYARG )
{
	DoubleClick();
	return 1;
}

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

IMPL_LINK( ListBox, ImplClickBtnHdl, void*, EMPTYARG )
{
	if( !mpFloatWin->IsInPopupMode() )
	{
        ImplCallEventListeners( VCLEVENT_DROPDOWN_PRE_OPEN );
		mpImplWin->GrabFocus();
		mpBtn->SetPressed( sal_True );
		mpFloatWin->StartFloat( sal_True );
        ImplCallEventListeners( VCLEVENT_DROPDOWN_OPEN );

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

	return 0;
}

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

IMPL_LINK( ListBox, ImplPopupModeEndHdl, void*, EMPTYARG )
{
    if( mpFloatWin->IsPopupModeCanceled() )
    {
        if ( ( mpFloatWin->GetPopupModeStartSaveSelection() != LISTBOX_ENTRY_NOTFOUND )
                && !IsEntryPosSelected( mpFloatWin->GetPopupModeStartSaveSelection() ) )
        {
            mpImplLB->SelectEntry( mpFloatWin->GetPopupModeStartSaveSelection(), sal_True );
            sal_Bool bTravelSelect = mpImplLB->IsTravelSelect();
            mpImplLB->SetTravelSelect( sal_True );

            ImplDelData aCheckDelete;
            ImplAddDel( &aCheckDelete );
            Select();
            if ( aCheckDelete.IsDelete() )
                return 0;
            ImplRemoveDel( &aCheckDelete );

            mpImplLB->SetTravelSelect( bTravelSelect );
        }
    }

    ImplClearLayoutData();
    if( mpImplLB )
        mpImplLB->GetMainWindow()->ImplClearLayoutData();
    if( mpImplWin )
        mpImplWin->ImplClearLayoutData();

    mpBtn->SetPressed( sal_False );
    ImplCallEventListeners( VCLEVENT_DROPDOWN_CLOSE );
	return 0;
}

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

void ListBox::ToggleDropDown()
{
    if( IsDropDownBox() )
    {
        if( mpFloatWin->IsInPopupMode() )
            mpFloatWin->EndPopupMode();
        else
        {
            ImplCallEventListeners( VCLEVENT_DROPDOWN_PRE_OPEN );
            mpImplWin->GrabFocus();
            mpBtn->SetPressed( sal_True );
            mpFloatWin->StartFloat( sal_True );
            ImplCallEventListeners( VCLEVENT_DROPDOWN_OPEN );
        }
    }
}

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

void ListBox::Draw( OutputDevice* pDev, const Point& rPos, const Size& rSize, sal_uLong nFlags )
{
	mpImplLB->GetMainWindow()->ImplInitSettings( sal_True, sal_True, sal_True );

	Point aPos = pDev->LogicToPixel( rPos );
	Size aSize = pDev->LogicToPixel( rSize );
	Font aFont = mpImplLB->GetMainWindow()->GetDrawPixelFont( pDev );
	OutDevType eOutDevType = pDev->GetOutDevType();

	pDev->Push();
	pDev->SetMapMode();
	pDev->SetFont( aFont );
	pDev->SetTextFillColor();

	// Border/Background
	pDev->SetLineColor();
	pDev->SetFillColor();
	sal_Bool bBorder = !(nFlags & WINDOW_DRAW_NOBORDER ) && (GetStyle() & WB_BORDER);
	sal_Bool bBackground = !(nFlags & WINDOW_DRAW_NOBACKGROUND) && IsControlBackground();
	if ( bBorder || bBackground )
	{
		Rectangle aRect( aPos, aSize );
		if ( bBorder )
		{
            ImplDrawFrame( pDev, aRect );
		}
		if ( bBackground )
		{
			pDev->SetFillColor( GetControlBackground() );
			pDev->DrawRect( aRect );
		}
	}

	// Inhalt
	if ( ( nFlags & WINDOW_DRAW_MONO ) || ( eOutDevType == OUTDEV_PRINTER ) )
	{
		pDev->SetTextColor( Color( COL_BLACK ) );
	}
	else
	{
		if ( !(nFlags & WINDOW_DRAW_NODISABLE ) && !IsEnabled() )
		{
			const StyleSettings& rStyleSettings = GetSettings().GetStyleSettings();
			pDev->SetTextColor( rStyleSettings.GetDisableColor() );
		}
		else
		{
			pDev->SetTextColor( GetTextColor() );
		}
	}

	long        nOnePixel = GetDrawPixel( pDev, 1 );
    sal_uInt16      nTextStyle = TEXT_DRAW_VCENTER;
    Rectangle   aTextRect( aPos, aSize );

    if ( GetStyle() & WB_CENTER )
        nTextStyle |= TEXT_DRAW_CENTER;
    else if ( GetStyle() & WB_RIGHT )
        nTextStyle |= TEXT_DRAW_RIGHT;
    else
        nTextStyle |= TEXT_DRAW_LEFT;

    aTextRect.Left() += 3*nOnePixel;
    aTextRect.Right() -= 3*nOnePixel;

    if ( IsDropDownBox() )
	{
		XubString	aText = GetSelectEntry();
		long		nTextHeight = pDev->GetTextHeight();
		long		nTextWidth = pDev->GetTextWidth( aText );
		long		nOffX = 3*nOnePixel;
		long		nOffY = (aSize.Height()-nTextHeight) / 2;

		// Clipping?
		if ( (nOffY < 0) ||
			 ((nOffY+nTextHeight) > aSize.Height()) ||
			 ((nOffX+nTextWidth) > aSize.Width()) )
		{
			Rectangle aClip( aPos, aSize );
			if ( nTextHeight > aSize.Height() )
				aClip.Bottom() += nTextHeight-aSize.Height()+1;  // Damit HP-Drucker nicht 'weg-optimieren'
			pDev->IntersectClipRegion( aClip );
		}

		pDev->DrawText( aTextRect, aText, nTextStyle );
	}
	else
	{
		long		nTextHeight = pDev->GetTextHeight();
		sal_uInt16		nLines = (sal_uInt16)(aSize.Height() / nTextHeight);
		Rectangle	aClip( aPos, aSize );

        pDev->IntersectClipRegion( aClip );

        if ( !nLines )
			nLines = 1;

        for ( sal_uInt16 n = 0; n < nLines; n++ )
		{
			sal_uInt16 nEntry = n+mpImplLB->GetTopEntry();
			sal_Bool bSelected = mpImplLB->GetEntryList()->IsEntryPosSelected( nEntry );
			if ( bSelected )
			{
				pDev->SetFillColor( COL_BLACK );
				pDev->DrawRect( Rectangle(	Point( aPos.X(), aPos.Y() + n*nTextHeight ),
											Point( aPos.X() + aSize.Width(), aPos.Y() + (n+1)*nTextHeight + 2*nOnePixel ) ) );
				pDev->SetFillColor();
				pDev->SetTextColor( COL_WHITE );
			}

            aTextRect.Top() = aPos.Y() + n*nTextHeight;
            aTextRect.Bottom() = aTextRect.Top() + nTextHeight;

            pDev->DrawText( aTextRect, mpImplLB->GetEntryList()->GetEntryText( nEntry ), nTextStyle );

            if ( bSelected )
				pDev->SetTextColor( COL_BLACK );
		}
	}

	pDev->Pop();
}

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

void ListBox::GetFocus()
{
	if ( mpImplLB )
	{
		if( IsDropDownBox() )
			mpImplWin->GrabFocus();
		else
			mpImplLB->GrabFocus();
	}

	Control::GetFocus();
}

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

Window* ListBox::GetPreferredKeyInputWindow()
{
	if ( mpImplLB )
	{
		if( IsDropDownBox() )
			return mpImplWin->GetPreferredKeyInputWindow();
		else
			return mpImplLB->GetPreferredKeyInputWindow();
	}

	return Control::GetPreferredKeyInputWindow();
}

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

void ListBox::LoseFocus()
{
	if( IsDropDownBox() )
		mpImplWin->HideFocus();
	else
		mpImplLB->HideFocus();

	Control::LoseFocus();
}

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

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

	if ( (rDCEvt.GetType() == DATACHANGED_FONTS) ||
		 (rDCEvt.GetType() == DATACHANGED_FONTSUBSTITUTION) ||
		 ((rDCEvt.GetType() == DATACHANGED_SETTINGS) &&
		  (rDCEvt.GetFlags() & SETTINGS_STYLE)) )
	{
        SetBackground();    // due to a hack in Window::UpdateSettings the background must be reset
                            // otherwise it will overpaint NWF drawn listboxes
		Resize();
		mpImplLB->Resize(); // Wird nicht durch ListBox::Resize() gerufen, wenn sich die ImplLB nicht aendert.

		if ( mpImplWin )
		{
			mpImplWin->SetSettings( GetSettings() );	// Falls noch nicht eingestellt...
			ImplInitFieldSettings( mpImplWin, sal_True, sal_True, sal_True );

			mpBtn->SetSettings( GetSettings() );
			ImplInitDropDownButton( mpBtn );
		}


		if ( IsDropDownBox() )
			Invalidate();
	}
}

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

void ListBox::EnableAutoSize( sal_Bool bAuto )
{
	mbDDAutoSize = bAuto;
	if ( mpFloatWin )
	{
		if ( bAuto && !mpFloatWin->GetDropDownLineCount() )
			mpFloatWin->SetDropDownLineCount( 5 );
		else if ( !bAuto )
			mpFloatWin->SetDropDownLineCount( 0 );
	}
}

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

void ListBox::EnableDDAutoWidth( sal_Bool b )
{
    if ( mpFloatWin )
        mpFloatWin->SetAutoWidth( b );
}

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

sal_Bool ListBox::IsDDAutoWidthEnabled() const
{
    return mpFloatWin ? mpFloatWin->IsAutoWidth() : sal_False;
}

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

void ListBox::SetDropDownLineCount( sal_uInt16 nLines )
{
    mnLineCount = nLines;
	if ( mpFloatWin )
		mpFloatWin->SetDropDownLineCount( mnLineCount );
}

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

sal_uInt16 ListBox::GetDropDownLineCount() const
{
    if ( mpFloatWin )
        return mpFloatWin->GetDropDownLineCount();
	return mnLineCount;
}

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

void ListBox::SetPosSizePixel( long nX, long nY, long nWidth, long nHeight, sal_uInt16 nFlags )
{
	if( IsDropDownBox() && ( nFlags & WINDOW_POSSIZE_SIZE ) )
	{
		Size aPrefSz = mpFloatWin->GetPrefSize();
		if ( ( nFlags & WINDOW_POSSIZE_HEIGHT ) && ( nHeight >= 2*mnDDHeight ) )
			aPrefSz.Height() = nHeight-mnDDHeight;
		if ( nFlags & WINDOW_POSSIZE_WIDTH )
			aPrefSz.Width() = nWidth;
		mpFloatWin->SetPrefSize( aPrefSz );

		if ( IsAutoSizeEnabled() && ! (nFlags & WINDOW_POSSIZE_DROPDOWN) )
			nHeight = mnDDHeight;
	}

	Control::SetPosSizePixel( nX, nY, nWidth, nHeight, nFlags );
}

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

void ListBox::Resize()
{
	Size aOutSz = GetOutputSizePixel();
	if( IsDropDownBox() )
	{
		// initialize the dropdown button size with the standard scrollbar width
		long nSBWidth = GetSettings().GetStyleSettings().GetScrollBarSize();
		long	nTop = 0;
		long	nBottom = aOutSz.Height();

        // note: in case of no border, pBorder will actually be this
		Window *pBorder = GetWindow( WINDOW_BORDER );
		ImplControlValue aControlValue;
		Point aPoint;
		Rectangle aContent, aBound;

		// use the full extent of the control
		Rectangle aArea( aPoint, pBorder->GetOutputSizePixel() );

		if ( GetNativeControlRegion( CTRL_LISTBOX, PART_BUTTON_DOWN,
					aArea, 0, aControlValue, rtl::OUString(), aBound, aContent) )
		{
			// convert back from border space to local coordinates
			aPoint = pBorder->ScreenToOutputPixel( OutputToScreenPixel( aPoint ) );
			aContent.Move( -aPoint.X(), -aPoint.Y() );

			// use the themes drop down size for the button
			aOutSz.Width() = aContent.Left();
			mpBtn->SetPosSizePixel( aContent.Left(), nTop, aContent.Right(), (nBottom-nTop) );

			// adjust the size of the edit field
			if ( GetNativeControlRegion( CTRL_LISTBOX, PART_SUB_EDIT,
						aArea, 0, aControlValue, rtl::OUString(), aBound, aContent) )
			{
				// convert back from border space to local coordinates
				aContent.Move( -aPoint.X(), -aPoint.Y() );

				// use the themes drop down size
                if( ! (GetStyle() & WB_BORDER) && ImplGetSVData()->maNWFData.mbNoFocusRects )
                {
                    // no border but focus ring behavior -> we have a problem; the
                    // native rect relies on the border to draw the focus
                    // let's do the best we can and center vertically, so it doesn't look
                    // completely wrong.
                    Size aSz( GetOutputSizePixel() );
                    long nDiff = aContent.Top() - (aSz.Height() - aContent.GetHeight())/2;
                    aContent.Top() -= nDiff;
                    aContent.Bottom() -= nDiff;
                }
                mpImplWin->SetPosSizePixel( aContent.TopLeft(), aContent.GetSize() );
			}
			else
				mpImplWin->SetSizePixel( aOutSz );
		}
		else
		{
			nSBWidth = CalcZoom( nSBWidth );
			mpImplWin->SetPosSizePixel( 0, 0, aOutSz.Width() - nSBWidth, aOutSz.Height() );
			mpBtn->SetPosSizePixel( aOutSz.Width() - nSBWidth, 0, nSBWidth, aOutSz.Height() );
		}
	}
	else
	{
		mpImplLB->SetSizePixel( aOutSz );
	}

	// FloatingWindow-Groesse auch im unsichtbare Zustand auf Stand halten,
	// weil KEY_PGUP/DOWN ausgewertet wird...
	if ( mpFloatWin )
		mpFloatWin->SetSizePixel( mpFloatWin->CalcFloatSize() );

    Control::Resize();
}

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

void ListBox::FillLayoutData() const
{
    mpControlData->mpLayoutData = new vcl::ControlLayoutData();
    const Control* pMainWin = mpImplLB->GetMainWindow();
    if( mpFloatWin )
    {
        // dropdown mode
        AppendLayoutData( *mpImplWin );
        mpImplWin->SetLayoutDataParent( this );
        if( mpFloatWin->IsReallyVisible() )
        {
            AppendLayoutData( *pMainWin );
            pMainWin->SetLayoutDataParent( this );
        }
    }
    else
    {
        AppendLayoutData( *pMainWin );
        pMainWin->SetLayoutDataParent( this );
    }
}

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

long ListBox::GetIndexForPoint( const Point& rPoint, sal_uInt16& rPos ) const
{
    if( !HasLayoutData() )
        FillLayoutData();

    // check whether rPoint fits at all
    long nIndex = Control::GetIndexForPoint( rPoint );
    if( nIndex != -1 )
    {
        // point must be either in main list window
        // or in impl window (dropdown case)
        ImplListBoxWindow* pMain = mpImplLB->GetMainWindow();
    
        // convert coordinates to ImplListBoxWindow pixel coordinate space
        Point aConvPoint = LogicToPixel( rPoint );
        aConvPoint = OutputToAbsoluteScreenPixel( aConvPoint );
        aConvPoint = pMain->AbsoluteScreenToOutputPixel( aConvPoint );
        aConvPoint = pMain->PixelToLogic( aConvPoint );

        // try to find entry
        sal_uInt16 nEntry = pMain->GetEntryPosForPoint( aConvPoint );
        if( nEntry == LISTBOX_ENTRY_NOTFOUND )
        {
            // not found, maybe dropdown case
            if( mpImplWin && mpImplWin->IsReallyVisible() )
            {
                // convert to impl window pixel coordinates
                aConvPoint = LogicToPixel( rPoint );
                aConvPoint = OutputToAbsoluteScreenPixel( aConvPoint );
                aConvPoint = mpImplWin->AbsoluteScreenToOutputPixel( aConvPoint );

                // check whether converted point is inside impl window
                Size aImplWinSize = mpImplWin->GetOutputSizePixel();
                if( aConvPoint.X() >= 0 && aConvPoint.Y() >= 0 && aConvPoint.X() < aImplWinSize.Width() && aConvPoint.Y() < aImplWinSize.Height() )
                {
                    // inside the impl window, the position is the current item pos
                    rPos = mpImplWin->GetItemPos();
                }
                else
                    nIndex = -1;
            }
            else
                nIndex = -1;
        }
        else
            rPos = nEntry;

        DBG_ASSERT( nIndex != -1, "found index for point, but relative index failed" );
    }

    // get line relative index
    if( nIndex != -1 )
        nIndex = ToRelativeLineIndex( nIndex );

    return nIndex;
}

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

void ListBox::StateChanged( StateChangedType nType )
{
	if( nType == STATE_CHANGE_READONLY )
	{
		if( mpImplWin )
			mpImplWin->Enable( !IsReadOnly() );
		if( mpBtn )
			mpBtn->Enable( !IsReadOnly() );
	}
	else if( nType == STATE_CHANGE_ENABLE )
	{
		mpImplLB->Enable( IsEnabled() );
		if( mpImplWin )
		{
			mpImplWin->Enable( IsEnabled() );
			if ( IsNativeControlSupported(CTRL_LISTBOX, PART_ENTIRE_CONTROL)
					&& ! IsNativeControlSupported(CTRL_LISTBOX, PART_BUTTON_DOWN) )
			{
				GetWindow( WINDOW_BORDER )->Invalidate( INVALIDATE_NOERASE );
			}
			else
				mpImplWin->Invalidate();
		}
		if( mpBtn )
			mpBtn->Enable( IsEnabled() );
	}
	else if( nType == STATE_CHANGE_UPDATEMODE )
	{
		mpImplLB->SetUpdateMode( IsUpdateMode() );
	}
	else if ( nType == STATE_CHANGE_ZOOM )
	{
		mpImplLB->SetZoom( GetZoom() );
		if ( mpImplWin )
		{
			mpImplWin->SetZoom( GetZoom() );
			mpImplWin->SetFont( mpImplLB->GetMainWindow()->GetFont() );
			mpImplWin->Invalidate();
		}
		Resize();
	}
	else if ( nType == STATE_CHANGE_CONTROLFONT )
	{
		mpImplLB->SetControlFont( GetControlFont() );
		if ( mpImplWin )
		{
			mpImplWin->SetControlFont( GetControlFont() );
			mpImplWin->SetFont( mpImplLB->GetMainWindow()->GetFont() );
			mpImplWin->Invalidate();
		}
		Resize();
	}
	else if ( nType == STATE_CHANGE_CONTROLFOREGROUND )
	{
		mpImplLB->SetControlForeground( GetControlForeground() );
		if ( mpImplWin )
		{
			mpImplWin->SetControlForeground( GetControlForeground() );
			mpImplWin->SetTextColor( GetControlForeground() );
			mpImplWin->SetFont( mpImplLB->GetMainWindow()->GetFont() );
			mpImplWin->Invalidate();
		}
	}
	else if ( nType == STATE_CHANGE_CONTROLBACKGROUND )
	{
		mpImplLB->SetControlBackground( GetControlBackground() );
		if ( mpImplWin )
		{
			if ( mpImplWin->IsNativeControlSupported(CTRL_LISTBOX, PART_ENTIRE_CONTROL) )
			{
				// Transparent background
				mpImplWin->SetBackground();
				mpImplWin->SetControlBackground();
			}
			else
			{
				mpImplWin->SetBackground( mpImplLB->GetMainWindow()->GetControlBackground() );
				mpImplWin->SetControlBackground( mpImplLB->GetMainWindow()->GetControlBackground() );
			}
			mpImplWin->SetFont( mpImplLB->GetMainWindow()->GetFont() );
			mpImplWin->Invalidate();
		}
	}
	else if ( nType == STATE_CHANGE_STYLE )
	{
		SetStyle( ImplInitStyle( GetStyle() ) );
		mpImplLB->GetMainWindow()->EnableSort( ( GetStyle() & WB_SORT ) ? sal_True : sal_False );
	    sal_Bool bSimpleMode = ( GetStyle() & WB_SIMPLEMODE ) ? sal_True : sal_False;
	    mpImplLB->SetMultiSelectionSimpleMode( bSimpleMode );
	}
    else if( nType == STATE_CHANGE_MIRRORING )
    {
        if( mpBtn )
        {
            mpBtn->EnableRTL( IsRTLEnabled() );
            ImplInitDropDownButton( mpBtn );
        }
        mpImplLB->EnableRTL( IsRTLEnabled() );
        if( mpImplWin )
            mpImplWin->EnableRTL( IsRTLEnabled() );
        Resize();
    }

	Control::StateChanged( nType );
}

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

long ListBox::PreNotify( NotifyEvent& rNEvt )
{
	long nDone = 0;
	if ( mpImplLB )
	{
		if( ( rNEvt.GetType() == EVENT_KEYINPUT ) && ( rNEvt.GetWindow() == mpImplWin ) )
		{
			KeyEvent aKeyEvt = *rNEvt.GetKeyEvent();
			switch( aKeyEvt.GetKeyCode().GetCode() )
			{
				case KEY_DOWN:
				{
					if( mpFloatWin && !mpFloatWin->IsInPopupMode() &&
						aKeyEvt.GetKeyCode().IsMod2() )
					{
                        ImplCallEventListeners( VCLEVENT_DROPDOWN_PRE_OPEN );
						mpBtn->SetPressed( sal_True );
						mpFloatWin->StartFloat( sal_False );
                        ImplCallEventListeners( VCLEVENT_DROPDOWN_OPEN );
						nDone = 1;
					}
					else
					{
						nDone = mpImplLB->ProcessKeyInput( aKeyEvt );
					}
				}
				break;
				case KEY_UP:
				{
					if( mpFloatWin && mpFloatWin->IsInPopupMode() &&
						aKeyEvt.GetKeyCode().IsMod2() )
					{
						mpFloatWin->EndPopupMode();
						nDone = 1;
					}
					else
					{
						nDone = mpImplLB->ProcessKeyInput( aKeyEvt );
					}
				}
				break;
				case KEY_RETURN:
				{
					if( IsInDropDown() )
					{
						mpImplLB->ProcessKeyInput( aKeyEvt );
						nDone = 1;
					}
				}
				break;

				default:
                {
					nDone = mpImplLB->ProcessKeyInput( aKeyEvt );
                }
			}
		}
		else if ( rNEvt.GetType() == EVENT_LOSEFOCUS )
		{
			if ( IsInDropDown() && !HasChildPathFocus( sal_True ) )
				mpFloatWin->EndPopupMode();
		}
		else if ( (rNEvt.GetType() == EVENT_COMMAND) &&
				  (rNEvt.GetCommandEvent()->GetCommand() == COMMAND_WHEEL) &&
				  (rNEvt.GetWindow() == mpImplWin) )
		{
            sal_uInt16 nWheelBehavior( GetSettings().GetMouseSettings().GetWheelBehavior() );
            if  (   ( nWheelBehavior == MOUSE_WHEEL_ALWAYS )
                ||  (   ( nWheelBehavior == MOUSE_WHEEL_FOCUS_ONLY )
                    &&  HasChildPathFocus()
                    )
                )
            {
                nDone = mpImplLB->HandleWheelAsCursorTravel( *rNEvt.GetCommandEvent() );
            }
            else
            {
                nDone = 0;  // don't eat this event, let the default handling happen (i.e. scroll the context)
            }
		}
	}

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

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

void ListBox::Select()
{
    ImplCallEventListenersAndHandler( VCLEVENT_LISTBOX_SELECT, maSelectHdl, this );
}

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

void ListBox::DoubleClick()
{
    ImplCallEventListenersAndHandler( VCLEVENT_LISTBOX_DOUBLECLICK, maDoubleClickHdl, this );
}

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

void ListBox::Clear()
{
	mpImplLB->Clear();
	if( IsDropDownBox() )
	{
		mpImplWin->SetItemPos( LISTBOX_ENTRY_NOTFOUND );
		mpImplWin->SetString( ImplGetSVEmptyStr() );
		Image aImage;
		mpImplWin->SetImage( aImage );
		mpImplWin->Invalidate();
	}
    CallEventListeners( VCLEVENT_LISTBOX_ITEMREMOVED, (void*) sal_IntPtr(-1) );
}

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

void ListBox::SetNoSelection()
{
	mpImplLB->SetNoSelection();
	if( IsDropDownBox() )
	{
		mpImplWin->SetItemPos( LISTBOX_ENTRY_NOTFOUND );
		mpImplWin->SetString( ImplGetSVEmptyStr() );
		Image aImage;
		mpImplWin->SetImage( aImage );
		mpImplWin->Invalidate();
	}
}

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

sal_uInt16 ListBox::InsertEntry( const XubString& rStr, sal_uInt16 nPos )
{
	sal_uInt16 nRealPos = mpImplLB->InsertEntry( nPos + mpImplLB->GetEntryList()->GetMRUCount(), rStr );
	nRealPos = sal::static_int_cast<sal_uInt16>(nRealPos - mpImplLB->GetEntryList()->GetMRUCount());
    CallEventListeners( VCLEVENT_LISTBOX_ITEMADDED, (void*) sal_IntPtr(nRealPos) );
	return nRealPos;
}

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

sal_uInt16 ListBox::InsertEntry( const Image& rImage, sal_uInt16 nPos )
{
	sal_uInt16 nRealPos = mpImplLB->InsertEntry( nPos + mpImplLB->GetEntryList()->GetMRUCount(), rImage );
	nRealPos = sal::static_int_cast<sal_uInt16>(nRealPos - mpImplLB->GetEntryList()->GetMRUCount());
    CallEventListeners( VCLEVENT_LISTBOX_ITEMADDED, (void*) sal_IntPtr(nRealPos) );
	return nRealPos;
}

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

sal_uInt16 ListBox::InsertEntry( const XubString& rStr, const Image& rImage, sal_uInt16 nPos )
{
	sal_uInt16 nRealPos = mpImplLB->InsertEntry( nPos + mpImplLB->GetEntryList()->GetMRUCount(), rStr, rImage );
	nRealPos = sal::static_int_cast<sal_uInt16>(nRealPos - mpImplLB->GetEntryList()->GetMRUCount());
    CallEventListeners( VCLEVENT_LISTBOX_ITEMADDED, (void*) sal_IntPtr(nRealPos) );
	return nRealPos;
}

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

void ListBox::RemoveEntry( const XubString& rStr )
{
	RemoveEntry( GetEntryPos( rStr ) );
}

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

void ListBox::RemoveEntry( sal_uInt16 nPos )
{
	mpImplLB->RemoveEntry( nPos + mpImplLB->GetEntryList()->GetMRUCount() );
    CallEventListeners( VCLEVENT_LISTBOX_ITEMREMOVED, (void*) sal_IntPtr(nPos) );
}

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

Image ListBox::GetEntryImage( sal_uInt16 nPos ) const
{
    if ( mpImplLB->GetEntryList()->HasEntryImage( nPos ) )
        return mpImplLB->GetEntryList()->GetEntryImage( nPos );
    return Image();
}

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

sal_uInt16 ListBox::GetEntryPos( const XubString& rStr ) const
{
	sal_uInt16 nPos = mpImplLB->GetEntryList()->FindEntry( rStr );
	if ( nPos != LISTBOX_ENTRY_NOTFOUND )
		nPos = sal::static_int_cast<sal_uInt16>(nPos - mpImplLB->GetEntryList()->GetMRUCount());
	return nPos;
}

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

sal_uInt16 ListBox::GetEntryPos( const void* pData ) const
{
	sal_uInt16 nPos = mpImplLB->GetEntryList()->FindEntry( pData );
	if ( nPos != LISTBOX_ENTRY_NOTFOUND )
		nPos = sal::static_int_cast<sal_uInt16>(nPos - mpImplLB->GetEntryList()->GetMRUCount());
	return nPos;
}

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

XubString ListBox::GetEntry( sal_uInt16 nPos ) const
{
	return mpImplLB->GetEntryList()->GetEntryText( nPos + mpImplLB->GetEntryList()->GetMRUCount() );
}

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

sal_uInt16 ListBox::GetEntryCount() const
{
	return mpImplLB->GetEntryList()->GetEntryCount() - mpImplLB->GetEntryList()->GetMRUCount();
}

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

XubString ListBox::GetSelectEntry( sal_uInt16 nIndex ) const
{
	return GetEntry( GetSelectEntryPos( nIndex ) );
}

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

sal_uInt16 ListBox::GetSelectEntryCount() const
{
	return mpImplLB->GetEntryList()->GetSelectEntryCount();
}

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

sal_uInt16 ListBox::GetSelectEntryPos( sal_uInt16 nIndex ) const
{
	sal_uInt16 nPos = mpImplLB->GetEntryList()->GetSelectEntryPos( nIndex );
	if ( nPos != LISTBOX_ENTRY_NOTFOUND )
	{
		if ( nPos < mpImplLB->GetEntryList()->GetMRUCount() )
			nPos = mpImplLB->GetEntryList()->FindEntry( mpImplLB->GetEntryList()->GetEntryText( nPos ) );
		nPos = sal::static_int_cast<sal_uInt16>(nPos - mpImplLB->GetEntryList()->GetMRUCount());
	}
	return nPos;
}

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

sal_Bool ListBox::IsEntrySelected( const XubString& rStr ) const
{
	return IsEntryPosSelected( GetEntryPos( rStr ) );
}

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

sal_Bool ListBox::IsEntryPosSelected( sal_uInt16 nPos ) const
{
	return mpImplLB->GetEntryList()->IsEntryPosSelected( nPos + mpImplLB->GetEntryList()->GetMRUCount() );
}

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

void ListBox::SelectEntry( const XubString& rStr, sal_Bool bSelect )
{
	SelectEntryPos( GetEntryPos( rStr ), bSelect );
}

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

void ListBox::SelectEntryPos( sal_uInt16 nPos, sal_Bool bSelect )
{
	if ( nPos < mpImplLB->GetEntryList()->GetEntryCount() )
		mpImplLB->SelectEntry( nPos + mpImplLB->GetEntryList()->GetMRUCount(), bSelect );
}

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

void ListBox::SetEntryData( sal_uInt16 nPos, void* pNewData )
{
	mpImplLB->SetEntryData( nPos + mpImplLB->GetEntryList()->GetMRUCount(), pNewData );
}

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

void* ListBox::GetEntryData( sal_uInt16 nPos ) const
{
	return mpImplLB->GetEntryList()->GetEntryData( nPos + mpImplLB->GetEntryList()->GetMRUCount() );
}

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

void ListBox::SetEntryFlags( sal_uInt16 nPos, long nFlags )
{
	mpImplLB->SetEntryFlags( nPos + mpImplLB->GetEntryList()->GetMRUCount(), nFlags );
}

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

long ListBox::GetEntryFlags( sal_uInt16 nPos ) const
{
	return mpImplLB->GetEntryList()->GetEntryFlags( nPos + mpImplLB->GetEntryList()->GetMRUCount() );
}

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

void ListBox::SetTopEntry( sal_uInt16 nPos )
{
	mpImplLB->SetTopEntry( nPos + mpImplLB->GetEntryList()->GetMRUCount() );
}

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

void ListBox::ShowProminentEntry( sal_uInt16 nPos )
{
	mpImplLB->ShowProminentEntry( nPos + mpImplLB->GetEntryList()->GetMRUCount() );
}

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

sal_uInt16 ListBox::GetTopEntry() const
{
	sal_uInt16 nPos = GetEntryCount() ? mpImplLB->GetTopEntry() : LISTBOX_ENTRY_NOTFOUND;
	if ( nPos < mpImplLB->GetEntryList()->GetMRUCount() )
		nPos = 0;
	return nPos;
}

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

void ListBox::SetProminentEntryType( ProminentEntry eType )
{
    mpImplLB->SetProminentEntryType( eType );
}

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

ProminentEntry ListBox::GetProminentEntryType() const
{
    return mpImplLB->GetProminentEntryType();
}

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

sal_Bool ListBox::IsTravelSelect() const
{
	return mpImplLB->IsTravelSelect();
}

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

sal_Bool ListBox::IsInDropDown() const
{
	return mpFloatWin && mpFloatWin->IsInPopupMode();
}

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

long ListBox::CalcWindowSizePixel( sal_uInt16 nLines ) const
{
	return mpImplLB->GetEntryHeight() * nLines;
}

Rectangle ListBox::GetBoundingRectangle( sal_uInt16 nItem ) const
{
    Rectangle aRect = mpImplLB->GetMainWindow()->GetBoundingRectangle( nItem );
    Rectangle aOffset = mpImplLB->GetMainWindow()->GetWindowExtentsRelative( (Window*)this );
    aRect.Move( aOffset.TopLeft().X(), aOffset.TopLeft().Y() );
    return aRect;
}

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

void ListBox::EnableMultiSelection( sal_Bool bMulti )
{
	EnableMultiSelection( bMulti, sal_False );
}

void ListBox::EnableMultiSelection( sal_Bool bMulti, sal_Bool bStackSelection )
{
	mpImplLB->EnableMultiSelection( bMulti, bStackSelection );

	// WB_SIMPLEMODE:
	// Die MultiListBox verh�lt sich wie eine normale ListBox.
	// Die Mehrfachselektion kann nur �ber entsprechende Zusatztasten erfolgen.

	sal_Bool bSimpleMode = ( GetStyle() & WB_SIMPLEMODE ) ? sal_True : sal_False;
	mpImplLB->SetMultiSelectionSimpleMode( bSimpleMode );

	// ohne Focus ist das Traveln in einer MultiSelection nicht zu sehen:
	if ( mpFloatWin )
		mpImplLB->GetMainWindow()->AllowGrabFocus( bMulti );
}

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

sal_Bool ListBox::IsMultiSelectionEnabled() const
{
	return mpImplLB->IsMultiSelectionEnabled();
}

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

Size ListBox::CalcMinimumSize() const
{
	Size aSz;
	if ( !IsDropDownBox() )
        aSz = mpImplLB->CalcSize (mnLineCount ? mnLineCount : mpImplLB->GetEntryList()->GetEntryCount());
	else
	{
		aSz.Height() = mpImplLB->CalcSize( 1 ).Height();
		aSz.Height() += 4; // add a space between entry and border
        // size to maxmimum entry width and add a little breathing space
		aSz.Width() = mpImplLB->GetMaxEntryWidth() + 4;
        // do not create ultrathin ListBoxes, it doesn't look good
        if( aSz.Width() < GetSettings().GetStyleSettings().GetScrollBarSize() )
            aSz.Width() = GetSettings().GetStyleSettings().GetScrollBarSize();

        // try native borders; scrollbar size may not be a good indicator
        // see how large the edit area inside is to estimate what is needed for the dropdown
		ImplControlValue aControlValue;
		Point aPoint;
		Rectangle aContent, aBound;
        Size aTestSize( 100, 20 );
		Rectangle aArea( aPoint, aTestSize );
        if( const_cast<ListBox*>(this)->GetNativeControlRegion(
                       CTRL_LISTBOX, PART_SUB_EDIT, aArea, 0, aControlValue, rtl::OUString(), aBound, aContent) )
        {
            // use the themes drop down size
            aSz.Width() += aTestSize.Width() - aContent.GetWidth();
        }
        else
            aSz.Width() += GetSettings().GetStyleSettings().GetScrollBarSize();
	}

	aSz = CalcWindowSize( aSz );
    
	if ( IsDropDownBox() ) // check minimum height of dropdown box
    {
        ImplControlValue aControlValue;
        Rectangle aRect( Point( 0, 0 ), aSz );
        Rectangle aContent, aBound;
        if( const_cast<ListBox*>(this)->GetNativeControlRegion(
                       CTRL_LISTBOX, PART_ENTIRE_CONTROL, aRect, 0, aControlValue, rtl::OUString(), aBound, aContent) )
        {
            if( aBound.GetHeight() > aSz.Height() )
                aSz.Height() = aBound.GetHeight();
        }
    }
    
	return aSz;
}

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

Size ListBox::GetOptimalSize(WindowSizeType eType) const
{
    switch (eType) {
    case WINDOWSIZE_MINIMUM:
        return CalcMinimumSize();
    default:
        return Control::GetOptimalSize( eType );
    }
}

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

Size ListBox::CalcAdjustedSize( const Size& rPrefSize ) const
{
	Size aSz = rPrefSize;
	sal_Int32 nLeft, nTop, nRight, nBottom;
	((Window*)this)->GetBorder( nLeft, nTop, nRight, nBottom );
	aSz.Height() -= nTop+nBottom;
	if ( !IsDropDownBox() )
	{
		long nEntryHeight = CalcSize( 1, 1 ).Height();
		long nLines = aSz.Height() / nEntryHeight;
		if ( nLines < 1 )
			nLines = 1;
		aSz.Height() = nLines * nEntryHeight;
	}
	else
	{
		aSz.Height() = mnDDHeight;
	}
	aSz.Height() += nTop+nBottom;

	aSz = CalcWindowSize( aSz );
	return aSz;
}

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

Size ListBox::CalcSize( sal_uInt16 nColumns, sal_uInt16 nLines ) const
{
	// ggf. werden ScrollBars eingeblendet
	Size aMinSz = CalcMinimumSize();
//	aMinSz = ImplCalcOutSz( aMinSz );

	Size aSz;

	// Hoehe
	if ( nLines )
	{
		if ( !IsDropDownBox() )
			aSz.Height() = mpImplLB->CalcSize( nLines ).Height();
		else
			aSz.Height() = mnDDHeight;
	}
	else
		aSz.Height() = aMinSz.Height();

	// Breite
	if ( nColumns )
		aSz.Width() = nColumns * GetTextWidth( XubString( 'X' ) );
	else
		aSz.Width() = aMinSz.Width();

	if ( IsDropDownBox() )
		aSz.Width() += GetSettings().GetStyleSettings().GetScrollBarSize();

	if ( !IsDropDownBox() )
	{
		if ( aSz.Width() < aMinSz.Width() )
			aSz.Height() += GetSettings().GetStyleSettings().GetScrollBarSize();
		if ( aSz.Height() < aMinSz.Height() )
			aSz.Width() += GetSettings().GetStyleSettings().GetScrollBarSize();
	}

	aSz = CalcWindowSize( aSz );
	return aSz;
}

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

void ListBox::GetMaxVisColumnsAndLines( sal_uInt16& rnCols, sal_uInt16& rnLines ) const
{
	long nCharWidth = GetTextWidth( UniString( 'x' ) );
	if ( !IsDropDownBox() )
	{
		Size aOutSz = mpImplLB->GetMainWindow()->GetOutputSizePixel();
		rnCols = (sal_uInt16) (aOutSz.Width()/nCharWidth);
		rnLines = (sal_uInt16) (aOutSz.Height()/mpImplLB->GetEntryHeight());
	}
	else
	{
		Size aOutSz = mpImplWin->GetOutputSizePixel();
		rnCols = (sal_uInt16) (aOutSz.Width()/nCharWidth);
		rnLines = 1;
	}
}

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

IMPL_LINK( ListBox, ImplUserDrawHdl, UserDrawEvent*, pEvent )
{
	UserDraw( *pEvent );
	return 1;
}

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

void ListBox::UserDraw( const UserDrawEvent& )
{
}

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

void ListBox::DrawEntry( const UserDrawEvent& rEvt, sal_Bool bDrawImage, sal_Bool bDrawText, sal_Bool bDrawTextAtImagePos )
{
	if ( rEvt.GetDevice() == mpImplLB->GetMainWindow() )
		mpImplLB->GetMainWindow()->DrawEntry( rEvt.GetItemId(), bDrawImage, bDrawText, bDrawTextAtImagePos );
	else if ( rEvt.GetDevice() == mpImplWin )
		mpImplWin->DrawEntry( bDrawImage, bDrawText, bDrawTextAtImagePos );
}

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

void ListBox::SetUserItemSize( const Size& rSz )
{
	mpImplLB->GetMainWindow()->SetUserItemSize( rSz );
	if ( mpImplWin )
		mpImplWin->SetUserItemSize( rSz );
}

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

const Size& ListBox::GetUserItemSize() const
{
	return mpImplLB->GetMainWindow()->GetUserItemSize();
}

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

void ListBox::EnableUserDraw( sal_Bool bUserDraw )
{
	mpImplLB->GetMainWindow()->EnableUserDraw( bUserDraw );
	if ( mpImplWin )
		mpImplWin->EnableUserDraw( bUserDraw );
}

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

sal_Bool ListBox::IsUserDrawEnabled() const
{
	return mpImplLB->GetMainWindow()->IsUserDrawEnabled();
}

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

void ListBox::SetReadOnly( sal_Bool bReadOnly )
{
	if ( mpImplLB->IsReadOnly() != bReadOnly )
	{
		mpImplLB->SetReadOnly( bReadOnly );
		StateChanged( STATE_CHANGE_READONLY );
	}
}

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

sal_Bool ListBox::IsReadOnly() const
{
	return mpImplLB->IsReadOnly();
}

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

void ListBox::SetSeparatorPos( sal_uInt16 n )
{
	mpImplLB->SetSeparatorPos( n );
}

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

void ListBox::SetSeparatorPos()
{
	mpImplLB->SetSeparatorPos( LISTBOX_ENTRY_NOTFOUND );
}

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

sal_uInt16 ListBox::GetSeparatorPos() const
{
	return mpImplLB->GetSeparatorPos();
}

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

void ListBox::SetMRUEntries( const XubString& rEntries, xub_Unicode cSep )
{
	mpImplLB->SetMRUEntries( rEntries, cSep );
}

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

XubString ListBox::GetMRUEntries( xub_Unicode cSep ) const
{
	return mpImplLB->GetMRUEntries( cSep );
}

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

void ListBox::SetMaxMRUCount( sal_uInt16 n )
{
	mpImplLB->SetMaxMRUCount( n );
}

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

sal_uInt16 ListBox::GetMaxMRUCount() const
{
	return mpImplLB->GetMaxMRUCount();
}

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

sal_uInt16 ListBox::GetDisplayLineCount() const
{
    return mpImplLB->GetDisplayLineCount();
}

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

// pb: #106948# explicit mirroring for calc

void ListBox::EnableMirroring()
{
    mpImplLB->EnableMirroring();
}

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

Rectangle ListBox::GetDropDownPosSizePixel() const
{
    return mpFloatWin ? mpFloatWin->GetWindowExtentsRelative( const_cast<ListBox*>(this) ) : Rectangle();
}

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

const Wallpaper& ListBox::GetDisplayBackground() const
{
    // !!! recursion does not occur because the ImplListBox is default
    // initialized to a nontransparent color in Window::ImplInitData
    return mpImplLB->GetDisplayBackground();
}

// =======================================================================
MultiListBox::MultiListBox( Window* pParent, WinBits nStyle ) :
	ListBox( WINDOW_MULTILISTBOX )
{
	ImplInit( pParent, nStyle );
	EnableMultiSelection( sal_True );
}

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

MultiListBox::MultiListBox( Window* pParent, const ResId& rResId ) :
	ListBox( WINDOW_MULTILISTBOX )
{
	rResId.SetRT( RSC_MULTILISTBOX );
	WinBits nStyle = ImplInitRes( rResId );
	ImplInit( pParent, nStyle );
	ImplLoadRes( rResId );

	if ( !(nStyle & WB_HIDE ) )
		Show();
	EnableMultiSelection( sal_True );
}
