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 <vcl/commandevent.hxx>
22 #include <vcl/event.hxx>
23 #include <vcl/lstbox.hxx>
24 #include <vcl/settings.hxx>
25 #include <vcl/uitest/uiobject.hxx>
26 #include <sal/log.hxx>
29 #include <controldata.hxx>
30 #include <listbox.hxx>
31 #include <dndeventdispatcher.hxx>
32 #include <comphelper/lok.hxx>
34 #include <com/sun/star/datatransfer/dnd/XDropTarget.hpp>
35 #include <boost/property_tree/ptree.hpp>
37 void ListBox::EnableQuickSelection( bool b
)
39 mpImplLB
->GetMainWindow()->EnableQuickSelection(b
);
42 ListBox::ListBox(WindowType nType
)
46 ImplInitListBoxData();
49 ListBox::ListBox( vcl::Window
* pParent
, WinBits nStyle
) : Control( WindowType::LISTBOX
)
51 ImplInitListBoxData();
52 ImplInit( pParent
, nStyle
);
60 void ListBox::dispose()
62 CallEventListeners( VclEventId::ObjectDying
);
64 mpImplLB
.disposeAndClear();
65 mpFloatWin
.disposeAndClear();
66 mpImplWin
.disposeAndClear();
67 mpBtn
.disposeAndClear();
72 void ListBox::ImplInitListBoxData()
78 mnSaveValue
= LISTBOX_ENTRY_NOTFOUND
;
80 m_nMaxWidthChars
= -1;
84 void ListBox::ImplInit( vcl::Window
* pParent
, WinBits nStyle
)
86 nStyle
= ImplInitStyle( nStyle
);
87 if ( !(nStyle
& WB_NOBORDER
) && ( nStyle
& WB_DROPDOWN
) )
90 Control::ImplInit( pParent
, nStyle
, nullptr );
92 css::uno::Reference
< css::datatransfer::dnd::XDropTargetListener
> xDrop
= new DNDEventDispatcher(this);
94 if( nStyle
& WB_DROPDOWN
)
96 sal_Int32 nLeft
, nTop
, nRight
, nBottom
;
97 GetBorder( nLeft
, nTop
, nRight
, nBottom
);
98 mnDDHeight
= static_cast<sal_uInt16
>(GetTextHeight() + nTop
+ nBottom
+ 4);
100 if( IsNativeWidgetEnabled() &&
101 IsNativeControlSupported( ControlType::Listbox
, ControlPart::Entire
) )
103 ImplControlValue aControlValue
;
104 tools::Rectangle
aCtrlRegion( Point( 0, 0 ), Size( 20, mnDDHeight
) );
105 tools::Rectangle
aBoundingRgn( aCtrlRegion
);
106 tools::Rectangle
aContentRgn( aCtrlRegion
);
107 if( GetNativeControlRegion( ControlType::Listbox
, ControlPart::Entire
, aCtrlRegion
,
108 ControlState::ENABLED
, aControlValue
,
109 aBoundingRgn
, aContentRgn
) )
111 sal_Int32 nHeight
= aBoundingRgn
.GetHeight();
112 if( nHeight
> mnDDHeight
)
113 mnDDHeight
= static_cast<sal_uInt16
>(nHeight
);
117 mpFloatWin
= VclPtr
<ImplListBoxFloatingWindow
>::Create( this );
118 if (!IsNativeControlSupported(ControlType::Pushbutton
, ControlPart::Focus
))
119 mpFloatWin
->RequestDoubleBuffering(true);
120 mpFloatWin
->SetAutoWidth( true );
121 mpFloatWin
->SetPopupModeEndHdl( LINK( this, ListBox
, ImplPopupModeEndHdl
) );
122 mpFloatWin
->GetDropTarget()->addDropTargetListener(xDrop
);
124 mpImplWin
= VclPtr
<ImplWin
>::Create( this, (nStyle
& (WB_LEFT
|WB_RIGHT
|WB_CENTER
))|WB_NOBORDER
);
125 mpImplWin
->SetMBDownHdl( LINK( this, ListBox
, ImplClickBtnHdl
) );
126 mpImplWin
->SetUserDrawHdl( LINK( this, ListBox
, ImplUserDrawHdl
) );
128 mpImplWin
->GetDropTarget()->addDropTargetListener(xDrop
);
129 mpImplWin
->SetEdgeBlending(false);
131 mpBtn
= VclPtr
<ImplBtn
>::Create( this, WB_NOLIGHTBORDER
| WB_RECTSTYLE
);
132 ImplInitDropDownButton( mpBtn
);
133 mpBtn
->SetMBDownHdl( LINK( this, ListBox
, ImplClickBtnHdl
) );
135 mpBtn
->GetDropTarget()->addDropTargetListener(xDrop
);
138 vcl::Window
* pLBParent
= this;
140 pLBParent
= mpFloatWin
;
141 mpImplLB
= VclPtr
<ImplListBox
>::Create( pLBParent
, nStyle
&(~WB_BORDER
) );
142 mpImplLB
->SetSelectHdl( LINK( this, ListBox
, ImplSelectHdl
) );
143 mpImplLB
->SetScrollHdl( LINK( this, ListBox
, ImplScrollHdl
) );
144 mpImplLB
->SetCancelHdl( LINK( this, ListBox
, ImplCancelHdl
) );
145 mpImplLB
->SetDoubleClickHdl( LINK( this, ListBox
, ImplDoubleClickHdl
) );
146 mpImplLB
->SetUserDrawHdl( LINK( this, ListBox
, ImplUserDrawHdl
) );
147 mpImplLB
->SetFocusHdl( LINK( this, ListBox
, ImplFocusHdl
) );
148 mpImplLB
->SetListItemSelectHdl( LINK( this, ListBox
, ImplListItemSelectHdl
) );
149 mpImplLB
->SetPosPixel( Point() );
150 mpImplLB
->SetEdgeBlending(false);
153 mpImplLB
->GetDropTarget()->addDropTargetListener(xDrop
);
157 mpFloatWin
->SetImplListBox( mpImplLB
);
158 mpImplLB
->SetSelectionChangedHdl( LINK( this, ListBox
, ImplSelectionChangedHdl
) );
161 mpImplLB
->GetMainWindow()->AllowGrabFocus( true );
163 SetCompoundControl( true );
166 WinBits
ListBox::ImplInitStyle( WinBits nStyle
)
168 if ( !(nStyle
& WB_NOTABSTOP
) )
169 nStyle
|= WB_TABSTOP
;
170 if ( !(nStyle
& WB_NOGROUP
) )
175 IMPL_LINK_NOARG(ListBox
, ImplSelectHdl
, LinkParamNone
*, void)
177 bool bPopup
= IsInDropDown();
178 if( IsDropDownBox() )
180 if( !mpImplLB
->IsTravelSelect() )
182 mpFloatWin
->EndPopupMode();
183 mpImplWin
->GrabFocus();
186 mpImplWin
->SetItemPos( GetSelectedEntryPos() );
187 mpImplWin
->SetString( GetSelectedEntry() );
188 if( mpImplLB
->GetEntryList()->HasImages() )
190 Image aImage
= mpImplLB
->GetEntryList()->GetEntryImage( GetSelectedEntryPos() );
191 mpImplWin
->SetImage( aImage
);
193 mpImplWin
->Invalidate();
196 if ( ( !IsTravelSelect() || mpImplLB
->IsSelectionChanged() ) || ( bPopup
&& !IsMultiSelectionEnabled() ) )
200 IMPL_LINK( ListBox
, ImplFocusHdl
, sal_Int32
, nPos
, void )
202 CallEventListeners( VclEventId::ListboxFocus
, reinterpret_cast<void*>(nPos
) );
205 IMPL_LINK_NOARG( ListBox
, ImplListItemSelectHdl
, LinkParamNone
*, void )
207 CallEventListeners( VclEventId::DropdownSelect
);
210 IMPL_LINK_NOARG(ListBox
, ImplScrollHdl
, ImplListBox
*, void)
212 CallEventListeners( VclEventId::ListboxScrolled
);
215 IMPL_LINK_NOARG(ListBox
, ImplCancelHdl
, LinkParamNone
*, void)
218 mpFloatWin
->EndPopupMode();
221 IMPL_LINK( ListBox
, ImplSelectionChangedHdl
, sal_Int32
, nChanged
, void )
223 if ( !mpImplLB
->IsTrackingSelect() )
225 const ImplEntryList
* pEntryList
= mpImplLB
->GetEntryList();
226 if ( pEntryList
->IsEntryPosSelected( nChanged
) )
228 // FIXME? This should've been turned into an ImplPaintEntry some time ago...
229 if ( nChanged
< pEntryList
->GetMRUCount() )
230 nChanged
= pEntryList
->FindEntry( pEntryList
->GetEntryText( nChanged
) );
231 mpImplWin
->SetItemPos( nChanged
);
232 mpImplWin
->SetString( mpImplLB
->GetEntryList()->GetEntryText( nChanged
) );
233 if( mpImplLB
->GetEntryList()->HasImages() )
235 Image aImage
= mpImplLB
->GetEntryList()->GetEntryImage( nChanged
);
236 mpImplWin
->SetImage( aImage
);
241 mpImplWin
->SetItemPos( LISTBOX_ENTRY_NOTFOUND
);
242 mpImplWin
->SetString( OUString() );
244 mpImplWin
->SetImage( aImage
);
246 mpImplWin
->Invalidate();
250 IMPL_LINK_NOARG(ListBox
, ImplDoubleClickHdl
, ImplListBoxWindow
*, void)
255 IMPL_LINK_NOARG(ListBox
, ImplClickBtnHdl
, void*, void)
257 if( !mpFloatWin
->IsInPopupMode() )
259 CallEventListeners( VclEventId::DropdownPreOpen
);
260 mpImplWin
->GrabFocus();
261 mpBtn
->SetPressed( true );
262 mpFloatWin
->StartFloat( true );
263 CallEventListeners( VclEventId::DropdownOpen
);
265 ImplClearLayoutData();
267 mpImplLB
->GetMainWindow()->ImplClearLayoutData();
269 mpImplWin
->ImplClearLayoutData();
273 IMPL_LINK_NOARG(ListBox
, ImplPopupModeEndHdl
, FloatingWindow
*, void)
275 if( mpFloatWin
->IsPopupModeCanceled() )
277 if ( ( mpFloatWin
->GetPopupModeStartSaveSelection() != LISTBOX_ENTRY_NOTFOUND
)
278 && !IsEntryPosSelected( mpFloatWin
->GetPopupModeStartSaveSelection() ) )
280 mpImplLB
->SelectEntry( mpFloatWin
->GetPopupModeStartSaveSelection(), true );
281 bool bTravelSelect
= mpImplLB
->IsTravelSelect();
282 mpImplLB
->SetTravelSelect( true );
284 VclPtr
<vcl::Window
> xWindow
= this;
286 if ( xWindow
->IsDisposed() )
289 mpImplLB
->SetTravelSelect( bTravelSelect
);
293 ImplClearLayoutData();
295 mpImplLB
->GetMainWindow()->ImplClearLayoutData();
297 mpImplWin
->ImplClearLayoutData();
299 mpBtn
->SetPressed( false );
300 CallEventListeners( VclEventId::DropdownClose
);
303 void ListBox::ToggleDropDown()
305 if( IsDropDownBox() )
307 if( mpFloatWin
->IsInPopupMode() )
308 mpFloatWin
->EndPopupMode();
311 CallEventListeners( VclEventId::DropdownPreOpen
);
312 mpImplWin
->GrabFocus();
313 mpBtn
->SetPressed( true );
314 mpFloatWin
->StartFloat( true );
315 CallEventListeners( VclEventId::DropdownOpen
);
320 void ListBox::ApplySettings(vcl::RenderContext
& rRenderContext
)
322 rRenderContext
.SetBackground();
325 void ListBox::Draw( OutputDevice
* pDev
, const Point
& rPos
, const Size
& rSize
, DrawFlags nFlags
)
327 mpImplLB
->GetMainWindow()->ApplySettings(*pDev
);
329 Point aPos
= pDev
->LogicToPixel( rPos
);
330 Size aSize
= pDev
->LogicToPixel( rSize
);
331 vcl::Font aFont
= mpImplLB
->GetMainWindow()->GetDrawPixelFont( pDev
);
332 OutDevType eOutDevType
= pDev
->GetOutDevType();
336 pDev
->SetFont( aFont
);
337 pDev
->SetTextFillColor();
340 pDev
->SetLineColor();
341 pDev
->SetFillColor();
342 bool bBorder
= (GetStyle() & WB_BORDER
);
343 bool bBackground
= IsControlBackground();
344 if ( bBorder
|| bBackground
)
346 tools::Rectangle
aRect( aPos
, aSize
);
349 ImplDrawFrame( pDev
, aRect
);
353 pDev
->SetFillColor( GetControlBackground() );
354 pDev
->DrawRect( aRect
);
359 if ( ( nFlags
& DrawFlags::Mono
) || ( eOutDevType
== OUTDEV_PRINTER
) )
361 pDev
->SetTextColor( COL_BLACK
);
367 const StyleSettings
& rStyleSettings
= GetSettings().GetStyleSettings();
368 pDev
->SetTextColor( rStyleSettings
.GetDisableColor() );
372 pDev
->SetTextColor( GetTextColor() );
376 const long nOnePixel
= GetDrawPixel( pDev
, 1 );
377 const long nOffX
= 3*nOnePixel
;
378 DrawTextFlags nTextStyle
= DrawTextFlags::VCenter
;
379 tools::Rectangle
aTextRect( aPos
, aSize
);
381 if ( GetStyle() & WB_CENTER
)
382 nTextStyle
|= DrawTextFlags::Center
;
383 else if ( GetStyle() & WB_RIGHT
)
384 nTextStyle
|= DrawTextFlags::Right
;
386 nTextStyle
|= DrawTextFlags::Left
;
388 aTextRect
.AdjustLeft(nOffX
);
389 aTextRect
.AdjustRight( -nOffX
);
391 if ( IsDropDownBox() )
393 OUString aText
= GetSelectedEntry();
394 long nTextHeight
= pDev
->GetTextHeight();
395 long nTextWidth
= pDev
->GetTextWidth( aText
);
396 long nOffY
= (aSize
.Height()-nTextHeight
) / 2;
400 ((nOffY
+nTextHeight
) > aSize
.Height()) ||
401 ((nOffX
+nTextWidth
) > aSize
.Width()) )
403 tools::Rectangle
aClip( aPos
, aSize
);
404 if ( nTextHeight
> aSize
.Height() )
405 aClip
.AdjustBottom(nTextHeight
-aSize
.Height()+1 ); // So that HP Printers don't optimize this away
406 pDev
->IntersectClipRegion( aClip
);
409 pDev
->DrawText( aTextRect
, aText
, nTextStyle
);
413 long nTextHeight
= pDev
->GetTextHeight();
414 sal_uInt16 nLines
= ( nTextHeight
> 0 ) ? static_cast<sal_uInt16
>(aSize
.Height() / nTextHeight
) : 1;
415 tools::Rectangle
aClip( aPos
, aSize
);
417 pDev
->IntersectClipRegion( aClip
);
422 for ( sal_uInt16 n
= 0; n
< nLines
; n
++ )
424 sal_Int32 nEntry
= n
+mpImplLB
->GetTopEntry();
425 bool bSelected
= mpImplLB
->GetEntryList()->IsEntryPosSelected( nEntry
);
428 pDev
->SetFillColor( COL_BLACK
);
429 pDev
->DrawRect( tools::Rectangle( Point( aPos
.X(), aPos
.Y() + n
*nTextHeight
),
430 Point( aPos
.X() + aSize
.Width(), aPos
.Y() + (n
+1)*nTextHeight
+ 2*nOnePixel
) ) );
431 pDev
->SetFillColor();
432 pDev
->SetTextColor( COL_WHITE
);
435 aTextRect
.SetTop( aPos
.Y() + n
*nTextHeight
);
436 aTextRect
.SetBottom( aTextRect
.Top() + nTextHeight
);
438 pDev
->DrawText( aTextRect
, mpImplLB
->GetEntryList()->GetEntryText( nEntry
), nTextStyle
);
441 pDev
->SetTextColor( COL_BLACK
);
448 void ListBox::GetFocus()
452 if( IsDropDownBox() )
453 mpImplWin
->GrabFocus();
455 mpImplLB
->GrabFocus();
461 void ListBox::LoseFocus()
463 if( IsDropDownBox() )
466 mpImplWin
->HideFocus();
471 mpImplLB
->HideFocus();
474 Control::LoseFocus();
477 void ListBox::DataChanged( const DataChangedEvent
& rDCEvt
)
479 Control::DataChanged( rDCEvt
);
481 if ( (rDCEvt
.GetType() == DataChangedEventType::FONTS
) ||
482 (rDCEvt
.GetType() == DataChangedEventType::FONTSUBSTITUTION
) ||
483 ((rDCEvt
.GetType() == DataChangedEventType::SETTINGS
) &&
484 (rDCEvt
.GetFlags() & AllSettingsFlags::STYLE
)) )
486 SetBackground(); // Due to a hack in Window::UpdateSettings the background must be reset
487 // otherwise it will overpaint NWF drawn listboxes
489 mpImplLB
->Resize(); // Is not called by ListBox::Resize() if the ImplLB does not change
493 mpImplWin
->SetSettings( GetSettings() ); // If not yet set...
494 mpImplWin
->ApplySettings(*mpImplWin
);
496 mpBtn
->SetSettings( GetSettings() );
497 ImplInitDropDownButton( mpBtn
);
500 if ( IsDropDownBox() )
505 void ListBox::EnableAutoSize( bool bAuto
)
507 mbDDAutoSize
= bAuto
;
510 if ( bAuto
&& !mpFloatWin
->GetDropDownLineCount() )
512 // use GetListBoxMaximumLineCount here; before, was on fixed number of five
513 AdaptDropDownLineCountToMaximum();
517 mpFloatWin
->SetDropDownLineCount( 0 );
522 void ListBox::SetDropDownLineCount( sal_uInt16 nLines
)
524 mnLineCount
= nLines
;
526 mpFloatWin
->SetDropDownLineCount( mnLineCount
);
529 void ListBox::AdaptDropDownLineCountToMaximum()
531 // Adapt to maximum allowed number.
532 // Limit for LOK as we can't render outside of the dialog canvas.
533 if (comphelper::LibreOfficeKit::isActive())
534 SetDropDownLineCount(11);
536 SetDropDownLineCount(GetSettings().GetStyleSettings().GetListBoxMaximumLineCount());
539 sal_uInt16
ListBox::GetDropDownLineCount() const
542 return mpFloatWin
->GetDropDownLineCount();
546 void ListBox::setPosSizePixel( long nX
, long nY
, long nWidth
, long nHeight
, PosSizeFlags nFlags
)
548 if( IsDropDownBox() && ( nFlags
& PosSizeFlags::Size
) )
550 Size aPrefSz
= mpFloatWin
->GetPrefSize();
551 if ( ( nFlags
& PosSizeFlags::Height
) && ( nHeight
>= 2*mnDDHeight
) )
552 aPrefSz
.setHeight( nHeight
-mnDDHeight
);
553 if ( nFlags
& PosSizeFlags::Width
)
554 aPrefSz
.setWidth( nWidth
);
555 mpFloatWin
->SetPrefSize( aPrefSz
);
557 if (IsAutoSizeEnabled())
558 nHeight
= mnDDHeight
;
561 Control::setPosSizePixel( nX
, nY
, nWidth
, nHeight
, nFlags
);
564 void ListBox::Resize()
566 Size aOutSz
= GetOutputSizePixel();
567 if( IsDropDownBox() )
569 // Initialize the dropdown button size with the standard scrollbar width
570 long nSBWidth
= GetSettings().GetStyleSettings().GetScrollBarSize();
571 long nBottom
= aOutSz
.Height();
573 // Note: in case of no border, pBorder will actually be this
574 vcl::Window
*pBorder
= GetWindow( GetWindowType::Border
);
575 ImplControlValue aControlValue
;
577 tools::Rectangle aContent
, aBound
;
579 // Use the full extent of the control
580 tools::Rectangle
aArea( aPoint
, pBorder
->GetOutputSizePixel() );
582 if ( GetNativeControlRegion( ControlType::Listbox
, ControlPart::ButtonDown
,
583 aArea
, ControlState::NONE
, aControlValue
, aBound
, aContent
) )
585 // Convert back from border space to local coordinates
586 aPoint
= pBorder
->ScreenToOutputPixel( OutputToScreenPixel( aPoint
) );
587 aContent
.Move( -aPoint
.X(), -aPoint
.Y() );
589 // Use the themes drop down size for the button
590 aOutSz
.setWidth( aContent
.Left() );
591 mpBtn
->setPosSizePixel( aContent
.Left(), 0, aContent
.GetWidth(), nBottom
);
593 // Adjust the size of the edit field
594 if ( GetNativeControlRegion( ControlType::Listbox
, ControlPart::SubEdit
,
595 aArea
, ControlState::NONE
, aControlValue
, aBound
, aContent
) )
597 // Convert back from border space to local coordinates
598 aContent
.Move( -aPoint
.X(), -aPoint
.Y() );
600 // Use the themes drop down size
601 if( ! (GetStyle() & WB_BORDER
) && ImplGetSVData()->maNWFData
.mbNoFocusRects
)
603 // No border but focus ring behavior -> we have a problem; the
604 // native rect relies on the border to draw the focus
605 // let's do the best we can and center vertically, so it doesn't look
607 Size
aSz( GetOutputSizePixel() );
608 long nDiff
= aContent
.Top() - (aSz
.Height() - aContent
.GetHeight())/2;
609 aContent
.AdjustTop( -nDiff
);
610 aContent
.AdjustBottom( -nDiff
);
612 mpImplWin
->SetPosSizePixel( aContent
.TopLeft(), aContent
.GetSize() );
615 mpImplWin
->SetSizePixel( aOutSz
);
619 nSBWidth
= CalcZoom( nSBWidth
);
620 mpImplWin
->setPosSizePixel( 0, 0, aOutSz
.Width() - nSBWidth
, aOutSz
.Height() );
621 mpBtn
->setPosSizePixel( aOutSz
.Width() - nSBWidth
, 0, nSBWidth
, aOutSz
.Height() );
626 mpImplLB
->SetSizePixel( aOutSz
);
629 // Retain FloatingWindow size even when it's invisible, as we still process KEY_PGUP/DOWN ...
631 mpFloatWin
->SetSizePixel( mpFloatWin
->CalcFloatSize() );
636 void ListBox::FillLayoutData() const
638 mpControlData
->mpLayoutData
.reset( new vcl::ControlLayoutData
);
639 const ImplListBoxWindow
* rMainWin
= mpImplLB
->GetMainWindow();
643 AppendLayoutData( *mpImplWin
);
644 mpImplWin
->SetLayoutDataParent( this );
645 if( mpFloatWin
->IsReallyVisible() )
647 AppendLayoutData( *rMainWin
);
648 rMainWin
->SetLayoutDataParent( this );
653 AppendLayoutData( *rMainWin
);
654 rMainWin
->SetLayoutDataParent( this );
658 long ListBox::GetIndexForPoint( const Point
& rPoint
, sal_Int32
& rPos
) const
660 if( !HasLayoutData() )
663 // Check whether rPoint fits at all
664 long nIndex
= Control::GetIndexForPoint( rPoint
);
667 // Point must be either in main list window
668 // or in impl window (dropdown case)
669 ImplListBoxWindow
* rMain
= mpImplLB
->GetMainWindow();
671 // Convert coordinates to ImplListBoxWindow pixel coordinate space
672 Point aConvPoint
= LogicToPixel( rPoint
);
673 aConvPoint
= OutputToAbsoluteScreenPixel( aConvPoint
);
674 aConvPoint
= rMain
->AbsoluteScreenToOutputPixel( aConvPoint
);
675 aConvPoint
= rMain
->PixelToLogic( aConvPoint
);
678 sal_Int32 nEntry
= rMain
->GetEntryPosForPoint( aConvPoint
);
679 if( nEntry
== LISTBOX_ENTRY_NOTFOUND
)
681 // Not found, maybe dropdown case
682 if( mpImplWin
&& mpImplWin
->IsReallyVisible() )
684 // Convert to impl window pixel coordinates
685 aConvPoint
= LogicToPixel( rPoint
);
686 aConvPoint
= OutputToAbsoluteScreenPixel( aConvPoint
);
687 aConvPoint
= mpImplWin
->AbsoluteScreenToOutputPixel( aConvPoint
);
689 // Check whether converted point is inside impl window
690 Size aImplWinSize
= mpImplWin
->GetOutputSizePixel();
691 if( aConvPoint
.X() >= 0 && aConvPoint
.Y() >= 0 && aConvPoint
.X() < aImplWinSize
.Width() && aConvPoint
.Y() < aImplWinSize
.Height() )
693 // Inside the impl window, the position is the current item pos
694 rPos
= mpImplWin
->GetItemPos();
705 SAL_WARN_IF( nIndex
== -1, "vcl", "found index for point, but relative index failed" );
708 // Get line relative index
710 nIndex
= ToRelativeLineIndex( nIndex
);
715 void ListBox::StateChanged( StateChangedType nType
)
717 if( nType
== StateChangedType::ReadOnly
)
720 mpImplWin
->Enable( !IsReadOnly() );
722 mpBtn
->Enable( !IsReadOnly() );
724 else if( nType
== StateChangedType::Enable
)
726 mpImplLB
->Enable( IsEnabled() );
729 mpImplWin
->Enable( IsEnabled() );
730 if ( IsNativeControlSupported(ControlType::Listbox
, ControlPart::Entire
)
731 && ! IsNativeControlSupported(ControlType::Listbox
, ControlPart::ButtonDown
) )
733 GetWindow( GetWindowType::Border
)->Invalidate( InvalidateFlags::NoErase
);
736 mpImplWin
->Invalidate();
739 mpBtn
->Enable( IsEnabled() );
741 else if( nType
== StateChangedType::UpdateMode
)
743 mpImplLB
->SetUpdateMode( IsUpdateMode() );
745 else if ( nType
== StateChangedType::Zoom
)
747 mpImplLB
->SetZoom( GetZoom() );
750 mpImplWin
->SetZoom( GetZoom() );
751 mpImplWin
->SetFont( mpImplLB
->GetMainWindow()->GetFont() );
752 mpImplWin
->Invalidate();
756 else if ( nType
== StateChangedType::ControlFont
)
758 mpImplLB
->SetControlFont( GetControlFont() );
761 mpImplWin
->SetControlFont( GetControlFont() );
762 mpImplWin
->SetFont( mpImplLB
->GetMainWindow()->GetFont() );
763 mpImplWin
->Invalidate();
767 else if ( nType
== StateChangedType::ControlForeground
)
769 mpImplLB
->SetControlForeground( GetControlForeground() );
772 mpImplWin
->SetControlForeground( GetControlForeground() );
773 mpImplWin
->SetTextColor( GetControlForeground() );
774 mpImplWin
->SetFont( mpImplLB
->GetMainWindow()->GetFont() );
775 mpImplWin
->Invalidate();
778 else if ( nType
== StateChangedType::ControlBackground
)
780 mpImplLB
->SetControlBackground( GetControlBackground() );
783 if ( mpImplWin
->IsNativeControlSupported(ControlType::Listbox
, ControlPart::Entire
) )
785 // Transparent background
786 mpImplWin
->SetBackground();
787 mpImplWin
->SetControlBackground();
791 mpImplWin
->SetBackground( mpImplLB
->GetMainWindow()->GetControlBackground() );
792 mpImplWin
->SetControlBackground( mpImplLB
->GetMainWindow()->GetControlBackground() );
794 mpImplWin
->SetFont( mpImplLB
->GetMainWindow()->GetFont() );
795 mpImplWin
->Invalidate();
798 else if ( nType
== StateChangedType::Style
)
800 SetStyle( ImplInitStyle( GetStyle() ) );
801 mpImplLB
->GetMainWindow()->EnableSort( ( GetStyle() & WB_SORT
) != 0 );
802 bool bSimpleMode
= ( GetStyle() & WB_SIMPLEMODE
) != 0;
803 mpImplLB
->SetMultiSelectionSimpleMode( bSimpleMode
);
805 else if( nType
== StateChangedType::Mirroring
)
809 mpBtn
->EnableRTL( IsRTLEnabled() );
810 ImplInitDropDownButton( mpBtn
);
812 mpImplLB
->EnableRTL( IsRTLEnabled() );
814 mpImplWin
->EnableRTL( IsRTLEnabled() );
818 Control::StateChanged( nType
);
821 bool ListBox::PreNotify( NotifyEvent
& rNEvt
)
826 if( ( rNEvt
.GetType() == MouseNotifyEvent::KEYINPUT
) && ( rNEvt
.GetWindow() == mpImplWin
) )
828 KeyEvent aKeyEvt
= *rNEvt
.GetKeyEvent();
829 switch( aKeyEvt
.GetKeyCode().GetCode() )
833 if( mpFloatWin
&& !mpFloatWin
->IsInPopupMode() &&
834 aKeyEvt
.GetKeyCode().IsMod2() )
836 CallEventListeners( VclEventId::DropdownPreOpen
);
837 mpBtn
->SetPressed( true );
838 mpFloatWin
->StartFloat( false );
839 CallEventListeners( VclEventId::DropdownOpen
);
844 bDone
= mpImplLB
->ProcessKeyInput( aKeyEvt
);
850 if( mpFloatWin
&& mpFloatWin
->IsInPopupMode() &&
851 aKeyEvt
.GetKeyCode().IsMod2() )
853 mpFloatWin
->EndPopupMode();
858 bDone
= mpImplLB
->ProcessKeyInput( aKeyEvt
);
866 mpImplLB
->ProcessKeyInput( aKeyEvt
);
874 bDone
= mpImplLB
->ProcessKeyInput( aKeyEvt
);
878 else if ( rNEvt
.GetType() == MouseNotifyEvent::LOSEFOCUS
)
880 if ( IsInDropDown() && !HasChildPathFocus( true ) )
881 mpFloatWin
->EndPopupMode();
883 else if ( (rNEvt
.GetType() == MouseNotifyEvent::COMMAND
) &&
884 (rNEvt
.GetCommandEvent()->GetCommand() == CommandEventId::Wheel
) &&
885 (rNEvt
.GetWindow() == mpImplWin
) )
887 MouseWheelBehaviour
nWheelBehavior( GetSettings().GetMouseSettings().GetWheelBehavior() );
888 if ( ( nWheelBehavior
== MouseWheelBehaviour::ALWAYS
)
889 || ( ( nWheelBehavior
== MouseWheelBehaviour::FocusOnly
)
890 && HasChildPathFocus()
894 bDone
= mpImplLB
->HandleWheelAsCursorTravel( *rNEvt
.GetCommandEvent() );
898 bDone
= false; // Don't consume this event, let the default handling take it (i.e. scroll the context)
903 return bDone
|| Control::PreNotify( rNEvt
);
906 void ListBox::Select()
908 ImplCallEventListenersAndHandler( VclEventId::ListboxSelect
, [this] () { maSelectHdl
.Call(*this); } );
911 void ListBox::DoubleClick()
913 ImplCallEventListenersAndHandler( VclEventId::ListboxDoubleClick
, [this] () { maDoubleClickHdl
.Call(*this); } );
916 void ListBox::Clear()
921 if( IsDropDownBox() )
923 mpImplWin
->SetItemPos( LISTBOX_ENTRY_NOTFOUND
);
924 mpImplWin
->SetString( OUString() );
926 mpImplWin
->SetImage( aImage
);
927 mpImplWin
->Invalidate();
929 CallEventListeners( VclEventId::ListboxItemRemoved
, reinterpret_cast<void*>(-1) );
932 void ListBox::SetNoSelection()
934 mpImplLB
->SetNoSelection();
935 if( IsDropDownBox() )
937 mpImplWin
->SetItemPos( LISTBOX_ENTRY_NOTFOUND
);
938 mpImplWin
->SetString( OUString() );
940 mpImplWin
->SetImage( aImage
);
941 mpImplWin
->Invalidate();
945 sal_Int32
ListBox::InsertEntry( const OUString
& rStr
, sal_Int32 nPos
)
947 sal_Int32 nRealPos
= mpImplLB
->InsertEntry( nPos
+ mpImplLB
->GetEntryList()->GetMRUCount(), rStr
);
948 nRealPos
= sal::static_int_cast
<sal_Int32
>(nRealPos
- mpImplLB
->GetEntryList()->GetMRUCount());
949 CallEventListeners( VclEventId::ListboxItemAdded
, reinterpret_cast<void*>(nRealPos
) );
953 sal_Int32
ListBox::InsertEntry( const OUString
& rStr
, const Image
& rImage
, sal_Int32 nPos
)
955 sal_Int32 nRealPos
= mpImplLB
->InsertEntry( nPos
+ mpImplLB
->GetEntryList()->GetMRUCount(), rStr
, rImage
);
956 nRealPos
= sal::static_int_cast
<sal_Int32
>(nRealPos
- mpImplLB
->GetEntryList()->GetMRUCount());
957 CallEventListeners( VclEventId::ListboxItemAdded
, reinterpret_cast<void*>(nRealPos
) );
961 void ListBox::RemoveEntry( const OUString
& rStr
)
963 RemoveEntry( GetEntryPos( rStr
) );
966 void ListBox::RemoveEntry( sal_Int32 nPos
)
968 mpImplLB
->RemoveEntry( nPos
+ mpImplLB
->GetEntryList()->GetMRUCount() );
969 CallEventListeners( VclEventId::ListboxItemRemoved
, reinterpret_cast<void*>(nPos
) );
972 Image
ListBox::GetEntryImage( sal_Int32 nPos
) const
974 if ( mpImplLB
&& mpImplLB
->GetEntryList()->HasEntryImage( nPos
) )
975 return mpImplLB
->GetEntryList()->GetEntryImage( nPos
);
979 sal_Int32
ListBox::GetEntryPos( const OUString
& rStr
) const
982 return LISTBOX_ENTRY_NOTFOUND
;
983 sal_Int32 nPos
= mpImplLB
->GetEntryList()->FindEntry( rStr
);
984 if ( nPos
!= LISTBOX_ENTRY_NOTFOUND
)
985 nPos
= nPos
- mpImplLB
->GetEntryList()->GetMRUCount();
989 sal_Int32
ListBox::GetEntryPos( const void* pData
) const
992 return LISTBOX_ENTRY_NOTFOUND
;
993 sal_Int32 nPos
= mpImplLB
->GetEntryList()->FindEntry( pData
);
994 if ( nPos
!= LISTBOX_ENTRY_NOTFOUND
)
995 nPos
= nPos
- mpImplLB
->GetEntryList()->GetMRUCount();
999 OUString
ListBox::GetEntry( sal_Int32 nPos
) const
1003 return mpImplLB
->GetEntryList()->GetEntryText( nPos
+ mpImplLB
->GetEntryList()->GetMRUCount() );
1006 sal_Int32
ListBox::GetEntryCount() const
1010 return mpImplLB
->GetEntryList()->GetEntryCount() - mpImplLB
->GetEntryList()->GetMRUCount();
1013 OUString
ListBox::GetSelectedEntry(sal_Int32 nIndex
) const
1015 return GetEntry( GetSelectedEntryPos( nIndex
) );
1018 sal_Int32
ListBox::GetSelectedEntryCount() const
1022 return mpImplLB
->GetEntryList()->GetSelectedEntryCount();
1025 sal_Int32
ListBox::GetSelectedEntryPos( sal_Int32 nIndex
) const
1027 if (!mpImplLB
|| !mpImplLB
->GetEntryList())
1028 return LISTBOX_ENTRY_NOTFOUND
;
1030 sal_Int32 nPos
= mpImplLB
->GetEntryList()->GetSelectedEntryPos( nIndex
);
1031 if ( nPos
!= LISTBOX_ENTRY_NOTFOUND
)
1033 if ( nPos
< mpImplLB
->GetEntryList()->GetMRUCount() )
1034 nPos
= mpImplLB
->GetEntryList()->FindEntry( mpImplLB
->GetEntryList()->GetEntryText( nPos
) );
1035 nPos
= nPos
- mpImplLB
->GetEntryList()->GetMRUCount();
1040 bool ListBox::IsEntrySelected(const OUString
& rStr
) const
1042 return IsEntryPosSelected( GetEntryPos( rStr
) );
1045 bool ListBox::IsEntryPosSelected( sal_Int32 nPos
) const
1047 return mpImplLB
->GetEntryList()->IsEntryPosSelected( nPos
+ mpImplLB
->GetEntryList()->GetMRUCount() );
1050 void ListBox::SelectEntry( const OUString
& rStr
, bool bSelect
)
1052 SelectEntryPos( GetEntryPos( rStr
), bSelect
);
1055 void ListBox::SelectEntryPos( sal_Int32 nPos
, bool bSelect
)
1060 if ( 0 <= nPos
&& nPos
< mpImplLB
->GetEntryList()->GetEntryCount() )
1062 sal_Int32 nCurrentPos
= mpImplLB
->GetCurrentPos();
1063 mpImplLB
->SelectEntry( nPos
+ mpImplLB
->GetEntryList()->GetMRUCount(), bSelect
);
1064 //Only when bSelect == true, send both Selection & Focus events
1065 if (nCurrentPos
!= nPos
&& bSelect
)
1067 CallEventListeners( VclEventId::ListboxSelect
, reinterpret_cast<void*>(nPos
));
1069 CallEventListeners( VclEventId::ListboxFocus
, reinterpret_cast<void*>(nPos
));
1074 void ListBox::SetEntryData( sal_Int32 nPos
, void* pNewData
)
1076 mpImplLB
->SetEntryData( nPos
+ mpImplLB
->GetEntryList()->GetMRUCount(), pNewData
);
1079 void* ListBox::GetEntryData( sal_Int32 nPos
) const
1081 return mpImplLB
->GetEntryList()->GetEntryData( nPos
+ mpImplLB
->GetEntryList()->GetMRUCount() );
1084 void ListBox::SetEntryFlags( sal_Int32 nPos
, ListBoxEntryFlags nFlags
)
1086 mpImplLB
->SetEntryFlags( nPos
+ mpImplLB
->GetEntryList()->GetMRUCount(), nFlags
);
1089 ListBoxEntryFlags
ListBox::GetEntryFlags( sal_Int32 nPos
) const
1091 return mpImplLB
->GetEntryList()->GetEntryFlags( nPos
+ mpImplLB
->GetEntryList()->GetMRUCount() );
1094 void ListBox::SetTopEntry( sal_Int32 nPos
)
1096 mpImplLB
->SetTopEntry( nPos
+ mpImplLB
->GetEntryList()->GetMRUCount() );
1099 sal_Int32
ListBox::GetTopEntry() const
1101 sal_Int32 nPos
= GetEntryCount() ? mpImplLB
->GetTopEntry() : LISTBOX_ENTRY_NOTFOUND
;
1102 if ( nPos
< mpImplLB
->GetEntryList()->GetMRUCount() )
1107 bool ListBox::IsTravelSelect() const
1109 return mpImplLB
->IsTravelSelect();
1112 bool ListBox::IsInDropDown() const
1114 // when the dropdown is dismissed, first mbInPopupMode is set to false, and on the next event iteration then
1115 // mbPopupMode is set to false
1116 return mpFloatWin
&& mpFloatWin
->IsInPopupMode() && mpFloatWin
->ImplIsInPrivatePopupMode();
1119 tools::Rectangle
ListBox::GetBoundingRectangle( sal_Int32 nItem
) const
1121 tools::Rectangle aRect
= mpImplLB
->GetMainWindow()->GetBoundingRectangle( nItem
);
1122 tools::Rectangle aOffset
= mpImplLB
->GetMainWindow()->GetWindowExtentsRelative( static_cast<vcl::Window
*>(const_cast<ListBox
*>(this)) );
1123 aRect
.Move( aOffset
.TopLeft().X(), aOffset
.TopLeft().Y() );
1127 void ListBox::EnableMultiSelection( bool bMulti
)
1129 EnableMultiSelection( bMulti
, false );
1132 void ListBox::EnableMultiSelection( bool bMulti
, bool bStackSelection
)
1134 mpImplLB
->EnableMultiSelection( bMulti
, bStackSelection
);
1137 // The MultiListBox behaves just like a normal ListBox
1138 // MultiSelection is possible via corresponding additional keys
1139 bool bSimpleMode
= ( GetStyle() & WB_SIMPLEMODE
) != 0;
1140 mpImplLB
->SetMultiSelectionSimpleMode( bSimpleMode
);
1142 // In a MultiSelection, we can't see us travelling without focus
1144 mpImplLB
->GetMainWindow()->AllowGrabFocus( bMulti
);
1147 bool ListBox::IsMultiSelectionEnabled() const
1149 return mpImplLB
->IsMultiSelectionEnabled();
1152 Size
ListBox::CalcMinimumSize() const
1159 aSz
= CalcSubEditSize();
1161 bool bAddScrollWidth
= false;
1163 if (IsDropDownBox())
1165 aSz
.AdjustHeight(4 ); // add a space between entry and border
1166 aSz
.AdjustWidth(4 ); // add a little breathing space
1167 bAddScrollWidth
= true;
1170 bAddScrollWidth
= (GetStyle() & WB_VSCROLL
) == WB_VSCROLL
;
1172 if (bAddScrollWidth
)
1174 // Try native borders; scrollbar size may not be a good indicator
1175 // See how large the edit area inside is to estimate what is needed for the dropdown
1176 ImplControlValue aControlValue
;
1177 tools::Rectangle aContent
, aBound
;
1178 Size
aTestSize( 100, 20 );
1179 tools::Rectangle
aArea( Point(), aTestSize
);
1180 if( GetNativeControlRegion( ControlType::Listbox
, ControlPart::SubEdit
, aArea
, ControlState::NONE
,
1181 aControlValue
, aBound
, aContent
) )
1183 // use the themes drop down size
1184 aSz
.AdjustWidth(aTestSize
.Width() - aContent
.GetWidth() );
1187 aSz
.AdjustWidth(GetSettings().GetStyleSettings().GetScrollBarSize() );
1190 aSz
= CalcWindowSize( aSz
);
1192 if (IsDropDownBox()) // Check minimum height of dropdown box
1194 ImplControlValue aControlValue
;
1195 tools::Rectangle
aRect( Point( 0, 0 ), aSz
);
1196 tools::Rectangle aContent
, aBound
;
1197 if( GetNativeControlRegion( ControlType::Listbox
, ControlPart::Entire
, aRect
, ControlState::NONE
,
1198 aControlValue
, aBound
, aContent
) )
1200 if( aBound
.GetHeight() > aSz
.Height() )
1201 aSz
.setHeight( aBound
.GetHeight() );
1208 Size
ListBox::CalcSubEditSize() const
1215 if ( !IsDropDownBox() )
1216 aSz
= mpImplLB
->CalcSize (mnLineCount
? mnLineCount
: mpImplLB
->GetEntryList()->GetEntryCount());
1219 aSz
.setHeight( mpImplLB
->GetEntryHeight() );
1220 // Size to maximum entry width
1221 aSz
.setWidth( mpImplLB
->GetMaxEntryWidth() );
1223 if (m_nMaxWidthChars
!= -1)
1225 long nMaxWidth
= m_nMaxWidthChars
* approximate_char_width();
1226 aSz
.setWidth( std::min(aSz
.Width(), nMaxWidth
) );
1229 // Do not create ultrathin ListBoxes, it doesn't look good
1230 if( aSz
.Width() < GetSettings().GetStyleSettings().GetScrollBarSize() )
1231 aSz
.setWidth( GetSettings().GetStyleSettings().GetScrollBarSize() );
1237 Size
ListBox::GetOptimalSize() const
1239 return CalcMinimumSize();
1242 Size
ListBox::CalcAdjustedSize( const Size
& rPrefSize
) const
1244 Size aSz
= rPrefSize
;
1245 sal_Int32 nLeft
, nTop
, nRight
, nBottom
;
1246 static_cast<vcl::Window
*>(const_cast<ListBox
*>(this))->GetBorder( nLeft
, nTop
, nRight
, nBottom
);
1247 aSz
.AdjustHeight( -(nTop
+nBottom
) );
1248 if ( !IsDropDownBox() )
1250 long nEntryHeight
= CalcBlockSize( 1, 1 ).Height();
1251 long nLines
= aSz
.Height() / nEntryHeight
;
1254 aSz
.setHeight( nLines
* nEntryHeight
);
1258 aSz
.setHeight( mnDDHeight
);
1260 aSz
.AdjustHeight(nTop
+nBottom
);
1262 aSz
= CalcWindowSize( aSz
);
1266 Size
ListBox::CalcBlockSize( sal_uInt16 nColumns
, sal_uInt16 nLines
) const
1268 // ScrollBars are shown if needed
1269 Size aMinSz
= CalcMinimumSize();
1270 // aMinSz = ImplCalcOutSz( aMinSz );
1277 if ( !IsDropDownBox() )
1278 aSz
.setHeight( mpImplLB
->CalcSize( nLines
).Height() );
1280 aSz
.setHeight( mnDDHeight
);
1283 aSz
.setHeight( aMinSz
.Height() );
1287 aSz
.setWidth( nColumns
* GetTextWidth( OUString('X') ) );
1289 aSz
.setWidth( aMinSz
.Width() );
1291 if ( IsDropDownBox() )
1292 aSz
.AdjustWidth(GetSettings().GetStyleSettings().GetScrollBarSize() );
1294 if ( !IsDropDownBox() )
1296 if ( aSz
.Width() < aMinSz
.Width() )
1297 aSz
.AdjustHeight(GetSettings().GetStyleSettings().GetScrollBarSize() );
1298 if ( aSz
.Height() < aMinSz
.Height() )
1299 aSz
.AdjustWidth(GetSettings().GetStyleSettings().GetScrollBarSize() );
1302 aSz
= CalcWindowSize( aSz
);
1306 void ListBox::GetMaxVisColumnsAndLines( sal_uInt16
& rnCols
, sal_uInt16
& rnLines
) const
1308 float nCharWidth
= approximate_char_width();
1309 if ( !IsDropDownBox() )
1311 Size aOutSz
= mpImplLB
->GetMainWindow()->GetOutputSizePixel();
1312 rnCols
= static_cast<sal_uInt16
>(aOutSz
.Width()/nCharWidth
);
1313 rnLines
= static_cast<sal_uInt16
>(aOutSz
.Height()/mpImplLB
->GetEntryHeightWithMargin());
1317 Size aOutSz
= mpImplWin
->GetOutputSizePixel();
1318 rnCols
= static_cast<sal_uInt16
>(aOutSz
.Width()/nCharWidth
);
1323 IMPL_LINK( ListBox
, ImplUserDrawHdl
, UserDrawEvent
*, pEvent
, void )
1325 UserDraw( *pEvent
);
1328 void ListBox::UserDraw( const UserDrawEvent
& )
1332 void ListBox::DrawEntry(const UserDrawEvent
& rEvt
)
1334 if (rEvt
.GetWindow() == mpImplLB
->GetMainWindow())
1335 mpImplLB
->GetMainWindow()->DrawEntry(*rEvt
.GetRenderContext(), rEvt
.GetItemId(), true/*bDrawImage*/, true/*bDrawText*/, false/*bDrawTextAtImagePos*/ );
1336 else if (rEvt
.GetWindow() == mpImplWin
)
1337 mpImplWin
->DrawEntry(*rEvt
.GetRenderContext(), false/*layout*/);
1340 void ListBox::EnableUserDraw( bool bUserDraw
)
1342 mpImplLB
->GetMainWindow()->EnableUserDraw( bUserDraw
);
1344 mpImplWin
->EnableUserDraw( bUserDraw
);
1347 void ListBox::SetReadOnly( bool bReadOnly
)
1349 if ( mpImplLB
->IsReadOnly() != bReadOnly
)
1351 mpImplLB
->SetReadOnly( bReadOnly
);
1352 CompatStateChanged( StateChangedType::ReadOnly
);
1356 bool ListBox::IsReadOnly() const
1358 return mpImplLB
->IsReadOnly();
1361 void ListBox::SetSeparatorPos( sal_Int32 n
)
1363 mpImplLB
->SetSeparatorPos( n
);
1366 sal_Int32
ListBox::GetSeparatorPos() const
1368 return mpImplLB
->GetSeparatorPos();
1371 void ListBox::AddSeparator( sal_Int32 n
)
1373 mpImplLB
->AddSeparator( n
);
1376 sal_uInt16
ListBox::GetDisplayLineCount() const
1378 return mpImplLB
->GetDisplayLineCount();
1381 void ListBox::EnableMirroring()
1383 mpImplLB
->EnableMirroring();
1386 tools::Rectangle
ListBox::GetDropDownPosSizePixel() const
1388 return mpFloatWin
? mpFloatWin
->GetWindowExtentsRelative( const_cast<ListBox
*>(this) ) : tools::Rectangle();
1391 const Wallpaper
& ListBox::GetDisplayBackground() const
1393 // !!! Recursion does not occur because the ImplListBox is initialized by default
1394 // to a non-transparent color in Window::ImplInitData
1395 return mpImplLB
->GetDisplayBackground();
1398 void ListBox::setMaxWidthChars(sal_Int32 nWidth
)
1400 if (nWidth
!= m_nMaxWidthChars
)
1402 m_nMaxWidthChars
= nWidth
;
1407 bool ListBox::set_property(const OString
&rKey
, const OUString
&rValue
)
1409 if (rKey
== "active")
1410 SelectEntryPos(rValue
.toInt32());
1411 else if (rKey
== "max-width-chars")
1412 setMaxWidthChars(rValue
.toInt32());
1413 else if (rKey
== "can-focus")
1415 // as far as I can see in Gtk, setting a ComboBox as can.focus means
1416 // the focus gets stuck in it, so try here to behave like gtk does
1417 // with the settings that work, i.e. can.focus of false doesn't
1418 // set the hard WB_NOTABSTOP
1419 WinBits nBits
= GetStyle();
1420 nBits
&= ~(WB_TABSTOP
|WB_NOTABSTOP
);
1422 nBits
|= WB_TABSTOP
;
1426 return Control::set_property(rKey
, rValue
);
1430 FactoryFunction
ListBox::GetUITestFactory() const
1432 return ListBoxUIObject::create
;
1435 boost::property_tree::ptree
ListBox::DumpAsPropertyTree()
1437 boost::property_tree::ptree
aTree(Control::DumpAsPropertyTree());
1438 boost::property_tree::ptree aEntries
;
1440 for (int i
= 0; i
< GetEntryCount(); ++i
)
1442 boost::property_tree::ptree aEntry
;
1443 aEntry
.put("", GetEntry(i
));
1444 aEntries
.push_back(std::make_pair("", aEntry
));
1447 aTree
.add_child("entries", aEntries
);
1449 boost::property_tree::ptree aSelected
;
1451 for (int i
= 0; i
< GetSelectedEntryCount(); ++i
)
1453 boost::property_tree::ptree aEntry
;
1454 aEntry
.put("", GetSelectedEntryPos(i
));
1455 aSelected
.push_back(std::make_pair("", aEntry
));
1458 aTree
.put("selectedCount", GetSelectedEntryCount());
1459 aTree
.add_child("selectedEntries", aSelected
);
1464 MultiListBox::MultiListBox( vcl::Window
* pParent
, WinBits nStyle
) :
1465 ListBox( WindowType::MULTILISTBOX
)
1467 ImplInit( pParent
, nStyle
);
1468 EnableMultiSelection( true );
1471 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */