1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
3 * This file is part of the LibreOffice project.
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/.
9 * This file incorporates work covered by the following license notice:
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 .
21 #include "tools/debug.hxx"
23 #include <vcl/decoview.hxx>
24 #include <vcl/dialog.hxx>
25 #include <vcl/event.hxx>
26 #include <vcl/scrbar.hxx>
27 #include <vcl/button.hxx>
28 #include <vcl/edit.hxx>
29 #include <vcl/lstbox.hxx>
30 #include <vcl/combobox.hxx>
31 #include <vcl/settings.hxx>
32 #include <vcl/uitest/uiobject.hxx>
35 #include "controldata.hxx"
36 #include "listbox.hxx"
37 #include "dndeventdispatcher.hxx"
39 #include <com/sun/star/datatransfer/dnd/XDropTarget.hpp>
41 void ListBox::EnableQuickSelection( bool b
)
43 mpImplLB
->GetMainWindow()->EnableQuickSelection(b
);
46 ListBox::ListBox(WindowType nType
)
50 ImplInitListBoxData();
53 ListBox::ListBox( vcl::Window
* pParent
, WinBits nStyle
) : Control( WINDOW_LISTBOX
)
55 ImplInitListBoxData();
56 ImplInit( pParent
, nStyle
);
64 void ListBox::dispose()
66 CallEventListeners( VCLEVENT_OBJECT_DYING
);
68 mpImplLB
.disposeAndClear();
69 mpFloatWin
.disposeAndClear();
70 mpImplWin
.disposeAndClear();
71 mpBtn
.disposeAndClear();
76 void ListBox::ImplInitListBoxData()
82 mnSaveValue
= LISTBOX_ENTRY_NOTFOUND
;
84 m_nMaxWidthChars
= -1;
86 mbEdgeBlending
= false;
89 void ListBox::ImplInit( vcl::Window
* pParent
, WinBits nStyle
)
91 nStyle
= ImplInitStyle( nStyle
);
92 if ( !(nStyle
& WB_NOBORDER
) && ( nStyle
& WB_DROPDOWN
) )
95 Control::ImplInit( pParent
, nStyle
, nullptr );
97 css::uno::Reference
< css::datatransfer::dnd::XDropTargetListener
> xDrop
= new DNDEventDispatcher(this);
99 if( nStyle
& WB_DROPDOWN
)
101 sal_Int32 nLeft
, nTop
, nRight
, nBottom
;
102 GetBorder( nLeft
, nTop
, nRight
, nBottom
);
103 mnDDHeight
= (sal_uInt16
)(GetTextHeight() + nTop
+ nBottom
+ 4);
105 if( IsNativeWidgetEnabled() &&
106 IsNativeControlSupported( ControlType::Listbox
, ControlPart::Entire
) )
108 ImplControlValue aControlValue
;
109 Rectangle
aCtrlRegion( Point( 0, 0 ), Size( 20, mnDDHeight
) );
110 Rectangle
aBoundingRgn( aCtrlRegion
);
111 Rectangle
aContentRgn( aCtrlRegion
);
112 if( GetNativeControlRegion( ControlType::Listbox
, ControlPart::Entire
, aCtrlRegion
,
113 ControlState::ENABLED
, aControlValue
, OUString(),
114 aBoundingRgn
, aContentRgn
) )
116 sal_Int32 nHeight
= aBoundingRgn
.GetHeight();
117 if( nHeight
> mnDDHeight
)
118 mnDDHeight
= static_cast<sal_uInt16
>(nHeight
);
122 mpFloatWin
= VclPtr
<ImplListBoxFloatingWindow
>::Create( this );
123 mpFloatWin
->SetAutoWidth( true );
124 mpFloatWin
->SetPopupModeEndHdl( LINK( this, ListBox
, ImplPopupModeEndHdl
) );
125 mpFloatWin
->GetDropTarget()->addDropTargetListener(xDrop
);
127 mpImplWin
= VclPtr
<ImplWin
>::Create( this, (nStyle
& (WB_LEFT
|WB_RIGHT
|WB_CENTER
))|WB_NOBORDER
);
128 mpImplWin
->SetMBDownHdl( LINK( this, ListBox
, ImplClickBtnHdl
) );
129 mpImplWin
->SetUserDrawHdl( LINK( this, ListBox
, ImplUserDrawHdl
) );
131 mpImplWin
->GetDropTarget()->addDropTargetListener(xDrop
);
132 mpImplWin
->SetEdgeBlending(GetEdgeBlending());
134 mpBtn
= VclPtr
<ImplBtn
>::Create( this, WB_NOLIGHTBORDER
| WB_RECTSTYLE
);
135 ImplInitDropDownButton( mpBtn
);
136 mpBtn
->SetMBDownHdl( LINK( this, ListBox
, ImplClickBtnHdl
) );
138 mpBtn
->GetDropTarget()->addDropTargetListener(xDrop
);
141 vcl::Window
* pLBParent
= this;
143 pLBParent
= mpFloatWin
;
144 mpImplLB
= VclPtr
<ImplListBox
>::Create( pLBParent
, nStyle
&(~WB_BORDER
) );
145 mpImplLB
->SetSelectHdl( LINK( this, ListBox
, ImplSelectHdl
) );
146 mpImplLB
->SetScrollHdl( LINK( this, ListBox
, ImplScrollHdl
) );
147 mpImplLB
->SetCancelHdl( LINK( this, ListBox
, ImplCancelHdl
) );
148 mpImplLB
->SetDoubleClickHdl( LINK( this, ListBox
, ImplDoubleClickHdl
) );
149 mpImplLB
->SetUserDrawHdl( LINK( this, ListBox
, ImplUserDrawHdl
) );
150 mpImplLB
->SetFocusHdl( LINK( this, ListBox
, ImplFocusHdl
) );
151 mpImplLB
->SetListItemSelectHdl( LINK( this, ListBox
, ImplListItemSelectHdl
) );
152 mpImplLB
->SetPosPixel( Point() );
153 mpImplLB
->SetEdgeBlending(GetEdgeBlending());
156 mpImplLB
->GetDropTarget()->addDropTargetListener(xDrop
);
157 mpImplLB
->SetDropTraget(xDrop
);
161 mpFloatWin
->SetImplListBox( mpImplLB
);
162 mpImplLB
->SetSelectionChangedHdl( LINK( this, ListBox
, ImplSelectionChangedHdl
) );
165 mpImplLB
->GetMainWindow()->AllowGrabFocus( true );
167 SetCompoundControl( true );
170 WinBits
ListBox::ImplInitStyle( WinBits nStyle
)
172 if ( !(nStyle
& WB_NOTABSTOP
) )
173 nStyle
|= WB_TABSTOP
;
174 if ( !(nStyle
& WB_NOGROUP
) )
179 IMPL_LINK_NOARG(ListBox
, ImplSelectHdl
, LinkParamNone
*, void)
181 bool bPopup
= IsInDropDown();
182 if( IsDropDownBox() )
184 if( !mpImplLB
->IsTravelSelect() )
186 mpFloatWin
->EndPopupMode();
187 mpImplWin
->GrabFocus();
190 mpImplWin
->SetItemPos( GetSelectEntryPos() );
191 mpImplWin
->SetString( GetSelectEntry() );
192 if( mpImplLB
->GetEntryList()->HasImages() )
194 Image aImage
= mpImplLB
->GetEntryList()->GetEntryImage( GetSelectEntryPos() );
195 mpImplWin
->SetImage( aImage
);
197 mpImplWin
->Invalidate();
200 if ( ( !IsTravelSelect() || mpImplLB
->IsSelectionChanged() ) || ( bPopup
&& !IsMultiSelectionEnabled() ) )
204 IMPL_LINK( ListBox
, ImplFocusHdl
, sal_Int32
, nPos
, void )
206 CallEventListeners( VCLEVENT_LISTBOX_FOCUS
, reinterpret_cast<void*>(nPos
) );
209 IMPL_LINK_NOARG( ListBox
, ImplListItemSelectHdl
, LinkParamNone
*, void )
211 CallEventListeners( VCLEVENT_DROPDOWN_SELECT
);
214 IMPL_LINK_NOARG(ListBox
, ImplScrollHdl
, ImplListBox
*, void)
216 CallEventListeners( VCLEVENT_LISTBOX_SCROLLED
);
219 IMPL_LINK_NOARG(ListBox
, ImplCancelHdl
, LinkParamNone
*, void)
222 mpFloatWin
->EndPopupMode();
225 IMPL_LINK( ListBox
, ImplSelectionChangedHdl
, sal_Int32
, nChanged
, void )
227 if ( !mpImplLB
->IsTrackingSelect() )
229 const ImplEntryList
* pEntryList
= mpImplLB
->GetEntryList();
230 if ( pEntryList
->IsEntryPosSelected( nChanged
) )
232 // FIXME? This should've been turned into an ImplPaintEntry some time ago...
233 if ( nChanged
< pEntryList
->GetMRUCount() )
234 nChanged
= pEntryList
->FindEntry( pEntryList
->GetEntryText( nChanged
) );
235 mpImplWin
->SetItemPos( nChanged
);
236 mpImplWin
->SetString( mpImplLB
->GetEntryList()->GetEntryText( nChanged
) );
237 if( mpImplLB
->GetEntryList()->HasImages() )
239 Image aImage
= mpImplLB
->GetEntryList()->GetEntryImage( nChanged
);
240 mpImplWin
->SetImage( aImage
);
245 mpImplWin
->SetItemPos( LISTBOX_ENTRY_NOTFOUND
);
246 mpImplWin
->SetString( OUString() );
248 mpImplWin
->SetImage( aImage
);
250 mpImplWin
->Invalidate();
254 IMPL_LINK_NOARG(ListBox
, ImplDoubleClickHdl
, ImplListBoxWindow
*, void)
259 IMPL_LINK_NOARG(ListBox
, ImplClickBtnHdl
, void*, void)
261 if( !mpFloatWin
->IsInPopupMode() )
263 CallEventListeners( VCLEVENT_DROPDOWN_PRE_OPEN
);
264 mpImplWin
->GrabFocus();
265 mpBtn
->SetPressed( true );
266 mpFloatWin
->StartFloat( true );
267 CallEventListeners( VCLEVENT_DROPDOWN_OPEN
);
269 ImplClearLayoutData();
271 mpImplLB
->GetMainWindow()->ImplClearLayoutData();
273 mpImplWin
->ImplClearLayoutData();
277 IMPL_LINK_NOARG(ListBox
, ImplPopupModeEndHdl
, FloatingWindow
*, void)
279 if( mpFloatWin
->IsPopupModeCanceled() )
281 if ( ( mpFloatWin
->GetPopupModeStartSaveSelection() != LISTBOX_ENTRY_NOTFOUND
)
282 && !IsEntryPosSelected( mpFloatWin
->GetPopupModeStartSaveSelection() ) )
284 mpImplLB
->SelectEntry( mpFloatWin
->GetPopupModeStartSaveSelection(), true );
285 bool bTravelSelect
= mpImplLB
->IsTravelSelect();
286 mpImplLB
->SetTravelSelect( true );
288 VclPtr
<vcl::Window
> xWindow
= this;
290 if ( xWindow
->IsDisposed() )
293 mpImplLB
->SetTravelSelect( bTravelSelect
);
297 ImplClearLayoutData();
299 mpImplLB
->GetMainWindow()->ImplClearLayoutData();
301 mpImplWin
->ImplClearLayoutData();
303 mpBtn
->SetPressed( false );
304 CallEventListeners( VCLEVENT_DROPDOWN_CLOSE
);
307 void ListBox::ToggleDropDown()
309 if( IsDropDownBox() )
311 if( mpFloatWin
->IsInPopupMode() )
312 mpFloatWin
->EndPopupMode();
315 CallEventListeners( VCLEVENT_DROPDOWN_PRE_OPEN
);
316 mpImplWin
->GrabFocus();
317 mpBtn
->SetPressed( true );
318 mpFloatWin
->StartFloat( true );
319 CallEventListeners( VCLEVENT_DROPDOWN_OPEN
);
324 void ListBox::ApplySettings(vcl::RenderContext
& rRenderContext
)
326 rRenderContext
.SetBackground();
329 void ListBox::Draw( OutputDevice
* pDev
, const Point
& rPos
, const Size
& rSize
, DrawFlags nFlags
)
331 mpImplLB
->GetMainWindow()->ApplySettings(*pDev
);
333 Point aPos
= pDev
->LogicToPixel( rPos
);
334 Size aSize
= pDev
->LogicToPixel( rSize
);
335 vcl::Font aFont
= mpImplLB
->GetMainWindow()->GetDrawPixelFont( pDev
);
336 OutDevType eOutDevType
= pDev
->GetOutDevType();
340 pDev
->SetFont( aFont
);
341 pDev
->SetTextFillColor();
344 pDev
->SetLineColor();
345 pDev
->SetFillColor();
346 bool bBorder
= !(nFlags
& DrawFlags::NoBorder
) && (GetStyle() & WB_BORDER
);
347 bool bBackground
= !(nFlags
& DrawFlags::NoBackground
) && IsControlBackground();
348 if ( bBorder
|| bBackground
)
350 Rectangle
aRect( aPos
, aSize
);
353 ImplDrawFrame( pDev
, aRect
);
357 pDev
->SetFillColor( GetControlBackground() );
358 pDev
->DrawRect( aRect
);
363 if ( ( nFlags
& DrawFlags::Mono
) || ( eOutDevType
== OUTDEV_PRINTER
) )
365 pDev
->SetTextColor( Color( COL_BLACK
) );
369 if ( !(nFlags
& DrawFlags::NoDisable
) && !IsEnabled() )
371 const StyleSettings
& rStyleSettings
= GetSettings().GetStyleSettings();
372 pDev
->SetTextColor( rStyleSettings
.GetDisableColor() );
376 pDev
->SetTextColor( GetTextColor() );
380 const long nOnePixel
= GetDrawPixel( pDev
, 1 );
381 const long nOffX
= 3*nOnePixel
;
382 DrawTextFlags nTextStyle
= DrawTextFlags::VCenter
;
383 Rectangle
aTextRect( aPos
, aSize
);
385 if ( GetStyle() & WB_CENTER
)
386 nTextStyle
|= DrawTextFlags::Center
;
387 else if ( GetStyle() & WB_RIGHT
)
388 nTextStyle
|= DrawTextFlags::Right
;
390 nTextStyle
|= DrawTextFlags::Left
;
392 aTextRect
.Left() += nOffX
;
393 aTextRect
.Right() -= nOffX
;
395 if ( IsDropDownBox() )
397 OUString aText
= GetSelectEntry();
398 long nTextHeight
= pDev
->GetTextHeight();
399 long nTextWidth
= pDev
->GetTextWidth( aText
);
400 long nOffY
= (aSize
.Height()-nTextHeight
) / 2;
404 ((nOffY
+nTextHeight
) > aSize
.Height()) ||
405 ((nOffX
+nTextWidth
) > aSize
.Width()) )
407 Rectangle
aClip( aPos
, aSize
);
408 if ( nTextHeight
> aSize
.Height() )
409 aClip
.Bottom() += nTextHeight
-aSize
.Height()+1; // So that HP Printers don't optimize this away
410 pDev
->IntersectClipRegion( aClip
);
413 pDev
->DrawText( aTextRect
, aText
, nTextStyle
);
417 long nTextHeight
= pDev
->GetTextHeight();
418 sal_uInt16 nLines
= ( nTextHeight
> 0 ) ? (sal_uInt16
)(aSize
.Height() / nTextHeight
) : 1;
419 Rectangle
aClip( aPos
, aSize
);
421 pDev
->IntersectClipRegion( aClip
);
426 for ( sal_uInt16 n
= 0; n
< nLines
; n
++ )
428 sal_Int32 nEntry
= n
+mpImplLB
->GetTopEntry();
429 bool bSelected
= mpImplLB
->GetEntryList()->IsEntryPosSelected( nEntry
);
432 pDev
->SetFillColor( COL_BLACK
);
433 pDev
->DrawRect( Rectangle( Point( aPos
.X(), aPos
.Y() + n
*nTextHeight
),
434 Point( aPos
.X() + aSize
.Width(), aPos
.Y() + (n
+1)*nTextHeight
+ 2*nOnePixel
) ) );
435 pDev
->SetFillColor();
436 pDev
->SetTextColor( COL_WHITE
);
439 aTextRect
.Top() = aPos
.Y() + n
*nTextHeight
;
440 aTextRect
.Bottom() = aTextRect
.Top() + nTextHeight
;
442 pDev
->DrawText( aTextRect
, mpImplLB
->GetEntryList()->GetEntryText( nEntry
), nTextStyle
);
445 pDev
->SetTextColor( COL_BLACK
);
452 void ListBox::GetFocus()
456 if( IsDropDownBox() )
457 mpImplWin
->GrabFocus();
459 mpImplLB
->GrabFocus();
465 void ListBox::LoseFocus()
467 if( IsDropDownBox() )
470 mpImplWin
->HideFocus();
475 mpImplLB
->HideFocus();
478 Control::LoseFocus();
481 void ListBox::DataChanged( const DataChangedEvent
& rDCEvt
)
483 Control::DataChanged( rDCEvt
);
485 if ( (rDCEvt
.GetType() == DataChangedEventType::FONTS
) ||
486 (rDCEvt
.GetType() == DataChangedEventType::FONTSUBSTITUTION
) ||
487 ((rDCEvt
.GetType() == DataChangedEventType::SETTINGS
) &&
488 (rDCEvt
.GetFlags() & AllSettingsFlags::STYLE
)) )
490 SetBackground(); // Due to a hack in Window::UpdateSettings the background must be reset
491 // otherwise it will overpaint NWF drawn listboxes
493 mpImplLB
->Resize(); // Is not called by ListBox::Resize() if the ImplLB does not change
497 mpImplWin
->SetSettings( GetSettings() ); // If not yet set...
498 mpImplWin
->ApplySettings(*mpImplWin
);
500 mpBtn
->SetSettings( GetSettings() );
501 ImplInitDropDownButton( mpBtn
);
504 if ( IsDropDownBox() )
509 void ListBox::EnableAutoSize( bool bAuto
)
511 mbDDAutoSize
= bAuto
;
514 if ( bAuto
&& !mpFloatWin
->GetDropDownLineCount() )
516 // use GetListBoxMaximumLineCount here; before, was on fixed number of five
517 AdaptDropDownLineCountToMaximum();
521 mpFloatWin
->SetDropDownLineCount( 0 );
526 void ListBox::EnableDDAutoWidth( bool b
)
529 mpFloatWin
->SetAutoWidth( b
);
532 void ListBox::SetDropDownLineCount( sal_uInt16 nLines
)
534 mnLineCount
= nLines
;
536 mpFloatWin
->SetDropDownLineCount( mnLineCount
);
539 void ListBox::AdaptDropDownLineCountToMaximum()
541 // adapt to maximum allowed number
542 SetDropDownLineCount(GetSettings().GetStyleSettings().GetListBoxMaximumLineCount());
545 sal_uInt16
ListBox::GetDropDownLineCount() const
548 return mpFloatWin
->GetDropDownLineCount();
552 void ListBox::setPosSizePixel( long nX
, long nY
, long nWidth
, long nHeight
, PosSizeFlags nFlags
)
554 if( IsDropDownBox() && ( nFlags
& PosSizeFlags::Size
) )
556 Size aPrefSz
= mpFloatWin
->GetPrefSize();
557 if ( ( nFlags
& PosSizeFlags::Height
) && ( nHeight
>= 2*mnDDHeight
) )
558 aPrefSz
.Height() = nHeight
-mnDDHeight
;
559 if ( nFlags
& PosSizeFlags::Width
)
560 aPrefSz
.Width() = nWidth
;
561 mpFloatWin
->SetPrefSize( aPrefSz
);
563 if (IsAutoSizeEnabled())
564 nHeight
= mnDDHeight
;
567 Control::setPosSizePixel( nX
, nY
, nWidth
, nHeight
, nFlags
);
570 void ListBox::Resize()
572 Size aOutSz
= GetOutputSizePixel();
573 if( IsDropDownBox() )
575 // Initialize the dropdown button size with the standard scrollbar width
576 long nSBWidth
= GetSettings().GetStyleSettings().GetScrollBarSize();
577 long nBottom
= aOutSz
.Height();
579 // Note: in case of no border, pBorder will actually be this
580 vcl::Window
*pBorder
= GetWindow( GetWindowType::Border
);
581 ImplControlValue aControlValue
;
583 Rectangle aContent
, aBound
;
585 // Use the full extent of the control
586 Rectangle
aArea( aPoint
, pBorder
->GetOutputSizePixel() );
588 if ( GetNativeControlRegion( ControlType::Listbox
, ControlPart::ButtonDown
,
589 aArea
, ControlState::NONE
, aControlValue
, OUString(), aBound
, aContent
) )
592 // Convert back from border space to local coordinates
593 aPoint
= pBorder
->ScreenToOutputPixel( OutputToScreenPixel( aPoint
) );
594 aContent
.Move( -aPoint
.X(), -aPoint
.Y() );
596 // Use the themes drop down size for the button
597 aOutSz
.Width() = aContent
.Left();
598 mpBtn
->setPosSizePixel( aContent
.Left(), nTop
, aContent
.Right(), (nBottom
-nTop
) );
600 // Adjust the size of the edit field
601 if ( GetNativeControlRegion( ControlType::Listbox
, ControlPart::SubEdit
,
602 aArea
, ControlState::NONE
, aControlValue
, OUString(), aBound
, aContent
) )
604 // Convert back from border space to local coordinates
605 aContent
.Move( -aPoint
.X(), -aPoint
.Y() );
607 // Use the themes drop down size
608 if( ! (GetStyle() & WB_BORDER
) && ImplGetSVData()->maNWFData
.mbNoFocusRects
)
610 // No border but focus ring behavior -> we have a problem; the
611 // native rect relies on the border to draw the focus
612 // let's do the best we can and center vertically, so it doesn't look
614 Size
aSz( GetOutputSizePixel() );
615 long nDiff
= aContent
.Top() - (aSz
.Height() - aContent
.GetHeight())/2;
616 aContent
.Top() -= nDiff
;
617 aContent
.Bottom() -= nDiff
;
619 mpImplWin
->SetPosSizePixel( aContent
.TopLeft(), aContent
.GetSize() );
622 mpImplWin
->SetSizePixel( aOutSz
);
626 nSBWidth
= CalcZoom( nSBWidth
);
627 mpImplWin
->setPosSizePixel( 0, 0, aOutSz
.Width() - nSBWidth
, aOutSz
.Height() );
628 mpBtn
->setPosSizePixel( aOutSz
.Width() - nSBWidth
, 0, nSBWidth
, aOutSz
.Height() );
633 mpImplLB
->SetSizePixel( aOutSz
);
636 // Retain FloatingWindow size even when it's invisible, as we still process KEY_PGUP/DOWN ...
638 mpFloatWin
->SetSizePixel( mpFloatWin
->CalcFloatSize() );
643 void ListBox::FillLayoutData() const
645 mpControlData
->mpLayoutData
.reset( new vcl::ControlLayoutData
);
646 const ImplListBoxWindow
* rMainWin
= mpImplLB
->GetMainWindow();
650 AppendLayoutData( *mpImplWin
);
651 mpImplWin
->SetLayoutDataParent( this );
652 if( mpFloatWin
->IsReallyVisible() )
654 AppendLayoutData( *rMainWin
);
655 rMainWin
->SetLayoutDataParent( this );
660 AppendLayoutData( *rMainWin
);
661 rMainWin
->SetLayoutDataParent( this );
665 long ListBox::GetIndexForPoint( const Point
& rPoint
, sal_Int32
& rPos
) const
667 if( !HasLayoutData() )
670 // Check whether rPoint fits at all
671 long nIndex
= Control::GetIndexForPoint( rPoint
);
674 // Point must be either in main list window
675 // or in impl window (dropdown case)
676 ImplListBoxWindow
* rMain
= mpImplLB
->GetMainWindow();
678 // Convert coordinates to ImplListBoxWindow pixel coordinate space
679 Point aConvPoint
= LogicToPixel( rPoint
);
680 aConvPoint
= OutputToAbsoluteScreenPixel( aConvPoint
);
681 aConvPoint
= rMain
->AbsoluteScreenToOutputPixel( aConvPoint
);
682 aConvPoint
= rMain
->PixelToLogic( aConvPoint
);
685 sal_Int32 nEntry
= rMain
->GetEntryPosForPoint( aConvPoint
);
686 if( nEntry
== LISTBOX_ENTRY_NOTFOUND
)
688 // Not found, maybe dropdown case
689 if( mpImplWin
&& mpImplWin
->IsReallyVisible() )
691 // Convert to impl window pixel coordinates
692 aConvPoint
= LogicToPixel( rPoint
);
693 aConvPoint
= OutputToAbsoluteScreenPixel( aConvPoint
);
694 aConvPoint
= mpImplWin
->AbsoluteScreenToOutputPixel( aConvPoint
);
696 // Check whether converted point is inside impl window
697 Size aImplWinSize
= mpImplWin
->GetOutputSizePixel();
698 if( aConvPoint
.X() >= 0 && aConvPoint
.Y() >= 0 && aConvPoint
.X() < aImplWinSize
.Width() && aConvPoint
.Y() < aImplWinSize
.Height() )
700 // Inside the impl window, the position is the current item pos
701 rPos
= mpImplWin
->GetItemPos();
712 SAL_WARN_IF( nIndex
== -1, "vcl", "found index for point, but relative index failed" );
715 // Get line relative index
717 nIndex
= ToRelativeLineIndex( nIndex
);
722 void ListBox::StateChanged( StateChangedType nType
)
724 if( nType
== StateChangedType::ReadOnly
)
727 mpImplWin
->Enable( !IsReadOnly() );
729 mpBtn
->Enable( !IsReadOnly() );
731 else if( nType
== StateChangedType::Enable
)
733 mpImplLB
->Enable( IsEnabled() );
736 mpImplWin
->Enable( IsEnabled() );
737 if ( IsNativeControlSupported(ControlType::Listbox
, ControlPart::Entire
)
738 && ! IsNativeControlSupported(ControlType::Listbox
, ControlPart::ButtonDown
) )
740 GetWindow( GetWindowType::Border
)->Invalidate( InvalidateFlags::NoErase
);
743 mpImplWin
->Invalidate();
746 mpBtn
->Enable( IsEnabled() );
748 else if( nType
== StateChangedType::UpdateMode
)
750 mpImplLB
->SetUpdateMode( IsUpdateMode() );
752 else if ( nType
== StateChangedType::Zoom
)
754 mpImplLB
->SetZoom( GetZoom() );
757 mpImplWin
->SetZoom( GetZoom() );
758 mpImplWin
->SetFont( mpImplLB
->GetMainWindow()->GetFont() );
759 mpImplWin
->Invalidate();
763 else if ( nType
== StateChangedType::ControlFont
)
765 mpImplLB
->SetControlFont( GetControlFont() );
768 mpImplWin
->SetControlFont( GetControlFont() );
769 mpImplWin
->SetFont( mpImplLB
->GetMainWindow()->GetFont() );
770 mpImplWin
->Invalidate();
774 else if ( nType
== StateChangedType::ControlForeground
)
776 mpImplLB
->SetControlForeground( GetControlForeground() );
779 mpImplWin
->SetControlForeground( GetControlForeground() );
780 mpImplWin
->SetTextColor( GetControlForeground() );
781 mpImplWin
->SetFont( mpImplLB
->GetMainWindow()->GetFont() );
782 mpImplWin
->Invalidate();
785 else if ( nType
== StateChangedType::ControlBackground
)
787 mpImplLB
->SetControlBackground( GetControlBackground() );
790 if ( mpImplWin
->IsNativeControlSupported(ControlType::Listbox
, ControlPart::Entire
) )
792 // Transparent background
793 mpImplWin
->SetBackground();
794 mpImplWin
->SetControlBackground();
798 mpImplWin
->SetBackground( mpImplLB
->GetMainWindow()->GetControlBackground() );
799 mpImplWin
->SetControlBackground( mpImplLB
->GetMainWindow()->GetControlBackground() );
801 mpImplWin
->SetFont( mpImplLB
->GetMainWindow()->GetFont() );
802 mpImplWin
->Invalidate();
805 else if ( nType
== StateChangedType::Style
)
807 SetStyle( ImplInitStyle( GetStyle() ) );
808 mpImplLB
->GetMainWindow()->EnableSort( ( GetStyle() & WB_SORT
) != 0 );
809 bool bSimpleMode
= ( GetStyle() & WB_SIMPLEMODE
) != 0;
810 mpImplLB
->SetMultiSelectionSimpleMode( bSimpleMode
);
812 else if( nType
== StateChangedType::Mirroring
)
816 mpBtn
->EnableRTL( IsRTLEnabled() );
817 ImplInitDropDownButton( mpBtn
);
819 mpImplLB
->EnableRTL( IsRTLEnabled() );
821 mpImplWin
->EnableRTL( IsRTLEnabled() );
825 Control::StateChanged( nType
);
828 bool ListBox::PreNotify( NotifyEvent
& rNEvt
)
833 if( ( rNEvt
.GetType() == MouseNotifyEvent::KEYINPUT
) && ( rNEvt
.GetWindow() == mpImplWin
) )
835 KeyEvent aKeyEvt
= *rNEvt
.GetKeyEvent();
836 switch( aKeyEvt
.GetKeyCode().GetCode() )
840 if( mpFloatWin
&& !mpFloatWin
->IsInPopupMode() &&
841 aKeyEvt
.GetKeyCode().IsMod2() )
843 CallEventListeners( VCLEVENT_DROPDOWN_PRE_OPEN
);
844 mpBtn
->SetPressed( true );
845 mpFloatWin
->StartFloat( false );
846 CallEventListeners( VCLEVENT_DROPDOWN_OPEN
);
851 bDone
= mpImplLB
->ProcessKeyInput( aKeyEvt
);
857 if( mpFloatWin
&& mpFloatWin
->IsInPopupMode() &&
858 aKeyEvt
.GetKeyCode().IsMod2() )
860 mpFloatWin
->EndPopupMode();
865 bDone
= mpImplLB
->ProcessKeyInput( aKeyEvt
);
873 mpImplLB
->ProcessKeyInput( aKeyEvt
);
881 bDone
= mpImplLB
->ProcessKeyInput( aKeyEvt
);
885 else if ( rNEvt
.GetType() == MouseNotifyEvent::LOSEFOCUS
)
887 if ( IsInDropDown() && !HasChildPathFocus( true ) )
888 mpFloatWin
->EndPopupMode();
890 else if ( (rNEvt
.GetType() == MouseNotifyEvent::COMMAND
) &&
891 (rNEvt
.GetCommandEvent()->GetCommand() == CommandEventId::Wheel
) &&
892 (rNEvt
.GetWindow() == mpImplWin
) )
894 MouseWheelBehaviour
nWheelBehavior( GetSettings().GetMouseSettings().GetWheelBehavior() );
895 if ( ( nWheelBehavior
== MouseWheelBehaviour::ALWAYS
)
896 || ( ( nWheelBehavior
== MouseWheelBehaviour::FocusOnly
)
897 && HasChildPathFocus()
901 bDone
= mpImplLB
->HandleWheelAsCursorTravel( *rNEvt
.GetCommandEvent() );
905 bDone
= false; // Don't consume this event, let the default handling take it (i.e. scroll the context)
910 return bDone
|| Control::PreNotify( rNEvt
);
913 void ListBox::Select()
915 ImplCallEventListenersAndHandler( VCLEVENT_LISTBOX_SELECT
, [this] () { maSelectHdl
.Call(*this); } );
918 void ListBox::DoubleClick()
920 ImplCallEventListenersAndHandler( VCLEVENT_LISTBOX_DOUBLECLICK
, [this] () { maDoubleClickHdl
.Call(*this); } );
923 void ListBox::Clear()
928 if( IsDropDownBox() )
930 mpImplWin
->SetItemPos( LISTBOX_ENTRY_NOTFOUND
);
931 mpImplWin
->SetString( OUString() );
933 mpImplWin
->SetImage( aImage
);
934 mpImplWin
->Invalidate();
936 CallEventListeners( VCLEVENT_LISTBOX_ITEMREMOVED
, reinterpret_cast<void*>(-1) );
939 void ListBox::SetNoSelection()
941 mpImplLB
->SetNoSelection();
942 if( IsDropDownBox() )
944 mpImplWin
->SetItemPos( LISTBOX_ENTRY_NOTFOUND
);
945 mpImplWin
->SetString( OUString() );
947 mpImplWin
->SetImage( aImage
);
948 mpImplWin
->Invalidate();
950 CallEventListeners(VCLEVENT_LISTBOX_STATEUPDATE
);
953 sal_Int32
ListBox::InsertEntry( const OUString
& rStr
, sal_Int32 nPos
)
955 sal_Int32 nRealPos
= mpImplLB
->InsertEntry( nPos
+ mpImplLB
->GetEntryList()->GetMRUCount(), rStr
);
956 nRealPos
= sal::static_int_cast
<sal_Int32
>(nRealPos
- mpImplLB
->GetEntryList()->GetMRUCount());
957 CallEventListeners( VCLEVENT_LISTBOX_ITEMADDED
, reinterpret_cast<void*>(nRealPos
) );
961 sal_Int32
ListBox::InsertEntry( const OUString
& rStr
, const Image
& rImage
, sal_Int32 nPos
)
963 sal_Int32 nRealPos
= mpImplLB
->InsertEntry( nPos
+ mpImplLB
->GetEntryList()->GetMRUCount(), rStr
, rImage
);
964 nRealPos
= sal::static_int_cast
<sal_Int32
>(nRealPos
- mpImplLB
->GetEntryList()->GetMRUCount());
965 CallEventListeners( VCLEVENT_LISTBOX_ITEMADDED
, reinterpret_cast<void*>(nRealPos
) );
969 void ListBox::RemoveEntry( const OUString
& rStr
)
971 RemoveEntry( GetEntryPos( rStr
) );
974 void ListBox::RemoveEntry( sal_Int32 nPos
)
976 mpImplLB
->RemoveEntry( nPos
+ mpImplLB
->GetEntryList()->GetMRUCount() );
977 CallEventListeners( VCLEVENT_LISTBOX_ITEMREMOVED
, reinterpret_cast<void*>(nPos
) );
980 Image
ListBox::GetEntryImage( sal_Int32 nPos
) const
982 if ( mpImplLB
&& mpImplLB
->GetEntryList()->HasEntryImage( nPos
) )
983 return mpImplLB
->GetEntryList()->GetEntryImage( nPos
);
987 sal_Int32
ListBox::GetEntryPos( const OUString
& rStr
) const
990 return LISTBOX_ENTRY_NOTFOUND
;
991 sal_Int32 nPos
= mpImplLB
->GetEntryList()->FindEntry( rStr
);
992 if ( nPos
!= LISTBOX_ENTRY_NOTFOUND
)
993 nPos
= nPos
- mpImplLB
->GetEntryList()->GetMRUCount();
997 sal_Int32
ListBox::GetEntryPos( const void* pData
) const
1000 return LISTBOX_ENTRY_NOTFOUND
;
1001 sal_Int32 nPos
= mpImplLB
->GetEntryList()->FindEntry( pData
);
1002 if ( nPos
!= LISTBOX_ENTRY_NOTFOUND
)
1003 nPos
= nPos
- mpImplLB
->GetEntryList()->GetMRUCount();
1007 OUString
ListBox::GetEntry( sal_Int32 nPos
) const
1011 return mpImplLB
->GetEntryList()->GetEntryText( nPos
+ mpImplLB
->GetEntryList()->GetMRUCount() );
1014 sal_Int32
ListBox::GetEntryCount() const
1018 return mpImplLB
->GetEntryList()->GetEntryCount() - mpImplLB
->GetEntryList()->GetMRUCount();
1021 OUString
ListBox::GetSelectEntry(sal_Int32 nIndex
) const
1023 return GetEntry( GetSelectEntryPos( nIndex
) );
1026 sal_Int32
ListBox::GetSelectEntryCount() const
1030 return mpImplLB
->GetEntryList()->GetSelectEntryCount();
1033 sal_Int32
ListBox::GetSelectEntryPos( sal_Int32 nIndex
) const
1035 if (!mpImplLB
|| !mpImplLB
->GetEntryList())
1036 return LISTBOX_ENTRY_NOTFOUND
;
1038 sal_Int32 nPos
= mpImplLB
->GetEntryList()->GetSelectEntryPos( nIndex
);
1039 if ( nPos
!= LISTBOX_ENTRY_NOTFOUND
)
1041 if ( nPos
< mpImplLB
->GetEntryList()->GetMRUCount() )
1042 nPos
= mpImplLB
->GetEntryList()->FindEntry( mpImplLB
->GetEntryList()->GetEntryText( nPos
) );
1043 nPos
= nPos
- mpImplLB
->GetEntryList()->GetMRUCount();
1048 bool ListBox::IsEntrySelected(const OUString
& rStr
) const
1050 return IsEntryPosSelected( GetEntryPos( rStr
) );
1053 bool ListBox::IsEntryPosSelected( sal_Int32 nPos
) const
1055 return mpImplLB
->GetEntryList()->IsEntryPosSelected( nPos
+ mpImplLB
->GetEntryList()->GetMRUCount() );
1058 void ListBox::SelectEntry( const OUString
& rStr
, bool bSelect
)
1060 SelectEntryPos( GetEntryPos( rStr
), bSelect
);
1063 void ListBox::SelectEntryPos( sal_Int32 nPos
, bool bSelect
)
1068 if ( 0 <= nPos
&& nPos
< mpImplLB
->GetEntryList()->GetEntryCount() )
1070 sal_Int32 oldSelectCount
= GetSelectEntryCount(), newSelectCount
= 0, nCurrentPos
= mpImplLB
->GetCurrentPos();
1071 mpImplLB
->SelectEntry( nPos
+ mpImplLB
->GetEntryList()->GetMRUCount(), bSelect
);
1072 newSelectCount
= GetSelectEntryCount();
1073 if (oldSelectCount
== 0 && newSelectCount
> 0)
1074 CallEventListeners(VCLEVENT_LISTBOX_STATEUPDATE
);
1075 //Only when bSelect == true, send both Selection & Focus events
1076 if (nCurrentPos
!= nPos
&& bSelect
)
1078 CallEventListeners( VCLEVENT_LISTBOX_SELECT
, reinterpret_cast<void*>(nPos
));
1080 CallEventListeners( VCLEVENT_LISTBOX_FOCUS
, reinterpret_cast<void*>(nPos
));
1085 void ListBox::SetEntryData( sal_Int32 nPos
, void* pNewData
)
1087 mpImplLB
->SetEntryData( nPos
+ mpImplLB
->GetEntryList()->GetMRUCount(), pNewData
);
1090 void* ListBox::GetEntryData( sal_Int32 nPos
) const
1092 return mpImplLB
->GetEntryList()->GetEntryData( nPos
+ mpImplLB
->GetEntryList()->GetMRUCount() );
1095 void ListBox::SetEntryFlags( sal_Int32 nPos
, ListBoxEntryFlags nFlags
)
1097 mpImplLB
->SetEntryFlags( nPos
+ mpImplLB
->GetEntryList()->GetMRUCount(), nFlags
);
1100 ListBoxEntryFlags
ListBox::GetEntryFlags( sal_Int32 nPos
) const
1102 return mpImplLB
->GetEntryList()->GetEntryFlags( nPos
+ mpImplLB
->GetEntryList()->GetMRUCount() );
1105 void ListBox::SetTopEntry( sal_Int32 nPos
)
1107 mpImplLB
->SetTopEntry( nPos
+ mpImplLB
->GetEntryList()->GetMRUCount() );
1110 sal_Int32
ListBox::GetTopEntry() const
1112 sal_Int32 nPos
= GetEntryCount() ? mpImplLB
->GetTopEntry() : LISTBOX_ENTRY_NOTFOUND
;
1113 if ( nPos
< mpImplLB
->GetEntryList()->GetMRUCount() )
1118 bool ListBox::IsTravelSelect() const
1120 return mpImplLB
->IsTravelSelect();
1123 bool ListBox::IsInDropDown() const
1125 return mpFloatWin
&& mpFloatWin
->IsInPopupMode();
1128 Rectangle
ListBox::GetBoundingRectangle( sal_Int32 nItem
) const
1130 Rectangle aRect
= mpImplLB
->GetMainWindow()->GetBoundingRectangle( nItem
);
1131 Rectangle aOffset
= mpImplLB
->GetMainWindow()->GetWindowExtentsRelative( static_cast<vcl::Window
*>(const_cast<ListBox
*>(this)) );
1132 aRect
.Move( aOffset
.TopLeft().X(), aOffset
.TopLeft().Y() );
1136 void ListBox::EnableMultiSelection( bool bMulti
)
1138 EnableMultiSelection( bMulti
, false );
1141 void ListBox::EnableMultiSelection( bool bMulti
, bool bStackSelection
)
1143 mpImplLB
->EnableMultiSelection( bMulti
, bStackSelection
);
1146 // The MultiListBox behaves just like a normal ListBox
1147 // MultiSelection is possible via corresponding additional keys
1148 bool bSimpleMode
= ( GetStyle() & WB_SIMPLEMODE
) != 0;
1149 mpImplLB
->SetMultiSelectionSimpleMode( bSimpleMode
);
1151 // In a MultiSelection, we can't see us travelling without focus
1153 mpImplLB
->GetMainWindow()->AllowGrabFocus( bMulti
);
1156 bool ListBox::IsMultiSelectionEnabled() const
1158 return mpImplLB
->IsMultiSelectionEnabled();
1161 Size
ListBox::CalcMinimumSize() const
1168 aSz
= CalcSubEditSize();
1170 bool bAddScrollWidth
= false;
1172 if (IsDropDownBox())
1174 aSz
.Height() += 4; // add a space between entry and border
1175 aSz
.Width() += 4; // add a little breathing space
1176 bAddScrollWidth
= true;
1179 bAddScrollWidth
= (GetStyle() & WB_VSCROLL
) == WB_VSCROLL
;
1181 if (bAddScrollWidth
)
1183 // Try native borders; scrollbar size may not be a good indicator
1184 // See how large the edit area inside is to estimate what is needed for the dropdown
1185 ImplControlValue aControlValue
;
1187 Rectangle aContent
, aBound
;
1188 Size
aTestSize( 100, 20 );
1189 Rectangle
aArea( aPoint
, aTestSize
);
1190 if( GetNativeControlRegion( ControlType::Listbox
, ControlPart::SubEdit
, aArea
, ControlState::NONE
,
1191 aControlValue
, OUString(), aBound
, aContent
) )
1193 // use the themes drop down size
1194 aSz
.Width() += aTestSize
.Width() - aContent
.GetWidth();
1197 aSz
.Width() += GetSettings().GetStyleSettings().GetScrollBarSize();
1200 aSz
= CalcWindowSize( aSz
);
1202 if (IsDropDownBox()) // Check minimum height of dropdown box
1204 ImplControlValue aControlValue
;
1205 Rectangle
aRect( Point( 0, 0 ), aSz
);
1206 Rectangle aContent
, aBound
;
1207 if( GetNativeControlRegion( ControlType::Listbox
, ControlPart::Entire
, aRect
, ControlState::NONE
,
1208 aControlValue
, OUString(), aBound
, aContent
) )
1210 if( aBound
.GetHeight() > aSz
.Height() )
1211 aSz
.Height() = aBound
.GetHeight();
1218 Size
ListBox::CalcSubEditSize() const
1225 if ( !IsDropDownBox() )
1226 aSz
= mpImplLB
->CalcSize (mnLineCount
? mnLineCount
: mpImplLB
->GetEntryList()->GetEntryCount());
1229 aSz
.Height() = mpImplLB
->CalcSize( 1 ).Height();
1230 // Size to maxmimum entry width
1231 aSz
.Width() = mpImplLB
->GetMaxEntryWidth();
1233 if (m_nMaxWidthChars
!= -1)
1235 long nMaxWidth
= m_nMaxWidthChars
* approximate_char_width();
1236 aSz
.Width() = std::min(aSz
.Width(), nMaxWidth
);
1239 // Do not create ultrathin ListBoxes, it doesn't look good
1240 if( aSz
.Width() < GetSettings().GetStyleSettings().GetScrollBarSize() )
1241 aSz
.Width() = GetSettings().GetStyleSettings().GetScrollBarSize();
1247 Size
ListBox::GetOptimalSize() const
1249 return CalcMinimumSize();
1252 Size
ListBox::CalcAdjustedSize( const Size
& rPrefSize
) const
1254 Size aSz
= rPrefSize
;
1255 sal_Int32 nLeft
, nTop
, nRight
, nBottom
;
1256 static_cast<vcl::Window
*>(const_cast<ListBox
*>(this))->GetBorder( nLeft
, nTop
, nRight
, nBottom
);
1257 aSz
.Height() -= nTop
+nBottom
;
1258 if ( !IsDropDownBox() )
1260 long nEntryHeight
= CalcBlockSize( 1, 1 ).Height();
1261 long nLines
= aSz
.Height() / nEntryHeight
;
1264 aSz
.Height() = nLines
* nEntryHeight
;
1268 aSz
.Height() = mnDDHeight
;
1270 aSz
.Height() += nTop
+nBottom
;
1272 aSz
= CalcWindowSize( aSz
);
1276 Size
ListBox::CalcBlockSize( sal_uInt16 nColumns
, sal_uInt16 nLines
) const
1278 // ScrollBars are shown if needed
1279 Size aMinSz
= CalcMinimumSize();
1280 // aMinSz = ImplCalcOutSz( aMinSz );
1287 if ( !IsDropDownBox() )
1288 aSz
.Height() = mpImplLB
->CalcSize( nLines
).Height();
1290 aSz
.Height() = mnDDHeight
;
1293 aSz
.Height() = aMinSz
.Height();
1297 aSz
.Width() = nColumns
* GetTextWidth( OUString('X') );
1299 aSz
.Width() = aMinSz
.Width();
1301 if ( IsDropDownBox() )
1302 aSz
.Width() += GetSettings().GetStyleSettings().GetScrollBarSize();
1304 if ( !IsDropDownBox() )
1306 if ( aSz
.Width() < aMinSz
.Width() )
1307 aSz
.Height() += GetSettings().GetStyleSettings().GetScrollBarSize();
1308 if ( aSz
.Height() < aMinSz
.Height() )
1309 aSz
.Width() += GetSettings().GetStyleSettings().GetScrollBarSize();
1312 aSz
= CalcWindowSize( aSz
);
1316 void ListBox::GetMaxVisColumnsAndLines( sal_uInt16
& rnCols
, sal_uInt16
& rnLines
) const
1318 float nCharWidth
= approximate_char_width();
1319 if ( !IsDropDownBox() )
1321 Size aOutSz
= mpImplLB
->GetMainWindow()->GetOutputSizePixel();
1322 rnCols
= (sal_uInt16
) (aOutSz
.Width()/nCharWidth
);
1323 rnLines
= (sal_uInt16
) (aOutSz
.Height()/mpImplLB
->GetEntryHeight());
1327 Size aOutSz
= mpImplWin
->GetOutputSizePixel();
1328 rnCols
= (sal_uInt16
) (aOutSz
.Width()/nCharWidth
);
1333 IMPL_LINK( ListBox
, ImplUserDrawHdl
, UserDrawEvent
*, pEvent
, void )
1335 UserDraw( *pEvent
);
1338 void ListBox::UserDraw( const UserDrawEvent
& )
1342 void ListBox::DrawEntry(const UserDrawEvent
& rEvt
, bool bDrawImage
, bool bDrawTextAtImagePos
)
1344 if (rEvt
.GetWindow() == mpImplLB
->GetMainWindow())
1345 mpImplLB
->GetMainWindow()->DrawEntry(*rEvt
.GetRenderContext(), rEvt
.GetItemId(), bDrawImage
, true/*bDrawText*/, bDrawTextAtImagePos
);
1346 else if (rEvt
.GetWindow() == mpImplWin
)
1347 mpImplWin
->DrawEntry(*rEvt
.GetRenderContext(), bDrawImage
, bDrawTextAtImagePos
);
1350 void ListBox::EnableUserDraw( bool bUserDraw
)
1352 mpImplLB
->GetMainWindow()->EnableUserDraw( bUserDraw
);
1354 mpImplWin
->EnableUserDraw( bUserDraw
);
1357 void ListBox::SetReadOnly( bool bReadOnly
)
1359 if ( mpImplLB
->IsReadOnly() != bReadOnly
)
1361 mpImplLB
->SetReadOnly( bReadOnly
);
1362 CompatStateChanged( StateChangedType::ReadOnly
);
1366 bool ListBox::IsReadOnly() const
1368 return mpImplLB
->IsReadOnly();
1371 void ListBox::SetSeparatorPos( sal_Int32 n
)
1373 mpImplLB
->SetSeparatorPos( n
);
1376 sal_Int32
ListBox::GetSeparatorPos() const
1378 return mpImplLB
->GetSeparatorPos();
1381 sal_uInt16
ListBox::GetDisplayLineCount() const
1383 return mpImplLB
->GetDisplayLineCount();
1386 void ListBox::EnableMirroring()
1388 mpImplLB
->EnableMirroring();
1391 Rectangle
ListBox::GetDropDownPosSizePixel() const
1393 return mpFloatWin
? mpFloatWin
->GetWindowExtentsRelative( const_cast<ListBox
*>(this) ) : Rectangle();
1396 const Wallpaper
& ListBox::GetDisplayBackground() const
1398 // !!! Recursion does not occur because the ImplListBox is initialized by default
1399 // to a non-transparent color in Window::ImplInitData
1400 return mpImplLB
->GetDisplayBackground();
1403 void ListBox::setMaxWidthChars(sal_Int32 nWidth
)
1405 if (nWidth
!= m_nMaxWidthChars
)
1407 m_nMaxWidthChars
= nWidth
;
1412 bool ListBox::set_property(const OString
&rKey
, const OString
&rValue
)
1414 if (rKey
== "active")
1415 SelectEntryPos(rValue
.toInt32());
1416 else if (rKey
== "max-width-chars")
1417 setMaxWidthChars(rValue
.toInt32());
1419 return Control::set_property(rKey
, rValue
);
1423 void ListBox::SetEdgeBlending(bool bNew
)
1425 if(mbEdgeBlending
!= bNew
)
1427 mbEdgeBlending
= bNew
;
1432 mpImplWin
->Invalidate();
1436 mpImplLB
->Invalidate();
1441 mpImplWin
->SetEdgeBlending(GetEdgeBlending());
1446 mpImplLB
->SetEdgeBlending(GetEdgeBlending());
1453 FactoryFunction
ListBox::GetUITestFactory() const
1455 return ListBoxUIObject::create
;
1458 MultiListBox::MultiListBox( vcl::Window
* pParent
, WinBits nStyle
) :
1459 ListBox( WINDOW_MULTILISTBOX
)
1461 ImplInit( pParent
, nStyle
);
1462 EnableMultiSelection( true );
1465 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */