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

Generated by: LCOV version 1.10