xref: /AOO41X/main/vcl/source/control/ilstbox.cxx (revision cdf0e10c4e3984b49a9502b011690b615761d4a3)
1*cdf0e10cSrcweir /*************************************************************************
2*cdf0e10cSrcweir  *
3*cdf0e10cSrcweir  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4*cdf0e10cSrcweir  *
5*cdf0e10cSrcweir  * Copyright 2000, 2010 Oracle and/or its affiliates.
6*cdf0e10cSrcweir  *
7*cdf0e10cSrcweir  * OpenOffice.org - a multi-platform office productivity suite
8*cdf0e10cSrcweir  *
9*cdf0e10cSrcweir  * This file is part of OpenOffice.org.
10*cdf0e10cSrcweir  *
11*cdf0e10cSrcweir  * OpenOffice.org is free software: you can redistribute it and/or modify
12*cdf0e10cSrcweir  * it under the terms of the GNU Lesser General Public License version 3
13*cdf0e10cSrcweir  * only, as published by the Free Software Foundation.
14*cdf0e10cSrcweir  *
15*cdf0e10cSrcweir  * OpenOffice.org is distributed in the hope that it will be useful,
16*cdf0e10cSrcweir  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17*cdf0e10cSrcweir  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18*cdf0e10cSrcweir  * GNU Lesser General Public License version 3 for more details
19*cdf0e10cSrcweir  * (a copy is included in the LICENSE file that accompanied this code).
20*cdf0e10cSrcweir  *
21*cdf0e10cSrcweir  * You should have received a copy of the GNU Lesser General Public License
22*cdf0e10cSrcweir  * version 3 along with OpenOffice.org.  If not, see
23*cdf0e10cSrcweir  * <http://www.openoffice.org/license.html>
24*cdf0e10cSrcweir  * for a copy of the LGPLv3 License.
25*cdf0e10cSrcweir  *
26*cdf0e10cSrcweir  ************************************************************************/
27*cdf0e10cSrcweir 
28*cdf0e10cSrcweir // MARKER(update_precomp.py): autogen include statement, do not remove
29*cdf0e10cSrcweir #include "precompiled_vcl.hxx"
30*cdf0e10cSrcweir 
31*cdf0e10cSrcweir #include <tools/debug.hxx>
32*cdf0e10cSrcweir 
33*cdf0e10cSrcweir #include <vcl/svapp.hxx>
34*cdf0e10cSrcweir #include <vcl/settings.hxx>
35*cdf0e10cSrcweir #include <vcl/event.hxx>
36*cdf0e10cSrcweir #include <vcl/scrbar.hxx>
37*cdf0e10cSrcweir #include <vcl/help.hxx>
38*cdf0e10cSrcweir #include <vcl/lstbox.h>
39*cdf0e10cSrcweir #include <vcl/unohelp.hxx>
40*cdf0e10cSrcweir #include <vcl/i18nhelp.hxx>
41*cdf0e10cSrcweir 
42*cdf0e10cSrcweir #include <ilstbox.hxx>
43*cdf0e10cSrcweir #include <controldata.hxx>
44*cdf0e10cSrcweir #include <svdata.hxx>
45*cdf0e10cSrcweir 
46*cdf0e10cSrcweir #include <com/sun/star/i18n/XCollator.hpp>
47*cdf0e10cSrcweir #include <com/sun/star/accessibility/XAccessible.hpp>
48*cdf0e10cSrcweir #include <com/sun/star/accessibility/AccessibleRole.hpp>
49*cdf0e10cSrcweir 
50*cdf0e10cSrcweir #define MULTILINE_ENTRY_DRAW_FLAGS ( TEXT_DRAW_WORDBREAK | TEXT_DRAW_MULTILINE | TEXT_DRAW_VCENTER )
51*cdf0e10cSrcweir 
52*cdf0e10cSrcweir using namespace ::com::sun::star;
53*cdf0e10cSrcweir 
54*cdf0e10cSrcweir // =======================================================================
55*cdf0e10cSrcweir 
56*cdf0e10cSrcweir void ImplInitFieldSettings( Window* pWin, sal_Bool bFont, sal_Bool bForeground, sal_Bool bBackground )
57*cdf0e10cSrcweir {
58*cdf0e10cSrcweir 	const StyleSettings& rStyleSettings = pWin->GetSettings().GetStyleSettings();
59*cdf0e10cSrcweir 
60*cdf0e10cSrcweir 	if ( bFont )
61*cdf0e10cSrcweir 	{
62*cdf0e10cSrcweir 		Font aFont = rStyleSettings.GetFieldFont();
63*cdf0e10cSrcweir 		if ( pWin->IsControlFont() )
64*cdf0e10cSrcweir 			aFont.Merge( pWin->GetControlFont() );
65*cdf0e10cSrcweir 		pWin->SetZoomedPointFont( aFont );
66*cdf0e10cSrcweir 	}
67*cdf0e10cSrcweir 
68*cdf0e10cSrcweir 	if ( bFont || bForeground )
69*cdf0e10cSrcweir 	{
70*cdf0e10cSrcweir 		Color aTextColor = rStyleSettings.GetFieldTextColor();
71*cdf0e10cSrcweir 		if ( pWin->IsControlForeground() )
72*cdf0e10cSrcweir 			aTextColor = pWin->GetControlForeground();
73*cdf0e10cSrcweir 		pWin->SetTextColor( aTextColor );
74*cdf0e10cSrcweir 	}
75*cdf0e10cSrcweir 
76*cdf0e10cSrcweir 	if ( bBackground )
77*cdf0e10cSrcweir 	{
78*cdf0e10cSrcweir 		if( pWin->IsControlBackground() )
79*cdf0e10cSrcweir 			pWin->SetBackground( pWin->GetControlBackground() );
80*cdf0e10cSrcweir 		else
81*cdf0e10cSrcweir 			pWin->SetBackground( rStyleSettings.GetFieldColor() );
82*cdf0e10cSrcweir 	}
83*cdf0e10cSrcweir }
84*cdf0e10cSrcweir 
85*cdf0e10cSrcweir // -----------------------------------------------------------------------
86*cdf0e10cSrcweir 
87*cdf0e10cSrcweir void ImplInitDropDownButton( PushButton* pButton )
88*cdf0e10cSrcweir {
89*cdf0e10cSrcweir 	if ( pButton->GetSettings().GetStyleSettings().GetOptions() & STYLE_OPTION_SPINUPDOWN )
90*cdf0e10cSrcweir 		pButton->SetSymbol( SYMBOL_SPIN_UPDOWN );
91*cdf0e10cSrcweir 	else
92*cdf0e10cSrcweir 		pButton->SetSymbol( SYMBOL_SPIN_DOWN );
93*cdf0e10cSrcweir 
94*cdf0e10cSrcweir 	if ( pButton->IsNativeControlSupported(CTRL_LISTBOX, PART_ENTIRE_CONTROL)
95*cdf0e10cSrcweir 			&& ! pButton->IsNativeControlSupported(CTRL_LISTBOX, PART_BUTTON_DOWN) )
96*cdf0e10cSrcweir 		pButton->SetBackground();
97*cdf0e10cSrcweir }
98*cdf0e10cSrcweir 
99*cdf0e10cSrcweir // =======================================================================
100*cdf0e10cSrcweir 
101*cdf0e10cSrcweir ImplEntryList::ImplEntryList( Window* pWindow )
102*cdf0e10cSrcweir {
103*cdf0e10cSrcweir     mpWindow = pWindow;
104*cdf0e10cSrcweir 	mnLastSelected = LISTBOX_ENTRY_NOTFOUND;
105*cdf0e10cSrcweir 	mnSelectionAnchor = LISTBOX_ENTRY_NOTFOUND;
106*cdf0e10cSrcweir 	mnImages = 0;
107*cdf0e10cSrcweir 	mbCallSelectionChangedHdl = sal_True;
108*cdf0e10cSrcweir 
109*cdf0e10cSrcweir 	mnMRUCount = 0;
110*cdf0e10cSrcweir 	mnMaxMRUCount = 0;
111*cdf0e10cSrcweir }
112*cdf0e10cSrcweir 
113*cdf0e10cSrcweir // -----------------------------------------------------------------------
114*cdf0e10cSrcweir 
115*cdf0e10cSrcweir ImplEntryList::~ImplEntryList()
116*cdf0e10cSrcweir {
117*cdf0e10cSrcweir 	Clear();
118*cdf0e10cSrcweir }
119*cdf0e10cSrcweir 
120*cdf0e10cSrcweir // -----------------------------------------------------------------------
121*cdf0e10cSrcweir 
122*cdf0e10cSrcweir void ImplEntryList::Clear()
123*cdf0e10cSrcweir {
124*cdf0e10cSrcweir 	mnImages = 0;
125*cdf0e10cSrcweir 	for ( sal_uInt16 n = GetEntryCount(); n; )
126*cdf0e10cSrcweir 	{
127*cdf0e10cSrcweir 		ImplEntryType* pImplEntry = GetEntry( --n );
128*cdf0e10cSrcweir 		delete pImplEntry;
129*cdf0e10cSrcweir 	}
130*cdf0e10cSrcweir 	List::Clear();
131*cdf0e10cSrcweir }
132*cdf0e10cSrcweir 
133*cdf0e10cSrcweir // -----------------------------------------------------------------------
134*cdf0e10cSrcweir 
135*cdf0e10cSrcweir void ImplEntryList::SelectEntry( sal_uInt16 nPos, sal_Bool bSelect )
136*cdf0e10cSrcweir {
137*cdf0e10cSrcweir 	ImplEntryType* pImplEntry = GetEntry( nPos );
138*cdf0e10cSrcweir 	if ( pImplEntry &&
139*cdf0e10cSrcweir 	   ( pImplEntry->mbIsSelected != bSelect ) &&
140*cdf0e10cSrcweir 	   ( (pImplEntry->mnFlags & LISTBOX_ENTRY_FLAG_DISABLE_SELECTION) == 0  ) )
141*cdf0e10cSrcweir 	{
142*cdf0e10cSrcweir 		pImplEntry->mbIsSelected = bSelect;
143*cdf0e10cSrcweir 		if ( mbCallSelectionChangedHdl )
144*cdf0e10cSrcweir 			maSelectionChangedHdl.Call( (void*)sal_IntPtr(nPos) );
145*cdf0e10cSrcweir 	}
146*cdf0e10cSrcweir }
147*cdf0e10cSrcweir 
148*cdf0e10cSrcweir // -----------------------------------------------------------------------
149*cdf0e10cSrcweir 
150*cdf0e10cSrcweir uno::Reference< i18n::XCollator > ImplGetCollator (lang::Locale &rLocale)
151*cdf0e10cSrcweir {
152*cdf0e10cSrcweir 	static uno::Reference< i18n::XCollator > xCollator;
153*cdf0e10cSrcweir 	if ( !xCollator.is() )
154*cdf0e10cSrcweir 		xCollator = vcl::unohelper::CreateCollator();
155*cdf0e10cSrcweir 	if( xCollator.is() )
156*cdf0e10cSrcweir 		xCollator->loadDefaultCollator (rLocale, 0);
157*cdf0e10cSrcweir 
158*cdf0e10cSrcweir 	return xCollator;
159*cdf0e10cSrcweir }
160*cdf0e10cSrcweir 
161*cdf0e10cSrcweir sal_uInt16 ImplEntryList::InsertEntry( sal_uInt16 nPos, ImplEntryType* pNewEntry, sal_Bool bSort )
162*cdf0e10cSrcweir {
163*cdf0e10cSrcweir 	if ( !!pNewEntry->maImage )
164*cdf0e10cSrcweir 		mnImages++;
165*cdf0e10cSrcweir 
166*cdf0e10cSrcweir 	if ( !bSort || !Count() )
167*cdf0e10cSrcweir 	{
168*cdf0e10cSrcweir 		Insert( pNewEntry, nPos );
169*cdf0e10cSrcweir 	}
170*cdf0e10cSrcweir 	else
171*cdf0e10cSrcweir 	{
172*cdf0e10cSrcweir 		lang::Locale aLocale = Application::GetSettings().GetLocale();
173*cdf0e10cSrcweir 		uno::Reference< i18n::XCollator > xCollator = ImplGetCollator(aLocale);
174*cdf0e10cSrcweir 
175*cdf0e10cSrcweir 		const XubString& rStr = pNewEntry->maStr;
176*cdf0e10cSrcweir 		sal_uLong nLow, nHigh, nMid;
177*cdf0e10cSrcweir 
178*cdf0e10cSrcweir 		nHigh = Count();
179*cdf0e10cSrcweir 
180*cdf0e10cSrcweir 		ImplEntryType* pTemp = GetEntry( (sal_uInt16)(nHigh-1) );
181*cdf0e10cSrcweir 
182*cdf0e10cSrcweir 		try
183*cdf0e10cSrcweir 		{
184*cdf0e10cSrcweir 			// XXX even though XCollator::compareString returns a sal_Int32 the only
185*cdf0e10cSrcweir 			// defined values are {-1, 0, 1} which is compatible with StringCompare
186*cdf0e10cSrcweir 			StringCompare eComp = xCollator.is() ?
187*cdf0e10cSrcweir 				(StringCompare)xCollator->compareString (rStr, pTemp->maStr)
188*cdf0e10cSrcweir 				: COMPARE_EQUAL;
189*cdf0e10cSrcweir 
190*cdf0e10cSrcweir 			// Schnelles Einfuegen bei sortierten Daten
191*cdf0e10cSrcweir 			if ( eComp != COMPARE_LESS )
192*cdf0e10cSrcweir 			{
193*cdf0e10cSrcweir 				Insert( pNewEntry, LIST_APPEND );
194*cdf0e10cSrcweir 			}
195*cdf0e10cSrcweir 			else
196*cdf0e10cSrcweir 			{
197*cdf0e10cSrcweir 				nLow  = mnMRUCount;
198*cdf0e10cSrcweir 				pTemp = (ImplEntryType*)GetEntry( (sal_uInt16)nLow );
199*cdf0e10cSrcweir 
200*cdf0e10cSrcweir 				eComp = (StringCompare)xCollator->compareString (rStr, pTemp->maStr);
201*cdf0e10cSrcweir 				if ( eComp != COMPARE_GREATER )
202*cdf0e10cSrcweir 				{
203*cdf0e10cSrcweir 					Insert( pNewEntry, (sal_uLong)0 );
204*cdf0e10cSrcweir 				}
205*cdf0e10cSrcweir 				else
206*cdf0e10cSrcweir 				{
207*cdf0e10cSrcweir 					// Binaeres Suchen
208*cdf0e10cSrcweir 					nHigh--;
209*cdf0e10cSrcweir 					do
210*cdf0e10cSrcweir 					{
211*cdf0e10cSrcweir 						nMid = (nLow + nHigh) / 2;
212*cdf0e10cSrcweir 						pTemp = (ImplEntryType*)GetObject( nMid );
213*cdf0e10cSrcweir 
214*cdf0e10cSrcweir 						eComp = (StringCompare)xCollator->compareString (rStr, pTemp->maStr);
215*cdf0e10cSrcweir 
216*cdf0e10cSrcweir 						if ( eComp == COMPARE_LESS )
217*cdf0e10cSrcweir 							nHigh = nMid-1;
218*cdf0e10cSrcweir 						else
219*cdf0e10cSrcweir 						{
220*cdf0e10cSrcweir 							if ( eComp == COMPARE_GREATER )
221*cdf0e10cSrcweir 								nLow = nMid + 1;
222*cdf0e10cSrcweir 							else
223*cdf0e10cSrcweir 								break;
224*cdf0e10cSrcweir 						}
225*cdf0e10cSrcweir 					}
226*cdf0e10cSrcweir 					while ( nLow <= nHigh );
227*cdf0e10cSrcweir 
228*cdf0e10cSrcweir 					if ( eComp != COMPARE_LESS )
229*cdf0e10cSrcweir 						nMid++;
230*cdf0e10cSrcweir 
231*cdf0e10cSrcweir 					Insert( pNewEntry, nMid );
232*cdf0e10cSrcweir 				}
233*cdf0e10cSrcweir 			}
234*cdf0e10cSrcweir 		}
235*cdf0e10cSrcweir 		catch (uno::RuntimeException& )
236*cdf0e10cSrcweir 		{
237*cdf0e10cSrcweir 			// XXX this is arguable, if the exception occured because pNewEntry is
238*cdf0e10cSrcweir 			// garbage you wouldn't insert it. If the exception occured because the
239*cdf0e10cSrcweir 			// Collator implementation is garbage then give the user a chance to see
240*cdf0e10cSrcweir 			// his stuff
241*cdf0e10cSrcweir 			Insert( pNewEntry, (sal_uLong)0 );
242*cdf0e10cSrcweir 		}
243*cdf0e10cSrcweir 
244*cdf0e10cSrcweir 	}
245*cdf0e10cSrcweir 
246*cdf0e10cSrcweir 	return (sal_uInt16)GetPos( pNewEntry );
247*cdf0e10cSrcweir }
248*cdf0e10cSrcweir 
249*cdf0e10cSrcweir // -----------------------------------------------------------------------
250*cdf0e10cSrcweir 
251*cdf0e10cSrcweir void ImplEntryList::RemoveEntry( sal_uInt16 nPos )
252*cdf0e10cSrcweir {
253*cdf0e10cSrcweir 	ImplEntryType* pImplEntry = (ImplEntryType*)List::Remove( nPos );
254*cdf0e10cSrcweir 	if ( pImplEntry )
255*cdf0e10cSrcweir 	{
256*cdf0e10cSrcweir 		if ( !!pImplEntry->maImage )
257*cdf0e10cSrcweir 			mnImages--;
258*cdf0e10cSrcweir 
259*cdf0e10cSrcweir 		delete pImplEntry;
260*cdf0e10cSrcweir 	}
261*cdf0e10cSrcweir }
262*cdf0e10cSrcweir 
263*cdf0e10cSrcweir // -----------------------------------------------------------------------
264*cdf0e10cSrcweir 
265*cdf0e10cSrcweir sal_uInt16 ImplEntryList::FindEntry( const XubString& rString, sal_Bool bSearchMRUArea ) const
266*cdf0e10cSrcweir {
267*cdf0e10cSrcweir     sal_uInt16 nEntries = GetEntryCount();
268*cdf0e10cSrcweir     for ( sal_uInt16 n = bSearchMRUArea ? 0 : GetMRUCount(); n < nEntries; n++ )
269*cdf0e10cSrcweir 	{
270*cdf0e10cSrcweir 		ImplEntryType* pImplEntry = GetEntry( n );
271*cdf0e10cSrcweir         String aComp( vcl::I18nHelper::filterFormattingChars( pImplEntry->maStr ) );
272*cdf0e10cSrcweir         if ( aComp == rString )
273*cdf0e10cSrcweir             return n;
274*cdf0e10cSrcweir     }
275*cdf0e10cSrcweir     return LISTBOX_ENTRY_NOTFOUND;
276*cdf0e10cSrcweir }
277*cdf0e10cSrcweir 
278*cdf0e10cSrcweir     // -----------------------------------------------------------------------
279*cdf0e10cSrcweir 
280*cdf0e10cSrcweir sal_uInt16 ImplEntryList::FindMatchingEntry( const XubString& rStr, sal_uInt16 nStart, sal_Bool bForward, sal_Bool bLazy ) const
281*cdf0e10cSrcweir {
282*cdf0e10cSrcweir 	sal_uInt16	nPos = LISTBOX_ENTRY_NOTFOUND;
283*cdf0e10cSrcweir 	sal_uInt16	nEntryCount = GetEntryCount();
284*cdf0e10cSrcweir 	if ( !bForward )
285*cdf0e10cSrcweir 		nStart++;	// wird sofort dekrementiert
286*cdf0e10cSrcweir 
287*cdf0e10cSrcweir     const vcl::I18nHelper& rI18nHelper = mpWindow->GetSettings().GetLocaleI18nHelper();
288*cdf0e10cSrcweir     for ( sal_uInt16 n = nStart; bForward ? ( n < nEntryCount ) : n; )
289*cdf0e10cSrcweir 	{
290*cdf0e10cSrcweir 		if ( !bForward )
291*cdf0e10cSrcweir 			n--;
292*cdf0e10cSrcweir 
293*cdf0e10cSrcweir 		ImplEntryType* pImplEntry = GetEntry( n );
294*cdf0e10cSrcweir         sal_Bool bMatch = bLazy ? rI18nHelper.MatchString( rStr, pImplEntry->maStr ) != 0 : ( rStr.Match( pImplEntry->maStr ) == STRING_MATCH );
295*cdf0e10cSrcweir 		if ( bMatch )
296*cdf0e10cSrcweir 		{
297*cdf0e10cSrcweir 			nPos = n;
298*cdf0e10cSrcweir 			break;
299*cdf0e10cSrcweir 		}
300*cdf0e10cSrcweir 
301*cdf0e10cSrcweir 		if ( bForward )
302*cdf0e10cSrcweir 			n++;
303*cdf0e10cSrcweir 	}
304*cdf0e10cSrcweir 
305*cdf0e10cSrcweir     return nPos;
306*cdf0e10cSrcweir }
307*cdf0e10cSrcweir 
308*cdf0e10cSrcweir // -----------------------------------------------------------------------
309*cdf0e10cSrcweir 
310*cdf0e10cSrcweir sal_uInt16 ImplEntryList::FindEntry( const void* pData ) const
311*cdf0e10cSrcweir {
312*cdf0e10cSrcweir 	sal_uInt16 nPos = LISTBOX_ENTRY_NOTFOUND;
313*cdf0e10cSrcweir 	for ( sal_uInt16 n = GetEntryCount(); n; )
314*cdf0e10cSrcweir 	{
315*cdf0e10cSrcweir 		ImplEntryType* pImplEntry = GetEntry( --n );
316*cdf0e10cSrcweir 		if ( pImplEntry->mpUserData == pData )
317*cdf0e10cSrcweir 		{
318*cdf0e10cSrcweir 			nPos = n;
319*cdf0e10cSrcweir 			break;
320*cdf0e10cSrcweir 		}
321*cdf0e10cSrcweir 	}
322*cdf0e10cSrcweir 	return nPos;
323*cdf0e10cSrcweir }
324*cdf0e10cSrcweir 
325*cdf0e10cSrcweir // -----------------------------------------------------------------------
326*cdf0e10cSrcweir 
327*cdf0e10cSrcweir long ImplEntryList::GetAddedHeight( sal_uInt16 i_nEndIndex, sal_uInt16 i_nBeginIndex, long i_nBeginHeight ) const
328*cdf0e10cSrcweir {
329*cdf0e10cSrcweir     long nHeight = i_nBeginHeight;
330*cdf0e10cSrcweir     sal_uInt16 nStart = i_nEndIndex > i_nBeginIndex ? i_nBeginIndex : i_nEndIndex;
331*cdf0e10cSrcweir     sal_uInt16 nStop  = i_nEndIndex > i_nBeginIndex ? i_nEndIndex : i_nBeginIndex;
332*cdf0e10cSrcweir     sal_uInt16 nEntryCount = GetEntryCount();
333*cdf0e10cSrcweir     if( nStop != LISTBOX_ENTRY_NOTFOUND && nEntryCount != 0 )
334*cdf0e10cSrcweir     {
335*cdf0e10cSrcweir         // sanity check
336*cdf0e10cSrcweir         if( nStop > nEntryCount-1 )
337*cdf0e10cSrcweir             nStop = nEntryCount-1;
338*cdf0e10cSrcweir         if( nStart > nEntryCount-1 )
339*cdf0e10cSrcweir             nStart = nEntryCount-1;
340*cdf0e10cSrcweir 
341*cdf0e10cSrcweir         sal_uInt16 nIndex = nStart;
342*cdf0e10cSrcweir         while( nIndex != LISTBOX_ENTRY_NOTFOUND && nIndex < nStop )
343*cdf0e10cSrcweir         {
344*cdf0e10cSrcweir             nHeight += GetEntryPtr( nIndex )-> mnHeight;
345*cdf0e10cSrcweir             nIndex++;
346*cdf0e10cSrcweir         }
347*cdf0e10cSrcweir     }
348*cdf0e10cSrcweir     else
349*cdf0e10cSrcweir         nHeight = 0;
350*cdf0e10cSrcweir     return i_nEndIndex > i_nBeginIndex ? nHeight : -nHeight;
351*cdf0e10cSrcweir }
352*cdf0e10cSrcweir 
353*cdf0e10cSrcweir // -----------------------------------------------------------------------
354*cdf0e10cSrcweir 
355*cdf0e10cSrcweir long ImplEntryList::GetEntryHeight( sal_uInt16 nPos ) const
356*cdf0e10cSrcweir {
357*cdf0e10cSrcweir 	ImplEntryType* pImplEntry = GetEntry( nPos );
358*cdf0e10cSrcweir 	return pImplEntry ? pImplEntry->mnHeight : 0;
359*cdf0e10cSrcweir }
360*cdf0e10cSrcweir 
361*cdf0e10cSrcweir // -----------------------------------------------------------------------
362*cdf0e10cSrcweir 
363*cdf0e10cSrcweir XubString ImplEntryList::GetEntryText( sal_uInt16 nPos ) const
364*cdf0e10cSrcweir {
365*cdf0e10cSrcweir 	XubString aEntryText;
366*cdf0e10cSrcweir 	ImplEntryType* pImplEntry = GetEntry( nPos );
367*cdf0e10cSrcweir 	if ( pImplEntry )
368*cdf0e10cSrcweir 		aEntryText = pImplEntry->maStr;
369*cdf0e10cSrcweir 	return aEntryText;
370*cdf0e10cSrcweir }
371*cdf0e10cSrcweir 
372*cdf0e10cSrcweir // -----------------------------------------------------------------------
373*cdf0e10cSrcweir 
374*cdf0e10cSrcweir sal_Bool ImplEntryList::HasEntryImage( sal_uInt16 nPos ) const
375*cdf0e10cSrcweir {
376*cdf0e10cSrcweir 	sal_Bool bImage = sal_False;
377*cdf0e10cSrcweir 	ImplEntryType* pImplEntry = (ImplEntryType*)List::GetObject( nPos );
378*cdf0e10cSrcweir 	if ( pImplEntry )
379*cdf0e10cSrcweir 		bImage = !!pImplEntry->maImage;
380*cdf0e10cSrcweir 	return bImage;
381*cdf0e10cSrcweir }
382*cdf0e10cSrcweir 
383*cdf0e10cSrcweir // -----------------------------------------------------------------------
384*cdf0e10cSrcweir 
385*cdf0e10cSrcweir Image ImplEntryList::GetEntryImage( sal_uInt16 nPos ) const
386*cdf0e10cSrcweir {
387*cdf0e10cSrcweir 	Image aImage;
388*cdf0e10cSrcweir 	ImplEntryType* pImplEntry = (ImplEntryType*)List::GetObject( nPos );
389*cdf0e10cSrcweir 	if ( pImplEntry )
390*cdf0e10cSrcweir 		aImage = pImplEntry->maImage;
391*cdf0e10cSrcweir 	return aImage;
392*cdf0e10cSrcweir }
393*cdf0e10cSrcweir 
394*cdf0e10cSrcweir // -----------------------------------------------------------------------
395*cdf0e10cSrcweir 
396*cdf0e10cSrcweir void ImplEntryList::SetEntryData( sal_uInt16 nPos, void* pNewData )
397*cdf0e10cSrcweir {
398*cdf0e10cSrcweir 	ImplEntryType* pImplEntry = (ImplEntryType*)List::GetObject( nPos );
399*cdf0e10cSrcweir 	if ( pImplEntry )
400*cdf0e10cSrcweir 		pImplEntry->mpUserData = pNewData;
401*cdf0e10cSrcweir }
402*cdf0e10cSrcweir 
403*cdf0e10cSrcweir // -----------------------------------------------------------------------
404*cdf0e10cSrcweir 
405*cdf0e10cSrcweir void* ImplEntryList::GetEntryData( sal_uInt16 nPos ) const
406*cdf0e10cSrcweir {
407*cdf0e10cSrcweir 	ImplEntryType* pImplEntry = (ImplEntryType*)List::GetObject( nPos );
408*cdf0e10cSrcweir 	return pImplEntry ? pImplEntry->mpUserData : NULL;
409*cdf0e10cSrcweir }
410*cdf0e10cSrcweir 
411*cdf0e10cSrcweir // -----------------------------------------------------------------------
412*cdf0e10cSrcweir 
413*cdf0e10cSrcweir void ImplEntryList::SetEntryFlags( sal_uInt16 nPos, long nFlags )
414*cdf0e10cSrcweir {
415*cdf0e10cSrcweir 	ImplEntryType* pImplEntry = (ImplEntryType*)List::GetObject( nPos );
416*cdf0e10cSrcweir 	if ( pImplEntry )
417*cdf0e10cSrcweir 		pImplEntry->mnFlags = nFlags;
418*cdf0e10cSrcweir }
419*cdf0e10cSrcweir 
420*cdf0e10cSrcweir // -----------------------------------------------------------------------
421*cdf0e10cSrcweir 
422*cdf0e10cSrcweir long ImplEntryList::GetEntryFlags( sal_uInt16 nPos ) const
423*cdf0e10cSrcweir {
424*cdf0e10cSrcweir 	ImplEntryType* pImplEntry = (ImplEntryType*)List::GetObject( nPos );
425*cdf0e10cSrcweir 	return pImplEntry ? pImplEntry->mnFlags : 0;
426*cdf0e10cSrcweir }
427*cdf0e10cSrcweir 
428*cdf0e10cSrcweir // -----------------------------------------------------------------------
429*cdf0e10cSrcweir 
430*cdf0e10cSrcweir sal_uInt16 ImplEntryList::GetSelectEntryCount() const
431*cdf0e10cSrcweir {
432*cdf0e10cSrcweir 	sal_uInt16 nSelCount = 0;
433*cdf0e10cSrcweir 	for ( sal_uInt16 n = GetEntryCount(); n; )
434*cdf0e10cSrcweir 	{
435*cdf0e10cSrcweir 		ImplEntryType* pImplEntry = GetEntry( --n );
436*cdf0e10cSrcweir 		if ( pImplEntry->mbIsSelected )
437*cdf0e10cSrcweir 			nSelCount++;
438*cdf0e10cSrcweir 	}
439*cdf0e10cSrcweir 	return nSelCount;
440*cdf0e10cSrcweir }
441*cdf0e10cSrcweir 
442*cdf0e10cSrcweir // -----------------------------------------------------------------------
443*cdf0e10cSrcweir 
444*cdf0e10cSrcweir XubString ImplEntryList::GetSelectEntry( sal_uInt16 nIndex ) const
445*cdf0e10cSrcweir {
446*cdf0e10cSrcweir 	return GetEntryText( GetSelectEntryPos( nIndex ) );
447*cdf0e10cSrcweir }
448*cdf0e10cSrcweir 
449*cdf0e10cSrcweir // -----------------------------------------------------------------------
450*cdf0e10cSrcweir 
451*cdf0e10cSrcweir sal_uInt16 ImplEntryList::GetSelectEntryPos( sal_uInt16 nIndex ) const
452*cdf0e10cSrcweir {
453*cdf0e10cSrcweir 	sal_uInt16 nSelEntryPos = LISTBOX_ENTRY_NOTFOUND;
454*cdf0e10cSrcweir 	sal_uInt16 nSel = 0;
455*cdf0e10cSrcweir 	sal_uInt16 nEntryCount = GetEntryCount();
456*cdf0e10cSrcweir 
457*cdf0e10cSrcweir 	for ( sal_uInt16 n = 0; n < nEntryCount; n++ )
458*cdf0e10cSrcweir 	{
459*cdf0e10cSrcweir 		ImplEntryType* pImplEntry = GetEntry( n );
460*cdf0e10cSrcweir 		if ( pImplEntry->mbIsSelected )
461*cdf0e10cSrcweir 		{
462*cdf0e10cSrcweir 			if ( nSel == nIndex )
463*cdf0e10cSrcweir 			{
464*cdf0e10cSrcweir 				nSelEntryPos = n;
465*cdf0e10cSrcweir 				break;
466*cdf0e10cSrcweir 			}
467*cdf0e10cSrcweir 			nSel++;
468*cdf0e10cSrcweir 		}
469*cdf0e10cSrcweir 	}
470*cdf0e10cSrcweir 
471*cdf0e10cSrcweir 	return nSelEntryPos;
472*cdf0e10cSrcweir }
473*cdf0e10cSrcweir 
474*cdf0e10cSrcweir // -----------------------------------------------------------------------
475*cdf0e10cSrcweir 
476*cdf0e10cSrcweir sal_Bool ImplEntryList::IsEntrySelected( const XubString& rStr ) const
477*cdf0e10cSrcweir {
478*cdf0e10cSrcweir 	return IsEntryPosSelected( FindEntry( rStr ) );
479*cdf0e10cSrcweir }
480*cdf0e10cSrcweir 
481*cdf0e10cSrcweir // -----------------------------------------------------------------------
482*cdf0e10cSrcweir 
483*cdf0e10cSrcweir sal_Bool ImplEntryList::IsEntryPosSelected( sal_uInt16 nIndex ) const
484*cdf0e10cSrcweir {
485*cdf0e10cSrcweir 	ImplEntryType* pImplEntry = GetEntry( nIndex );
486*cdf0e10cSrcweir 	return pImplEntry ? pImplEntry->mbIsSelected : sal_False;
487*cdf0e10cSrcweir }
488*cdf0e10cSrcweir 
489*cdf0e10cSrcweir // -----------------------------------------------------------------------
490*cdf0e10cSrcweir 
491*cdf0e10cSrcweir bool ImplEntryList::IsEntrySelectable( sal_uInt16 nPos ) const
492*cdf0e10cSrcweir {
493*cdf0e10cSrcweir 	ImplEntryType* pImplEntry = GetEntry( nPos );
494*cdf0e10cSrcweir 	return pImplEntry ? ((pImplEntry->mnFlags & LISTBOX_ENTRY_FLAG_DISABLE_SELECTION) == 0) : true;
495*cdf0e10cSrcweir }
496*cdf0e10cSrcweir 
497*cdf0e10cSrcweir // -----------------------------------------------------------------------
498*cdf0e10cSrcweir 
499*cdf0e10cSrcweir sal_uInt16 ImplEntryList::FindFirstSelectable( sal_uInt16 nPos, bool bForward /* = true */ )
500*cdf0e10cSrcweir {
501*cdf0e10cSrcweir 	if( IsEntrySelectable( nPos ) )
502*cdf0e10cSrcweir 		return nPos;
503*cdf0e10cSrcweir 
504*cdf0e10cSrcweir 	if( bForward )
505*cdf0e10cSrcweir 	{
506*cdf0e10cSrcweir 		for( nPos = nPos + 1; nPos < GetEntryCount(); nPos++ )
507*cdf0e10cSrcweir 		{
508*cdf0e10cSrcweir 			if( IsEntrySelectable( nPos ) )
509*cdf0e10cSrcweir 				return nPos;
510*cdf0e10cSrcweir 		}
511*cdf0e10cSrcweir 	}
512*cdf0e10cSrcweir 	else
513*cdf0e10cSrcweir 	{
514*cdf0e10cSrcweir 		while( nPos )
515*cdf0e10cSrcweir 		{
516*cdf0e10cSrcweir 			nPos--;
517*cdf0e10cSrcweir 			if( IsEntrySelectable( nPos ) )
518*cdf0e10cSrcweir 				return nPos;
519*cdf0e10cSrcweir 		}
520*cdf0e10cSrcweir 	}
521*cdf0e10cSrcweir 
522*cdf0e10cSrcweir 	return LISTBOX_ENTRY_NOTFOUND;
523*cdf0e10cSrcweir }
524*cdf0e10cSrcweir 
525*cdf0e10cSrcweir // =======================================================================
526*cdf0e10cSrcweir 
527*cdf0e10cSrcweir ImplListBoxWindow::ImplListBoxWindow( Window* pParent, WinBits nWinStyle ) :
528*cdf0e10cSrcweir 	Control( pParent, 0 ),
529*cdf0e10cSrcweir     maQuickSelectionEngine( *this )
530*cdf0e10cSrcweir {
531*cdf0e10cSrcweir 	mpEntryList 		= new ImplEntryList( this );
532*cdf0e10cSrcweir 
533*cdf0e10cSrcweir 	mnTop				= 0;
534*cdf0e10cSrcweir 	mnLeft				= 0;
535*cdf0e10cSrcweir 	mnBorder			= 1;
536*cdf0e10cSrcweir 	mnSelectModifier	= 0;
537*cdf0e10cSrcweir 	mnUserDrawEntry 	= LISTBOX_ENTRY_NOTFOUND;
538*cdf0e10cSrcweir 	mbTrack 			= sal_False;
539*cdf0e10cSrcweir 	mbImgsDiffSz		= sal_False;
540*cdf0e10cSrcweir 	mbTravelSelect		= sal_False;
541*cdf0e10cSrcweir 	mbTrackingSelect	= sal_False;
542*cdf0e10cSrcweir 	mbSelectionChanged	= sal_False;
543*cdf0e10cSrcweir 	mbMouseMoveSelect	= sal_False;
544*cdf0e10cSrcweir 	mbMulti 			= sal_False;
545*cdf0e10cSrcweir 	mbStackMode 		= sal_False;
546*cdf0e10cSrcweir 	mbGrabFocus 		= sal_False;
547*cdf0e10cSrcweir 	mbUserDrawEnabled	= sal_False;
548*cdf0e10cSrcweir 	mbInUserDraw		= sal_False;
549*cdf0e10cSrcweir 	mbReadOnly			= sal_False;
550*cdf0e10cSrcweir     mbHasFocusRect      = sal_False;
551*cdf0e10cSrcweir     mbRight             = ( nWinStyle & WB_RIGHT )      ? sal_True : sal_False;
552*cdf0e10cSrcweir     mbCenter            = ( nWinStyle & WB_CENTER )     ? sal_True : sal_False;
553*cdf0e10cSrcweir 	mbSimpleMode		= ( nWinStyle & WB_SIMPLEMODE ) ? sal_True : sal_False;
554*cdf0e10cSrcweir 	mbSort				= ( nWinStyle & WB_SORT )       ? sal_True : sal_False;
555*cdf0e10cSrcweir 
556*cdf0e10cSrcweir 	// pb: #106948# explicit mirroring for calc
557*cdf0e10cSrcweir 	mbMirroring			= sal_False;
558*cdf0e10cSrcweir 
559*cdf0e10cSrcweir 	mnCurrentPos			= LISTBOX_ENTRY_NOTFOUND;
560*cdf0e10cSrcweir 	mnTrackingSaveSelection = LISTBOX_ENTRY_NOTFOUND;
561*cdf0e10cSrcweir 	mnSeparatorPos			= LISTBOX_ENTRY_NOTFOUND;
562*cdf0e10cSrcweir 	meProminentType         = PROMINENT_TOP;
563*cdf0e10cSrcweir 
564*cdf0e10cSrcweir 	SetLineColor();
565*cdf0e10cSrcweir 	SetTextFillColor();
566*cdf0e10cSrcweir 	SetBackground( Wallpaper( GetSettings().GetStyleSettings().GetFieldColor() ) );
567*cdf0e10cSrcweir 
568*cdf0e10cSrcweir 	ImplInitSettings( sal_True, sal_True, sal_True );
569*cdf0e10cSrcweir 	ImplCalcMetrics();
570*cdf0e10cSrcweir }
571*cdf0e10cSrcweir 
572*cdf0e10cSrcweir // -----------------------------------------------------------------------
573*cdf0e10cSrcweir 
574*cdf0e10cSrcweir ImplListBoxWindow::~ImplListBoxWindow()
575*cdf0e10cSrcweir {
576*cdf0e10cSrcweir 	delete mpEntryList;
577*cdf0e10cSrcweir }
578*cdf0e10cSrcweir 
579*cdf0e10cSrcweir // -----------------------------------------------------------------------
580*cdf0e10cSrcweir 
581*cdf0e10cSrcweir void ImplListBoxWindow::ImplInitSettings( sal_Bool bFont, sal_Bool bForeground, sal_Bool bBackground )
582*cdf0e10cSrcweir {
583*cdf0e10cSrcweir 	ImplInitFieldSettings( this, bFont, bForeground, bBackground );
584*cdf0e10cSrcweir }
585*cdf0e10cSrcweir 
586*cdf0e10cSrcweir // -----------------------------------------------------------------------
587*cdf0e10cSrcweir 
588*cdf0e10cSrcweir void ImplListBoxWindow::ImplCalcMetrics()
589*cdf0e10cSrcweir {
590*cdf0e10cSrcweir 	mnMaxWidth		= 0;
591*cdf0e10cSrcweir 	mnMaxTxtWidth	= 0;
592*cdf0e10cSrcweir 	mnMaxImgWidth	= 0;
593*cdf0e10cSrcweir 	mnMaxImgTxtWidth= 0;
594*cdf0e10cSrcweir 	mnMaxImgHeight	= 0;
595*cdf0e10cSrcweir 
596*cdf0e10cSrcweir 	mnTextHeight = (sal_uInt16)GetTextHeight();
597*cdf0e10cSrcweir 	mnMaxTxtHeight = mnTextHeight + mnBorder;
598*cdf0e10cSrcweir 	mnMaxHeight = mnMaxTxtHeight;
599*cdf0e10cSrcweir 
600*cdf0e10cSrcweir 	if ( maUserItemSize.Height() > mnMaxHeight )
601*cdf0e10cSrcweir 		mnMaxHeight = (sal_uInt16) maUserItemSize.Height();
602*cdf0e10cSrcweir 	if ( maUserItemSize.Width() > mnMaxWidth )
603*cdf0e10cSrcweir 		mnMaxWidth= (sal_uInt16) maUserItemSize.Width();
604*cdf0e10cSrcweir 
605*cdf0e10cSrcweir 	for ( sal_uInt16 n = mpEntryList->GetEntryCount(); n; )
606*cdf0e10cSrcweir 	{
607*cdf0e10cSrcweir 		ImplEntryType* pEntry = mpEntryList->GetMutableEntryPtr( --n );
608*cdf0e10cSrcweir 		ImplUpdateEntryMetrics( *pEntry );
609*cdf0e10cSrcweir 	}
610*cdf0e10cSrcweir 
611*cdf0e10cSrcweir     if( mnCurrentPos != LISTBOX_ENTRY_NOTFOUND )
612*cdf0e10cSrcweir     {
613*cdf0e10cSrcweir         Size aSz( GetOutputSizePixel().Width(), mpEntryList->GetEntryPtr( mnCurrentPos )->mnHeight );
614*cdf0e10cSrcweir         maFocusRect.SetSize( aSz );
615*cdf0e10cSrcweir     }
616*cdf0e10cSrcweir }
617*cdf0e10cSrcweir 
618*cdf0e10cSrcweir // -----------------------------------------------------------------------
619*cdf0e10cSrcweir 
620*cdf0e10cSrcweir void ImplListBoxWindow::Clear()
621*cdf0e10cSrcweir {
622*cdf0e10cSrcweir 	mpEntryList->Clear();
623*cdf0e10cSrcweir 
624*cdf0e10cSrcweir 	mnMaxHeight 	= mnMaxTxtHeight;
625*cdf0e10cSrcweir 	mnMaxWidth		= 0;
626*cdf0e10cSrcweir 	mnMaxTxtWidth	= 0;
627*cdf0e10cSrcweir 	mnMaxImgTxtWidth= 0;
628*cdf0e10cSrcweir 	mnMaxImgWidth	= 0;
629*cdf0e10cSrcweir 	mnMaxImgHeight	= 0;
630*cdf0e10cSrcweir 	mnTop			= 0;
631*cdf0e10cSrcweir 	mnLeft			= 0;
632*cdf0e10cSrcweir 	mbImgsDiffSz	= sal_False;
633*cdf0e10cSrcweir     ImplClearLayoutData();
634*cdf0e10cSrcweir 
635*cdf0e10cSrcweir     mnCurrentPos = LISTBOX_ENTRY_NOTFOUND;
636*cdf0e10cSrcweir     maQuickSelectionEngine.Reset();
637*cdf0e10cSrcweir 
638*cdf0e10cSrcweir 	Invalidate();
639*cdf0e10cSrcweir }
640*cdf0e10cSrcweir 
641*cdf0e10cSrcweir void ImplListBoxWindow::SetUserItemSize( const Size& rSz )
642*cdf0e10cSrcweir {
643*cdf0e10cSrcweir     ImplClearLayoutData();
644*cdf0e10cSrcweir 	maUserItemSize = rSz;
645*cdf0e10cSrcweir 	ImplCalcMetrics();
646*cdf0e10cSrcweir }
647*cdf0e10cSrcweir 
648*cdf0e10cSrcweir // -----------------------------------------------------------------------
649*cdf0e10cSrcweir 
650*cdf0e10cSrcweir struct ImplEntryMetrics
651*cdf0e10cSrcweir {
652*cdf0e10cSrcweir 	sal_Bool	bText;
653*cdf0e10cSrcweir 	sal_Bool	bImage;
654*cdf0e10cSrcweir 	long	nEntryWidth;
655*cdf0e10cSrcweir 	long	nEntryHeight;
656*cdf0e10cSrcweir 	long	nTextWidth;
657*cdf0e10cSrcweir 	long	nImgWidth;
658*cdf0e10cSrcweir 	long	nImgHeight;
659*cdf0e10cSrcweir };
660*cdf0e10cSrcweir 
661*cdf0e10cSrcweir // -----------------------------------------------------------------------
662*cdf0e10cSrcweir 
663*cdf0e10cSrcweir void ImplListBoxWindow::ImplUpdateEntryMetrics( ImplEntryType& rEntry )
664*cdf0e10cSrcweir {
665*cdf0e10cSrcweir 	ImplEntryMetrics aMetrics;
666*cdf0e10cSrcweir 	aMetrics.bText = rEntry.maStr.Len() ? sal_True : sal_False;
667*cdf0e10cSrcweir 	aMetrics.bImage = !!rEntry.maImage;
668*cdf0e10cSrcweir 	aMetrics.nEntryWidth = 0;
669*cdf0e10cSrcweir 	aMetrics.nEntryHeight = 0;
670*cdf0e10cSrcweir 	aMetrics.nTextWidth = 0;
671*cdf0e10cSrcweir 	aMetrics.nImgWidth = 0;
672*cdf0e10cSrcweir 	aMetrics.nImgHeight = 0;
673*cdf0e10cSrcweir 
674*cdf0e10cSrcweir 	if ( aMetrics.bText )
675*cdf0e10cSrcweir 	{
676*cdf0e10cSrcweir         if( (rEntry.mnFlags & LISTBOX_ENTRY_FLAG_MULTILINE) )
677*cdf0e10cSrcweir         {
678*cdf0e10cSrcweir             // multiline case
679*cdf0e10cSrcweir             Size aCurSize( PixelToLogic( GetSizePixel() ) );
680*cdf0e10cSrcweir             // set the current size to a large number
681*cdf0e10cSrcweir             // GetTextRect should shrink it to the actual size
682*cdf0e10cSrcweir             aCurSize.Height() = 0x7fffff;
683*cdf0e10cSrcweir             Rectangle aTextRect( Point( 0, 0 ), aCurSize );
684*cdf0e10cSrcweir             aTextRect = GetTextRect( aTextRect, rEntry.maStr, TEXT_DRAW_WORDBREAK | TEXT_DRAW_MULTILINE );
685*cdf0e10cSrcweir             aMetrics.nTextWidth = aTextRect.GetWidth();
686*cdf0e10cSrcweir             if( aMetrics.nTextWidth > mnMaxTxtWidth )
687*cdf0e10cSrcweir                 mnMaxTxtWidth = aMetrics.nTextWidth;
688*cdf0e10cSrcweir             aMetrics.nEntryWidth = mnMaxTxtWidth;
689*cdf0e10cSrcweir             aMetrics.nEntryHeight = aTextRect.GetHeight() + mnBorder;
690*cdf0e10cSrcweir         }
691*cdf0e10cSrcweir         else
692*cdf0e10cSrcweir         {
693*cdf0e10cSrcweir             // normal single line case
694*cdf0e10cSrcweir             aMetrics.nTextWidth = (sal_uInt16)GetTextWidth( rEntry.maStr );
695*cdf0e10cSrcweir             if( aMetrics.nTextWidth > mnMaxTxtWidth )
696*cdf0e10cSrcweir                 mnMaxTxtWidth = aMetrics.nTextWidth;
697*cdf0e10cSrcweir             aMetrics.nEntryWidth = mnMaxTxtWidth;
698*cdf0e10cSrcweir             aMetrics.nEntryHeight = mnTextHeight + mnBorder;
699*cdf0e10cSrcweir         }
700*cdf0e10cSrcweir 	}
701*cdf0e10cSrcweir 	if ( aMetrics.bImage )
702*cdf0e10cSrcweir 	{
703*cdf0e10cSrcweir 		Size aImgSz = rEntry.maImage.GetSizePixel();
704*cdf0e10cSrcweir 		aMetrics.nImgWidth	= (sal_uInt16) CalcZoom( aImgSz.Width() );
705*cdf0e10cSrcweir 		aMetrics.nImgHeight = (sal_uInt16) CalcZoom( aImgSz.Height() );
706*cdf0e10cSrcweir 
707*cdf0e10cSrcweir         if( mnMaxImgWidth && ( aMetrics.nImgWidth != mnMaxImgWidth ) )
708*cdf0e10cSrcweir             mbImgsDiffSz = sal_True;
709*cdf0e10cSrcweir         else if ( mnMaxImgHeight && ( aMetrics.nImgHeight != mnMaxImgHeight ) )
710*cdf0e10cSrcweir             mbImgsDiffSz = sal_True;
711*cdf0e10cSrcweir 
712*cdf0e10cSrcweir         if( aMetrics.nImgWidth > mnMaxImgWidth )
713*cdf0e10cSrcweir             mnMaxImgWidth = aMetrics.nImgWidth;
714*cdf0e10cSrcweir         if( aMetrics.nImgHeight > mnMaxImgHeight )
715*cdf0e10cSrcweir             mnMaxImgHeight = aMetrics.nImgHeight;
716*cdf0e10cSrcweir 
717*cdf0e10cSrcweir         mnMaxImgTxtWidth = Max( mnMaxImgTxtWidth, aMetrics.nTextWidth );
718*cdf0e10cSrcweir         aMetrics.nEntryHeight = Max( aMetrics.nImgHeight, aMetrics.nEntryHeight );
719*cdf0e10cSrcweir 
720*cdf0e10cSrcweir 	}
721*cdf0e10cSrcweir 	if ( IsUserDrawEnabled() || aMetrics.bImage )
722*cdf0e10cSrcweir 	{
723*cdf0e10cSrcweir 		aMetrics.nEntryWidth = Max( aMetrics.nImgWidth, maUserItemSize.Width() );
724*cdf0e10cSrcweir 		if ( aMetrics.bText )
725*cdf0e10cSrcweir 			aMetrics.nEntryWidth += aMetrics.nTextWidth + IMG_TXT_DISTANCE;
726*cdf0e10cSrcweir 		aMetrics.nEntryHeight = Max( Max( mnMaxImgHeight, maUserItemSize.Height() ) + 2,
727*cdf0e10cSrcweir                                      aMetrics.nEntryHeight );
728*cdf0e10cSrcweir 	}
729*cdf0e10cSrcweir 
730*cdf0e10cSrcweir     if ( !aMetrics.bText && !aMetrics.bImage && !IsUserDrawEnabled() )
731*cdf0e10cSrcweir     {
732*cdf0e10cSrcweir         // entries which have no (aka an empty) text, and no image, and are not user-drawn, should be
733*cdf0e10cSrcweir         // shown nonetheless
734*cdf0e10cSrcweir         aMetrics.nEntryHeight = mnTextHeight + mnBorder;
735*cdf0e10cSrcweir     }
736*cdf0e10cSrcweir 
737*cdf0e10cSrcweir     if ( aMetrics.nEntryWidth > mnMaxWidth )
738*cdf0e10cSrcweir         mnMaxWidth = aMetrics.nEntryWidth;
739*cdf0e10cSrcweir     if ( aMetrics.nEntryHeight > mnMaxHeight )
740*cdf0e10cSrcweir         mnMaxHeight = aMetrics.nEntryHeight;
741*cdf0e10cSrcweir 
742*cdf0e10cSrcweir     rEntry.mnHeight = aMetrics.nEntryHeight;
743*cdf0e10cSrcweir }
744*cdf0e10cSrcweir 
745*cdf0e10cSrcweir // -----------------------------------------------------------------------
746*cdf0e10cSrcweir 
747*cdf0e10cSrcweir void ImplListBoxWindow::ImplCallSelect()
748*cdf0e10cSrcweir {
749*cdf0e10cSrcweir 	if ( !IsTravelSelect() && GetEntryList()->GetMaxMRUCount() )
750*cdf0e10cSrcweir 	{
751*cdf0e10cSrcweir 		// Insert the selected entry as MRU, if not allready first MRU
752*cdf0e10cSrcweir 		sal_uInt16 nSelected = GetEntryList()->GetSelectEntryPos( 0 );
753*cdf0e10cSrcweir 		sal_uInt16 nMRUCount = GetEntryList()->GetMRUCount();
754*cdf0e10cSrcweir 		String aSelected = GetEntryList()->GetEntryText( nSelected );
755*cdf0e10cSrcweir 		sal_uInt16 nFirstMatchingEntryPos = GetEntryList()->FindEntry( aSelected, sal_True );
756*cdf0e10cSrcweir 		if ( nFirstMatchingEntryPos || !nMRUCount )
757*cdf0e10cSrcweir 		{
758*cdf0e10cSrcweir 			sal_Bool bSelectNewEntry = sal_False;
759*cdf0e10cSrcweir 			if ( nFirstMatchingEntryPos < nMRUCount )
760*cdf0e10cSrcweir 			{
761*cdf0e10cSrcweir 				RemoveEntry( nFirstMatchingEntryPos );
762*cdf0e10cSrcweir 				nMRUCount--;
763*cdf0e10cSrcweir 				if ( nFirstMatchingEntryPos == nSelected )
764*cdf0e10cSrcweir 					bSelectNewEntry = sal_True;
765*cdf0e10cSrcweir 			}
766*cdf0e10cSrcweir 			else if ( nMRUCount == GetEntryList()->GetMaxMRUCount() )
767*cdf0e10cSrcweir 			{
768*cdf0e10cSrcweir 				RemoveEntry( nMRUCount - 1 );
769*cdf0e10cSrcweir 				nMRUCount--;
770*cdf0e10cSrcweir 			}
771*cdf0e10cSrcweir 
772*cdf0e10cSrcweir             ImplClearLayoutData();
773*cdf0e10cSrcweir 
774*cdf0e10cSrcweir 			ImplEntryType* pNewEntry = new ImplEntryType( aSelected );
775*cdf0e10cSrcweir 			pNewEntry->mbIsSelected = bSelectNewEntry;
776*cdf0e10cSrcweir 			GetEntryList()->InsertEntry( 0, pNewEntry, sal_False );
777*cdf0e10cSrcweir             ImplUpdateEntryMetrics( *pNewEntry );
778*cdf0e10cSrcweir 			GetEntryList()->SetMRUCount( ++nMRUCount );
779*cdf0e10cSrcweir 			SetSeparatorPos( nMRUCount ? nMRUCount-1 : 0 );
780*cdf0e10cSrcweir 			maMRUChangedHdl.Call( NULL );
781*cdf0e10cSrcweir 		}
782*cdf0e10cSrcweir 	}
783*cdf0e10cSrcweir 
784*cdf0e10cSrcweir 	maSelectHdl.Call( NULL );
785*cdf0e10cSrcweir 	mbSelectionChanged = sal_False;
786*cdf0e10cSrcweir }
787*cdf0e10cSrcweir 
788*cdf0e10cSrcweir // -----------------------------------------------------------------------
789*cdf0e10cSrcweir 
790*cdf0e10cSrcweir sal_uInt16 ImplListBoxWindow::InsertEntry( sal_uInt16 nPos, ImplEntryType* pNewEntry )
791*cdf0e10cSrcweir {
792*cdf0e10cSrcweir     ImplClearLayoutData();
793*cdf0e10cSrcweir 	sal_uInt16 nNewPos = mpEntryList->InsertEntry( nPos, pNewEntry, mbSort );
794*cdf0e10cSrcweir 
795*cdf0e10cSrcweir     if( (GetStyle() & WB_WORDBREAK) )
796*cdf0e10cSrcweir         pNewEntry->mnFlags |= LISTBOX_ENTRY_FLAG_MULTILINE;
797*cdf0e10cSrcweir 
798*cdf0e10cSrcweir 	ImplUpdateEntryMetrics( *pNewEntry );
799*cdf0e10cSrcweir 	return nNewPos;
800*cdf0e10cSrcweir }
801*cdf0e10cSrcweir 
802*cdf0e10cSrcweir // -----------------------------------------------------------------------
803*cdf0e10cSrcweir 
804*cdf0e10cSrcweir void ImplListBoxWindow::RemoveEntry( sal_uInt16 nPos )
805*cdf0e10cSrcweir {
806*cdf0e10cSrcweir     ImplClearLayoutData();
807*cdf0e10cSrcweir 	mpEntryList->RemoveEntry( nPos );
808*cdf0e10cSrcweir     if( mnCurrentPos >= mpEntryList->GetEntryCount() )
809*cdf0e10cSrcweir         mnCurrentPos = LISTBOX_ENTRY_NOTFOUND;
810*cdf0e10cSrcweir 	ImplCalcMetrics();
811*cdf0e10cSrcweir }
812*cdf0e10cSrcweir 
813*cdf0e10cSrcweir // -----------------------------------------------------------------------
814*cdf0e10cSrcweir 
815*cdf0e10cSrcweir void ImplListBoxWindow::SetEntryFlags( sal_uInt16 nPos, long nFlags )
816*cdf0e10cSrcweir {
817*cdf0e10cSrcweir 	mpEntryList->SetEntryFlags( nPos, nFlags );
818*cdf0e10cSrcweir     ImplEntryType* pEntry = mpEntryList->GetMutableEntryPtr( nPos );
819*cdf0e10cSrcweir     if( pEntry )
820*cdf0e10cSrcweir         ImplUpdateEntryMetrics( *pEntry );
821*cdf0e10cSrcweir }
822*cdf0e10cSrcweir 
823*cdf0e10cSrcweir // -----------------------------------------------------------------------
824*cdf0e10cSrcweir 
825*cdf0e10cSrcweir void ImplListBoxWindow::ImplShowFocusRect()
826*cdf0e10cSrcweir {
827*cdf0e10cSrcweir     if ( mbHasFocusRect )
828*cdf0e10cSrcweir         HideFocus();
829*cdf0e10cSrcweir     ShowFocus( maFocusRect );
830*cdf0e10cSrcweir     mbHasFocusRect = sal_True;
831*cdf0e10cSrcweir }
832*cdf0e10cSrcweir 
833*cdf0e10cSrcweir // -----------------------------------------------------------------------
834*cdf0e10cSrcweir 
835*cdf0e10cSrcweir void ImplListBoxWindow::ImplHideFocusRect()
836*cdf0e10cSrcweir {
837*cdf0e10cSrcweir     if ( mbHasFocusRect )
838*cdf0e10cSrcweir     {
839*cdf0e10cSrcweir         HideFocus();
840*cdf0e10cSrcweir         mbHasFocusRect = sal_False;
841*cdf0e10cSrcweir     }
842*cdf0e10cSrcweir }
843*cdf0e10cSrcweir 
844*cdf0e10cSrcweir 
845*cdf0e10cSrcweir // -----------------------------------------------------------------------
846*cdf0e10cSrcweir 
847*cdf0e10cSrcweir sal_uInt16 ImplListBoxWindow::GetEntryPosForPoint( const Point& rPoint ) const
848*cdf0e10cSrcweir {
849*cdf0e10cSrcweir     long nY = mnBorder;
850*cdf0e10cSrcweir 
851*cdf0e10cSrcweir     sal_uInt16 nSelect = mnTop;
852*cdf0e10cSrcweir     const ImplEntryType* pEntry = mpEntryList->GetEntryPtr( nSelect );
853*cdf0e10cSrcweir     while( pEntry && rPoint.Y() > pEntry->mnHeight + nY )
854*cdf0e10cSrcweir     {
855*cdf0e10cSrcweir         nY += pEntry->mnHeight;
856*cdf0e10cSrcweir         pEntry = mpEntryList->GetEntryPtr( ++nSelect );
857*cdf0e10cSrcweir     }
858*cdf0e10cSrcweir     if( pEntry == NULL )
859*cdf0e10cSrcweir         nSelect = LISTBOX_ENTRY_NOTFOUND;
860*cdf0e10cSrcweir 
861*cdf0e10cSrcweir     return nSelect;
862*cdf0e10cSrcweir }
863*cdf0e10cSrcweir 
864*cdf0e10cSrcweir // -----------------------------------------------------------------------
865*cdf0e10cSrcweir 
866*cdf0e10cSrcweir sal_Bool ImplListBoxWindow::IsVisible( sal_uInt16 i_nEntry ) const
867*cdf0e10cSrcweir {
868*cdf0e10cSrcweir     sal_Bool bRet = sal_False;
869*cdf0e10cSrcweir 
870*cdf0e10cSrcweir     if( i_nEntry >= mnTop )
871*cdf0e10cSrcweir     {
872*cdf0e10cSrcweir         if( mpEntryList->GetAddedHeight( i_nEntry, mnTop ) <
873*cdf0e10cSrcweir             PixelToLogic( GetSizePixel() ).Height() )
874*cdf0e10cSrcweir         {
875*cdf0e10cSrcweir             bRet = sal_True;
876*cdf0e10cSrcweir         }
877*cdf0e10cSrcweir     }
878*cdf0e10cSrcweir 
879*cdf0e10cSrcweir     return bRet;
880*cdf0e10cSrcweir }
881*cdf0e10cSrcweir 
882*cdf0e10cSrcweir // -----------------------------------------------------------------------
883*cdf0e10cSrcweir 
884*cdf0e10cSrcweir sal_uInt16 ImplListBoxWindow::GetLastVisibleEntry() const
885*cdf0e10cSrcweir {
886*cdf0e10cSrcweir     sal_uInt16 nPos = mnTop;
887*cdf0e10cSrcweir     long nWindowHeight = GetSizePixel().Height();
888*cdf0e10cSrcweir     sal_uInt16 nCount = mpEntryList->GetEntryCount();
889*cdf0e10cSrcweir     long nDiff;
890*cdf0e10cSrcweir     for( nDiff = 0; nDiff < nWindowHeight && nPos < nCount; nDiff = mpEntryList->GetAddedHeight( nPos, mnTop ) )
891*cdf0e10cSrcweir         nPos++;
892*cdf0e10cSrcweir 
893*cdf0e10cSrcweir     if( nDiff > nWindowHeight && nPos > mnTop )
894*cdf0e10cSrcweir         nPos--;
895*cdf0e10cSrcweir 
896*cdf0e10cSrcweir     if( nPos >= nCount )
897*cdf0e10cSrcweir         nPos = nCount-1;
898*cdf0e10cSrcweir 
899*cdf0e10cSrcweir     return nPos;
900*cdf0e10cSrcweir }
901*cdf0e10cSrcweir 
902*cdf0e10cSrcweir // -----------------------------------------------------------------------
903*cdf0e10cSrcweir 
904*cdf0e10cSrcweir void ImplListBoxWindow::MouseButtonDown( const MouseEvent& rMEvt )
905*cdf0e10cSrcweir {
906*cdf0e10cSrcweir 	mbMouseMoveSelect = sal_False;	// Nur bis zum ersten MouseButtonDown
907*cdf0e10cSrcweir     maQuickSelectionEngine.Reset();
908*cdf0e10cSrcweir 
909*cdf0e10cSrcweir 	if ( !IsReadOnly() )
910*cdf0e10cSrcweir 	{
911*cdf0e10cSrcweir 		if( rMEvt.GetClicks() == 1 )
912*cdf0e10cSrcweir 		{
913*cdf0e10cSrcweir 			sal_uInt16 nSelect = GetEntryPosForPoint( rMEvt.GetPosPixel() );
914*cdf0e10cSrcweir 			if( nSelect != LISTBOX_ENTRY_NOTFOUND )
915*cdf0e10cSrcweir 			{
916*cdf0e10cSrcweir 				if ( !mbMulti && GetEntryList()->GetSelectEntryCount() )
917*cdf0e10cSrcweir 					mnTrackingSaveSelection = GetEntryList()->GetSelectEntryPos( 0 );
918*cdf0e10cSrcweir 				else
919*cdf0e10cSrcweir 					mnTrackingSaveSelection = LISTBOX_ENTRY_NOTFOUND;
920*cdf0e10cSrcweir 
921*cdf0e10cSrcweir 				mnCurrentPos = nSelect;
922*cdf0e10cSrcweir 				mbTrackingSelect = sal_True;
923*cdf0e10cSrcweir 				SelectEntries( nSelect, LET_MBDOWN, rMEvt.IsShift(), rMEvt.IsMod1() );
924*cdf0e10cSrcweir 				mbTrackingSelect = sal_False;
925*cdf0e10cSrcweir 				if ( mbGrabFocus )
926*cdf0e10cSrcweir 					GrabFocus();
927*cdf0e10cSrcweir 
928*cdf0e10cSrcweir 				StartTracking( STARTTRACK_SCROLLREPEAT );
929*cdf0e10cSrcweir 			}
930*cdf0e10cSrcweir 		}
931*cdf0e10cSrcweir 		if( rMEvt.GetClicks() == 2 )
932*cdf0e10cSrcweir 		{
933*cdf0e10cSrcweir 			maDoubleClickHdl.Call( this );
934*cdf0e10cSrcweir 		}
935*cdf0e10cSrcweir 	}
936*cdf0e10cSrcweir 	else // if ( mbGrabFocus )
937*cdf0e10cSrcweir 	{
938*cdf0e10cSrcweir 		GrabFocus();
939*cdf0e10cSrcweir 	}
940*cdf0e10cSrcweir }
941*cdf0e10cSrcweir 
942*cdf0e10cSrcweir // -----------------------------------------------------------------------
943*cdf0e10cSrcweir 
944*cdf0e10cSrcweir void ImplListBoxWindow::MouseMove( const MouseEvent& rMEvt )
945*cdf0e10cSrcweir {
946*cdf0e10cSrcweir     if ( rMEvt.IsLeaveWindow() )
947*cdf0e10cSrcweir     {
948*cdf0e10cSrcweir 		if ( mbStackMode && IsMouseMoveSelect() && IsReallyVisible() )
949*cdf0e10cSrcweir 		{
950*cdf0e10cSrcweir 			if ( rMEvt.GetPosPixel().Y() < 0 )
951*cdf0e10cSrcweir 			{
952*cdf0e10cSrcweir 				DeselectAll();
953*cdf0e10cSrcweir 				mnCurrentPos = LISTBOX_ENTRY_NOTFOUND;
954*cdf0e10cSrcweir                 SetTopEntry( 0 );
955*cdf0e10cSrcweir 				if ( mbStackMode ) // #87072#, #92323#
956*cdf0e10cSrcweir 				{
957*cdf0e10cSrcweir 					mbTravelSelect = sal_True;
958*cdf0e10cSrcweir 					mnSelectModifier = rMEvt.GetModifier();
959*cdf0e10cSrcweir 					ImplCallSelect();
960*cdf0e10cSrcweir 					mbTravelSelect = sal_False;
961*cdf0e10cSrcweir 				}
962*cdf0e10cSrcweir 
963*cdf0e10cSrcweir 			}
964*cdf0e10cSrcweir 		}
965*cdf0e10cSrcweir     }
966*cdf0e10cSrcweir     else if ( ( ( !mbMulti && IsMouseMoveSelect() ) || mbStackMode ) && mpEntryList->GetEntryCount() )
967*cdf0e10cSrcweir 	{
968*cdf0e10cSrcweir 		Point aPoint;
969*cdf0e10cSrcweir 		Rectangle aRect( aPoint, GetOutputSizePixel() );
970*cdf0e10cSrcweir 		if( aRect.IsInside( rMEvt.GetPosPixel() ) )
971*cdf0e10cSrcweir 		{
972*cdf0e10cSrcweir 			if ( IsMouseMoveSelect() )
973*cdf0e10cSrcweir 			{
974*cdf0e10cSrcweir 				sal_uInt16 nSelect = GetEntryPosForPoint( rMEvt.GetPosPixel() );
975*cdf0e10cSrcweir                 if( nSelect == LISTBOX_ENTRY_NOTFOUND )
976*cdf0e10cSrcweir                     nSelect = mpEntryList->GetEntryCount() - 1;
977*cdf0e10cSrcweir 				nSelect = Min( nSelect, GetLastVisibleEntry() );
978*cdf0e10cSrcweir 				nSelect = Min( nSelect, (sal_uInt16) ( mpEntryList->GetEntryCount() - 1 ) );
979*cdf0e10cSrcweir 				// Select only visible Entries with MouseMove, otherwise Tracking...
980*cdf0e10cSrcweir 				if ( IsVisible( nSelect ) &&
981*cdf0e10cSrcweir 					mpEntryList->IsEntrySelectable( nSelect ) &&
982*cdf0e10cSrcweir 					( ( nSelect != mnCurrentPos ) || !GetEntryList()->GetSelectEntryCount() || ( nSelect != GetEntryList()->GetSelectEntryPos( 0 ) ) ) )
983*cdf0e10cSrcweir 				{
984*cdf0e10cSrcweir 					mbTrackingSelect = sal_True;
985*cdf0e10cSrcweir 					if ( SelectEntries( nSelect, LET_TRACKING, sal_False, sal_False ) )
986*cdf0e10cSrcweir 		            {
987*cdf0e10cSrcweir                         if ( mbStackMode ) // #87072#
988*cdf0e10cSrcweir                         {
989*cdf0e10cSrcweir 			                mbTravelSelect = sal_True;
990*cdf0e10cSrcweir 			                mnSelectModifier = rMEvt.GetModifier();
991*cdf0e10cSrcweir 			                ImplCallSelect();
992*cdf0e10cSrcweir 			                mbTravelSelect = sal_False;
993*cdf0e10cSrcweir                         }
994*cdf0e10cSrcweir 		            }
995*cdf0e10cSrcweir 					mbTrackingSelect = sal_False;
996*cdf0e10cSrcweir 				}
997*cdf0e10cSrcweir 			}
998*cdf0e10cSrcweir 
999*cdf0e10cSrcweir 			// Falls der DD-Button gedrueckt wurde und jemand mit gedrueckter
1000*cdf0e10cSrcweir 			// Maustaste in die ListBox faehrt...
1001*cdf0e10cSrcweir 			if ( rMEvt.IsLeft() && !rMEvt.IsSynthetic() )
1002*cdf0e10cSrcweir 			{
1003*cdf0e10cSrcweir 				if ( !mbMulti && GetEntryList()->GetSelectEntryCount() )
1004*cdf0e10cSrcweir 					mnTrackingSaveSelection = GetEntryList()->GetSelectEntryPos( 0 );
1005*cdf0e10cSrcweir 				else
1006*cdf0e10cSrcweir 					mnTrackingSaveSelection = LISTBOX_ENTRY_NOTFOUND;
1007*cdf0e10cSrcweir 
1008*cdf0e10cSrcweir 				if ( mbStackMode && ( mpEntryList->GetSelectionAnchor() == LISTBOX_ENTRY_NOTFOUND ) )
1009*cdf0e10cSrcweir 					mpEntryList->SetSelectionAnchor( 0 );
1010*cdf0e10cSrcweir 
1011*cdf0e10cSrcweir 				StartTracking( STARTTRACK_SCROLLREPEAT );
1012*cdf0e10cSrcweir 			}
1013*cdf0e10cSrcweir 		}
1014*cdf0e10cSrcweir 	}
1015*cdf0e10cSrcweir }
1016*cdf0e10cSrcweir 
1017*cdf0e10cSrcweir // -----------------------------------------------------------------------
1018*cdf0e10cSrcweir 
1019*cdf0e10cSrcweir void ImplListBoxWindow::DeselectAll()
1020*cdf0e10cSrcweir {
1021*cdf0e10cSrcweir 	while ( GetEntryList()->GetSelectEntryCount() )
1022*cdf0e10cSrcweir 	{
1023*cdf0e10cSrcweir 		sal_uInt16 nS = GetEntryList()->GetSelectEntryPos( 0 );
1024*cdf0e10cSrcweir 		SelectEntry( nS, sal_False );
1025*cdf0e10cSrcweir 	}
1026*cdf0e10cSrcweir }
1027*cdf0e10cSrcweir 
1028*cdf0e10cSrcweir // -----------------------------------------------------------------------
1029*cdf0e10cSrcweir 
1030*cdf0e10cSrcweir void ImplListBoxWindow::SelectEntry( sal_uInt16 nPos, sal_Bool bSelect )
1031*cdf0e10cSrcweir {
1032*cdf0e10cSrcweir 	if( (mpEntryList->IsEntryPosSelected( nPos ) != bSelect) && mpEntryList->IsEntrySelectable( nPos ) )
1033*cdf0e10cSrcweir 	{
1034*cdf0e10cSrcweir 		ImplHideFocusRect();
1035*cdf0e10cSrcweir 		if( bSelect )
1036*cdf0e10cSrcweir 		{
1037*cdf0e10cSrcweir 			if( !mbMulti )
1038*cdf0e10cSrcweir 			{
1039*cdf0e10cSrcweir 				// Selektierten Eintrag deselektieren
1040*cdf0e10cSrcweir 				sal_uInt16 nDeselect = GetEntryList()->GetSelectEntryPos( 0 );
1041*cdf0e10cSrcweir 				if( nDeselect != LISTBOX_ENTRY_NOTFOUND )
1042*cdf0e10cSrcweir 				{
1043*cdf0e10cSrcweir 					//SelectEntryPos( nDeselect, sal_False );
1044*cdf0e10cSrcweir 					GetEntryList()->SelectEntry( nDeselect, sal_False );
1045*cdf0e10cSrcweir 					if ( IsUpdateMode() && IsReallyVisible() )
1046*cdf0e10cSrcweir 						ImplPaint( nDeselect, sal_True );
1047*cdf0e10cSrcweir 				}
1048*cdf0e10cSrcweir 			}
1049*cdf0e10cSrcweir 			mpEntryList->SelectEntry( nPos, sal_True );
1050*cdf0e10cSrcweir 			mnCurrentPos = nPos;
1051*cdf0e10cSrcweir 			if ( ( nPos != LISTBOX_ENTRY_NOTFOUND ) && IsUpdateMode() )
1052*cdf0e10cSrcweir 			{
1053*cdf0e10cSrcweir 				ImplPaint( nPos );
1054*cdf0e10cSrcweir 				if ( !IsVisible( nPos ) )
1055*cdf0e10cSrcweir                 {
1056*cdf0e10cSrcweir                     ImplClearLayoutData();
1057*cdf0e10cSrcweir                     sal_uInt16 nVisibleEntries = GetLastVisibleEntry()-mnTop;
1058*cdf0e10cSrcweir                     if ( !nVisibleEntries || !IsReallyVisible() || ( nPos < GetTopEntry() ) )
1059*cdf0e10cSrcweir                     {
1060*cdf0e10cSrcweir                         Resize();
1061*cdf0e10cSrcweir 					    ShowProminentEntry( nPos );
1062*cdf0e10cSrcweir                     }
1063*cdf0e10cSrcweir                     else
1064*cdf0e10cSrcweir                     {
1065*cdf0e10cSrcweir                         ShowProminentEntry( nPos );
1066*cdf0e10cSrcweir                     }
1067*cdf0e10cSrcweir                 }
1068*cdf0e10cSrcweir 			}
1069*cdf0e10cSrcweir 		}
1070*cdf0e10cSrcweir 		else
1071*cdf0e10cSrcweir 		{
1072*cdf0e10cSrcweir 			mpEntryList->SelectEntry( nPos, sal_False );
1073*cdf0e10cSrcweir 			ImplPaint( nPos, sal_True );
1074*cdf0e10cSrcweir 		}
1075*cdf0e10cSrcweir 		mbSelectionChanged = sal_True;
1076*cdf0e10cSrcweir 	}
1077*cdf0e10cSrcweir }
1078*cdf0e10cSrcweir 
1079*cdf0e10cSrcweir // -----------------------------------------------------------------------
1080*cdf0e10cSrcweir 
1081*cdf0e10cSrcweir sal_Bool ImplListBoxWindow::SelectEntries( sal_uInt16 nSelect, LB_EVENT_TYPE eLET, sal_Bool bShift, sal_Bool bCtrl )
1082*cdf0e10cSrcweir {
1083*cdf0e10cSrcweir 	sal_Bool bFocusChanged = sal_False;
1084*cdf0e10cSrcweir 	sal_Bool bSelectionChanged = sal_False;
1085*cdf0e10cSrcweir 
1086*cdf0e10cSrcweir 	if( IsEnabled() && mpEntryList->IsEntrySelectable( nSelect ) )
1087*cdf0e10cSrcweir 	{
1088*cdf0e10cSrcweir 		// Hier (Single-ListBox) kann nur ein Eintrag deselektiert werden
1089*cdf0e10cSrcweir 		if( !mbMulti )
1090*cdf0e10cSrcweir 		{
1091*cdf0e10cSrcweir 			sal_uInt16 nDeselect = mpEntryList->GetSelectEntryPos( 0 );
1092*cdf0e10cSrcweir 			if( nSelect != nDeselect )
1093*cdf0e10cSrcweir 			{
1094*cdf0e10cSrcweir 				SelectEntry( nSelect, sal_True );
1095*cdf0e10cSrcweir 				mpEntryList->SetLastSelected( nSelect );
1096*cdf0e10cSrcweir 				bFocusChanged = sal_True;
1097*cdf0e10cSrcweir 				bSelectionChanged = sal_True;
1098*cdf0e10cSrcweir 			}
1099*cdf0e10cSrcweir 		}
1100*cdf0e10cSrcweir 		// MultiListBox ohne Modifier
1101*cdf0e10cSrcweir 		else if( mbSimpleMode && !bCtrl && !bShift )
1102*cdf0e10cSrcweir 		{
1103*cdf0e10cSrcweir 			sal_uInt16 nEntryCount = mpEntryList->GetEntryCount();
1104*cdf0e10cSrcweir 			for ( sal_uInt16 nPos = 0; nPos < nEntryCount; nPos++ )
1105*cdf0e10cSrcweir 			{
1106*cdf0e10cSrcweir 				sal_Bool bSelect = nPos == nSelect;
1107*cdf0e10cSrcweir 				if ( mpEntryList->IsEntryPosSelected( nPos ) != bSelect )
1108*cdf0e10cSrcweir 				{
1109*cdf0e10cSrcweir 					SelectEntry( nPos, bSelect );
1110*cdf0e10cSrcweir 					bFocusChanged = sal_True;
1111*cdf0e10cSrcweir 					bSelectionChanged = sal_True;
1112*cdf0e10cSrcweir 				}
1113*cdf0e10cSrcweir 			}
1114*cdf0e10cSrcweir 			mpEntryList->SetLastSelected( nSelect );
1115*cdf0e10cSrcweir 			mpEntryList->SetSelectionAnchor( nSelect );
1116*cdf0e10cSrcweir 		}
1117*cdf0e10cSrcweir 		// MultiListBox nur mit CTRL/SHIFT oder nicht im SimpleMode
1118*cdf0e10cSrcweir 		else if( ( !mbSimpleMode /* && !bShift */ ) || ( (mbSimpleMode && ( bCtrl || bShift )) || mbStackMode ) )
1119*cdf0e10cSrcweir 		{
1120*cdf0e10cSrcweir 			// Space fuer Selektionswechsel
1121*cdf0e10cSrcweir 			if( !bShift && ( ( eLET == LET_KEYSPACE ) || ( eLET == LET_MBDOWN ) ) )
1122*cdf0e10cSrcweir 			{
1123*cdf0e10cSrcweir 				sal_Bool bSelect = ( mbStackMode && IsMouseMoveSelect() ) ? sal_True : !mpEntryList->IsEntryPosSelected( nSelect );
1124*cdf0e10cSrcweir 				if ( mbStackMode )
1125*cdf0e10cSrcweir 				{
1126*cdf0e10cSrcweir 					sal_uInt16 n;
1127*cdf0e10cSrcweir 					if ( bSelect )
1128*cdf0e10cSrcweir 					{
1129*cdf0e10cSrcweir 						// All entries before nSelect must be selected...
1130*cdf0e10cSrcweir 						for ( n = 0; n < nSelect; n++ )
1131*cdf0e10cSrcweir 							SelectEntry( n, sal_True );
1132*cdf0e10cSrcweir 					}
1133*cdf0e10cSrcweir 					if ( !bSelect )
1134*cdf0e10cSrcweir 					{
1135*cdf0e10cSrcweir 						for ( n = nSelect+1; n < mpEntryList->GetEntryCount(); n++ )
1136*cdf0e10cSrcweir 							SelectEntry( n, sal_False );
1137*cdf0e10cSrcweir 					}
1138*cdf0e10cSrcweir 				}
1139*cdf0e10cSrcweir 				SelectEntry( nSelect, bSelect );
1140*cdf0e10cSrcweir 				mpEntryList->SetLastSelected( nSelect );
1141*cdf0e10cSrcweir 				mpEntryList->SetSelectionAnchor( mbStackMode ? 0 : nSelect );
1142*cdf0e10cSrcweir 				if ( !mpEntryList->IsEntryPosSelected( nSelect ) )
1143*cdf0e10cSrcweir 					mpEntryList->SetSelectionAnchor( LISTBOX_ENTRY_NOTFOUND );
1144*cdf0e10cSrcweir 				bFocusChanged = sal_True;
1145*cdf0e10cSrcweir 				bSelectionChanged = sal_True;
1146*cdf0e10cSrcweir 			}
1147*cdf0e10cSrcweir 			else if( ( ( eLET == LET_TRACKING ) && ( nSelect != mnCurrentPos ) ) ||
1148*cdf0e10cSrcweir 					 ( (bShift||mbStackMode) && ( ( eLET == LET_KEYMOVE ) || ( eLET == LET_MBDOWN ) ) ) )
1149*cdf0e10cSrcweir 			{
1150*cdf0e10cSrcweir 				mnCurrentPos = nSelect;
1151*cdf0e10cSrcweir 				bFocusChanged = sal_True;
1152*cdf0e10cSrcweir 
1153*cdf0e10cSrcweir 				sal_uInt16 nAnchor = mpEntryList->GetSelectionAnchor();
1154*cdf0e10cSrcweir 				if( ( nAnchor == LISTBOX_ENTRY_NOTFOUND ) && ( mpEntryList->GetSelectEntryCount() || mbStackMode ) )
1155*cdf0e10cSrcweir 				{
1156*cdf0e10cSrcweir 					nAnchor = mbStackMode ? 0 : mpEntryList->GetSelectEntryPos( mpEntryList->GetSelectEntryCount() - 1 );
1157*cdf0e10cSrcweir 				}
1158*cdf0e10cSrcweir 				if( nAnchor != LISTBOX_ENTRY_NOTFOUND )
1159*cdf0e10cSrcweir 				{
1160*cdf0e10cSrcweir 					// Alle Eintraege vom Anchor bis nSelect muessen selektiert sein
1161*cdf0e10cSrcweir 					sal_uInt16 nStart = Min( nSelect, nAnchor );
1162*cdf0e10cSrcweir 					sal_uInt16 nEnd = Max( nSelect, nAnchor );
1163*cdf0e10cSrcweir 					for ( sal_uInt16 n = nStart; n <= nEnd; n++ )
1164*cdf0e10cSrcweir 					{
1165*cdf0e10cSrcweir 						if ( !mpEntryList->IsEntryPosSelected( n ) )
1166*cdf0e10cSrcweir 						{
1167*cdf0e10cSrcweir 							SelectEntry( n, sal_True );
1168*cdf0e10cSrcweir 							bSelectionChanged = sal_True;
1169*cdf0e10cSrcweir 						}
1170*cdf0e10cSrcweir 					}
1171*cdf0e10cSrcweir 
1172*cdf0e10cSrcweir 					// Ggf. muss noch was deselektiert werden...
1173*cdf0e10cSrcweir 					sal_uInt16 nLast = mpEntryList->GetLastSelected();
1174*cdf0e10cSrcweir 					if ( nLast != LISTBOX_ENTRY_NOTFOUND )
1175*cdf0e10cSrcweir 					{
1176*cdf0e10cSrcweir 						if ( ( nLast > nSelect ) && ( nLast > nAnchor ) )
1177*cdf0e10cSrcweir 						{
1178*cdf0e10cSrcweir 							for ( sal_uInt16 n = nSelect+1; n <= nLast; n++ )
1179*cdf0e10cSrcweir 							{
1180*cdf0e10cSrcweir 								if ( mpEntryList->IsEntryPosSelected( n ) )
1181*cdf0e10cSrcweir 								{
1182*cdf0e10cSrcweir 									SelectEntry( n, sal_False );
1183*cdf0e10cSrcweir 									bSelectionChanged = sal_True;
1184*cdf0e10cSrcweir 								}
1185*cdf0e10cSrcweir 							}
1186*cdf0e10cSrcweir 						}
1187*cdf0e10cSrcweir 						else if ( ( nLast < nSelect ) && ( nLast < nAnchor ) )
1188*cdf0e10cSrcweir 						{
1189*cdf0e10cSrcweir 							for ( sal_uInt16 n = nLast; n < nSelect; n++ )
1190*cdf0e10cSrcweir 							{
1191*cdf0e10cSrcweir 								if ( mpEntryList->IsEntryPosSelected( n ) )
1192*cdf0e10cSrcweir 								{
1193*cdf0e10cSrcweir 									SelectEntry( n, sal_False );
1194*cdf0e10cSrcweir 									bSelectionChanged = sal_True;
1195*cdf0e10cSrcweir 								}
1196*cdf0e10cSrcweir 							}
1197*cdf0e10cSrcweir 						}
1198*cdf0e10cSrcweir 					}
1199*cdf0e10cSrcweir 					mpEntryList->SetLastSelected( nSelect );
1200*cdf0e10cSrcweir 				}
1201*cdf0e10cSrcweir 			}
1202*cdf0e10cSrcweir 			else if( eLET != LET_TRACKING )
1203*cdf0e10cSrcweir 			{
1204*cdf0e10cSrcweir 				ImplHideFocusRect();
1205*cdf0e10cSrcweir 				ImplPaint( nSelect, sal_True );
1206*cdf0e10cSrcweir 				bFocusChanged = sal_True;
1207*cdf0e10cSrcweir 			}
1208*cdf0e10cSrcweir 		}
1209*cdf0e10cSrcweir 		else if( bShift )
1210*cdf0e10cSrcweir 		{
1211*cdf0e10cSrcweir 			bFocusChanged = sal_True;
1212*cdf0e10cSrcweir 		}
1213*cdf0e10cSrcweir 
1214*cdf0e10cSrcweir 		if( bSelectionChanged )
1215*cdf0e10cSrcweir 			mbSelectionChanged = sal_True;
1216*cdf0e10cSrcweir 
1217*cdf0e10cSrcweir 		if( bFocusChanged )
1218*cdf0e10cSrcweir 		{
1219*cdf0e10cSrcweir             long nHeightDiff = mpEntryList->GetAddedHeight( nSelect, mnTop, 0 );
1220*cdf0e10cSrcweir 			maFocusRect.SetPos( Point( 0, nHeightDiff ) );
1221*cdf0e10cSrcweir             Size aSz( maFocusRect.GetWidth(),
1222*cdf0e10cSrcweir                       mpEntryList->GetEntryHeight( nSelect ) );
1223*cdf0e10cSrcweir             maFocusRect.SetSize( aSz );
1224*cdf0e10cSrcweir 			if( HasFocus() )
1225*cdf0e10cSrcweir 				ImplShowFocusRect();
1226*cdf0e10cSrcweir 		}
1227*cdf0e10cSrcweir         ImplClearLayoutData();
1228*cdf0e10cSrcweir 	}
1229*cdf0e10cSrcweir 	return bSelectionChanged;
1230*cdf0e10cSrcweir }
1231*cdf0e10cSrcweir 
1232*cdf0e10cSrcweir // -----------------------------------------------------------------------
1233*cdf0e10cSrcweir 
1234*cdf0e10cSrcweir void ImplListBoxWindow::Tracking( const TrackingEvent& rTEvt )
1235*cdf0e10cSrcweir {
1236*cdf0e10cSrcweir 	Point aPoint;
1237*cdf0e10cSrcweir 	Rectangle aRect( aPoint, GetOutputSizePixel() );
1238*cdf0e10cSrcweir 	sal_Bool bInside = aRect.IsInside( rTEvt.GetMouseEvent().GetPosPixel() );
1239*cdf0e10cSrcweir 
1240*cdf0e10cSrcweir 	if( rTEvt.IsTrackingCanceled() || rTEvt.IsTrackingEnded() ) // MouseButtonUp
1241*cdf0e10cSrcweir 	{
1242*cdf0e10cSrcweir 		if ( bInside && !rTEvt.IsTrackingCanceled() )
1243*cdf0e10cSrcweir 		{
1244*cdf0e10cSrcweir 			mnSelectModifier = rTEvt.GetMouseEvent().GetModifier();
1245*cdf0e10cSrcweir 			ImplCallSelect();
1246*cdf0e10cSrcweir 		}
1247*cdf0e10cSrcweir 		else
1248*cdf0e10cSrcweir 		{
1249*cdf0e10cSrcweir 			maCancelHdl.Call( NULL );
1250*cdf0e10cSrcweir 			if ( !mbMulti )
1251*cdf0e10cSrcweir 			{
1252*cdf0e10cSrcweir 				mbTrackingSelect = sal_True;
1253*cdf0e10cSrcweir 				SelectEntry( mnTrackingSaveSelection, sal_True );
1254*cdf0e10cSrcweir 				mbTrackingSelect = sal_False;
1255*cdf0e10cSrcweir 				if ( mnTrackingSaveSelection != LISTBOX_ENTRY_NOTFOUND )
1256*cdf0e10cSrcweir 				{
1257*cdf0e10cSrcweir                     long nHeightDiff = mpEntryList->GetAddedHeight( mnCurrentPos, mnTop, 0 );
1258*cdf0e10cSrcweir 					maFocusRect.SetPos( Point( 0, nHeightDiff ) );
1259*cdf0e10cSrcweir                     Size aSz( maFocusRect.GetWidth(),
1260*cdf0e10cSrcweir                               mpEntryList->GetEntryHeight( mnCurrentPos ) );
1261*cdf0e10cSrcweir                     maFocusRect.SetSize( aSz );
1262*cdf0e10cSrcweir 					ImplShowFocusRect();
1263*cdf0e10cSrcweir 				}
1264*cdf0e10cSrcweir 			}
1265*cdf0e10cSrcweir 		}
1266*cdf0e10cSrcweir 
1267*cdf0e10cSrcweir 		mbTrack = sal_False;
1268*cdf0e10cSrcweir 	}
1269*cdf0e10cSrcweir 	else
1270*cdf0e10cSrcweir 	{
1271*cdf0e10cSrcweir 		sal_Bool bTrackOrQuickClick = mbTrack;
1272*cdf0e10cSrcweir 		if( !mbTrack )
1273*cdf0e10cSrcweir 		{
1274*cdf0e10cSrcweir 			if ( bInside )
1275*cdf0e10cSrcweir 			{
1276*cdf0e10cSrcweir 				mbTrack = sal_True;
1277*cdf0e10cSrcweir 			}
1278*cdf0e10cSrcweir 
1279*cdf0e10cSrcweir 			// Folgender Fall tritt nur auf, wenn man ganz kurz die Maustaste drueckt
1280*cdf0e10cSrcweir 			if( rTEvt.IsTrackingEnded() && mbTrack )
1281*cdf0e10cSrcweir 			{
1282*cdf0e10cSrcweir 				bTrackOrQuickClick = sal_True;
1283*cdf0e10cSrcweir 				mbTrack = sal_False;
1284*cdf0e10cSrcweir 			}
1285*cdf0e10cSrcweir 		}
1286*cdf0e10cSrcweir 
1287*cdf0e10cSrcweir 		if( bTrackOrQuickClick )
1288*cdf0e10cSrcweir 		{
1289*cdf0e10cSrcweir 			MouseEvent aMEvt = rTEvt.GetMouseEvent();
1290*cdf0e10cSrcweir 			Point aPt( aMEvt.GetPosPixel() );
1291*cdf0e10cSrcweir 			sal_Bool bShift = aMEvt.IsShift();
1292*cdf0e10cSrcweir 			sal_Bool bCtrl	= aMEvt.IsMod1();
1293*cdf0e10cSrcweir 
1294*cdf0e10cSrcweir 			sal_uInt16 nSelect = LISTBOX_ENTRY_NOTFOUND;
1295*cdf0e10cSrcweir 			if( aPt.Y() < 0 )
1296*cdf0e10cSrcweir 			{
1297*cdf0e10cSrcweir                 if ( mnCurrentPos != LISTBOX_ENTRY_NOTFOUND )
1298*cdf0e10cSrcweir                 {
1299*cdf0e10cSrcweir 				    nSelect = mnCurrentPos ? ( mnCurrentPos - 1 ) : 0;
1300*cdf0e10cSrcweir 				    if( nSelect < mnTop )
1301*cdf0e10cSrcweir 					    SetTopEntry( mnTop-1 );
1302*cdf0e10cSrcweir                 }
1303*cdf0e10cSrcweir 			}
1304*cdf0e10cSrcweir 			else if( aPt.Y() > GetOutputSizePixel().Height() )
1305*cdf0e10cSrcweir 			{
1306*cdf0e10cSrcweir                 if ( mnCurrentPos != LISTBOX_ENTRY_NOTFOUND )
1307*cdf0e10cSrcweir                 {
1308*cdf0e10cSrcweir 				    nSelect = Min(	(sal_uInt16)(mnCurrentPos+1), (sal_uInt16)(mpEntryList->GetEntryCount()-1) );
1309*cdf0e10cSrcweir 				    if( nSelect >= GetLastVisibleEntry() )
1310*cdf0e10cSrcweir 					    SetTopEntry( mnTop+1 );
1311*cdf0e10cSrcweir                 }
1312*cdf0e10cSrcweir 			}
1313*cdf0e10cSrcweir 			else
1314*cdf0e10cSrcweir 			{
1315*cdf0e10cSrcweir 				nSelect = (sal_uInt16) ( ( aPt.Y() + mnBorder ) / mnMaxHeight ) + (sal_uInt16) mnTop;
1316*cdf0e10cSrcweir 				nSelect = Min( nSelect, GetLastVisibleEntry() );
1317*cdf0e10cSrcweir 				nSelect = Min( nSelect, (sal_uInt16) ( mpEntryList->GetEntryCount() - 1 ) );
1318*cdf0e10cSrcweir 			}
1319*cdf0e10cSrcweir 
1320*cdf0e10cSrcweir 			if ( bInside )
1321*cdf0e10cSrcweir 			{
1322*cdf0e10cSrcweir 				if ( ( nSelect != mnCurrentPos ) || !GetEntryList()->GetSelectEntryCount() )
1323*cdf0e10cSrcweir 				{
1324*cdf0e10cSrcweir 					mbTrackingSelect = sal_True;
1325*cdf0e10cSrcweir 					if ( SelectEntries( nSelect, LET_TRACKING, bShift, bCtrl ) )
1326*cdf0e10cSrcweir 		            {
1327*cdf0e10cSrcweir                         if ( mbStackMode ) // #87734# (#87072#)
1328*cdf0e10cSrcweir                         {
1329*cdf0e10cSrcweir 			                mbTravelSelect = sal_True;
1330*cdf0e10cSrcweir 			                mnSelectModifier = rTEvt.GetMouseEvent().GetModifier();
1331*cdf0e10cSrcweir 			                ImplCallSelect();
1332*cdf0e10cSrcweir 			                mbTravelSelect = sal_False;
1333*cdf0e10cSrcweir                         }
1334*cdf0e10cSrcweir 		            }
1335*cdf0e10cSrcweir 					mbTrackingSelect = sal_False;
1336*cdf0e10cSrcweir 				}
1337*cdf0e10cSrcweir 			}
1338*cdf0e10cSrcweir 			else
1339*cdf0e10cSrcweir 			{
1340*cdf0e10cSrcweir 				if ( !mbMulti && GetEntryList()->GetSelectEntryCount() )
1341*cdf0e10cSrcweir 				{
1342*cdf0e10cSrcweir 					mbTrackingSelect = sal_True;
1343*cdf0e10cSrcweir 					SelectEntry( GetEntryList()->GetSelectEntryPos( 0 ), sal_False );
1344*cdf0e10cSrcweir 					mbTrackingSelect = sal_False;
1345*cdf0e10cSrcweir 				}
1346*cdf0e10cSrcweir 				else if ( mbStackMode )
1347*cdf0e10cSrcweir                 {
1348*cdf0e10cSrcweir                     if ( ( rTEvt.GetMouseEvent().GetPosPixel().X() > 0 )  && ( rTEvt.GetMouseEvent().GetPosPixel().X() < aRect.Right() ) )
1349*cdf0e10cSrcweir                     {
1350*cdf0e10cSrcweir 				        if ( ( rTEvt.GetMouseEvent().GetPosPixel().Y() < 0 ) || ( rTEvt.GetMouseEvent().GetPosPixel().Y() > GetOutputSizePixel().Height() ) )
1351*cdf0e10cSrcweir 				        {
1352*cdf0e10cSrcweir                             sal_Bool bSelectionChanged = sal_False;
1353*cdf0e10cSrcweir                             if ( ( rTEvt.GetMouseEvent().GetPosPixel().Y() < 0 )
1354*cdf0e10cSrcweir                                    && !mnCurrentPos )
1355*cdf0e10cSrcweir                             {
1356*cdf0e10cSrcweir                                 if ( mpEntryList->IsEntryPosSelected( 0 ) )
1357*cdf0e10cSrcweir                                 {
1358*cdf0e10cSrcweir 					                SelectEntry( 0, sal_False );
1359*cdf0e10cSrcweir                                     bSelectionChanged = sal_True;
1360*cdf0e10cSrcweir                                     nSelect = LISTBOX_ENTRY_NOTFOUND;
1361*cdf0e10cSrcweir 
1362*cdf0e10cSrcweir                                 }
1363*cdf0e10cSrcweir                             }
1364*cdf0e10cSrcweir                             else
1365*cdf0e10cSrcweir                             {
1366*cdf0e10cSrcweir 					            mbTrackingSelect = sal_True;
1367*cdf0e10cSrcweir                                 bSelectionChanged = SelectEntries( nSelect, LET_TRACKING, bShift, bCtrl );
1368*cdf0e10cSrcweir 					            mbTrackingSelect = sal_False;
1369*cdf0e10cSrcweir                             }
1370*cdf0e10cSrcweir 
1371*cdf0e10cSrcweir                             if ( bSelectionChanged )
1372*cdf0e10cSrcweir 		                    {
1373*cdf0e10cSrcweir                                 mbSelectionChanged = sal_True;
1374*cdf0e10cSrcweir 			                    mbTravelSelect = sal_True;
1375*cdf0e10cSrcweir 			                    mnSelectModifier = rTEvt.GetMouseEvent().GetModifier();
1376*cdf0e10cSrcweir 			                    ImplCallSelect();
1377*cdf0e10cSrcweir 			                    mbTravelSelect = sal_False;
1378*cdf0e10cSrcweir 		                    }
1379*cdf0e10cSrcweir 				        }
1380*cdf0e10cSrcweir                     }
1381*cdf0e10cSrcweir                 }
1382*cdf0e10cSrcweir 			}
1383*cdf0e10cSrcweir 			mnCurrentPos = nSelect;
1384*cdf0e10cSrcweir             if ( mnCurrentPos == LISTBOX_ENTRY_NOTFOUND )
1385*cdf0e10cSrcweir             {
1386*cdf0e10cSrcweir                 ImplHideFocusRect();
1387*cdf0e10cSrcweir             }
1388*cdf0e10cSrcweir             else
1389*cdf0e10cSrcweir             {
1390*cdf0e10cSrcweir                 long nHeightDiff = mpEntryList->GetAddedHeight( mnCurrentPos, mnTop, 0 );
1391*cdf0e10cSrcweir 				maFocusRect.SetPos( Point( 0, nHeightDiff ) );
1392*cdf0e10cSrcweir                 Size aSz( maFocusRect.GetWidth(), mpEntryList->GetEntryHeight( mnCurrentPos ) );
1393*cdf0e10cSrcweir                 maFocusRect.SetSize( aSz );
1394*cdf0e10cSrcweir 				ImplShowFocusRect();
1395*cdf0e10cSrcweir             }
1396*cdf0e10cSrcweir 		}
1397*cdf0e10cSrcweir 	}
1398*cdf0e10cSrcweir }
1399*cdf0e10cSrcweir 
1400*cdf0e10cSrcweir 
1401*cdf0e10cSrcweir // -----------------------------------------------------------------------
1402*cdf0e10cSrcweir 
1403*cdf0e10cSrcweir void ImplListBoxWindow::KeyInput( const KeyEvent& rKEvt )
1404*cdf0e10cSrcweir {
1405*cdf0e10cSrcweir 	if( !ProcessKeyInput( rKEvt ) )
1406*cdf0e10cSrcweir 		Control::KeyInput( rKEvt );
1407*cdf0e10cSrcweir }
1408*cdf0e10cSrcweir 
1409*cdf0e10cSrcweir // -----------------------------------------------------------------------
1410*cdf0e10cSrcweir 
1411*cdf0e10cSrcweir #define IMPL_SELECT_NODIRECTION	0
1412*cdf0e10cSrcweir #define IMPL_SELECT_UP			1
1413*cdf0e10cSrcweir #define IMPL_SELECT_DOWN		2
1414*cdf0e10cSrcweir 
1415*cdf0e10cSrcweir sal_Bool ImplListBoxWindow::ProcessKeyInput( const KeyEvent& rKEvt )
1416*cdf0e10cSrcweir {
1417*cdf0e10cSrcweir 	// zu selektierender Eintrag
1418*cdf0e10cSrcweir 	sal_uInt16 nSelect = LISTBOX_ENTRY_NOTFOUND;
1419*cdf0e10cSrcweir 	LB_EVENT_TYPE eLET = LET_KEYMOVE;
1420*cdf0e10cSrcweir 
1421*cdf0e10cSrcweir 	KeyCode aKeyCode = rKEvt.GetKeyCode();
1422*cdf0e10cSrcweir 
1423*cdf0e10cSrcweir 	sal_Bool bShift = aKeyCode.IsShift();
1424*cdf0e10cSrcweir 	sal_Bool bCtrl	= aKeyCode.IsMod1() || aKeyCode.IsMod3();
1425*cdf0e10cSrcweir 	sal_Bool bMod2 = aKeyCode.IsMod2();
1426*cdf0e10cSrcweir 	sal_Bool bDone = sal_False;
1427*cdf0e10cSrcweir 
1428*cdf0e10cSrcweir 	switch( aKeyCode.GetCode() )
1429*cdf0e10cSrcweir 	{
1430*cdf0e10cSrcweir 		case KEY_UP:
1431*cdf0e10cSrcweir 		{
1432*cdf0e10cSrcweir 			if ( IsReadOnly() )
1433*cdf0e10cSrcweir 			{
1434*cdf0e10cSrcweir 				if ( GetTopEntry() )
1435*cdf0e10cSrcweir 					SetTopEntry( GetTopEntry()-1 );
1436*cdf0e10cSrcweir 			}
1437*cdf0e10cSrcweir 			else if ( !bMod2 )
1438*cdf0e10cSrcweir 			{
1439*cdf0e10cSrcweir 				if( mnCurrentPos == LISTBOX_ENTRY_NOTFOUND )
1440*cdf0e10cSrcweir 				{
1441*cdf0e10cSrcweir 					nSelect = mpEntryList->FindFirstSelectable( 0, true );
1442*cdf0e10cSrcweir 				}
1443*cdf0e10cSrcweir 				else if ( mnCurrentPos )
1444*cdf0e10cSrcweir 				{
1445*cdf0e10cSrcweir 					// search first selectable above the current position
1446*cdf0e10cSrcweir 					nSelect = mpEntryList->FindFirstSelectable( mnCurrentPos - 1, false );
1447*cdf0e10cSrcweir 				}
1448*cdf0e10cSrcweir 
1449*cdf0e10cSrcweir 				if( ( nSelect != LISTBOX_ENTRY_NOTFOUND ) && ( nSelect < mnTop ) )
1450*cdf0e10cSrcweir 					SetTopEntry( mnTop-1 );
1451*cdf0e10cSrcweir 
1452*cdf0e10cSrcweir 				bDone = sal_True;
1453*cdf0e10cSrcweir 			}
1454*cdf0e10cSrcweir             maQuickSelectionEngine.Reset();
1455*cdf0e10cSrcweir 		}
1456*cdf0e10cSrcweir 		break;
1457*cdf0e10cSrcweir 
1458*cdf0e10cSrcweir 		case KEY_DOWN:
1459*cdf0e10cSrcweir 		{
1460*cdf0e10cSrcweir 			if ( IsReadOnly() )
1461*cdf0e10cSrcweir 			{
1462*cdf0e10cSrcweir 				SetTopEntry( GetTopEntry()+1 );
1463*cdf0e10cSrcweir 			}
1464*cdf0e10cSrcweir 			else if ( !bMod2 )
1465*cdf0e10cSrcweir 			{
1466*cdf0e10cSrcweir 				if( mnCurrentPos == LISTBOX_ENTRY_NOTFOUND )
1467*cdf0e10cSrcweir 				{
1468*cdf0e10cSrcweir 					nSelect = mpEntryList->FindFirstSelectable( 0, true );
1469*cdf0e10cSrcweir 				}
1470*cdf0e10cSrcweir 				else if ( (mnCurrentPos+1) < mpEntryList->GetEntryCount() )
1471*cdf0e10cSrcweir 				{
1472*cdf0e10cSrcweir 					// search first selectable below the current position
1473*cdf0e10cSrcweir 					nSelect = mpEntryList->FindFirstSelectable( mnCurrentPos + 1, true );
1474*cdf0e10cSrcweir 				}
1475*cdf0e10cSrcweir 
1476*cdf0e10cSrcweir 				if( ( nSelect != LISTBOX_ENTRY_NOTFOUND ) && ( nSelect >= GetLastVisibleEntry() ) )
1477*cdf0e10cSrcweir 					SetTopEntry( mnTop+1 );
1478*cdf0e10cSrcweir 
1479*cdf0e10cSrcweir 				bDone = sal_True;
1480*cdf0e10cSrcweir 			}
1481*cdf0e10cSrcweir 			maQuickSelectionEngine.Reset();
1482*cdf0e10cSrcweir 		}
1483*cdf0e10cSrcweir 		break;
1484*cdf0e10cSrcweir 
1485*cdf0e10cSrcweir 		case KEY_PAGEUP:
1486*cdf0e10cSrcweir 		{
1487*cdf0e10cSrcweir 			if ( IsReadOnly() )
1488*cdf0e10cSrcweir 			{
1489*cdf0e10cSrcweir                 sal_uInt16 nCurVis = GetLastVisibleEntry() - mnTop +1;
1490*cdf0e10cSrcweir 				SetTopEntry( ( mnTop > nCurVis ) ?
1491*cdf0e10cSrcweir 								(mnTop-nCurVis) : 0 );
1492*cdf0e10cSrcweir 			}
1493*cdf0e10cSrcweir 			else if ( !bCtrl && !bMod2 )
1494*cdf0e10cSrcweir 			{
1495*cdf0e10cSrcweir 				if( mnCurrentPos == LISTBOX_ENTRY_NOTFOUND )
1496*cdf0e10cSrcweir 				{
1497*cdf0e10cSrcweir 					nSelect = mpEntryList->FindFirstSelectable( 0, true );
1498*cdf0e10cSrcweir 				}
1499*cdf0e10cSrcweir 				else if ( mnCurrentPos )
1500*cdf0e10cSrcweir 				{
1501*cdf0e10cSrcweir 					if( mnCurrentPos == mnTop )
1502*cdf0e10cSrcweir                     {
1503*cdf0e10cSrcweir                         sal_uInt16 nCurVis = GetLastVisibleEntry() - mnTop +1;
1504*cdf0e10cSrcweir 						SetTopEntry( ( mnTop > nCurVis ) ? ( mnTop-nCurVis+1 ) : 0 );
1505*cdf0e10cSrcweir                     }
1506*cdf0e10cSrcweir 
1507*cdf0e10cSrcweir 					// find first selectable starting from mnTop looking foreward
1508*cdf0e10cSrcweir 					nSelect = mpEntryList->FindFirstSelectable( mnTop, true );
1509*cdf0e10cSrcweir 				}
1510*cdf0e10cSrcweir 				bDone = sal_True;
1511*cdf0e10cSrcweir 			}
1512*cdf0e10cSrcweir 			maQuickSelectionEngine.Reset();
1513*cdf0e10cSrcweir 		}
1514*cdf0e10cSrcweir 		break;
1515*cdf0e10cSrcweir 
1516*cdf0e10cSrcweir 		case KEY_PAGEDOWN:
1517*cdf0e10cSrcweir 		{
1518*cdf0e10cSrcweir 			if ( IsReadOnly() )
1519*cdf0e10cSrcweir 			{
1520*cdf0e10cSrcweir 				SetTopEntry( GetLastVisibleEntry() );
1521*cdf0e10cSrcweir 			}
1522*cdf0e10cSrcweir 			else if ( !bCtrl && !bMod2 )
1523*cdf0e10cSrcweir 			{
1524*cdf0e10cSrcweir 				if( mnCurrentPos == LISTBOX_ENTRY_NOTFOUND )
1525*cdf0e10cSrcweir 				{
1526*cdf0e10cSrcweir 					nSelect = mpEntryList->FindFirstSelectable( 0, true );
1527*cdf0e10cSrcweir 				}
1528*cdf0e10cSrcweir 				else if ( (mnCurrentPos+1) < mpEntryList->GetEntryCount() )
1529*cdf0e10cSrcweir 				{
1530*cdf0e10cSrcweir 					sal_uInt16 nCount = mpEntryList->GetEntryCount();
1531*cdf0e10cSrcweir                     sal_uInt16 nCurVis = GetLastVisibleEntry() - mnTop;
1532*cdf0e10cSrcweir 					sal_uInt16 nTmp = Min( nCurVis, nCount );
1533*cdf0e10cSrcweir 					nTmp += mnTop - 1;
1534*cdf0e10cSrcweir 					if( mnCurrentPos == nTmp && mnCurrentPos != nCount - 1 )
1535*cdf0e10cSrcweir 					{
1536*cdf0e10cSrcweir 						long nTmp2 = Min( (long)(nCount-nCurVis), (long)((long)mnTop+(long)nCurVis-1) );
1537*cdf0e10cSrcweir 						nTmp2 = Max( (long)0 , nTmp2 );
1538*cdf0e10cSrcweir 						nTmp = (sal_uInt16)(nTmp2+(nCurVis-1) );
1539*cdf0e10cSrcweir 						SetTopEntry( (sal_uInt16)nTmp2 );
1540*cdf0e10cSrcweir 					}
1541*cdf0e10cSrcweir 					// find first selectable starting from nTmp looking backwards
1542*cdf0e10cSrcweir 					nSelect = mpEntryList->FindFirstSelectable( nTmp, false );
1543*cdf0e10cSrcweir 				}
1544*cdf0e10cSrcweir 				bDone = sal_True;
1545*cdf0e10cSrcweir 			}
1546*cdf0e10cSrcweir 			maQuickSelectionEngine.Reset();
1547*cdf0e10cSrcweir 		}
1548*cdf0e10cSrcweir 		break;
1549*cdf0e10cSrcweir 
1550*cdf0e10cSrcweir 		case KEY_HOME:
1551*cdf0e10cSrcweir 		{
1552*cdf0e10cSrcweir 			if ( IsReadOnly() )
1553*cdf0e10cSrcweir 			{
1554*cdf0e10cSrcweir 				SetTopEntry( 0 );
1555*cdf0e10cSrcweir 			}
1556*cdf0e10cSrcweir 			else if ( !bCtrl && !bMod2 )
1557*cdf0e10cSrcweir 			{
1558*cdf0e10cSrcweir 				if ( mnCurrentPos )
1559*cdf0e10cSrcweir 				{
1560*cdf0e10cSrcweir 					nSelect = mpEntryList->FindFirstSelectable( mpEntryList->GetEntryCount() ? 0 : LISTBOX_ENTRY_NOTFOUND, true );
1561*cdf0e10cSrcweir 					if( mnTop != 0 )
1562*cdf0e10cSrcweir 						SetTopEntry( 0 );
1563*cdf0e10cSrcweir 
1564*cdf0e10cSrcweir 					bDone = sal_True;
1565*cdf0e10cSrcweir 				}
1566*cdf0e10cSrcweir 			}
1567*cdf0e10cSrcweir 			maQuickSelectionEngine.Reset();
1568*cdf0e10cSrcweir 		}
1569*cdf0e10cSrcweir 		break;
1570*cdf0e10cSrcweir 
1571*cdf0e10cSrcweir 		case KEY_END:
1572*cdf0e10cSrcweir 		{
1573*cdf0e10cSrcweir 			if ( IsReadOnly() )
1574*cdf0e10cSrcweir 			{
1575*cdf0e10cSrcweir 				SetTopEntry( 0xFFFF );
1576*cdf0e10cSrcweir 			}
1577*cdf0e10cSrcweir 			else if ( !bCtrl && !bMod2 )
1578*cdf0e10cSrcweir 			{
1579*cdf0e10cSrcweir 				if( mnCurrentPos == LISTBOX_ENTRY_NOTFOUND )
1580*cdf0e10cSrcweir 				{
1581*cdf0e10cSrcweir 					nSelect = mpEntryList->FindFirstSelectable( 0, true );
1582*cdf0e10cSrcweir 				}
1583*cdf0e10cSrcweir 				else if ( (mnCurrentPos+1) < mpEntryList->GetEntryCount() )
1584*cdf0e10cSrcweir 				{
1585*cdf0e10cSrcweir 					sal_uInt16 nCount = mpEntryList->GetEntryCount();
1586*cdf0e10cSrcweir 					nSelect = mpEntryList->FindFirstSelectable( nCount - 1, false );
1587*cdf0e10cSrcweir                     sal_uInt16 nCurVis = GetLastVisibleEntry() - mnTop + 1;
1588*cdf0e10cSrcweir 					if( nCount > nCurVis )
1589*cdf0e10cSrcweir 						SetTopEntry( nCount - nCurVis );
1590*cdf0e10cSrcweir 				}
1591*cdf0e10cSrcweir 				bDone = sal_True;
1592*cdf0e10cSrcweir 			}
1593*cdf0e10cSrcweir 			maQuickSelectionEngine.Reset();
1594*cdf0e10cSrcweir 		}
1595*cdf0e10cSrcweir 		break;
1596*cdf0e10cSrcweir 
1597*cdf0e10cSrcweir 		case KEY_LEFT:
1598*cdf0e10cSrcweir 		{
1599*cdf0e10cSrcweir 			if ( !bCtrl && !bMod2 )
1600*cdf0e10cSrcweir 			{
1601*cdf0e10cSrcweir 				ScrollHorz( -HORZ_SCROLL );
1602*cdf0e10cSrcweir 				bDone = sal_True;
1603*cdf0e10cSrcweir 			}
1604*cdf0e10cSrcweir 			maQuickSelectionEngine.Reset();
1605*cdf0e10cSrcweir 		}
1606*cdf0e10cSrcweir 		break;
1607*cdf0e10cSrcweir 
1608*cdf0e10cSrcweir 		case KEY_RIGHT:
1609*cdf0e10cSrcweir 		{
1610*cdf0e10cSrcweir 			if ( !bCtrl && !bMod2 )
1611*cdf0e10cSrcweir 			{
1612*cdf0e10cSrcweir 				ScrollHorz( HORZ_SCROLL );
1613*cdf0e10cSrcweir 				bDone = sal_True;
1614*cdf0e10cSrcweir 			}
1615*cdf0e10cSrcweir 			maQuickSelectionEngine.Reset();
1616*cdf0e10cSrcweir 		}
1617*cdf0e10cSrcweir 		break;
1618*cdf0e10cSrcweir 
1619*cdf0e10cSrcweir 		case KEY_RETURN:
1620*cdf0e10cSrcweir 		{
1621*cdf0e10cSrcweir 			if ( !bMod2 && !IsReadOnly() )
1622*cdf0e10cSrcweir 			{
1623*cdf0e10cSrcweir 				mnSelectModifier = rKEvt.GetKeyCode().GetModifier();
1624*cdf0e10cSrcweir 				ImplCallSelect();
1625*cdf0e10cSrcweir 				bDone = sal_False;	// RETURN nicht abfangen.
1626*cdf0e10cSrcweir 			}
1627*cdf0e10cSrcweir 			maQuickSelectionEngine.Reset();
1628*cdf0e10cSrcweir 		}
1629*cdf0e10cSrcweir 		break;
1630*cdf0e10cSrcweir 
1631*cdf0e10cSrcweir 		case KEY_SPACE:
1632*cdf0e10cSrcweir 		{
1633*cdf0e10cSrcweir 			if ( !bMod2 && !IsReadOnly() )
1634*cdf0e10cSrcweir 			{
1635*cdf0e10cSrcweir 				if( mbMulti && ( !mbSimpleMode || ( mbSimpleMode && bCtrl && !bShift ) || mbStackMode ) )
1636*cdf0e10cSrcweir 				{
1637*cdf0e10cSrcweir 					nSelect = mnCurrentPos;
1638*cdf0e10cSrcweir 					eLET = LET_KEYSPACE;
1639*cdf0e10cSrcweir 				}
1640*cdf0e10cSrcweir 				bDone = sal_True;
1641*cdf0e10cSrcweir 			}
1642*cdf0e10cSrcweir 			maQuickSelectionEngine.Reset();
1643*cdf0e10cSrcweir 		}
1644*cdf0e10cSrcweir 		break;
1645*cdf0e10cSrcweir 
1646*cdf0e10cSrcweir 		case KEY_A:
1647*cdf0e10cSrcweir 		{
1648*cdf0e10cSrcweir 			if( bCtrl && mbMulti )
1649*cdf0e10cSrcweir 			{
1650*cdf0e10cSrcweir                 // paint only once
1651*cdf0e10cSrcweir                 sal_Bool bUpdates = IsUpdateMode();
1652*cdf0e10cSrcweir                 SetUpdateMode( sal_False );
1653*cdf0e10cSrcweir 
1654*cdf0e10cSrcweir                 sal_uInt16 nEntryCount = mpEntryList->GetEntryCount();
1655*cdf0e10cSrcweir                 for( sal_uInt16 i = 0; i < nEntryCount; i++ )
1656*cdf0e10cSrcweir                     SelectEntry( i, sal_True );
1657*cdf0e10cSrcweir 
1658*cdf0e10cSrcweir                 // restore update mode
1659*cdf0e10cSrcweir                 SetUpdateMode( bUpdates );
1660*cdf0e10cSrcweir                 Invalidate();
1661*cdf0e10cSrcweir 
1662*cdf0e10cSrcweir                 maQuickSelectionEngine.Reset();
1663*cdf0e10cSrcweir 
1664*cdf0e10cSrcweir 				bDone = sal_True;
1665*cdf0e10cSrcweir                 break;
1666*cdf0e10cSrcweir 			}
1667*cdf0e10cSrcweir 		}
1668*cdf0e10cSrcweir         // fall through intentional
1669*cdf0e10cSrcweir 		default:
1670*cdf0e10cSrcweir 		{
1671*cdf0e10cSrcweir             if ( !IsReadOnly() )
1672*cdf0e10cSrcweir             {
1673*cdf0e10cSrcweir                 bDone = maQuickSelectionEngine.HandleKeyEvent( rKEvt );
1674*cdf0e10cSrcweir             }
1675*cdf0e10cSrcweir   		}
1676*cdf0e10cSrcweir         break;
1677*cdf0e10cSrcweir 	}
1678*cdf0e10cSrcweir 
1679*cdf0e10cSrcweir     if  (   ( nSelect != LISTBOX_ENTRY_NOTFOUND )
1680*cdf0e10cSrcweir         &&  (   ( !mpEntryList->IsEntryPosSelected( nSelect ) )
1681*cdf0e10cSrcweir             ||  ( eLET == LET_KEYSPACE )
1682*cdf0e10cSrcweir             )
1683*cdf0e10cSrcweir         )
1684*cdf0e10cSrcweir 	{
1685*cdf0e10cSrcweir 		DBG_ASSERT( !mpEntryList->IsEntryPosSelected( nSelect ) || mbMulti, "ImplListBox: Selecting same Entry" );
1686*cdf0e10cSrcweir 	    if( nSelect >= mpEntryList->GetEntryCount() )
1687*cdf0e10cSrcweir             nSelect = mpEntryList->GetEntryCount()-1;
1688*cdf0e10cSrcweir 		mnCurrentPos = nSelect;
1689*cdf0e10cSrcweir 		if ( SelectEntries( nSelect, eLET, bShift, bCtrl ) )
1690*cdf0e10cSrcweir 		{
1691*cdf0e10cSrcweir 			mbTravelSelect = sal_True;
1692*cdf0e10cSrcweir 			mnSelectModifier = rKEvt.GetKeyCode().GetModifier();
1693*cdf0e10cSrcweir 			ImplCallSelect();
1694*cdf0e10cSrcweir 			mbTravelSelect = sal_False;
1695*cdf0e10cSrcweir 		}
1696*cdf0e10cSrcweir 	}
1697*cdf0e10cSrcweir 
1698*cdf0e10cSrcweir 	return bDone;
1699*cdf0e10cSrcweir }
1700*cdf0e10cSrcweir 
1701*cdf0e10cSrcweir // -----------------------------------------------------------------------
1702*cdf0e10cSrcweir namespace
1703*cdf0e10cSrcweir {
1704*cdf0e10cSrcweir     static ::vcl::StringEntryIdentifier lcl_getEntry( const ImplEntryList& _rList, sal_uInt16 _nPos, String& _out_entryText )
1705*cdf0e10cSrcweir     {
1706*cdf0e10cSrcweir         OSL_PRECOND( ( _nPos != LISTBOX_ENTRY_NOTFOUND ), "lcl_getEntry: invalid position!" );
1707*cdf0e10cSrcweir         sal_uInt16 nEntryCount( _rList.GetEntryCount() );
1708*cdf0e10cSrcweir         if ( _nPos >= nEntryCount )
1709*cdf0e10cSrcweir             _nPos = 0;
1710*cdf0e10cSrcweir         _out_entryText = _rList.GetEntryText( _nPos );
1711*cdf0e10cSrcweir 
1712*cdf0e10cSrcweir         // ::vcl::StringEntryIdentifier does not allow for 0 values, but our position is 0-based
1713*cdf0e10cSrcweir         // => normalize
1714*cdf0e10cSrcweir         return reinterpret_cast< ::vcl::StringEntryIdentifier >( _nPos + 1 );
1715*cdf0e10cSrcweir     }
1716*cdf0e10cSrcweir 
1717*cdf0e10cSrcweir     static sal_uInt16 lcl_getEntryPos( ::vcl::StringEntryIdentifier _entry )
1718*cdf0e10cSrcweir     {
1719*cdf0e10cSrcweir         // our pos is 0-based, but StringEntryIdentifier does not allow for a NULL
1720*cdf0e10cSrcweir         return static_cast< sal_uInt16 >( reinterpret_cast< sal_Int64 >( _entry ) ) - 1;
1721*cdf0e10cSrcweir     }
1722*cdf0e10cSrcweir }
1723*cdf0e10cSrcweir 
1724*cdf0e10cSrcweir // -----------------------------------------------------------------------
1725*cdf0e10cSrcweir ::vcl::StringEntryIdentifier ImplListBoxWindow::CurrentEntry( String& _out_entryText ) const
1726*cdf0e10cSrcweir {
1727*cdf0e10cSrcweir     return lcl_getEntry( *GetEntryList(), ( mnCurrentPos == LISTBOX_ENTRY_NOTFOUND ) ? 0 : mnCurrentPos + 1, _out_entryText );
1728*cdf0e10cSrcweir }
1729*cdf0e10cSrcweir 
1730*cdf0e10cSrcweir // -----------------------------------------------------------------------
1731*cdf0e10cSrcweir ::vcl::StringEntryIdentifier ImplListBoxWindow::NextEntry( ::vcl::StringEntryIdentifier _currentEntry, String& _out_entryText ) const
1732*cdf0e10cSrcweir {
1733*cdf0e10cSrcweir     sal_uInt16 nNextPos = lcl_getEntryPos( _currentEntry ) + 1;
1734*cdf0e10cSrcweir     return lcl_getEntry( *GetEntryList(), nNextPos, _out_entryText );
1735*cdf0e10cSrcweir }
1736*cdf0e10cSrcweir 
1737*cdf0e10cSrcweir // -----------------------------------------------------------------------
1738*cdf0e10cSrcweir void ImplListBoxWindow::SelectEntry( ::vcl::StringEntryIdentifier _entry )
1739*cdf0e10cSrcweir {
1740*cdf0e10cSrcweir     sal_uInt16 nSelect = lcl_getEntryPos( _entry );
1741*cdf0e10cSrcweir     if ( mpEntryList->IsEntryPosSelected( nSelect ) )
1742*cdf0e10cSrcweir     {
1743*cdf0e10cSrcweir         // ignore that. This method is a callback from the QuickSelectionEngine, which means the user attempted
1744*cdf0e10cSrcweir         // to select the given entry by typing its starting letters. No need to act.
1745*cdf0e10cSrcweir         return;
1746*cdf0e10cSrcweir     }
1747*cdf0e10cSrcweir 
1748*cdf0e10cSrcweir     // normalize
1749*cdf0e10cSrcweir     OSL_ENSURE( nSelect < mpEntryList->GetEntryCount(), "ImplListBoxWindow::SelectEntry: how that?" );
1750*cdf0e10cSrcweir     if( nSelect >= mpEntryList->GetEntryCount() )
1751*cdf0e10cSrcweir         nSelect = mpEntryList->GetEntryCount()-1;
1752*cdf0e10cSrcweir 
1753*cdf0e10cSrcweir     // make visible
1754*cdf0e10cSrcweir     ShowProminentEntry( nSelect );
1755*cdf0e10cSrcweir 
1756*cdf0e10cSrcweir     // actually select
1757*cdf0e10cSrcweir     mnCurrentPos = nSelect;
1758*cdf0e10cSrcweir 	if ( SelectEntries( nSelect, LET_KEYMOVE, sal_False, sal_False ) )
1759*cdf0e10cSrcweir 	{
1760*cdf0e10cSrcweir 		mbTravelSelect = sal_True;
1761*cdf0e10cSrcweir 		mnSelectModifier = 0;
1762*cdf0e10cSrcweir 		ImplCallSelect();
1763*cdf0e10cSrcweir 		mbTravelSelect = sal_False;
1764*cdf0e10cSrcweir 	}
1765*cdf0e10cSrcweir }
1766*cdf0e10cSrcweir 
1767*cdf0e10cSrcweir // -----------------------------------------------------------------------
1768*cdf0e10cSrcweir 
1769*cdf0e10cSrcweir void ImplListBoxWindow::ImplPaint( sal_uInt16 nPos, sal_Bool bErase, bool bLayout )
1770*cdf0e10cSrcweir {
1771*cdf0e10cSrcweir 	const StyleSettings& rStyleSettings = GetSettings().GetStyleSettings();
1772*cdf0e10cSrcweir 
1773*cdf0e10cSrcweir     const ImplEntryType* pEntry = mpEntryList->GetEntryPtr( nPos );
1774*cdf0e10cSrcweir     if( ! pEntry )
1775*cdf0e10cSrcweir         return;
1776*cdf0e10cSrcweir 
1777*cdf0e10cSrcweir 	long nWidth  = GetOutputSizePixel().Width();
1778*cdf0e10cSrcweir 	long nY = mpEntryList->GetAddedHeight( nPos, mnTop );
1779*cdf0e10cSrcweir 	Rectangle aRect( Point( 0, nY ), Size( nWidth, pEntry->mnHeight ) );
1780*cdf0e10cSrcweir 
1781*cdf0e10cSrcweir     if( ! bLayout )
1782*cdf0e10cSrcweir     {
1783*cdf0e10cSrcweir         if( mpEntryList->IsEntryPosSelected( nPos ) )
1784*cdf0e10cSrcweir         {
1785*cdf0e10cSrcweir             SetTextColor( !IsEnabled() ? rStyleSettings.GetDisableColor() : rStyleSettings.GetHighlightTextColor() );
1786*cdf0e10cSrcweir             SetFillColor( rStyleSettings.GetHighlightColor() );
1787*cdf0e10cSrcweir             SetTextFillColor( rStyleSettings.GetHighlightColor() );
1788*cdf0e10cSrcweir             DrawRect( aRect );
1789*cdf0e10cSrcweir         }
1790*cdf0e10cSrcweir         else
1791*cdf0e10cSrcweir         {
1792*cdf0e10cSrcweir             ImplInitSettings( sal_False, sal_True, sal_False );
1793*cdf0e10cSrcweir             if( !IsEnabled() )
1794*cdf0e10cSrcweir                 SetTextColor( rStyleSettings.GetDisableColor() );
1795*cdf0e10cSrcweir             SetTextFillColor();
1796*cdf0e10cSrcweir             if( bErase )
1797*cdf0e10cSrcweir                 Erase( aRect );
1798*cdf0e10cSrcweir         }
1799*cdf0e10cSrcweir     }
1800*cdf0e10cSrcweir 
1801*cdf0e10cSrcweir     if ( IsUserDrawEnabled() )
1802*cdf0e10cSrcweir     {
1803*cdf0e10cSrcweir         mbInUserDraw = sal_True;
1804*cdf0e10cSrcweir 		mnUserDrawEntry = nPos;
1805*cdf0e10cSrcweir 		aRect.Left() -= mnLeft;
1806*cdf0e10cSrcweir 		if ( nPos < GetEntryList()->GetMRUCount() )
1807*cdf0e10cSrcweir 			nPos = GetEntryList()->FindEntry( GetEntryList()->GetEntryText( nPos ) );
1808*cdf0e10cSrcweir 		nPos = sal::static_int_cast<sal_uInt16>(nPos - GetEntryList()->GetMRUCount());
1809*cdf0e10cSrcweir 		UserDrawEvent aUDEvt( this, aRect, nPos, 0 );
1810*cdf0e10cSrcweir 		maUserDrawHdl.Call( &aUDEvt );
1811*cdf0e10cSrcweir 		mbInUserDraw = sal_False;
1812*cdf0e10cSrcweir 	}
1813*cdf0e10cSrcweir 	else
1814*cdf0e10cSrcweir 	{
1815*cdf0e10cSrcweir 		DrawEntry( nPos, sal_True, sal_True, sal_False, bLayout );
1816*cdf0e10cSrcweir 	}
1817*cdf0e10cSrcweir }
1818*cdf0e10cSrcweir 
1819*cdf0e10cSrcweir // -----------------------------------------------------------------------
1820*cdf0e10cSrcweir 
1821*cdf0e10cSrcweir void ImplListBoxWindow::DrawEntry( sal_uInt16 nPos, sal_Bool bDrawImage, sal_Bool bDrawText, sal_Bool bDrawTextAtImagePos, bool bLayout )
1822*cdf0e10cSrcweir {
1823*cdf0e10cSrcweir     const ImplEntryType* pEntry = mpEntryList->GetEntryPtr( nPos );
1824*cdf0e10cSrcweir     if( ! pEntry )
1825*cdf0e10cSrcweir         return;
1826*cdf0e10cSrcweir 
1827*cdf0e10cSrcweir 	// Bei Aenderungen in dieser Methode ggf. auch ImplWin::DrawEntry() anpassen.
1828*cdf0e10cSrcweir 
1829*cdf0e10cSrcweir 	if ( mbInUserDraw )
1830*cdf0e10cSrcweir 		nPos = mnUserDrawEntry; // real entry, not the matching entry from MRU
1831*cdf0e10cSrcweir 
1832*cdf0e10cSrcweir     long nY = mpEntryList->GetAddedHeight( nPos, mnTop );
1833*cdf0e10cSrcweir 	Size aImgSz;
1834*cdf0e10cSrcweir 
1835*cdf0e10cSrcweir 	if( bDrawImage && mpEntryList->HasImages() && !bLayout )
1836*cdf0e10cSrcweir 	{
1837*cdf0e10cSrcweir 		Image aImage = mpEntryList->GetEntryImage( nPos );
1838*cdf0e10cSrcweir 		if( !!aImage )
1839*cdf0e10cSrcweir 		{
1840*cdf0e10cSrcweir             aImgSz = aImage.GetSizePixel();
1841*cdf0e10cSrcweir 			Point aPtImg( mnBorder - mnLeft, nY + ( ( pEntry->mnHeight - aImgSz.Height() ) / 2 ) );
1842*cdf0e10cSrcweir 
1843*cdf0e10cSrcweir 			// pb: #106948# explicit mirroring for calc
1844*cdf0e10cSrcweir 			if ( mbMirroring )
1845*cdf0e10cSrcweir 				// right aligned
1846*cdf0e10cSrcweir 				aPtImg.X() = mnMaxWidth + mnBorder - aImgSz.Width() - mnLeft;
1847*cdf0e10cSrcweir 
1848*cdf0e10cSrcweir 			if ( !IsZoom() )
1849*cdf0e10cSrcweir 			{
1850*cdf0e10cSrcweir 				DrawImage( aPtImg, aImage );
1851*cdf0e10cSrcweir 			}
1852*cdf0e10cSrcweir 			else
1853*cdf0e10cSrcweir 			{
1854*cdf0e10cSrcweir 				aImgSz.Width() = CalcZoom( aImgSz.Width() );
1855*cdf0e10cSrcweir 				aImgSz.Height() = CalcZoom( aImgSz.Height() );
1856*cdf0e10cSrcweir 				DrawImage( aPtImg, aImgSz, aImage );
1857*cdf0e10cSrcweir 			}
1858*cdf0e10cSrcweir 		}
1859*cdf0e10cSrcweir 	}
1860*cdf0e10cSrcweir 
1861*cdf0e10cSrcweir 	if( bDrawText )
1862*cdf0e10cSrcweir 	{
1863*cdf0e10cSrcweir         MetricVector* pVector = bLayout ? &mpControlData->mpLayoutData->m_aUnicodeBoundRects : NULL;
1864*cdf0e10cSrcweir         String* pDisplayText = bLayout ? &mpControlData->mpLayoutData->m_aDisplayText : NULL;
1865*cdf0e10cSrcweir 		XubString aStr( mpEntryList->GetEntryText( nPos ) );
1866*cdf0e10cSrcweir 		if ( aStr.Len() )
1867*cdf0e10cSrcweir 		{
1868*cdf0e10cSrcweir             long nMaxWidth = Max( static_cast< long >( mnMaxWidth ),
1869*cdf0e10cSrcweir                                   GetOutputSizePixel().Width() - 2*mnBorder );
1870*cdf0e10cSrcweir             // a multiline entry should only be as wide a the window
1871*cdf0e10cSrcweir             if( (pEntry->mnFlags & LISTBOX_ENTRY_FLAG_MULTILINE) )
1872*cdf0e10cSrcweir                 nMaxWidth = GetOutputSizePixel().Width() - 2*mnBorder;
1873*cdf0e10cSrcweir 
1874*cdf0e10cSrcweir             Rectangle aTextRect( Point( mnBorder - mnLeft, nY ),
1875*cdf0e10cSrcweir                                  Size( nMaxWidth, pEntry->mnHeight ) );
1876*cdf0e10cSrcweir 
1877*cdf0e10cSrcweir             if( !bDrawTextAtImagePos && ( mpEntryList->HasEntryImage(nPos) || IsUserDrawEnabled() ) )
1878*cdf0e10cSrcweir 			{
1879*cdf0e10cSrcweir 				long nImageWidth = Max( mnMaxImgWidth, maUserItemSize.Width() );
1880*cdf0e10cSrcweir                 aTextRect.Left() += nImageWidth + IMG_TXT_DISTANCE;
1881*cdf0e10cSrcweir 			}
1882*cdf0e10cSrcweir 
1883*cdf0e10cSrcweir             if( bLayout )
1884*cdf0e10cSrcweir                 mpControlData->mpLayoutData->m_aLineIndices.push_back( mpControlData->mpLayoutData->m_aDisplayText.Len() );
1885*cdf0e10cSrcweir 
1886*cdf0e10cSrcweir 			// pb: #106948# explicit mirroring for calc
1887*cdf0e10cSrcweir 			if ( mbMirroring )
1888*cdf0e10cSrcweir 			{
1889*cdf0e10cSrcweir 				// right aligned
1890*cdf0e10cSrcweir                 aTextRect.Left() = nMaxWidth + mnBorder - GetTextWidth( aStr ) - mnLeft;
1891*cdf0e10cSrcweir 				if ( aImgSz.Width() > 0 )
1892*cdf0e10cSrcweir 					aTextRect.Left() -= ( aImgSz.Width() + IMG_TXT_DISTANCE );
1893*cdf0e10cSrcweir 			}
1894*cdf0e10cSrcweir 
1895*cdf0e10cSrcweir             sal_uInt16 nDrawStyle = ImplGetTextStyle();
1896*cdf0e10cSrcweir             if( (pEntry->mnFlags & LISTBOX_ENTRY_FLAG_MULTILINE) )
1897*cdf0e10cSrcweir                 nDrawStyle |= MULTILINE_ENTRY_DRAW_FLAGS;
1898*cdf0e10cSrcweir             if( (pEntry->mnFlags & LISTBOX_ENTRY_FLAG_DRAW_DISABLED) )
1899*cdf0e10cSrcweir                 nDrawStyle |= TEXT_DRAW_DISABLE;
1900*cdf0e10cSrcweir 
1901*cdf0e10cSrcweir             DrawText( aTextRect, aStr, nDrawStyle, pVector, pDisplayText );
1902*cdf0e10cSrcweir 		}
1903*cdf0e10cSrcweir 	}
1904*cdf0e10cSrcweir 
1905*cdf0e10cSrcweir     if( !bLayout )
1906*cdf0e10cSrcweir     {
1907*cdf0e10cSrcweir         if ( ( mnSeparatorPos != LISTBOX_ENTRY_NOTFOUND ) &&
1908*cdf0e10cSrcweir              ( ( nPos == mnSeparatorPos ) || ( nPos == mnSeparatorPos+1 ) ) )
1909*cdf0e10cSrcweir         {
1910*cdf0e10cSrcweir             Color aOldLineColor( GetLineColor() );
1911*cdf0e10cSrcweir             SetLineColor( ( GetBackground().GetColor() != COL_LIGHTGRAY ) ? COL_LIGHTGRAY : COL_GRAY );
1912*cdf0e10cSrcweir             Point aStartPos( 0, nY );
1913*cdf0e10cSrcweir             if ( nPos == mnSeparatorPos )
1914*cdf0e10cSrcweir                 aStartPos.Y() += pEntry->mnHeight-1;
1915*cdf0e10cSrcweir             Point aEndPos( aStartPos );
1916*cdf0e10cSrcweir             aEndPos.X() = GetOutputSizePixel().Width();
1917*cdf0e10cSrcweir             DrawLine( aStartPos, aEndPos );
1918*cdf0e10cSrcweir             SetLineColor( aOldLineColor );
1919*cdf0e10cSrcweir         }
1920*cdf0e10cSrcweir     }
1921*cdf0e10cSrcweir }
1922*cdf0e10cSrcweir 
1923*cdf0e10cSrcweir // -----------------------------------------------------------------------
1924*cdf0e10cSrcweir 
1925*cdf0e10cSrcweir void ImplListBoxWindow::FillLayoutData() const
1926*cdf0e10cSrcweir {
1927*cdf0e10cSrcweir     mpControlData->mpLayoutData = new vcl::ControlLayoutData();
1928*cdf0e10cSrcweir     const_cast<ImplListBoxWindow*>(this)->
1929*cdf0e10cSrcweir         ImplDoPaint( Rectangle( Point( 0, 0 ), GetOutputSize() ), true );
1930*cdf0e10cSrcweir }
1931*cdf0e10cSrcweir 
1932*cdf0e10cSrcweir // -----------------------------------------------------------------------
1933*cdf0e10cSrcweir 
1934*cdf0e10cSrcweir void ImplListBoxWindow::ImplDoPaint( const Rectangle& rRect, bool bLayout )
1935*cdf0e10cSrcweir {
1936*cdf0e10cSrcweir 	sal_uInt16 nCount = mpEntryList->GetEntryCount();
1937*cdf0e10cSrcweir 
1938*cdf0e10cSrcweir     sal_Bool bShowFocusRect = mbHasFocusRect;
1939*cdf0e10cSrcweir     if ( mbHasFocusRect && ! bLayout )
1940*cdf0e10cSrcweir         ImplHideFocusRect();
1941*cdf0e10cSrcweir 
1942*cdf0e10cSrcweir 	long nY = 0; // + mnBorder;
1943*cdf0e10cSrcweir 	long nHeight = GetOutputSizePixel().Height();// - mnMaxHeight + mnBorder;
1944*cdf0e10cSrcweir 
1945*cdf0e10cSrcweir 	for( sal_uInt16 i = (sal_uInt16)mnTop; i < nCount && nY < nHeight + mnMaxHeight; i++ )
1946*cdf0e10cSrcweir 	{
1947*cdf0e10cSrcweir         const ImplEntryType* pEntry = mpEntryList->GetEntryPtr( i );
1948*cdf0e10cSrcweir 		if( nY + pEntry->mnHeight >= rRect.Top() &&
1949*cdf0e10cSrcweir 			nY <= rRect.Bottom() + mnMaxHeight )
1950*cdf0e10cSrcweir 		{
1951*cdf0e10cSrcweir 			ImplPaint( i, sal_False, bLayout );
1952*cdf0e10cSrcweir 		}
1953*cdf0e10cSrcweir 		nY += pEntry->mnHeight;
1954*cdf0e10cSrcweir 	}
1955*cdf0e10cSrcweir 
1956*cdf0e10cSrcweir     long nHeightDiff = mpEntryList->GetAddedHeight( mnCurrentPos, mnTop, 0 );
1957*cdf0e10cSrcweir 	maFocusRect.SetPos( Point( 0, nHeightDiff ) );
1958*cdf0e10cSrcweir     Size aSz( maFocusRect.GetWidth(), mpEntryList->GetEntryHeight( mnCurrentPos ) );
1959*cdf0e10cSrcweir     maFocusRect.SetSize( aSz );
1960*cdf0e10cSrcweir 	if( HasFocus() && bShowFocusRect && !bLayout )
1961*cdf0e10cSrcweir 		ImplShowFocusRect();
1962*cdf0e10cSrcweir }
1963*cdf0e10cSrcweir 
1964*cdf0e10cSrcweir // -----------------------------------------------------------------------
1965*cdf0e10cSrcweir 
1966*cdf0e10cSrcweir void ImplListBoxWindow::Paint( const Rectangle& rRect )
1967*cdf0e10cSrcweir {
1968*cdf0e10cSrcweir     ImplDoPaint( rRect );
1969*cdf0e10cSrcweir }
1970*cdf0e10cSrcweir 
1971*cdf0e10cSrcweir // -----------------------------------------------------------------------
1972*cdf0e10cSrcweir 
1973*cdf0e10cSrcweir sal_uInt16 ImplListBoxWindow::GetDisplayLineCount() const
1974*cdf0e10cSrcweir {
1975*cdf0e10cSrcweir     // FIXME: LISTBOX_ENTRY_FLAG_MULTILINE
1976*cdf0e10cSrcweir 
1977*cdf0e10cSrcweir 	sal_uInt16 nCount = mpEntryList->GetEntryCount();
1978*cdf0e10cSrcweir 	long nHeight = GetOutputSizePixel().Height();// - mnMaxHeight + mnBorder;
1979*cdf0e10cSrcweir     sal_uInt16 nEntries = static_cast< sal_uInt16 >( ( nHeight + mnMaxHeight - 1 ) / mnMaxHeight );
1980*cdf0e10cSrcweir     if( nEntries > nCount-mnTop )
1981*cdf0e10cSrcweir         nEntries = nCount-mnTop;
1982*cdf0e10cSrcweir 
1983*cdf0e10cSrcweir     return nEntries;
1984*cdf0e10cSrcweir }
1985*cdf0e10cSrcweir 
1986*cdf0e10cSrcweir // -----------------------------------------------------------------------
1987*cdf0e10cSrcweir 
1988*cdf0e10cSrcweir void ImplListBoxWindow::Resize()
1989*cdf0e10cSrcweir {
1990*cdf0e10cSrcweir     Control::Resize();
1991*cdf0e10cSrcweir 
1992*cdf0e10cSrcweir     sal_Bool bShowFocusRect = mbHasFocusRect;
1993*cdf0e10cSrcweir     if ( bShowFocusRect )
1994*cdf0e10cSrcweir         ImplHideFocusRect();
1995*cdf0e10cSrcweir 
1996*cdf0e10cSrcweir     if( mnCurrentPos != LISTBOX_ENTRY_NOTFOUND )
1997*cdf0e10cSrcweir     {
1998*cdf0e10cSrcweir         Size aSz( GetOutputSizePixel().Width(), mpEntryList->GetEntryHeight( mnCurrentPos ) );
1999*cdf0e10cSrcweir         maFocusRect.SetSize( aSz );
2000*cdf0e10cSrcweir     }
2001*cdf0e10cSrcweir 
2002*cdf0e10cSrcweir     if ( bShowFocusRect )
2003*cdf0e10cSrcweir         ImplShowFocusRect();
2004*cdf0e10cSrcweir 
2005*cdf0e10cSrcweir     ImplClearLayoutData();
2006*cdf0e10cSrcweir }
2007*cdf0e10cSrcweir 
2008*cdf0e10cSrcweir // -----------------------------------------------------------------------
2009*cdf0e10cSrcweir 
2010*cdf0e10cSrcweir void ImplListBoxWindow::GetFocus()
2011*cdf0e10cSrcweir {
2012*cdf0e10cSrcweir 	sal_uInt16 nPos = mnCurrentPos;
2013*cdf0e10cSrcweir 	if ( nPos == LISTBOX_ENTRY_NOTFOUND )
2014*cdf0e10cSrcweir 		nPos = 0;
2015*cdf0e10cSrcweir     long nHeightDiff = mpEntryList->GetAddedHeight( nPos, mnTop, 0 );
2016*cdf0e10cSrcweir 	maFocusRect.SetPos( Point( 0, nHeightDiff ) );
2017*cdf0e10cSrcweir     Size aSz( maFocusRect.GetWidth(), mpEntryList->GetEntryHeight( nPos ) );
2018*cdf0e10cSrcweir     maFocusRect.SetSize( aSz );
2019*cdf0e10cSrcweir 	ImplShowFocusRect();
2020*cdf0e10cSrcweir 	Control::GetFocus();
2021*cdf0e10cSrcweir }
2022*cdf0e10cSrcweir 
2023*cdf0e10cSrcweir // -----------------------------------------------------------------------
2024*cdf0e10cSrcweir 
2025*cdf0e10cSrcweir void ImplListBoxWindow::LoseFocus()
2026*cdf0e10cSrcweir {
2027*cdf0e10cSrcweir 	ImplHideFocusRect();
2028*cdf0e10cSrcweir 	Control::LoseFocus();
2029*cdf0e10cSrcweir }
2030*cdf0e10cSrcweir 
2031*cdf0e10cSrcweir // -----------------------------------------------------------------------
2032*cdf0e10cSrcweir 
2033*cdf0e10cSrcweir /*
2034*cdf0e10cSrcweir void ImplListBoxWindow::RequestHelp( const HelpEvent& rHEvt )
2035*cdf0e10cSrcweir {
2036*cdf0e10cSrcweir 	if ( rHEvt.GetMode() & HELPMODE_BALLOON )
2037*cdf0e10cSrcweir 		Help::ShowBalloon( this, rHEvt.GetMousePosPixel(), String() );
2038*cdf0e10cSrcweir 
2039*cdf0e10cSrcweir 	Window::RequestHelp( rHEvt );
2040*cdf0e10cSrcweir }
2041*cdf0e10cSrcweir */
2042*cdf0e10cSrcweir 
2043*cdf0e10cSrcweir // -----------------------------------------------------------------------
2044*cdf0e10cSrcweir 
2045*cdf0e10cSrcweir void ImplListBoxWindow::SetTopEntry( sal_uInt16 nTop )
2046*cdf0e10cSrcweir {
2047*cdf0e10cSrcweir     if( mpEntryList->GetEntryCount() == 0 )
2048*cdf0e10cSrcweir         return;
2049*cdf0e10cSrcweir 
2050*cdf0e10cSrcweir     long nWHeight = PixelToLogic( GetSizePixel() ).Height();
2051*cdf0e10cSrcweir 
2052*cdf0e10cSrcweir     sal_uInt16 nLastEntry = mpEntryList->GetEntryCount()-1;
2053*cdf0e10cSrcweir     if( nTop > nLastEntry )
2054*cdf0e10cSrcweir         nTop = nLastEntry;
2055*cdf0e10cSrcweir     const ImplEntryType* pLast = mpEntryList->GetEntryPtr( nLastEntry );
2056*cdf0e10cSrcweir     while( nTop > 0 && mpEntryList->GetAddedHeight( nLastEntry, nTop-1 ) + pLast->mnHeight <= nWHeight )
2057*cdf0e10cSrcweir         nTop--;
2058*cdf0e10cSrcweir 
2059*cdf0e10cSrcweir 	if ( nTop != mnTop )
2060*cdf0e10cSrcweir 	{
2061*cdf0e10cSrcweir         ImplClearLayoutData();
2062*cdf0e10cSrcweir 		long nDiff = mpEntryList->GetAddedHeight( mnTop, nTop, 0 );
2063*cdf0e10cSrcweir         Update();
2064*cdf0e10cSrcweir 		ImplHideFocusRect();
2065*cdf0e10cSrcweir 		mnTop = nTop;
2066*cdf0e10cSrcweir 		Scroll( 0, nDiff );
2067*cdf0e10cSrcweir         Update();
2068*cdf0e10cSrcweir 		if( HasFocus() )
2069*cdf0e10cSrcweir 			ImplShowFocusRect();
2070*cdf0e10cSrcweir 		maScrollHdl.Call( this );
2071*cdf0e10cSrcweir 	}
2072*cdf0e10cSrcweir }
2073*cdf0e10cSrcweir 
2074*cdf0e10cSrcweir // -----------------------------------------------------------------------
2075*cdf0e10cSrcweir 
2076*cdf0e10cSrcweir void ImplListBoxWindow::ShowProminentEntry( sal_uInt16 nEntryPos )
2077*cdf0e10cSrcweir {
2078*cdf0e10cSrcweir     if( meProminentType == PROMINENT_MIDDLE )
2079*cdf0e10cSrcweir     {
2080*cdf0e10cSrcweir         sal_uInt16 nPos = nEntryPos;
2081*cdf0e10cSrcweir         long nWHeight = PixelToLogic( GetSizePixel() ).Height();
2082*cdf0e10cSrcweir         while( nEntryPos > 0 && mpEntryList->GetAddedHeight( nPos+1, nEntryPos ) < nWHeight/2 )
2083*cdf0e10cSrcweir             nEntryPos--;
2084*cdf0e10cSrcweir     }
2085*cdf0e10cSrcweir     SetTopEntry( nEntryPos );
2086*cdf0e10cSrcweir }
2087*cdf0e10cSrcweir 
2088*cdf0e10cSrcweir // -----------------------------------------------------------------------
2089*cdf0e10cSrcweir 
2090*cdf0e10cSrcweir void ImplListBoxWindow::SetLeftIndent( long n )
2091*cdf0e10cSrcweir {
2092*cdf0e10cSrcweir 	ScrollHorz( n - mnLeft );
2093*cdf0e10cSrcweir }
2094*cdf0e10cSrcweir 
2095*cdf0e10cSrcweir // -----------------------------------------------------------------------
2096*cdf0e10cSrcweir 
2097*cdf0e10cSrcweir void ImplListBoxWindow::ScrollHorz( long n )
2098*cdf0e10cSrcweir {
2099*cdf0e10cSrcweir 	long nDiff = 0;
2100*cdf0e10cSrcweir 	if ( n > 0 )
2101*cdf0e10cSrcweir 	{
2102*cdf0e10cSrcweir 		long nWidth = GetOutputSizePixel().Width();
2103*cdf0e10cSrcweir 		if( ( mnMaxWidth - mnLeft + n ) > nWidth )
2104*cdf0e10cSrcweir 			nDiff = n;
2105*cdf0e10cSrcweir 	}
2106*cdf0e10cSrcweir 	else if ( n < 0 )
2107*cdf0e10cSrcweir 	{
2108*cdf0e10cSrcweir 		if( mnLeft )
2109*cdf0e10cSrcweir 		{
2110*cdf0e10cSrcweir 			long nAbs = -n;
2111*cdf0e10cSrcweir 			nDiff = - ( ( mnLeft > nAbs ) ? nAbs : mnLeft );
2112*cdf0e10cSrcweir 		}
2113*cdf0e10cSrcweir 	}
2114*cdf0e10cSrcweir 
2115*cdf0e10cSrcweir 	if ( nDiff )
2116*cdf0e10cSrcweir 	{
2117*cdf0e10cSrcweir         ImplClearLayoutData();
2118*cdf0e10cSrcweir 		mnLeft = sal::static_int_cast<sal_uInt16>(mnLeft + nDiff);
2119*cdf0e10cSrcweir         Update();
2120*cdf0e10cSrcweir 		ImplHideFocusRect();
2121*cdf0e10cSrcweir 		Scroll( -nDiff, 0 );
2122*cdf0e10cSrcweir         Update();
2123*cdf0e10cSrcweir 		if( HasFocus() )
2124*cdf0e10cSrcweir 			ImplShowFocusRect();
2125*cdf0e10cSrcweir 		maScrollHdl.Call( this );
2126*cdf0e10cSrcweir 	}
2127*cdf0e10cSrcweir }
2128*cdf0e10cSrcweir 
2129*cdf0e10cSrcweir // -----------------------------------------------------------------------
2130*cdf0e10cSrcweir 
2131*cdf0e10cSrcweir Size ImplListBoxWindow::CalcSize( sal_uInt16 nMaxLines ) const
2132*cdf0e10cSrcweir {
2133*cdf0e10cSrcweir     // FIXME: LISTBOX_ENTRY_FLAG_MULTILINE
2134*cdf0e10cSrcweir 
2135*cdf0e10cSrcweir 	Size aSz;
2136*cdf0e10cSrcweir //	sal_uInt16 nL = Min( nMaxLines, mpEntryList->GetEntryCount() );
2137*cdf0e10cSrcweir 	aSz.Height() =	nMaxLines * mnMaxHeight;
2138*cdf0e10cSrcweir 	aSz.Width() = mnMaxWidth + 2*mnBorder;
2139*cdf0e10cSrcweir 	return aSz;
2140*cdf0e10cSrcweir }
2141*cdf0e10cSrcweir 
2142*cdf0e10cSrcweir // -----------------------------------------------------------------------
2143*cdf0e10cSrcweir 
2144*cdf0e10cSrcweir Rectangle ImplListBoxWindow::GetBoundingRectangle( sal_uInt16 nItem ) const
2145*cdf0e10cSrcweir {
2146*cdf0e10cSrcweir     const ImplEntryType* pEntry = mpEntryList->GetEntryPtr( nItem );
2147*cdf0e10cSrcweir     Size aSz( GetSizePixel().Width(), pEntry ? pEntry->mnHeight : GetEntryHeight() );
2148*cdf0e10cSrcweir     long nY = mpEntryList->GetAddedHeight( nItem, GetTopEntry() ) - mpEntryList->GetAddedHeight( GetTopEntry() );
2149*cdf0e10cSrcweir     Rectangle aRect( Point( 0, nY ), aSz );
2150*cdf0e10cSrcweir     return aRect;
2151*cdf0e10cSrcweir }
2152*cdf0e10cSrcweir 
2153*cdf0e10cSrcweir 
2154*cdf0e10cSrcweir // -----------------------------------------------------------------------
2155*cdf0e10cSrcweir 
2156*cdf0e10cSrcweir void ImplListBoxWindow::StateChanged( StateChangedType nType )
2157*cdf0e10cSrcweir {
2158*cdf0e10cSrcweir 	Control::StateChanged( nType );
2159*cdf0e10cSrcweir 
2160*cdf0e10cSrcweir 	if ( nType == STATE_CHANGE_ZOOM )
2161*cdf0e10cSrcweir 	{
2162*cdf0e10cSrcweir 		ImplInitSettings( sal_True, sal_False, sal_False );
2163*cdf0e10cSrcweir 		ImplCalcMetrics();
2164*cdf0e10cSrcweir 		Invalidate();
2165*cdf0e10cSrcweir 	}
2166*cdf0e10cSrcweir 	else if ( nType == STATE_CHANGE_UPDATEMODE )
2167*cdf0e10cSrcweir 	{
2168*cdf0e10cSrcweir 		if ( IsUpdateMode() && IsReallyVisible() )
2169*cdf0e10cSrcweir 			Invalidate();
2170*cdf0e10cSrcweir 	}
2171*cdf0e10cSrcweir 	else if ( nType == STATE_CHANGE_CONTROLFONT )
2172*cdf0e10cSrcweir 	{
2173*cdf0e10cSrcweir 		ImplInitSettings( sal_True, sal_False, sal_False );
2174*cdf0e10cSrcweir 		ImplCalcMetrics();
2175*cdf0e10cSrcweir 		Invalidate();
2176*cdf0e10cSrcweir 	}
2177*cdf0e10cSrcweir 	else if ( nType == STATE_CHANGE_CONTROLFOREGROUND )
2178*cdf0e10cSrcweir 	{
2179*cdf0e10cSrcweir 		ImplInitSettings( sal_False, sal_True, sal_False );
2180*cdf0e10cSrcweir 		Invalidate();
2181*cdf0e10cSrcweir 	}
2182*cdf0e10cSrcweir 	else if ( nType == STATE_CHANGE_CONTROLBACKGROUND )
2183*cdf0e10cSrcweir 	{
2184*cdf0e10cSrcweir 		ImplInitSettings( sal_False, sal_False, sal_True );
2185*cdf0e10cSrcweir 		Invalidate();
2186*cdf0e10cSrcweir 	}
2187*cdf0e10cSrcweir     ImplClearLayoutData();
2188*cdf0e10cSrcweir }
2189*cdf0e10cSrcweir 
2190*cdf0e10cSrcweir // -----------------------------------------------------------------------
2191*cdf0e10cSrcweir 
2192*cdf0e10cSrcweir void ImplListBoxWindow::DataChanged( const DataChangedEvent& rDCEvt )
2193*cdf0e10cSrcweir {
2194*cdf0e10cSrcweir 	Control::DataChanged( rDCEvt );
2195*cdf0e10cSrcweir 
2196*cdf0e10cSrcweir 	if ( (rDCEvt.GetType() == DATACHANGED_FONTS) ||
2197*cdf0e10cSrcweir 		 (rDCEvt.GetType() == DATACHANGED_FONTSUBSTITUTION) ||
2198*cdf0e10cSrcweir 		 ((rDCEvt.GetType() == DATACHANGED_SETTINGS) &&
2199*cdf0e10cSrcweir 		  (rDCEvt.GetFlags() & SETTINGS_STYLE)) )
2200*cdf0e10cSrcweir 	{
2201*cdf0e10cSrcweir         ImplClearLayoutData();
2202*cdf0e10cSrcweir 		ImplInitSettings( sal_True, sal_True, sal_True );
2203*cdf0e10cSrcweir 		ImplCalcMetrics();
2204*cdf0e10cSrcweir 		Invalidate();
2205*cdf0e10cSrcweir 	}
2206*cdf0e10cSrcweir }
2207*cdf0e10cSrcweir 
2208*cdf0e10cSrcweir // -----------------------------------------------------------------------
2209*cdf0e10cSrcweir 
2210*cdf0e10cSrcweir sal_uInt16 ImplListBoxWindow::ImplGetTextStyle() const
2211*cdf0e10cSrcweir {
2212*cdf0e10cSrcweir     sal_uInt16 nTextStyle = TEXT_DRAW_VCENTER;
2213*cdf0e10cSrcweir 
2214*cdf0e10cSrcweir     if ( mpEntryList->HasImages() )
2215*cdf0e10cSrcweir         nTextStyle |= TEXT_DRAW_LEFT;
2216*cdf0e10cSrcweir     else if ( mbCenter )
2217*cdf0e10cSrcweir         nTextStyle |= TEXT_DRAW_CENTER;
2218*cdf0e10cSrcweir     else if ( mbRight )
2219*cdf0e10cSrcweir         nTextStyle |= TEXT_DRAW_RIGHT;
2220*cdf0e10cSrcweir     else
2221*cdf0e10cSrcweir         nTextStyle |= TEXT_DRAW_LEFT;
2222*cdf0e10cSrcweir 
2223*cdf0e10cSrcweir     return nTextStyle;
2224*cdf0e10cSrcweir }
2225*cdf0e10cSrcweir 
2226*cdf0e10cSrcweir // =======================================================================
2227*cdf0e10cSrcweir 
2228*cdf0e10cSrcweir ImplListBox::ImplListBox( Window* pParent, WinBits nWinStyle ) :
2229*cdf0e10cSrcweir 	Control( pParent, nWinStyle ),
2230*cdf0e10cSrcweir 	maLBWindow( this, nWinStyle&(~WB_BORDER) )
2231*cdf0e10cSrcweir {
2232*cdf0e10cSrcweir     // for native widget rendering we must be able to detect this window type
2233*cdf0e10cSrcweir     SetType( WINDOW_LISTBOXWINDOW );
2234*cdf0e10cSrcweir 
2235*cdf0e10cSrcweir 	mpVScrollBar	= new ScrollBar( this, WB_VSCROLL | WB_DRAG );
2236*cdf0e10cSrcweir 	mpHScrollBar	= new ScrollBar( this, WB_HSCROLL | WB_DRAG );
2237*cdf0e10cSrcweir 	mpScrollBarBox	= new ScrollBarBox( this );
2238*cdf0e10cSrcweir 
2239*cdf0e10cSrcweir 	Link aLink( LINK( this, ImplListBox, ScrollBarHdl ) );
2240*cdf0e10cSrcweir 	mpVScrollBar->SetScrollHdl( aLink );
2241*cdf0e10cSrcweir 	mpHScrollBar->SetScrollHdl( aLink );
2242*cdf0e10cSrcweir 
2243*cdf0e10cSrcweir 	mbVScroll		= sal_False;
2244*cdf0e10cSrcweir 	mbHScroll		= sal_False;
2245*cdf0e10cSrcweir 	mbAutoHScroll	= ( nWinStyle & WB_AUTOHSCROLL ) ? sal_True : sal_False;
2246*cdf0e10cSrcweir 
2247*cdf0e10cSrcweir 	maLBWindow.SetScrollHdl( LINK( this, ImplListBox, LBWindowScrolled ) );
2248*cdf0e10cSrcweir 	maLBWindow.SetMRUChangedHdl( LINK( this, ImplListBox, MRUChanged ) );
2249*cdf0e10cSrcweir 	maLBWindow.Show();
2250*cdf0e10cSrcweir }
2251*cdf0e10cSrcweir 
2252*cdf0e10cSrcweir // -----------------------------------------------------------------------
2253*cdf0e10cSrcweir 
2254*cdf0e10cSrcweir ImplListBox::~ImplListBox()
2255*cdf0e10cSrcweir {
2256*cdf0e10cSrcweir 	delete mpHScrollBar;
2257*cdf0e10cSrcweir 	delete mpVScrollBar;
2258*cdf0e10cSrcweir 	delete mpScrollBarBox;
2259*cdf0e10cSrcweir }
2260*cdf0e10cSrcweir 
2261*cdf0e10cSrcweir // -----------------------------------------------------------------------
2262*cdf0e10cSrcweir 
2263*cdf0e10cSrcweir void ImplListBox::Clear()
2264*cdf0e10cSrcweir {
2265*cdf0e10cSrcweir 	maLBWindow.Clear();
2266*cdf0e10cSrcweir 	if ( GetEntryList()->GetMRUCount() )
2267*cdf0e10cSrcweir 	{
2268*cdf0e10cSrcweir 		maLBWindow.GetEntryList()->SetMRUCount( 0 );
2269*cdf0e10cSrcweir 		maLBWindow.SetSeparatorPos( LISTBOX_ENTRY_NOTFOUND );
2270*cdf0e10cSrcweir 	}
2271*cdf0e10cSrcweir 	mpVScrollBar->SetThumbPos( 0 );
2272*cdf0e10cSrcweir 	mpHScrollBar->SetThumbPos( 0 );
2273*cdf0e10cSrcweir 	StateChanged( STATE_CHANGE_DATA );
2274*cdf0e10cSrcweir }
2275*cdf0e10cSrcweir 
2276*cdf0e10cSrcweir // -----------------------------------------------------------------------
2277*cdf0e10cSrcweir 
2278*cdf0e10cSrcweir sal_uInt16 ImplListBox::InsertEntry( sal_uInt16 nPos, const XubString& rStr )
2279*cdf0e10cSrcweir {
2280*cdf0e10cSrcweir 	ImplEntryType* pNewEntry = new ImplEntryType( rStr );
2281*cdf0e10cSrcweir 	sal_uInt16 nNewPos = maLBWindow.InsertEntry( nPos, pNewEntry );
2282*cdf0e10cSrcweir 	StateChanged( STATE_CHANGE_DATA );
2283*cdf0e10cSrcweir 	return nNewPos;
2284*cdf0e10cSrcweir }
2285*cdf0e10cSrcweir 
2286*cdf0e10cSrcweir // -----------------------------------------------------------------------
2287*cdf0e10cSrcweir 
2288*cdf0e10cSrcweir sal_uInt16 ImplListBox::InsertEntry( sal_uInt16 nPos, const Image& rImage )
2289*cdf0e10cSrcweir {
2290*cdf0e10cSrcweir 	ImplEntryType* pNewEntry = new ImplEntryType( rImage );
2291*cdf0e10cSrcweir 	sal_uInt16 nNewPos = maLBWindow.InsertEntry( nPos, pNewEntry );
2292*cdf0e10cSrcweir 	StateChanged( STATE_CHANGE_DATA );
2293*cdf0e10cSrcweir 	return nNewPos;
2294*cdf0e10cSrcweir }
2295*cdf0e10cSrcweir 
2296*cdf0e10cSrcweir // -----------------------------------------------------------------------
2297*cdf0e10cSrcweir 
2298*cdf0e10cSrcweir sal_uInt16 ImplListBox::InsertEntry( sal_uInt16 nPos, const XubString& rStr, const Image& rImage )
2299*cdf0e10cSrcweir {
2300*cdf0e10cSrcweir 	ImplEntryType* pNewEntry = new ImplEntryType( rStr, rImage );
2301*cdf0e10cSrcweir 	sal_uInt16 nNewPos = maLBWindow.InsertEntry( nPos, pNewEntry );
2302*cdf0e10cSrcweir 	StateChanged( STATE_CHANGE_DATA );
2303*cdf0e10cSrcweir 	return nNewPos;
2304*cdf0e10cSrcweir }
2305*cdf0e10cSrcweir 
2306*cdf0e10cSrcweir // -----------------------------------------------------------------------
2307*cdf0e10cSrcweir 
2308*cdf0e10cSrcweir void ImplListBox::RemoveEntry( sal_uInt16 nPos )
2309*cdf0e10cSrcweir {
2310*cdf0e10cSrcweir 	maLBWindow.RemoveEntry( nPos );
2311*cdf0e10cSrcweir 	StateChanged( STATE_CHANGE_DATA );
2312*cdf0e10cSrcweir }
2313*cdf0e10cSrcweir 
2314*cdf0e10cSrcweir // -----------------------------------------------------------------------
2315*cdf0e10cSrcweir 
2316*cdf0e10cSrcweir void ImplListBox::SetEntryFlags( sal_uInt16 nPos, long nFlags )
2317*cdf0e10cSrcweir {
2318*cdf0e10cSrcweir 	maLBWindow.SetEntryFlags( nPos, nFlags );
2319*cdf0e10cSrcweir }
2320*cdf0e10cSrcweir 
2321*cdf0e10cSrcweir // -----------------------------------------------------------------------
2322*cdf0e10cSrcweir 
2323*cdf0e10cSrcweir long ImplListBox::GetEntryFlags( sal_uInt16 nPos ) const
2324*cdf0e10cSrcweir {
2325*cdf0e10cSrcweir 	return maLBWindow.GetEntryList()->GetEntryFlags( nPos );
2326*cdf0e10cSrcweir }
2327*cdf0e10cSrcweir 
2328*cdf0e10cSrcweir // -----------------------------------------------------------------------
2329*cdf0e10cSrcweir 
2330*cdf0e10cSrcweir void ImplListBox::SelectEntry( sal_uInt16 nPos, sal_Bool bSelect )
2331*cdf0e10cSrcweir {
2332*cdf0e10cSrcweir 	maLBWindow.SelectEntry( nPos, bSelect );
2333*cdf0e10cSrcweir }
2334*cdf0e10cSrcweir 
2335*cdf0e10cSrcweir // -----------------------------------------------------------------------
2336*cdf0e10cSrcweir 
2337*cdf0e10cSrcweir void ImplListBox::SetNoSelection()
2338*cdf0e10cSrcweir {
2339*cdf0e10cSrcweir 	maLBWindow.DeselectAll();
2340*cdf0e10cSrcweir }
2341*cdf0e10cSrcweir 
2342*cdf0e10cSrcweir // -----------------------------------------------------------------------
2343*cdf0e10cSrcweir 
2344*cdf0e10cSrcweir void ImplListBox::GetFocus()
2345*cdf0e10cSrcweir {
2346*cdf0e10cSrcweir 	maLBWindow.GrabFocus();
2347*cdf0e10cSrcweir }
2348*cdf0e10cSrcweir 
2349*cdf0e10cSrcweir // -----------------------------------------------------------------------
2350*cdf0e10cSrcweir 
2351*cdf0e10cSrcweir Window* ImplListBox::GetPreferredKeyInputWindow()
2352*cdf0e10cSrcweir {
2353*cdf0e10cSrcweir     return &maLBWindow;
2354*cdf0e10cSrcweir }
2355*cdf0e10cSrcweir 
2356*cdf0e10cSrcweir // -----------------------------------------------------------------------
2357*cdf0e10cSrcweir 
2358*cdf0e10cSrcweir void ImplListBox::Resize()
2359*cdf0e10cSrcweir {
2360*cdf0e10cSrcweir     Control::Resize();
2361*cdf0e10cSrcweir 	ImplResizeControls();
2362*cdf0e10cSrcweir 	ImplCheckScrollBars();
2363*cdf0e10cSrcweir }
2364*cdf0e10cSrcweir 
2365*cdf0e10cSrcweir 
2366*cdf0e10cSrcweir // -----------------------------------------------------------------------
2367*cdf0e10cSrcweir 
2368*cdf0e10cSrcweir IMPL_LINK( ImplListBox, MRUChanged, void*, EMPTYARG )
2369*cdf0e10cSrcweir {
2370*cdf0e10cSrcweir 	StateChanged( STATE_CHANGE_DATA );
2371*cdf0e10cSrcweir 	return 1;
2372*cdf0e10cSrcweir }
2373*cdf0e10cSrcweir 
2374*cdf0e10cSrcweir // -----------------------------------------------------------------------
2375*cdf0e10cSrcweir 
2376*cdf0e10cSrcweir IMPL_LINK( ImplListBox, LBWindowScrolled, void*, EMPTYARG )
2377*cdf0e10cSrcweir {
2378*cdf0e10cSrcweir     long nSet = GetTopEntry();
2379*cdf0e10cSrcweir     if( nSet > mpVScrollBar->GetRangeMax() )
2380*cdf0e10cSrcweir         mpVScrollBar->SetRangeMax( GetEntryList()->GetEntryCount() );
2381*cdf0e10cSrcweir 	mpVScrollBar->SetThumbPos( GetTopEntry() );
2382*cdf0e10cSrcweir 
2383*cdf0e10cSrcweir 	mpHScrollBar->SetThumbPos( GetLeftIndent() );
2384*cdf0e10cSrcweir 
2385*cdf0e10cSrcweir 	maScrollHdl.Call( this );
2386*cdf0e10cSrcweir 
2387*cdf0e10cSrcweir 	return 1;
2388*cdf0e10cSrcweir }
2389*cdf0e10cSrcweir 
2390*cdf0e10cSrcweir // -----------------------------------------------------------------------
2391*cdf0e10cSrcweir 
2392*cdf0e10cSrcweir IMPL_LINK( ImplListBox, ScrollBarHdl, ScrollBar*, pSB )
2393*cdf0e10cSrcweir {
2394*cdf0e10cSrcweir 	sal_uInt16 nPos = (sal_uInt16) pSB->GetThumbPos();
2395*cdf0e10cSrcweir 	if( pSB == mpVScrollBar )
2396*cdf0e10cSrcweir 		SetTopEntry( nPos );
2397*cdf0e10cSrcweir 	else if( pSB == mpHScrollBar )
2398*cdf0e10cSrcweir 		SetLeftIndent( nPos );
2399*cdf0e10cSrcweir 
2400*cdf0e10cSrcweir 	return 1;
2401*cdf0e10cSrcweir }
2402*cdf0e10cSrcweir 
2403*cdf0e10cSrcweir // -----------------------------------------------------------------------
2404*cdf0e10cSrcweir 
2405*cdf0e10cSrcweir void ImplListBox::ImplCheckScrollBars()
2406*cdf0e10cSrcweir {
2407*cdf0e10cSrcweir 	sal_Bool bArrange = sal_False;
2408*cdf0e10cSrcweir 
2409*cdf0e10cSrcweir 	Size aOutSz = GetOutputSizePixel();
2410*cdf0e10cSrcweir 	sal_uInt16 nEntries = GetEntryList()->GetEntryCount();
2411*cdf0e10cSrcweir 	sal_uInt16 nMaxVisEntries = (sal_uInt16) (aOutSz.Height() / GetEntryHeight());
2412*cdf0e10cSrcweir 
2413*cdf0e10cSrcweir 	// vert. ScrollBar
2414*cdf0e10cSrcweir 	if( nEntries > nMaxVisEntries )
2415*cdf0e10cSrcweir 	{
2416*cdf0e10cSrcweir 		if( !mbVScroll )
2417*cdf0e10cSrcweir 			bArrange = sal_True;
2418*cdf0e10cSrcweir 		mbVScroll = sal_True;
2419*cdf0e10cSrcweir 
2420*cdf0e10cSrcweir 		// Ueberpruefung des rausgescrollten Bereichs
2421*cdf0e10cSrcweir         if( GetEntryList()->GetSelectEntryCount() == 1 &&
2422*cdf0e10cSrcweir             GetEntryList()->GetSelectEntryPos( 0 ) != LISTBOX_ENTRY_NOTFOUND )
2423*cdf0e10cSrcweir 		    ShowProminentEntry( GetEntryList()->GetSelectEntryPos( 0 ) );
2424*cdf0e10cSrcweir 		else
2425*cdf0e10cSrcweir 		    SetTopEntry( GetTopEntry() );	// MaxTop wird geprueft...
2426*cdf0e10cSrcweir 	}
2427*cdf0e10cSrcweir 	else
2428*cdf0e10cSrcweir 	{
2429*cdf0e10cSrcweir 		if( mbVScroll )
2430*cdf0e10cSrcweir 			bArrange = sal_True;
2431*cdf0e10cSrcweir 		mbVScroll = sal_False;
2432*cdf0e10cSrcweir 		SetTopEntry( 0 );
2433*cdf0e10cSrcweir 	}
2434*cdf0e10cSrcweir 
2435*cdf0e10cSrcweir 	// horz. ScrollBar
2436*cdf0e10cSrcweir 	if( mbAutoHScroll )
2437*cdf0e10cSrcweir 	{
2438*cdf0e10cSrcweir 		long nWidth = (sal_uInt16) aOutSz.Width();
2439*cdf0e10cSrcweir 		if ( mbVScroll )
2440*cdf0e10cSrcweir 			nWidth -= mpVScrollBar->GetSizePixel().Width();
2441*cdf0e10cSrcweir 
2442*cdf0e10cSrcweir 		long nMaxWidth = GetMaxEntryWidth();
2443*cdf0e10cSrcweir 		if( nWidth < nMaxWidth )
2444*cdf0e10cSrcweir 		{
2445*cdf0e10cSrcweir 			if( !mbHScroll )
2446*cdf0e10cSrcweir 				bArrange = sal_True;
2447*cdf0e10cSrcweir 			mbHScroll = sal_True;
2448*cdf0e10cSrcweir 
2449*cdf0e10cSrcweir 			if ( !mbVScroll )	// ggf. brauchen wir jetzt doch einen
2450*cdf0e10cSrcweir 			{
2451*cdf0e10cSrcweir 				nMaxVisEntries = (sal_uInt16) ( ( aOutSz.Height() - mpHScrollBar->GetSizePixel().Height() ) / GetEntryHeight() );
2452*cdf0e10cSrcweir 				if( nEntries > nMaxVisEntries )
2453*cdf0e10cSrcweir 				{
2454*cdf0e10cSrcweir 					bArrange = sal_True;
2455*cdf0e10cSrcweir 					mbVScroll = sal_True;
2456*cdf0e10cSrcweir 
2457*cdf0e10cSrcweir 					// Ueberpruefung des rausgescrollten Bereichs
2458*cdf0e10cSrcweir                     if( GetEntryList()->GetSelectEntryCount() == 1 &&
2459*cdf0e10cSrcweir                         GetEntryList()->GetSelectEntryPos( 0 ) != LISTBOX_ENTRY_NOTFOUND )
2460*cdf0e10cSrcweir                         ShowProminentEntry( GetEntryList()->GetSelectEntryPos( 0 ) );
2461*cdf0e10cSrcweir                     else
2462*cdf0e10cSrcweir                         SetTopEntry( GetTopEntry() );	// MaxTop wird geprueft...
2463*cdf0e10cSrcweir 				}
2464*cdf0e10cSrcweir 			}
2465*cdf0e10cSrcweir 
2466*cdf0e10cSrcweir 			// Ueberpruefung des rausgescrollten Bereichs
2467*cdf0e10cSrcweir 			sal_uInt16 nMaxLI = (sal_uInt16) (nMaxWidth - nWidth);
2468*cdf0e10cSrcweir 			if ( nMaxLI < GetLeftIndent() )
2469*cdf0e10cSrcweir 				SetLeftIndent( nMaxLI );
2470*cdf0e10cSrcweir 		}
2471*cdf0e10cSrcweir 		else
2472*cdf0e10cSrcweir 		{
2473*cdf0e10cSrcweir 			if( mbHScroll )
2474*cdf0e10cSrcweir 				bArrange = sal_True;
2475*cdf0e10cSrcweir 			mbHScroll = sal_False;
2476*cdf0e10cSrcweir 			SetLeftIndent( 0 );
2477*cdf0e10cSrcweir 		}
2478*cdf0e10cSrcweir 	}
2479*cdf0e10cSrcweir 
2480*cdf0e10cSrcweir 	if( bArrange )
2481*cdf0e10cSrcweir 		ImplResizeControls();
2482*cdf0e10cSrcweir 
2483*cdf0e10cSrcweir 	ImplInitScrollBars();
2484*cdf0e10cSrcweir }
2485*cdf0e10cSrcweir 
2486*cdf0e10cSrcweir // -----------------------------------------------------------------------
2487*cdf0e10cSrcweir 
2488*cdf0e10cSrcweir void ImplListBox::ImplInitScrollBars()
2489*cdf0e10cSrcweir {
2490*cdf0e10cSrcweir 	Size aOutSz = maLBWindow.GetOutputSizePixel();
2491*cdf0e10cSrcweir 
2492*cdf0e10cSrcweir 	if ( mbVScroll )
2493*cdf0e10cSrcweir 	{
2494*cdf0e10cSrcweir 		sal_uInt16 nEntries = GetEntryList()->GetEntryCount();
2495*cdf0e10cSrcweir 		sal_uInt16 nVisEntries = (sal_uInt16) (aOutSz.Height() / GetEntryHeight());
2496*cdf0e10cSrcweir 		mpVScrollBar->SetRangeMax( nEntries );
2497*cdf0e10cSrcweir 		mpVScrollBar->SetVisibleSize( nVisEntries );
2498*cdf0e10cSrcweir 		mpVScrollBar->SetPageSize( nVisEntries - 1 );
2499*cdf0e10cSrcweir 	}
2500*cdf0e10cSrcweir 
2501*cdf0e10cSrcweir 	if ( mbHScroll )
2502*cdf0e10cSrcweir 	{
2503*cdf0e10cSrcweir 		mpHScrollBar->SetRangeMax( GetMaxEntryWidth() + HORZ_SCROLL );
2504*cdf0e10cSrcweir 		mpHScrollBar->SetVisibleSize( (sal_uInt16)aOutSz.Width() );
2505*cdf0e10cSrcweir 		mpHScrollBar->SetLineSize( HORZ_SCROLL );
2506*cdf0e10cSrcweir 		mpHScrollBar->SetPageSize( aOutSz.Width() - HORZ_SCROLL );
2507*cdf0e10cSrcweir 	}
2508*cdf0e10cSrcweir }
2509*cdf0e10cSrcweir 
2510*cdf0e10cSrcweir // -----------------------------------------------------------------------
2511*cdf0e10cSrcweir 
2512*cdf0e10cSrcweir void ImplListBox::ImplResizeControls()
2513*cdf0e10cSrcweir {
2514*cdf0e10cSrcweir 	// Hier werden die Controls nur angeordnet, ob die Scrollbars
2515*cdf0e10cSrcweir 	// sichtbar sein sollen wird bereits in ImplCheckScrollBars ermittelt.
2516*cdf0e10cSrcweir 
2517*cdf0e10cSrcweir 	Size aOutSz = GetOutputSizePixel();
2518*cdf0e10cSrcweir 	long nSBWidth = GetSettings().GetStyleSettings().GetScrollBarSize();
2519*cdf0e10cSrcweir 	nSBWidth = CalcZoom( nSBWidth );
2520*cdf0e10cSrcweir 
2521*cdf0e10cSrcweir 	Size aInnerSz( aOutSz );
2522*cdf0e10cSrcweir 	if ( mbVScroll )
2523*cdf0e10cSrcweir 		aInnerSz.Width() -= nSBWidth;
2524*cdf0e10cSrcweir 	if ( mbHScroll )
2525*cdf0e10cSrcweir 		aInnerSz.Height() -= nSBWidth;
2526*cdf0e10cSrcweir 
2527*cdf0e10cSrcweir 	// pb: #106948# explicit mirroring for calc
2528*cdf0e10cSrcweir 	// Scrollbar on left or right side?
2529*cdf0e10cSrcweir 	sal_Bool bMirroring = maLBWindow.IsMirroring();
2530*cdf0e10cSrcweir 	Point aWinPos( bMirroring && mbVScroll ? nSBWidth : 0, 0 );
2531*cdf0e10cSrcweir 	maLBWindow.SetPosSizePixel( aWinPos, aInnerSz );
2532*cdf0e10cSrcweir 
2533*cdf0e10cSrcweir 	// ScrollBarBox
2534*cdf0e10cSrcweir 	if( mbVScroll && mbHScroll )
2535*cdf0e10cSrcweir 	{
2536*cdf0e10cSrcweir 		Point aBoxPos( bMirroring ? 0 : aInnerSz.Width(), aInnerSz.Height() );
2537*cdf0e10cSrcweir 		mpScrollBarBox->SetPosSizePixel( aBoxPos, Size( nSBWidth, nSBWidth ) );
2538*cdf0e10cSrcweir 		mpScrollBarBox->Show();
2539*cdf0e10cSrcweir 	}
2540*cdf0e10cSrcweir 	else
2541*cdf0e10cSrcweir 	{
2542*cdf0e10cSrcweir 		mpScrollBarBox->Hide();
2543*cdf0e10cSrcweir 	}
2544*cdf0e10cSrcweir 
2545*cdf0e10cSrcweir 	// vert. ScrollBar
2546*cdf0e10cSrcweir 	if( mbVScroll )
2547*cdf0e10cSrcweir 	{
2548*cdf0e10cSrcweir 		// Scrollbar on left or right side?
2549*cdf0e10cSrcweir 		Point aVPos( bMirroring ? 0 : aOutSz.Width() - nSBWidth, 0 );
2550*cdf0e10cSrcweir 		mpVScrollBar->SetPosSizePixel( aVPos, Size( nSBWidth, aInnerSz.Height() ) );
2551*cdf0e10cSrcweir 		mpVScrollBar->Show();
2552*cdf0e10cSrcweir 	}
2553*cdf0e10cSrcweir 	else
2554*cdf0e10cSrcweir 	{
2555*cdf0e10cSrcweir 		mpVScrollBar->Hide();
2556*cdf0e10cSrcweir         // #107254# Don't reset top entry after resize, but check for max top entry
2557*cdf0e10cSrcweir 		SetTopEntry( GetTopEntry() );
2558*cdf0e10cSrcweir 	}
2559*cdf0e10cSrcweir 
2560*cdf0e10cSrcweir 	// horz. ScrollBar
2561*cdf0e10cSrcweir 	if( mbHScroll )
2562*cdf0e10cSrcweir 	{
2563*cdf0e10cSrcweir 		Point aHPos( ( bMirroring && mbVScroll ) ? nSBWidth : 0, aOutSz.Height() - nSBWidth );
2564*cdf0e10cSrcweir 		mpHScrollBar->SetPosSizePixel( aHPos, Size( aInnerSz.Width(), nSBWidth ) );
2565*cdf0e10cSrcweir 		mpHScrollBar->Show();
2566*cdf0e10cSrcweir 	}
2567*cdf0e10cSrcweir 	else
2568*cdf0e10cSrcweir 	{
2569*cdf0e10cSrcweir 		mpHScrollBar->Hide();
2570*cdf0e10cSrcweir 		SetLeftIndent( 0 );
2571*cdf0e10cSrcweir 	}
2572*cdf0e10cSrcweir }
2573*cdf0e10cSrcweir 
2574*cdf0e10cSrcweir // -----------------------------------------------------------------------
2575*cdf0e10cSrcweir 
2576*cdf0e10cSrcweir void ImplListBox::StateChanged( StateChangedType nType )
2577*cdf0e10cSrcweir {
2578*cdf0e10cSrcweir 	if ( nType == STATE_CHANGE_INITSHOW )
2579*cdf0e10cSrcweir 	{
2580*cdf0e10cSrcweir 		ImplCheckScrollBars();
2581*cdf0e10cSrcweir 	}
2582*cdf0e10cSrcweir 	else if ( ( nType == STATE_CHANGE_UPDATEMODE ) || ( nType == STATE_CHANGE_DATA ) )
2583*cdf0e10cSrcweir 	{
2584*cdf0e10cSrcweir 		sal_Bool bUpdate = IsUpdateMode();
2585*cdf0e10cSrcweir 		maLBWindow.SetUpdateMode( bUpdate );
2586*cdf0e10cSrcweir //		mpHScrollBar->SetUpdateMode( bUpdate );
2587*cdf0e10cSrcweir //		mpVScrollBar->SetUpdateMode( bUpdate );
2588*cdf0e10cSrcweir 		if ( bUpdate && IsReallyVisible() )
2589*cdf0e10cSrcweir 			ImplCheckScrollBars();
2590*cdf0e10cSrcweir 	}
2591*cdf0e10cSrcweir 	else if( nType == STATE_CHANGE_ENABLE )
2592*cdf0e10cSrcweir 	{
2593*cdf0e10cSrcweir 		mpHScrollBar->Enable( IsEnabled() );
2594*cdf0e10cSrcweir 		mpVScrollBar->Enable( IsEnabled() );
2595*cdf0e10cSrcweir 		mpScrollBarBox->Enable( IsEnabled() );
2596*cdf0e10cSrcweir 		Invalidate();
2597*cdf0e10cSrcweir 	}
2598*cdf0e10cSrcweir 	else if ( nType == STATE_CHANGE_ZOOM )
2599*cdf0e10cSrcweir 	{
2600*cdf0e10cSrcweir 		maLBWindow.SetZoom( GetZoom() );
2601*cdf0e10cSrcweir 		Resize();
2602*cdf0e10cSrcweir 	}
2603*cdf0e10cSrcweir 	else if ( nType == STATE_CHANGE_CONTROLFONT )
2604*cdf0e10cSrcweir 	{
2605*cdf0e10cSrcweir 		maLBWindow.SetControlFont( GetControlFont() );
2606*cdf0e10cSrcweir 	}
2607*cdf0e10cSrcweir 	else if ( nType == STATE_CHANGE_CONTROLFOREGROUND )
2608*cdf0e10cSrcweir 	{
2609*cdf0e10cSrcweir 		maLBWindow.SetControlForeground( GetControlForeground() );
2610*cdf0e10cSrcweir 	}
2611*cdf0e10cSrcweir 	else if ( nType == STATE_CHANGE_CONTROLBACKGROUND )
2612*cdf0e10cSrcweir 	{
2613*cdf0e10cSrcweir 		maLBWindow.SetControlBackground( GetControlBackground() );
2614*cdf0e10cSrcweir 	}
2615*cdf0e10cSrcweir     else if( nType == STATE_CHANGE_MIRRORING )
2616*cdf0e10cSrcweir     {
2617*cdf0e10cSrcweir         maLBWindow.EnableRTL( IsRTLEnabled() );
2618*cdf0e10cSrcweir         mpHScrollBar->EnableRTL( IsRTLEnabled() );
2619*cdf0e10cSrcweir         mpVScrollBar->EnableRTL( IsRTLEnabled() );
2620*cdf0e10cSrcweir         ImplResizeControls();
2621*cdf0e10cSrcweir     }
2622*cdf0e10cSrcweir 
2623*cdf0e10cSrcweir 	Control::StateChanged( nType );
2624*cdf0e10cSrcweir }
2625*cdf0e10cSrcweir 
2626*cdf0e10cSrcweir // -----------------------------------------------------------------------
2627*cdf0e10cSrcweir 
2628*cdf0e10cSrcweir void ImplListBox::DataChanged( const DataChangedEvent& rDCEvt )
2629*cdf0e10cSrcweir {
2630*cdf0e10cSrcweir //	if ( (rDCEvt.GetType() == DATACHANGED_SETTINGS) &&
2631*cdf0e10cSrcweir //		 (rDCEvt.GetFlags() & SETTINGS_STYLE) )
2632*cdf0e10cSrcweir //	{
2633*cdf0e10cSrcweir //		maLBWindow.SetSettings( GetSettings() );
2634*cdf0e10cSrcweir //		Resize();
2635*cdf0e10cSrcweir //	}
2636*cdf0e10cSrcweir //	else
2637*cdf0e10cSrcweir 		Control::DataChanged( rDCEvt );
2638*cdf0e10cSrcweir }
2639*cdf0e10cSrcweir 
2640*cdf0e10cSrcweir // -----------------------------------------------------------------------
2641*cdf0e10cSrcweir 
2642*cdf0e10cSrcweir long ImplListBox::Notify( NotifyEvent& rNEvt )
2643*cdf0e10cSrcweir {
2644*cdf0e10cSrcweir 	long nDone = 0;
2645*cdf0e10cSrcweir 	if ( rNEvt.GetType() == EVENT_COMMAND )
2646*cdf0e10cSrcweir 	{
2647*cdf0e10cSrcweir 		const CommandEvent& rCEvt = *rNEvt.GetCommandEvent();
2648*cdf0e10cSrcweir 		if ( rCEvt.GetCommand() == COMMAND_WHEEL )
2649*cdf0e10cSrcweir 		{
2650*cdf0e10cSrcweir 			const CommandWheelData* pData = rCEvt.GetWheelData();
2651*cdf0e10cSrcweir 			if( !pData->GetModifier() && ( pData->GetMode() == COMMAND_WHEEL_SCROLL ) )
2652*cdf0e10cSrcweir 			{
2653*cdf0e10cSrcweir 				nDone = HandleScrollCommand( rCEvt, mpHScrollBar, mpVScrollBar );
2654*cdf0e10cSrcweir 			}
2655*cdf0e10cSrcweir 		}
2656*cdf0e10cSrcweir 	}
2657*cdf0e10cSrcweir 
2658*cdf0e10cSrcweir 	return nDone ? nDone : Window::Notify( rNEvt );
2659*cdf0e10cSrcweir }
2660*cdf0e10cSrcweir 
2661*cdf0e10cSrcweir // -----------------------------------------------------------------------
2662*cdf0e10cSrcweir 
2663*cdf0e10cSrcweir const Wallpaper& ImplListBox::GetDisplayBackground() const
2664*cdf0e10cSrcweir {
2665*cdf0e10cSrcweir     return maLBWindow.GetDisplayBackground();
2666*cdf0e10cSrcweir }
2667*cdf0e10cSrcweir 
2668*cdf0e10cSrcweir // -----------------------------------------------------------------------
2669*cdf0e10cSrcweir 
2670*cdf0e10cSrcweir sal_Bool ImplListBox::HandleWheelAsCursorTravel( const CommandEvent& rCEvt )
2671*cdf0e10cSrcweir {
2672*cdf0e10cSrcweir 	sal_Bool bDone = sal_False;
2673*cdf0e10cSrcweir 	if ( rCEvt.GetCommand() == COMMAND_WHEEL )
2674*cdf0e10cSrcweir 	{
2675*cdf0e10cSrcweir 		const CommandWheelData* pData = rCEvt.GetWheelData();
2676*cdf0e10cSrcweir 		if( !pData->GetModifier() && ( pData->GetMode() == COMMAND_WHEEL_SCROLL ) )
2677*cdf0e10cSrcweir 		{
2678*cdf0e10cSrcweir 			sal_uInt16 nKey = ( pData->GetDelta() < 0 ) ? KEY_DOWN : KEY_UP;
2679*cdf0e10cSrcweir 			KeyEvent aKeyEvent( 0, KeyCode( nKey ) );
2680*cdf0e10cSrcweir 			bDone = ProcessKeyInput( aKeyEvent );
2681*cdf0e10cSrcweir 		}
2682*cdf0e10cSrcweir 	}
2683*cdf0e10cSrcweir 	return bDone;
2684*cdf0e10cSrcweir }
2685*cdf0e10cSrcweir 
2686*cdf0e10cSrcweir // -----------------------------------------------------------------------
2687*cdf0e10cSrcweir 
2688*cdf0e10cSrcweir void ImplListBox::SetMRUEntries( const XubString& rEntries, xub_Unicode cSep )
2689*cdf0e10cSrcweir {
2690*cdf0e10cSrcweir 	sal_Bool bChanges = GetEntryList()->GetMRUCount() ? sal_True : sal_False;
2691*cdf0e10cSrcweir 
2692*cdf0e10cSrcweir 	// Remove old MRU entries
2693*cdf0e10cSrcweir 	for ( sal_uInt16 n = GetEntryList()->GetMRUCount();n; )
2694*cdf0e10cSrcweir 		maLBWindow.RemoveEntry( --n );
2695*cdf0e10cSrcweir 
2696*cdf0e10cSrcweir 	sal_uInt16 nMRUCount = 0;
2697*cdf0e10cSrcweir 	sal_uInt16 nEntries = rEntries.GetTokenCount( cSep );
2698*cdf0e10cSrcweir 	for ( sal_uInt16 nEntry = 0; nEntry < nEntries; nEntry++ )
2699*cdf0e10cSrcweir 	{
2700*cdf0e10cSrcweir 		XubString aEntry = rEntries.GetToken( nEntry, cSep );
2701*cdf0e10cSrcweir 		// Accept only existing entries
2702*cdf0e10cSrcweir 		if ( GetEntryList()->FindEntry( aEntry ) != LISTBOX_ENTRY_NOTFOUND )
2703*cdf0e10cSrcweir 		{
2704*cdf0e10cSrcweir 			ImplEntryType* pNewEntry = new ImplEntryType( aEntry );
2705*cdf0e10cSrcweir 			maLBWindow.GetEntryList()->InsertEntry( nMRUCount++, pNewEntry, sal_False );
2706*cdf0e10cSrcweir 			bChanges = sal_True;
2707*cdf0e10cSrcweir 		}
2708*cdf0e10cSrcweir 	}
2709*cdf0e10cSrcweir 
2710*cdf0e10cSrcweir 	if ( bChanges )
2711*cdf0e10cSrcweir 	{
2712*cdf0e10cSrcweir 		maLBWindow.GetEntryList()->SetMRUCount( nMRUCount );
2713*cdf0e10cSrcweir 		SetSeparatorPos( nMRUCount ? nMRUCount-1 : 0 );
2714*cdf0e10cSrcweir 		StateChanged( STATE_CHANGE_DATA );
2715*cdf0e10cSrcweir 	}
2716*cdf0e10cSrcweir }
2717*cdf0e10cSrcweir 
2718*cdf0e10cSrcweir // -----------------------------------------------------------------------
2719*cdf0e10cSrcweir 
2720*cdf0e10cSrcweir XubString ImplListBox::GetMRUEntries( xub_Unicode cSep ) const
2721*cdf0e10cSrcweir {
2722*cdf0e10cSrcweir 	String aEntries;
2723*cdf0e10cSrcweir 	for ( sal_uInt16 n = 0; n < GetEntryList()->GetMRUCount(); n++ )
2724*cdf0e10cSrcweir 	{
2725*cdf0e10cSrcweir 		aEntries += GetEntryList()->GetEntryText( n );
2726*cdf0e10cSrcweir 		if( n < ( GetEntryList()->GetMRUCount() - 1 ) )
2727*cdf0e10cSrcweir 			aEntries += cSep;
2728*cdf0e10cSrcweir 	}
2729*cdf0e10cSrcweir 	return aEntries;
2730*cdf0e10cSrcweir }
2731*cdf0e10cSrcweir 
2732*cdf0e10cSrcweir // =======================================================================
2733*cdf0e10cSrcweir 
2734*cdf0e10cSrcweir ImplWin::ImplWin( Window* pParent, WinBits nWinStyle ) :
2735*cdf0e10cSrcweir 	Control ( pParent, nWinStyle )
2736*cdf0e10cSrcweir {
2737*cdf0e10cSrcweir 	if ( IsNativeControlSupported(CTRL_LISTBOX, PART_ENTIRE_CONTROL)
2738*cdf0e10cSrcweir 			&& ! IsNativeControlSupported(CTRL_LISTBOX, PART_BUTTON_DOWN) )
2739*cdf0e10cSrcweir 		SetBackground();
2740*cdf0e10cSrcweir 	else
2741*cdf0e10cSrcweir 		SetBackground( Wallpaper( GetSettings().GetStyleSettings().GetFieldColor() ) );
2742*cdf0e10cSrcweir 
2743*cdf0e10cSrcweir 	mbInUserDraw = sal_False;
2744*cdf0e10cSrcweir 	mbUserDrawEnabled = sal_False;
2745*cdf0e10cSrcweir 	mnItemPos = LISTBOX_ENTRY_NOTFOUND;
2746*cdf0e10cSrcweir }
2747*cdf0e10cSrcweir 
2748*cdf0e10cSrcweir // -----------------------------------------------------------------------
2749*cdf0e10cSrcweir 
2750*cdf0e10cSrcweir sal_Bool ImplWin::SetModeImage( const Image& rImage, BmpColorMode eMode )
2751*cdf0e10cSrcweir {
2752*cdf0e10cSrcweir     if( eMode == BMP_COLOR_NORMAL )
2753*cdf0e10cSrcweir         SetImage( rImage );
2754*cdf0e10cSrcweir     else if( eMode == BMP_COLOR_HIGHCONTRAST )
2755*cdf0e10cSrcweir 		maImageHC = rImage;
2756*cdf0e10cSrcweir     else
2757*cdf0e10cSrcweir         return sal_False;
2758*cdf0e10cSrcweir     return sal_True;
2759*cdf0e10cSrcweir }
2760*cdf0e10cSrcweir 
2761*cdf0e10cSrcweir // -----------------------------------------------------------------------
2762*cdf0e10cSrcweir 
2763*cdf0e10cSrcweir const Image& ImplWin::GetModeImage( BmpColorMode eMode ) const
2764*cdf0e10cSrcweir {
2765*cdf0e10cSrcweir     if( eMode == BMP_COLOR_HIGHCONTRAST )
2766*cdf0e10cSrcweir         return maImageHC;
2767*cdf0e10cSrcweir     else
2768*cdf0e10cSrcweir         return maImage;
2769*cdf0e10cSrcweir }
2770*cdf0e10cSrcweir 
2771*cdf0e10cSrcweir // -----------------------------------------------------------------------
2772*cdf0e10cSrcweir 
2773*cdf0e10cSrcweir void ImplWin::MBDown()
2774*cdf0e10cSrcweir {
2775*cdf0e10cSrcweir 	if( IsEnabled() )
2776*cdf0e10cSrcweir 		maMBDownHdl.Call( this );
2777*cdf0e10cSrcweir }
2778*cdf0e10cSrcweir 
2779*cdf0e10cSrcweir // -----------------------------------------------------------------------
2780*cdf0e10cSrcweir 
2781*cdf0e10cSrcweir void ImplWin::MouseButtonDown( const MouseEvent& )
2782*cdf0e10cSrcweir {
2783*cdf0e10cSrcweir 	if( IsEnabled() )
2784*cdf0e10cSrcweir 	{
2785*cdf0e10cSrcweir //		Control::MouseButtonDown( rMEvt );
2786*cdf0e10cSrcweir 		MBDown();
2787*cdf0e10cSrcweir 	}
2788*cdf0e10cSrcweir }
2789*cdf0e10cSrcweir 
2790*cdf0e10cSrcweir // -----------------------------------------------------------------------
2791*cdf0e10cSrcweir 
2792*cdf0e10cSrcweir void ImplWin::FillLayoutData() const
2793*cdf0e10cSrcweir {
2794*cdf0e10cSrcweir     mpControlData->mpLayoutData = new vcl::ControlLayoutData();
2795*cdf0e10cSrcweir     const_cast<ImplWin*>(this)->ImplDraw( true );
2796*cdf0e10cSrcweir }
2797*cdf0e10cSrcweir 
2798*cdf0e10cSrcweir // -----------------------------------------------------------------------
2799*cdf0e10cSrcweir 
2800*cdf0e10cSrcweir long ImplWin::PreNotify( NotifyEvent& rNEvt )
2801*cdf0e10cSrcweir {
2802*cdf0e10cSrcweir     long nDone = 0;
2803*cdf0e10cSrcweir     const MouseEvent* pMouseEvt = NULL;
2804*cdf0e10cSrcweir 
2805*cdf0e10cSrcweir     if( (rNEvt.GetType() == EVENT_MOUSEMOVE) && (pMouseEvt = rNEvt.GetMouseEvent()) != NULL )
2806*cdf0e10cSrcweir     {
2807*cdf0e10cSrcweir         if( pMouseEvt->IsEnterWindow() || pMouseEvt->IsLeaveWindow() )
2808*cdf0e10cSrcweir         {
2809*cdf0e10cSrcweir             // trigger redraw as mouse over state has changed
2810*cdf0e10cSrcweir             if ( IsNativeControlSupported(CTRL_LISTBOX, PART_ENTIRE_CONTROL)
2811*cdf0e10cSrcweir 			&& ! IsNativeControlSupported(CTRL_LISTBOX, PART_BUTTON_DOWN) )
2812*cdf0e10cSrcweir             {
2813*cdf0e10cSrcweir                 GetParent()->GetWindow( WINDOW_BORDER )->Invalidate( INVALIDATE_NOERASE );
2814*cdf0e10cSrcweir                 GetParent()->GetWindow( WINDOW_BORDER )->Update();
2815*cdf0e10cSrcweir             }
2816*cdf0e10cSrcweir         }
2817*cdf0e10cSrcweir     }
2818*cdf0e10cSrcweir 
2819*cdf0e10cSrcweir     return nDone ? nDone : Control::PreNotify(rNEvt);
2820*cdf0e10cSrcweir }
2821*cdf0e10cSrcweir 
2822*cdf0e10cSrcweir // -----------------------------------------------------------------------
2823*cdf0e10cSrcweir 
2824*cdf0e10cSrcweir void ImplWin::ImplDraw( bool bLayout )
2825*cdf0e10cSrcweir {
2826*cdf0e10cSrcweir 	const StyleSettings& rStyleSettings = GetSettings().GetStyleSettings();
2827*cdf0e10cSrcweir 
2828*cdf0e10cSrcweir     sal_Bool bNativeOK = sal_False;
2829*cdf0e10cSrcweir 
2830*cdf0e10cSrcweir     if( ! bLayout )
2831*cdf0e10cSrcweir     {
2832*cdf0e10cSrcweir         ControlState nState = CTRL_STATE_ENABLED;
2833*cdf0e10cSrcweir         if ( IsNativeControlSupported(CTRL_LISTBOX, PART_ENTIRE_CONTROL)
2834*cdf0e10cSrcweir 			&& IsNativeControlSupported(CTRL_LISTBOX, HAS_BACKGROUND_TEXTURE) )
2835*cdf0e10cSrcweir         {
2836*cdf0e10cSrcweir 	        // Repaint the (focused) area similarly to
2837*cdf0e10cSrcweir 	        // ImplSmallBorderWindowView::DrawWindow() in
2838*cdf0e10cSrcweir 	        // vcl/source/window/brdwin.cxx
2839*cdf0e10cSrcweir 	        Window *pWin = GetParent();
2840*cdf0e10cSrcweir 
2841*cdf0e10cSrcweir 	        ImplControlValue aControlValue;
2842*cdf0e10cSrcweir 	        if ( !pWin->IsEnabled() )
2843*cdf0e10cSrcweir 		    nState &= ~CTRL_STATE_ENABLED;
2844*cdf0e10cSrcweir 	        if ( pWin->HasFocus() )
2845*cdf0e10cSrcweir 		    nState |= CTRL_STATE_FOCUSED;
2846*cdf0e10cSrcweir 
2847*cdf0e10cSrcweir 	        // The listbox is painted over the entire control including the
2848*cdf0e10cSrcweir 	        // border, but ImplWin does not contain the border => correction
2849*cdf0e10cSrcweir 	        // needed.
2850*cdf0e10cSrcweir 	        sal_Int32 nLeft, nTop, nRight, nBottom;
2851*cdf0e10cSrcweir 	        pWin->GetBorder( nLeft, nTop, nRight, nBottom );
2852*cdf0e10cSrcweir 	        Point aPoint( -nLeft, -nTop );
2853*cdf0e10cSrcweir 	        Rectangle aCtrlRegion( aPoint - GetPosPixel(), pWin->GetSizePixel() );
2854*cdf0e10cSrcweir 
2855*cdf0e10cSrcweir             sal_Bool bMouseOver = sal_False;
2856*cdf0e10cSrcweir             if( GetParent() )
2857*cdf0e10cSrcweir             {
2858*cdf0e10cSrcweir                 Window *pChild = GetParent()->GetWindow( WINDOW_FIRSTCHILD );
2859*cdf0e10cSrcweir                 while( pChild && (bMouseOver = pChild->IsMouseOver()) == sal_False )
2860*cdf0e10cSrcweir                     pChild = pChild->GetWindow( WINDOW_NEXT );
2861*cdf0e10cSrcweir             }
2862*cdf0e10cSrcweir 
2863*cdf0e10cSrcweir             if( bMouseOver )
2864*cdf0e10cSrcweir                 nState |= CTRL_STATE_ROLLOVER;
2865*cdf0e10cSrcweir 
2866*cdf0e10cSrcweir             // if parent has no border, then nobody has drawn the background
2867*cdf0e10cSrcweir             // since no border window exists. so draw it here.
2868*cdf0e10cSrcweir             WinBits nParentStyle = pWin->GetStyle();
2869*cdf0e10cSrcweir             if( ! (nParentStyle & WB_BORDER) || (nParentStyle & WB_NOBORDER) )
2870*cdf0e10cSrcweir             {
2871*cdf0e10cSrcweir                 Rectangle aParentRect( Point( 0, 0 ), pWin->GetSizePixel() );
2872*cdf0e10cSrcweir                 pWin->DrawNativeControl( CTRL_LISTBOX, PART_ENTIRE_CONTROL, aParentRect,
2873*cdf0e10cSrcweir                                          nState, aControlValue, rtl::OUString() );
2874*cdf0e10cSrcweir             }
2875*cdf0e10cSrcweir 
2876*cdf0e10cSrcweir 	        bNativeOK = DrawNativeControl( CTRL_LISTBOX, PART_ENTIRE_CONTROL, aCtrlRegion, nState,
2877*cdf0e10cSrcweir 		        aControlValue, rtl::OUString() );
2878*cdf0e10cSrcweir 	    }
2879*cdf0e10cSrcweir 
2880*cdf0e10cSrcweir         if( IsEnabled() )
2881*cdf0e10cSrcweir         {
2882*cdf0e10cSrcweir             if( HasFocus() )
2883*cdf0e10cSrcweir             {
2884*cdf0e10cSrcweir                 SetTextColor( rStyleSettings.GetHighlightTextColor() );
2885*cdf0e10cSrcweir                 SetFillColor( rStyleSettings.GetHighlightColor() );
2886*cdf0e10cSrcweir                 DrawRect( maFocusRect );
2887*cdf0e10cSrcweir             }
2888*cdf0e10cSrcweir             else
2889*cdf0e10cSrcweir             {
2890*cdf0e10cSrcweir                 Color aColor;
2891*cdf0e10cSrcweir                 if( bNativeOK && (nState & CTRL_STATE_ROLLOVER) )
2892*cdf0e10cSrcweir                     aColor = rStyleSettings.GetFieldRolloverTextColor();
2893*cdf0e10cSrcweir                 else
2894*cdf0e10cSrcweir                     aColor = rStyleSettings.GetFieldTextColor();
2895*cdf0e10cSrcweir                 if( IsControlForeground() )
2896*cdf0e10cSrcweir                     aColor = GetControlForeground();
2897*cdf0e10cSrcweir                 SetTextColor( aColor );
2898*cdf0e10cSrcweir 		        if ( !bNativeOK )
2899*cdf0e10cSrcweir 		            Erase( maFocusRect );
2900*cdf0e10cSrcweir             }
2901*cdf0e10cSrcweir         }
2902*cdf0e10cSrcweir         else // Disabled
2903*cdf0e10cSrcweir         {
2904*cdf0e10cSrcweir             SetTextColor( rStyleSettings.GetDisableColor() );
2905*cdf0e10cSrcweir 	        if ( !bNativeOK )
2906*cdf0e10cSrcweir 		        Erase( maFocusRect );
2907*cdf0e10cSrcweir         }
2908*cdf0e10cSrcweir     }
2909*cdf0e10cSrcweir 
2910*cdf0e10cSrcweir 	if ( IsUserDrawEnabled() )
2911*cdf0e10cSrcweir 	{
2912*cdf0e10cSrcweir 		mbInUserDraw = sal_True;
2913*cdf0e10cSrcweir 		UserDrawEvent aUDEvt( this, maFocusRect, mnItemPos, 0 );
2914*cdf0e10cSrcweir 		maUserDrawHdl.Call( &aUDEvt );
2915*cdf0e10cSrcweir 		mbInUserDraw = sal_False;
2916*cdf0e10cSrcweir 	}
2917*cdf0e10cSrcweir 	else
2918*cdf0e10cSrcweir 	{
2919*cdf0e10cSrcweir 		DrawEntry( sal_True, sal_True, sal_False, bLayout );
2920*cdf0e10cSrcweir 	}
2921*cdf0e10cSrcweir }
2922*cdf0e10cSrcweir 
2923*cdf0e10cSrcweir // -----------------------------------------------------------------------
2924*cdf0e10cSrcweir 
2925*cdf0e10cSrcweir void ImplWin::Paint( const Rectangle& )
2926*cdf0e10cSrcweir {
2927*cdf0e10cSrcweir     ImplDraw();
2928*cdf0e10cSrcweir }
2929*cdf0e10cSrcweir 
2930*cdf0e10cSrcweir // -----------------------------------------------------------------------
2931*cdf0e10cSrcweir 
2932*cdf0e10cSrcweir void ImplWin::DrawEntry( sal_Bool bDrawImage, sal_Bool bDrawText, sal_Bool bDrawTextAtImagePos, bool bLayout )
2933*cdf0e10cSrcweir {
2934*cdf0e10cSrcweir 	long nBorder = 1;
2935*cdf0e10cSrcweir 	Size aOutSz = GetOutputSizePixel();
2936*cdf0e10cSrcweir 
2937*cdf0e10cSrcweir 	sal_Bool bImage = !!maImage;
2938*cdf0e10cSrcweir 	if( bDrawImage && bImage && !bLayout )
2939*cdf0e10cSrcweir 	{
2940*cdf0e10cSrcweir 		sal_uInt16 nStyle = 0;
2941*cdf0e10cSrcweir 		Size aImgSz = maImage.GetSizePixel();
2942*cdf0e10cSrcweir 		Point aPtImg( nBorder, ( ( aOutSz.Height() - aImgSz.Height() ) / 2 ) );
2943*cdf0e10cSrcweir 
2944*cdf0e10cSrcweir 		// check for HC mode
2945*cdf0e10cSrcweir 		Image *pImage = &maImage;
2946*cdf0e10cSrcweir 
2947*cdf0e10cSrcweir 		if( !!maImageHC )
2948*cdf0e10cSrcweir 		{
2949*cdf0e10cSrcweir 			if( GetSettings().GetStyleSettings().GetHighContrastMode() )
2950*cdf0e10cSrcweir 				pImage = &maImageHC;
2951*cdf0e10cSrcweir 		}
2952*cdf0e10cSrcweir 
2953*cdf0e10cSrcweir 		if ( !IsZoom() )
2954*cdf0e10cSrcweir 		{
2955*cdf0e10cSrcweir 			DrawImage( aPtImg, *pImage, nStyle );
2956*cdf0e10cSrcweir 		}
2957*cdf0e10cSrcweir 		else
2958*cdf0e10cSrcweir 		{
2959*cdf0e10cSrcweir 			aImgSz.Width() = CalcZoom( aImgSz.Width() );
2960*cdf0e10cSrcweir 			aImgSz.Height() = CalcZoom( aImgSz.Height() );
2961*cdf0e10cSrcweir 			DrawImage( aPtImg, aImgSz, *pImage, nStyle );
2962*cdf0e10cSrcweir 		}
2963*cdf0e10cSrcweir 	}
2964*cdf0e10cSrcweir 
2965*cdf0e10cSrcweir 	if( bDrawText && maString.Len() )
2966*cdf0e10cSrcweir 	{
2967*cdf0e10cSrcweir         sal_uInt16 nTextStyle = TEXT_DRAW_VCENTER;
2968*cdf0e10cSrcweir 
2969*cdf0e10cSrcweir         if ( bDrawImage && bImage && !bLayout )
2970*cdf0e10cSrcweir             nTextStyle |= TEXT_DRAW_LEFT;
2971*cdf0e10cSrcweir         else if ( GetStyle() & WB_CENTER )
2972*cdf0e10cSrcweir             nTextStyle |= TEXT_DRAW_CENTER;
2973*cdf0e10cSrcweir         else if ( GetStyle() & WB_RIGHT )
2974*cdf0e10cSrcweir             nTextStyle |= TEXT_DRAW_RIGHT;
2975*cdf0e10cSrcweir         else
2976*cdf0e10cSrcweir             nTextStyle |= TEXT_DRAW_LEFT;
2977*cdf0e10cSrcweir 
2978*cdf0e10cSrcweir         Rectangle aTextRect( Point( nBorder, 0 ), Size( aOutSz.Width()-2*nBorder, aOutSz.Height() ) );
2979*cdf0e10cSrcweir 
2980*cdf0e10cSrcweir         if ( !bDrawTextAtImagePos && ( bImage || IsUserDrawEnabled() ) )
2981*cdf0e10cSrcweir 		{
2982*cdf0e10cSrcweir 			long nMaxWidth = Max( maImage.GetSizePixel().Width(), maUserItemSize.Width() );
2983*cdf0e10cSrcweir 			aTextRect.Left() += nMaxWidth + IMG_TXT_DISTANCE;
2984*cdf0e10cSrcweir 		}
2985*cdf0e10cSrcweir 
2986*cdf0e10cSrcweir         MetricVector* pVector = bLayout ? &mpControlData->mpLayoutData->m_aUnicodeBoundRects : NULL;
2987*cdf0e10cSrcweir         String* pDisplayText = bLayout ? &mpControlData->mpLayoutData->m_aDisplayText : NULL;
2988*cdf0e10cSrcweir 		DrawText( aTextRect, maString, nTextStyle, pVector, pDisplayText );
2989*cdf0e10cSrcweir 	}
2990*cdf0e10cSrcweir 
2991*cdf0e10cSrcweir 	if( HasFocus() && !bLayout )
2992*cdf0e10cSrcweir 		ShowFocus( maFocusRect );
2993*cdf0e10cSrcweir }
2994*cdf0e10cSrcweir 
2995*cdf0e10cSrcweir // -----------------------------------------------------------------------
2996*cdf0e10cSrcweir 
2997*cdf0e10cSrcweir void ImplWin::Resize()
2998*cdf0e10cSrcweir {
2999*cdf0e10cSrcweir     Control::Resize();
3000*cdf0e10cSrcweir 	maFocusRect.SetSize( GetOutputSizePixel() );
3001*cdf0e10cSrcweir 	Invalidate();
3002*cdf0e10cSrcweir }
3003*cdf0e10cSrcweir 
3004*cdf0e10cSrcweir // -----------------------------------------------------------------------
3005*cdf0e10cSrcweir 
3006*cdf0e10cSrcweir void ImplWin::GetFocus()
3007*cdf0e10cSrcweir {
3008*cdf0e10cSrcweir 	ShowFocus( maFocusRect );
3009*cdf0e10cSrcweir     if( ImplGetSVData()->maNWFData.mbNoFocusRects &&
3010*cdf0e10cSrcweir         IsNativeWidgetEnabled() &&
3011*cdf0e10cSrcweir         IsNativeControlSupported( CTRL_LISTBOX, PART_ENTIRE_CONTROL ) )
3012*cdf0e10cSrcweir     {
3013*cdf0e10cSrcweir         Window* pWin = GetParent()->GetWindow( WINDOW_BORDER );
3014*cdf0e10cSrcweir         if( ! pWin )
3015*cdf0e10cSrcweir             pWin = GetParent();
3016*cdf0e10cSrcweir         pWin->Invalidate();
3017*cdf0e10cSrcweir     }
3018*cdf0e10cSrcweir     else
3019*cdf0e10cSrcweir         Invalidate();
3020*cdf0e10cSrcweir 	Control::GetFocus();
3021*cdf0e10cSrcweir }
3022*cdf0e10cSrcweir 
3023*cdf0e10cSrcweir // -----------------------------------------------------------------------
3024*cdf0e10cSrcweir 
3025*cdf0e10cSrcweir void ImplWin::LoseFocus()
3026*cdf0e10cSrcweir {
3027*cdf0e10cSrcweir 	HideFocus();
3028*cdf0e10cSrcweir     if( ImplGetSVData()->maNWFData.mbNoFocusRects &&
3029*cdf0e10cSrcweir         IsNativeWidgetEnabled() &&
3030*cdf0e10cSrcweir         IsNativeControlSupported( CTRL_LISTBOX, PART_ENTIRE_CONTROL ) )
3031*cdf0e10cSrcweir     {
3032*cdf0e10cSrcweir         Window* pWin = GetParent()->GetWindow( WINDOW_BORDER );
3033*cdf0e10cSrcweir         if( ! pWin )
3034*cdf0e10cSrcweir             pWin = GetParent();
3035*cdf0e10cSrcweir         pWin->Invalidate();
3036*cdf0e10cSrcweir     }
3037*cdf0e10cSrcweir     else
3038*cdf0e10cSrcweir         Invalidate();
3039*cdf0e10cSrcweir 	Control::LoseFocus();
3040*cdf0e10cSrcweir }
3041*cdf0e10cSrcweir 
3042*cdf0e10cSrcweir // =======================================================================
3043*cdf0e10cSrcweir 
3044*cdf0e10cSrcweir ImplBtn::ImplBtn( Window* pParent, WinBits nWinStyle ) :
3045*cdf0e10cSrcweir 	PushButton(  pParent, nWinStyle ),
3046*cdf0e10cSrcweir 	mbDown	( sal_False )
3047*cdf0e10cSrcweir {
3048*cdf0e10cSrcweir }
3049*cdf0e10cSrcweir 
3050*cdf0e10cSrcweir // -----------------------------------------------------------------------
3051*cdf0e10cSrcweir 
3052*cdf0e10cSrcweir void ImplBtn::MBDown()
3053*cdf0e10cSrcweir {
3054*cdf0e10cSrcweir 	if( IsEnabled() )
3055*cdf0e10cSrcweir 	   maMBDownHdl.Call( this );
3056*cdf0e10cSrcweir }
3057*cdf0e10cSrcweir 
3058*cdf0e10cSrcweir // -----------------------------------------------------------------------
3059*cdf0e10cSrcweir 
3060*cdf0e10cSrcweir void ImplBtn::MouseButtonDown( const MouseEvent& )
3061*cdf0e10cSrcweir {
3062*cdf0e10cSrcweir 	//PushButton::MouseButtonDown( rMEvt );
3063*cdf0e10cSrcweir 	if( IsEnabled() )
3064*cdf0e10cSrcweir 	{
3065*cdf0e10cSrcweir 		MBDown();
3066*cdf0e10cSrcweir 		mbDown = sal_True;
3067*cdf0e10cSrcweir 	}
3068*cdf0e10cSrcweir }
3069*cdf0e10cSrcweir 
3070*cdf0e10cSrcweir // =======================================================================
3071*cdf0e10cSrcweir 
3072*cdf0e10cSrcweir ImplListBoxFloatingWindow::ImplListBoxFloatingWindow( Window* pParent ) :
3073*cdf0e10cSrcweir 	FloatingWindow( pParent, WB_BORDER | WB_SYSTEMWINDOW | WB_NOSHADOW )    // no drop shadow for list boxes
3074*cdf0e10cSrcweir {
3075*cdf0e10cSrcweir 	mpImplLB = NULL;
3076*cdf0e10cSrcweir 	mnDDLineCount = 0;
3077*cdf0e10cSrcweir 	mbAutoWidth = sal_False;
3078*cdf0e10cSrcweir 
3079*cdf0e10cSrcweir     mnPopupModeStartSaveSelection = LISTBOX_ENTRY_NOTFOUND;
3080*cdf0e10cSrcweir 
3081*cdf0e10cSrcweir 	EnableSaveBackground();
3082*cdf0e10cSrcweir 
3083*cdf0e10cSrcweir     Window * pBorderWindow = ImplGetBorderWindow();
3084*cdf0e10cSrcweir     if( pBorderWindow )
3085*cdf0e10cSrcweir     {
3086*cdf0e10cSrcweir         SetAccessibleRole(accessibility::AccessibleRole::PANEL);
3087*cdf0e10cSrcweir         pBorderWindow->SetAccessibleRole(accessibility::AccessibleRole::WINDOW);
3088*cdf0e10cSrcweir     }
3089*cdf0e10cSrcweir     else
3090*cdf0e10cSrcweir     {
3091*cdf0e10cSrcweir         SetAccessibleRole(accessibility::AccessibleRole::WINDOW);
3092*cdf0e10cSrcweir     }
3093*cdf0e10cSrcweir 
3094*cdf0e10cSrcweir }
3095*cdf0e10cSrcweir 
3096*cdf0e10cSrcweir // -----------------------------------------------------------------------
3097*cdf0e10cSrcweir 
3098*cdf0e10cSrcweir long ImplListBoxFloatingWindow::PreNotify( NotifyEvent& rNEvt )
3099*cdf0e10cSrcweir {
3100*cdf0e10cSrcweir 	if( rNEvt.GetType() == EVENT_LOSEFOCUS )
3101*cdf0e10cSrcweir 	{
3102*cdf0e10cSrcweir 		if( !GetParent()->HasChildPathFocus( sal_True ) )
3103*cdf0e10cSrcweir 			EndPopupMode();
3104*cdf0e10cSrcweir 	}
3105*cdf0e10cSrcweir 
3106*cdf0e10cSrcweir 	return FloatingWindow::PreNotify( rNEvt );
3107*cdf0e10cSrcweir }
3108*cdf0e10cSrcweir 
3109*cdf0e10cSrcweir // -----------------------------------------------------------------------
3110*cdf0e10cSrcweir 
3111*cdf0e10cSrcweir void ImplListBoxFloatingWindow::SetPosSizePixel( long nX, long nY, long nWidth, long nHeight, sal_uInt16 nFlags )
3112*cdf0e10cSrcweir {
3113*cdf0e10cSrcweir 	FloatingWindow::SetPosSizePixel( nX, nY, nWidth, nHeight, nFlags );
3114*cdf0e10cSrcweir 
3115*cdf0e10cSrcweir 	// Fix #60890# ( MBA ): um auch im aufgeklappten Zustand der Listbox die Gr"o\se einfach zu einen
3116*cdf0e10cSrcweir 	// Aufruf von Resize() "andern zu k"onnen, wird die Position hier ggf. angepa\t
3117*cdf0e10cSrcweir 	if ( IsReallyVisible() && ( nFlags & WINDOW_POSSIZE_HEIGHT ) )
3118*cdf0e10cSrcweir 	{
3119*cdf0e10cSrcweir 		Point aPos = GetParent()->GetPosPixel();
3120*cdf0e10cSrcweir 		aPos = GetParent()->GetParent()->OutputToScreenPixel( aPos );
3121*cdf0e10cSrcweir 
3122*cdf0e10cSrcweir 		if ( nFlags & WINDOW_POSSIZE_X )
3123*cdf0e10cSrcweir 			aPos.X() = nX;
3124*cdf0e10cSrcweir 
3125*cdf0e10cSrcweir 		if ( nFlags & WINDOW_POSSIZE_Y )
3126*cdf0e10cSrcweir 			aPos.Y() = nY;
3127*cdf0e10cSrcweir 
3128*cdf0e10cSrcweir 		sal_uInt16 nIndex;
3129*cdf0e10cSrcweir 		SetPosPixel( ImplCalcPos( this, Rectangle( aPos, GetParent()->GetSizePixel() ), FLOATWIN_POPUPMODE_DOWN, nIndex ) );
3130*cdf0e10cSrcweir 	}
3131*cdf0e10cSrcweir 
3132*cdf0e10cSrcweir //	if( !IsReallyVisible() )
3133*cdf0e10cSrcweir 	{
3134*cdf0e10cSrcweir 		// Die ImplListBox erhaelt kein Resize, weil nicht sichtbar.
3135*cdf0e10cSrcweir 		// Die Fenster muessen aber ein Resize() erhalten, damit die
3136*cdf0e10cSrcweir 		// Anzahl der sichtbaren Eintraege fuer PgUp/PgDown stimmt.
3137*cdf0e10cSrcweir 		// Die Anzahl kann auch nicht von List/Combobox berechnet werden,
3138*cdf0e10cSrcweir 		// weil hierfuer auch die ggf. vorhandene vertikale Scrollbar
3139*cdf0e10cSrcweir 		// beruecksichtigt werden muss.
3140*cdf0e10cSrcweir 		mpImplLB->SetSizePixel( GetOutputSizePixel() );
3141*cdf0e10cSrcweir 		((Window*)mpImplLB)->Resize();
3142*cdf0e10cSrcweir 		((Window*)mpImplLB->GetMainWindow())->Resize();
3143*cdf0e10cSrcweir 	}
3144*cdf0e10cSrcweir }
3145*cdf0e10cSrcweir 
3146*cdf0e10cSrcweir // -----------------------------------------------------------------------
3147*cdf0e10cSrcweir 
3148*cdf0e10cSrcweir void ImplListBoxFloatingWindow::Resize()
3149*cdf0e10cSrcweir {
3150*cdf0e10cSrcweir     mpImplLB->GetMainWindow()->ImplClearLayoutData();
3151*cdf0e10cSrcweir     FloatingWindow::Resize();
3152*cdf0e10cSrcweir }
3153*cdf0e10cSrcweir 
3154*cdf0e10cSrcweir // -----------------------------------------------------------------------
3155*cdf0e10cSrcweir 
3156*cdf0e10cSrcweir Size ImplListBoxFloatingWindow::CalcFloatSize()
3157*cdf0e10cSrcweir {
3158*cdf0e10cSrcweir 	Size aFloatSz( maPrefSz );
3159*cdf0e10cSrcweir 
3160*cdf0e10cSrcweir 	sal_Int32 nLeft, nTop, nRight, nBottom;
3161*cdf0e10cSrcweir 	GetBorder( nLeft, nTop, nRight, nBottom );
3162*cdf0e10cSrcweir 
3163*cdf0e10cSrcweir 	sal_uInt16 nLines = mpImplLB->GetEntryList()->GetEntryCount();
3164*cdf0e10cSrcweir 	if ( mnDDLineCount && ( nLines > mnDDLineCount ) )
3165*cdf0e10cSrcweir 		nLines = mnDDLineCount;
3166*cdf0e10cSrcweir 
3167*cdf0e10cSrcweir 	Size aSz = mpImplLB->CalcSize( nLines );
3168*cdf0e10cSrcweir 	long nMaxHeight = aSz.Height() + nTop + nBottom;
3169*cdf0e10cSrcweir 
3170*cdf0e10cSrcweir 	if ( mnDDLineCount )
3171*cdf0e10cSrcweir 		aFloatSz.Height() = nMaxHeight;
3172*cdf0e10cSrcweir 
3173*cdf0e10cSrcweir 	if( mbAutoWidth )
3174*cdf0e10cSrcweir 	{
3175*cdf0e10cSrcweir 		// AutoSize erstmal nur fuer die Breite...
3176*cdf0e10cSrcweir 
3177*cdf0e10cSrcweir 		aFloatSz.Width() = aSz.Width() + nLeft + nRight;
3178*cdf0e10cSrcweir 		aFloatSz.Width() += nRight; // etwas mehr Platz sieht besser aus...
3179*cdf0e10cSrcweir 
3180*cdf0e10cSrcweir 		if ( ( aFloatSz.Height() < nMaxHeight ) || ( mnDDLineCount && ( mnDDLineCount < mpImplLB->GetEntryList()->GetEntryCount() ) ) )
3181*cdf0e10cSrcweir 		{
3182*cdf0e10cSrcweir 			// dann wird noch der vertikale Scrollbar benoetigt
3183*cdf0e10cSrcweir 			long nSBWidth = GetSettings().GetStyleSettings().GetScrollBarSize();
3184*cdf0e10cSrcweir 			aFloatSz.Width() += nSBWidth;
3185*cdf0e10cSrcweir 		}
3186*cdf0e10cSrcweir 	}
3187*cdf0e10cSrcweir 
3188*cdf0e10cSrcweir 	if ( aFloatSz.Height() > nMaxHeight )
3189*cdf0e10cSrcweir 		aFloatSz.Height() = nMaxHeight;
3190*cdf0e10cSrcweir 
3191*cdf0e10cSrcweir 	// Minimale Hoehe, falls Hoehe nicht auf Float-Hoehe eingestellt wurde.
3192*cdf0e10cSrcweir 	// Der Parent vom FloatWin muss die DropDown-Combo/Listbox sein.
3193*cdf0e10cSrcweir 	Size aParentSz = GetParent()->GetSizePixel();
3194*cdf0e10cSrcweir 	if( !mnDDLineCount && ( aFloatSz.Height() < aParentSz.Height() ) )
3195*cdf0e10cSrcweir 		aFloatSz.Height() = aParentSz.Height();
3196*cdf0e10cSrcweir 
3197*cdf0e10cSrcweir 	// Nicht schmaler als der Parent werden...
3198*cdf0e10cSrcweir 	if( aFloatSz.Width() < aParentSz.Width() )
3199*cdf0e10cSrcweir 		aFloatSz.Width() = aParentSz.Width();
3200*cdf0e10cSrcweir 
3201*cdf0e10cSrcweir 	// Hoehe auf Entries alignen...
3202*cdf0e10cSrcweir 	long nInnerHeight = aFloatSz.Height() - nTop - nBottom;
3203*cdf0e10cSrcweir 	long nEntryHeight = mpImplLB->GetEntryHeight();
3204*cdf0e10cSrcweir 	if ( nInnerHeight % nEntryHeight )
3205*cdf0e10cSrcweir 	{
3206*cdf0e10cSrcweir 		nInnerHeight /= nEntryHeight;
3207*cdf0e10cSrcweir 		nInnerHeight++;
3208*cdf0e10cSrcweir 		nInnerHeight *= nEntryHeight;
3209*cdf0e10cSrcweir 		aFloatSz.Height() = nInnerHeight + nTop + nBottom;
3210*cdf0e10cSrcweir 	}
3211*cdf0e10cSrcweir 
3212*cdf0e10cSrcweir 	return aFloatSz;
3213*cdf0e10cSrcweir }
3214*cdf0e10cSrcweir 
3215*cdf0e10cSrcweir // -----------------------------------------------------------------------
3216*cdf0e10cSrcweir 
3217*cdf0e10cSrcweir void ImplListBoxFloatingWindow::StartFloat( sal_Bool bStartTracking )
3218*cdf0e10cSrcweir {
3219*cdf0e10cSrcweir 	if( !IsInPopupMode() )
3220*cdf0e10cSrcweir 	{
3221*cdf0e10cSrcweir 		Size aFloatSz = CalcFloatSize();
3222*cdf0e10cSrcweir 
3223*cdf0e10cSrcweir 		SetSizePixel( aFloatSz );
3224*cdf0e10cSrcweir 		mpImplLB->SetSizePixel( GetOutputSizePixel() );
3225*cdf0e10cSrcweir 
3226*cdf0e10cSrcweir 		sal_uInt16 nPos = mpImplLB->GetEntryList()->GetSelectEntryPos( 0 );
3227*cdf0e10cSrcweir         mnPopupModeStartSaveSelection = nPos;
3228*cdf0e10cSrcweir 
3229*cdf0e10cSrcweir         Size aSz = GetParent()->GetSizePixel();
3230*cdf0e10cSrcweir 		Point aPos = GetParent()->GetPosPixel();
3231*cdf0e10cSrcweir 		aPos = GetParent()->GetParent()->OutputToScreenPixel( aPos );
3232*cdf0e10cSrcweir         // FIXME: this ugly hack is for Mac/Aqua
3233*cdf0e10cSrcweir         // should be replaced by a real mechanism to place the float rectangle
3234*cdf0e10cSrcweir         if( ImplGetSVData()->maNWFData.mbNoFocusRects &&
3235*cdf0e10cSrcweir             GetParent()->IsNativeWidgetEnabled() )
3236*cdf0e10cSrcweir         {
3237*cdf0e10cSrcweir             sal_Int32 nLeft = 4, nTop = 4, nRight = 4, nBottom = 4;
3238*cdf0e10cSrcweir             aPos.X() += nLeft;
3239*cdf0e10cSrcweir             aPos.Y() += nTop;
3240*cdf0e10cSrcweir             aSz.Width() -= nLeft + nRight;
3241*cdf0e10cSrcweir             aSz.Height() -= nTop + nBottom;
3242*cdf0e10cSrcweir         }
3243*cdf0e10cSrcweir 		Rectangle aRect( aPos, aSz );
3244*cdf0e10cSrcweir 
3245*cdf0e10cSrcweir         // check if the control's parent is un-mirrored which is the case for form controls in a mirrored UI
3246*cdf0e10cSrcweir         // where the document is unmirrored
3247*cdf0e10cSrcweir         // because StartPopupMode() expects a rectangle in mirrored coordinates we have to re-mirror
3248*cdf0e10cSrcweir         if( GetParent()->GetParent()->ImplIsAntiparallel() )
3249*cdf0e10cSrcweir             GetParent()->GetParent()->ImplReMirror( aRect );
3250*cdf0e10cSrcweir 
3251*cdf0e10cSrcweir 		StartPopupMode( aRect, FLOATWIN_POPUPMODE_DOWN );
3252*cdf0e10cSrcweir 
3253*cdf0e10cSrcweir         if( nPos != LISTBOX_ENTRY_NOTFOUND )
3254*cdf0e10cSrcweir             mpImplLB->ShowProminentEntry( nPos );
3255*cdf0e10cSrcweir 
3256*cdf0e10cSrcweir 		if( bStartTracking )
3257*cdf0e10cSrcweir 			mpImplLB->GetMainWindow()->EnableMouseMoveSelect( sal_True );
3258*cdf0e10cSrcweir 
3259*cdf0e10cSrcweir 		if ( mpImplLB->GetMainWindow()->IsGrabFocusAllowed() )
3260*cdf0e10cSrcweir 			mpImplLB->GetMainWindow()->GrabFocus();
3261*cdf0e10cSrcweir 
3262*cdf0e10cSrcweir         mpImplLB->GetMainWindow()->ImplClearLayoutData();
3263*cdf0e10cSrcweir 	}
3264*cdf0e10cSrcweir }
3265