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