LCOV - code coverage report
Current view: top level - usr/local/src/libreoffice/vcl/source/control - ilstbox.cxx (source / functions) Hit Total Coverage
Test: libreoffice_filtered.info Lines: 892 1696 52.6 %
Date: 2013-07-09 Functions: 81 128 63.3 %
Legend: Lines: hit not hit

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

Generated by: LCOV version 1.10