xref: /aoo42x/main/vcl/source/control/ilstbox.cxx (revision 86e1cf34)
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 
ImplInitFieldSettings(Window * pWin,sal_Bool bFont,sal_Bool bForeground,sal_Bool bBackground)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 
ImplInitDropDownButton(PushButton * pButton)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 
ImplEntryList(Window * pWindow)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 
~ImplEntryList()111cdf0e10cSrcweir ImplEntryList::~ImplEntryList()
112cdf0e10cSrcweir {
113cdf0e10cSrcweir 	Clear();
114cdf0e10cSrcweir }
115cdf0e10cSrcweir 
116cdf0e10cSrcweir // -----------------------------------------------------------------------
117cdf0e10cSrcweir 
Clear()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 
SelectEntry(sal_uInt16 nPos,sal_Bool bSelect)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 
ImplGetCollator(lang::Locale & rLocale)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 
InsertEntry(sal_uInt16 nPos,ImplEntryType * pNewEntry,sal_Bool bSort)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 		{
233*86e1cf34SPedro Giffuni 			// XXX this is arguable, if the exception occurred because pNewEntry is
234*86e1cf34SPedro Giffuni 			// garbage you wouldn't insert it. If the exception occurred 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 
RemoveEntry(sal_uInt16 nPos)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 
FindEntry(const XubString & rString,sal_Bool bSearchMRUArea) const261cdf0e10cSrcweir 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 
FindMatchingEntry(const XubString & rStr,sal_uInt16 nStart,sal_Bool bForward,sal_Bool bLazy) const276cdf0e10cSrcweir 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 
FindEntry(const void * pData) const306cdf0e10cSrcweir 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 
GetAddedHeight(sal_uInt16 i_nEndIndex,sal_uInt16 i_nBeginIndex,long i_nBeginHeight) const323cdf0e10cSrcweir 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 
GetEntryHeight(sal_uInt16 nPos) const351cdf0e10cSrcweir long ImplEntryList::GetEntryHeight( sal_uInt16 nPos ) const
352cdf0e10cSrcweir {
353cdf0e10cSrcweir 	ImplEntryType* pImplEntry = GetEntry( nPos );
354cdf0e10cSrcweir 	return pImplEntry ? pImplEntry->mnHeight : 0;
355cdf0e10cSrcweir }
356cdf0e10cSrcweir 
357cdf0e10cSrcweir // -----------------------------------------------------------------------
358cdf0e10cSrcweir 
GetEntryText(sal_uInt16 nPos) const359cdf0e10cSrcweir 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 
HasEntryImage(sal_uInt16 nPos) const370cdf0e10cSrcweir 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 
GetEntryImage(sal_uInt16 nPos) const381cdf0e10cSrcweir 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 
SetEntryData(sal_uInt16 nPos,void * pNewData)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 
GetEntryData(sal_uInt16 nPos) const401cdf0e10cSrcweir 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 
SetEntryFlags(sal_uInt16 nPos,long nFlags)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 
GetEntryFlags(sal_uInt16 nPos) const418cdf0e10cSrcweir 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 
GetSelectEntryCount() const426cdf0e10cSrcweir 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 
GetSelectEntry(sal_uInt16 nIndex) const440cdf0e10cSrcweir XubString ImplEntryList::GetSelectEntry( sal_uInt16 nIndex ) const
441cdf0e10cSrcweir {
442cdf0e10cSrcweir 	return GetEntryText( GetSelectEntryPos( nIndex ) );
443cdf0e10cSrcweir }
444cdf0e10cSrcweir 
445cdf0e10cSrcweir // -----------------------------------------------------------------------
446cdf0e10cSrcweir 
GetSelectEntryPos(sal_uInt16 nIndex) const447cdf0e10cSrcweir 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 
IsEntrySelected(const XubString & rStr) const472cdf0e10cSrcweir sal_Bool ImplEntryList::IsEntrySelected( const XubString& rStr ) const
473cdf0e10cSrcweir {
474cdf0e10cSrcweir 	return IsEntryPosSelected( FindEntry( rStr ) );
475cdf0e10cSrcweir }
476cdf0e10cSrcweir 
477cdf0e10cSrcweir // -----------------------------------------------------------------------
478cdf0e10cSrcweir 
IsEntryPosSelected(sal_uInt16 nIndex) const479cdf0e10cSrcweir 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 
IsEntrySelectable(sal_uInt16 nPos) const487cdf0e10cSrcweir 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 
FindFirstSelectable(sal_uInt16 nPos,bool bForward)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 
ImplListBoxWindow(Window * pParent,WinBits nWinStyle)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;
534a68b38dfSArmin Le Grand 	mbTrack 			= false;
535a68b38dfSArmin Le Grand 	mbImgsDiffSz		= false;
536a68b38dfSArmin Le Grand 	mbTravelSelect		= false;
537a68b38dfSArmin Le Grand 	mbTrackingSelect	= false;
538a68b38dfSArmin Le Grand 	mbSelectionChanged	= false;
539a68b38dfSArmin Le Grand 	mbMouseMoveSelect	= false;
540a68b38dfSArmin Le Grand 	mbMulti 			= false;
541a68b38dfSArmin Le Grand 	mbStackMode 		= false;
542a68b38dfSArmin Le Grand 	mbGrabFocus 		= false;
543a68b38dfSArmin Le Grand 	mbUserDrawEnabled	= false;
544a68b38dfSArmin Le Grand 	mbInUserDraw		= false;
545a68b38dfSArmin Le Grand 	mbReadOnly			= false;
546a68b38dfSArmin Le Grand     mbHasFocusRect      = false;
547a68b38dfSArmin Le Grand     mbRight             = ( nWinStyle & WB_RIGHT );
548a68b38dfSArmin Le Grand     mbCenter            = ( nWinStyle & WB_CENTER );
549a68b38dfSArmin Le Grand 	mbSimpleMode		= ( nWinStyle & WB_SIMPLEMODE );
550a68b38dfSArmin Le Grand 	mbSort				= ( nWinStyle & WB_SORT );
551a68b38dfSArmin Le Grand     mbEdgeBlending      = false;
552cdf0e10cSrcweir 
553cdf0e10cSrcweir 	// pb: #106948# explicit mirroring for calc
554a68b38dfSArmin 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 
~ImplListBoxWindow()571cdf0e10cSrcweir ImplListBoxWindow::~ImplListBoxWindow()
572cdf0e10cSrcweir {
573cdf0e10cSrcweir 	delete mpEntryList;
574cdf0e10cSrcweir }
575cdf0e10cSrcweir 
576cdf0e10cSrcweir // -----------------------------------------------------------------------
577cdf0e10cSrcweir 
ImplInitSettings(sal_Bool bFont,sal_Bool bForeground,sal_Bool bBackground)578cdf0e10cSrcweir void ImplListBoxWindow::ImplInitSettings( sal_Bool bFont, sal_Bool bForeground, sal_Bool bBackground )
579cdf0e10cSrcweir {
580cdf0e10cSrcweir 	ImplInitFieldSettings( this, bFont, bForeground, bBackground );
581cdf0e10cSrcweir }
582cdf0e10cSrcweir 
583cdf0e10cSrcweir // -----------------------------------------------------------------------
584cdf0e10cSrcweir 
ImplCalcMetrics()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 
Clear()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;
629a68b38dfSArmin Le Grand 	mbImgsDiffSz	= false;
630cdf0e10cSrcweir     ImplClearLayoutData();
631cdf0e10cSrcweir 
632cdf0e10cSrcweir     mnCurrentPos = LISTBOX_ENTRY_NOTFOUND;
633cdf0e10cSrcweir     maQuickSelectionEngine.Reset();
634cdf0e10cSrcweir 
635cdf0e10cSrcweir 	Invalidate();
636cdf0e10cSrcweir }
637cdf0e10cSrcweir 
SetUserItemSize(const Size & rSz)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 
ImplUpdateEntryMetrics(ImplEntryType & rEntry)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 ) )
705a68b38dfSArmin Le Grand             mbImgsDiffSz = true;
706cdf0e10cSrcweir         else if ( mnMaxImgHeight && ( aMetrics.nImgHeight != mnMaxImgHeight ) )
707a68b38dfSArmin 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 
ImplCallSelect()744cdf0e10cSrcweir void ImplListBoxWindow::ImplCallSelect()
745cdf0e10cSrcweir {
746cdf0e10cSrcweir 	if ( !IsTravelSelect() && GetEntryList()->GetMaxMRUCount() )
747cdf0e10cSrcweir 	{
748*86e1cf34SPedro Giffuni 		// Insert the selected entry as MRU, if not already 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 );
782a68b38dfSArmin Le Grand 	mbSelectionChanged = false;
783cdf0e10cSrcweir }
784cdf0e10cSrcweir 
785cdf0e10cSrcweir // -----------------------------------------------------------------------
786cdf0e10cSrcweir 
InsertEntry(sal_uInt16 nPos,ImplEntryType * pNewEntry)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 
RemoveEntry(sal_uInt16 nPos)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 
SetEntryFlags(sal_uInt16 nPos,long nFlags)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 
ImplShowFocusRect()822cdf0e10cSrcweir void ImplListBoxWindow::ImplShowFocusRect()
823cdf0e10cSrcweir {
824cdf0e10cSrcweir     if ( mbHasFocusRect )
825cdf0e10cSrcweir         HideFocus();
826cdf0e10cSrcweir     ShowFocus( maFocusRect );
827a68b38dfSArmin Le Grand     mbHasFocusRect = true;
828cdf0e10cSrcweir }
829cdf0e10cSrcweir 
830cdf0e10cSrcweir // -----------------------------------------------------------------------
831cdf0e10cSrcweir 
ImplHideFocusRect()832cdf0e10cSrcweir void ImplListBoxWindow::ImplHideFocusRect()
833cdf0e10cSrcweir {
834cdf0e10cSrcweir     if ( mbHasFocusRect )
835cdf0e10cSrcweir     {
836cdf0e10cSrcweir         HideFocus();
837a68b38dfSArmin Le Grand         mbHasFocusRect = false;
838cdf0e10cSrcweir     }
839cdf0e10cSrcweir }
840cdf0e10cSrcweir 
841cdf0e10cSrcweir 
842cdf0e10cSrcweir // -----------------------------------------------------------------------
843cdf0e10cSrcweir 
GetEntryPosForPoint(const Point & rPoint) const844cdf0e10cSrcweir 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 
IsVisible(sal_uInt16 i_nEntry) const863cdf0e10cSrcweir 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 
GetLastVisibleEntry() const881cdf0e10cSrcweir 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 
MouseButtonDown(const MouseEvent & rMEvt)901cdf0e10cSrcweir void ImplListBoxWindow::MouseButtonDown( const MouseEvent& rMEvt )
902cdf0e10cSrcweir {
903a68b38dfSArmin 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;
919a68b38dfSArmin Le Grand 				mbTrackingSelect = true;
920ad3a95a3SSteve Yin 				sal_Bool bCurPosChange = (mnCurrentPos != nSelect);
921ad3a95a3SSteve Yin 				//SelectEntries( nSelect, LET_MBDOWN, rMEvt.IsShift(), rMEvt.IsMod1() );
922ad3a95a3SSteve Yin 				SelectEntries( nSelect, LET_MBDOWN, rMEvt.IsShift(), rMEvt.IsMod1() ,bCurPosChange);
923a68b38dfSArmin Le Grand 				mbTrackingSelect = false;
924cdf0e10cSrcweir 				if ( mbGrabFocus )
925cdf0e10cSrcweir 					GrabFocus();
926cdf0e10cSrcweir 
927cdf0e10cSrcweir 				StartTracking( STARTTRACK_SCROLLREPEAT );
928cdf0e10cSrcweir 			}
929cdf0e10cSrcweir 		}
930cdf0e10cSrcweir 		if( rMEvt.GetClicks() == 2 )
931cdf0e10cSrcweir 		{
932cdf0e10cSrcweir 			maDoubleClickHdl.Call( this );
933cdf0e10cSrcweir 		}
934cdf0e10cSrcweir 	}
935cdf0e10cSrcweir 	else // if ( mbGrabFocus )
936cdf0e10cSrcweir 	{
937cdf0e10cSrcweir 		GrabFocus();
938cdf0e10cSrcweir 	}
939cdf0e10cSrcweir }
940cdf0e10cSrcweir 
941cdf0e10cSrcweir // -----------------------------------------------------------------------
942cdf0e10cSrcweir 
MouseMove(const MouseEvent & rMEvt)943cdf0e10cSrcweir void ImplListBoxWindow::MouseMove( const MouseEvent& rMEvt )
944cdf0e10cSrcweir {
945cdf0e10cSrcweir     if ( rMEvt.IsLeaveWindow() )
946cdf0e10cSrcweir     {
947cdf0e10cSrcweir 		if ( mbStackMode && IsMouseMoveSelect() && IsReallyVisible() )
948cdf0e10cSrcweir 		{
949cdf0e10cSrcweir 			if ( rMEvt.GetPosPixel().Y() < 0 )
950cdf0e10cSrcweir 			{
951cdf0e10cSrcweir 				DeselectAll();
952cdf0e10cSrcweir 				mnCurrentPos = LISTBOX_ENTRY_NOTFOUND;
953cdf0e10cSrcweir                 SetTopEntry( 0 );
954cdf0e10cSrcweir 				if ( mbStackMode ) // #87072#, #92323#
955cdf0e10cSrcweir 				{
956a68b38dfSArmin Le Grand 					mbTravelSelect = true;
957cdf0e10cSrcweir 					mnSelectModifier = rMEvt.GetModifier();
958cdf0e10cSrcweir 					ImplCallSelect();
959a68b38dfSArmin Le Grand 					mbTravelSelect = false;
960cdf0e10cSrcweir 				}
961cdf0e10cSrcweir 
962cdf0e10cSrcweir 			}
963cdf0e10cSrcweir 		}
964cdf0e10cSrcweir     }
965cdf0e10cSrcweir     else if ( ( ( !mbMulti && IsMouseMoveSelect() ) || mbStackMode ) && mpEntryList->GetEntryCount() )
966cdf0e10cSrcweir 	{
967cdf0e10cSrcweir 		Point aPoint;
968cdf0e10cSrcweir 		Rectangle aRect( aPoint, GetOutputSizePixel() );
969cdf0e10cSrcweir 		if( aRect.IsInside( rMEvt.GetPosPixel() ) )
970cdf0e10cSrcweir 		{
971cdf0e10cSrcweir 			if ( IsMouseMoveSelect() )
972cdf0e10cSrcweir 			{
973cdf0e10cSrcweir 				sal_uInt16 nSelect = GetEntryPosForPoint( rMEvt.GetPosPixel() );
974cdf0e10cSrcweir                 if( nSelect == LISTBOX_ENTRY_NOTFOUND )
975cdf0e10cSrcweir                     nSelect = mpEntryList->GetEntryCount() - 1;
976cdf0e10cSrcweir 				nSelect = Min( nSelect, GetLastVisibleEntry() );
977cdf0e10cSrcweir 				nSelect = Min( nSelect, (sal_uInt16) ( mpEntryList->GetEntryCount() - 1 ) );
978cdf0e10cSrcweir 				// Select only visible Entries with MouseMove, otherwise Tracking...
979cdf0e10cSrcweir 				if ( IsVisible( nSelect ) &&
980cdf0e10cSrcweir 					mpEntryList->IsEntrySelectable( nSelect ) &&
981cdf0e10cSrcweir 					( ( nSelect != mnCurrentPos ) || !GetEntryList()->GetSelectEntryCount() || ( nSelect != GetEntryList()->GetSelectEntryPos( 0 ) ) ) )
982cdf0e10cSrcweir 				{
983a68b38dfSArmin Le Grand 					mbTrackingSelect = true;
984cdf0e10cSrcweir 					if ( SelectEntries( nSelect, LET_TRACKING, sal_False, sal_False ) )
985cdf0e10cSrcweir 		            {
986cdf0e10cSrcweir                         if ( mbStackMode ) // #87072#
987cdf0e10cSrcweir                         {
988a68b38dfSArmin Le Grand 			                mbTravelSelect = true;
989cdf0e10cSrcweir 			                mnSelectModifier = rMEvt.GetModifier();
990cdf0e10cSrcweir 			                ImplCallSelect();
991a68b38dfSArmin Le Grand 			                mbTravelSelect = false;
992cdf0e10cSrcweir                         }
993ad3a95a3SSteve Yin 						// When list box selection change by mouse move, notity
994ad3a95a3SSteve Yin 						// VCLEVENT_LISTBOX_SELECT vcl event.
995ad3a95a3SSteve Yin 						else
996ad3a95a3SSteve Yin 						{
997ad3a95a3SSteve Yin 							maListItemSelectHdl.Call(NULL);
998ad3a95a3SSteve Yin 						}
999cdf0e10cSrcweir 		            }
1000a68b38dfSArmin Le Grand 					mbTrackingSelect = false;
1001cdf0e10cSrcweir 				}
1002cdf0e10cSrcweir 			}
1003cdf0e10cSrcweir 
1004cdf0e10cSrcweir 			// Falls der DD-Button gedrueckt wurde und jemand mit gedrueckter
1005cdf0e10cSrcweir 			// Maustaste in die ListBox faehrt...
1006cdf0e10cSrcweir 			if ( rMEvt.IsLeft() && !rMEvt.IsSynthetic() )
1007cdf0e10cSrcweir 			{
1008cdf0e10cSrcweir 				if ( !mbMulti && GetEntryList()->GetSelectEntryCount() )
1009cdf0e10cSrcweir 					mnTrackingSaveSelection = GetEntryList()->GetSelectEntryPos( 0 );
1010cdf0e10cSrcweir 				else
1011cdf0e10cSrcweir 					mnTrackingSaveSelection = LISTBOX_ENTRY_NOTFOUND;
1012cdf0e10cSrcweir 
1013cdf0e10cSrcweir 				if ( mbStackMode && ( mpEntryList->GetSelectionAnchor() == LISTBOX_ENTRY_NOTFOUND ) )
1014cdf0e10cSrcweir 					mpEntryList->SetSelectionAnchor( 0 );
1015cdf0e10cSrcweir 
1016cdf0e10cSrcweir 				StartTracking( STARTTRACK_SCROLLREPEAT );
1017cdf0e10cSrcweir 			}
1018cdf0e10cSrcweir 		}
1019cdf0e10cSrcweir 	}
1020cdf0e10cSrcweir }
1021cdf0e10cSrcweir 
1022cdf0e10cSrcweir // -----------------------------------------------------------------------
1023cdf0e10cSrcweir 
DeselectAll()1024cdf0e10cSrcweir void ImplListBoxWindow::DeselectAll()
1025cdf0e10cSrcweir {
1026cdf0e10cSrcweir 	while ( GetEntryList()->GetSelectEntryCount() )
1027cdf0e10cSrcweir 	{
1028cdf0e10cSrcweir 		sal_uInt16 nS = GetEntryList()->GetSelectEntryPos( 0 );
1029cdf0e10cSrcweir 		SelectEntry( nS, sal_False );
1030cdf0e10cSrcweir 	}
1031cdf0e10cSrcweir }
1032cdf0e10cSrcweir 
1033cdf0e10cSrcweir // -----------------------------------------------------------------------
1034cdf0e10cSrcweir 
SelectEntry(sal_uInt16 nPos,sal_Bool bSelect)1035cdf0e10cSrcweir void ImplListBoxWindow::SelectEntry( sal_uInt16 nPos, sal_Bool bSelect )
1036cdf0e10cSrcweir {
1037cdf0e10cSrcweir 	if( (mpEntryList->IsEntryPosSelected( nPos ) != bSelect) && mpEntryList->IsEntrySelectable( nPos ) )
1038cdf0e10cSrcweir 	{
1039cdf0e10cSrcweir 		ImplHideFocusRect();
1040cdf0e10cSrcweir 		if( bSelect )
1041cdf0e10cSrcweir 		{
1042cdf0e10cSrcweir 			if( !mbMulti )
1043cdf0e10cSrcweir 			{
1044cdf0e10cSrcweir 				// Selektierten Eintrag deselektieren
1045cdf0e10cSrcweir 				sal_uInt16 nDeselect = GetEntryList()->GetSelectEntryPos( 0 );
1046cdf0e10cSrcweir 				if( nDeselect != LISTBOX_ENTRY_NOTFOUND )
1047cdf0e10cSrcweir 				{
1048cdf0e10cSrcweir 					//SelectEntryPos( nDeselect, sal_False );
1049cdf0e10cSrcweir 					GetEntryList()->SelectEntry( nDeselect, sal_False );
1050cdf0e10cSrcweir 					if ( IsUpdateMode() && IsReallyVisible() )
1051cdf0e10cSrcweir 						ImplPaint( nDeselect, sal_True );
1052cdf0e10cSrcweir 				}
1053cdf0e10cSrcweir 			}
1054cdf0e10cSrcweir 			mpEntryList->SelectEntry( nPos, sal_True );
1055cdf0e10cSrcweir 			mnCurrentPos = nPos;
1056cdf0e10cSrcweir 			if ( ( nPos != LISTBOX_ENTRY_NOTFOUND ) && IsUpdateMode() )
1057cdf0e10cSrcweir 			{
1058cdf0e10cSrcweir 				ImplPaint( nPos );
1059cdf0e10cSrcweir 				if ( !IsVisible( nPos ) )
1060cdf0e10cSrcweir                 {
1061cdf0e10cSrcweir                     ImplClearLayoutData();
1062cdf0e10cSrcweir                     sal_uInt16 nVisibleEntries = GetLastVisibleEntry()-mnTop;
1063cdf0e10cSrcweir                     if ( !nVisibleEntries || !IsReallyVisible() || ( nPos < GetTopEntry() ) )
1064cdf0e10cSrcweir                     {
1065cdf0e10cSrcweir                         Resize();
1066cdf0e10cSrcweir 					    ShowProminentEntry( nPos );
1067cdf0e10cSrcweir                     }
1068cdf0e10cSrcweir                     else
1069cdf0e10cSrcweir                     {
1070cdf0e10cSrcweir                         ShowProminentEntry( nPos );
1071cdf0e10cSrcweir                     }
1072cdf0e10cSrcweir                 }
1073cdf0e10cSrcweir 			}
1074cdf0e10cSrcweir 		}
1075cdf0e10cSrcweir 		else
1076cdf0e10cSrcweir 		{
1077cdf0e10cSrcweir 			mpEntryList->SelectEntry( nPos, sal_False );
1078cdf0e10cSrcweir 			ImplPaint( nPos, sal_True );
1079cdf0e10cSrcweir 		}
1080a68b38dfSArmin Le Grand 		mbSelectionChanged = true;
1081cdf0e10cSrcweir 	}
1082cdf0e10cSrcweir }
1083cdf0e10cSrcweir 
1084cdf0e10cSrcweir // -----------------------------------------------------------------------
1085cdf0e10cSrcweir 
SelectEntries(sal_uInt16 nSelect,LB_EVENT_TYPE eLET,sal_Bool bShift,sal_Bool bCtrl,sal_Bool bSelectPosChange)1086ad3a95a3SSteve Yin sal_Bool ImplListBoxWindow::SelectEntries( sal_uInt16 nSelect, LB_EVENT_TYPE eLET, sal_Bool bShift, sal_Bool bCtrl, sal_Bool bSelectPosChange /*=FALSE*/ )
1087cdf0e10cSrcweir {
1088cdf0e10cSrcweir 	sal_Bool bFocusChanged = sal_False;
1089cdf0e10cSrcweir 	sal_Bool bSelectionChanged = sal_False;
1090cdf0e10cSrcweir 
1091cdf0e10cSrcweir 	if( IsEnabled() && mpEntryList->IsEntrySelectable( nSelect ) )
1092cdf0e10cSrcweir 	{
1093cdf0e10cSrcweir 		// Hier (Single-ListBox) kann nur ein Eintrag deselektiert werden
1094cdf0e10cSrcweir 		if( !mbMulti )
1095cdf0e10cSrcweir 		{
1096cdf0e10cSrcweir 			sal_uInt16 nDeselect = mpEntryList->GetSelectEntryPos( 0 );
1097cdf0e10cSrcweir 			if( nSelect != nDeselect )
1098cdf0e10cSrcweir 			{
1099cdf0e10cSrcweir 				SelectEntry( nSelect, sal_True );
1100cdf0e10cSrcweir 				mpEntryList->SetLastSelected( nSelect );
1101cdf0e10cSrcweir 				bFocusChanged = sal_True;
1102cdf0e10cSrcweir 				bSelectionChanged = sal_True;
1103cdf0e10cSrcweir 			}
1104cdf0e10cSrcweir 		}
1105cdf0e10cSrcweir 		// MultiListBox ohne Modifier
1106cdf0e10cSrcweir 		else if( mbSimpleMode && !bCtrl && !bShift )
1107cdf0e10cSrcweir 		{
1108cdf0e10cSrcweir 			sal_uInt16 nEntryCount = mpEntryList->GetEntryCount();
1109cdf0e10cSrcweir 			for ( sal_uInt16 nPos = 0; nPos < nEntryCount; nPos++ )
1110cdf0e10cSrcweir 			{
1111cdf0e10cSrcweir 				sal_Bool bSelect = nPos == nSelect;
1112cdf0e10cSrcweir 				if ( mpEntryList->IsEntryPosSelected( nPos ) != bSelect )
1113cdf0e10cSrcweir 				{
1114cdf0e10cSrcweir 					SelectEntry( nPos, bSelect );
1115cdf0e10cSrcweir 					bFocusChanged = sal_True;
1116cdf0e10cSrcweir 					bSelectionChanged = sal_True;
1117cdf0e10cSrcweir 				}
1118cdf0e10cSrcweir 			}
1119cdf0e10cSrcweir 			mpEntryList->SetLastSelected( nSelect );
1120cdf0e10cSrcweir 			mpEntryList->SetSelectionAnchor( nSelect );
1121cdf0e10cSrcweir 		}
1122cdf0e10cSrcweir 		// MultiListBox nur mit CTRL/SHIFT oder nicht im SimpleMode
1123cdf0e10cSrcweir 		else if( ( !mbSimpleMode /* && !bShift */ ) || ( (mbSimpleMode && ( bCtrl || bShift )) || mbStackMode ) )
1124cdf0e10cSrcweir 		{
1125cdf0e10cSrcweir 			// Space fuer Selektionswechsel
1126cdf0e10cSrcweir 			if( !bShift && ( ( eLET == LET_KEYSPACE ) || ( eLET == LET_MBDOWN ) ) )
1127cdf0e10cSrcweir 			{
1128cdf0e10cSrcweir 				sal_Bool bSelect = ( mbStackMode && IsMouseMoveSelect() ) ? sal_True : !mpEntryList->IsEntryPosSelected( nSelect );
1129cdf0e10cSrcweir 				if ( mbStackMode )
1130cdf0e10cSrcweir 				{
1131cdf0e10cSrcweir 					sal_uInt16 n;
1132cdf0e10cSrcweir 					if ( bSelect )
1133cdf0e10cSrcweir 					{
1134cdf0e10cSrcweir 						// All entries before nSelect must be selected...
1135cdf0e10cSrcweir 						for ( n = 0; n < nSelect; n++ )
1136cdf0e10cSrcweir 							SelectEntry( n, sal_True );
1137cdf0e10cSrcweir 					}
1138cdf0e10cSrcweir 					if ( !bSelect )
1139cdf0e10cSrcweir 					{
1140cdf0e10cSrcweir 						for ( n = nSelect+1; n < mpEntryList->GetEntryCount(); n++ )
1141cdf0e10cSrcweir 							SelectEntry( n, sal_False );
1142cdf0e10cSrcweir 					}
1143cdf0e10cSrcweir 				}
1144cdf0e10cSrcweir 				SelectEntry( nSelect, bSelect );
1145cdf0e10cSrcweir 				mpEntryList->SetLastSelected( nSelect );
1146cdf0e10cSrcweir 				mpEntryList->SetSelectionAnchor( mbStackMode ? 0 : nSelect );
1147cdf0e10cSrcweir 				if ( !mpEntryList->IsEntryPosSelected( nSelect ) )
1148cdf0e10cSrcweir 					mpEntryList->SetSelectionAnchor( LISTBOX_ENTRY_NOTFOUND );
1149cdf0e10cSrcweir 				bFocusChanged = sal_True;
1150cdf0e10cSrcweir 				bSelectionChanged = sal_True;
1151cdf0e10cSrcweir 			}
1152cdf0e10cSrcweir 			else if( ( ( eLET == LET_TRACKING ) && ( nSelect != mnCurrentPos ) ) ||
1153cdf0e10cSrcweir 					 ( (bShift||mbStackMode) && ( ( eLET == LET_KEYMOVE ) || ( eLET == LET_MBDOWN ) ) ) )
1154cdf0e10cSrcweir 			{
1155cdf0e10cSrcweir 				mnCurrentPos = nSelect;
1156cdf0e10cSrcweir 				bFocusChanged = sal_True;
1157cdf0e10cSrcweir 
1158cdf0e10cSrcweir 				sal_uInt16 nAnchor = mpEntryList->GetSelectionAnchor();
1159cdf0e10cSrcweir 				if( ( nAnchor == LISTBOX_ENTRY_NOTFOUND ) && ( mpEntryList->GetSelectEntryCount() || mbStackMode ) )
1160cdf0e10cSrcweir 				{
1161cdf0e10cSrcweir 					nAnchor = mbStackMode ? 0 : mpEntryList->GetSelectEntryPos( mpEntryList->GetSelectEntryCount() - 1 );
1162cdf0e10cSrcweir 				}
1163cdf0e10cSrcweir 				if( nAnchor != LISTBOX_ENTRY_NOTFOUND )
1164cdf0e10cSrcweir 				{
1165cdf0e10cSrcweir 					// Alle Eintraege vom Anchor bis nSelect muessen selektiert sein
1166cdf0e10cSrcweir 					sal_uInt16 nStart = Min( nSelect, nAnchor );
1167cdf0e10cSrcweir 					sal_uInt16 nEnd = Max( nSelect, nAnchor );
1168cdf0e10cSrcweir 					for ( sal_uInt16 n = nStart; n <= nEnd; n++ )
1169cdf0e10cSrcweir 					{
1170cdf0e10cSrcweir 						if ( !mpEntryList->IsEntryPosSelected( n ) )
1171cdf0e10cSrcweir 						{
1172cdf0e10cSrcweir 							SelectEntry( n, sal_True );
1173cdf0e10cSrcweir 							bSelectionChanged = sal_True;
1174cdf0e10cSrcweir 						}
1175cdf0e10cSrcweir 					}
1176cdf0e10cSrcweir 
1177cdf0e10cSrcweir 					// Ggf. muss noch was deselektiert werden...
1178cdf0e10cSrcweir 					sal_uInt16 nLast = mpEntryList->GetLastSelected();
1179cdf0e10cSrcweir 					if ( nLast != LISTBOX_ENTRY_NOTFOUND )
1180cdf0e10cSrcweir 					{
1181cdf0e10cSrcweir 						if ( ( nLast > nSelect ) && ( nLast > nAnchor ) )
1182cdf0e10cSrcweir 						{
1183cdf0e10cSrcweir 							for ( sal_uInt16 n = nSelect+1; n <= nLast; n++ )
1184cdf0e10cSrcweir 							{
1185cdf0e10cSrcweir 								if ( mpEntryList->IsEntryPosSelected( n ) )
1186cdf0e10cSrcweir 								{
1187cdf0e10cSrcweir 									SelectEntry( n, sal_False );
1188cdf0e10cSrcweir 									bSelectionChanged = sal_True;
1189cdf0e10cSrcweir 								}
1190cdf0e10cSrcweir 							}
1191cdf0e10cSrcweir 						}
1192cdf0e10cSrcweir 						else if ( ( nLast < nSelect ) && ( nLast < nAnchor ) )
1193cdf0e10cSrcweir 						{
1194cdf0e10cSrcweir 							for ( sal_uInt16 n = nLast; n < nSelect; n++ )
1195cdf0e10cSrcweir 							{
1196cdf0e10cSrcweir 								if ( mpEntryList->IsEntryPosSelected( n ) )
1197cdf0e10cSrcweir 								{
1198cdf0e10cSrcweir 									SelectEntry( n, sal_False );
1199cdf0e10cSrcweir 									bSelectionChanged = sal_True;
1200cdf0e10cSrcweir 								}
1201cdf0e10cSrcweir 							}
1202cdf0e10cSrcweir 						}
1203cdf0e10cSrcweir 					}
1204cdf0e10cSrcweir 					mpEntryList->SetLastSelected( nSelect );
1205cdf0e10cSrcweir 				}
1206cdf0e10cSrcweir 			}
1207cdf0e10cSrcweir 			else if( eLET != LET_TRACKING )
1208cdf0e10cSrcweir 			{
1209cdf0e10cSrcweir 				ImplHideFocusRect();
1210cdf0e10cSrcweir 				ImplPaint( nSelect, sal_True );
1211cdf0e10cSrcweir 				bFocusChanged = sal_True;
1212cdf0e10cSrcweir 			}
1213cdf0e10cSrcweir 		}
1214cdf0e10cSrcweir 		else if( bShift )
1215cdf0e10cSrcweir 		{
1216cdf0e10cSrcweir 			bFocusChanged = sal_True;
1217cdf0e10cSrcweir 		}
1218cdf0e10cSrcweir 
1219cdf0e10cSrcweir 		if( bSelectionChanged )
1220a68b38dfSArmin Le Grand 			mbSelectionChanged = true;
1221cdf0e10cSrcweir 
1222cdf0e10cSrcweir 		if( bFocusChanged )
1223cdf0e10cSrcweir 		{
1224cdf0e10cSrcweir             long nHeightDiff = mpEntryList->GetAddedHeight( nSelect, mnTop, 0 );
1225cdf0e10cSrcweir 			maFocusRect.SetPos( Point( 0, nHeightDiff ) );
1226cdf0e10cSrcweir             Size aSz( maFocusRect.GetWidth(),
1227cdf0e10cSrcweir                       mpEntryList->GetEntryHeight( nSelect ) );
1228cdf0e10cSrcweir             maFocusRect.SetSize( aSz );
1229cdf0e10cSrcweir 			if( HasFocus() )
1230cdf0e10cSrcweir 				ImplShowFocusRect();
1231ad3a95a3SSteve Yin 			if (bSelectPosChange)
1232ad3a95a3SSteve Yin 			{
1233ad3a95a3SSteve Yin 				maFocusHdl.Call(reinterpret_cast<void*>(nSelect));
1234ad3a95a3SSteve Yin 			}
1235cdf0e10cSrcweir 		}
1236cdf0e10cSrcweir         ImplClearLayoutData();
1237cdf0e10cSrcweir 	}
1238cdf0e10cSrcweir 	return bSelectionChanged;
1239cdf0e10cSrcweir }
1240cdf0e10cSrcweir 
1241cdf0e10cSrcweir // -----------------------------------------------------------------------
1242cdf0e10cSrcweir 
Tracking(const TrackingEvent & rTEvt)1243cdf0e10cSrcweir void ImplListBoxWindow::Tracking( const TrackingEvent& rTEvt )
1244cdf0e10cSrcweir {
1245cdf0e10cSrcweir 	Point aPoint;
1246cdf0e10cSrcweir 	Rectangle aRect( aPoint, GetOutputSizePixel() );
1247cdf0e10cSrcweir 	sal_Bool bInside = aRect.IsInside( rTEvt.GetMouseEvent().GetPosPixel() );
1248cdf0e10cSrcweir 
1249cdf0e10cSrcweir 	if( rTEvt.IsTrackingCanceled() || rTEvt.IsTrackingEnded() ) // MouseButtonUp
1250cdf0e10cSrcweir 	{
1251cdf0e10cSrcweir 		if ( bInside && !rTEvt.IsTrackingCanceled() )
1252cdf0e10cSrcweir 		{
1253cdf0e10cSrcweir 			mnSelectModifier = rTEvt.GetMouseEvent().GetModifier();
1254cdf0e10cSrcweir 			ImplCallSelect();
1255cdf0e10cSrcweir 		}
1256cdf0e10cSrcweir 		else
1257cdf0e10cSrcweir 		{
1258cdf0e10cSrcweir 			maCancelHdl.Call( NULL );
1259cdf0e10cSrcweir 			if ( !mbMulti )
1260cdf0e10cSrcweir 			{
1261a68b38dfSArmin Le Grand 				mbTrackingSelect = true;
1262cdf0e10cSrcweir 				SelectEntry( mnTrackingSaveSelection, sal_True );
1263a68b38dfSArmin Le Grand 				mbTrackingSelect = false;
1264cdf0e10cSrcweir 				if ( mnTrackingSaveSelection != LISTBOX_ENTRY_NOTFOUND )
1265cdf0e10cSrcweir 				{
1266cdf0e10cSrcweir                     long nHeightDiff = mpEntryList->GetAddedHeight( mnCurrentPos, mnTop, 0 );
1267cdf0e10cSrcweir 					maFocusRect.SetPos( Point( 0, nHeightDiff ) );
1268cdf0e10cSrcweir                     Size aSz( maFocusRect.GetWidth(),
1269cdf0e10cSrcweir                               mpEntryList->GetEntryHeight( mnCurrentPos ) );
1270cdf0e10cSrcweir                     maFocusRect.SetSize( aSz );
1271cdf0e10cSrcweir 					ImplShowFocusRect();
1272cdf0e10cSrcweir 				}
1273cdf0e10cSrcweir 			}
1274cdf0e10cSrcweir 		}
1275cdf0e10cSrcweir 
1276a68b38dfSArmin Le Grand 		mbTrack = false;
1277cdf0e10cSrcweir 	}
1278cdf0e10cSrcweir 	else
1279cdf0e10cSrcweir 	{
1280cdf0e10cSrcweir 		sal_Bool bTrackOrQuickClick = mbTrack;
1281cdf0e10cSrcweir 		if( !mbTrack )
1282cdf0e10cSrcweir 		{
1283cdf0e10cSrcweir 			if ( bInside )
1284cdf0e10cSrcweir 			{
1285a68b38dfSArmin Le Grand 				mbTrack = true;
1286cdf0e10cSrcweir 			}
1287cdf0e10cSrcweir 
1288cdf0e10cSrcweir 			// Folgender Fall tritt nur auf, wenn man ganz kurz die Maustaste drueckt
1289cdf0e10cSrcweir 			if( rTEvt.IsTrackingEnded() && mbTrack )
1290cdf0e10cSrcweir 			{
1291cdf0e10cSrcweir 				bTrackOrQuickClick = sal_True;
1292a68b38dfSArmin Le Grand 				mbTrack = false;
1293cdf0e10cSrcweir 			}
1294cdf0e10cSrcweir 		}
1295cdf0e10cSrcweir 
1296cdf0e10cSrcweir 		if( bTrackOrQuickClick )
1297cdf0e10cSrcweir 		{
1298cdf0e10cSrcweir 			MouseEvent aMEvt = rTEvt.GetMouseEvent();
1299cdf0e10cSrcweir 			Point aPt( aMEvt.GetPosPixel() );
1300cdf0e10cSrcweir 			sal_Bool bShift = aMEvt.IsShift();
1301cdf0e10cSrcweir 			sal_Bool bCtrl	= aMEvt.IsMod1();
1302cdf0e10cSrcweir 
1303cdf0e10cSrcweir 			sal_uInt16 nSelect = LISTBOX_ENTRY_NOTFOUND;
1304cdf0e10cSrcweir 			if( aPt.Y() < 0 )
1305cdf0e10cSrcweir 			{
1306cdf0e10cSrcweir                 if ( mnCurrentPos != LISTBOX_ENTRY_NOTFOUND )
1307cdf0e10cSrcweir                 {
1308cdf0e10cSrcweir 				    nSelect = mnCurrentPos ? ( mnCurrentPos - 1 ) : 0;
1309cdf0e10cSrcweir 				    if( nSelect < mnTop )
1310cdf0e10cSrcweir 					    SetTopEntry( mnTop-1 );
1311cdf0e10cSrcweir                 }
1312cdf0e10cSrcweir 			}
1313cdf0e10cSrcweir 			else if( aPt.Y() > GetOutputSizePixel().Height() )
1314cdf0e10cSrcweir 			{
1315cdf0e10cSrcweir                 if ( mnCurrentPos != LISTBOX_ENTRY_NOTFOUND )
1316cdf0e10cSrcweir                 {
1317cdf0e10cSrcweir 				    nSelect = Min(	(sal_uInt16)(mnCurrentPos+1), (sal_uInt16)(mpEntryList->GetEntryCount()-1) );
1318cdf0e10cSrcweir 				    if( nSelect >= GetLastVisibleEntry() )
1319cdf0e10cSrcweir 					    SetTopEntry( mnTop+1 );
1320cdf0e10cSrcweir                 }
1321cdf0e10cSrcweir 			}
1322cdf0e10cSrcweir 			else
1323cdf0e10cSrcweir 			{
1324cdf0e10cSrcweir 				nSelect = (sal_uInt16) ( ( aPt.Y() + mnBorder ) / mnMaxHeight ) + (sal_uInt16) mnTop;
1325cdf0e10cSrcweir 				nSelect = Min( nSelect, GetLastVisibleEntry() );
1326cdf0e10cSrcweir 				nSelect = Min( nSelect, (sal_uInt16) ( mpEntryList->GetEntryCount() - 1 ) );
1327cdf0e10cSrcweir 			}
1328cdf0e10cSrcweir 
1329cdf0e10cSrcweir 			if ( bInside )
1330cdf0e10cSrcweir 			{
1331cdf0e10cSrcweir 				if ( ( nSelect != mnCurrentPos ) || !GetEntryList()->GetSelectEntryCount() )
1332cdf0e10cSrcweir 				{
1333a68b38dfSArmin Le Grand 					mbTrackingSelect = true;
1334cdf0e10cSrcweir 					if ( SelectEntries( nSelect, LET_TRACKING, bShift, bCtrl ) )
1335cdf0e10cSrcweir 		            {
1336cdf0e10cSrcweir                         if ( mbStackMode ) // #87734# (#87072#)
1337cdf0e10cSrcweir                         {
1338a68b38dfSArmin Le Grand 			                mbTravelSelect = true;
1339cdf0e10cSrcweir 			                mnSelectModifier = rTEvt.GetMouseEvent().GetModifier();
1340cdf0e10cSrcweir 			                ImplCallSelect();
1341a68b38dfSArmin Le Grand 			                mbTravelSelect = false;
1342cdf0e10cSrcweir                         }
1343cdf0e10cSrcweir 		            }
1344a68b38dfSArmin Le Grand 					mbTrackingSelect = false;
1345cdf0e10cSrcweir 				}
1346cdf0e10cSrcweir 			}
1347cdf0e10cSrcweir 			else
1348cdf0e10cSrcweir 			{
1349cdf0e10cSrcweir 				if ( !mbMulti && GetEntryList()->GetSelectEntryCount() )
1350cdf0e10cSrcweir 				{
1351a68b38dfSArmin Le Grand 					mbTrackingSelect = true;
1352cdf0e10cSrcweir 					SelectEntry( GetEntryList()->GetSelectEntryPos( 0 ), sal_False );
1353a68b38dfSArmin Le Grand 					mbTrackingSelect = false;
1354cdf0e10cSrcweir 				}
1355cdf0e10cSrcweir 				else if ( mbStackMode )
1356cdf0e10cSrcweir                 {
1357cdf0e10cSrcweir                     if ( ( rTEvt.GetMouseEvent().GetPosPixel().X() > 0 )  && ( rTEvt.GetMouseEvent().GetPosPixel().X() < aRect.Right() ) )
1358cdf0e10cSrcweir                     {
1359cdf0e10cSrcweir 				        if ( ( rTEvt.GetMouseEvent().GetPosPixel().Y() < 0 ) || ( rTEvt.GetMouseEvent().GetPosPixel().Y() > GetOutputSizePixel().Height() ) )
1360cdf0e10cSrcweir 				        {
1361cdf0e10cSrcweir                             sal_Bool bSelectionChanged = sal_False;
1362cdf0e10cSrcweir                             if ( ( rTEvt.GetMouseEvent().GetPosPixel().Y() < 0 )
1363cdf0e10cSrcweir                                    && !mnCurrentPos )
1364cdf0e10cSrcweir                             {
1365cdf0e10cSrcweir                                 if ( mpEntryList->IsEntryPosSelected( 0 ) )
1366cdf0e10cSrcweir                                 {
1367cdf0e10cSrcweir 					                SelectEntry( 0, sal_False );
1368cdf0e10cSrcweir                                     bSelectionChanged = sal_True;
1369cdf0e10cSrcweir                                     nSelect = LISTBOX_ENTRY_NOTFOUND;
1370cdf0e10cSrcweir 
1371cdf0e10cSrcweir                                 }
1372cdf0e10cSrcweir                             }
1373cdf0e10cSrcweir                             else
1374cdf0e10cSrcweir                             {
1375a68b38dfSArmin Le Grand 					            mbTrackingSelect = true;
1376cdf0e10cSrcweir                                 bSelectionChanged = SelectEntries( nSelect, LET_TRACKING, bShift, bCtrl );
1377a68b38dfSArmin Le Grand 					            mbTrackingSelect = false;
1378cdf0e10cSrcweir                             }
1379cdf0e10cSrcweir 
1380cdf0e10cSrcweir                             if ( bSelectionChanged )
1381cdf0e10cSrcweir 		                    {
1382a68b38dfSArmin Le Grand                                 mbSelectionChanged = true;
1383a68b38dfSArmin Le Grand 			                    mbTravelSelect = true;
1384cdf0e10cSrcweir 			                    mnSelectModifier = rTEvt.GetMouseEvent().GetModifier();
1385cdf0e10cSrcweir 			                    ImplCallSelect();
1386a68b38dfSArmin Le Grand 			                    mbTravelSelect = false;
1387cdf0e10cSrcweir 		                    }
1388cdf0e10cSrcweir 				        }
1389cdf0e10cSrcweir                     }
1390cdf0e10cSrcweir                 }
1391cdf0e10cSrcweir 			}
1392cdf0e10cSrcweir 			mnCurrentPos = nSelect;
1393cdf0e10cSrcweir             if ( mnCurrentPos == LISTBOX_ENTRY_NOTFOUND )
1394cdf0e10cSrcweir             {
1395cdf0e10cSrcweir                 ImplHideFocusRect();
1396cdf0e10cSrcweir             }
1397cdf0e10cSrcweir             else
1398cdf0e10cSrcweir             {
1399cdf0e10cSrcweir                 long nHeightDiff = mpEntryList->GetAddedHeight( mnCurrentPos, mnTop, 0 );
1400cdf0e10cSrcweir 				maFocusRect.SetPos( Point( 0, nHeightDiff ) );
1401cdf0e10cSrcweir                 Size aSz( maFocusRect.GetWidth(), mpEntryList->GetEntryHeight( mnCurrentPos ) );
1402cdf0e10cSrcweir                 maFocusRect.SetSize( aSz );
1403cdf0e10cSrcweir 				ImplShowFocusRect();
1404cdf0e10cSrcweir             }
1405cdf0e10cSrcweir 		}
1406cdf0e10cSrcweir 	}
1407cdf0e10cSrcweir }
1408cdf0e10cSrcweir 
1409cdf0e10cSrcweir 
1410cdf0e10cSrcweir // -----------------------------------------------------------------------
1411cdf0e10cSrcweir 
KeyInput(const KeyEvent & rKEvt)1412cdf0e10cSrcweir void ImplListBoxWindow::KeyInput( const KeyEvent& rKEvt )
1413cdf0e10cSrcweir {
1414cdf0e10cSrcweir 	if( !ProcessKeyInput( rKEvt ) )
1415cdf0e10cSrcweir 		Control::KeyInput( rKEvt );
1416cdf0e10cSrcweir }
1417cdf0e10cSrcweir 
1418cdf0e10cSrcweir // -----------------------------------------------------------------------
1419cdf0e10cSrcweir 
1420cdf0e10cSrcweir #define IMPL_SELECT_NODIRECTION	0
1421cdf0e10cSrcweir #define IMPL_SELECT_UP			1
1422cdf0e10cSrcweir #define IMPL_SELECT_DOWN		2
1423cdf0e10cSrcweir 
ProcessKeyInput(const KeyEvent & rKEvt)1424cdf0e10cSrcweir sal_Bool ImplListBoxWindow::ProcessKeyInput( const KeyEvent& rKEvt )
1425cdf0e10cSrcweir {
1426cdf0e10cSrcweir 	// zu selektierender Eintrag
1427cdf0e10cSrcweir 	sal_uInt16 nSelect = LISTBOX_ENTRY_NOTFOUND;
1428cdf0e10cSrcweir 	LB_EVENT_TYPE eLET = LET_KEYMOVE;
1429cdf0e10cSrcweir 
1430cdf0e10cSrcweir 	KeyCode aKeyCode = rKEvt.GetKeyCode();
1431cdf0e10cSrcweir 
1432cdf0e10cSrcweir 	sal_Bool bShift = aKeyCode.IsShift();
1433cdf0e10cSrcweir 	sal_Bool bCtrl	= aKeyCode.IsMod1() || aKeyCode.IsMod3();
1434cdf0e10cSrcweir 	sal_Bool bMod2 = aKeyCode.IsMod2();
1435cdf0e10cSrcweir 	sal_Bool bDone = sal_False;
1436cdf0e10cSrcweir 
1437cdf0e10cSrcweir 	switch( aKeyCode.GetCode() )
1438cdf0e10cSrcweir 	{
1439cdf0e10cSrcweir 		case KEY_UP:
1440cdf0e10cSrcweir 		{
1441cdf0e10cSrcweir 			if ( IsReadOnly() )
1442cdf0e10cSrcweir 			{
1443cdf0e10cSrcweir 				if ( GetTopEntry() )
1444cdf0e10cSrcweir 					SetTopEntry( GetTopEntry()-1 );
1445cdf0e10cSrcweir 			}
1446cdf0e10cSrcweir 			else if ( !bMod2 )
1447cdf0e10cSrcweir 			{
1448cdf0e10cSrcweir 				if( mnCurrentPos == LISTBOX_ENTRY_NOTFOUND )
1449cdf0e10cSrcweir 				{
1450cdf0e10cSrcweir 					nSelect = mpEntryList->FindFirstSelectable( 0, true );
1451cdf0e10cSrcweir 				}
1452cdf0e10cSrcweir 				else if ( mnCurrentPos )
1453cdf0e10cSrcweir 				{
1454cdf0e10cSrcweir 					// search first selectable above the current position
1455cdf0e10cSrcweir 					nSelect = mpEntryList->FindFirstSelectable( mnCurrentPos - 1, false );
1456cdf0e10cSrcweir 				}
1457cdf0e10cSrcweir 
1458cdf0e10cSrcweir 				if( ( nSelect != LISTBOX_ENTRY_NOTFOUND ) && ( nSelect < mnTop ) )
1459cdf0e10cSrcweir 					SetTopEntry( mnTop-1 );
1460cdf0e10cSrcweir 
1461cdf0e10cSrcweir 				bDone = sal_True;
1462cdf0e10cSrcweir 			}
1463cdf0e10cSrcweir             maQuickSelectionEngine.Reset();
1464cdf0e10cSrcweir 		}
1465cdf0e10cSrcweir 		break;
1466cdf0e10cSrcweir 
1467cdf0e10cSrcweir 		case KEY_DOWN:
1468cdf0e10cSrcweir 		{
1469cdf0e10cSrcweir 			if ( IsReadOnly() )
1470cdf0e10cSrcweir 			{
1471cdf0e10cSrcweir 				SetTopEntry( GetTopEntry()+1 );
1472cdf0e10cSrcweir 			}
1473cdf0e10cSrcweir 			else if ( !bMod2 )
1474cdf0e10cSrcweir 			{
1475cdf0e10cSrcweir 				if( mnCurrentPos == LISTBOX_ENTRY_NOTFOUND )
1476cdf0e10cSrcweir 				{
1477cdf0e10cSrcweir 					nSelect = mpEntryList->FindFirstSelectable( 0, true );
1478cdf0e10cSrcweir 				}
1479cdf0e10cSrcweir 				else if ( (mnCurrentPos+1) < mpEntryList->GetEntryCount() )
1480cdf0e10cSrcweir 				{
1481cdf0e10cSrcweir 					// search first selectable below the current position
1482cdf0e10cSrcweir 					nSelect = mpEntryList->FindFirstSelectable( mnCurrentPos + 1, true );
1483cdf0e10cSrcweir 				}
1484cdf0e10cSrcweir 
1485cdf0e10cSrcweir 				if( ( nSelect != LISTBOX_ENTRY_NOTFOUND ) && ( nSelect >= GetLastVisibleEntry() ) )
1486cdf0e10cSrcweir 					SetTopEntry( mnTop+1 );
1487cdf0e10cSrcweir 
1488cdf0e10cSrcweir 				bDone = sal_True;
1489cdf0e10cSrcweir 			}
1490cdf0e10cSrcweir 			maQuickSelectionEngine.Reset();
1491cdf0e10cSrcweir 		}
1492cdf0e10cSrcweir 		break;
1493cdf0e10cSrcweir 
1494cdf0e10cSrcweir 		case KEY_PAGEUP:
1495cdf0e10cSrcweir 		{
1496cdf0e10cSrcweir 			if ( IsReadOnly() )
1497cdf0e10cSrcweir 			{
1498cdf0e10cSrcweir                 sal_uInt16 nCurVis = GetLastVisibleEntry() - mnTop +1;
1499cdf0e10cSrcweir 				SetTopEntry( ( mnTop > nCurVis ) ?
1500cdf0e10cSrcweir 								(mnTop-nCurVis) : 0 );
1501cdf0e10cSrcweir 			}
1502cdf0e10cSrcweir 			else if ( !bCtrl && !bMod2 )
1503cdf0e10cSrcweir 			{
1504cdf0e10cSrcweir 				if( mnCurrentPos == LISTBOX_ENTRY_NOTFOUND )
1505cdf0e10cSrcweir 				{
1506cdf0e10cSrcweir 					nSelect = mpEntryList->FindFirstSelectable( 0, true );
1507cdf0e10cSrcweir 				}
1508cdf0e10cSrcweir 				else if ( mnCurrentPos )
1509cdf0e10cSrcweir 				{
1510cdf0e10cSrcweir 					if( mnCurrentPos == mnTop )
1511cdf0e10cSrcweir                     {
1512cdf0e10cSrcweir                         sal_uInt16 nCurVis = GetLastVisibleEntry() - mnTop +1;
1513cdf0e10cSrcweir 						SetTopEntry( ( mnTop > nCurVis ) ? ( mnTop-nCurVis+1 ) : 0 );
1514cdf0e10cSrcweir                     }
1515cdf0e10cSrcweir 
1516cdf0e10cSrcweir 					// find first selectable starting from mnTop looking foreward
1517cdf0e10cSrcweir 					nSelect = mpEntryList->FindFirstSelectable( mnTop, true );
1518cdf0e10cSrcweir 				}
1519cdf0e10cSrcweir 				bDone = sal_True;
1520cdf0e10cSrcweir 			}
1521cdf0e10cSrcweir 			maQuickSelectionEngine.Reset();
1522cdf0e10cSrcweir 		}
1523cdf0e10cSrcweir 		break;
1524cdf0e10cSrcweir 
1525cdf0e10cSrcweir 		case KEY_PAGEDOWN:
1526cdf0e10cSrcweir 		{
1527cdf0e10cSrcweir 			if ( IsReadOnly() )
1528cdf0e10cSrcweir 			{
1529cdf0e10cSrcweir 				SetTopEntry( GetLastVisibleEntry() );
1530cdf0e10cSrcweir 			}
1531cdf0e10cSrcweir 			else if ( !bCtrl && !bMod2 )
1532cdf0e10cSrcweir 			{
1533cdf0e10cSrcweir 				if( mnCurrentPos == LISTBOX_ENTRY_NOTFOUND )
1534cdf0e10cSrcweir 				{
1535cdf0e10cSrcweir 					nSelect = mpEntryList->FindFirstSelectable( 0, true );
1536cdf0e10cSrcweir 				}
1537cdf0e10cSrcweir 				else if ( (mnCurrentPos+1) < mpEntryList->GetEntryCount() )
1538cdf0e10cSrcweir 				{
1539cdf0e10cSrcweir 					sal_uInt16 nCount = mpEntryList->GetEntryCount();
1540cdf0e10cSrcweir                     sal_uInt16 nCurVis = GetLastVisibleEntry() - mnTop;
1541cdf0e10cSrcweir 					sal_uInt16 nTmp = Min( nCurVis, nCount );
1542cdf0e10cSrcweir 					nTmp += mnTop - 1;
1543cdf0e10cSrcweir 					if( mnCurrentPos == nTmp && mnCurrentPos != nCount - 1 )
1544cdf0e10cSrcweir 					{
1545cdf0e10cSrcweir 						long nTmp2 = Min( (long)(nCount-nCurVis), (long)((long)mnTop+(long)nCurVis-1) );
1546cdf0e10cSrcweir 						nTmp2 = Max( (long)0 , nTmp2 );
1547cdf0e10cSrcweir 						nTmp = (sal_uInt16)(nTmp2+(nCurVis-1) );
1548cdf0e10cSrcweir 						SetTopEntry( (sal_uInt16)nTmp2 );
1549cdf0e10cSrcweir 					}
1550cdf0e10cSrcweir 					// find first selectable starting from nTmp looking backwards
1551cdf0e10cSrcweir 					nSelect = mpEntryList->FindFirstSelectable( nTmp, false );
1552cdf0e10cSrcweir 				}
1553cdf0e10cSrcweir 				bDone = sal_True;
1554cdf0e10cSrcweir 			}
1555cdf0e10cSrcweir 			maQuickSelectionEngine.Reset();
1556cdf0e10cSrcweir 		}
1557cdf0e10cSrcweir 		break;
1558cdf0e10cSrcweir 
1559cdf0e10cSrcweir 		case KEY_HOME:
1560cdf0e10cSrcweir 		{
1561cdf0e10cSrcweir 			if ( IsReadOnly() )
1562cdf0e10cSrcweir 			{
1563cdf0e10cSrcweir 				SetTopEntry( 0 );
1564cdf0e10cSrcweir 			}
1565cdf0e10cSrcweir 			else if ( !bCtrl && !bMod2 )
1566cdf0e10cSrcweir 			{
1567cdf0e10cSrcweir 				if ( mnCurrentPos )
1568cdf0e10cSrcweir 				{
1569cdf0e10cSrcweir 					nSelect = mpEntryList->FindFirstSelectable( mpEntryList->GetEntryCount() ? 0 : LISTBOX_ENTRY_NOTFOUND, true );
1570cdf0e10cSrcweir 					if( mnTop != 0 )
1571cdf0e10cSrcweir 						SetTopEntry( 0 );
1572cdf0e10cSrcweir 
1573cdf0e10cSrcweir 					bDone = sal_True;
1574cdf0e10cSrcweir 				}
1575cdf0e10cSrcweir 			}
1576cdf0e10cSrcweir 			maQuickSelectionEngine.Reset();
1577cdf0e10cSrcweir 		}
1578cdf0e10cSrcweir 		break;
1579cdf0e10cSrcweir 
1580cdf0e10cSrcweir 		case KEY_END:
1581cdf0e10cSrcweir 		{
1582cdf0e10cSrcweir 			if ( IsReadOnly() )
1583cdf0e10cSrcweir 			{
1584cdf0e10cSrcweir 				SetTopEntry( 0xFFFF );
1585cdf0e10cSrcweir 			}
1586cdf0e10cSrcweir 			else if ( !bCtrl && !bMod2 )
1587cdf0e10cSrcweir 			{
1588cdf0e10cSrcweir 				if( mnCurrentPos == LISTBOX_ENTRY_NOTFOUND )
1589cdf0e10cSrcweir 				{
1590cdf0e10cSrcweir 					nSelect = mpEntryList->FindFirstSelectable( 0, true );
1591cdf0e10cSrcweir 				}
1592cdf0e10cSrcweir 				else if ( (mnCurrentPos+1) < mpEntryList->GetEntryCount() )
1593cdf0e10cSrcweir 				{
1594cdf0e10cSrcweir 					sal_uInt16 nCount = mpEntryList->GetEntryCount();
1595cdf0e10cSrcweir 					nSelect = mpEntryList->FindFirstSelectable( nCount - 1, false );
1596cdf0e10cSrcweir                     sal_uInt16 nCurVis = GetLastVisibleEntry() - mnTop + 1;
1597cdf0e10cSrcweir 					if( nCount > nCurVis )
1598cdf0e10cSrcweir 						SetTopEntry( nCount - nCurVis );
1599cdf0e10cSrcweir 				}
1600cdf0e10cSrcweir 				bDone = sal_True;
1601cdf0e10cSrcweir 			}
1602cdf0e10cSrcweir 			maQuickSelectionEngine.Reset();
1603cdf0e10cSrcweir 		}
1604cdf0e10cSrcweir 		break;
1605cdf0e10cSrcweir 
1606cdf0e10cSrcweir 		case KEY_LEFT:
1607cdf0e10cSrcweir 		{
1608cdf0e10cSrcweir 			if ( !bCtrl && !bMod2 )
1609cdf0e10cSrcweir 			{
1610cdf0e10cSrcweir 				ScrollHorz( -HORZ_SCROLL );
1611cdf0e10cSrcweir 				bDone = sal_True;
1612cdf0e10cSrcweir 			}
1613cdf0e10cSrcweir 			maQuickSelectionEngine.Reset();
1614cdf0e10cSrcweir 		}
1615cdf0e10cSrcweir 		break;
1616cdf0e10cSrcweir 
1617cdf0e10cSrcweir 		case KEY_RIGHT:
1618cdf0e10cSrcweir 		{
1619cdf0e10cSrcweir 			if ( !bCtrl && !bMod2 )
1620cdf0e10cSrcweir 			{
1621cdf0e10cSrcweir 				ScrollHorz( HORZ_SCROLL );
1622cdf0e10cSrcweir 				bDone = sal_True;
1623cdf0e10cSrcweir 			}
1624cdf0e10cSrcweir 			maQuickSelectionEngine.Reset();
1625cdf0e10cSrcweir 		}
1626cdf0e10cSrcweir 		break;
1627cdf0e10cSrcweir 
1628cdf0e10cSrcweir 		case KEY_RETURN:
1629cdf0e10cSrcweir 		{
1630cdf0e10cSrcweir 			if ( !bMod2 && !IsReadOnly() )
1631cdf0e10cSrcweir 			{
1632cdf0e10cSrcweir 				mnSelectModifier = rKEvt.GetKeyCode().GetModifier();
1633cdf0e10cSrcweir 				ImplCallSelect();
1634cdf0e10cSrcweir 				bDone = sal_False;	// RETURN nicht abfangen.
1635cdf0e10cSrcweir 			}
1636cdf0e10cSrcweir 			maQuickSelectionEngine.Reset();
1637cdf0e10cSrcweir 		}
1638cdf0e10cSrcweir 		break;
1639cdf0e10cSrcweir 
1640cdf0e10cSrcweir 		case KEY_SPACE:
1641cdf0e10cSrcweir 		{
1642cdf0e10cSrcweir 			if ( !bMod2 && !IsReadOnly() )
1643cdf0e10cSrcweir 			{
1644cdf0e10cSrcweir 				if( mbMulti && ( !mbSimpleMode || ( mbSimpleMode && bCtrl && !bShift ) || mbStackMode ) )
1645cdf0e10cSrcweir 				{
1646cdf0e10cSrcweir 					nSelect = mnCurrentPos;
1647cdf0e10cSrcweir 					eLET = LET_KEYSPACE;
1648cdf0e10cSrcweir 				}
1649cdf0e10cSrcweir 				bDone = sal_True;
1650cdf0e10cSrcweir 			}
1651cdf0e10cSrcweir 			maQuickSelectionEngine.Reset();
1652cdf0e10cSrcweir 		}
1653cdf0e10cSrcweir 		break;
1654cdf0e10cSrcweir 
1655cdf0e10cSrcweir 		case KEY_A:
1656cdf0e10cSrcweir 		{
1657cdf0e10cSrcweir 			if( bCtrl && mbMulti )
1658cdf0e10cSrcweir 			{
1659cdf0e10cSrcweir                 // paint only once
1660cdf0e10cSrcweir                 sal_Bool bUpdates = IsUpdateMode();
1661cdf0e10cSrcweir                 SetUpdateMode( sal_False );
1662cdf0e10cSrcweir 
1663cdf0e10cSrcweir                 sal_uInt16 nEntryCount = mpEntryList->GetEntryCount();
1664cdf0e10cSrcweir                 for( sal_uInt16 i = 0; i < nEntryCount; i++ )
1665cdf0e10cSrcweir                     SelectEntry( i, sal_True );
1666cdf0e10cSrcweir 
1667cdf0e10cSrcweir                 // restore update mode
1668cdf0e10cSrcweir                 SetUpdateMode( bUpdates );
1669cdf0e10cSrcweir                 Invalidate();
1670cdf0e10cSrcweir 
1671cdf0e10cSrcweir                 maQuickSelectionEngine.Reset();
1672cdf0e10cSrcweir 
1673cdf0e10cSrcweir 				bDone = sal_True;
1674cdf0e10cSrcweir                 break;
1675cdf0e10cSrcweir 			}
1676cdf0e10cSrcweir 		}
1677cdf0e10cSrcweir         // fall through intentional
1678cdf0e10cSrcweir 		default:
1679cdf0e10cSrcweir 		{
1680cdf0e10cSrcweir             if ( !IsReadOnly() )
1681cdf0e10cSrcweir             {
1682cdf0e10cSrcweir                 bDone = maQuickSelectionEngine.HandleKeyEvent( rKEvt );
1683cdf0e10cSrcweir             }
1684cdf0e10cSrcweir   		}
1685cdf0e10cSrcweir         break;
1686cdf0e10cSrcweir 	}
1687cdf0e10cSrcweir 
1688cdf0e10cSrcweir     if  (   ( nSelect != LISTBOX_ENTRY_NOTFOUND )
1689cdf0e10cSrcweir         &&  (   ( !mpEntryList->IsEntryPosSelected( nSelect ) )
1690cdf0e10cSrcweir             ||  ( eLET == LET_KEYSPACE )
1691cdf0e10cSrcweir             )
1692cdf0e10cSrcweir         )
1693cdf0e10cSrcweir 	{
1694cdf0e10cSrcweir 		DBG_ASSERT( !mpEntryList->IsEntryPosSelected( nSelect ) || mbMulti, "ImplListBox: Selecting same Entry" );
1695cdf0e10cSrcweir 	    if( nSelect >= mpEntryList->GetEntryCount() )
1696cdf0e10cSrcweir             nSelect = mpEntryList->GetEntryCount()-1;
1697ad3a95a3SSteve Yin 		sal_Bool bCurPosChange = (mnCurrentPos != nSelect);
1698cdf0e10cSrcweir 		mnCurrentPos = nSelect;
1699ad3a95a3SSteve Yin 		//if ( SelectEntries( nSelect, eLET, bShift, bCtrl ) )
1700ad3a95a3SSteve Yin 		if(SelectEntries( nSelect, eLET, bShift, bCtrl ,bCurPosChange))
1701cdf0e10cSrcweir 		{
1702a68b38dfSArmin Le Grand 			mbTravelSelect = true;
1703cdf0e10cSrcweir 			mnSelectModifier = rKEvt.GetKeyCode().GetModifier();
1704cdf0e10cSrcweir 			ImplCallSelect();
1705a68b38dfSArmin Le Grand 			mbTravelSelect = false;
1706cdf0e10cSrcweir 		}
1707cdf0e10cSrcweir 	}
1708cdf0e10cSrcweir 
1709cdf0e10cSrcweir 	return bDone;
1710cdf0e10cSrcweir }
1711cdf0e10cSrcweir 
1712cdf0e10cSrcweir // -----------------------------------------------------------------------
1713cdf0e10cSrcweir namespace
1714cdf0e10cSrcweir {
lcl_getEntry(const ImplEntryList & _rList,sal_uInt16 _nPos,String & _out_entryText)1715cdf0e10cSrcweir     static ::vcl::StringEntryIdentifier lcl_getEntry( const ImplEntryList& _rList, sal_uInt16 _nPos, String& _out_entryText )
1716cdf0e10cSrcweir     {
1717cdf0e10cSrcweir         OSL_PRECOND( ( _nPos != LISTBOX_ENTRY_NOTFOUND ), "lcl_getEntry: invalid position!" );
1718cdf0e10cSrcweir         sal_uInt16 nEntryCount( _rList.GetEntryCount() );
1719cdf0e10cSrcweir         if ( _nPos >= nEntryCount )
1720cdf0e10cSrcweir             _nPos = 0;
1721cdf0e10cSrcweir         _out_entryText = _rList.GetEntryText( _nPos );
1722cdf0e10cSrcweir 
1723cdf0e10cSrcweir         // ::vcl::StringEntryIdentifier does not allow for 0 values, but our position is 0-based
1724cdf0e10cSrcweir         // => normalize
1725cdf0e10cSrcweir         return reinterpret_cast< ::vcl::StringEntryIdentifier >( _nPos + 1 );
1726cdf0e10cSrcweir     }
1727cdf0e10cSrcweir 
lcl_getEntryPos(::vcl::StringEntryIdentifier _entry)1728cdf0e10cSrcweir     static sal_uInt16 lcl_getEntryPos( ::vcl::StringEntryIdentifier _entry )
1729cdf0e10cSrcweir     {
1730cdf0e10cSrcweir         // our pos is 0-based, but StringEntryIdentifier does not allow for a NULL
1731cdf0e10cSrcweir         return static_cast< sal_uInt16 >( reinterpret_cast< sal_Int64 >( _entry ) ) - 1;
1732cdf0e10cSrcweir     }
1733cdf0e10cSrcweir }
1734cdf0e10cSrcweir 
1735cdf0e10cSrcweir // -----------------------------------------------------------------------
CurrentEntry(String & _out_entryText) const1736cdf0e10cSrcweir ::vcl::StringEntryIdentifier ImplListBoxWindow::CurrentEntry( String& _out_entryText ) const
1737cdf0e10cSrcweir {
1738cdf0e10cSrcweir     return lcl_getEntry( *GetEntryList(), ( mnCurrentPos == LISTBOX_ENTRY_NOTFOUND ) ? 0 : mnCurrentPos + 1, _out_entryText );
1739cdf0e10cSrcweir }
1740cdf0e10cSrcweir 
1741cdf0e10cSrcweir // -----------------------------------------------------------------------
NextEntry(::vcl::StringEntryIdentifier _currentEntry,String & _out_entryText) const1742cdf0e10cSrcweir ::vcl::StringEntryIdentifier ImplListBoxWindow::NextEntry( ::vcl::StringEntryIdentifier _currentEntry, String& _out_entryText ) const
1743cdf0e10cSrcweir {
1744cdf0e10cSrcweir     sal_uInt16 nNextPos = lcl_getEntryPos( _currentEntry ) + 1;
1745cdf0e10cSrcweir     return lcl_getEntry( *GetEntryList(), nNextPos, _out_entryText );
1746cdf0e10cSrcweir }
1747cdf0e10cSrcweir 
1748cdf0e10cSrcweir // -----------------------------------------------------------------------
SelectEntry(::vcl::StringEntryIdentifier _entry)1749cdf0e10cSrcweir void ImplListBoxWindow::SelectEntry( ::vcl::StringEntryIdentifier _entry )
1750cdf0e10cSrcweir {
1751cdf0e10cSrcweir     sal_uInt16 nSelect = lcl_getEntryPos( _entry );
1752cdf0e10cSrcweir     if ( mpEntryList->IsEntryPosSelected( nSelect ) )
1753cdf0e10cSrcweir     {
1754cdf0e10cSrcweir         // ignore that. This method is a callback from the QuickSelectionEngine, which means the user attempted
1755cdf0e10cSrcweir         // to select the given entry by typing its starting letters. No need to act.
1756cdf0e10cSrcweir         return;
1757cdf0e10cSrcweir     }
1758cdf0e10cSrcweir 
1759cdf0e10cSrcweir     // normalize
1760cdf0e10cSrcweir     OSL_ENSURE( nSelect < mpEntryList->GetEntryCount(), "ImplListBoxWindow::SelectEntry: how that?" );
1761cdf0e10cSrcweir     if( nSelect >= mpEntryList->GetEntryCount() )
1762cdf0e10cSrcweir         nSelect = mpEntryList->GetEntryCount()-1;
1763cdf0e10cSrcweir 
1764cdf0e10cSrcweir     // make visible
1765cdf0e10cSrcweir     ShowProminentEntry( nSelect );
1766cdf0e10cSrcweir 
1767cdf0e10cSrcweir     // actually select
1768cdf0e10cSrcweir     mnCurrentPos = nSelect;
1769cdf0e10cSrcweir 	if ( SelectEntries( nSelect, LET_KEYMOVE, sal_False, sal_False ) )
1770cdf0e10cSrcweir 	{
1771a68b38dfSArmin Le Grand 		mbTravelSelect = true;
1772cdf0e10cSrcweir 		mnSelectModifier = 0;
1773cdf0e10cSrcweir 		ImplCallSelect();
1774a68b38dfSArmin Le Grand 		mbTravelSelect = false;
1775cdf0e10cSrcweir 	}
1776cdf0e10cSrcweir }
1777cdf0e10cSrcweir 
1778cdf0e10cSrcweir // -----------------------------------------------------------------------
1779cdf0e10cSrcweir 
ImplPaint(sal_uInt16 nPos,sal_Bool bErase,bool bLayout)1780cdf0e10cSrcweir void ImplListBoxWindow::ImplPaint( sal_uInt16 nPos, sal_Bool bErase, bool bLayout )
1781cdf0e10cSrcweir {
1782cdf0e10cSrcweir 	const StyleSettings& rStyleSettings = GetSettings().GetStyleSettings();
1783cdf0e10cSrcweir 
1784cdf0e10cSrcweir     const ImplEntryType* pEntry = mpEntryList->GetEntryPtr( nPos );
1785cdf0e10cSrcweir     if( ! pEntry )
1786cdf0e10cSrcweir         return;
1787cdf0e10cSrcweir 
1788cdf0e10cSrcweir 	long nWidth  = GetOutputSizePixel().Width();
1789cdf0e10cSrcweir 	long nY = mpEntryList->GetAddedHeight( nPos, mnTop );
1790cdf0e10cSrcweir 	Rectangle aRect( Point( 0, nY ), Size( nWidth, pEntry->mnHeight ) );
1791cdf0e10cSrcweir 
1792cdf0e10cSrcweir     if( ! bLayout )
1793cdf0e10cSrcweir     {
1794cdf0e10cSrcweir         if( mpEntryList->IsEntryPosSelected( nPos ) )
1795cdf0e10cSrcweir         {
1796cdf0e10cSrcweir             SetTextColor( !IsEnabled() ? rStyleSettings.GetDisableColor() : rStyleSettings.GetHighlightTextColor() );
1797cdf0e10cSrcweir             SetFillColor( rStyleSettings.GetHighlightColor() );
1798cdf0e10cSrcweir             SetTextFillColor( rStyleSettings.GetHighlightColor() );
1799cdf0e10cSrcweir             DrawRect( aRect );
1800cdf0e10cSrcweir         }
1801cdf0e10cSrcweir         else
1802cdf0e10cSrcweir         {
1803cdf0e10cSrcweir             ImplInitSettings( sal_False, sal_True, sal_False );
1804cdf0e10cSrcweir             if( !IsEnabled() )
1805cdf0e10cSrcweir                 SetTextColor( rStyleSettings.GetDisableColor() );
1806cdf0e10cSrcweir             SetTextFillColor();
1807cdf0e10cSrcweir             if( bErase )
1808cdf0e10cSrcweir                 Erase( aRect );
1809cdf0e10cSrcweir         }
1810cdf0e10cSrcweir     }
1811cdf0e10cSrcweir 
1812cdf0e10cSrcweir     if ( IsUserDrawEnabled() )
1813cdf0e10cSrcweir     {
1814a68b38dfSArmin Le Grand         mbInUserDraw = true;
1815cdf0e10cSrcweir 		mnUserDrawEntry = nPos;
1816cdf0e10cSrcweir 		aRect.Left() -= mnLeft;
1817cdf0e10cSrcweir 		if ( nPos < GetEntryList()->GetMRUCount() )
1818cdf0e10cSrcweir 			nPos = GetEntryList()->FindEntry( GetEntryList()->GetEntryText( nPos ) );
1819cdf0e10cSrcweir 		nPos = sal::static_int_cast<sal_uInt16>(nPos - GetEntryList()->GetMRUCount());
1820cdf0e10cSrcweir 		UserDrawEvent aUDEvt( this, aRect, nPos, 0 );
1821cdf0e10cSrcweir 		maUserDrawHdl.Call( &aUDEvt );
1822a68b38dfSArmin Le Grand 		mbInUserDraw = false;
1823cdf0e10cSrcweir 	}
1824cdf0e10cSrcweir 	else
1825cdf0e10cSrcweir 	{
1826cdf0e10cSrcweir 		DrawEntry( nPos, sal_True, sal_True, sal_False, bLayout );
1827cdf0e10cSrcweir 	}
1828cdf0e10cSrcweir }
1829cdf0e10cSrcweir 
1830cdf0e10cSrcweir // -----------------------------------------------------------------------
1831cdf0e10cSrcweir 
DrawEntry(sal_uInt16 nPos,sal_Bool bDrawImage,sal_Bool bDrawText,sal_Bool bDrawTextAtImagePos,bool bLayout)1832cdf0e10cSrcweir void ImplListBoxWindow::DrawEntry( sal_uInt16 nPos, sal_Bool bDrawImage, sal_Bool bDrawText, sal_Bool bDrawTextAtImagePos, bool bLayout )
1833cdf0e10cSrcweir {
1834cdf0e10cSrcweir     const ImplEntryType* pEntry = mpEntryList->GetEntryPtr( nPos );
1835cdf0e10cSrcweir     if( ! pEntry )
1836cdf0e10cSrcweir         return;
1837cdf0e10cSrcweir 
1838cdf0e10cSrcweir 	// Bei Aenderungen in dieser Methode ggf. auch ImplWin::DrawEntry() anpassen.
1839cdf0e10cSrcweir 
1840cdf0e10cSrcweir 	if ( mbInUserDraw )
1841cdf0e10cSrcweir 		nPos = mnUserDrawEntry; // real entry, not the matching entry from MRU
1842cdf0e10cSrcweir 
1843cdf0e10cSrcweir     long nY = mpEntryList->GetAddedHeight( nPos, mnTop );
1844cdf0e10cSrcweir 	Size aImgSz;
1845cdf0e10cSrcweir 
1846cdf0e10cSrcweir 	if( bDrawImage && mpEntryList->HasImages() && !bLayout )
1847cdf0e10cSrcweir 	{
1848cdf0e10cSrcweir 		Image aImage = mpEntryList->GetEntryImage( nPos );
1849cdf0e10cSrcweir 		if( !!aImage )
1850cdf0e10cSrcweir 		{
1851cdf0e10cSrcweir             aImgSz = aImage.GetSizePixel();
1852cdf0e10cSrcweir 			Point aPtImg( mnBorder - mnLeft, nY + ( ( pEntry->mnHeight - aImgSz.Height() ) / 2 ) );
1853cdf0e10cSrcweir 
1854cdf0e10cSrcweir 			// pb: #106948# explicit mirroring for calc
1855cdf0e10cSrcweir 			if ( mbMirroring )
1856cdf0e10cSrcweir 				// right aligned
1857cdf0e10cSrcweir 				aPtImg.X() = mnMaxWidth + mnBorder - aImgSz.Width() - mnLeft;
1858cdf0e10cSrcweir 
1859cdf0e10cSrcweir 			if ( !IsZoom() )
1860cdf0e10cSrcweir 			{
1861cdf0e10cSrcweir 				DrawImage( aPtImg, aImage );
1862cdf0e10cSrcweir 			}
1863cdf0e10cSrcweir 			else
1864cdf0e10cSrcweir 			{
1865cdf0e10cSrcweir 				aImgSz.Width() = CalcZoom( aImgSz.Width() );
1866cdf0e10cSrcweir 				aImgSz.Height() = CalcZoom( aImgSz.Height() );
1867cdf0e10cSrcweir 				DrawImage( aPtImg, aImgSz, aImage );
1868cdf0e10cSrcweir 			}
1869a68b38dfSArmin Le Grand 
1870a68b38dfSArmin Le Grand             const StyleSettings& rStyleSettings = Application::GetSettings().GetStyleSettings();
1871a68b38dfSArmin Le Grand             const sal_uInt16 nEdgeBlendingPercent(GetEdgeBlending() ? rStyleSettings.GetEdgeBlending() : 0);
1872a68b38dfSArmin Le Grand 
1873ff0f521cSArmin Le Grand             if(nEdgeBlendingPercent && aImgSz.Width() && aImgSz.Height())
1874a68b38dfSArmin Le Grand             {
1875ff0f521cSArmin Le Grand                 const Color& rTopLeft(rStyleSettings.GetEdgeBlendingTopLeftColor());
1876ff0f521cSArmin Le Grand                 const Color& rBottomRight(rStyleSettings.GetEdgeBlendingBottomRightColor());
1877ff0f521cSArmin Le Grand                 const sal_uInt8 nAlpha((nEdgeBlendingPercent * 255) / 100);
1878ff0f521cSArmin Le Grand                 const BitmapEx aBlendFrame(createBlendFrame(aImgSz, nAlpha, rTopLeft, rBottomRight));
1879a68b38dfSArmin Le Grand 
1880ff0f521cSArmin Le Grand                 if(!aBlendFrame.IsEmpty())
1881a68b38dfSArmin Le Grand                 {
1882ff0f521cSArmin Le Grand                     DrawBitmapEx(aPtImg, aBlendFrame);
1883a68b38dfSArmin Le Grand                 }
1884a68b38dfSArmin Le Grand             }
1885cdf0e10cSrcweir 		}
1886cdf0e10cSrcweir 	}
1887cdf0e10cSrcweir 
1888cdf0e10cSrcweir 	if( bDrawText )
1889cdf0e10cSrcweir 	{
1890cdf0e10cSrcweir         MetricVector* pVector = bLayout ? &mpControlData->mpLayoutData->m_aUnicodeBoundRects : NULL;
1891cdf0e10cSrcweir         String* pDisplayText = bLayout ? &mpControlData->mpLayoutData->m_aDisplayText : NULL;
1892cdf0e10cSrcweir 		XubString aStr( mpEntryList->GetEntryText( nPos ) );
1893cdf0e10cSrcweir 		if ( aStr.Len() )
1894cdf0e10cSrcweir 		{
1895cdf0e10cSrcweir             long nMaxWidth = Max( static_cast< long >( mnMaxWidth ),
1896cdf0e10cSrcweir                                   GetOutputSizePixel().Width() - 2*mnBorder );
1897cdf0e10cSrcweir             // a multiline entry should only be as wide a the window
1898cdf0e10cSrcweir             if( (pEntry->mnFlags & LISTBOX_ENTRY_FLAG_MULTILINE) )
1899cdf0e10cSrcweir                 nMaxWidth = GetOutputSizePixel().Width() - 2*mnBorder;
1900cdf0e10cSrcweir 
1901cdf0e10cSrcweir             Rectangle aTextRect( Point( mnBorder - mnLeft, nY ),
1902cdf0e10cSrcweir                                  Size( nMaxWidth, pEntry->mnHeight ) );
1903cdf0e10cSrcweir 
1904cdf0e10cSrcweir             if( !bDrawTextAtImagePos && ( mpEntryList->HasEntryImage(nPos) || IsUserDrawEnabled() ) )
1905cdf0e10cSrcweir 			{
1906cdf0e10cSrcweir 				long nImageWidth = Max( mnMaxImgWidth, maUserItemSize.Width() );
1907cdf0e10cSrcweir                 aTextRect.Left() += nImageWidth + IMG_TXT_DISTANCE;
1908cdf0e10cSrcweir 			}
1909cdf0e10cSrcweir 
1910cdf0e10cSrcweir             if( bLayout )
1911cdf0e10cSrcweir                 mpControlData->mpLayoutData->m_aLineIndices.push_back( mpControlData->mpLayoutData->m_aDisplayText.Len() );
1912cdf0e10cSrcweir 
1913cdf0e10cSrcweir 			// pb: #106948# explicit mirroring for calc
1914cdf0e10cSrcweir 			if ( mbMirroring )
1915cdf0e10cSrcweir 			{
1916cdf0e10cSrcweir 				// right aligned
1917cdf0e10cSrcweir                 aTextRect.Left() = nMaxWidth + mnBorder - GetTextWidth( aStr ) - mnLeft;
1918cdf0e10cSrcweir 				if ( aImgSz.Width() > 0 )
1919cdf0e10cSrcweir 					aTextRect.Left() -= ( aImgSz.Width() + IMG_TXT_DISTANCE );
1920cdf0e10cSrcweir 			}
1921cdf0e10cSrcweir 
1922cdf0e10cSrcweir             sal_uInt16 nDrawStyle = ImplGetTextStyle();
1923cdf0e10cSrcweir             if( (pEntry->mnFlags & LISTBOX_ENTRY_FLAG_MULTILINE) )
1924cdf0e10cSrcweir                 nDrawStyle |= MULTILINE_ENTRY_DRAW_FLAGS;
1925cdf0e10cSrcweir             if( (pEntry->mnFlags & LISTBOX_ENTRY_FLAG_DRAW_DISABLED) )
1926cdf0e10cSrcweir                 nDrawStyle |= TEXT_DRAW_DISABLE;
1927cdf0e10cSrcweir 
1928cdf0e10cSrcweir             DrawText( aTextRect, aStr, nDrawStyle, pVector, pDisplayText );
1929cdf0e10cSrcweir 		}
1930cdf0e10cSrcweir 	}
1931cdf0e10cSrcweir 
1932cdf0e10cSrcweir     if( !bLayout )
1933cdf0e10cSrcweir     {
1934cdf0e10cSrcweir         if ( ( mnSeparatorPos != LISTBOX_ENTRY_NOTFOUND ) &&
1935cdf0e10cSrcweir              ( ( nPos == mnSeparatorPos ) || ( nPos == mnSeparatorPos+1 ) ) )
1936cdf0e10cSrcweir         {
1937cdf0e10cSrcweir             Color aOldLineColor( GetLineColor() );
1938cdf0e10cSrcweir             SetLineColor( ( GetBackground().GetColor() != COL_LIGHTGRAY ) ? COL_LIGHTGRAY : COL_GRAY );
1939cdf0e10cSrcweir             Point aStartPos( 0, nY );
1940cdf0e10cSrcweir             if ( nPos == mnSeparatorPos )
1941cdf0e10cSrcweir                 aStartPos.Y() += pEntry->mnHeight-1;
1942cdf0e10cSrcweir             Point aEndPos( aStartPos );
1943cdf0e10cSrcweir             aEndPos.X() = GetOutputSizePixel().Width();
1944cdf0e10cSrcweir             DrawLine( aStartPos, aEndPos );
1945cdf0e10cSrcweir             SetLineColor( aOldLineColor );
1946cdf0e10cSrcweir         }
1947cdf0e10cSrcweir     }
1948cdf0e10cSrcweir }
1949cdf0e10cSrcweir 
1950cdf0e10cSrcweir // -----------------------------------------------------------------------
1951cdf0e10cSrcweir 
FillLayoutData() const1952cdf0e10cSrcweir void ImplListBoxWindow::FillLayoutData() const
1953cdf0e10cSrcweir {
1954cdf0e10cSrcweir     mpControlData->mpLayoutData = new vcl::ControlLayoutData();
1955cdf0e10cSrcweir     const_cast<ImplListBoxWindow*>(this)->
1956cdf0e10cSrcweir         ImplDoPaint( Rectangle( Point( 0, 0 ), GetOutputSize() ), true );
1957cdf0e10cSrcweir }
1958cdf0e10cSrcweir 
1959cdf0e10cSrcweir // -----------------------------------------------------------------------
1960cdf0e10cSrcweir 
ImplDoPaint(const Rectangle & rRect,bool bLayout)1961cdf0e10cSrcweir void ImplListBoxWindow::ImplDoPaint( const Rectangle& rRect, bool bLayout )
1962cdf0e10cSrcweir {
1963cdf0e10cSrcweir 	sal_uInt16 nCount = mpEntryList->GetEntryCount();
1964cdf0e10cSrcweir 
1965cdf0e10cSrcweir     sal_Bool bShowFocusRect = mbHasFocusRect;
1966cdf0e10cSrcweir     if ( mbHasFocusRect && ! bLayout )
1967cdf0e10cSrcweir         ImplHideFocusRect();
1968cdf0e10cSrcweir 
1969cdf0e10cSrcweir 	long nY = 0; // + mnBorder;
1970cdf0e10cSrcweir 	long nHeight = GetOutputSizePixel().Height();// - mnMaxHeight + mnBorder;
1971cdf0e10cSrcweir 
1972cdf0e10cSrcweir 	for( sal_uInt16 i = (sal_uInt16)mnTop; i < nCount && nY < nHeight + mnMaxHeight; i++ )
1973cdf0e10cSrcweir 	{
1974cdf0e10cSrcweir         const ImplEntryType* pEntry = mpEntryList->GetEntryPtr( i );
1975cdf0e10cSrcweir 		if( nY + pEntry->mnHeight >= rRect.Top() &&
1976cdf0e10cSrcweir 			nY <= rRect.Bottom() + mnMaxHeight )
1977cdf0e10cSrcweir 		{
1978cdf0e10cSrcweir 			ImplPaint( i, sal_False, bLayout );
1979cdf0e10cSrcweir 		}
1980cdf0e10cSrcweir 		nY += pEntry->mnHeight;
1981cdf0e10cSrcweir 	}
1982cdf0e10cSrcweir 
1983cdf0e10cSrcweir     long nHeightDiff = mpEntryList->GetAddedHeight( mnCurrentPos, mnTop, 0 );
1984cdf0e10cSrcweir 	maFocusRect.SetPos( Point( 0, nHeightDiff ) );
1985cdf0e10cSrcweir     Size aSz( maFocusRect.GetWidth(), mpEntryList->GetEntryHeight( mnCurrentPos ) );
1986cdf0e10cSrcweir     maFocusRect.SetSize( aSz );
1987cdf0e10cSrcweir 	if( HasFocus() && bShowFocusRect && !bLayout )
1988cdf0e10cSrcweir 		ImplShowFocusRect();
1989cdf0e10cSrcweir }
1990cdf0e10cSrcweir 
1991cdf0e10cSrcweir // -----------------------------------------------------------------------
1992cdf0e10cSrcweir 
Paint(const Rectangle & rRect)1993cdf0e10cSrcweir void ImplListBoxWindow::Paint( const Rectangle& rRect )
1994cdf0e10cSrcweir {
1995cdf0e10cSrcweir     ImplDoPaint( rRect );
1996cdf0e10cSrcweir }
1997cdf0e10cSrcweir 
1998cdf0e10cSrcweir // -----------------------------------------------------------------------
1999cdf0e10cSrcweir 
GetDisplayLineCount() const2000cdf0e10cSrcweir sal_uInt16 ImplListBoxWindow::GetDisplayLineCount() const
2001cdf0e10cSrcweir {
2002cdf0e10cSrcweir     // FIXME: LISTBOX_ENTRY_FLAG_MULTILINE
2003cdf0e10cSrcweir 
2004cdf0e10cSrcweir 	sal_uInt16 nCount = mpEntryList->GetEntryCount();
2005cdf0e10cSrcweir 	long nHeight = GetOutputSizePixel().Height();// - mnMaxHeight + mnBorder;
2006cdf0e10cSrcweir     sal_uInt16 nEntries = static_cast< sal_uInt16 >( ( nHeight + mnMaxHeight - 1 ) / mnMaxHeight );
2007cdf0e10cSrcweir     if( nEntries > nCount-mnTop )
2008cdf0e10cSrcweir         nEntries = nCount-mnTop;
2009cdf0e10cSrcweir 
2010cdf0e10cSrcweir     return nEntries;
2011cdf0e10cSrcweir }
2012cdf0e10cSrcweir 
2013cdf0e10cSrcweir // -----------------------------------------------------------------------
2014cdf0e10cSrcweir 
Resize()2015cdf0e10cSrcweir void ImplListBoxWindow::Resize()
2016cdf0e10cSrcweir {
2017cdf0e10cSrcweir     Control::Resize();
2018cdf0e10cSrcweir 
2019cdf0e10cSrcweir     sal_Bool bShowFocusRect = mbHasFocusRect;
2020cdf0e10cSrcweir     if ( bShowFocusRect )
2021cdf0e10cSrcweir         ImplHideFocusRect();
2022cdf0e10cSrcweir 
2023cdf0e10cSrcweir     if( mnCurrentPos != LISTBOX_ENTRY_NOTFOUND )
2024cdf0e10cSrcweir     {
2025cdf0e10cSrcweir         Size aSz( GetOutputSizePixel().Width(), mpEntryList->GetEntryHeight( mnCurrentPos ) );
2026cdf0e10cSrcweir         maFocusRect.SetSize( aSz );
2027cdf0e10cSrcweir     }
2028cdf0e10cSrcweir 
2029cdf0e10cSrcweir     if ( bShowFocusRect )
2030cdf0e10cSrcweir         ImplShowFocusRect();
2031cdf0e10cSrcweir 
2032cdf0e10cSrcweir     ImplClearLayoutData();
2033cdf0e10cSrcweir }
2034cdf0e10cSrcweir 
2035cdf0e10cSrcweir // -----------------------------------------------------------------------
2036cdf0e10cSrcweir 
GetFocus()2037cdf0e10cSrcweir void ImplListBoxWindow::GetFocus()
2038cdf0e10cSrcweir {
2039cdf0e10cSrcweir 	sal_uInt16 nPos = mnCurrentPos;
2040cdf0e10cSrcweir 	if ( nPos == LISTBOX_ENTRY_NOTFOUND )
2041cdf0e10cSrcweir 		nPos = 0;
2042cdf0e10cSrcweir     long nHeightDiff = mpEntryList->GetAddedHeight( nPos, mnTop, 0 );
2043cdf0e10cSrcweir 	maFocusRect.SetPos( Point( 0, nHeightDiff ) );
2044cdf0e10cSrcweir     Size aSz( maFocusRect.GetWidth(), mpEntryList->GetEntryHeight( nPos ) );
2045cdf0e10cSrcweir     maFocusRect.SetSize( aSz );
2046cdf0e10cSrcweir 	ImplShowFocusRect();
2047cdf0e10cSrcweir 	Control::GetFocus();
2048cdf0e10cSrcweir }
2049cdf0e10cSrcweir 
2050cdf0e10cSrcweir // -----------------------------------------------------------------------
2051cdf0e10cSrcweir 
LoseFocus()2052cdf0e10cSrcweir void ImplListBoxWindow::LoseFocus()
2053cdf0e10cSrcweir {
2054cdf0e10cSrcweir 	ImplHideFocusRect();
2055cdf0e10cSrcweir 	Control::LoseFocus();
2056cdf0e10cSrcweir }
2057cdf0e10cSrcweir 
2058cdf0e10cSrcweir // -----------------------------------------------------------------------
2059cdf0e10cSrcweir 
2060cdf0e10cSrcweir /*
2061cdf0e10cSrcweir void ImplListBoxWindow::RequestHelp( const HelpEvent& rHEvt )
2062cdf0e10cSrcweir {
2063cdf0e10cSrcweir 	if ( rHEvt.GetMode() & HELPMODE_BALLOON )
2064cdf0e10cSrcweir 		Help::ShowBalloon( this, rHEvt.GetMousePosPixel(), String() );
2065cdf0e10cSrcweir 
2066cdf0e10cSrcweir 	Window::RequestHelp( rHEvt );
2067cdf0e10cSrcweir }
2068cdf0e10cSrcweir */
2069cdf0e10cSrcweir 
2070cdf0e10cSrcweir // -----------------------------------------------------------------------
2071cdf0e10cSrcweir 
SetTopEntry(sal_uInt16 nTop)2072cdf0e10cSrcweir void ImplListBoxWindow::SetTopEntry( sal_uInt16 nTop )
2073cdf0e10cSrcweir {
2074cdf0e10cSrcweir     if( mpEntryList->GetEntryCount() == 0 )
2075cdf0e10cSrcweir         return;
2076cdf0e10cSrcweir 
2077cdf0e10cSrcweir     long nWHeight = PixelToLogic( GetSizePixel() ).Height();
2078cdf0e10cSrcweir 
2079cdf0e10cSrcweir     sal_uInt16 nLastEntry = mpEntryList->GetEntryCount()-1;
2080cdf0e10cSrcweir     if( nTop > nLastEntry )
2081cdf0e10cSrcweir         nTop = nLastEntry;
2082cdf0e10cSrcweir     const ImplEntryType* pLast = mpEntryList->GetEntryPtr( nLastEntry );
2083cdf0e10cSrcweir     while( nTop > 0 && mpEntryList->GetAddedHeight( nLastEntry, nTop-1 ) + pLast->mnHeight <= nWHeight )
2084cdf0e10cSrcweir         nTop--;
2085cdf0e10cSrcweir 
2086cdf0e10cSrcweir 	if ( nTop != mnTop )
2087cdf0e10cSrcweir 	{
2088cdf0e10cSrcweir         ImplClearLayoutData();
2089cdf0e10cSrcweir 		long nDiff = mpEntryList->GetAddedHeight( mnTop, nTop, 0 );
2090cdf0e10cSrcweir         Update();
2091cdf0e10cSrcweir 		ImplHideFocusRect();
2092cdf0e10cSrcweir 		mnTop = nTop;
2093cdf0e10cSrcweir 		Scroll( 0, nDiff );
2094cdf0e10cSrcweir         Update();
2095cdf0e10cSrcweir 		if( HasFocus() )
2096cdf0e10cSrcweir 			ImplShowFocusRect();
2097cdf0e10cSrcweir 		maScrollHdl.Call( this );
2098cdf0e10cSrcweir 	}
2099cdf0e10cSrcweir }
2100cdf0e10cSrcweir 
2101cdf0e10cSrcweir // -----------------------------------------------------------------------
2102cdf0e10cSrcweir 
ShowProminentEntry(sal_uInt16 nEntryPos)2103cdf0e10cSrcweir void ImplListBoxWindow::ShowProminentEntry( sal_uInt16 nEntryPos )
2104cdf0e10cSrcweir {
2105cdf0e10cSrcweir     if( meProminentType == PROMINENT_MIDDLE )
2106cdf0e10cSrcweir     {
2107cdf0e10cSrcweir         sal_uInt16 nPos = nEntryPos;
2108cdf0e10cSrcweir         long nWHeight = PixelToLogic( GetSizePixel() ).Height();
2109cdf0e10cSrcweir         while( nEntryPos > 0 && mpEntryList->GetAddedHeight( nPos+1, nEntryPos ) < nWHeight/2 )
2110cdf0e10cSrcweir             nEntryPos--;
2111cdf0e10cSrcweir     }
2112cdf0e10cSrcweir     SetTopEntry( nEntryPos );
2113cdf0e10cSrcweir }
2114cdf0e10cSrcweir 
2115cdf0e10cSrcweir // -----------------------------------------------------------------------
2116cdf0e10cSrcweir 
SetLeftIndent(long n)2117cdf0e10cSrcweir void ImplListBoxWindow::SetLeftIndent( long n )
2118cdf0e10cSrcweir {
2119cdf0e10cSrcweir 	ScrollHorz( n - mnLeft );
2120cdf0e10cSrcweir }
2121cdf0e10cSrcweir 
2122cdf0e10cSrcweir // -----------------------------------------------------------------------
2123cdf0e10cSrcweir 
ScrollHorz(long n)2124cdf0e10cSrcweir void ImplListBoxWindow::ScrollHorz( long n )
2125cdf0e10cSrcweir {
2126cdf0e10cSrcweir 	long nDiff = 0;
2127cdf0e10cSrcweir 	if ( n > 0 )
2128cdf0e10cSrcweir 	{
2129cdf0e10cSrcweir 		long nWidth = GetOutputSizePixel().Width();
2130cdf0e10cSrcweir 		if( ( mnMaxWidth - mnLeft + n ) > nWidth )
2131cdf0e10cSrcweir 			nDiff = n;
2132cdf0e10cSrcweir 	}
2133cdf0e10cSrcweir 	else if ( n < 0 )
2134cdf0e10cSrcweir 	{
2135cdf0e10cSrcweir 		if( mnLeft )
2136cdf0e10cSrcweir 		{
2137cdf0e10cSrcweir 			long nAbs = -n;
2138cdf0e10cSrcweir 			nDiff = - ( ( mnLeft > nAbs ) ? nAbs : mnLeft );
2139cdf0e10cSrcweir 		}
2140cdf0e10cSrcweir 	}
2141cdf0e10cSrcweir 
2142cdf0e10cSrcweir 	if ( nDiff )
2143cdf0e10cSrcweir 	{
2144cdf0e10cSrcweir         ImplClearLayoutData();
2145cdf0e10cSrcweir 		mnLeft = sal::static_int_cast<sal_uInt16>(mnLeft + nDiff);
2146cdf0e10cSrcweir         Update();
2147cdf0e10cSrcweir 		ImplHideFocusRect();
2148cdf0e10cSrcweir 		Scroll( -nDiff, 0 );
2149cdf0e10cSrcweir         Update();
2150cdf0e10cSrcweir 		if( HasFocus() )
2151cdf0e10cSrcweir 			ImplShowFocusRect();
2152cdf0e10cSrcweir 		maScrollHdl.Call( this );
2153cdf0e10cSrcweir 	}
2154cdf0e10cSrcweir }
2155cdf0e10cSrcweir 
2156cdf0e10cSrcweir // -----------------------------------------------------------------------
2157cdf0e10cSrcweir 
CalcSize(sal_uInt16 nMaxLines) const2158cdf0e10cSrcweir Size ImplListBoxWindow::CalcSize( sal_uInt16 nMaxLines ) const
2159cdf0e10cSrcweir {
2160cdf0e10cSrcweir     // FIXME: LISTBOX_ENTRY_FLAG_MULTILINE
2161cdf0e10cSrcweir 
2162cdf0e10cSrcweir 	Size aSz;
2163cdf0e10cSrcweir //	sal_uInt16 nL = Min( nMaxLines, mpEntryList->GetEntryCount() );
2164cdf0e10cSrcweir 	aSz.Height() =	nMaxLines * mnMaxHeight;
2165cdf0e10cSrcweir 	aSz.Width() = mnMaxWidth + 2*mnBorder;
2166cdf0e10cSrcweir 	return aSz;
2167cdf0e10cSrcweir }
2168cdf0e10cSrcweir 
2169cdf0e10cSrcweir // -----------------------------------------------------------------------
2170cdf0e10cSrcweir 
GetBoundingRectangle(sal_uInt16 nItem) const2171cdf0e10cSrcweir Rectangle ImplListBoxWindow::GetBoundingRectangle( sal_uInt16 nItem ) const
2172cdf0e10cSrcweir {
2173cdf0e10cSrcweir     const ImplEntryType* pEntry = mpEntryList->GetEntryPtr( nItem );
2174cdf0e10cSrcweir     Size aSz( GetSizePixel().Width(), pEntry ? pEntry->mnHeight : GetEntryHeight() );
2175ad3a95a3SSteve Yin     //long nY = mpEntryList->GetAddedHeight( nItem, GetTopEntry() ) - mpEntryList->GetAddedHeight( GetTopEntry() );
2176ad3a95a3SSteve Yin     long nY = mpEntryList->GetAddedHeight( nItem, GetTopEntry() ) + GetEntryList()->GetMRUCount()*GetEntryHeight();
2177cdf0e10cSrcweir     Rectangle aRect( Point( 0, nY ), aSz );
2178cdf0e10cSrcweir     return aRect;
2179cdf0e10cSrcweir }
2180cdf0e10cSrcweir 
2181cdf0e10cSrcweir 
2182cdf0e10cSrcweir // -----------------------------------------------------------------------
2183cdf0e10cSrcweir 
StateChanged(StateChangedType nType)2184cdf0e10cSrcweir void ImplListBoxWindow::StateChanged( StateChangedType nType )
2185cdf0e10cSrcweir {
2186cdf0e10cSrcweir 	Control::StateChanged( nType );
2187cdf0e10cSrcweir 
2188cdf0e10cSrcweir 	if ( nType == STATE_CHANGE_ZOOM )
2189cdf0e10cSrcweir 	{
2190cdf0e10cSrcweir 		ImplInitSettings( sal_True, sal_False, sal_False );
2191cdf0e10cSrcweir 		ImplCalcMetrics();
2192cdf0e10cSrcweir 		Invalidate();
2193cdf0e10cSrcweir 	}
2194cdf0e10cSrcweir 	else if ( nType == STATE_CHANGE_UPDATEMODE )
2195cdf0e10cSrcweir 	{
2196cdf0e10cSrcweir 		if ( IsUpdateMode() && IsReallyVisible() )
2197cdf0e10cSrcweir 			Invalidate();
2198cdf0e10cSrcweir 	}
2199cdf0e10cSrcweir 	else if ( nType == STATE_CHANGE_CONTROLFONT )
2200cdf0e10cSrcweir 	{
2201cdf0e10cSrcweir 		ImplInitSettings( sal_True, sal_False, sal_False );
2202cdf0e10cSrcweir 		ImplCalcMetrics();
2203cdf0e10cSrcweir 		Invalidate();
2204cdf0e10cSrcweir 	}
2205cdf0e10cSrcweir 	else if ( nType == STATE_CHANGE_CONTROLFOREGROUND )
2206cdf0e10cSrcweir 	{
2207cdf0e10cSrcweir 		ImplInitSettings( sal_False, sal_True, sal_False );
2208cdf0e10cSrcweir 		Invalidate();
2209cdf0e10cSrcweir 	}
2210cdf0e10cSrcweir 	else if ( nType == STATE_CHANGE_CONTROLBACKGROUND )
2211cdf0e10cSrcweir 	{
2212cdf0e10cSrcweir 		ImplInitSettings( sal_False, sal_False, sal_True );
2213cdf0e10cSrcweir 		Invalidate();
2214cdf0e10cSrcweir 	}
2215cdf0e10cSrcweir     ImplClearLayoutData();
2216cdf0e10cSrcweir }
2217cdf0e10cSrcweir 
2218cdf0e10cSrcweir // -----------------------------------------------------------------------
2219cdf0e10cSrcweir 
DataChanged(const DataChangedEvent & rDCEvt)2220cdf0e10cSrcweir void ImplListBoxWindow::DataChanged( const DataChangedEvent& rDCEvt )
2221cdf0e10cSrcweir {
2222cdf0e10cSrcweir 	Control::DataChanged( rDCEvt );
2223cdf0e10cSrcweir 
2224cdf0e10cSrcweir 	if ( (rDCEvt.GetType() == DATACHANGED_FONTS) ||
2225cdf0e10cSrcweir 		 (rDCEvt.GetType() == DATACHANGED_FONTSUBSTITUTION) ||
2226cdf0e10cSrcweir 		 ((rDCEvt.GetType() == DATACHANGED_SETTINGS) &&
2227cdf0e10cSrcweir 		  (rDCEvt.GetFlags() & SETTINGS_STYLE)) )
2228cdf0e10cSrcweir 	{
2229cdf0e10cSrcweir         ImplClearLayoutData();
2230cdf0e10cSrcweir 		ImplInitSettings( sal_True, sal_True, sal_True );
2231cdf0e10cSrcweir 		ImplCalcMetrics();
2232cdf0e10cSrcweir 		Invalidate();
2233cdf0e10cSrcweir 	}
2234cdf0e10cSrcweir }
2235cdf0e10cSrcweir 
2236cdf0e10cSrcweir // -----------------------------------------------------------------------
2237cdf0e10cSrcweir 
ImplGetTextStyle() const2238cdf0e10cSrcweir sal_uInt16 ImplListBoxWindow::ImplGetTextStyle() const
2239cdf0e10cSrcweir {
2240cdf0e10cSrcweir     sal_uInt16 nTextStyle = TEXT_DRAW_VCENTER;
2241cdf0e10cSrcweir 
2242cdf0e10cSrcweir     if ( mpEntryList->HasImages() )
2243cdf0e10cSrcweir         nTextStyle |= TEXT_DRAW_LEFT;
2244cdf0e10cSrcweir     else if ( mbCenter )
2245cdf0e10cSrcweir         nTextStyle |= TEXT_DRAW_CENTER;
2246cdf0e10cSrcweir     else if ( mbRight )
2247cdf0e10cSrcweir         nTextStyle |= TEXT_DRAW_RIGHT;
2248cdf0e10cSrcweir     else
2249cdf0e10cSrcweir         nTextStyle |= TEXT_DRAW_LEFT;
2250cdf0e10cSrcweir 
2251cdf0e10cSrcweir     return nTextStyle;
2252cdf0e10cSrcweir }
2253cdf0e10cSrcweir 
2254cdf0e10cSrcweir // =======================================================================
2255cdf0e10cSrcweir 
ImplListBox(Window * pParent,WinBits nWinStyle)2256cdf0e10cSrcweir ImplListBox::ImplListBox( Window* pParent, WinBits nWinStyle ) :
2257cdf0e10cSrcweir 	Control( pParent, nWinStyle ),
2258cdf0e10cSrcweir 	maLBWindow( this, nWinStyle&(~WB_BORDER) )
2259cdf0e10cSrcweir {
2260cdf0e10cSrcweir     // for native widget rendering we must be able to detect this window type
2261cdf0e10cSrcweir     SetType( WINDOW_LISTBOXWINDOW );
2262cdf0e10cSrcweir 
2263cdf0e10cSrcweir 	mpVScrollBar	= new ScrollBar( this, WB_VSCROLL | WB_DRAG );
2264cdf0e10cSrcweir 	mpHScrollBar	= new ScrollBar( this, WB_HSCROLL | WB_DRAG );
2265cdf0e10cSrcweir 	mpScrollBarBox	= new ScrollBarBox( this );
2266cdf0e10cSrcweir 
2267cdf0e10cSrcweir 	Link aLink( LINK( this, ImplListBox, ScrollBarHdl ) );
2268cdf0e10cSrcweir 	mpVScrollBar->SetScrollHdl( aLink );
2269cdf0e10cSrcweir 	mpHScrollBar->SetScrollHdl( aLink );
2270cdf0e10cSrcweir 
2271a68b38dfSArmin Le Grand 	mbVScroll		= false;
2272a68b38dfSArmin Le Grand 	mbHScroll		= false;
2273a68b38dfSArmin Le Grand 	mbAutoHScroll	= ( nWinStyle & WB_AUTOHSCROLL );
2274a68b38dfSArmin Le Grand     mbEdgeBlending  = false;
2275cdf0e10cSrcweir 
2276cdf0e10cSrcweir 	maLBWindow.SetScrollHdl( LINK( this, ImplListBox, LBWindowScrolled ) );
2277cdf0e10cSrcweir 	maLBWindow.SetMRUChangedHdl( LINK( this, ImplListBox, MRUChanged ) );
2278a68b38dfSArmin Le Grand     maLBWindow.SetEdgeBlending(GetEdgeBlending());
2279cdf0e10cSrcweir 	maLBWindow.Show();
2280cdf0e10cSrcweir }
2281cdf0e10cSrcweir 
2282cdf0e10cSrcweir // -----------------------------------------------------------------------
2283cdf0e10cSrcweir 
~ImplListBox()2284cdf0e10cSrcweir ImplListBox::~ImplListBox()
2285cdf0e10cSrcweir {
2286cdf0e10cSrcweir 	delete mpHScrollBar;
2287cdf0e10cSrcweir 	delete mpVScrollBar;
2288cdf0e10cSrcweir 	delete mpScrollBarBox;
2289cdf0e10cSrcweir }
2290cdf0e10cSrcweir 
2291cdf0e10cSrcweir // -----------------------------------------------------------------------
2292cdf0e10cSrcweir 
Clear()2293cdf0e10cSrcweir void ImplListBox::Clear()
2294cdf0e10cSrcweir {
2295cdf0e10cSrcweir 	maLBWindow.Clear();
2296cdf0e10cSrcweir 	if ( GetEntryList()->GetMRUCount() )
2297cdf0e10cSrcweir 	{
2298cdf0e10cSrcweir 		maLBWindow.GetEntryList()->SetMRUCount( 0 );
2299cdf0e10cSrcweir 		maLBWindow.SetSeparatorPos( LISTBOX_ENTRY_NOTFOUND );
2300cdf0e10cSrcweir 	}
2301cdf0e10cSrcweir 	mpVScrollBar->SetThumbPos( 0 );
2302cdf0e10cSrcweir 	mpHScrollBar->SetThumbPos( 0 );
2303cdf0e10cSrcweir 	StateChanged( STATE_CHANGE_DATA );
2304cdf0e10cSrcweir }
2305cdf0e10cSrcweir 
2306cdf0e10cSrcweir // -----------------------------------------------------------------------
2307cdf0e10cSrcweir 
InsertEntry(sal_uInt16 nPos,const XubString & rStr)2308cdf0e10cSrcweir sal_uInt16 ImplListBox::InsertEntry( sal_uInt16 nPos, const XubString& rStr )
2309cdf0e10cSrcweir {
2310cdf0e10cSrcweir 	ImplEntryType* pNewEntry = new ImplEntryType( rStr );
2311cdf0e10cSrcweir 	sal_uInt16 nNewPos = maLBWindow.InsertEntry( nPos, pNewEntry );
2312cdf0e10cSrcweir 	StateChanged( STATE_CHANGE_DATA );
2313cdf0e10cSrcweir 	return nNewPos;
2314cdf0e10cSrcweir }
2315cdf0e10cSrcweir 
2316cdf0e10cSrcweir // -----------------------------------------------------------------------
2317cdf0e10cSrcweir 
InsertEntry(sal_uInt16 nPos,const Image & rImage)2318cdf0e10cSrcweir sal_uInt16 ImplListBox::InsertEntry( sal_uInt16 nPos, const Image& rImage )
2319cdf0e10cSrcweir {
2320cdf0e10cSrcweir 	ImplEntryType* pNewEntry = new ImplEntryType( rImage );
2321cdf0e10cSrcweir 	sal_uInt16 nNewPos = maLBWindow.InsertEntry( nPos, pNewEntry );
2322cdf0e10cSrcweir 	StateChanged( STATE_CHANGE_DATA );
2323cdf0e10cSrcweir 	return nNewPos;
2324cdf0e10cSrcweir }
2325cdf0e10cSrcweir 
2326cdf0e10cSrcweir // -----------------------------------------------------------------------
2327cdf0e10cSrcweir 
InsertEntry(sal_uInt16 nPos,const XubString & rStr,const Image & rImage)2328cdf0e10cSrcweir sal_uInt16 ImplListBox::InsertEntry( sal_uInt16 nPos, const XubString& rStr, const Image& rImage )
2329cdf0e10cSrcweir {
2330cdf0e10cSrcweir 	ImplEntryType* pNewEntry = new ImplEntryType( rStr, rImage );
2331cdf0e10cSrcweir 	sal_uInt16 nNewPos = maLBWindow.InsertEntry( nPos, pNewEntry );
2332cdf0e10cSrcweir 	StateChanged( STATE_CHANGE_DATA );
2333cdf0e10cSrcweir 	return nNewPos;
2334cdf0e10cSrcweir }
2335cdf0e10cSrcweir 
2336cdf0e10cSrcweir // -----------------------------------------------------------------------
2337cdf0e10cSrcweir 
RemoveEntry(sal_uInt16 nPos)2338cdf0e10cSrcweir void ImplListBox::RemoveEntry( sal_uInt16 nPos )
2339cdf0e10cSrcweir {
2340cdf0e10cSrcweir 	maLBWindow.RemoveEntry( nPos );
2341cdf0e10cSrcweir 	StateChanged( STATE_CHANGE_DATA );
2342cdf0e10cSrcweir }
2343cdf0e10cSrcweir 
2344cdf0e10cSrcweir // -----------------------------------------------------------------------
2345cdf0e10cSrcweir 
SetEntryFlags(sal_uInt16 nPos,long nFlags)2346cdf0e10cSrcweir void ImplListBox::SetEntryFlags( sal_uInt16 nPos, long nFlags )
2347cdf0e10cSrcweir {
2348cdf0e10cSrcweir 	maLBWindow.SetEntryFlags( nPos, nFlags );
2349cdf0e10cSrcweir }
2350cdf0e10cSrcweir 
2351cdf0e10cSrcweir // -----------------------------------------------------------------------
2352cdf0e10cSrcweir 
GetEntryFlags(sal_uInt16 nPos) const2353cdf0e10cSrcweir long ImplListBox::GetEntryFlags( sal_uInt16 nPos ) const
2354cdf0e10cSrcweir {
2355cdf0e10cSrcweir 	return maLBWindow.GetEntryList()->GetEntryFlags( nPos );
2356cdf0e10cSrcweir }
2357cdf0e10cSrcweir 
2358cdf0e10cSrcweir // -----------------------------------------------------------------------
2359cdf0e10cSrcweir 
SelectEntry(sal_uInt16 nPos,sal_Bool bSelect)2360cdf0e10cSrcweir void ImplListBox::SelectEntry( sal_uInt16 nPos, sal_Bool bSelect )
2361cdf0e10cSrcweir {
2362cdf0e10cSrcweir 	maLBWindow.SelectEntry( nPos, bSelect );
2363cdf0e10cSrcweir }
2364cdf0e10cSrcweir 
2365cdf0e10cSrcweir // -----------------------------------------------------------------------
2366cdf0e10cSrcweir 
SetNoSelection()2367cdf0e10cSrcweir void ImplListBox::SetNoSelection()
2368cdf0e10cSrcweir {
2369cdf0e10cSrcweir 	maLBWindow.DeselectAll();
2370cdf0e10cSrcweir }
2371cdf0e10cSrcweir 
2372cdf0e10cSrcweir // -----------------------------------------------------------------------
2373cdf0e10cSrcweir 
GetFocus()2374cdf0e10cSrcweir void ImplListBox::GetFocus()
2375cdf0e10cSrcweir {
2376cdf0e10cSrcweir 	maLBWindow.GrabFocus();
2377cdf0e10cSrcweir }
2378cdf0e10cSrcweir 
2379cdf0e10cSrcweir // -----------------------------------------------------------------------
2380cdf0e10cSrcweir 
GetPreferredKeyInputWindow()2381cdf0e10cSrcweir Window* ImplListBox::GetPreferredKeyInputWindow()
2382cdf0e10cSrcweir {
2383cdf0e10cSrcweir     return &maLBWindow;
2384cdf0e10cSrcweir }
2385cdf0e10cSrcweir 
2386cdf0e10cSrcweir // -----------------------------------------------------------------------
2387cdf0e10cSrcweir 
Resize()2388cdf0e10cSrcweir void ImplListBox::Resize()
2389cdf0e10cSrcweir {
2390cdf0e10cSrcweir     Control::Resize();
2391cdf0e10cSrcweir 	ImplResizeControls();
2392cdf0e10cSrcweir 	ImplCheckScrollBars();
2393cdf0e10cSrcweir }
2394cdf0e10cSrcweir 
2395cdf0e10cSrcweir 
2396cdf0e10cSrcweir // -----------------------------------------------------------------------
2397cdf0e10cSrcweir 
IMPL_LINK(ImplListBox,MRUChanged,void *,EMPTYARG)2398cdf0e10cSrcweir IMPL_LINK( ImplListBox, MRUChanged, void*, EMPTYARG )
2399cdf0e10cSrcweir {
2400cdf0e10cSrcweir 	StateChanged( STATE_CHANGE_DATA );
2401cdf0e10cSrcweir 	return 1;
2402cdf0e10cSrcweir }
2403cdf0e10cSrcweir 
2404cdf0e10cSrcweir // -----------------------------------------------------------------------
2405cdf0e10cSrcweir 
IMPL_LINK(ImplListBox,LBWindowScrolled,void *,EMPTYARG)2406cdf0e10cSrcweir IMPL_LINK( ImplListBox, LBWindowScrolled, void*, EMPTYARG )
2407cdf0e10cSrcweir {
2408cdf0e10cSrcweir     long nSet = GetTopEntry();
2409cdf0e10cSrcweir     if( nSet > mpVScrollBar->GetRangeMax() )
2410cdf0e10cSrcweir         mpVScrollBar->SetRangeMax( GetEntryList()->GetEntryCount() );
2411cdf0e10cSrcweir 	mpVScrollBar->SetThumbPos( GetTopEntry() );
2412cdf0e10cSrcweir 
2413cdf0e10cSrcweir 	mpHScrollBar->SetThumbPos( GetLeftIndent() );
2414cdf0e10cSrcweir 
2415cdf0e10cSrcweir 	maScrollHdl.Call( this );
2416cdf0e10cSrcweir 
2417cdf0e10cSrcweir 	return 1;
2418cdf0e10cSrcweir }
2419cdf0e10cSrcweir 
2420cdf0e10cSrcweir // -----------------------------------------------------------------------
2421cdf0e10cSrcweir 
IMPL_LINK(ImplListBox,ScrollBarHdl,ScrollBar *,pSB)2422cdf0e10cSrcweir IMPL_LINK( ImplListBox, ScrollBarHdl, ScrollBar*, pSB )
2423cdf0e10cSrcweir {
2424cdf0e10cSrcweir 	sal_uInt16 nPos = (sal_uInt16) pSB->GetThumbPos();
2425cdf0e10cSrcweir 	if( pSB == mpVScrollBar )
2426cdf0e10cSrcweir 		SetTopEntry( nPos );
2427cdf0e10cSrcweir 	else if( pSB == mpHScrollBar )
2428cdf0e10cSrcweir 		SetLeftIndent( nPos );
2429cdf0e10cSrcweir 
2430cdf0e10cSrcweir 	return 1;
2431cdf0e10cSrcweir }
2432cdf0e10cSrcweir 
2433cdf0e10cSrcweir // -----------------------------------------------------------------------
2434cdf0e10cSrcweir 
ImplCheckScrollBars()2435cdf0e10cSrcweir void ImplListBox::ImplCheckScrollBars()
2436cdf0e10cSrcweir {
2437cdf0e10cSrcweir 	sal_Bool bArrange = sal_False;
2438cdf0e10cSrcweir 
2439cdf0e10cSrcweir 	Size aOutSz = GetOutputSizePixel();
2440cdf0e10cSrcweir 	sal_uInt16 nEntries = GetEntryList()->GetEntryCount();
2441cdf0e10cSrcweir 	sal_uInt16 nMaxVisEntries = (sal_uInt16) (aOutSz.Height() / GetEntryHeight());
2442cdf0e10cSrcweir 
2443cdf0e10cSrcweir 	// vert. ScrollBar
2444cdf0e10cSrcweir 	if( nEntries > nMaxVisEntries )
2445cdf0e10cSrcweir 	{
2446cdf0e10cSrcweir 		if( !mbVScroll )
2447cdf0e10cSrcweir 			bArrange = sal_True;
2448a68b38dfSArmin Le Grand 		mbVScroll = true;
2449cdf0e10cSrcweir 
2450cdf0e10cSrcweir 		// Ueberpruefung des rausgescrollten Bereichs
2451cdf0e10cSrcweir         if( GetEntryList()->GetSelectEntryCount() == 1 &&
2452cdf0e10cSrcweir             GetEntryList()->GetSelectEntryPos( 0 ) != LISTBOX_ENTRY_NOTFOUND )
2453cdf0e10cSrcweir 		    ShowProminentEntry( GetEntryList()->GetSelectEntryPos( 0 ) );
2454cdf0e10cSrcweir 		else
2455cdf0e10cSrcweir 		    SetTopEntry( GetTopEntry() );	// MaxTop wird geprueft...
2456cdf0e10cSrcweir 	}
2457cdf0e10cSrcweir 	else
2458cdf0e10cSrcweir 	{
2459cdf0e10cSrcweir 		if( mbVScroll )
2460cdf0e10cSrcweir 			bArrange = sal_True;
2461a68b38dfSArmin Le Grand 		mbVScroll = false;
2462cdf0e10cSrcweir 		SetTopEntry( 0 );
2463cdf0e10cSrcweir 	}
2464cdf0e10cSrcweir 
2465cdf0e10cSrcweir 	// horz. ScrollBar
2466cdf0e10cSrcweir 	if( mbAutoHScroll )
2467cdf0e10cSrcweir 	{
2468cdf0e10cSrcweir 		long nWidth = (sal_uInt16) aOutSz.Width();
2469cdf0e10cSrcweir 		if ( mbVScroll )
2470cdf0e10cSrcweir 			nWidth -= mpVScrollBar->GetSizePixel().Width();
2471cdf0e10cSrcweir 
2472cdf0e10cSrcweir 		long nMaxWidth = GetMaxEntryWidth();
2473cdf0e10cSrcweir 		if( nWidth < nMaxWidth )
2474cdf0e10cSrcweir 		{
2475cdf0e10cSrcweir 			if( !mbHScroll )
2476cdf0e10cSrcweir 				bArrange = sal_True;
2477a68b38dfSArmin Le Grand 			mbHScroll = true;
2478cdf0e10cSrcweir 
2479cdf0e10cSrcweir 			if ( !mbVScroll )	// ggf. brauchen wir jetzt doch einen
2480cdf0e10cSrcweir 			{
2481cdf0e10cSrcweir 				nMaxVisEntries = (sal_uInt16) ( ( aOutSz.Height() - mpHScrollBar->GetSizePixel().Height() ) / GetEntryHeight() );
2482cdf0e10cSrcweir 				if( nEntries > nMaxVisEntries )
2483cdf0e10cSrcweir 				{
2484cdf0e10cSrcweir 					bArrange = sal_True;
2485a68b38dfSArmin Le Grand 					mbVScroll = true;
2486cdf0e10cSrcweir 
2487cdf0e10cSrcweir 					// Ueberpruefung des rausgescrollten Bereichs
2488cdf0e10cSrcweir                     if( GetEntryList()->GetSelectEntryCount() == 1 &&
2489cdf0e10cSrcweir                         GetEntryList()->GetSelectEntryPos( 0 ) != LISTBOX_ENTRY_NOTFOUND )
2490cdf0e10cSrcweir                         ShowProminentEntry( GetEntryList()->GetSelectEntryPos( 0 ) );
2491cdf0e10cSrcweir                     else
2492cdf0e10cSrcweir                         SetTopEntry( GetTopEntry() );	// MaxTop wird geprueft...
2493cdf0e10cSrcweir 				}
2494cdf0e10cSrcweir 			}
2495cdf0e10cSrcweir 
2496cdf0e10cSrcweir 			// Ueberpruefung des rausgescrollten Bereichs
2497cdf0e10cSrcweir 			sal_uInt16 nMaxLI = (sal_uInt16) (nMaxWidth - nWidth);
2498cdf0e10cSrcweir 			if ( nMaxLI < GetLeftIndent() )
2499cdf0e10cSrcweir 				SetLeftIndent( nMaxLI );
2500cdf0e10cSrcweir 		}
2501cdf0e10cSrcweir 		else
2502cdf0e10cSrcweir 		{
2503cdf0e10cSrcweir 			if( mbHScroll )
2504cdf0e10cSrcweir 				bArrange = sal_True;
2505a68b38dfSArmin Le Grand 			mbHScroll = false;
2506cdf0e10cSrcweir 			SetLeftIndent( 0 );
2507cdf0e10cSrcweir 		}
2508cdf0e10cSrcweir 	}
2509cdf0e10cSrcweir 
2510cdf0e10cSrcweir 	if( bArrange )
2511cdf0e10cSrcweir 		ImplResizeControls();
2512cdf0e10cSrcweir 
2513cdf0e10cSrcweir 	ImplInitScrollBars();
2514cdf0e10cSrcweir }
2515cdf0e10cSrcweir 
2516cdf0e10cSrcweir // -----------------------------------------------------------------------
2517cdf0e10cSrcweir 
ImplInitScrollBars()2518cdf0e10cSrcweir void ImplListBox::ImplInitScrollBars()
2519cdf0e10cSrcweir {
2520cdf0e10cSrcweir 	Size aOutSz = maLBWindow.GetOutputSizePixel();
2521cdf0e10cSrcweir 
2522cdf0e10cSrcweir 	if ( mbVScroll )
2523cdf0e10cSrcweir 	{
2524cdf0e10cSrcweir 		sal_uInt16 nEntries = GetEntryList()->GetEntryCount();
2525cdf0e10cSrcweir 		sal_uInt16 nVisEntries = (sal_uInt16) (aOutSz.Height() / GetEntryHeight());
2526cdf0e10cSrcweir 		mpVScrollBar->SetRangeMax( nEntries );
2527cdf0e10cSrcweir 		mpVScrollBar->SetVisibleSize( nVisEntries );
2528cdf0e10cSrcweir 		mpVScrollBar->SetPageSize( nVisEntries - 1 );
2529cdf0e10cSrcweir 	}
2530cdf0e10cSrcweir 
2531cdf0e10cSrcweir 	if ( mbHScroll )
2532cdf0e10cSrcweir 	{
2533cdf0e10cSrcweir 		mpHScrollBar->SetRangeMax( GetMaxEntryWidth() + HORZ_SCROLL );
2534cdf0e10cSrcweir 		mpHScrollBar->SetVisibleSize( (sal_uInt16)aOutSz.Width() );
2535cdf0e10cSrcweir 		mpHScrollBar->SetLineSize( HORZ_SCROLL );
2536cdf0e10cSrcweir 		mpHScrollBar->SetPageSize( aOutSz.Width() - HORZ_SCROLL );
2537cdf0e10cSrcweir 	}
2538cdf0e10cSrcweir }
2539cdf0e10cSrcweir 
2540cdf0e10cSrcweir // -----------------------------------------------------------------------
2541cdf0e10cSrcweir 
ImplResizeControls()2542cdf0e10cSrcweir void ImplListBox::ImplResizeControls()
2543cdf0e10cSrcweir {
2544cdf0e10cSrcweir 	// Hier werden die Controls nur angeordnet, ob die Scrollbars
2545cdf0e10cSrcweir 	// sichtbar sein sollen wird bereits in ImplCheckScrollBars ermittelt.
2546cdf0e10cSrcweir 
2547cdf0e10cSrcweir 	Size aOutSz = GetOutputSizePixel();
2548cdf0e10cSrcweir 	long nSBWidth = GetSettings().GetStyleSettings().GetScrollBarSize();
2549cdf0e10cSrcweir 	nSBWidth = CalcZoom( nSBWidth );
2550cdf0e10cSrcweir 
2551cdf0e10cSrcweir 	Size aInnerSz( aOutSz );
2552cdf0e10cSrcweir 	if ( mbVScroll )
2553cdf0e10cSrcweir 		aInnerSz.Width() -= nSBWidth;
2554cdf0e10cSrcweir 	if ( mbHScroll )
2555cdf0e10cSrcweir 		aInnerSz.Height() -= nSBWidth;
2556cdf0e10cSrcweir 
2557cdf0e10cSrcweir 	// pb: #106948# explicit mirroring for calc
2558cdf0e10cSrcweir 	// Scrollbar on left or right side?
2559cdf0e10cSrcweir 	sal_Bool bMirroring = maLBWindow.IsMirroring();
2560cdf0e10cSrcweir 	Point aWinPos( bMirroring && mbVScroll ? nSBWidth : 0, 0 );
2561cdf0e10cSrcweir 	maLBWindow.SetPosSizePixel( aWinPos, aInnerSz );
2562cdf0e10cSrcweir 
2563cdf0e10cSrcweir 	// ScrollBarBox
2564cdf0e10cSrcweir 	if( mbVScroll && mbHScroll )
2565cdf0e10cSrcweir 	{
2566cdf0e10cSrcweir 		Point aBoxPos( bMirroring ? 0 : aInnerSz.Width(), aInnerSz.Height() );
2567cdf0e10cSrcweir 		mpScrollBarBox->SetPosSizePixel( aBoxPos, Size( nSBWidth, nSBWidth ) );
2568cdf0e10cSrcweir 		mpScrollBarBox->Show();
2569cdf0e10cSrcweir 	}
2570cdf0e10cSrcweir 	else
2571cdf0e10cSrcweir 	{
2572cdf0e10cSrcweir 		mpScrollBarBox->Hide();
2573cdf0e10cSrcweir 	}
2574cdf0e10cSrcweir 
2575cdf0e10cSrcweir 	// vert. ScrollBar
2576cdf0e10cSrcweir 	if( mbVScroll )
2577cdf0e10cSrcweir 	{
2578cdf0e10cSrcweir 		// Scrollbar on left or right side?
2579cdf0e10cSrcweir 		Point aVPos( bMirroring ? 0 : aOutSz.Width() - nSBWidth, 0 );
2580cdf0e10cSrcweir 		mpVScrollBar->SetPosSizePixel( aVPos, Size( nSBWidth, aInnerSz.Height() ) );
2581cdf0e10cSrcweir 		mpVScrollBar->Show();
2582cdf0e10cSrcweir 	}
2583cdf0e10cSrcweir 	else
2584cdf0e10cSrcweir 	{
2585cdf0e10cSrcweir 		mpVScrollBar->Hide();
2586cdf0e10cSrcweir         // #107254# Don't reset top entry after resize, but check for max top entry
2587cdf0e10cSrcweir 		SetTopEntry( GetTopEntry() );
2588cdf0e10cSrcweir 	}
2589cdf0e10cSrcweir 
2590cdf0e10cSrcweir 	// horz. ScrollBar
2591cdf0e10cSrcweir 	if( mbHScroll )
2592cdf0e10cSrcweir 	{
2593cdf0e10cSrcweir 		Point aHPos( ( bMirroring && mbVScroll ) ? nSBWidth : 0, aOutSz.Height() - nSBWidth );
2594cdf0e10cSrcweir 		mpHScrollBar->SetPosSizePixel( aHPos, Size( aInnerSz.Width(), nSBWidth ) );
2595cdf0e10cSrcweir 		mpHScrollBar->Show();
2596cdf0e10cSrcweir 	}
2597cdf0e10cSrcweir 	else
2598cdf0e10cSrcweir 	{
2599cdf0e10cSrcweir 		mpHScrollBar->Hide();
2600cdf0e10cSrcweir 		SetLeftIndent( 0 );
2601cdf0e10cSrcweir 	}
2602cdf0e10cSrcweir }
2603cdf0e10cSrcweir 
2604cdf0e10cSrcweir // -----------------------------------------------------------------------
2605cdf0e10cSrcweir 
StateChanged(StateChangedType nType)2606cdf0e10cSrcweir void ImplListBox::StateChanged( StateChangedType nType )
2607cdf0e10cSrcweir {
2608cdf0e10cSrcweir 	if ( nType == STATE_CHANGE_INITSHOW )
2609cdf0e10cSrcweir 	{
2610cdf0e10cSrcweir 		ImplCheckScrollBars();
2611cdf0e10cSrcweir 	}
2612cdf0e10cSrcweir 	else if ( ( nType == STATE_CHANGE_UPDATEMODE ) || ( nType == STATE_CHANGE_DATA ) )
2613cdf0e10cSrcweir 	{
2614cdf0e10cSrcweir 		sal_Bool bUpdate = IsUpdateMode();
2615cdf0e10cSrcweir 		maLBWindow.SetUpdateMode( bUpdate );
2616cdf0e10cSrcweir //		mpHScrollBar->SetUpdateMode( bUpdate );
2617cdf0e10cSrcweir //		mpVScrollBar->SetUpdateMode( bUpdate );
2618cdf0e10cSrcweir 		if ( bUpdate && IsReallyVisible() )
2619cdf0e10cSrcweir 			ImplCheckScrollBars();
2620cdf0e10cSrcweir 	}
2621cdf0e10cSrcweir 	else if( nType == STATE_CHANGE_ENABLE )
2622cdf0e10cSrcweir 	{
2623cdf0e10cSrcweir 		mpHScrollBar->Enable( IsEnabled() );
2624cdf0e10cSrcweir 		mpVScrollBar->Enable( IsEnabled() );
2625cdf0e10cSrcweir 		mpScrollBarBox->Enable( IsEnabled() );
2626cdf0e10cSrcweir 		Invalidate();
2627cdf0e10cSrcweir 	}
2628cdf0e10cSrcweir 	else if ( nType == STATE_CHANGE_ZOOM )
2629cdf0e10cSrcweir 	{
2630cdf0e10cSrcweir 		maLBWindow.SetZoom( GetZoom() );
2631cdf0e10cSrcweir 		Resize();
2632cdf0e10cSrcweir 	}
2633cdf0e10cSrcweir 	else if ( nType == STATE_CHANGE_CONTROLFONT )
2634cdf0e10cSrcweir 	{
2635cdf0e10cSrcweir 		maLBWindow.SetControlFont( GetControlFont() );
2636cdf0e10cSrcweir 	}
2637cdf0e10cSrcweir 	else if ( nType == STATE_CHANGE_CONTROLFOREGROUND )
2638cdf0e10cSrcweir 	{
2639cdf0e10cSrcweir 		maLBWindow.SetControlForeground( GetControlForeground() );
2640cdf0e10cSrcweir 	}
2641cdf0e10cSrcweir 	else if ( nType == STATE_CHANGE_CONTROLBACKGROUND )
2642cdf0e10cSrcweir 	{
2643cdf0e10cSrcweir 		maLBWindow.SetControlBackground( GetControlBackground() );
2644cdf0e10cSrcweir 	}
2645cdf0e10cSrcweir     else if( nType == STATE_CHANGE_MIRRORING )
2646cdf0e10cSrcweir     {
2647cdf0e10cSrcweir         maLBWindow.EnableRTL( IsRTLEnabled() );
2648cdf0e10cSrcweir         mpHScrollBar->EnableRTL( IsRTLEnabled() );
2649cdf0e10cSrcweir         mpVScrollBar->EnableRTL( IsRTLEnabled() );
2650cdf0e10cSrcweir         ImplResizeControls();
2651cdf0e10cSrcweir     }
2652cdf0e10cSrcweir 
2653cdf0e10cSrcweir 	Control::StateChanged( nType );
2654cdf0e10cSrcweir }
2655cdf0e10cSrcweir 
2656cdf0e10cSrcweir // -----------------------------------------------------------------------
2657cdf0e10cSrcweir 
DataChanged(const DataChangedEvent & rDCEvt)2658cdf0e10cSrcweir void ImplListBox::DataChanged( const DataChangedEvent& rDCEvt )
2659cdf0e10cSrcweir {
2660cdf0e10cSrcweir //	if ( (rDCEvt.GetType() == DATACHANGED_SETTINGS) &&
2661cdf0e10cSrcweir //		 (rDCEvt.GetFlags() & SETTINGS_STYLE) )
2662cdf0e10cSrcweir //	{
2663cdf0e10cSrcweir //		maLBWindow.SetSettings( GetSettings() );
2664cdf0e10cSrcweir //		Resize();
2665cdf0e10cSrcweir //	}
2666cdf0e10cSrcweir //	else
2667cdf0e10cSrcweir 		Control::DataChanged( rDCEvt );
2668cdf0e10cSrcweir }
2669cdf0e10cSrcweir 
2670cdf0e10cSrcweir // -----------------------------------------------------------------------
2671cdf0e10cSrcweir 
Notify(NotifyEvent & rNEvt)2672cdf0e10cSrcweir long ImplListBox::Notify( NotifyEvent& rNEvt )
2673cdf0e10cSrcweir {
2674cdf0e10cSrcweir 	long nDone = 0;
2675cdf0e10cSrcweir 	if ( rNEvt.GetType() == EVENT_COMMAND )
2676cdf0e10cSrcweir 	{
2677cdf0e10cSrcweir 		const CommandEvent& rCEvt = *rNEvt.GetCommandEvent();
2678cdf0e10cSrcweir 		if ( rCEvt.GetCommand() == COMMAND_WHEEL )
2679cdf0e10cSrcweir 		{
2680cdf0e10cSrcweir 			const CommandWheelData* pData = rCEvt.GetWheelData();
2681cdf0e10cSrcweir 			if( !pData->GetModifier() && ( pData->GetMode() == COMMAND_WHEEL_SCROLL ) )
2682cdf0e10cSrcweir 			{
2683cdf0e10cSrcweir 				nDone = HandleScrollCommand( rCEvt, mpHScrollBar, mpVScrollBar );
2684cdf0e10cSrcweir 			}
2685cdf0e10cSrcweir 		}
2686cdf0e10cSrcweir 	}
2687cdf0e10cSrcweir 
2688cdf0e10cSrcweir 	return nDone ? nDone : Window::Notify( rNEvt );
2689cdf0e10cSrcweir }
2690cdf0e10cSrcweir 
2691cdf0e10cSrcweir // -----------------------------------------------------------------------
2692cdf0e10cSrcweir 
GetDisplayBackground() const2693cdf0e10cSrcweir const Wallpaper& ImplListBox::GetDisplayBackground() const
2694cdf0e10cSrcweir {
2695cdf0e10cSrcweir     return maLBWindow.GetDisplayBackground();
2696cdf0e10cSrcweir }
2697cdf0e10cSrcweir 
2698cdf0e10cSrcweir // -----------------------------------------------------------------------
2699cdf0e10cSrcweir 
HandleWheelAsCursorTravel(const CommandEvent & rCEvt)2700cdf0e10cSrcweir sal_Bool ImplListBox::HandleWheelAsCursorTravel( const CommandEvent& rCEvt )
2701cdf0e10cSrcweir {
2702cdf0e10cSrcweir 	sal_Bool bDone = sal_False;
2703cdf0e10cSrcweir 	if ( rCEvt.GetCommand() == COMMAND_WHEEL )
2704cdf0e10cSrcweir 	{
2705cdf0e10cSrcweir 		const CommandWheelData* pData = rCEvt.GetWheelData();
2706cdf0e10cSrcweir 		if( !pData->GetModifier() && ( pData->GetMode() == COMMAND_WHEEL_SCROLL ) )
2707cdf0e10cSrcweir 		{
2708cdf0e10cSrcweir 			sal_uInt16 nKey = ( pData->GetDelta() < 0 ) ? KEY_DOWN : KEY_UP;
2709cdf0e10cSrcweir 			KeyEvent aKeyEvent( 0, KeyCode( nKey ) );
2710cdf0e10cSrcweir 			bDone = ProcessKeyInput( aKeyEvent );
2711cdf0e10cSrcweir 		}
2712cdf0e10cSrcweir 	}
2713cdf0e10cSrcweir 	return bDone;
2714cdf0e10cSrcweir }
2715cdf0e10cSrcweir 
2716cdf0e10cSrcweir // -----------------------------------------------------------------------
2717cdf0e10cSrcweir 
SetMRUEntries(const XubString & rEntries,xub_Unicode cSep)2718cdf0e10cSrcweir void ImplListBox::SetMRUEntries( const XubString& rEntries, xub_Unicode cSep )
2719cdf0e10cSrcweir {
2720cdf0e10cSrcweir 	sal_Bool bChanges = GetEntryList()->GetMRUCount() ? sal_True : sal_False;
2721cdf0e10cSrcweir 
2722cdf0e10cSrcweir 	// Remove old MRU entries
2723cdf0e10cSrcweir 	for ( sal_uInt16 n = GetEntryList()->GetMRUCount();n; )
2724cdf0e10cSrcweir 		maLBWindow.RemoveEntry( --n );
2725cdf0e10cSrcweir 
2726cdf0e10cSrcweir 	sal_uInt16 nMRUCount = 0;
2727cdf0e10cSrcweir 	sal_uInt16 nEntries = rEntries.GetTokenCount( cSep );
2728cdf0e10cSrcweir 	for ( sal_uInt16 nEntry = 0; nEntry < nEntries; nEntry++ )
2729cdf0e10cSrcweir 	{
2730cdf0e10cSrcweir 		XubString aEntry = rEntries.GetToken( nEntry, cSep );
2731cdf0e10cSrcweir 		// Accept only existing entries
2732cdf0e10cSrcweir 		if ( GetEntryList()->FindEntry( aEntry ) != LISTBOX_ENTRY_NOTFOUND )
2733cdf0e10cSrcweir 		{
2734cdf0e10cSrcweir 			ImplEntryType* pNewEntry = new ImplEntryType( aEntry );
2735cdf0e10cSrcweir 			maLBWindow.GetEntryList()->InsertEntry( nMRUCount++, pNewEntry, sal_False );
2736cdf0e10cSrcweir 			bChanges = sal_True;
2737cdf0e10cSrcweir 		}
2738cdf0e10cSrcweir 	}
2739cdf0e10cSrcweir 
2740cdf0e10cSrcweir 	if ( bChanges )
2741cdf0e10cSrcweir 	{
2742cdf0e10cSrcweir 		maLBWindow.GetEntryList()->SetMRUCount( nMRUCount );
2743cdf0e10cSrcweir 		SetSeparatorPos( nMRUCount ? nMRUCount-1 : 0 );
2744cdf0e10cSrcweir 		StateChanged( STATE_CHANGE_DATA );
2745cdf0e10cSrcweir 	}
2746cdf0e10cSrcweir }
2747cdf0e10cSrcweir 
2748cdf0e10cSrcweir // -----------------------------------------------------------------------
2749cdf0e10cSrcweir 
GetMRUEntries(xub_Unicode cSep) const2750cdf0e10cSrcweir XubString ImplListBox::GetMRUEntries( xub_Unicode cSep ) const
2751cdf0e10cSrcweir {
2752cdf0e10cSrcweir 	String aEntries;
2753cdf0e10cSrcweir 	for ( sal_uInt16 n = 0; n < GetEntryList()->GetMRUCount(); n++ )
2754cdf0e10cSrcweir 	{
2755cdf0e10cSrcweir 		aEntries += GetEntryList()->GetEntryText( n );
2756cdf0e10cSrcweir 		if( n < ( GetEntryList()->GetMRUCount() - 1 ) )
2757cdf0e10cSrcweir 			aEntries += cSep;
2758cdf0e10cSrcweir 	}
2759cdf0e10cSrcweir 	return aEntries;
2760cdf0e10cSrcweir }
2761cdf0e10cSrcweir 
2762a68b38dfSArmin Le Grand // -----------------------------------------------------------------------
2763a68b38dfSArmin Le Grand 
SetEdgeBlending(bool bNew)2764a68b38dfSArmin Le Grand void ImplListBox::SetEdgeBlending(bool bNew)
2765a68b38dfSArmin Le Grand {
2766a68b38dfSArmin Le Grand     if(mbEdgeBlending != bNew)
2767a68b38dfSArmin Le Grand     {
2768a68b38dfSArmin Le Grand         mbEdgeBlending = bNew;
2769a68b38dfSArmin Le Grand         maLBWindow.SetEdgeBlending(GetEdgeBlending());
2770a68b38dfSArmin Le Grand     }
2771a68b38dfSArmin Le Grand }
2772a68b38dfSArmin Le Grand 
2773cdf0e10cSrcweir // =======================================================================
2774cdf0e10cSrcweir 
ImplWin(Window * pParent,WinBits nWinStyle)2775cdf0e10cSrcweir ImplWin::ImplWin( Window* pParent, WinBits nWinStyle ) :
2776cdf0e10cSrcweir 	Control ( pParent, nWinStyle )
2777cdf0e10cSrcweir {
2778cdf0e10cSrcweir 	if ( IsNativeControlSupported(CTRL_LISTBOX, PART_ENTIRE_CONTROL)
2779cdf0e10cSrcweir 			&& ! IsNativeControlSupported(CTRL_LISTBOX, PART_BUTTON_DOWN) )
2780cdf0e10cSrcweir 		SetBackground();
2781cdf0e10cSrcweir 	else
2782cdf0e10cSrcweir 		SetBackground( Wallpaper( GetSettings().GetStyleSettings().GetFieldColor() ) );
2783cdf0e10cSrcweir 
2784a68b38dfSArmin Le Grand 	mbInUserDraw = false;
2785a68b38dfSArmin Le Grand 	mbUserDrawEnabled = false;
2786a68b38dfSArmin Le Grand     mbEdgeBlending = false;
2787cdf0e10cSrcweir 	mnItemPos = LISTBOX_ENTRY_NOTFOUND;
2788cdf0e10cSrcweir }
2789cdf0e10cSrcweir 
2790cdf0e10cSrcweir // -----------------------------------------------------------------------
2791cdf0e10cSrcweir 
SetModeImage(const Image & rImage,BmpColorMode eMode)2792cdf0e10cSrcweir sal_Bool ImplWin::SetModeImage( const Image& rImage, BmpColorMode eMode )
2793cdf0e10cSrcweir {
2794cdf0e10cSrcweir     if( eMode == BMP_COLOR_NORMAL )
2795cdf0e10cSrcweir         SetImage( rImage );
2796cdf0e10cSrcweir     else if( eMode == BMP_COLOR_HIGHCONTRAST )
2797cdf0e10cSrcweir 		maImageHC = rImage;
2798cdf0e10cSrcweir     else
2799cdf0e10cSrcweir         return sal_False;
2800cdf0e10cSrcweir     return sal_True;
2801cdf0e10cSrcweir }
2802cdf0e10cSrcweir 
2803cdf0e10cSrcweir // -----------------------------------------------------------------------
2804cdf0e10cSrcweir 
GetModeImage(BmpColorMode eMode) const2805cdf0e10cSrcweir const Image& ImplWin::GetModeImage( BmpColorMode eMode ) const
2806cdf0e10cSrcweir {
2807cdf0e10cSrcweir     if( eMode == BMP_COLOR_HIGHCONTRAST )
2808cdf0e10cSrcweir         return maImageHC;
2809cdf0e10cSrcweir     else
2810cdf0e10cSrcweir         return maImage;
2811cdf0e10cSrcweir }
2812cdf0e10cSrcweir 
2813cdf0e10cSrcweir // -----------------------------------------------------------------------
2814cdf0e10cSrcweir 
MBDown()2815cdf0e10cSrcweir void ImplWin::MBDown()
2816cdf0e10cSrcweir {
2817cdf0e10cSrcweir 	if( IsEnabled() )
2818cdf0e10cSrcweir 		maMBDownHdl.Call( this );
2819cdf0e10cSrcweir }
2820cdf0e10cSrcweir 
2821cdf0e10cSrcweir // -----------------------------------------------------------------------
2822cdf0e10cSrcweir 
MouseButtonDown(const MouseEvent &)2823cdf0e10cSrcweir void ImplWin::MouseButtonDown( const MouseEvent& )
2824cdf0e10cSrcweir {
2825cdf0e10cSrcweir 	if( IsEnabled() )
2826cdf0e10cSrcweir 	{
2827cdf0e10cSrcweir //		Control::MouseButtonDown( rMEvt );
2828cdf0e10cSrcweir 		MBDown();
2829cdf0e10cSrcweir 	}
2830cdf0e10cSrcweir }
2831cdf0e10cSrcweir 
2832cdf0e10cSrcweir // -----------------------------------------------------------------------
2833cdf0e10cSrcweir 
FillLayoutData() const2834cdf0e10cSrcweir void ImplWin::FillLayoutData() const
2835cdf0e10cSrcweir {
2836cdf0e10cSrcweir     mpControlData->mpLayoutData = new vcl::ControlLayoutData();
2837cdf0e10cSrcweir     const_cast<ImplWin*>(this)->ImplDraw( true );
2838cdf0e10cSrcweir }
2839cdf0e10cSrcweir 
2840cdf0e10cSrcweir // -----------------------------------------------------------------------
2841cdf0e10cSrcweir 
PreNotify(NotifyEvent & rNEvt)2842cdf0e10cSrcweir long ImplWin::PreNotify( NotifyEvent& rNEvt )
2843cdf0e10cSrcweir {
2844cdf0e10cSrcweir     long nDone = 0;
2845cdf0e10cSrcweir     const MouseEvent* pMouseEvt = NULL;
2846cdf0e10cSrcweir 
2847cdf0e10cSrcweir     if( (rNEvt.GetType() == EVENT_MOUSEMOVE) && (pMouseEvt = rNEvt.GetMouseEvent()) != NULL )
2848cdf0e10cSrcweir     {
2849cdf0e10cSrcweir         if( pMouseEvt->IsEnterWindow() || pMouseEvt->IsLeaveWindow() )
2850cdf0e10cSrcweir         {
2851cdf0e10cSrcweir             // trigger redraw as mouse over state has changed
2852cdf0e10cSrcweir             if ( IsNativeControlSupported(CTRL_LISTBOX, PART_ENTIRE_CONTROL)
2853cdf0e10cSrcweir 			&& ! IsNativeControlSupported(CTRL_LISTBOX, PART_BUTTON_DOWN) )
2854cdf0e10cSrcweir             {
2855cdf0e10cSrcweir                 GetParent()->GetWindow( WINDOW_BORDER )->Invalidate( INVALIDATE_NOERASE );
2856cdf0e10cSrcweir                 GetParent()->GetWindow( WINDOW_BORDER )->Update();
2857cdf0e10cSrcweir             }
2858cdf0e10cSrcweir         }
2859cdf0e10cSrcweir     }
2860cdf0e10cSrcweir 
2861cdf0e10cSrcweir     return nDone ? nDone : Control::PreNotify(rNEvt);
2862cdf0e10cSrcweir }
2863cdf0e10cSrcweir 
2864cdf0e10cSrcweir // -----------------------------------------------------------------------
2865cdf0e10cSrcweir 
ImplDraw(bool bLayout)2866cdf0e10cSrcweir void ImplWin::ImplDraw( bool bLayout )
2867cdf0e10cSrcweir {
2868cdf0e10cSrcweir 	const StyleSettings& rStyleSettings = GetSettings().GetStyleSettings();
2869cdf0e10cSrcweir 
2870cdf0e10cSrcweir     sal_Bool bNativeOK = sal_False;
2871cdf0e10cSrcweir 
2872cdf0e10cSrcweir     if( ! bLayout )
2873cdf0e10cSrcweir     {
2874cdf0e10cSrcweir         ControlState nState = CTRL_STATE_ENABLED;
2875cdf0e10cSrcweir         if ( IsNativeControlSupported(CTRL_LISTBOX, PART_ENTIRE_CONTROL)
2876cdf0e10cSrcweir 			&& IsNativeControlSupported(CTRL_LISTBOX, HAS_BACKGROUND_TEXTURE) )
2877cdf0e10cSrcweir         {
2878cdf0e10cSrcweir 	        // Repaint the (focused) area similarly to
2879cdf0e10cSrcweir 	        // ImplSmallBorderWindowView::DrawWindow() in
2880cdf0e10cSrcweir 	        // vcl/source/window/brdwin.cxx
2881cdf0e10cSrcweir 	        Window *pWin = GetParent();
2882cdf0e10cSrcweir 
2883cdf0e10cSrcweir 	        ImplControlValue aControlValue;
2884cdf0e10cSrcweir 	        if ( !pWin->IsEnabled() )
2885cdf0e10cSrcweir 		    nState &= ~CTRL_STATE_ENABLED;
2886cdf0e10cSrcweir 	        if ( pWin->HasFocus() )
2887cdf0e10cSrcweir 		    nState |= CTRL_STATE_FOCUSED;
2888cdf0e10cSrcweir 
2889cdf0e10cSrcweir 	        // The listbox is painted over the entire control including the
2890cdf0e10cSrcweir 	        // border, but ImplWin does not contain the border => correction
2891cdf0e10cSrcweir 	        // needed.
2892cdf0e10cSrcweir 	        sal_Int32 nLeft, nTop, nRight, nBottom;
2893cdf0e10cSrcweir 	        pWin->GetBorder( nLeft, nTop, nRight, nBottom );
2894cdf0e10cSrcweir 	        Point aPoint( -nLeft, -nTop );
2895cdf0e10cSrcweir 	        Rectangle aCtrlRegion( aPoint - GetPosPixel(), pWin->GetSizePixel() );
2896cdf0e10cSrcweir 
2897cdf0e10cSrcweir             sal_Bool bMouseOver = sal_False;
2898cdf0e10cSrcweir             if( GetParent() )
2899cdf0e10cSrcweir             {
2900cdf0e10cSrcweir                 Window *pChild = GetParent()->GetWindow( WINDOW_FIRSTCHILD );
2901cdf0e10cSrcweir                 while( pChild && (bMouseOver = pChild->IsMouseOver()) == sal_False )
2902cdf0e10cSrcweir                     pChild = pChild->GetWindow( WINDOW_NEXT );
2903cdf0e10cSrcweir             }
2904cdf0e10cSrcweir 
2905cdf0e10cSrcweir             if( bMouseOver )
2906cdf0e10cSrcweir                 nState |= CTRL_STATE_ROLLOVER;
2907cdf0e10cSrcweir 
2908cdf0e10cSrcweir             // if parent has no border, then nobody has drawn the background
2909cdf0e10cSrcweir             // since no border window exists. so draw it here.
2910cdf0e10cSrcweir             WinBits nParentStyle = pWin->GetStyle();
2911cdf0e10cSrcweir             if( ! (nParentStyle & WB_BORDER) || (nParentStyle & WB_NOBORDER) )
2912cdf0e10cSrcweir             {
2913cdf0e10cSrcweir                 Rectangle aParentRect( Point( 0, 0 ), pWin->GetSizePixel() );
2914cdf0e10cSrcweir                 pWin->DrawNativeControl( CTRL_LISTBOX, PART_ENTIRE_CONTROL, aParentRect,
2915cdf0e10cSrcweir                                          nState, aControlValue, rtl::OUString() );
2916cdf0e10cSrcweir             }
2917cdf0e10cSrcweir 
2918cdf0e10cSrcweir 	        bNativeOK = DrawNativeControl( CTRL_LISTBOX, PART_ENTIRE_CONTROL, aCtrlRegion, nState,
2919cdf0e10cSrcweir 		        aControlValue, rtl::OUString() );
2920cdf0e10cSrcweir 	    }
2921cdf0e10cSrcweir 
2922cdf0e10cSrcweir         if( IsEnabled() )
2923cdf0e10cSrcweir         {
2924cdf0e10cSrcweir             if( HasFocus() )
2925cdf0e10cSrcweir             {
2926cdf0e10cSrcweir                 SetTextColor( rStyleSettings.GetHighlightTextColor() );
2927cdf0e10cSrcweir                 SetFillColor( rStyleSettings.GetHighlightColor() );
2928cdf0e10cSrcweir                 DrawRect( maFocusRect );
2929cdf0e10cSrcweir             }
2930cdf0e10cSrcweir             else
2931cdf0e10cSrcweir             {
2932cdf0e10cSrcweir                 Color aColor;
2933cdf0e10cSrcweir                 if( bNativeOK && (nState & CTRL_STATE_ROLLOVER) )
2934cdf0e10cSrcweir                     aColor = rStyleSettings.GetFieldRolloverTextColor();
2935cdf0e10cSrcweir                 else
2936cdf0e10cSrcweir                     aColor = rStyleSettings.GetFieldTextColor();
2937cdf0e10cSrcweir                 if( IsControlForeground() )
2938cdf0e10cSrcweir                     aColor = GetControlForeground();
2939cdf0e10cSrcweir                 SetTextColor( aColor );
2940cdf0e10cSrcweir 		        if ( !bNativeOK )
2941cdf0e10cSrcweir 		            Erase( maFocusRect );
2942cdf0e10cSrcweir             }
2943cdf0e10cSrcweir         }
2944cdf0e10cSrcweir         else // Disabled
2945cdf0e10cSrcweir         {
2946cdf0e10cSrcweir             SetTextColor( rStyleSettings.GetDisableColor() );
2947cdf0e10cSrcweir 	        if ( !bNativeOK )
2948cdf0e10cSrcweir 		        Erase( maFocusRect );
2949cdf0e10cSrcweir         }
2950cdf0e10cSrcweir     }
2951cdf0e10cSrcweir 
2952cdf0e10cSrcweir 	if ( IsUserDrawEnabled() )
2953cdf0e10cSrcweir 	{
2954a68b38dfSArmin Le Grand 		mbInUserDraw = true;
2955cdf0e10cSrcweir 		UserDrawEvent aUDEvt( this, maFocusRect, mnItemPos, 0 );
2956cdf0e10cSrcweir 		maUserDrawHdl.Call( &aUDEvt );
2957a68b38dfSArmin Le Grand 		mbInUserDraw = false;
2958cdf0e10cSrcweir 	}
2959cdf0e10cSrcweir 	else
2960cdf0e10cSrcweir 	{
2961cdf0e10cSrcweir 		DrawEntry( sal_True, sal_True, sal_False, bLayout );
2962cdf0e10cSrcweir 	}
2963cdf0e10cSrcweir }
2964cdf0e10cSrcweir 
2965cdf0e10cSrcweir // -----------------------------------------------------------------------
2966cdf0e10cSrcweir 
Paint(const Rectangle &)2967cdf0e10cSrcweir void ImplWin::Paint( const Rectangle& )
2968cdf0e10cSrcweir {
2969cdf0e10cSrcweir     ImplDraw();
2970cdf0e10cSrcweir }
2971cdf0e10cSrcweir 
2972cdf0e10cSrcweir // -----------------------------------------------------------------------
2973cdf0e10cSrcweir 
DrawEntry(sal_Bool bDrawImage,sal_Bool bDrawText,sal_Bool bDrawTextAtImagePos,bool bLayout)2974cdf0e10cSrcweir void ImplWin::DrawEntry( sal_Bool bDrawImage, sal_Bool bDrawText, sal_Bool bDrawTextAtImagePos, bool bLayout )
2975cdf0e10cSrcweir {
2976cdf0e10cSrcweir 	long nBorder = 1;
2977cdf0e10cSrcweir 	Size aOutSz = GetOutputSizePixel();
2978cdf0e10cSrcweir 
2979cdf0e10cSrcweir 	sal_Bool bImage = !!maImage;
2980cdf0e10cSrcweir 	if( bDrawImage && bImage && !bLayout )
2981cdf0e10cSrcweir 	{
2982cdf0e10cSrcweir 		sal_uInt16 nStyle = 0;
2983cdf0e10cSrcweir 		Size aImgSz = maImage.GetSizePixel();
2984cdf0e10cSrcweir 		Point aPtImg( nBorder, ( ( aOutSz.Height() - aImgSz.Height() ) / 2 ) );
2985a68b38dfSArmin Le Grand         const StyleSettings& rStyleSettings = Application::GetSettings().GetStyleSettings();
2986cdf0e10cSrcweir 
2987cdf0e10cSrcweir 		// check for HC mode
2988cdf0e10cSrcweir 		Image *pImage = &maImage;
2989cdf0e10cSrcweir 
2990cdf0e10cSrcweir 		if( !!maImageHC )
2991cdf0e10cSrcweir 		{
2992a68b38dfSArmin Le Grand 			if( rStyleSettings.GetHighContrastMode() )
2993cdf0e10cSrcweir 				pImage = &maImageHC;
2994cdf0e10cSrcweir 		}
2995cdf0e10cSrcweir 
2996cdf0e10cSrcweir 		if ( !IsZoom() )
2997cdf0e10cSrcweir 		{
2998cdf0e10cSrcweir 			DrawImage( aPtImg, *pImage, nStyle );
2999cdf0e10cSrcweir 		}
3000cdf0e10cSrcweir 		else
3001cdf0e10cSrcweir 		{
3002cdf0e10cSrcweir 			aImgSz.Width() = CalcZoom( aImgSz.Width() );
3003cdf0e10cSrcweir 			aImgSz.Height() = CalcZoom( aImgSz.Height() );
3004cdf0e10cSrcweir 			DrawImage( aPtImg, aImgSz, *pImage, nStyle );
3005cdf0e10cSrcweir 		}
3006a68b38dfSArmin Le Grand 
3007a68b38dfSArmin Le Grand         const sal_uInt16 nEdgeBlendingPercent(GetEdgeBlending() ? rStyleSettings.GetEdgeBlending() : 0);
3008a68b38dfSArmin Le Grand 
3009a68b38dfSArmin Le Grand         if(nEdgeBlendingPercent)
3010a68b38dfSArmin Le Grand         {
3011ff0f521cSArmin Le Grand             const Color& rTopLeft(rStyleSettings.GetEdgeBlendingTopLeftColor());
3012ff0f521cSArmin Le Grand             const Color& rBottomRight(rStyleSettings.GetEdgeBlendingBottomRightColor());
3013ff0f521cSArmin Le Grand             const sal_uInt8 nAlpha((nEdgeBlendingPercent * 255) / 100);
3014ff0f521cSArmin Le Grand             const BitmapEx aBlendFrame(createBlendFrame(aImgSz, nAlpha, rTopLeft, rBottomRight));
3015a68b38dfSArmin Le Grand 
3016ff0f521cSArmin Le Grand             if(!aBlendFrame.IsEmpty())
3017a68b38dfSArmin Le Grand             {
3018ff0f521cSArmin Le Grand                 DrawBitmapEx(aPtImg, aBlendFrame);
3019a68b38dfSArmin Le Grand             }
3020a68b38dfSArmin Le Grand         }
3021cdf0e10cSrcweir 	}
3022cdf0e10cSrcweir 
3023cdf0e10cSrcweir 	if( bDrawText && maString.Len() )
3024cdf0e10cSrcweir 	{
3025cdf0e10cSrcweir         sal_uInt16 nTextStyle = TEXT_DRAW_VCENTER;
3026cdf0e10cSrcweir 
3027cdf0e10cSrcweir         if ( bDrawImage && bImage && !bLayout )
3028cdf0e10cSrcweir             nTextStyle |= TEXT_DRAW_LEFT;
3029cdf0e10cSrcweir         else if ( GetStyle() & WB_CENTER )
3030cdf0e10cSrcweir             nTextStyle |= TEXT_DRAW_CENTER;
3031cdf0e10cSrcweir         else if ( GetStyle() & WB_RIGHT )
3032cdf0e10cSrcweir             nTextStyle |= TEXT_DRAW_RIGHT;
3033cdf0e10cSrcweir         else
3034cdf0e10cSrcweir             nTextStyle |= TEXT_DRAW_LEFT;
3035cdf0e10cSrcweir 
3036cdf0e10cSrcweir         Rectangle aTextRect( Point( nBorder, 0 ), Size( aOutSz.Width()-2*nBorder, aOutSz.Height() ) );
3037cdf0e10cSrcweir 
3038cdf0e10cSrcweir         if ( !bDrawTextAtImagePos && ( bImage || IsUserDrawEnabled() ) )
3039cdf0e10cSrcweir 		{
3040cdf0e10cSrcweir 			long nMaxWidth = Max( maImage.GetSizePixel().Width(), maUserItemSize.Width() );
3041cdf0e10cSrcweir 			aTextRect.Left() += nMaxWidth + IMG_TXT_DISTANCE;
3042cdf0e10cSrcweir 		}
3043cdf0e10cSrcweir 
3044cdf0e10cSrcweir         MetricVector* pVector = bLayout ? &mpControlData->mpLayoutData->m_aUnicodeBoundRects : NULL;
3045cdf0e10cSrcweir         String* pDisplayText = bLayout ? &mpControlData->mpLayoutData->m_aDisplayText : NULL;
3046cdf0e10cSrcweir 		DrawText( aTextRect, maString, nTextStyle, pVector, pDisplayText );
3047cdf0e10cSrcweir 	}
3048cdf0e10cSrcweir 
3049cdf0e10cSrcweir 	if( HasFocus() && !bLayout )
3050cdf0e10cSrcweir 		ShowFocus( maFocusRect );
3051cdf0e10cSrcweir }
3052cdf0e10cSrcweir 
3053cdf0e10cSrcweir // -----------------------------------------------------------------------
3054cdf0e10cSrcweir 
Resize()3055cdf0e10cSrcweir void ImplWin::Resize()
3056cdf0e10cSrcweir {
3057cdf0e10cSrcweir     Control::Resize();
3058cdf0e10cSrcweir 	maFocusRect.SetSize( GetOutputSizePixel() );
3059cdf0e10cSrcweir 	Invalidate();
3060cdf0e10cSrcweir }
3061cdf0e10cSrcweir 
3062cdf0e10cSrcweir // -----------------------------------------------------------------------
3063cdf0e10cSrcweir 
GetFocus()3064cdf0e10cSrcweir void ImplWin::GetFocus()
3065cdf0e10cSrcweir {
3066cdf0e10cSrcweir 	ShowFocus( maFocusRect );
3067cdf0e10cSrcweir     if( ImplGetSVData()->maNWFData.mbNoFocusRects &&
3068cdf0e10cSrcweir         IsNativeWidgetEnabled() &&
3069cdf0e10cSrcweir         IsNativeControlSupported( CTRL_LISTBOX, PART_ENTIRE_CONTROL ) )
3070cdf0e10cSrcweir     {
3071cdf0e10cSrcweir         Window* pWin = GetParent()->GetWindow( WINDOW_BORDER );
3072cdf0e10cSrcweir         if( ! pWin )
3073cdf0e10cSrcweir             pWin = GetParent();
3074cdf0e10cSrcweir         pWin->Invalidate();
3075cdf0e10cSrcweir     }
3076cdf0e10cSrcweir     else
3077cdf0e10cSrcweir         Invalidate();
3078cdf0e10cSrcweir 	Control::GetFocus();
3079cdf0e10cSrcweir }
3080cdf0e10cSrcweir 
3081cdf0e10cSrcweir // -----------------------------------------------------------------------
3082cdf0e10cSrcweir 
LoseFocus()3083cdf0e10cSrcweir void ImplWin::LoseFocus()
3084cdf0e10cSrcweir {
3085cdf0e10cSrcweir 	HideFocus();
3086cdf0e10cSrcweir     if( ImplGetSVData()->maNWFData.mbNoFocusRects &&
3087cdf0e10cSrcweir         IsNativeWidgetEnabled() &&
3088cdf0e10cSrcweir         IsNativeControlSupported( CTRL_LISTBOX, PART_ENTIRE_CONTROL ) )
3089cdf0e10cSrcweir     {
3090cdf0e10cSrcweir         Window* pWin = GetParent()->GetWindow( WINDOW_BORDER );
3091cdf0e10cSrcweir         if( ! pWin )
3092cdf0e10cSrcweir             pWin = GetParent();
3093cdf0e10cSrcweir         pWin->Invalidate();
3094cdf0e10cSrcweir     }
3095cdf0e10cSrcweir     else
3096cdf0e10cSrcweir         Invalidate();
3097cdf0e10cSrcweir 	Control::LoseFocus();
3098cdf0e10cSrcweir }
3099cdf0e10cSrcweir 
3100cdf0e10cSrcweir // =======================================================================
3101cdf0e10cSrcweir 
ImplBtn(Window * pParent,WinBits nWinStyle)3102cdf0e10cSrcweir ImplBtn::ImplBtn( Window* pParent, WinBits nWinStyle ) :
3103cdf0e10cSrcweir 	PushButton(  pParent, nWinStyle ),
3104cdf0e10cSrcweir 	mbDown	( sal_False )
3105cdf0e10cSrcweir {
3106cdf0e10cSrcweir }
3107cdf0e10cSrcweir 
3108cdf0e10cSrcweir // -----------------------------------------------------------------------
3109cdf0e10cSrcweir 
MBDown()3110cdf0e10cSrcweir void ImplBtn::MBDown()
3111cdf0e10cSrcweir {
3112cdf0e10cSrcweir 	if( IsEnabled() )
3113cdf0e10cSrcweir 	   maMBDownHdl.Call( this );
3114cdf0e10cSrcweir }
3115cdf0e10cSrcweir 
3116cdf0e10cSrcweir // -----------------------------------------------------------------------
3117cdf0e10cSrcweir 
MouseButtonDown(const MouseEvent &)3118cdf0e10cSrcweir void ImplBtn::MouseButtonDown( const MouseEvent& )
3119cdf0e10cSrcweir {
3120cdf0e10cSrcweir 	//PushButton::MouseButtonDown( rMEvt );
3121cdf0e10cSrcweir 	if( IsEnabled() )
3122cdf0e10cSrcweir 	{
3123cdf0e10cSrcweir 		MBDown();
3124cdf0e10cSrcweir 		mbDown = sal_True;
3125cdf0e10cSrcweir 	}
3126cdf0e10cSrcweir }
3127cdf0e10cSrcweir 
3128cdf0e10cSrcweir // =======================================================================
3129cdf0e10cSrcweir 
ImplListBoxFloatingWindow(Window * pParent)3130cdf0e10cSrcweir ImplListBoxFloatingWindow::ImplListBoxFloatingWindow( Window* pParent ) :
3131cdf0e10cSrcweir 	FloatingWindow( pParent, WB_BORDER | WB_SYSTEMWINDOW | WB_NOSHADOW )    // no drop shadow for list boxes
3132cdf0e10cSrcweir {
3133cdf0e10cSrcweir 	mpImplLB = NULL;
3134cdf0e10cSrcweir 	mnDDLineCount = 0;
3135cdf0e10cSrcweir 	mbAutoWidth = sal_False;
3136cdf0e10cSrcweir 
3137cdf0e10cSrcweir     mnPopupModeStartSaveSelection = LISTBOX_ENTRY_NOTFOUND;
3138cdf0e10cSrcweir 
3139cdf0e10cSrcweir 	EnableSaveBackground();
3140cdf0e10cSrcweir 
3141cdf0e10cSrcweir     Window * pBorderWindow = ImplGetBorderWindow();
3142cdf0e10cSrcweir     if( pBorderWindow )
3143cdf0e10cSrcweir     {
3144cdf0e10cSrcweir         SetAccessibleRole(accessibility::AccessibleRole::PANEL);
3145cdf0e10cSrcweir         pBorderWindow->SetAccessibleRole(accessibility::AccessibleRole::WINDOW);
3146cdf0e10cSrcweir     }
3147cdf0e10cSrcweir     else
3148cdf0e10cSrcweir     {
3149cdf0e10cSrcweir         SetAccessibleRole(accessibility::AccessibleRole::WINDOW);
3150cdf0e10cSrcweir     }
3151cdf0e10cSrcweir 
3152cdf0e10cSrcweir }
3153cdf0e10cSrcweir 
3154cdf0e10cSrcweir // -----------------------------------------------------------------------
3155cdf0e10cSrcweir 
PreNotify(NotifyEvent & rNEvt)3156cdf0e10cSrcweir long ImplListBoxFloatingWindow::PreNotify( NotifyEvent& rNEvt )
3157cdf0e10cSrcweir {
3158cdf0e10cSrcweir 	if( rNEvt.GetType() == EVENT_LOSEFOCUS )
3159cdf0e10cSrcweir 	{
3160cdf0e10cSrcweir 		if( !GetParent()->HasChildPathFocus( sal_True ) )
3161cdf0e10cSrcweir 			EndPopupMode();
3162cdf0e10cSrcweir 	}
3163cdf0e10cSrcweir 
3164cdf0e10cSrcweir 	return FloatingWindow::PreNotify( rNEvt );
3165cdf0e10cSrcweir }
3166cdf0e10cSrcweir 
3167cdf0e10cSrcweir // -----------------------------------------------------------------------
3168cdf0e10cSrcweir 
SetPosSizePixel(long nX,long nY,long nWidth,long nHeight,sal_uInt16 nFlags)3169cdf0e10cSrcweir void ImplListBoxFloatingWindow::SetPosSizePixel( long nX, long nY, long nWidth, long nHeight, sal_uInt16 nFlags )
3170cdf0e10cSrcweir {
3171cdf0e10cSrcweir 	FloatingWindow::SetPosSizePixel( nX, nY, nWidth, nHeight, nFlags );
3172cdf0e10cSrcweir 
3173cdf0e10cSrcweir 	// Fix #60890# ( MBA ): um auch im aufgeklappten Zustand der Listbox die Gr"o\se einfach zu einen
3174cdf0e10cSrcweir 	// Aufruf von Resize() "andern zu k"onnen, wird die Position hier ggf. angepa\t
3175cdf0e10cSrcweir 	if ( IsReallyVisible() && ( nFlags & WINDOW_POSSIZE_HEIGHT ) )
3176cdf0e10cSrcweir 	{
3177cdf0e10cSrcweir 		Point aPos = GetParent()->GetPosPixel();
3178cdf0e10cSrcweir 		aPos = GetParent()->GetParent()->OutputToScreenPixel( aPos );
3179cdf0e10cSrcweir 
3180cdf0e10cSrcweir 		if ( nFlags & WINDOW_POSSIZE_X )
3181cdf0e10cSrcweir 			aPos.X() = nX;
3182cdf0e10cSrcweir 
3183cdf0e10cSrcweir 		if ( nFlags & WINDOW_POSSIZE_Y )
3184cdf0e10cSrcweir 			aPos.Y() = nY;
3185cdf0e10cSrcweir 
3186cdf0e10cSrcweir 		sal_uInt16 nIndex;
3187cdf0e10cSrcweir 		SetPosPixel( ImplCalcPos( this, Rectangle( aPos, GetParent()->GetSizePixel() ), FLOATWIN_POPUPMODE_DOWN, nIndex ) );
3188cdf0e10cSrcweir 	}
3189cdf0e10cSrcweir 
3190cdf0e10cSrcweir //	if( !IsReallyVisible() )
3191cdf0e10cSrcweir 	{
3192cdf0e10cSrcweir 		// Die ImplListBox erhaelt kein Resize, weil nicht sichtbar.
3193cdf0e10cSrcweir 		// Die Fenster muessen aber ein Resize() erhalten, damit die
3194cdf0e10cSrcweir 		// Anzahl der sichtbaren Eintraege fuer PgUp/PgDown stimmt.
3195cdf0e10cSrcweir 		// Die Anzahl kann auch nicht von List/Combobox berechnet werden,
3196cdf0e10cSrcweir 		// weil hierfuer auch die ggf. vorhandene vertikale Scrollbar
3197cdf0e10cSrcweir 		// beruecksichtigt werden muss.
3198cdf0e10cSrcweir 		mpImplLB->SetSizePixel( GetOutputSizePixel() );
3199cdf0e10cSrcweir 		((Window*)mpImplLB)->Resize();
3200cdf0e10cSrcweir 		((Window*)mpImplLB->GetMainWindow())->Resize();
3201cdf0e10cSrcweir 	}
3202cdf0e10cSrcweir }
3203cdf0e10cSrcweir 
3204cdf0e10cSrcweir // -----------------------------------------------------------------------
3205cdf0e10cSrcweir 
Resize()3206cdf0e10cSrcweir void ImplListBoxFloatingWindow::Resize()
3207cdf0e10cSrcweir {
3208cdf0e10cSrcweir     mpImplLB->GetMainWindow()->ImplClearLayoutData();
3209cdf0e10cSrcweir     FloatingWindow::Resize();
3210cdf0e10cSrcweir }
3211cdf0e10cSrcweir 
3212cdf0e10cSrcweir // -----------------------------------------------------------------------
3213cdf0e10cSrcweir 
CalcFloatSize()3214cdf0e10cSrcweir Size ImplListBoxFloatingWindow::CalcFloatSize()
3215cdf0e10cSrcweir {
3216cdf0e10cSrcweir 	Size aFloatSz( maPrefSz );
3217cdf0e10cSrcweir 
3218cdf0e10cSrcweir 	sal_Int32 nLeft, nTop, nRight, nBottom;
3219cdf0e10cSrcweir 	GetBorder( nLeft, nTop, nRight, nBottom );
3220cdf0e10cSrcweir 
3221cdf0e10cSrcweir 	sal_uInt16 nLines = mpImplLB->GetEntryList()->GetEntryCount();
3222cdf0e10cSrcweir 	if ( mnDDLineCount && ( nLines > mnDDLineCount ) )
3223cdf0e10cSrcweir 		nLines = mnDDLineCount;
3224cdf0e10cSrcweir 
3225cdf0e10cSrcweir 	Size aSz = mpImplLB->CalcSize( nLines );
3226cdf0e10cSrcweir 	long nMaxHeight = aSz.Height() + nTop + nBottom;
3227cdf0e10cSrcweir 
3228cdf0e10cSrcweir 	if ( mnDDLineCount )
3229cdf0e10cSrcweir 		aFloatSz.Height() = nMaxHeight;
3230cdf0e10cSrcweir 
3231cdf0e10cSrcweir 	if( mbAutoWidth )
3232cdf0e10cSrcweir 	{
3233cdf0e10cSrcweir 		// AutoSize erstmal nur fuer die Breite...
3234cdf0e10cSrcweir 
3235cdf0e10cSrcweir 		aFloatSz.Width() = aSz.Width() + nLeft + nRight;
3236cdf0e10cSrcweir 		aFloatSz.Width() += nRight; // etwas mehr Platz sieht besser aus...
3237cdf0e10cSrcweir 
3238cdf0e10cSrcweir 		if ( ( aFloatSz.Height() < nMaxHeight ) || ( mnDDLineCount && ( mnDDLineCount < mpImplLB->GetEntryList()->GetEntryCount() ) ) )
3239cdf0e10cSrcweir 		{
3240cdf0e10cSrcweir 			// dann wird noch der vertikale Scrollbar benoetigt
3241cdf0e10cSrcweir 			long nSBWidth = GetSettings().GetStyleSettings().GetScrollBarSize();
3242cdf0e10cSrcweir 			aFloatSz.Width() += nSBWidth;
3243cdf0e10cSrcweir 		}
3244cdf0e10cSrcweir 	}
3245cdf0e10cSrcweir 
3246cdf0e10cSrcweir 	if ( aFloatSz.Height() > nMaxHeight )
3247cdf0e10cSrcweir 		aFloatSz.Height() = nMaxHeight;
3248cdf0e10cSrcweir 
3249cdf0e10cSrcweir 	// Minimale Hoehe, falls Hoehe nicht auf Float-Hoehe eingestellt wurde.
3250cdf0e10cSrcweir 	// Der Parent vom FloatWin muss die DropDown-Combo/Listbox sein.
3251cdf0e10cSrcweir 	Size aParentSz = GetParent()->GetSizePixel();
3252cdf0e10cSrcweir 	if( !mnDDLineCount && ( aFloatSz.Height() < aParentSz.Height() ) )
3253cdf0e10cSrcweir 		aFloatSz.Height() = aParentSz.Height();
3254cdf0e10cSrcweir 
3255cdf0e10cSrcweir 	// Nicht schmaler als der Parent werden...
3256cdf0e10cSrcweir 	if( aFloatSz.Width() < aParentSz.Width() )
3257cdf0e10cSrcweir 		aFloatSz.Width() = aParentSz.Width();
3258cdf0e10cSrcweir 
3259cdf0e10cSrcweir 	// Hoehe auf Entries alignen...
3260cdf0e10cSrcweir 	long nInnerHeight = aFloatSz.Height() - nTop - nBottom;
3261cdf0e10cSrcweir 	long nEntryHeight = mpImplLB->GetEntryHeight();
3262cdf0e10cSrcweir 	if ( nInnerHeight % nEntryHeight )
3263cdf0e10cSrcweir 	{
3264cdf0e10cSrcweir 		nInnerHeight /= nEntryHeight;
3265cdf0e10cSrcweir 		nInnerHeight++;
3266cdf0e10cSrcweir 		nInnerHeight *= nEntryHeight;
3267cdf0e10cSrcweir 		aFloatSz.Height() = nInnerHeight + nTop + nBottom;
3268cdf0e10cSrcweir 	}
3269cdf0e10cSrcweir 
3270cdf0e10cSrcweir 	return aFloatSz;
3271cdf0e10cSrcweir }
3272cdf0e10cSrcweir 
3273cdf0e10cSrcweir // -----------------------------------------------------------------------
3274cdf0e10cSrcweir 
StartFloat(sal_Bool bStartTracking)3275cdf0e10cSrcweir void ImplListBoxFloatingWindow::StartFloat( sal_Bool bStartTracking )
3276cdf0e10cSrcweir {
3277cdf0e10cSrcweir 	if( !IsInPopupMode() )
3278cdf0e10cSrcweir 	{
3279cdf0e10cSrcweir 		Size aFloatSz = CalcFloatSize();
3280cdf0e10cSrcweir 
3281cdf0e10cSrcweir 		SetSizePixel( aFloatSz );
3282cdf0e10cSrcweir 		mpImplLB->SetSizePixel( GetOutputSizePixel() );
3283cdf0e10cSrcweir 
3284cdf0e10cSrcweir 		sal_uInt16 nPos = mpImplLB->GetEntryList()->GetSelectEntryPos( 0 );
3285cdf0e10cSrcweir         mnPopupModeStartSaveSelection = nPos;
3286cdf0e10cSrcweir 
3287cdf0e10cSrcweir         Size aSz = GetParent()->GetSizePixel();
3288cdf0e10cSrcweir 		Point aPos = GetParent()->GetPosPixel();
3289cdf0e10cSrcweir 		aPos = GetParent()->GetParent()->OutputToScreenPixel( aPos );
3290cdf0e10cSrcweir         // FIXME: this ugly hack is for Mac/Aqua
3291cdf0e10cSrcweir         // should be replaced by a real mechanism to place the float rectangle
3292cdf0e10cSrcweir         if( ImplGetSVData()->maNWFData.mbNoFocusRects &&
3293cdf0e10cSrcweir             GetParent()->IsNativeWidgetEnabled() )
3294cdf0e10cSrcweir         {
3295cdf0e10cSrcweir             sal_Int32 nLeft = 4, nTop = 4, nRight = 4, nBottom = 4;
3296cdf0e10cSrcweir             aPos.X() += nLeft;
3297cdf0e10cSrcweir             aPos.Y() += nTop;
3298cdf0e10cSrcweir             aSz.Width() -= nLeft + nRight;
3299cdf0e10cSrcweir             aSz.Height() -= nTop + nBottom;
3300cdf0e10cSrcweir         }
3301cdf0e10cSrcweir 		Rectangle aRect( aPos, aSz );
3302cdf0e10cSrcweir 
3303cdf0e10cSrcweir         // check if the control's parent is un-mirrored which is the case for form controls in a mirrored UI
3304cdf0e10cSrcweir         // where the document is unmirrored
3305cdf0e10cSrcweir         // because StartPopupMode() expects a rectangle in mirrored coordinates we have to re-mirror
3306cdf0e10cSrcweir         if( GetParent()->GetParent()->ImplIsAntiparallel() )
3307cdf0e10cSrcweir             GetParent()->GetParent()->ImplReMirror( aRect );
3308cdf0e10cSrcweir 
3309cdf0e10cSrcweir 		StartPopupMode( aRect, FLOATWIN_POPUPMODE_DOWN );
3310cdf0e10cSrcweir 
3311cdf0e10cSrcweir         if( nPos != LISTBOX_ENTRY_NOTFOUND )
3312cdf0e10cSrcweir             mpImplLB->ShowProminentEntry( nPos );
3313cdf0e10cSrcweir 
3314cdf0e10cSrcweir 		if( bStartTracking )
3315cdf0e10cSrcweir 			mpImplLB->GetMainWindow()->EnableMouseMoveSelect( sal_True );
3316cdf0e10cSrcweir 
3317cdf0e10cSrcweir 		if ( mpImplLB->GetMainWindow()->IsGrabFocusAllowed() )
3318cdf0e10cSrcweir 			mpImplLB->GetMainWindow()->GrabFocus();
3319cdf0e10cSrcweir 
3320cdf0e10cSrcweir         mpImplLB->GetMainWindow()->ImplClearLayoutData();
3321cdf0e10cSrcweir 	}
3322cdf0e10cSrcweir }
3323