LCOV - code coverage report
Current view: top level - usr/local/src/libreoffice/vcl/source/control - combobox.cxx (source / functions) Hit Total Coverage
Test: libreoffice_filtered.info Lines: 422 813 51.9 %
Date: 2013-07-09 Functions: 56 98 57.1 %
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 <set>
      22             : #include <comphelper/string.hxx>
      23             : #include <tools/debug.hxx>
      24             : #include <tools/rc.h>
      25             : #include <vcl/decoview.hxx>
      26             : #include <vcl/lstbox.h>
      27             : #include <vcl/button.hxx>
      28             : #include <vcl/event.hxx>
      29             : #include <vcl/combobox.hxx>
      30             : 
      31             : #include <svdata.hxx>
      32             : #include <ilstbox.hxx>
      33             : #include <controldata.hxx>
      34             : 
      35             : // =======================================================================
      36             : 
      37           0 : static void lcl_GetSelectedEntries( ::std::set< sal_uInt16 >& rSelectedPos, const OUString& rText, sal_Unicode cTokenSep, const ImplEntryList* pEntryList )
      38             : {
      39           0 :     for (sal_Int32 n = comphelper::string::getTokenCount(rText, cTokenSep); n;)
      40             :     {
      41           0 :         OUString aToken = rText.getToken( --n, cTokenSep );
      42           0 :         aToken = comphelper::string::strip(aToken, ' ');
      43           0 :         sal_uInt16 nPos = pEntryList->FindEntry( aToken );
      44           0 :         if ( nPos != LISTBOX_ENTRY_NOTFOUND )
      45           0 :             rSelectedPos.insert( nPos );
      46           0 :     }
      47           0 : }
      48             : 
      49             : // =======================================================================
      50             : 
      51           0 : ComboBox::ComboBox( WindowType nType ) :
      52           0 :     Edit( nType )
      53             : {
      54           0 :     ImplInitComboBoxData();
      55           0 :     SetWidthInChars(-1);
      56           0 : }
      57             : 
      58             : // -----------------------------------------------------------------------
      59             : 
      60        1289 : ComboBox::ComboBox( Window* pParent, WinBits nStyle ) :
      61        1289 :     Edit( WINDOW_COMBOBOX )
      62             : {
      63        1289 :     ImplInitComboBoxData();
      64        1289 :     ImplInit( pParent, nStyle );
      65        1289 :     SetWidthInChars(-1);
      66        1289 : }
      67             : 
      68             : // -----------------------------------------------------------------------
      69             : 
      70         532 : ComboBox::ComboBox( Window* pParent, const ResId& rResId ) :
      71         532 :     Edit( WINDOW_COMBOBOX )
      72             : {
      73         532 :     ImplInitComboBoxData();
      74         532 :     rResId.SetRT( RSC_COMBOBOX );
      75         532 :     WinBits nStyle = ImplInitRes( rResId );
      76         532 :     ImplInit( pParent, nStyle );
      77         532 :     ImplLoadRes( rResId );
      78             : 
      79         532 :     SetWidthInChars(-1);
      80         532 :     if ( !(nStyle & WB_HIDE ) )
      81           0 :         Show();
      82         532 : }
      83             : 
      84             : // -----------------------------------------------------------------------
      85             : 
      86        3660 : ComboBox::~ComboBox()
      87             : {
      88        1819 :     SetSubEdit( NULL );
      89        1819 :     delete mpSubEdit;
      90             : 
      91        1819 :     ImplListBox *pImplLB = mpImplLB;
      92        1819 :     mpImplLB = NULL;
      93        1819 :     delete pImplLB;
      94             : 
      95        1819 :     delete mpFloatWin;
      96        1819 :     delete mpBtn;
      97        1841 : }
      98             : 
      99             : // -----------------------------------------------------------------------
     100             : 
     101        1821 : void ComboBox::ImplInitComboBoxData()
     102             : {
     103        1821 :     mpSubEdit           = NULL;
     104        1821 :     mpBtn               = NULL;
     105        1821 :     mpImplLB            = NULL;
     106        1821 :     mpFloatWin          = NULL;
     107             : 
     108        1821 :     mnDDHeight          = 0;
     109        1821 :     mbDDAutoSize        = sal_True;
     110        1821 :     mbSyntheticModify   = sal_False;
     111        1821 :     mbMatchCase         = sal_False;
     112        1821 :     mcMultiSep          = ';';
     113        1821 :     m_nMaxWidthChars    = -1;
     114        1821 : }
     115             : 
     116             : // -----------------------------------------------------------------------
     117             : 
     118        1984 : void ComboBox::ImplCalcEditHeight()
     119             : {
     120             :     sal_Int32 nLeft, nTop, nRight, nBottom;
     121        1984 :     GetBorder( nLeft, nTop, nRight, nBottom );
     122        1984 :     mnDDHeight = (sal_uInt16)(mpSubEdit->GetTextHeight() + nTop + nBottom + 4);
     123        1984 :     if ( !IsDropDownBox() )
     124          56 :         mnDDHeight += 4;
     125             : 
     126        1984 :     Rectangle aCtrlRegion( Point( 0, 0 ), Size( 10, 10 ) );
     127        1984 :     Rectangle aBoundRegion, aContentRegion;
     128        1984 :     ImplControlValue aControlValue;
     129        1984 :     ControlType aType = IsDropDownBox() ? CTRL_COMBOBOX : CTRL_EDITBOX;
     130        3968 :     if( GetNativeControlRegion( aType, PART_ENTIRE_CONTROL,
     131             :                                 aCtrlRegion,
     132             :                                 CTRL_STATE_ENABLED,
     133             :                                 aControlValue, OUString(),
     134        3968 :                                 aBoundRegion, aContentRegion ) )
     135             :     {
     136           0 :         const long nNCHeight = aBoundRegion.GetHeight();
     137           0 :         if( mnDDHeight < nNCHeight )
     138           0 :             mnDDHeight = sal::static_int_cast<sal_uInt16>( nNCHeight );
     139        1984 :     }
     140        1984 : }
     141             : 
     142             : // -----------------------------------------------------------------------
     143             : 
     144        1821 : void ComboBox::ImplInit( Window* pParent, WinBits nStyle )
     145             : {
     146        1821 :     ImplInitStyle( nStyle );
     147             : 
     148        1821 :     bool bNoBorder = ( nStyle & WB_NOBORDER ) ? true : false;
     149        1821 :     if ( !(nStyle & WB_DROPDOWN) )
     150             :     {
     151          14 :         nStyle &= ~WB_BORDER;
     152          14 :         nStyle |= WB_NOBORDER;
     153             :     }
     154             :     else
     155             :     {
     156        1807 :         if ( !bNoBorder )
     157        1807 :             nStyle |= WB_BORDER;
     158             :     }
     159             : 
     160        1821 :     Edit::ImplInit( pParent, nStyle );
     161        1821 :     SetBackground();
     162             : 
     163             :     // DropDown ?
     164        1821 :     WinBits nEditStyle = nStyle & ( WB_LEFT | WB_RIGHT | WB_CENTER );
     165        1821 :     WinBits nListStyle = nStyle;
     166        1821 :     if( nStyle & WB_DROPDOWN )
     167             :     {
     168        1807 :         mpFloatWin = new ImplListBoxFloatingWindow( this );
     169        1807 :         mpFloatWin->SetAutoWidth( sal_True );
     170        1807 :         mpFloatWin->SetPopupModeEndHdl( LINK( this, ComboBox, ImplPopupModeEndHdl ) );
     171             : 
     172        1807 :         mpBtn = new ImplBtn( this, WB_NOLIGHTBORDER | WB_RECTSTYLE );
     173        1807 :         ImplInitDropDownButton( mpBtn );
     174        1807 :         mpBtn->SetMBDownHdl( LINK( this, ComboBox, ImplClickBtnHdl ) );
     175        1807 :         mpBtn->Show();
     176             : 
     177        1807 :         nEditStyle |= WB_NOBORDER;
     178        1807 :         nListStyle &= ~WB_BORDER;
     179        1807 :         nListStyle |= WB_NOBORDER;
     180             :     }
     181             :     else
     182             :     {
     183          14 :         if ( !bNoBorder )
     184             :         {
     185          14 :             nEditStyle |= WB_BORDER;
     186          14 :             nListStyle &= ~WB_NOBORDER;
     187          14 :             nListStyle |= WB_BORDER;
     188             :         }
     189             :     }
     190             : 
     191        1821 :     mpSubEdit = new Edit( this, nEditStyle );
     192        1821 :     mpSubEdit->EnableRTL( sal_False );
     193        1821 :     SetSubEdit( mpSubEdit );
     194        1821 :     mpSubEdit->SetPosPixel( Point() );
     195        1821 :     EnableAutocomplete( sal_True );
     196        1821 :     mpSubEdit->Show();
     197             : 
     198        1821 :     Window* pLBParent = this;
     199        1821 :     if ( mpFloatWin )
     200        1807 :         pLBParent = mpFloatWin;
     201        1821 :     mpImplLB = new ImplListBox( pLBParent, nListStyle|WB_SIMPLEMODE|WB_AUTOHSCROLL );
     202        1821 :     mpImplLB->SetPosPixel( Point() );
     203        1821 :     mpImplLB->SetSelectHdl( LINK( this, ComboBox, ImplSelectHdl ) );
     204        1821 :     mpImplLB->SetCancelHdl( LINK( this, ComboBox, ImplCancelHdl ) );
     205        1821 :     mpImplLB->SetDoubleClickHdl( LINK( this, ComboBox, ImplDoubleClickHdl ) );
     206        1821 :     mpImplLB->SetUserDrawHdl( LINK( this, ComboBox, ImplUserDrawHdl ) );
     207        1821 :     mpImplLB->SetSelectionChangedHdl( LINK( this, ComboBox, ImplSelectionChangedHdl ) );
     208        1821 :     mpImplLB->Show();
     209             : 
     210        1821 :     if ( mpFloatWin )
     211        1807 :         mpFloatWin->SetImplListBox( mpImplLB );
     212             :     else
     213          14 :         mpImplLB->GetMainWindow()->AllowGrabFocus( sal_True );
     214             : 
     215        1821 :     ImplCalcEditHeight();
     216             : 
     217        1821 :     SetCompoundControl( sal_True );
     218        1821 : }
     219             : 
     220             : // -----------------------------------------------------------------------
     221             : 
     222       11607 : WinBits ComboBox::ImplInitStyle( WinBits nStyle )
     223             : {
     224       11607 :     if ( !(nStyle & WB_NOTABSTOP) )
     225       11607 :         nStyle |= WB_TABSTOP;
     226       11607 :     if ( !(nStyle & WB_NOGROUP) )
     227       11607 :         nStyle |= WB_GROUP;
     228       11607 :     return nStyle;
     229             : }
     230             : 
     231             : // -----------------------------------------------------------------------
     232             : 
     233         532 : void ComboBox::ImplLoadRes( const ResId& rResId )
     234             : {
     235         532 :     Edit::ImplLoadRes( rResId );
     236             : 
     237         532 :     sal_uLong nNumber = ReadLongRes();
     238             : 
     239         532 :     if( nNumber )
     240             :     {
     241           0 :         for( sal_uInt16 i = 0; i < nNumber; i++ )
     242             :         {
     243           0 :             InsertEntry( ReadStringRes(), LISTBOX_APPEND );
     244             :         }
     245             :     }
     246         532 : }
     247             : 
     248             : // -----------------------------------------------------------------------
     249             : 
     250        2885 : void ComboBox::EnableAutocomplete( sal_Bool bEnable, sal_Bool bMatchCase )
     251             : {
     252        2885 :     mbMatchCase = bMatchCase;
     253             : 
     254        2885 :     if ( bEnable )
     255        2353 :         mpSubEdit->SetAutocompleteHdl( LINK( this, ComboBox, ImplAutocompleteHdl ) );
     256             :     else
     257         532 :         mpSubEdit->SetAutocompleteHdl( Link() );
     258        2885 : }
     259             : 
     260             : // -----------------------------------------------------------------------
     261             : 
     262           0 : sal_Bool ComboBox::IsAutocompleteEnabled() const
     263             : {
     264           0 :     return mpSubEdit->GetAutocompleteHdl().IsSet();
     265             : }
     266             : 
     267             : // -----------------------------------------------------------------------
     268             : 
     269           0 : IMPL_LINK_NOARG(ComboBox, ImplClickBtnHdl)
     270             : {
     271           0 :     ImplCallEventListeners( VCLEVENT_DROPDOWN_PRE_OPEN );
     272           0 :     mpSubEdit->GrabFocus();
     273           0 :     if ( !mpImplLB->GetEntryList()->GetMRUCount() )
     274           0 :         ImplUpdateFloatSelection();
     275             :     else
     276           0 :         mpImplLB->SelectEntry( 0 , sal_True );
     277           0 :     mpBtn->SetPressed( sal_True );
     278           0 :     SetSelection( Selection( 0, SELECTION_MAX ) );
     279           0 :     mpFloatWin->StartFloat( sal_True );
     280           0 :     ImplCallEventListeners( VCLEVENT_DROPDOWN_OPEN );
     281             : 
     282           0 :     ImplClearLayoutData();
     283           0 :     if( mpImplLB )
     284           0 :         mpImplLB->GetMainWindow()->ImplClearLayoutData();
     285             : 
     286           0 :     return 0;
     287             : }
     288             : 
     289             : // -----------------------------------------------------------------------
     290             : 
     291           2 : IMPL_LINK_NOARG(ComboBox, ImplPopupModeEndHdl)
     292             : {
     293           1 :     if( mpFloatWin->IsPopupModeCanceled() )
     294             :     {
     295           0 :         if ( !mpImplLB->GetEntryList()->IsEntryPosSelected( mpFloatWin->GetPopupModeStartSaveSelection() ) )
     296             :         {
     297           0 :             mpImplLB->SelectEntry( mpFloatWin->GetPopupModeStartSaveSelection(), sal_True );
     298           0 :             sal_Bool bTravelSelect = mpImplLB->IsTravelSelect();
     299           0 :             mpImplLB->SetTravelSelect( sal_True );
     300           0 :             Select();
     301           0 :             mpImplLB->SetTravelSelect( bTravelSelect );
     302             :         }
     303             :     }
     304             : 
     305           1 :     ImplClearLayoutData();
     306           1 :     if( mpImplLB )
     307           1 :         mpImplLB->GetMainWindow()->ImplClearLayoutData();
     308             : 
     309           1 :     mpBtn->SetPressed( sal_False );
     310           1 :     ImplCallEventListeners( VCLEVENT_DROPDOWN_CLOSE );
     311           1 :     return 0;
     312             : }
     313             : 
     314             : // -----------------------------------------------------------------------
     315             : 
     316           0 : IMPL_LINK( ComboBox, ImplAutocompleteHdl, Edit*, pEdit )
     317             : {
     318           0 :     Selection           aSel = pEdit->GetSelection();
     319           0 :     AutocompleteAction  eAction = pEdit->GetAutocompleteAction();
     320             : 
     321             :     /* If there is no current selection do not auto complete on
     322             :        Tab/Shift-Tab since then we would not cycle to the next field.
     323             :     */
     324           0 :     if ( aSel.Len() ||
     325           0 :          ((eAction != AUTOCOMPLETE_TABFORWARD) && (eAction != AUTOCOMPLETE_TABBACKWARD)) )
     326             :     {
     327           0 :         OUString    aFullText = pEdit->GetText();
     328           0 :         OUString    aStartText = aFullText.copy( 0, (sal_Int32)aSel.Max() );
     329           0 :         sal_uInt16      nStart = mpImplLB->GetCurrentPos();
     330             : 
     331           0 :         if ( nStart == LISTBOX_ENTRY_NOTFOUND )
     332           0 :             nStart = 0;
     333             : 
     334           0 :         sal_Bool bForward = sal_True;
     335           0 :         if ( eAction == AUTOCOMPLETE_TABFORWARD )
     336           0 :             nStart++;
     337           0 :         else if ( eAction == AUTOCOMPLETE_TABBACKWARD )
     338             :         {
     339           0 :             bForward = sal_False;
     340           0 :             nStart = nStart ? nStart - 1 : mpImplLB->GetEntryList()->GetEntryCount()-1;
     341             :         }
     342             : 
     343           0 :         sal_uInt16 nPos = LISTBOX_ENTRY_NOTFOUND;
     344           0 :         if( ! mbMatchCase )
     345             :         {
     346             :             // Try match case insensitive from current position
     347           0 :             nPos = mpImplLB->GetEntryList()->FindMatchingEntry( aStartText, nStart, bForward, sal_True );
     348           0 :             if ( nPos == LISTBOX_ENTRY_NOTFOUND )
     349             :                 // Try match case insensitive, but from start
     350           0 :                 nPos = mpImplLB->GetEntryList()->FindMatchingEntry( aStartText, bForward ? 0 : (mpImplLB->GetEntryList()->GetEntryCount()-1), bForward, sal_True );
     351             :         }
     352             : 
     353           0 :         if ( nPos == LISTBOX_ENTRY_NOTFOUND )
     354             :             // Try match full from current position
     355           0 :             nPos = mpImplLB->GetEntryList()->FindMatchingEntry( aStartText, nStart, bForward, sal_False );
     356           0 :         if ( nPos == LISTBOX_ENTRY_NOTFOUND )
     357             :             //  Match full, but from start
     358           0 :             nPos = mpImplLB->GetEntryList()->FindMatchingEntry( aStartText, bForward ? 0 : (mpImplLB->GetEntryList()->GetEntryCount()-1), bForward, sal_False );
     359             : 
     360           0 :         if ( nPos != LISTBOX_ENTRY_NOTFOUND )
     361             :         {
     362           0 :             OUString aText = mpImplLB->GetEntryList()->GetEntryText( nPos );
     363           0 :             Selection aSelection( aText.getLength(), aStartText.getLength() );
     364           0 :             pEdit->SetText( aText, aSelection );
     365           0 :         }
     366             :     }
     367             : 
     368           0 :     return 0;
     369             : }
     370             : 
     371             : // -----------------------------------------------------------------------
     372             : 
     373           0 : IMPL_LINK_NOARG(ComboBox, ImplSelectHdl)
     374             : {
     375           0 :     sal_Bool bPopup = IsInDropDown();
     376           0 :     bool bCallSelect = false;
     377           0 :     if ( mpImplLB->IsSelectionChanged() || bPopup )
     378             :     {
     379           0 :         OUString aText;
     380           0 :         if ( IsMultiSelectionEnabled() )
     381             :         {
     382           0 :             aText = mpSubEdit->GetText();
     383             : 
     384             :             // remove all entries to which there is an entry, but which is not selected
     385           0 :             sal_Int32 nIndex = 0;
     386           0 :             while ( nIndex >= 0 )
     387             :             {
     388           0 :                 sal_Int32  nPrevIndex = nIndex;
     389           0 :                 OUString   aToken = aText.getToken( 0, mcMultiSep, nIndex );
     390           0 :                 sal_Int32  nTokenLen = aToken.getLength();
     391           0 :                 aToken = comphelper::string::strip(aToken, ' ');
     392           0 :                 sal_uInt16      nP = mpImplLB->GetEntryList()->FindEntry( aToken );
     393           0 :                 if ( (nP != LISTBOX_ENTRY_NOTFOUND) && (!mpImplLB->GetEntryList()->IsEntryPosSelected( nP )) )
     394             :                 {
     395           0 :                     aText = aText.replaceAt( nPrevIndex, nTokenLen, "" );
     396           0 :                     nIndex = sal::static_int_cast<xub_StrLen>(nIndex - nTokenLen);
     397           0 :                     sal_Int32 nSepCount=0;
     398           0 :                     if ( (nPrevIndex+nSepCount < aText.getLength()) && (aText[nPrevIndex+nSepCount] == mcMultiSep) )
     399             :                     {
     400           0 :                         nIndex--;
     401           0 :                         ++nSepCount;
     402             :                     }
     403           0 :                     aText = aText.replaceAt( nPrevIndex, nSepCount, "" );
     404             :                 }
     405           0 :                 aText = comphelper::string::strip(aText, ' ');
     406           0 :             }
     407             : 
     408             :             // attach missing entries
     409           0 :             ::std::set< sal_uInt16 > aSelInText;
     410           0 :             lcl_GetSelectedEntries( aSelInText, aText, mcMultiSep, mpImplLB->GetEntryList() );
     411           0 :             sal_uInt16 nSelectedEntries = mpImplLB->GetEntryList()->GetSelectEntryCount();
     412           0 :             for ( sal_uInt16 n = 0; n < nSelectedEntries; n++ )
     413             :             {
     414           0 :                 sal_uInt16 nP = mpImplLB->GetEntryList()->GetSelectEntryPos( n );
     415           0 :                 if ( !aSelInText.count( nP ) )
     416             :                 {
     417           0 :                     if ( !aText.isEmpty() && (aText[ aText.getLength()-1 ] != mcMultiSep) )
     418           0 :                         aText += OUString(mcMultiSep);
     419           0 :                     if ( !aText.isEmpty() )
     420           0 :                         aText += " ";   // slightly loosen
     421           0 :                     aText += mpImplLB->GetEntryList()->GetEntryText( nP );
     422           0 :                     aText += OUString(mcMultiSep);
     423             :                 }
     424             :             }
     425           0 :             aText = comphelper::string::stripEnd( aText, mcMultiSep );
     426             :         }
     427             :         else
     428             :         {
     429           0 :             aText = mpImplLB->GetEntryList()->GetSelectEntry( 0 );
     430             :         }
     431             : 
     432           0 :         mpSubEdit->SetText( aText );
     433             : 
     434           0 :         Selection aNewSelection( 0, aText.getLength() );
     435           0 :         if ( IsMultiSelectionEnabled() )
     436           0 :             aNewSelection.Min() = aText.getLength();
     437           0 :         mpSubEdit->SetSelection( aNewSelection );
     438             : 
     439           0 :         bCallSelect = true;
     440             :     }
     441             : 
     442             :     // #84652# Call GrabFocus and EndPopupMode before calling Select/Modify, but after changing the text
     443             : 
     444           0 :     if ( bPopup && !mpImplLB->IsTravelSelect() &&
     445           0 :         ( !IsMultiSelectionEnabled() || !mpImplLB->GetSelectModifier() ) )
     446             :     {
     447           0 :         mpFloatWin->EndPopupMode();
     448           0 :         GrabFocus();
     449             :     }
     450             : 
     451           0 :     if ( bCallSelect )
     452             :     {
     453           0 :         mpSubEdit->SetModifyFlag();
     454           0 :         mbSyntheticModify = sal_True;
     455           0 :         Modify();
     456           0 :         mbSyntheticModify = sal_False;
     457           0 :         Select();
     458             :     }
     459             : 
     460           0 :     return 0;
     461             : }
     462             : 
     463             : // -----------------------------------------------------------------------
     464             : 
     465           0 : IMPL_LINK_NOARG(ComboBox, ImplCancelHdl)
     466             : {
     467           0 :     if( IsInDropDown() )
     468           0 :         mpFloatWin->EndPopupMode();
     469             : 
     470           0 :     return 1;
     471             : }
     472             : 
     473             : // -----------------------------------------------------------------------
     474             : 
     475           0 : IMPL_LINK( ComboBox, ImplSelectionChangedHdl, void*, n )
     476             : {
     477           0 :     if ( !mpImplLB->IsTrackingSelect() )
     478             :     {
     479           0 :         sal_uInt16 nChanged = (sal_uInt16)(sal_uLong)n;
     480           0 :         if ( !mpSubEdit->IsReadOnly() && mpImplLB->GetEntryList()->IsEntryPosSelected( nChanged ) )
     481           0 :             mpSubEdit->SetText( mpImplLB->GetEntryList()->GetEntryText( nChanged ) );
     482             :     }
     483           0 :     return 1;
     484             : }
     485             : 
     486             : // -----------------------------------------------------------------------
     487             : 
     488           0 : IMPL_LINK_NOARG(ComboBox, ImplDoubleClickHdl)
     489             : {
     490           0 :     DoubleClick();
     491           0 :     return 0;
     492             : }
     493             : 
     494             : // -----------------------------------------------------------------------
     495             : 
     496           3 : void ComboBox::ToggleDropDown()
     497             : {
     498           3 :     if( IsDropDownBox() )
     499             :     {
     500           3 :         if( mpFloatWin->IsInPopupMode() )
     501           1 :             mpFloatWin->EndPopupMode();
     502             :         else
     503             :         {
     504           2 :             mpSubEdit->GrabFocus();
     505           2 :             if ( !mpImplLB->GetEntryList()->GetMRUCount() )
     506           2 :                 ImplUpdateFloatSelection();
     507             :             else
     508           0 :                 mpImplLB->SelectEntry( 0 , sal_True );
     509           2 :             ImplCallEventListeners( VCLEVENT_DROPDOWN_PRE_OPEN );
     510           2 :             mpBtn->SetPressed( sal_True );
     511           2 :             SetSelection( Selection( 0, SELECTION_MAX ) );
     512           2 :             mpFloatWin->StartFloat( sal_True );
     513           2 :             ImplCallEventListeners( VCLEVENT_DROPDOWN_OPEN );
     514             :         }
     515             :     }
     516           3 : }
     517             : 
     518             : // -----------------------------------------------------------------------
     519             : 
     520           0 : void ComboBox::Select()
     521             : {
     522           0 :     ImplCallEventListenersAndHandler( VCLEVENT_COMBOBOX_SELECT, maSelectHdl, this );
     523           0 : }
     524             : 
     525             : // -----------------------------------------------------------------------
     526             : 
     527           0 : void ComboBox::DoubleClick()
     528             : {
     529           0 :     ImplCallEventListenersAndHandler( VCLEVENT_COMBOBOX_DOUBLECLICK, maDoubleClickHdl, this );
     530           0 : }
     531             : 
     532             : // -----------------------------------------------------------------------
     533             : 
     534          22 : void ComboBox::EnableAutoSize( bool bAuto )
     535             : {
     536          22 :     mbDDAutoSize = bAuto;
     537          22 :     if ( mpFloatWin )
     538             :     {
     539           8 :         if ( bAuto && !mpFloatWin->GetDropDownLineCount() )
     540             :         {
     541             :             // Adapt to GetListBoxMaximumLineCount here; was on fixed number of five before
     542           0 :             AdaptDropDownLineCountToMaximum();
     543             :         }
     544           8 :         else if ( !bAuto )
     545             :         {
     546           8 :             mpFloatWin->SetDropDownLineCount( 0 );
     547             :         }
     548             :     }
     549          22 : }
     550             : 
     551             : // -----------------------------------------------------------------------
     552             : 
     553           0 : void ComboBox::EnableDDAutoWidth( sal_Bool b )
     554             : {
     555           0 :     if ( mpFloatWin )
     556           0 :         mpFloatWin->SetAutoWidth( b );
     557           0 : }
     558             : 
     559             :  // -----------------------------------------------------------------------
     560             : 
     561        4909 : void ComboBox::SetDropDownLineCount( sal_uInt16 nLines )
     562             : {
     563        4909 :     if ( mpFloatWin )
     564        4892 :         mpFloatWin->SetDropDownLineCount( nLines );
     565        4909 : }
     566             : 
     567             : // -----------------------------------------------------------------------
     568             : 
     569           0 : void ComboBox::AdaptDropDownLineCountToMaximum()
     570             : {
     571             :     // adapt to maximum allowed number
     572           0 :     SetDropDownLineCount(GetSettings().GetStyleSettings().GetListBoxMaximumLineCount());
     573           0 : }
     574             : 
     575             : // -----------------------------------------------------------------------
     576             : 
     577           0 : sal_uInt16 ComboBox::GetDropDownLineCount() const
     578             : {
     579           0 :     sal_uInt16 nLines = 0;
     580           0 :     if ( mpFloatWin )
     581           0 :         nLines = mpFloatWin->GetDropDownLineCount();
     582           0 :     return nLines;
     583             : }
     584             : 
     585             : // -----------------------------------------------------------------------
     586             : 
     587        5176 : void ComboBox::setPosSizePixel( long nX, long nY, long nWidth, long nHeight,
     588             :                                 sal_uInt16 nFlags )
     589             : {
     590        5176 :     if( IsDropDownBox() && ( nFlags & WINDOW_POSSIZE_SIZE ) )
     591             :     {
     592        1815 :         Size aPrefSz = mpFloatWin->GetPrefSize();
     593        1815 :         if ( ( nFlags & WINDOW_POSSIZE_HEIGHT ) && ( nHeight >= 2*mnDDHeight ) )
     594        1810 :             aPrefSz.Height() = nHeight-mnDDHeight;
     595        1815 :         if ( nFlags & WINDOW_POSSIZE_WIDTH )
     596        1815 :             aPrefSz.Width() = nWidth;
     597        1815 :         mpFloatWin->SetPrefSize( aPrefSz );
     598             : 
     599        1815 :         if ( IsAutoSizeEnabled() && ! (nFlags & WINDOW_POSSIZE_DROPDOWN) )
     600        1799 :             nHeight = mnDDHeight;
     601             :     }
     602             : 
     603        5176 :     Edit::setPosSizePixel( nX, nY, nWidth, nHeight, nFlags );
     604        5176 : }
     605             : 
     606             : // -----------------------------------------------------------------------
     607             : 
     608        2045 : void ComboBox::Resize()
     609             : {
     610        2045 :     Control::Resize();
     611             : 
     612        2045 :     Size aOutSz = GetOutputSizePixel();
     613        2045 :     if( IsDropDownBox() )
     614             :     {
     615             :         ComboBoxBounds aBounds(calcComboBoxDropDownComponentBounds(aOutSz,
     616        1891 :             GetWindow(WINDOW_BORDER)->GetOutputSizePixel()));
     617        1891 :         mpSubEdit->SetPosSizePixel(aBounds.aSubEditPos, aBounds.aSubEditSize);
     618        1891 :         mpBtn->SetPosSizePixel(aBounds.aButtonPos, aBounds.aButtonSize);
     619             :     }
     620             :     else
     621             :     {
     622         154 :         mpSubEdit->SetSizePixel( Size( aOutSz.Width(), mnDDHeight ) );
     623         154 :         mpImplLB->setPosSizePixel( 0, mnDDHeight, aOutSz.Width(), aOutSz.Height() - mnDDHeight );
     624         154 :         if ( !GetText().isEmpty() )
     625           0 :             ImplUpdateFloatSelection();
     626             :     }
     627             : 
     628             :     // adjust the size of the FloatingWindow even when invisible
     629             :     // as KEY_PGUP/DOWN is being processed...
     630        2045 :     if ( mpFloatWin )
     631        1891 :         mpFloatWin->SetSizePixel( mpFloatWin->CalcFloatSize() );
     632        2045 : }
     633             : 
     634             : // -----------------------------------------------------------------------
     635             : 
     636           0 : void ComboBox::FillLayoutData() const
     637             : {
     638           0 :     mpControlData->mpLayoutData = new vcl::ControlLayoutData();
     639           0 :     AppendLayoutData( *mpSubEdit );
     640           0 :     mpSubEdit->SetLayoutDataParent( this );
     641           0 :     Control* pMainWindow = mpImplLB->GetMainWindow();
     642           0 :     if( mpFloatWin )
     643             :     {
     644             :         // dropdown mode
     645           0 :         if( mpFloatWin->IsReallyVisible() )
     646             :         {
     647           0 :             AppendLayoutData( *pMainWindow );
     648           0 :             pMainWindow->SetLayoutDataParent( this );
     649             :         }
     650             :     }
     651             :     else
     652             :     {
     653           0 :         AppendLayoutData( *pMainWindow );
     654           0 :         pMainWindow->SetLayoutDataParent( this );
     655             :     }
     656           0 : }
     657             : 
     658             : // -----------------------------------------------------------------------
     659             : 
     660       27716 : void ComboBox::StateChanged( StateChangedType nType )
     661             : {
     662       27716 :     Edit::StateChanged( nType );
     663             : 
     664       27716 :     if ( nType == STATE_CHANGE_READONLY )
     665             :     {
     666          18 :         mpImplLB->SetReadOnly( IsReadOnly() );
     667          18 :         if ( mpBtn )
     668           6 :             mpBtn->Enable( IsEnabled() && !IsReadOnly() );
     669             :     }
     670       27698 :     else if ( nType == STATE_CHANGE_ENABLE )
     671             :     {
     672          71 :         mpSubEdit->Enable( IsEnabled() );
     673          71 :         mpImplLB->Enable( IsEnabled() && !IsReadOnly() );
     674          71 :         if ( mpBtn )
     675          65 :             mpBtn->Enable( IsEnabled() && !IsReadOnly() );
     676          71 :         Invalidate();
     677             :     }
     678       27627 :     else if( nType == STATE_CHANGE_UPDATEMODE )
     679             :     {
     680       14018 :         mpImplLB->SetUpdateMode( IsUpdateMode() );
     681             :     }
     682       13609 :     else if ( nType == STATE_CHANGE_ZOOM )
     683             :     {
     684           1 :         mpImplLB->SetZoom( GetZoom() );
     685           1 :         mpSubEdit->SetZoom( GetZoom() );
     686           1 :         ImplCalcEditHeight();
     687           1 :         Resize();
     688             :     }
     689       13608 :     else if ( nType == STATE_CHANGE_CONTROLFONT )
     690             :     {
     691         162 :         mpImplLB->SetControlFont( GetControlFont() );
     692         162 :         mpSubEdit->SetControlFont( GetControlFont() );
     693         162 :         ImplCalcEditHeight();
     694         162 :         Resize();
     695             :     }
     696       13446 :     else if ( nType == STATE_CHANGE_CONTROLFOREGROUND )
     697             :     {
     698           2 :         mpImplLB->SetControlForeground( GetControlForeground() );
     699           2 :         mpSubEdit->SetControlForeground( GetControlForeground() );
     700             :     }
     701       13444 :     else if ( nType == STATE_CHANGE_CONTROLBACKGROUND )
     702             :     {
     703           2 :         mpImplLB->SetControlBackground( GetControlBackground() );
     704           2 :         mpSubEdit->SetControlBackground( GetControlBackground() );
     705             :     }
     706       13442 :     else if ( nType == STATE_CHANGE_STYLE )
     707             :     {
     708        9786 :         SetStyle( ImplInitStyle( GetStyle() ) );
     709        9786 :         mpImplLB->GetMainWindow()->EnableSort( ( GetStyle() & WB_SORT ) ? sal_True : sal_False );
     710             :     }
     711        3656 :     else if( nType == STATE_CHANGE_MIRRORING )
     712             :     {
     713          52 :         if( mpBtn )
     714             :         {
     715          20 :             mpBtn->EnableRTL( IsRTLEnabled() );
     716          20 :             ImplInitDropDownButton( mpBtn );
     717             :         }
     718          52 :         mpSubEdit->StateChanged( STATE_CHANGE_MIRRORING );
     719          52 :         mpImplLB->EnableRTL( IsRTLEnabled() );
     720          52 :         Resize();
     721             :     }
     722       27716 : }
     723             : 
     724             : // -----------------------------------------------------------------------
     725             : 
     726         186 : void ComboBox::DataChanged( const DataChangedEvent& rDCEvt )
     727             : {
     728         186 :     Control::DataChanged( rDCEvt );
     729             : 
     730         558 :     if ( (rDCEvt.GetType() == DATACHANGED_FONTS) ||
     731         537 :          (rDCEvt.GetType() == DATACHANGED_FONTSUBSTITUTION) ||
     732         372 :          ((rDCEvt.GetType() == DATACHANGED_SETTINGS) &&
     733         186 :           (rDCEvt.GetFlags() & SETTINGS_STYLE)) )
     734             :     {
     735         165 :         if ( mpBtn )
     736             :         {
     737          98 :             mpBtn->SetSettings( GetSettings() );
     738          98 :             ImplInitDropDownButton( mpBtn );
     739             :         }
     740         165 :         Resize();
     741         165 :         mpImplLB->Resize(); // not called by ComboBox::Resize() if ImplLB is unchanged
     742             : 
     743         165 :         SetBackground();    // due to a hack in Window::UpdateSettings the background must be reset
     744             :                             // otherwise it will overpaint NWF drawn comboboxes
     745             :     }
     746         186 : }
     747             : 
     748             : // -----------------------------------------------------------------------
     749             : 
     750           3 : long ComboBox::PreNotify( NotifyEvent& rNEvt )
     751             : {
     752             : 
     753           3 :     return Edit::PreNotify( rNEvt );
     754             : }
     755             : 
     756             : // -----------------------------------------------------------------------
     757             : 
     758        3960 : long ComboBox::Notify( NotifyEvent& rNEvt )
     759             : {
     760        3960 :     long nDone = 0;
     761        7920 :     if( ( rNEvt.GetType() == EVENT_KEYINPUT ) && ( rNEvt.GetWindow() == mpSubEdit )
     762        3960 :             && !IsReadOnly() )
     763             :     {
     764           0 :         KeyEvent aKeyEvt = *rNEvt.GetKeyEvent();
     765           0 :         sal_uInt16   nKeyCode = aKeyEvt.GetKeyCode().GetCode();
     766           0 :         switch( nKeyCode )
     767             :         {
     768             :             case KEY_UP:
     769             :             case KEY_DOWN:
     770             :             case KEY_PAGEUP:
     771             :             case KEY_PAGEDOWN:
     772             :             {
     773           0 :                 ImplUpdateFloatSelection();
     774           0 :                 if( ( nKeyCode == KEY_DOWN ) && mpFloatWin && !mpFloatWin->IsInPopupMode() && aKeyEvt.GetKeyCode().IsMod2() )
     775             :                 {
     776           0 :                     ImplCallEventListeners( VCLEVENT_DROPDOWN_PRE_OPEN );
     777           0 :                     mpBtn->SetPressed( sal_True );
     778           0 :                     if ( mpImplLB->GetEntryList()->GetMRUCount() )
     779           0 :                         mpImplLB->SelectEntry( 0 , sal_True );
     780           0 :                     SetSelection( Selection( 0, SELECTION_MAX ) );
     781           0 :                     mpFloatWin->StartFloat( sal_False );
     782           0 :                     ImplCallEventListeners( VCLEVENT_DROPDOWN_OPEN );
     783           0 :                     nDone = 1;
     784             :                 }
     785           0 :                 else if( ( nKeyCode == KEY_UP ) && mpFloatWin && mpFloatWin->IsInPopupMode() && aKeyEvt.GetKeyCode().IsMod2() )
     786             :                 {
     787           0 :                     mpFloatWin->EndPopupMode();
     788           0 :                     nDone = 1;
     789             :                 }
     790             :                 else
     791             :                 {
     792           0 :                     nDone = mpImplLB->ProcessKeyInput( aKeyEvt );
     793             :                 }
     794             :             }
     795           0 :             break;
     796             : 
     797             :             case KEY_RETURN:
     798             :             {
     799           0 :                 if( ( rNEvt.GetWindow() == mpSubEdit ) && IsInDropDown() )
     800             :                 {
     801           0 :                     mpImplLB->ProcessKeyInput( aKeyEvt );
     802           0 :                     nDone = 1;
     803             :                 }
     804             :             }
     805           0 :             break;
     806             :         }
     807             :     }
     808        3960 :     else if ( (rNEvt.GetType() == EVENT_LOSEFOCUS) && mpFloatWin )
     809             :     {
     810           1 :         if( mpFloatWin->HasChildPathFocus() )
     811           0 :             mpSubEdit->GrabFocus();
     812           1 :         else if ( mpFloatWin->IsInPopupMode() && !HasChildPathFocus( sal_True ) )
     813           0 :             mpFloatWin->EndPopupMode();
     814             :     }
     815        7918 :     else if( (rNEvt.GetType() == EVENT_COMMAND) &&
     816        3959 :              (rNEvt.GetCommandEvent()->GetCommand() == COMMAND_WHEEL) &&
     817           0 :              (rNEvt.GetWindow() == mpSubEdit) )
     818             :     {
     819           0 :         sal_uInt16 nWheelBehavior( GetSettings().GetMouseSettings().GetWheelBehavior() );
     820           0 :         if  (   ( nWheelBehavior == MOUSE_WHEEL_ALWAYS )
     821           0 :             ||  (   ( nWheelBehavior == MOUSE_WHEEL_FOCUS_ONLY )
     822           0 :                 &&  HasChildPathFocus()
     823             :                 )
     824             :             )
     825             :         {
     826           0 :             nDone = mpImplLB->HandleWheelAsCursorTravel( *rNEvt.GetCommandEvent() );
     827             :         }
     828             :         else
     829             :         {
     830           0 :             nDone = 0;  // don't eat this event, let the default handling happen (i.e. scroll the context)
     831             :         }
     832             :     }
     833        3959 :     else if( ( rNEvt.GetType() == EVENT_MOUSEBUTTONDOWN ) && ( rNEvt.GetWindow() == mpImplLB->GetMainWindow() ) )
     834             :     {
     835           0 :         mpSubEdit->GrabFocus();
     836             :     }
     837             : 
     838        3960 :     return nDone ? nDone : Edit::Notify( rNEvt );
     839             : }
     840             : 
     841             : // -----------------------------------------------------------------------
     842             : 
     843        3540 : void ComboBox::SetText( const OUString& rStr )
     844             : {
     845        3540 :     ImplCallEventListeners( VCLEVENT_COMBOBOX_SETTEXT );
     846             : 
     847        3540 :     Edit::SetText( rStr );
     848        3540 :     ImplUpdateFloatSelection();
     849        3540 : }
     850             : 
     851             : // -----------------------------------------------------------------------
     852             : 
     853        4489 : void ComboBox::SetText( const OUString& rStr, const Selection& rNewSelection )
     854             : {
     855        4489 :     ImplCallEventListeners( VCLEVENT_COMBOBOX_SETTEXT );
     856             : 
     857        4489 :     Edit::SetText( rStr, rNewSelection );
     858        4489 :     ImplUpdateFloatSelection();
     859        4489 : }
     860             : 
     861             : // -----------------------------------------------------------------------
     862             : 
     863          55 : void ComboBox::Modify()
     864             : {
     865          55 :     if ( !mbSyntheticModify )
     866          55 :         ImplUpdateFloatSelection();
     867             : 
     868          55 :     Edit::Modify();
     869          55 : }
     870             : 
     871             : // -----------------------------------------------------------------------
     872             : 
     873        8086 : void ComboBox::ImplUpdateFloatSelection()
     874             : {
     875             :     // move text in the ListBox into the visible region
     876        8086 :     mpImplLB->SetCallSelectionChangedHdl( sal_False );
     877        8086 :     if ( !IsMultiSelectionEnabled() )
     878             :     {
     879        8086 :         XubString   aSearchStr( mpSubEdit->GetText() );
     880        8086 :         sal_uInt16      nSelect = LISTBOX_ENTRY_NOTFOUND;
     881        8086 :         sal_Bool        bSelect = sal_True;
     882             : 
     883        8086 :         if ( mpImplLB->GetCurrentPos() != LISTBOX_ENTRY_NOTFOUND )
     884             :         {
     885        1302 :             XubString aCurrent = mpImplLB->GetEntryList()->GetEntryText( mpImplLB->GetCurrentPos() );
     886        1302 :             if ( aCurrent == aSearchStr )
     887        1294 :                 nSelect = mpImplLB->GetCurrentPos();
     888             :         }
     889             : 
     890        8086 :         if ( nSelect == LISTBOX_ENTRY_NOTFOUND )
     891        6792 :             nSelect = mpImplLB->GetEntryList()->FindEntry( aSearchStr );
     892        8086 :         if ( nSelect == LISTBOX_ENTRY_NOTFOUND )
     893             :         {
     894        5372 :             nSelect = mpImplLB->GetEntryList()->FindMatchingEntry( aSearchStr );
     895        5372 :             bSelect = sal_False;
     896             :         }
     897             : 
     898        8086 :         if( nSelect != LISTBOX_ENTRY_NOTFOUND )
     899             :         {
     900        2747 :             if ( !mpImplLB->IsVisible( nSelect ) )
     901        1429 :                 mpImplLB->ShowProminentEntry( nSelect );
     902        2747 :             mpImplLB->SelectEntry( nSelect, bSelect );
     903             :         }
     904             :         else
     905             :         {
     906        5339 :             nSelect = mpImplLB->GetEntryList()->GetSelectEntryPos( 0 );
     907        5339 :             if( nSelect != LISTBOX_ENTRY_NOTFOUND )
     908           7 :                 mpImplLB->SelectEntry( nSelect, sal_False );
     909        5339 :             mpImplLB->ResetCurrentPos();
     910        8086 :         }
     911             :     }
     912             :     else
     913             :     {
     914           0 :         ::std::set< sal_uInt16 > aSelInText;
     915           0 :         lcl_GetSelectedEntries( aSelInText, mpSubEdit->GetText(), mcMultiSep, mpImplLB->GetEntryList() );
     916           0 :         for ( sal_uInt16 n = 0; n < mpImplLB->GetEntryList()->GetEntryCount(); n++ )
     917           0 :             mpImplLB->SelectEntry( n, aSelInText.count( n ) );
     918             :     }
     919        8086 :     mpImplLB->SetCallSelectionChangedHdl( sal_True );
     920        8086 : }
     921             : 
     922             : // -----------------------------------------------------------------------
     923             : 
     924      100840 : sal_uInt16 ComboBox::InsertEntry( const OUString& rStr, sal_uInt16 nPos )
     925             : {
     926      100840 :     sal_uInt16 nRealPos = mpImplLB->InsertEntry( nPos + mpImplLB->GetEntryList()->GetMRUCount(), rStr );
     927      100840 :     nRealPos = sal::static_int_cast<sal_uInt16>(nRealPos - mpImplLB->GetEntryList()->GetMRUCount());
     928      100840 :     CallEventListeners( VCLEVENT_COMBOBOX_ITEMADDED, (void*) sal_IntPtr(nRealPos) );
     929      100840 :     return nRealPos;
     930             : }
     931             : 
     932             : // -----------------------------------------------------------------------
     933             : 
     934          57 : sal_uInt16 ComboBox::InsertEntry( const OUString& rStr, const Image& rImage, sal_uInt16 nPos )
     935             : {
     936          57 :     sal_uInt16 nRealPos = mpImplLB->InsertEntry( nPos + mpImplLB->GetEntryList()->GetMRUCount(), rStr, rImage );
     937          57 :     nRealPos = sal::static_int_cast<sal_uInt16>(nRealPos - mpImplLB->GetEntryList()->GetMRUCount());
     938          57 :     CallEventListeners( VCLEVENT_COMBOBOX_ITEMADDED, (void*) sal_IntPtr(nRealPos) );
     939          57 :     return nRealPos;
     940             : }
     941             : 
     942             : // -----------------------------------------------------------------------
     943             : 
     944           0 : void ComboBox::RemoveEntry( const OUString& rStr )
     945             : {
     946           0 :     RemoveEntry( GetEntryPos( rStr ) );
     947           0 : }
     948             : 
     949             : // -----------------------------------------------------------------------
     950             : 
     951           0 : void ComboBox::RemoveEntry( sal_uInt16 nPos )
     952             : {
     953           0 :     mpImplLB->RemoveEntry( nPos + mpImplLB->GetEntryList()->GetMRUCount() );
     954           0 :     CallEventListeners( VCLEVENT_COMBOBOX_ITEMREMOVED, (void*) sal_IntPtr(nPos) );
     955           0 : }
     956             : 
     957             : // -----------------------------------------------------------------------
     958             : 
     959        7152 : void ComboBox::Clear()
     960             : {
     961        7152 :     mpImplLB->Clear();
     962        7152 :     CallEventListeners( VCLEVENT_COMBOBOX_ITEMREMOVED, (void*) sal_IntPtr(-1) );
     963        7152 : }
     964             : // -----------------------------------------------------------------------
     965             : 
     966           0 : Image ComboBox::GetEntryImage( sal_uInt16 nPos ) const
     967             : {
     968           0 :     if ( mpImplLB->GetEntryList()->HasEntryImage( nPos ) )
     969           0 :         return mpImplLB->GetEntryList()->GetEntryImage( nPos );
     970           0 :     return Image();
     971             : }
     972             : 
     973             : // -----------------------------------------------------------------------
     974             : 
     975           0 : sal_uInt16 ComboBox::GetEntryPos( const OUString& rStr ) const
     976             : {
     977           0 :     sal_uInt16 nPos = mpImplLB->GetEntryList()->FindEntry( rStr );
     978           0 :     if ( nPos != LISTBOX_ENTRY_NOTFOUND )
     979           0 :         nPos = sal::static_int_cast<sal_uInt16>(nPos - mpImplLB->GetEntryList()->GetMRUCount());
     980           0 :     return nPos;
     981             : }
     982             : 
     983             : // -----------------------------------------------------------------------
     984             : 
     985        1063 : OUString ComboBox::GetEntry( sal_uInt16 nPos ) const
     986             : {
     987        1063 :     return mpImplLB->GetEntryList()->GetEntryText( nPos + mpImplLB->GetEntryList()->GetMRUCount() );
     988             : }
     989             : 
     990             : // -----------------------------------------------------------------------
     991             : 
     992       12772 : sal_uInt16 ComboBox::GetEntryCount() const
     993             : {
     994       12772 :     return mpImplLB->GetEntryList()->GetEntryCount() - mpImplLB->GetEntryList()->GetMRUCount();
     995             : }
     996             : 
     997             : // -----------------------------------------------------------------------
     998             : 
     999           0 : sal_Bool ComboBox::IsTravelSelect() const
    1000             : {
    1001           0 :     return mpImplLB->IsTravelSelect();
    1002             : }
    1003             : 
    1004             : // -----------------------------------------------------------------------
    1005             : 
    1006          11 : sal_Bool ComboBox::IsInDropDown() const
    1007             : {
    1008          11 :     return mpFloatWin && mpFloatWin->IsInPopupMode();
    1009             : }
    1010             : 
    1011             : // -----------------------------------------------------------------------
    1012             : 
    1013           0 : void ComboBox::EnableMultiSelection( sal_Bool bMulti )
    1014             : {
    1015           0 :     mpImplLB->EnableMultiSelection( bMulti, sal_False );
    1016           0 :     mpImplLB->SetMultiSelectionSimpleMode( sal_True );
    1017           0 : }
    1018             : 
    1019             : // -----------------------------------------------------------------------
    1020             : 
    1021        8095 : sal_Bool ComboBox::IsMultiSelectionEnabled() const
    1022             : {
    1023        8095 :     return mpImplLB->IsMultiSelectionEnabled();
    1024             : }
    1025             : 
    1026             : // -----------------------------------------------------------------------
    1027             : 
    1028         203 : long ComboBox::CalcWindowSizePixel( sal_uInt16 nLines ) const
    1029             : {
    1030         203 :     return mpImplLB->GetEntryHeight() * nLines;
    1031             : }
    1032             : 
    1033             : // -----------------------------------------------------------------------
    1034             : 
    1035           0 : Size ComboBox::GetOptimalSize() const
    1036             : {
    1037           0 :     return CalcMinimumSize();
    1038             : }
    1039             : 
    1040             : // -----------------------------------------------------------------------
    1041             : 
    1042           0 : long ComboBox::getMaxWidthScrollBarAndDownButton() const
    1043             : {
    1044           0 :     long nButtonDownWidth = 0;
    1045             : 
    1046           0 :     Window *pBorder = GetWindow( WINDOW_BORDER );
    1047           0 :     ImplControlValue aControlValue;
    1048           0 :     Point aPoint;
    1049           0 :     Rectangle aContent, aBound;
    1050             : 
    1051             :     // use the full extent of the control
    1052           0 :     Rectangle aArea( aPoint, pBorder->GetOutputSizePixel() );
    1053             : 
    1054           0 :     if ( GetNativeControlRegion(CTRL_COMBOBOX, PART_BUTTON_DOWN,
    1055           0 :         aArea, 0, aControlValue, OUString(), aBound, aContent) )
    1056             :     {
    1057           0 :         nButtonDownWidth = aContent.getWidth();
    1058             :     }
    1059             : 
    1060           0 :     long nScrollBarWidth = GetSettings().GetStyleSettings().GetScrollBarSize();
    1061             : 
    1062           0 :     return std::max(nScrollBarWidth, nButtonDownWidth);
    1063             : }
    1064             : 
    1065           8 : Size ComboBox::CalcMinimumSize() const
    1066             : {
    1067           8 :     Size aSz;
    1068             : 
    1069           8 :     if (!mpImplLB)
    1070           0 :         return aSz;
    1071             : 
    1072           8 :     if (!IsDropDownBox())
    1073             :     {
    1074           8 :         aSz = mpImplLB->CalcSize( mpImplLB->GetEntryList()->GetEntryCount() );
    1075           8 :         aSz.Height() += mnDDHeight;
    1076             :     }
    1077             :     else
    1078             :     {
    1079           0 :         aSz.Height() = Edit::CalcMinimumSizeForText(GetText()).Height();
    1080           0 :         aSz.Width() = mpImplLB->GetMaxEntryWidth();
    1081             :     }
    1082             : 
    1083           8 :     if (m_nMaxWidthChars != -1)
    1084             :     {
    1085           0 :         long nMaxWidth = m_nMaxWidthChars * approximate_char_width();
    1086           0 :         aSz.Width() = std::min(aSz.Width(), nMaxWidth);
    1087             :     }
    1088             : 
    1089           8 :     if (IsDropDownBox())
    1090           0 :         aSz.Width() += getMaxWidthScrollBarAndDownButton();
    1091             : 
    1092             :     ComboBoxBounds aBounds(calcComboBoxDropDownComponentBounds(
    1093           8 :         Size(0xFFFF, 0xFFFF), Size(0xFFFF, 0xFFFF)));
    1094           8 :     aSz.Width() += aBounds.aSubEditPos.X()*2;
    1095             : 
    1096           8 :     aSz.Width() += ImplGetExtraOffset() * 2;
    1097             : 
    1098           8 :     aSz = CalcWindowSize( aSz );
    1099           8 :     return aSz;
    1100             : }
    1101             : 
    1102             : // -----------------------------------------------------------------------
    1103             : 
    1104           2 : Size ComboBox::CalcAdjustedSize( const Size& rPrefSize ) const
    1105             : {
    1106           2 :     Size aSz = rPrefSize;
    1107             :     sal_Int32 nLeft, nTop, nRight, nBottom;
    1108           2 :     ((Window*)this)->GetBorder( nLeft, nTop, nRight, nBottom );
    1109           2 :     aSz.Height() -= nTop+nBottom;
    1110           2 :     if ( !IsDropDownBox() )
    1111             :     {
    1112           2 :         long nEntryHeight = CalcSize( 1, 1 ).Height();
    1113           2 :         long nLines = aSz.Height() / nEntryHeight;
    1114           2 :         if ( nLines < 1 )
    1115           0 :             nLines = 1;
    1116           2 :         aSz.Height() = nLines * nEntryHeight;
    1117           2 :         aSz.Height() += mnDDHeight;
    1118             :     }
    1119             :     else
    1120             :     {
    1121           0 :         aSz.Height() = mnDDHeight;
    1122             :     }
    1123           2 :     aSz.Height() += nTop+nBottom;
    1124             : 
    1125           2 :     aSz = CalcWindowSize( aSz );
    1126           2 :     return aSz;
    1127             : }
    1128             : 
    1129             : // -----------------------------------------------------------------------
    1130             : 
    1131           4 : Size ComboBox::CalcSize( sal_uInt16 nColumns, sal_uInt16 nLines ) const
    1132             : {
    1133             :     // show ScrollBars where appropriate
    1134           4 :     Size aMinSz = CalcMinimumSize();
    1135           4 :     Size aSz;
    1136             : 
    1137             :     // height
    1138           4 :     if ( nLines )
    1139             :     {
    1140           2 :         if ( !IsDropDownBox() )
    1141           2 :             aSz.Height() = mpImplLB->CalcSize( nLines ).Height() + mnDDHeight;
    1142             :         else
    1143           0 :             aSz.Height() = mnDDHeight;
    1144             :     }
    1145             :     else
    1146           2 :         aSz.Height() = aMinSz.Height();
    1147             : 
    1148             :     // width
    1149           4 :     if ( nColumns )
    1150           2 :         aSz.Width() = nColumns * approximate_char_width();
    1151             :     else
    1152           2 :         aSz.Width() = aMinSz.Width();
    1153             : 
    1154           4 :     if ( IsDropDownBox() )
    1155           0 :         aSz.Width() += getMaxWidthScrollBarAndDownButton();
    1156             : 
    1157           4 :     if ( !IsDropDownBox() )
    1158             :     {
    1159           4 :         if ( aSz.Width() < aMinSz.Width() )
    1160           0 :             aSz.Height() += GetSettings().GetStyleSettings().GetScrollBarSize();
    1161           4 :         if ( aSz.Height() < aMinSz.Height() )
    1162           0 :             aSz.Width() += GetSettings().GetStyleSettings().GetScrollBarSize();
    1163             :     }
    1164             : 
    1165           4 :     aSz.Width() += ImplGetExtraOffset() * 2;
    1166             : 
    1167           4 :     aSz = CalcWindowSize( aSz );
    1168           4 :     return aSz;
    1169             : }
    1170             : 
    1171             : // -----------------------------------------------------------------------
    1172             : 
    1173           2 : void ComboBox::GetMaxVisColumnsAndLines( sal_uInt16& rnCols, sal_uInt16& rnLines ) const
    1174             : {
    1175           2 :     long nCharWidth = GetTextWidth(OUString(static_cast<sal_Unicode>('x')));
    1176           2 :     if ( !IsDropDownBox() )
    1177             :     {
    1178           2 :         Size aOutSz = mpImplLB->GetMainWindow()->GetOutputSizePixel();
    1179           2 :         rnCols = (sal_uInt16)(aOutSz.Width()/nCharWidth);
    1180           2 :         rnLines = (sal_uInt16)(aOutSz.Height()/mpImplLB->GetEntryHeight());
    1181             :     }
    1182             :     else
    1183             :     {
    1184           0 :         Size aOutSz = mpSubEdit->GetOutputSizePixel();
    1185           0 :         rnCols = (sal_uInt16)(aOutSz.Width()/nCharWidth);
    1186           0 :         rnLines = 1;
    1187             :     }
    1188           2 : }
    1189             : 
    1190             : // -----------------------------------------------------------------------
    1191             : 
    1192           0 : void ComboBox::Draw( OutputDevice* pDev, const Point& rPos, const Size& rSize, sal_uLong nFlags )
    1193             : {
    1194           0 :     mpImplLB->GetMainWindow()->ImplInitSettings( sal_True, sal_True, sal_True );
    1195             : 
    1196           0 :     Point aPos = pDev->LogicToPixel( rPos );
    1197           0 :     Size aSize = pDev->LogicToPixel( rSize );
    1198           0 :     Font aFont = mpImplLB->GetMainWindow()->GetDrawPixelFont( pDev );
    1199           0 :     OutDevType eOutDevType = pDev->GetOutDevType();
    1200             : 
    1201           0 :     pDev->Push();
    1202           0 :     pDev->SetMapMode();
    1203           0 :     pDev->SetFont( aFont );
    1204           0 :     pDev->SetTextFillColor();
    1205             : 
    1206             :     // Border/Background
    1207           0 :     pDev->SetLineColor();
    1208           0 :     pDev->SetFillColor();
    1209           0 :     sal_Bool bBorder = !(nFlags & WINDOW_DRAW_NOBORDER ) && (GetStyle() & WB_BORDER);
    1210           0 :     sal_Bool bBackground = !(nFlags & WINDOW_DRAW_NOBACKGROUND) && IsControlBackground();
    1211           0 :     if ( bBorder || bBackground )
    1212             :     {
    1213           0 :         Rectangle aRect( aPos, aSize );
    1214             :         // aRect.Top() += nEditHeight;
    1215           0 :         if ( bBorder )
    1216             :         {
    1217           0 :             ImplDrawFrame( pDev, aRect );
    1218             :         }
    1219           0 :         if ( bBackground )
    1220             :         {
    1221           0 :             pDev->SetFillColor( GetControlBackground() );
    1222           0 :             pDev->DrawRect( aRect );
    1223             :         }
    1224             :     }
    1225             : 
    1226             :     // contents
    1227           0 :     if ( !IsDropDownBox() )
    1228             :     {
    1229           0 :         long        nOnePixel = GetDrawPixel( pDev, 1 );
    1230           0 :         long        nTextHeight = pDev->GetTextHeight();
    1231           0 :         long        nEditHeight = nTextHeight + 6*nOnePixel;
    1232           0 :         sal_uInt16      nTextStyle = TEXT_DRAW_VCENTER;
    1233             : 
    1234             :         // First, draw the edit part
    1235           0 :         mpSubEdit->Draw( pDev, aPos, Size( aSize.Width(), nEditHeight ), nFlags );
    1236             : 
    1237             :         // Second, draw the listbox
    1238           0 :         if ( GetStyle() & WB_CENTER )
    1239           0 :             nTextStyle |= TEXT_DRAW_CENTER;
    1240           0 :         else if ( GetStyle() & WB_RIGHT )
    1241           0 :             nTextStyle |= TEXT_DRAW_RIGHT;
    1242             :         else
    1243           0 :             nTextStyle |= TEXT_DRAW_LEFT;
    1244             : 
    1245           0 :         if ( ( nFlags & WINDOW_DRAW_MONO ) || ( eOutDevType == OUTDEV_PRINTER ) )
    1246             :         {
    1247           0 :             pDev->SetTextColor( Color( COL_BLACK ) );
    1248             :         }
    1249             :         else
    1250             :         {
    1251           0 :             if ( !(nFlags & WINDOW_DRAW_NODISABLE ) && !IsEnabled() )
    1252             :             {
    1253           0 :                 const StyleSettings& rStyleSettings = GetSettings().GetStyleSettings();
    1254           0 :                 pDev->SetTextColor( rStyleSettings.GetDisableColor() );
    1255             :             }
    1256             :             else
    1257             :             {
    1258           0 :                 pDev->SetTextColor( GetTextColor() );
    1259             :             }
    1260             :         }
    1261             : 
    1262           0 :         Rectangle aClip( aPos, aSize );
    1263           0 :         pDev->IntersectClipRegion( aClip );
    1264           0 :         sal_uInt16 nLines = (sal_uInt16) ( (aSize.Height()-nEditHeight) / nTextHeight );
    1265           0 :         if ( !nLines )
    1266           0 :             nLines = 1;
    1267           0 :         sal_uInt16 nTEntry = IsReallyVisible() ? mpImplLB->GetTopEntry() : 0;
    1268             : 
    1269           0 :         Rectangle aTextRect( aPos, aSize );
    1270             : 
    1271           0 :         aTextRect.Left() += 3*nOnePixel;
    1272           0 :         aTextRect.Right() -= 3*nOnePixel;
    1273           0 :         aTextRect.Top() += nEditHeight + nOnePixel;
    1274           0 :         aTextRect.Bottom() = aTextRect.Top() + nTextHeight;
    1275             : 
    1276             :         // the drawing starts here
    1277           0 :         for ( sal_uInt16 n = 0; n < nLines; n++ )
    1278             :         {
    1279           0 :             pDev->DrawText( aTextRect, mpImplLB->GetEntryList()->GetEntryText( n+nTEntry ), nTextStyle );
    1280           0 :             aTextRect.Top() += nTextHeight;
    1281           0 :             aTextRect.Bottom() += nTextHeight;
    1282             :         }
    1283             :     }
    1284             : 
    1285           0 :     pDev->Pop();
    1286             : 
    1287             :     // Call Edit::Draw after restoring the MapMode...
    1288           0 :     if ( IsDropDownBox() )
    1289             :     {
    1290           0 :         mpSubEdit->Draw( pDev, rPos, rSize, nFlags );
    1291             :         // DD-Button ?
    1292           0 :     }
    1293             : 
    1294           0 : }
    1295             : 
    1296             : // -----------------------------------------------------------------------
    1297             : 
    1298        1822 : IMPL_LINK( ComboBox, ImplUserDrawHdl, UserDrawEvent*, pEvent )
    1299             : {
    1300         911 :     UserDraw( *pEvent );
    1301         911 :     return 1;
    1302             : }
    1303             : 
    1304             : // -----------------------------------------------------------------------
    1305             : 
    1306           0 : void ComboBox::UserDraw( const UserDrawEvent& )
    1307             : {
    1308           0 : }
    1309             : 
    1310             : // -----------------------------------------------------------------------
    1311             : 
    1312        1581 : void ComboBox::SetUserItemSize( const Size& rSz )
    1313             : {
    1314        1581 :     mpImplLB->GetMainWindow()->SetUserItemSize( rSz );
    1315        1581 : }
    1316             : 
    1317             : // -----------------------------------------------------------------------
    1318             : 
    1319        1064 : void ComboBox::EnableUserDraw( sal_Bool bUserDraw )
    1320             : {
    1321        1064 :     mpImplLB->GetMainWindow()->EnableUserDraw( bUserDraw );
    1322        1064 : }
    1323             : 
    1324             : // -----------------------------------------------------------------------
    1325             : 
    1326         911 : void ComboBox::DrawEntry( const UserDrawEvent& rEvt, sal_Bool bDrawImage, sal_Bool bDrawText, sal_Bool bDrawTextAtImagePos )
    1327             : {
    1328             :     DBG_ASSERT( rEvt.GetDevice() == mpImplLB->GetMainWindow(), "DrawEntry?!" );
    1329         911 :     mpImplLB->GetMainWindow()->DrawEntry( rEvt.GetItemId(), bDrawImage, bDrawText, bDrawTextAtImagePos );
    1330         911 : }
    1331             : 
    1332             : // -----------------------------------------------------------------------
    1333             : 
    1334        5327 : void ComboBox::SetSeparatorPos( sal_uInt16 n )
    1335             : {
    1336        5327 :     mpImplLB->SetSeparatorPos( n );
    1337        5327 : }
    1338             : 
    1339             : // -----------------------------------------------------------------------
    1340             : 
    1341           0 : void ComboBox::SetMRUEntries( const OUString& rEntries, sal_Unicode cSep )
    1342             : {
    1343           0 :     mpImplLB->SetMRUEntries( rEntries, cSep );
    1344           0 : }
    1345             : 
    1346             : // -----------------------------------------------------------------------
    1347             : 
    1348        1049 : OUString ComboBox::GetMRUEntries( sal_Unicode cSep ) const
    1349             : {
    1350        1049 :     return mpImplLB->GetMRUEntries( cSep );
    1351             : }
    1352             : 
    1353             : // -----------------------------------------------------------------------
    1354             : 
    1355         532 : void ComboBox::SetMaxMRUCount( sal_uInt16 n )
    1356             : {
    1357         532 :     mpImplLB->SetMaxMRUCount( n );
    1358         532 : }
    1359             : 
    1360             : // -----------------------------------------------------------------------
    1361             : 
    1362         532 : sal_uInt16 ComboBox::GetMaxMRUCount() const
    1363             : {
    1364         532 :     return mpImplLB->GetMaxMRUCount();
    1365             : }
    1366             : 
    1367             : // -----------------------------------------------------------------------
    1368             : 
    1369         115 : sal_uInt16 ComboBox::GetDisplayLineCount() const
    1370             : {
    1371         115 :     return mpImplLB->GetDisplayLineCount();
    1372             : }
    1373             : 
    1374             : // -----------------------------------------------------------------------
    1375             : 
    1376       15510 : void ComboBox::SetEntryData( sal_uInt16 nPos, void* pNewData )
    1377             : {
    1378       15510 :     mpImplLB->SetEntryData( nPos + mpImplLB->GetEntryList()->GetMRUCount(), pNewData );
    1379       15510 : }
    1380             : 
    1381             : // -----------------------------------------------------------------------
    1382             : 
    1383           0 : void* ComboBox::GetEntryData( sal_uInt16 nPos ) const
    1384             : {
    1385           0 :     return mpImplLB->GetEntryList()->GetEntryData( nPos + mpImplLB->GetEntryList()->GetMRUCount() );
    1386             : }
    1387             : 
    1388             : // -----------------------------------------------------------------------
    1389             : 
    1390         109 : sal_uInt16 ComboBox::GetTopEntry() const
    1391             : {
    1392         109 :     sal_uInt16 nPos = GetEntryCount() ? mpImplLB->GetTopEntry() : LISTBOX_ENTRY_NOTFOUND;
    1393         109 :     if ( nPos < mpImplLB->GetEntryList()->GetMRUCount() )
    1394           0 :         nPos = 0;
    1395         109 :     return nPos;
    1396             : }
    1397             : 
    1398             : // -----------------------------------------------------------------------
    1399             : 
    1400         532 : void ComboBox::SetProminentEntryType( ProminentEntry eType )
    1401             : {
    1402         532 :     mpImplLB->SetProminentEntryType( eType );
    1403         532 : }
    1404             : 
    1405             : // -----------------------------------------------------------------------
    1406             : 
    1407           0 : Rectangle ComboBox::GetDropDownPosSizePixel() const
    1408             : {
    1409           0 :     return mpFloatWin ? mpFloatWin->GetWindowExtentsRelative( const_cast<ComboBox*>(this) ) : Rectangle();
    1410             : }
    1411             : 
    1412             : // -----------------------------------------------------------------------
    1413             : 
    1414           0 : const Wallpaper& ComboBox::GetDisplayBackground() const
    1415             : {
    1416           0 :     if( ! mpSubEdit->IsBackground() )
    1417           0 :         return Control::GetDisplayBackground();
    1418             : 
    1419           0 :     const Wallpaper& rBack = mpSubEdit->GetBackground();
    1420           0 :     if( ! rBack.IsBitmap() &&
    1421           0 :         ! rBack.IsGradient() &&
    1422           0 :         rBack.GetColor().GetColor() == COL_TRANSPARENT
    1423             :         )
    1424           0 :         return Control::GetDisplayBackground();
    1425           0 :     return rBack;
    1426             : }
    1427             : // -----------------------------------------------------------------------------
    1428           0 : sal_uInt16 ComboBox::GetSelectEntryCount() const
    1429             : {
    1430           0 :     return mpImplLB->GetEntryList()->GetSelectEntryCount();
    1431             : }
    1432             : // -----------------------------------------------------------------------------
    1433         781 : sal_uInt16 ComboBox::GetSelectEntryPos( sal_uInt16 nIndex ) const
    1434             : {
    1435         781 :     sal_uInt16 nPos = mpImplLB->GetEntryList()->GetSelectEntryPos( nIndex );
    1436         781 :     if ( nPos != LISTBOX_ENTRY_NOTFOUND )
    1437             :     {
    1438         780 :         if ( nPos < mpImplLB->GetEntryList()->GetMRUCount() )
    1439           0 :             nPos = mpImplLB->GetEntryList()->FindEntry( mpImplLB->GetEntryList()->GetEntryText( nPos ) );
    1440         780 :         nPos = sal::static_int_cast<sal_uInt16>(nPos - mpImplLB->GetEntryList()->GetMRUCount());
    1441             :     }
    1442         781 :     return nPos;
    1443             : }
    1444             : // -----------------------------------------------------------------------------
    1445         109 : sal_Bool ComboBox::IsEntryPosSelected( sal_uInt16 nPos ) const
    1446             : {
    1447         109 :     return mpImplLB->GetEntryList()->IsEntryPosSelected( nPos + mpImplLB->GetEntryList()->GetMRUCount() );
    1448             : }
    1449             : // -----------------------------------------------------------------------------
    1450           0 : void ComboBox::SelectEntryPos( sal_uInt16 nPos, sal_Bool bSelect)
    1451             : {
    1452           0 :     if ( nPos < mpImplLB->GetEntryList()->GetEntryCount() )
    1453           0 :         mpImplLB->SelectEntry( nPos + mpImplLB->GetEntryList()->GetMRUCount(), bSelect );
    1454           0 : }
    1455             : // -----------------------------------------------------------------------------
    1456           0 : void ComboBox::SetNoSelection()
    1457             : {
    1458           0 :     mpImplLB->SetNoSelection();
    1459           0 :     mpSubEdit->SetText( String() );
    1460           0 : }
    1461             : // -----------------------------------------------------------------------------
    1462           0 : Rectangle ComboBox::GetBoundingRectangle( sal_uInt16 nItem ) const
    1463             : {
    1464           0 :     Rectangle aRect = mpImplLB->GetMainWindow()->GetBoundingRectangle( nItem );
    1465           0 :     Rectangle aOffset = mpImplLB->GetMainWindow()->GetWindowExtentsRelative( (Window*)this );
    1466           0 :     aRect.Move( aOffset.TopLeft().X(), aOffset.TopLeft().Y() );
    1467           0 :     return aRect;
    1468             : }
    1469             : // -----------------------------------------------------------------------------
    1470             : 
    1471          22 : void ComboBox::SetBorderStyle( sal_uInt16 nBorderStyle )
    1472             : {
    1473          22 :     Window::SetBorderStyle( nBorderStyle );
    1474          22 :     if ( !IsDropDownBox() )
    1475             :     {
    1476          14 :         mpSubEdit->SetBorderStyle( nBorderStyle );
    1477          14 :         mpImplLB->SetBorderStyle( nBorderStyle );
    1478             :     }
    1479          22 : }
    1480             : // -----------------------------------------------------------------------------
    1481             : 
    1482           0 : long ComboBox::GetIndexForPoint( const Point& rPoint, sal_uInt16& rPos ) const
    1483             : {
    1484           0 :     if( !HasLayoutData() )
    1485           0 :         FillLayoutData();
    1486             : 
    1487             :     // check whether rPoint fits at all
    1488           0 :     long nIndex = Control::GetIndexForPoint( rPoint );
    1489           0 :     if( nIndex != -1 )
    1490             :     {
    1491             :         // point must be either in main list window
    1492             :         // or in impl window (dropdown case)
    1493           0 :         ImplListBoxWindow* pMain = mpImplLB->GetMainWindow();
    1494             : 
    1495             :         // convert coordinates to ImplListBoxWindow pixel coordinate space
    1496           0 :         Point aConvPoint = LogicToPixel( rPoint );
    1497           0 :         aConvPoint = OutputToAbsoluteScreenPixel( aConvPoint );
    1498           0 :         aConvPoint = pMain->AbsoluteScreenToOutputPixel( aConvPoint );
    1499           0 :         aConvPoint = pMain->PixelToLogic( aConvPoint );
    1500             : 
    1501             :         // try to find entry
    1502           0 :         sal_uInt16 nEntry = pMain->GetEntryPosForPoint( aConvPoint );
    1503           0 :         if( nEntry == LISTBOX_ENTRY_NOTFOUND )
    1504           0 :             nIndex = -1;
    1505             :         else
    1506           0 :             rPos = nEntry;
    1507             :     }
    1508             : 
    1509             :     // get line relative index
    1510           0 :     if( nIndex != -1 )
    1511           0 :         nIndex = ToRelativeLineIndex( nIndex );
    1512             : 
    1513           0 :     return nIndex;
    1514             : }
    1515             : 
    1516        1899 : ComboBox::ComboBoxBounds ComboBox::calcComboBoxDropDownComponentBounds(const Size &rOutSz,
    1517             :     const Size &rBorderOutSz) const
    1518             : {
    1519        1899 :     ComboBoxBounds aBounds;
    1520             : 
    1521        1899 :     long    nTop = 0;
    1522        1899 :     long    nBottom = rOutSz.Height();
    1523             : 
    1524        1899 :     Window *pBorder = GetWindow( WINDOW_BORDER );
    1525        1899 :     ImplControlValue aControlValue;
    1526        1899 :     Point aPoint;
    1527        1899 :     Rectangle aContent, aBound;
    1528             : 
    1529             :     // use the full extent of the control
    1530        1899 :     Rectangle aArea( aPoint, rBorderOutSz );
    1531             : 
    1532        3798 :     if ( GetNativeControlRegion(CTRL_COMBOBOX, PART_BUTTON_DOWN,
    1533        3798 :             aArea, 0, aControlValue, OUString(), aBound, aContent) )
    1534             :     {
    1535             :         // convert back from border space to local coordinates
    1536           0 :         aPoint = pBorder->ScreenToOutputPixel( OutputToScreenPixel( aPoint ) );
    1537           0 :         aContent.Move(-aPoint.X(), -aPoint.Y());
    1538             : 
    1539           0 :         aBounds.aButtonPos = Point(aContent.Left(), nTop);
    1540           0 :         aBounds.aButtonSize = Size(aContent.getWidth(), (nBottom-nTop));
    1541             : 
    1542             :         // adjust the size of the edit field
    1543           0 :         if ( GetNativeControlRegion(CTRL_COMBOBOX, PART_SUB_EDIT,
    1544           0 :                     aArea, 0, aControlValue, OUString(), aBound, aContent) )
    1545             :         {
    1546             :             // convert back from border space to local coordinates
    1547           0 :             aContent.Move(-aPoint.X(), -aPoint.Y());
    1548             : 
    1549             :             // use the themes drop down size
    1550           0 :             aBounds.aSubEditPos = aContent.TopLeft();
    1551           0 :             aBounds.aSubEditSize = aContent.GetSize();
    1552             :         }
    1553             :         else
    1554             :         {
    1555             :             // use the themes drop down size for the button
    1556           0 :             aBounds.aSubEditSize = Size(rOutSz.Width() - aContent.getWidth(), rOutSz.Height());
    1557             :         }
    1558             :     }
    1559             :     else
    1560             :     {
    1561        1899 :         long nSBWidth = GetSettings().GetStyleSettings().GetScrollBarSize();
    1562        1899 :         nSBWidth = CalcZoom( nSBWidth );
    1563        1899 :         aBounds.aSubEditSize = Size(rOutSz.Width() - nSBWidth, rOutSz.Height());
    1564        1899 :         aBounds.aButtonPos = Point(rOutSz.Width() - nSBWidth, nTop);
    1565        1899 :         aBounds.aButtonSize = Size(nSBWidth, (nBottom-nTop));
    1566             :     }
    1567        1899 :     return aBounds;
    1568             : }
    1569             : 
    1570           0 : void ComboBox::setMaxWidthChars(sal_Int32 nWidth)
    1571             : {
    1572           0 :     if (nWidth != m_nMaxWidthChars)
    1573             :     {
    1574           0 :         m_nMaxWidthChars = nWidth;
    1575           0 :         queue_resize();
    1576             :     }
    1577           0 : }
    1578             : 
    1579           0 : bool ComboBox::set_property(const OString &rKey, const OString &rValue)
    1580             : {
    1581           0 :     if (rKey == "max-width-chars")
    1582           0 :         setMaxWidthChars(rValue.toInt32());
    1583             :     else
    1584           0 :         return Control::set_property(rKey, rValue);
    1585           0 :     return true;
    1586         465 : }
    1587             : 
    1588             : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.10