| /************************************************************** | 
 |  * | 
 |  * 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 occurred because pNewEntry is | 
 | 			// garbage you wouldn't insert it. If the exception occurred 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 already 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; | 
 | 				sal_Bool bCurPosChange = (mnCurrentPos != nSelect); | 
 | 				//SelectEntries( nSelect, LET_MBDOWN, rMEvt.IsShift(), rMEvt.IsMod1() ); | 
 | 				SelectEntries( nSelect, LET_MBDOWN, rMEvt.IsShift(), rMEvt.IsMod1() ,bCurPosChange); | 
 | 				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; | 
 |                         } | 
 | 						// When list box selection change by mouse move, notity | 
 | 						// VCLEVENT_LISTBOX_SELECT vcl event. | 
 | 						else | 
 | 						{ | 
 | 							maListItemSelectHdl.Call(NULL); | 
 | 						} | 
 | 		            } | 
 | 					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 bSelectPosChange /*=FALSE*/ ) | 
 | { | 
 | 	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(); | 
 | 			if (bSelectPosChange) | 
 | 			{ | 
 | 				maFocusHdl.Call(reinterpret_cast<void*>(nSelect)); | 
 | 			} | 
 | 		} | 
 |         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; | 
 | 		sal_Bool bCurPosChange = (mnCurrentPos != nSelect); | 
 | 		mnCurrentPos = nSelect; | 
 | 		//if ( SelectEntries( nSelect, eLET, bShift, bCtrl ) ) | 
 | 		if(SelectEntries( nSelect, eLET, bShift, bCtrl ,bCurPosChange)) | 
 | 		{ | 
 | 			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() ); | 
 |     long nY = mpEntryList->GetAddedHeight( nItem, GetTopEntry() ) + GetEntryList()->GetMRUCount()*GetEntryHeight(); | 
 |     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(); | 
 | 	} | 
 | } |