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