1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: combobox.cxx,v $
12 * This file is part of OpenOffice.org.
14 * OpenOffice.org is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU Lesser General Public License version 3
16 * only, as published by the Free Software Foundation.
18 * OpenOffice.org is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Lesser General Public License version 3 for more details
22 * (a copy is included in the LICENSE file that accompanied this code).
24 * You should have received a copy of the GNU Lesser General Public License
25 * version 3 along with OpenOffice.org. If not, see
26 * <http://www.openoffice.org/license.html>
27 * for a copy of the LGPLv3 License.
29 ************************************************************************/
31 // MARKER(update_precomp.py): autogen include statement, do not remove
32 #include "precompiled_vcl.hxx"
33 #include <tools/table.hxx>
34 #include <tools/debug.hxx>
39 #include <vcl/svdata.hxx>
40 #include <vcl/decoview.hxx>
41 #include <vcl/ilstbox.hxx>
42 #include <vcl/lstbox.h>
43 #include <vcl/button.hxx>
44 #include <vcl/subedit.hxx>
45 #include <vcl/event.hxx>
46 #include <vcl/combobox.hxx>
47 #include <vcl/controllayout.hxx>
51 // =======================================================================
53 inline ULONG
ImplCreateKey( USHORT nPos
)
55 // Key = Pos+1, wegen Pos 0
59 // -----------------------------------------------------------------------
61 static void lcl_GetSelectedEntries( Table
& rSelectedPos
, const XubString
& rText
, xub_Unicode cTokenSep
, const ImplEntryList
* pEntryList
)
63 for( xub_StrLen n
= rText
.GetTokenCount( cTokenSep
); n
; )
65 XubString aToken
= rText
.GetToken( --n
, cTokenSep
);
66 aToken
.EraseLeadingAndTrailingChars( ' ' );
67 USHORT nPos
= pEntryList
->FindEntry( aToken
);
68 if ( nPos
!= LISTBOX_ENTRY_NOTFOUND
)
69 rSelectedPos
.Insert( ImplCreateKey( nPos
), (void*)sal_IntPtr(1L) );
73 // =======================================================================
75 ComboBox::ComboBox( WindowType nType
) :
78 ImplInitComboBoxData();
81 // -----------------------------------------------------------------------
83 ComboBox::ComboBox( Window
* pParent
, WinBits nStyle
) :
84 Edit( WINDOW_COMBOBOX
)
86 ImplInitComboBoxData();
87 ImplInit( pParent
, nStyle
);
90 // -----------------------------------------------------------------------
92 ComboBox::ComboBox( Window
* pParent
, const ResId
& rResId
) :
93 Edit( WINDOW_COMBOBOX
)
95 ImplInitComboBoxData();
96 rResId
.SetRT( RSC_COMBOBOX
);
97 WinBits nStyle
= ImplInitRes( rResId
);
98 ImplInit( pParent
, nStyle
);
99 ImplLoadRes( rResId
);
101 if ( !(nStyle
& WB_HIDE
) )
105 // -----------------------------------------------------------------------
107 ComboBox::~ComboBox()
119 // -----------------------------------------------------------------------
121 void ComboBox::ImplInitComboBoxData()
130 mbSyntheticModify
= FALSE
;
135 // -----------------------------------------------------------------------
137 void ComboBox::ImplCalcEditHeight()
139 sal_Int32 nLeft
, nTop
, nRight
, nBottom
;
140 GetBorder( nLeft
, nTop
, nRight
, nBottom
);
141 mnDDHeight
= (USHORT
)(mpSubEdit
->GetTextHeight() + nTop
+ nBottom
+ 4);
142 if ( !IsDropDownBox() )
145 Region
aCtrlRegion( Rectangle( (const Point
&)Point(), Size( 10, 10 ) ) );
146 Region aBoundRegion
, aContentRegion
;
147 ImplControlValue aControlValue
;
148 ControlType aType
= IsDropDownBox() ? CTRL_COMBOBOX
: CTRL_EDITBOX
;
149 if( GetNativeControlRegion( aType
, PART_ENTIRE_CONTROL
,
152 aControlValue
, rtl::OUString(),
153 aBoundRegion
, aContentRegion
) )
155 const long nNCHeight
= aBoundRegion
.GetBoundRect().GetHeight();
156 if( mnDDHeight
< nNCHeight
)
157 mnDDHeight
= sal::static_int_cast
<USHORT
>( nNCHeight
);
161 // -----------------------------------------------------------------------
163 void ComboBox::ImplInit( Window
* pParent
, WinBits nStyle
)
165 ImplInitStyle( nStyle
);
167 BOOL bNoBorder
= ( nStyle
& WB_NOBORDER
) ? TRUE
: FALSE
;
168 if ( !(nStyle
& WB_DROPDOWN
) )
170 nStyle
&= ~WB_BORDER
;
171 nStyle
|= WB_NOBORDER
;
179 Edit::ImplInit( pParent
, nStyle
);
183 WinBits nEditStyle
= nStyle
& ( WB_LEFT
| WB_RIGHT
| WB_CENTER
);
184 WinBits nListStyle
= nStyle
;
185 if( nStyle
& WB_DROPDOWN
)
187 mpFloatWin
= new ImplListBoxFloatingWindow( this );
188 mpFloatWin
->SetAutoWidth( TRUE
);
189 mpFloatWin
->SetPopupModeEndHdl( LINK( this, ComboBox
, ImplPopupModeEndHdl
) );
191 mpBtn
= new ImplBtn( this, WB_NOLIGHTBORDER
| WB_RECTSTYLE
);
192 ImplInitDropDownButton( mpBtn
);
193 mpBtn
->SetMBDownHdl( LINK( this, ComboBox
, ImplClickBtnHdl
) );
196 nEditStyle
|= WB_NOBORDER
;
197 nListStyle
&= ~WB_BORDER
;
198 nListStyle
|= WB_NOBORDER
;
204 nEditStyle
|= WB_BORDER
;
205 nListStyle
&= ~WB_NOBORDER
;
206 nListStyle
|= WB_BORDER
;
210 mpSubEdit
= new Edit( this, nEditStyle
);
211 mpSubEdit
->EnableRTL( FALSE
);
212 SetSubEdit( mpSubEdit
);
213 mpSubEdit
->SetPosPixel( Point() );
214 EnableAutocomplete( TRUE
);
217 Window
* pLBParent
= this;
219 pLBParent
= mpFloatWin
;
220 mpImplLB
= new ImplListBox( pLBParent
, nListStyle
|WB_SIMPLEMODE
);
221 mpImplLB
->SetPosPixel( Point() );
222 mpImplLB
->SetSelectHdl( LINK( this, ComboBox
, ImplSelectHdl
) );
223 mpImplLB
->SetCancelHdl( LINK( this, ComboBox
, ImplCancelHdl
) );
224 mpImplLB
->SetDoubleClickHdl( LINK( this, ComboBox
, ImplDoubleClickHdl
) );
225 mpImplLB
->SetUserDrawHdl( LINK( this, ComboBox
, ImplUserDrawHdl
) );
226 mpImplLB
->SetSelectionChangedHdl( LINK( this, ComboBox
, ImplSelectionChangedHdl
) );
230 mpFloatWin
->SetImplListBox( mpImplLB
);
232 mpImplLB
->GetMainWindow()->AllowGrabFocus( TRUE
);
234 ImplCalcEditHeight();
236 SetCompoundControl( TRUE
);
239 // -----------------------------------------------------------------------
241 WinBits
ComboBox::ImplInitStyle( WinBits nStyle
)
243 if ( !(nStyle
& WB_NOTABSTOP
) )
244 nStyle
|= WB_TABSTOP
;
245 if ( !(nStyle
& WB_NOGROUP
) )
250 // -----------------------------------------------------------------------
252 void ComboBox::ImplLoadRes( const ResId
& rResId
)
254 Edit::ImplLoadRes( rResId
);
256 ULONG nNumber
= ReadLongRes();
260 for( USHORT i
= 0; i
< nNumber
; i
++ )
262 InsertEntry( ReadStringRes(), LISTBOX_APPEND
);
267 // -----------------------------------------------------------------------
269 void ComboBox::EnableAutocomplete( BOOL bEnable
, BOOL bMatchCase
)
271 mbMatchCase
= bMatchCase
;
274 mpSubEdit
->SetAutocompleteHdl( LINK( this, ComboBox
, ImplAutocompleteHdl
) );
276 mpSubEdit
->SetAutocompleteHdl( Link() );
279 // -----------------------------------------------------------------------
281 BOOL
ComboBox::IsAutocompleteEnabled() const
283 return mpSubEdit
->GetAutocompleteHdl().IsSet();
286 // -----------------------------------------------------------------------
288 IMPL_LINK( ComboBox
, ImplClickBtnHdl
, void*, EMPTYARG
)
290 ImplCallEventListeners( VCLEVENT_DROPDOWN_PRE_OPEN
);
291 mpSubEdit
->GrabFocus();
292 if ( !mpImplLB
->GetEntryList()->GetMRUCount() )
293 ImplUpdateFloatSelection();
295 mpImplLB
->SelectEntry( 0 , TRUE
);
296 mpBtn
->SetPressed( TRUE
);
297 SetSelection( Selection( 0, SELECTION_MAX
) );
298 mpFloatWin
->StartFloat( TRUE
);
299 ImplCallEventListeners( VCLEVENT_DROPDOWN_OPEN
);
301 ImplClearLayoutData();
303 mpImplLB
->GetMainWindow()->ImplClearLayoutData();
308 // -----------------------------------------------------------------------
310 IMPL_LINK( ComboBox
, ImplPopupModeEndHdl
, void*, EMPTYARG
)
312 if( mpFloatWin
->IsPopupModeCanceled() )
314 if ( !mpImplLB
->GetEntryList()->IsEntryPosSelected( mpFloatWin
->GetPopupModeStartSaveSelection() ) )
316 mpImplLB
->SelectEntry( mpFloatWin
->GetPopupModeStartSaveSelection(), TRUE
);
317 BOOL bTravelSelect
= mpImplLB
->IsTravelSelect();
318 mpImplLB
->SetTravelSelect( TRUE
);
320 mpImplLB
->SetTravelSelect( bTravelSelect
);
324 ImplClearLayoutData();
326 mpImplLB
->GetMainWindow()->ImplClearLayoutData();
328 mpBtn
->SetPressed( FALSE
);
329 ImplCallEventListeners( VCLEVENT_DROPDOWN_CLOSE
);
333 // -----------------------------------------------------------------------
335 IMPL_LINK( ComboBox
, ImplAutocompleteHdl
, Edit
*, pEdit
)
337 Selection aSel
= pEdit
->GetSelection();
338 AutocompleteAction eAction
= pEdit
->GetAutocompleteAction();
340 /* If there is no current selection do not auto complete on
341 Tab/Shift-Tab since then we would not cycle to the next field.
344 ((eAction
!= AUTOCOMPLETE_TABFORWARD
) && (eAction
!= AUTOCOMPLETE_TABBACKWARD
)) )
346 XubString aFullText
= pEdit
->GetText();
347 XubString aStartText
= aFullText
.Copy( 0, (xub_StrLen
)aSel
.Max() );
348 USHORT nStart
= mpImplLB
->GetCurrentPos();
350 if ( nStart
== LISTBOX_ENTRY_NOTFOUND
)
353 BOOL bForward
= TRUE
;
354 if ( eAction
== AUTOCOMPLETE_TABFORWARD
)
356 else if ( eAction
== AUTOCOMPLETE_TABBACKWARD
)
359 nStart
= nStart
? nStart
- 1 : mpImplLB
->GetEntryList()->GetEntryCount()-1;
362 USHORT nPos
= LISTBOX_ENTRY_NOTFOUND
;
365 // Try match case insensitive from current position
366 nPos
= mpImplLB
->GetEntryList()->FindMatchingEntry( aStartText
, nStart
, bForward
, TRUE
);
367 if ( nPos
== LISTBOX_ENTRY_NOTFOUND
)
368 // Try match case insensitive, but from start
369 nPos
= mpImplLB
->GetEntryList()->FindMatchingEntry( aStartText
, bForward
? 0 : (mpImplLB
->GetEntryList()->GetEntryCount()-1), bForward
, TRUE
);
372 if ( nPos
== LISTBOX_ENTRY_NOTFOUND
)
373 // Try match full from current position
374 nPos
= mpImplLB
->GetEntryList()->FindMatchingEntry( aStartText
, nStart
, bForward
, FALSE
);
375 if ( nPos
== LISTBOX_ENTRY_NOTFOUND
)
376 // Match full, but from start
377 nPos
= mpImplLB
->GetEntryList()->FindMatchingEntry( aStartText
, bForward
? 0 : (mpImplLB
->GetEntryList()->GetEntryCount()-1), bForward
, FALSE
);
379 if ( nPos
!= LISTBOX_ENTRY_NOTFOUND
)
381 XubString aText
= mpImplLB
->GetEntryList()->GetEntryText( nPos
);
382 Selection
aSelection( aText
.Len(), aStartText
.Len() );
383 pEdit
->SetText( aText
, aSelection
);
390 // -----------------------------------------------------------------------
392 IMPL_LINK( ComboBox
, ImplSelectHdl
, void*, EMPTYARG
)
394 BOOL bPopup
= IsInDropDown();
395 BOOL bCallSelect
= FALSE
;
396 if ( mpImplLB
->IsSelectionChanged() || bPopup
)
399 if ( IsMultiSelectionEnabled() )
401 aText
= mpSubEdit
->GetText();
403 // Alle Eintraege entfernen, zu denen es einen Entry gibt, der aber nicht selektiert ist.
404 xub_StrLen nIndex
= 0;
405 while ( nIndex
!= STRING_NOTFOUND
)
407 xub_StrLen nPrevIndex
= nIndex
;
408 XubString aToken
= aText
.GetToken( 0, mcMultiSep
, nIndex
);
409 xub_StrLen nTokenLen
= aToken
.Len();
410 aToken
.EraseLeadingAndTrailingChars( ' ' );
411 USHORT nP
= mpImplLB
->GetEntryList()->FindEntry( aToken
);
412 if ( (nP
!= LISTBOX_ENTRY_NOTFOUND
) && (!mpImplLB
->GetEntryList()->IsEntryPosSelected( nP
)) )
414 aText
.Erase( nPrevIndex
, nTokenLen
);
415 nIndex
= sal::static_int_cast
<xub_StrLen
>(nIndex
- nTokenLen
);
416 if ( (nPrevIndex
< aText
.Len()) && (aText
.GetChar( nPrevIndex
) == mcMultiSep
) )
418 aText
.Erase( nPrevIndex
, 1 );
422 aText
.EraseLeadingAndTrailingChars( ' ' );
425 // Fehlende Eintraege anhaengen...
427 lcl_GetSelectedEntries( aSelInText
, aText
, mcMultiSep
, mpImplLB
->GetEntryList() );
428 USHORT nSelectedEntries
= mpImplLB
->GetEntryList()->GetSelectEntryCount();
429 for ( USHORT n
= 0; n
< nSelectedEntries
; n
++ )
431 USHORT nP
= mpImplLB
->GetEntryList()->GetSelectEntryPos( n
);
432 if ( !aSelInText
.IsKeyValid( ImplCreateKey( nP
) ) )
434 if ( aText
.Len() && (aText
.GetChar( aText
.Len()-1 ) != mcMultiSep
) )
437 aText
+= ' '; // etwas auflockern
438 aText
+= mpImplLB
->GetEntryList()->GetEntryText( nP
);
442 if ( aText
.Len() && (aText
.GetChar( aText
.Len()-1 ) == mcMultiSep
) )
443 aText
.Erase( aText
.Len()-1, 1 );
447 aText
= mpImplLB
->GetEntryList()->GetSelectEntry( 0 );
450 mpSubEdit
->SetText( aText
);
452 Selection
aNewSelection( 0, aText
.Len() );
453 if ( IsMultiSelectionEnabled() )
454 aNewSelection
.Min() = aText
.Len();
455 mpSubEdit
->SetSelection( aNewSelection
);
460 // #84652# Call GrabFocus and EndPopupMode before calling Select/Modify, but after changing the text
462 if ( bPopup
&& !mpImplLB
->IsTravelSelect() &&
463 ( !IsMultiSelectionEnabled() || !mpImplLB
->GetSelectModifier() ) )
465 mpFloatWin
->EndPopupMode();
471 mpSubEdit
->SetModifyFlag();
472 mbSyntheticModify
= TRUE
;
474 mbSyntheticModify
= FALSE
;
475 if (ImplGetWindowImpl() != NULL
) //liuchen 2009-7-28, resolve the problem that soffice get crashed if in ComboBox_Change event a Worksheets("SheetX").Activate sentence needs to be executed
484 // -----------------------------------------------------------------------
486 IMPL_LINK( ComboBox
, ImplCancelHdl
, void*, EMPTYARG
)
489 mpFloatWin
->EndPopupMode();
494 // -----------------------------------------------------------------------
496 IMPL_LINK( ComboBox
, ImplSelectionChangedHdl
, void*, n
)
498 if ( !mpImplLB
->IsTrackingSelect() )
500 USHORT nChanged
= (USHORT
)(ULONG
)n
;
501 if ( !mpSubEdit
->IsReadOnly() && mpImplLB
->GetEntryList()->IsEntryPosSelected( nChanged
) )
502 mpSubEdit
->SetText( mpImplLB
->GetEntryList()->GetEntryText( nChanged
) );
507 // -----------------------------------------------------------------------
509 IMPL_LINK( ComboBox
, ImplDoubleClickHdl
, void*, EMPTYARG
)
515 // -----------------------------------------------------------------------
517 void ComboBox::ToggleDropDown()
519 if( IsDropDownBox() )
521 if( mpFloatWin
->IsInPopupMode() )
522 mpFloatWin
->EndPopupMode();
525 mpSubEdit
->GrabFocus();
526 if ( !mpImplLB
->GetEntryList()->GetMRUCount() )
527 ImplUpdateFloatSelection();
529 mpImplLB
->SelectEntry( 0 , TRUE
);
530 ImplCallEventListeners( VCLEVENT_DROPDOWN_PRE_OPEN
);
531 mpBtn
->SetPressed( TRUE
);
532 SetSelection( Selection( 0, SELECTION_MAX
) );
533 mpFloatWin
->StartFloat( TRUE
);
534 ImplCallEventListeners( VCLEVENT_DROPDOWN_OPEN
);
539 // -----------------------------------------------------------------------
541 void ComboBox::Select()
543 ImplCallEventListenersAndHandler( VCLEVENT_COMBOBOX_SELECT
, maSelectHdl
, this );
546 // -----------------------------------------------------------------------
548 void ComboBox::DoubleClick()
550 ImplCallEventListenersAndHandler( VCLEVENT_COMBOBOX_DOUBLECLICK
, maDoubleClickHdl
, this );
553 // -----------------------------------------------------------------------
555 void ComboBox::EnableAutoSize( BOOL bAuto
)
557 mbDDAutoSize
= bAuto
;
560 if ( bAuto
&& !mpFloatWin
->GetDropDownLineCount() )
561 mpFloatWin
->SetDropDownLineCount( 5 );
563 mpFloatWin
->SetDropDownLineCount( 0 );
567 // -----------------------------------------------------------------------
569 void ComboBox::EnableDDAutoWidth( BOOL b
)
572 mpFloatWin
->SetAutoWidth( b
);
575 // -----------------------------------------------------------------------
577 BOOL
ComboBox::IsDDAutoWidthEnabled() const
579 return mpFloatWin
? mpFloatWin
->IsAutoWidth() : FALSE
;
583 // -----------------------------------------------------------------------
585 void ComboBox::SetDropDownLineCount( USHORT nLines
)
588 mpFloatWin
->SetDropDownLineCount( nLines
);
591 // -----------------------------------------------------------------------
593 USHORT
ComboBox::GetDropDownLineCount() const
597 nLines
= mpFloatWin
->GetDropDownLineCount();
601 // -----------------------------------------------------------------------
603 void ComboBox::SetPosSizePixel( long nX
, long nY
, long nWidth
, long nHeight
,
606 if( IsDropDownBox() && ( nFlags
& WINDOW_POSSIZE_SIZE
) )
608 Size aPrefSz
= mpFloatWin
->GetPrefSize();
609 if ( ( nFlags
& WINDOW_POSSIZE_HEIGHT
) && ( nHeight
>= 2*mnDDHeight
) )
610 aPrefSz
.Height() = nHeight
-mnDDHeight
;
611 if ( nFlags
& WINDOW_POSSIZE_WIDTH
)
612 aPrefSz
.Width() = nWidth
;
613 mpFloatWin
->SetPrefSize( aPrefSz
);
615 if ( IsAutoSizeEnabled() && ! (nFlags
& WINDOW_POSSIZE_DROPDOWN
) )
616 nHeight
= mnDDHeight
;
619 Edit::SetPosSizePixel( nX
, nY
, nWidth
, nHeight
, nFlags
);
622 // -----------------------------------------------------------------------
624 void ComboBox::Resize()
628 Size aOutSz
= GetOutputSizePixel();
629 if( IsDropDownBox() )
631 long nSBWidth
= GetSettings().GetStyleSettings().GetScrollBarSize();
633 long nBottom
= aOutSz
.Height();
635 Window
*pBorder
= GetWindow( WINDOW_BORDER
);
636 ImplControlValue aControlValue
;
638 Region aContent
, aBound
;
640 // use the full extent of the control
641 Region
aArea( Rectangle(aPoint
, pBorder
->GetOutputSizePixel()) );
643 if ( GetNativeControlRegion(CTRL_COMBOBOX
, PART_BUTTON_DOWN
,
644 aArea
, 0, aControlValue
, rtl::OUString(), aBound
, aContent
) )
646 // convert back from border space to local coordinates
647 aPoint
= pBorder
->ScreenToOutputPixel( OutputToScreenPixel( aPoint
) );
648 aContent
.Move(-aPoint
.X(), -aPoint
.Y());
650 mpBtn
->SetPosSizePixel( aContent
.GetBoundRect().Left(), nTop
, aContent
.GetBoundRect().getWidth(), (nBottom
-nTop
) );
652 // adjust the size of the edit field
653 if ( GetNativeControlRegion(CTRL_COMBOBOX
, PART_SUB_EDIT
,
654 aArea
, 0, aControlValue
, rtl::OUString(), aBound
, aContent
) )
656 // convert back from border space to local coordinates
657 aContent
.Move(-aPoint
.X(), -aPoint
.Y());
659 // use the themes drop down size
660 Rectangle aContentRect
= aContent
.GetBoundRect();
661 mpSubEdit
->SetPosSizePixel( aContentRect
.TopLeft(), aContentRect
.GetSize() );
665 // use the themes drop down size for the button
666 aOutSz
.Width() -= aContent
.GetBoundRect().getWidth();
667 mpSubEdit
->SetSizePixel( aOutSz
);
672 nSBWidth
= CalcZoom( nSBWidth
);
673 mpSubEdit
->SetPosSizePixel( Point( 0, 0 ), Size( aOutSz
.Width() - nSBWidth
, aOutSz
.Height() ) );
674 mpBtn
->SetPosSizePixel( aOutSz
.Width() - nSBWidth
, nTop
, nSBWidth
, (nBottom
-nTop
) );
679 mpSubEdit
->SetSizePixel( Size( aOutSz
.Width(), mnDDHeight
) );
680 mpImplLB
->SetPosSizePixel( 0, mnDDHeight
, aOutSz
.Width(), aOutSz
.Height() - mnDDHeight
);
681 if ( GetText().Len() )
682 ImplUpdateFloatSelection();
685 // FloatingWindow-Groesse auch im unsichtbare Zustand auf Stand halten,
686 // weil KEY_PGUP/DOWN ausgewertet wird...
688 mpFloatWin
->SetSizePixel( mpFloatWin
->CalcFloatSize() );
691 // -----------------------------------------------------------------------
693 void ComboBox::FillLayoutData() const
695 mpLayoutData
= new vcl::ControlLayoutData();
696 AppendLayoutData( *mpSubEdit
);
697 mpSubEdit
->SetLayoutDataParent( this );
698 Control
* pMainWindow
= mpImplLB
->GetMainWindow();
702 if( mpFloatWin
->IsReallyVisible() )
704 AppendLayoutData( *pMainWindow
);
705 pMainWindow
->SetLayoutDataParent( this );
710 AppendLayoutData( *pMainWindow
);
711 pMainWindow
->SetLayoutDataParent( this );
715 // -----------------------------------------------------------------------
717 void ComboBox::StateChanged( StateChangedType nType
)
719 Edit::StateChanged( nType
);
721 if ( nType
== STATE_CHANGE_READONLY
)
723 mpImplLB
->SetReadOnly( IsReadOnly() );
725 mpBtn
->Enable( IsEnabled() && !IsReadOnly() );
727 else if ( nType
== STATE_CHANGE_ENABLE
)
729 mpSubEdit
->Enable( IsEnabled() );
730 mpImplLB
->Enable( IsEnabled() && !IsReadOnly() );
732 mpBtn
->Enable( IsEnabled() && !IsReadOnly() );
735 else if( nType
== STATE_CHANGE_UPDATEMODE
)
737 mpImplLB
->SetUpdateMode( IsUpdateMode() );
739 else if ( nType
== STATE_CHANGE_ZOOM
)
741 mpImplLB
->SetZoom( GetZoom() );
742 mpSubEdit
->SetZoom( GetZoom() );
743 ImplCalcEditHeight();
746 else if ( nType
== STATE_CHANGE_CONTROLFONT
)
748 mpImplLB
->SetControlFont( GetControlFont() );
749 mpSubEdit
->SetControlFont( GetControlFont() );
750 ImplCalcEditHeight();
753 else if ( nType
== STATE_CHANGE_CONTROLFOREGROUND
)
755 mpImplLB
->SetControlForeground( GetControlForeground() );
756 mpSubEdit
->SetControlForeground( GetControlForeground() );
758 else if ( nType
== STATE_CHANGE_CONTROLBACKGROUND
)
760 mpImplLB
->SetControlBackground( GetControlBackground() );
761 mpSubEdit
->SetControlBackground( GetControlBackground() );
763 else if ( nType
== STATE_CHANGE_STYLE
)
765 SetStyle( ImplInitStyle( GetStyle() ) );
766 mpImplLB
->GetMainWindow()->EnableSort( ( GetStyle() & WB_SORT
) ? TRUE
: FALSE
);
768 else if( nType
== STATE_CHANGE_MIRRORING
)
772 mpBtn
->EnableRTL( IsRTLEnabled() );
773 ImplInitDropDownButton( mpBtn
);
775 mpSubEdit
->StateChanged( STATE_CHANGE_MIRRORING
);
776 mpImplLB
->EnableRTL( IsRTLEnabled() );
781 // -----------------------------------------------------------------------
783 void ComboBox::DataChanged( const DataChangedEvent
& rDCEvt
)
785 Control::DataChanged( rDCEvt
);
787 if ( (rDCEvt
.GetType() == DATACHANGED_FONTS
) ||
788 (rDCEvt
.GetType() == DATACHANGED_FONTSUBSTITUTION
) ||
789 ((rDCEvt
.GetType() == DATACHANGED_SETTINGS
) &&
790 (rDCEvt
.GetFlags() & SETTINGS_STYLE
)) )
794 mpBtn
->SetSettings( GetSettings() );
795 ImplInitDropDownButton( mpBtn
);
798 mpImplLB
->Resize(); // Wird nicht durch ComboBox::Resize() gerufen, wenn sich die ImplLB nicht aendert.
799 SetBackground(); // due to a hack in Window::UpdateSettings the background must be reset
800 // otherwise it will overpaint NWF drawn comboboxes
804 // -----------------------------------------------------------------------
806 long ComboBox::PreNotify( NotifyEvent
& rNEvt
)
809 return Edit::PreNotify( rNEvt
);
812 // -----------------------------------------------------------------------
814 long ComboBox::Notify( NotifyEvent
& rNEvt
)
817 if( ( rNEvt
.GetType() == EVENT_KEYINPUT
) && ( rNEvt
.GetWindow() == mpSubEdit
)
820 KeyEvent aKeyEvt
= *rNEvt
.GetKeyEvent();
821 USHORT nKeyCode
= aKeyEvt
.GetKeyCode().GetCode();
829 ImplUpdateFloatSelection();
830 if( ( nKeyCode
== KEY_DOWN
) && mpFloatWin
&& !mpFloatWin
->IsInPopupMode() && aKeyEvt
.GetKeyCode().IsMod2() )
832 ImplCallEventListeners( VCLEVENT_DROPDOWN_PRE_OPEN
);
833 mpBtn
->SetPressed( TRUE
);
834 if ( mpImplLB
->GetEntryList()->GetMRUCount() )
835 mpImplLB
->SelectEntry( 0 , TRUE
);
836 SetSelection( Selection( 0, SELECTION_MAX
) );
837 mpFloatWin
->StartFloat( FALSE
);
838 ImplCallEventListeners( VCLEVENT_DROPDOWN_OPEN
);
841 else if( ( nKeyCode
== KEY_UP
) && mpFloatWin
&& mpFloatWin
->IsInPopupMode() && aKeyEvt
.GetKeyCode().IsMod2() )
843 mpFloatWin
->EndPopupMode();
848 nDone
= mpImplLB
->ProcessKeyInput( aKeyEvt
);
855 if( ( rNEvt
.GetWindow() == mpSubEdit
) && IsInDropDown() )
857 mpImplLB
->ProcessKeyInput( aKeyEvt
);
864 else if ( (rNEvt
.GetType() == EVENT_LOSEFOCUS
) && mpFloatWin
)
866 if( mpFloatWin
->HasChildPathFocus() )
867 mpSubEdit
->GrabFocus();
868 else if ( mpFloatWin
->IsInPopupMode() && !HasChildPathFocus( TRUE
) )
869 mpFloatWin
->EndPopupMode();
871 else if( (rNEvt
.GetType() == EVENT_COMMAND
) &&
872 (rNEvt
.GetCommandEvent()->GetCommand() == COMMAND_WHEEL
) &&
873 (rNEvt
.GetWindow() == mpSubEdit
) )
875 USHORT
nWheelBehavior( GetSettings().GetMouseSettings().GetWheelBehavior() );
876 if ( ( nWheelBehavior
== MOUSE_WHEEL_ALWAYS
)
877 || ( ( nWheelBehavior
== MOUSE_WHEEL_FOCUS_ONLY
)
878 && HasChildPathFocus()
882 nDone
= mpImplLB
->HandleWheelAsCursorTravel( *rNEvt
.GetCommandEvent() );
886 nDone
= 0; // don't eat this event, let the default handling happen (i.e. scroll the context)
889 else if( ( rNEvt
.GetType() == EVENT_MOUSEBUTTONDOWN
) && ( rNEvt
.GetWindow() == mpImplLB
->GetMainWindow() ) )
891 mpSubEdit
->GrabFocus();
894 return nDone
? nDone
: Edit::Notify( rNEvt
);
897 // -----------------------------------------------------------------------
899 void ComboBox::SetText( const XubString
& rStr
)
901 ImplCallEventListeners( VCLEVENT_COMBOBOX_SETTEXT
);
903 Edit::SetText( rStr
);
904 ImplUpdateFloatSelection();
907 // -----------------------------------------------------------------------
909 void ComboBox::SetText( const XubString
& rStr
, const Selection
& rNewSelection
)
911 ImplCallEventListeners( VCLEVENT_COMBOBOX_SETTEXT
);
913 Edit::SetText( rStr
, rNewSelection
);
914 ImplUpdateFloatSelection();
917 // -----------------------------------------------------------------------
919 void ComboBox::Modify()
921 if ( !mbSyntheticModify
)
922 ImplUpdateFloatSelection();
927 // -----------------------------------------------------------------------
929 void ComboBox::ImplUpdateFloatSelection()
931 // Text in der ListBox in den sichtbaren Bereich bringen
932 mpImplLB
->SetCallSelectionChangedHdl( FALSE
);
933 if ( !IsMultiSelectionEnabled() )
935 XubString
aSearchStr( mpSubEdit
->GetText() );
936 USHORT nSelect
= LISTBOX_ENTRY_NOTFOUND
;
939 if ( mpImplLB
->GetCurrentPos() != LISTBOX_ENTRY_NOTFOUND
)
941 XubString aCurrent
= mpImplLB
->GetEntryList()->GetEntryText( mpImplLB
->GetCurrentPos() );
942 if ( aCurrent
== aSearchStr
)
943 nSelect
= mpImplLB
->GetCurrentPos();
946 if ( nSelect
== LISTBOX_ENTRY_NOTFOUND
)
947 nSelect
= mpImplLB
->GetEntryList()->FindEntry( aSearchStr
);
948 if ( nSelect
== LISTBOX_ENTRY_NOTFOUND
)
950 nSelect
= mpImplLB
->GetEntryList()->FindMatchingEntry( aSearchStr
);
954 if( nSelect
!= LISTBOX_ENTRY_NOTFOUND
)
956 if ( !mpImplLB
->IsVisible( nSelect
) )
957 mpImplLB
->SetTopEntry( nSelect
);
958 mpImplLB
->SelectEntry( nSelect
, bSelect
);
962 nSelect
= mpImplLB
->GetEntryList()->GetSelectEntryPos( 0 );
963 if( nSelect
!= LISTBOX_ENTRY_NOTFOUND
)
964 mpImplLB
->SelectEntry( nSelect
, FALSE
);
965 // mpImplLB->SetTopEntry( 0 ); #92555# Ugly....
966 mpImplLB
->ResetCurrentPos();
972 lcl_GetSelectedEntries( aSelInText
, mpSubEdit
->GetText(), mcMultiSep
, mpImplLB
->GetEntryList() );
973 for ( USHORT n
= 0; n
< mpImplLB
->GetEntryList()->GetEntryCount(); n
++ )
974 mpImplLB
->SelectEntry( n
, aSelInText
.IsKeyValid( ImplCreateKey( n
) ) );
976 mpImplLB
->SetCallSelectionChangedHdl( TRUE
);
979 // -----------------------------------------------------------------------
981 USHORT
ComboBox::InsertEntry( const XubString
& rStr
, USHORT nPos
)
983 USHORT nRealPos
= mpImplLB
->InsertEntry( nPos
+ mpImplLB
->GetEntryList()->GetMRUCount(), rStr
);
984 nRealPos
= sal::static_int_cast
<USHORT
>(nRealPos
- mpImplLB
->GetEntryList()->GetMRUCount());
985 CallEventListeners( VCLEVENT_COMBOBOX_ITEMADDED
, (void*) sal_IntPtr(nRealPos
) );
989 // -----------------------------------------------------------------------
991 USHORT
ComboBox::InsertEntry( const XubString
& rStr
, const Image
& rImage
, USHORT nPos
)
993 USHORT nRealPos
= mpImplLB
->InsertEntry( nPos
+ mpImplLB
->GetEntryList()->GetMRUCount(), rStr
, rImage
);
994 nRealPos
= sal::static_int_cast
<USHORT
>(nRealPos
- mpImplLB
->GetEntryList()->GetMRUCount());
995 CallEventListeners( VCLEVENT_COMBOBOX_ITEMADDED
, (void*) sal_IntPtr(nRealPos
) );
999 // -----------------------------------------------------------------------
1001 void ComboBox::RemoveEntry( const XubString
& rStr
)
1003 RemoveEntry( GetEntryPos( rStr
) );
1006 // -----------------------------------------------------------------------
1008 void ComboBox::RemoveEntry( USHORT nPos
)
1010 mpImplLB
->RemoveEntry( nPos
+ mpImplLB
->GetEntryList()->GetMRUCount() );
1011 CallEventListeners( VCLEVENT_COMBOBOX_ITEMREMOVED
, (void*) sal_IntPtr(nPos
) );
1014 // -----------------------------------------------------------------------
1016 void ComboBox::Clear()
1019 CallEventListeners( VCLEVENT_COMBOBOX_ITEMREMOVED
, (void*) sal_IntPtr(-1) );
1022 // -----------------------------------------------------------------------
1024 USHORT
ComboBox::GetEntryPos( const XubString
& rStr
) const
1026 USHORT nPos
= mpImplLB
->GetEntryList()->FindEntry( rStr
);
1027 if ( nPos
!= LISTBOX_ENTRY_NOTFOUND
)
1028 nPos
= sal::static_int_cast
<USHORT
>(nPos
- mpImplLB
->GetEntryList()->GetMRUCount());
1032 // -----------------------------------------------------------------------
1034 USHORT
ComboBox::GetEntryPos( const void* pData
) const
1036 USHORT nPos
= mpImplLB
->GetEntryList()->FindEntry( pData
);
1037 if ( nPos
!= LISTBOX_ENTRY_NOTFOUND
)
1038 nPos
= sal::static_int_cast
<USHORT
>(nPos
- mpImplLB
->GetEntryList()->GetMRUCount());
1042 // -----------------------------------------------------------------------
1044 XubString
ComboBox::GetEntry( USHORT nPos
) const
1046 return mpImplLB
->GetEntryList()->GetEntryText( nPos
+ mpImplLB
->GetEntryList()->GetMRUCount() );
1049 // -----------------------------------------------------------------------
1051 USHORT
ComboBox::GetEntryCount() const
1053 return mpImplLB
->GetEntryList()->GetEntryCount() - mpImplLB
->GetEntryList()->GetMRUCount();
1056 // -----------------------------------------------------------------------
1058 BOOL
ComboBox::IsTravelSelect() const
1060 return mpImplLB
->IsTravelSelect();
1063 // -----------------------------------------------------------------------
1065 BOOL
ComboBox::IsInDropDown() const
1067 return mpFloatWin
&& mpFloatWin
->IsInPopupMode();
1070 // -----------------------------------------------------------------------
1072 void ComboBox::EnableMultiSelection( BOOL bMulti
)
1074 mpImplLB
->EnableMultiSelection( bMulti
, FALSE
);
1075 mpImplLB
->SetMultiSelectionSimpleMode( TRUE
);
1078 // -----------------------------------------------------------------------
1080 BOOL
ComboBox::IsMultiSelectionEnabled() const
1082 return mpImplLB
->IsMultiSelectionEnabled();
1085 // -----------------------------------------------------------------------
1087 long ComboBox::CalcWindowSizePixel( USHORT nLines
) const
1089 return mpImplLB
->GetEntryHeight() * nLines
;
1092 // -----------------------------------------------------------------------
1094 Size
ComboBox::GetOptimalSize(WindowSizeType eType
) const
1097 case WINDOWSIZE_MINIMUM
:
1098 return CalcMinimumSize();
1100 return Edit::GetOptimalSize( eType
);
1104 // -----------------------------------------------------------------------
1106 Size
ComboBox::CalcMinimumSize() const
1109 if ( !IsDropDownBox() )
1111 aSz
= mpImplLB
->CalcSize( mpImplLB
->GetEntryList()->GetEntryCount() );
1112 aSz
.Height() += mnDDHeight
;
1116 aSz
.Height() = mpImplLB
->CalcSize( 1 ).Height();
1117 aSz
.Width() = mpImplLB
->GetMaxEntryWidth();
1118 aSz
.Width() += GetSettings().GetStyleSettings().GetScrollBarSize();
1121 aSz
= CalcWindowSize( aSz
);
1125 // -----------------------------------------------------------------------
1127 Size
ComboBox::CalcAdjustedSize( const Size
& rPrefSize
) const
1129 Size aSz
= rPrefSize
;
1130 sal_Int32 nLeft
, nTop
, nRight
, nBottom
;
1131 ((Window
*)this)->GetBorder( nLeft
, nTop
, nRight
, nBottom
);
1132 aSz
.Height() -= nTop
+nBottom
;
1133 if ( !IsDropDownBox() )
1135 long nEntryHeight
= CalcSize( 1, 1 ).Height();
1136 long nLines
= aSz
.Height() / nEntryHeight
;
1139 aSz
.Height() = nLines
* nEntryHeight
;
1140 aSz
.Height() += mnDDHeight
;
1144 aSz
.Height() = mnDDHeight
;
1146 aSz
.Height() += nTop
+nBottom
;
1148 aSz
= CalcWindowSize( aSz
);
1152 // -----------------------------------------------------------------------
1154 Size
ComboBox::CalcSize( USHORT nColumns
, USHORT nLines
) const
1156 // ggf. werden ScrollBars eingeblendet
1157 Size aMinSz
= CalcMinimumSize();
1163 if ( !IsDropDownBox() )
1164 aSz
.Height() = mpImplLB
->CalcSize( nLines
).Height() + mnDDHeight
;
1166 aSz
.Height() = mnDDHeight
;
1169 aSz
.Height() = aMinSz
.Height();
1173 aSz
.Width() = nColumns
* GetTextWidth( UniString( 'X' ) );
1175 aSz
.Width() = aMinSz
.Width();
1177 if ( IsDropDownBox() )
1178 aSz
.Width() += GetSettings().GetStyleSettings().GetScrollBarSize();
1180 if ( !IsDropDownBox() )
1182 if ( aSz
.Width() < aMinSz
.Width() )
1183 aSz
.Height() += GetSettings().GetStyleSettings().GetScrollBarSize();
1184 if ( aSz
.Height() < aMinSz
.Height() )
1185 aSz
.Width() += GetSettings().GetStyleSettings().GetScrollBarSize();
1188 aSz
= CalcWindowSize( aSz
);
1192 // -----------------------------------------------------------------------
1194 void ComboBox::GetMaxVisColumnsAndLines( USHORT
& rnCols
, USHORT
& rnLines
) const
1196 long nCharWidth
= GetTextWidth( UniString( 'x' ) );
1197 if ( !IsDropDownBox() )
1199 Size aOutSz
= mpImplLB
->GetMainWindow()->GetOutputSizePixel();
1200 rnCols
= (USHORT
)(aOutSz
.Width()/nCharWidth
);
1201 rnLines
= (USHORT
)(aOutSz
.Height()/mpImplLB
->GetEntryHeight());
1205 Size aOutSz
= mpSubEdit
->GetOutputSizePixel();
1206 rnCols
= (USHORT
)(aOutSz
.Width()/nCharWidth
);
1211 // -----------------------------------------------------------------------
1213 void ComboBox::Draw( OutputDevice
* pDev
, const Point
& rPos
, const Size
& rSize
, ULONG nFlags
)
1215 mpImplLB
->GetMainWindow()->ImplInitSettings( TRUE
, TRUE
, TRUE
);
1217 Point aPos
= pDev
->LogicToPixel( rPos
);
1218 Size aSize
= pDev
->LogicToPixel( rSize
);
1219 Font aFont
= mpImplLB
->GetMainWindow()->GetDrawPixelFont( pDev
);
1220 OutDevType eOutDevType
= pDev
->GetOutDevType();
1224 pDev
->SetFont( aFont
);
1225 pDev
->SetTextFillColor();
1227 // Border/Background
1228 pDev
->SetLineColor();
1229 pDev
->SetFillColor();
1230 BOOL bBorder
= !(nFlags
& WINDOW_DRAW_NOBORDER
) && (GetStyle() & WB_BORDER
);
1231 BOOL bBackground
= !(nFlags
& WINDOW_DRAW_NOBACKGROUND
) && IsControlBackground();
1232 if ( bBorder
|| bBackground
)
1234 Rectangle
aRect( aPos
, aSize
);
1235 // aRect.Top() += nEditHeight;
1238 ImplDrawFrame( pDev
, aRect
);
1242 pDev
->SetFillColor( GetControlBackground() );
1243 pDev
->DrawRect( aRect
);
1248 if ( !IsDropDownBox() )
1250 long nOnePixel
= GetDrawPixel( pDev
, 1 );
1251 long nTextHeight
= pDev
->GetTextHeight();
1252 long nEditHeight
= nTextHeight
+ 6*nOnePixel
;
1253 USHORT nTextStyle
= TEXT_DRAW_VCENTER
;
1255 // First, draw the edit part
1256 mpSubEdit
->Draw( pDev
, aPos
, Size( aSize
.Width(), nEditHeight
), nFlags
);
1258 // Second, draw the listbox
1259 if ( GetStyle() & WB_CENTER
)
1260 nTextStyle
|= TEXT_DRAW_CENTER
;
1261 else if ( GetStyle() & WB_RIGHT
)
1262 nTextStyle
|= TEXT_DRAW_RIGHT
;
1264 nTextStyle
|= TEXT_DRAW_LEFT
;
1266 if ( ( nFlags
& WINDOW_DRAW_MONO
) || ( eOutDevType
== OUTDEV_PRINTER
) )
1268 pDev
->SetTextColor( Color( COL_BLACK
) );
1272 if ( !(nFlags
& WINDOW_DRAW_NODISABLE
) && !IsEnabled() )
1274 const StyleSettings
& rStyleSettings
= GetSettings().GetStyleSettings();
1275 pDev
->SetTextColor( rStyleSettings
.GetDisableColor() );
1279 pDev
->SetTextColor( GetTextColor() );
1283 Rectangle
aClip( aPos
, aSize
);
1284 pDev
->IntersectClipRegion( aClip
);
1285 USHORT nLines
= (USHORT
) ( (aSize
.Height()-nEditHeight
) / nTextHeight
);
1288 USHORT nTEntry
= IsReallyVisible() ? mpImplLB
->GetTopEntry() : 0;
1290 Rectangle
aTextRect( aPos
, aSize
);
1292 aTextRect
.Left() += 3*nOnePixel
;
1293 aTextRect
.Right() -= 3*nOnePixel
;
1294 aTextRect
.Top() += nEditHeight
+ nOnePixel
;
1295 aTextRect
.Bottom() = aTextRect
.Top() + nTextHeight
;
1297 // the drawing starts here
1298 for ( USHORT n
= 0; n
< nLines
; n
++ )
1300 pDev
->DrawText( aTextRect
, mpImplLB
->GetEntryList()->GetEntryText( n
+nTEntry
), nTextStyle
);
1301 aTextRect
.Top() += nTextHeight
;
1302 aTextRect
.Bottom() += nTextHeight
;
1308 // Call Edit::Draw after restoring the MapMode...
1309 if ( IsDropDownBox() )
1311 mpSubEdit
->Draw( pDev
, rPos
, rSize
, nFlags
);
1317 // -----------------------------------------------------------------------
1319 IMPL_LINK( ComboBox
, ImplUserDrawHdl
, UserDrawEvent
*, pEvent
)
1321 UserDraw( *pEvent
);
1325 // -----------------------------------------------------------------------
1327 void ComboBox::UserDraw( const UserDrawEvent
& )
1331 // -----------------------------------------------------------------------
1333 void ComboBox::SetUserItemSize( const Size
& rSz
)
1335 mpImplLB
->GetMainWindow()->SetUserItemSize( rSz
);
1338 // -----------------------------------------------------------------------
1340 const Size
& ComboBox::GetUserItemSize() const
1342 return mpImplLB
->GetMainWindow()->GetUserItemSize();
1345 // -----------------------------------------------------------------------
1347 void ComboBox::EnableUserDraw( BOOL bUserDraw
)
1349 mpImplLB
->GetMainWindow()->EnableUserDraw( bUserDraw
);
1352 // -----------------------------------------------------------------------
1354 BOOL
ComboBox::IsUserDrawEnabled() const
1356 return mpImplLB
->GetMainWindow()->IsUserDrawEnabled();
1359 // -----------------------------------------------------------------------
1361 void ComboBox::DrawEntry( const UserDrawEvent
& rEvt
, BOOL bDrawImage
, BOOL bDrawText
, BOOL bDrawTextAtImagePos
)
1363 DBG_ASSERT( rEvt
.GetDevice() == mpImplLB
->GetMainWindow(), "DrawEntry?!" );
1364 mpImplLB
->GetMainWindow()->DrawEntry( rEvt
.GetItemId(), bDrawImage
, bDrawText
, bDrawTextAtImagePos
);
1367 // -----------------------------------------------------------------------
1369 void ComboBox::SetSeparatorPos( USHORT n
)
1371 mpImplLB
->SetSeparatorPos( n
);
1374 // -----------------------------------------------------------------------
1376 void ComboBox::SetSeparatorPos()
1378 mpImplLB
->SetSeparatorPos( LISTBOX_ENTRY_NOTFOUND
);
1381 // -----------------------------------------------------------------------
1383 USHORT
ComboBox::GetSeparatorPos() const
1385 return mpImplLB
->GetSeparatorPos();
1388 // -----------------------------------------------------------------------
1390 void ComboBox::SetMRUEntries( const XubString
& rEntries
, xub_Unicode cSep
)
1392 mpImplLB
->SetMRUEntries( rEntries
, cSep
);
1395 // -----------------------------------------------------------------------
1397 XubString
ComboBox::GetMRUEntries( xub_Unicode cSep
) const
1399 return mpImplLB
->GetMRUEntries( cSep
);
1402 // -----------------------------------------------------------------------
1404 void ComboBox::SetMaxMRUCount( USHORT n
)
1406 mpImplLB
->SetMaxMRUCount( n
);
1409 // -----------------------------------------------------------------------
1411 USHORT
ComboBox::GetMaxMRUCount() const
1413 return mpImplLB
->GetMaxMRUCount();
1416 // -----------------------------------------------------------------------
1418 USHORT
ComboBox::GetDisplayLineCount() const
1420 return mpImplLB
->GetDisplayLineCount();
1423 // -----------------------------------------------------------------------
1425 void ComboBox::SetEntryData( USHORT nPos
, void* pNewData
)
1427 mpImplLB
->SetEntryData( nPos
+ mpImplLB
->GetEntryList()->GetMRUCount(), pNewData
);
1430 // -----------------------------------------------------------------------
1432 void* ComboBox::GetEntryData( USHORT nPos
) const
1434 return mpImplLB
->GetEntryList()->GetEntryData( nPos
+ mpImplLB
->GetEntryList()->GetMRUCount() );
1437 // -----------------------------------------------------------------------
1439 void ComboBox::SetTopEntry( USHORT nPos
)
1441 mpImplLB
->SetTopEntry( nPos
+ mpImplLB
->GetEntryList()->GetMRUCount() );
1444 // -----------------------------------------------------------------------
1446 USHORT
ComboBox::GetTopEntry() const
1448 USHORT nPos
= GetEntryCount() ? mpImplLB
->GetTopEntry() : LISTBOX_ENTRY_NOTFOUND
;
1449 if ( nPos
< mpImplLB
->GetEntryList()->GetMRUCount() )
1454 // -----------------------------------------------------------------------
1456 Rectangle
ComboBox::GetDropDownPosSizePixel() const
1458 return mpFloatWin
? mpFloatWin
->GetWindowExtentsRelative( const_cast<ComboBox
*>(this) ) : Rectangle();
1461 // -----------------------------------------------------------------------
1463 Rectangle
ComboBox::GetListPosSizePixel() const
1465 return mpFloatWin
? Rectangle() : mpImplLB
->GetMainWindow()->GetWindowExtentsRelative( const_cast<ComboBox
*>(this) );
1468 // -----------------------------------------------------------------------
1470 const Wallpaper
& ComboBox::GetDisplayBackground() const
1472 if( ! mpSubEdit
->IsBackground() )
1473 return Control::GetDisplayBackground();
1475 const Wallpaper
& rBack
= mpSubEdit
->GetBackground();
1476 if( ! rBack
.IsBitmap() &&
1477 ! rBack
.IsGradient() &&
1478 rBack
.GetColor().GetColor() == COL_TRANSPARENT
1480 return Control::GetDisplayBackground();
1483 // -----------------------------------------------------------------------------
1484 USHORT
ComboBox::GetSelectEntryCount() const
1486 return mpImplLB
->GetEntryList()->GetSelectEntryCount();
1488 // -----------------------------------------------------------------------------
1489 USHORT
ComboBox::GetSelectEntryPos( USHORT nIndex
) const
1491 USHORT nPos
= mpImplLB
->GetEntryList()->GetSelectEntryPos( nIndex
);
1492 if ( nPos
!= LISTBOX_ENTRY_NOTFOUND
)
1494 if ( nPos
< mpImplLB
->GetEntryList()->GetMRUCount() )
1495 nPos
= mpImplLB
->GetEntryList()->FindEntry( mpImplLB
->GetEntryList()->GetEntryText( nPos
) );
1496 nPos
= sal::static_int_cast
<USHORT
>(nPos
- mpImplLB
->GetEntryList()->GetMRUCount());
1500 // -----------------------------------------------------------------------------
1501 BOOL
ComboBox::IsEntryPosSelected( USHORT nPos
) const
1503 return mpImplLB
->GetEntryList()->IsEntryPosSelected( nPos
+ mpImplLB
->GetEntryList()->GetMRUCount() );
1505 // -----------------------------------------------------------------------------
1506 void ComboBox::SelectEntryPos( USHORT nPos
, BOOL bSelect
)
1508 if ( nPos
< mpImplLB
->GetEntryList()->GetEntryCount() )
1509 mpImplLB
->SelectEntry( nPos
+ mpImplLB
->GetEntryList()->GetMRUCount(), bSelect
);
1511 // -----------------------------------------------------------------------------
1512 void ComboBox::SetNoSelection()
1514 mpImplLB
->SetNoSelection();
1515 mpSubEdit
->SetText( String() );
1517 // -----------------------------------------------------------------------------
1518 Rectangle
ComboBox::GetBoundingRectangle( USHORT nItem
) const
1520 Rectangle aRect
= mpImplLB
->GetMainWindow()->GetBoundingRectangle( nItem
);
1521 Rectangle aOffset
= mpImplLB
->GetMainWindow()->GetWindowExtentsRelative( (Window
*)this );
1522 aRect
.Move( aOffset
.TopLeft().X(), aOffset
.TopLeft().Y() );
1525 // -----------------------------------------------------------------------------
1527 void ComboBox::SetBorderStyle( USHORT nBorderStyle
)
1529 Window::SetBorderStyle( nBorderStyle
);
1530 if ( !IsDropDownBox() )
1532 mpSubEdit
->SetBorderStyle( nBorderStyle
);
1533 mpImplLB
->SetBorderStyle( nBorderStyle
);
1536 // -----------------------------------------------------------------------------
1538 long ComboBox::GetIndexForPoint( const Point
& rPoint
, USHORT
& rPos
) const
1540 if( ! mpLayoutData
)
1543 // check whether rPoint fits at all
1544 long nIndex
= Control::GetIndexForPoint( rPoint
);
1547 // point must be either in main list window
1548 // or in impl window (dropdown case)
1549 ImplListBoxWindow
* pMain
= mpImplLB
->GetMainWindow();
1551 // convert coordinates to ImplListBoxWindow pixel coordinate space
1552 Point aConvPoint
= LogicToPixel( rPoint
);
1553 aConvPoint
= OutputToAbsoluteScreenPixel( aConvPoint
);
1554 aConvPoint
= pMain
->AbsoluteScreenToOutputPixel( aConvPoint
);
1555 aConvPoint
= pMain
->PixelToLogic( aConvPoint
);
1557 // try to find entry
1558 USHORT nEntry
= pMain
->GetEntryPosForPoint( aConvPoint
);
1559 if( nEntry
== LISTBOX_ENTRY_NOTFOUND
)
1565 // get line relative index
1567 nIndex
= ToRelativeLineIndex( nIndex
);