Quelle vclxwindows.cxx
Sprache: C
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/*
* This file is part of the LibreOffice project.
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
*
* This file incorporates work covered by the following license notice:
*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed
* with this work for additional information regarding copyright
* ownership. The ASF licenses this file to you under the Apache
* License, Version 2.0 (the "License"); you may not use this file
* except in compliance with the License. You may obtain a copy of
* the License at http://www.apache.org/licenses/LICENSE-2.0 .
*/
#include <toolkit/awt/vclxwindows.hxx>
#include <com/sun/star/awt/LineEndFormat.hpp>
#include <com/sun/star/awt/ScrollBarOrientation.hpp>
#include <com/sun/star/graphic/GraphicProvider.hpp>
#include <com/sun/star/graphic/XGraphicProvider.hpp>
#include <toolkit/helper/vclunohelper.hxx>
#include <helper/property.hxx>
#include <com/sun/star/awt/VisualEffect.hpp>
#include <com/sun/star/lang/IndexOutOfBoundsException.hpp>
#include <com/sun/star/resource/XStringResourceResolver.hpp>
#include <com/sun/star/awt/ImageScaleMode.hpp>
#include <com/sun/star/awt/XItemList.hpp>
#include <com/sun/star/awt/TextAlign.hpp>
#include <comphelper/namedvaluecollection.hxx>
#include <comphelper/processfactory.hxx>
#include <sal/log.hxx>
#include <awt/vclxwindows.hxx>
#include <controls/filectrl.hxx>
#include <controls/svmedit.hxx>
#include <vcl/toolkit/button.hxx>
#include <vcl/toolkit/fmtfield.hxx>
#include <vcl/graph.hxx>
#include <vcl/headbar.hxx>
#include <vcl/toolbox.hxx>
#include <vcl/toolkit/lstbox.hxx>
#include <vcl/toolkit/combobox.hxx>
#include <vcl/toolkit/field.hxx>
#include <vcl/toolkit/fixedhyper.hxx>
#include <vcl/toolkit/imgctrl.hxx>
#include <vcl/toolkit/dialog.hxx>
#include <vcl/toolkit/prgsbar.hxx>
#include <vcl/toolkit/scrbar.hxx>
#include <vcl/svapp.hxx>
#include <vcl/tabpage.hxx>
#include <vcl/tabctrl.hxx>
#include <vcl/unohelp.hxx>
#include <vcl/settings.hxx>
#include <comphelper/diagnose_ex.hxx>
#include <tools/debug.hxx>
#include <helper/imagealign.hxx>
#include <helper/msgbox.hxx>
#include <helper/tkresmgr.hxx>
#include "vclxwindows_internal.hxx"
#include <svl/numformat.hxx>
using ::com::sun::star::uno::Any;
using ::com::sun::star::uno::Reference;
using ::com::sun::star::uno::RuntimeException;
using ::com::sun::star::lang::EventObject;
using ::com::sun::star::awt::ItemListEvent;
using ::com::sun::star::awt::XItemList;
using ::com::sun::star::graphic::XGraphic;
using ::com::sun::star::graphic::XGraphicProvider;
using namespace ::com::sun::star;
using namespace ::com::sun::star::awt::VisualEffect;
namespace ImageScaleMode = ::com::sun::star::awt::ImageScaleMode;
static double ImplCalcLongValue(
double nValue, sal_uInt16 nDigits )
{
double n = nValue;
for ( sal_uInt16 d = 0; d < nDigits; d++ )
n *= 10;
return n;
}
static double ImplCalcDoubleValue(
double nValue, sal_uInt16 nDigits )
{
double n = nValue;
for ( sal_uInt16 d = 0; d < nDigits; d++ )
n /= 10;
return n;
}
namespace toolkit
{
/** sets the "face color" for button like controls (scroll bar, spin button)
*/
void setButtonLikeFaceColor( vcl::Window* _pWindow,
const css::uno::Any& _rColorVa
lue )
{
AllSettings aSettings = _pWindow->GetSettings();
StyleSettings aStyleSettings = aSettings.GetStyleSettings();
if ( !_rColorValue.hasValue() )
{
const StyleSettings& aAppStyle = Application::GetSettings().GetStyleSettings();
aStyleSettings.SetFaceColor( aAppStyle.GetFaceColor( ) );
aStyleSettings.SetCheckedColor( aAppStyle.GetCheckedColor( ) );
aStyleSettings.SetLightBorderColor( aAppStyle.GetLightBorderColor() );
aStyleSettings.SetLightColor( aAppStyle.GetLightColor() );
aStyleSettings.SetShadowColor( aAppStyle.GetShadowColor() );
aStyleSettings.SetDarkShadowColor( aAppStyle.GetDarkShadowColor() );
}
else
{
Color nBackgroundColor;
_rColorValue >>= nBackgroundColor;
aStyleSettings.SetFaceColor( nBackgroundColor );
// for the real background (everything except the buttons and the thumb),
// use an average between the desired color and "white"
Color aWhite( COL_WHITE );
Color aCheckedBackground( nBackgroundColor );
aCheckedBackground.SetRed( ( aCheckedBackground.GetRed() + aWhite.GetRed() ) / 2 );
aCheckedBackground.SetGreen( ( aCheckedBackground.GetGreen() + aWhite.GetGreen() ) / 2 );
aCheckedBackground.SetBlue( ( aCheckedBackground.GetBlue() + aWhite.GetBlue() ) / 2 );
aStyleSettings.SetCheckedColor( aCheckedBackground );
sal_Int32 nBackgroundLuminance = nBackgroundColor.GetLuminance();
sal_Int32 nWhiteLuminance = COL_WHITE.GetLuminance();
Color aLightShadow( nBackgroundColor );
aLightShadow.IncreaseLuminance( static_cast <sal_uInt8>( ( nWhiteLuminance - nBackgroundLuminance ) * 2 / 3 ) );
aStyleSettings.SetLightBorderColor( aLightShadow );
Color aLight( nBackgroundColor );
aLight.IncreaseLuminance( static_cast <sal_uInt8>( ( nWhiteLuminance - nBackgroundLuminance ) * 1 / 3 ) );
aStyleSettings.SetLightColor( aLight );
Color aShadow( nBackgroundColor );
aShadow.DecreaseLuminance( static_cast <sal_uInt8>( nBackgroundLuminance * 1 / 3 ) );
aStyleSettings.SetShadowColor( aShadow );
Color aDarkShadow( nBackgroundColor );
aDarkShadow.DecreaseLuminance( static_cast <sal_uInt8>( nBackgroundLuminance * 2 / 3 ) );
aStyleSettings.SetDarkShadowColor( aDarkShadow );
}
aSettings.SetStyleSettings( aStyleSettings );
_pWindow->SetSettings( aSettings, true );
}
Any getButtonLikeFaceColor( const vcl::Window* _pWindow )
{
Color nBackgroundColor = _pWindow->GetSettings().GetStyleSettings().GetFaceColor();
return Any( sal_Int32(nBackgroundColor) );
}
static void adjustBooleanWindowStyle( const Any& _rValue, vcl::Window* _pWindow, WinBits _nBits, bool _bInverseSemantics )
{
WinBits nStyle = _pWindow->GetStyle();
bool bValue( false );
OSL_VERIFY( _rValue >>= bValue );
if ( bValue != _bInverseSemantics )
nStyle |= _nBits;
else
nStyle &= ~_nBits;
_pWindow->SetStyle( nStyle );
}
static void setVisualEffect( const Any& _rValue, vcl::Window* _pWindow )
{
AllSettings aSettings = _pWindow->GetSettings();
StyleSettings aStyleSettings = aSettings.GetStyleSettings();
sal_Int16 nStyle = LOOK3D;
OSL_VERIFY( _rValue >>= nStyle );
switch ( nStyle )
{
case FLAT:
aStyleSettings.SetOptions( aStyleSettings.GetOptions() | StyleSettingsOptions::Mono );
break ;
case LOOK3D:
default :
aStyleSettings.SetOptions( aStyleSettings.GetOptions() & ~StyleSettingsOptions::Mono );
}
aSettings.SetStyleSettings( aStyleSettings );
_pWindow->SetSettings( aSettings );
}
static Any getVisualEffect( vcl::Window const * _pWindow )
{
Any aEffect;
StyleSettings aStyleSettings = _pWindow->GetSettings().GetStyleSettings();
if ( aStyleSettings.GetOptions() & StyleSettingsOptions::Mono )
aEffect <<= sal_Int16(FLAT);
else
aEffect <<= sal_Int16(LOOK3D);
return aEffect;
}
}
void VCLXGraphicControl::ImplGetPropertyIds( std::vector< sal_uInt16 > &rIds )
{
PushPropertyIds(rIds, BASEPROPERTY_REFERER, 0);
VCLXWindow::ImplGetPropertyIds( rIds );
}
void VCLXGraphicControl::ImplSetNewImage()
{
OSL_PRECOND( GetWindow(), "VCLXGraphicControl::ImplSetNewImage: window is required to be not-NULL!" );
VclPtr< Button > pButton = GetAsDynamic< Button >();
pButton->SetModeImage( GetImage() );
}
void VCLXGraphicControl::setPosSize( sal_Int32 X, sal_Int32 Y, sal_Int32 Width, sal_Int32 Height, sal_Int16 Flags )
{
SolarMutexGuard aGuard;
if ( GetWindow() )
{
Size aOldSize = GetWindow()->GetSizePixel();
VCLXWindow::setPosSize( X, Y, Width, Height, Flags );
if ( ( aOldSize.Width() != Width ) || ( aOldSize.Height() != Height ) )
ImplSetNewImage();
}
}
void VCLXGraphicControl::setProperty( const OUString& PropertyName, const css::uno::Any& Value)
{
SolarMutexGuard aGuard;
if ( !GetWindow() )
return ;
sal_uInt16 nPropType = GetPropertyId( PropertyName );
switch ( nPropType )
{
case BASEPROPERTY_GRAPHIC:
{
Reference< XGraphic > xGraphic;
OSL_VERIFY( Value >>= xGraphic );
maImage = Image( xGraphic );
ImplSetNewImage();
}
break ;
case BASEPROPERTY_IMAGEALIGN:
{
WindowType eType = GetWindow()->GetType();
if ( ( eType == WindowType::PUSHBUTTON )
|| ( eType == WindowType::RADIOBUTTON )
|| ( eType == WindowType::CHECKBOX )
)
{
sal_Int16 nAlignment = sal_Int16();
if ( Value >>= nAlignment )
GetAs< Button >()->SetImageAlign( static_cast < ImageAlign >( nAlignment ) );
}
}
break ;
case BASEPROPERTY_IMAGEPOSITION:
{
WindowType eType = GetWindow()->GetType();
if ( ( eType == WindowType::PUSHBUTTON )
|| ( eType == WindowType::RADIOBUTTON )
|| ( eType == WindowType::CHECKBOX )
)
{
sal_Int16 nImagePosition = 2;
OSL_VERIFY( Value >>= nImagePosition );
GetAs<Button>()->SetImageAlign( ::toolkit::translateImagePosition( nImagePosition ) );
}
}
break ;
default :
VCLXWindow::setProperty( PropertyName, Value );
break ;
}
}
css::uno::Any VCLXGraphicControl::getProperty( const OUString& PropertyName )
{
SolarMutexGuard aGuard;
css::uno::Any aProp;
if ( !GetWindow() )
return aProp;
sal_uInt16 nPropType = GetPropertyId( PropertyName );
switch ( nPropType )
{
case BASEPROPERTY_GRAPHIC:
aProp <<= Graphic(maImage.GetBitmapEx()).GetXGraphic();
break ;
case BASEPROPERTY_IMAGEALIGN:
{
WindowType eType = GetWindow()->GetType();
if ( ( eType == WindowType::PUSHBUTTON )
|| ( eType == WindowType::RADIOBUTTON )
|| ( eType == WindowType::CHECKBOX )
)
{
aProp <<= ::toolkit::getCompatibleImageAlign(
GetAs<Button>()->GetImageAlign() );
}
}
break ;
case BASEPROPERTY_IMAGEPOSITION:
{
WindowType eType = GetWindow()->GetType();
if ( ( eType == WindowType::PUSHBUTTON )
|| ( eType == WindowType::RADIOBUTTON )
|| ( eType == WindowType::CHECKBOX )
)
{
aProp <<= ::toolkit::translateImagePosition(
GetAs< Button >()->GetImageAlign() );
}
}
break ;
default :
{
aProp = VCLXWindow::getProperty( PropertyName );
}
break ;
}
return aProp;
}
void VCLXButton::ImplGetPropertyIds( std::vector< sal_uInt16 > &rIds )
{
PushPropertyIds( rIds,
BASEPROPERTY_BACKGROUNDCOLOR,
BASEPROPERTY_DEFAULTBUTTON,
BASEPROPERTY_DEFAULTCONTROL,
BASEPROPERTY_ENABLED,
BASEPROPERTY_ENABLEVISIBLE,
BASEPROPERTY_FONTDESCRIPTOR,
BASEPROPERTY_GRAPHIC,
BASEPROPERTY_HELPTEXT,
BASEPROPERTY_HELPURL,
BASEPROPERTY_IMAGEALIGN,
BASEPROPERTY_IMAGEPOSITION,
BASEPROPERTY_IMAGEURL,
BASEPROPERTY_LABEL,
BASEPROPERTY_PRINTABLE,
BASEPROPERTY_PUSHBUTTONTYPE,
BASEPROPERTY_REPEAT,
BASEPROPERTY_REPEAT_DELAY,
BASEPROPERTY_STATE,
BASEPROPERTY_TABSTOP,
BASEPROPERTY_TOGGLE,
BASEPROPERTY_FOCUSONCLICK,
BASEPROPERTY_MULTILINE,
BASEPROPERTY_ALIGN,
BASEPROPERTY_VERTICALALIGN,
BASEPROPERTY_WRITING_MODE,
BASEPROPERTY_CONTEXT_WRITING_MODE,
BASEPROPERTY_REFERENCE_DEVICE,
0);
VCLXGraphicControl::ImplGetPropertyIds( rIds );
}
VCLXButton::VCLXButton()
:maActionListeners( *this )
,maItemListeners( *this )
{
}
VCLXButton::~VCLXButton()
{
}
void VCLXButton::dispose()
{
SolarMutexGuard aGuard;
css::lang::EventObject aObj;
aObj.Source = getXWeak();
maActionListeners.disposeAndClear( aObj );
maItemListeners.disposeAndClear( aObj );
VCLXGraphicControl::dispose();
}
void VCLXButton::addActionListener( const css::uno::Reference< css::awt::XActionListener > & l )
{
SolarMutexGuard aGuard;
maActionListeners.addInterface( l );
}
void VCLXButton::removeActionListener( const css::uno::Reference< css::awt::XActionListener > & l )
{
SolarMutexGuard aGuard;
maActionListeners.removeInterface( l );
}
void VCLXButton::addItemListener( const css::uno::Reference< css::awt::XItemListener > & l )
{
SolarMutexGuard aGuard;
maItemListeners.addInterface( l );
}
void VCLXButton::removeItemListener( const css::uno::Reference< css::awt::XItemListener > & l )
{
SolarMutexGuard aGuard;
maItemListeners.removeInterface( l );
}
void VCLXButton::setLabel( const OUString& rLabel )
{
SolarMutexGuard aGuard;
VclPtr<vcl::Window> pWindow = GetWindow();
if ( pWindow )
pWindow->SetText( rLabel );
}
void VCLXButton::setActionCommand( const OUString& rCommand )
{
SolarMutexGuard aGuard;
maActionCommand = rCommand;
}
css::awt::Size VCLXButton::getMinimumSize( )
{
SolarMutexGuard aGuard;
Size aSz;
VclPtr< PushButton > pButton = GetAs< PushButton >();
if ( pButton )
aSz = pButton->CalcMinimumSize();
return vcl::unohelper::ConvertToAWTSize(aSz);
}
css::awt::Size VCLXButton::getPreferredSize( )
{
css::awt::Size aSz = getMinimumSize();
aSz.Width += 16;
aSz.Height += 10;
return aSz;
}
css::awt::Size VCLXButton::calcAdjustedSize( const css::awt::Size& rNewSize )
{
SolarMutexGuard aGuard;
Size aSz = vcl::unohelper::ConvertToVCLSize(rNewSize);
VclPtr< PushButton > pButton = GetAs< PushButton >();
if ( pButton )
{
Size aMinSz = pButton->CalcMinimumSize();
// no text, thus image
if ( pButton->GetText().isEmpty() )
{
if ( aSz.Width() < aMinSz.Width() )
aSz.setWidth( aMinSz.Width() );
if ( aSz.Height() < aMinSz.Height() )
aSz.setHeight( aMinSz.Height() );
}
else
{
if ( ( aSz.Width() > aMinSz.Width() ) && ( aSz.Height() < aMinSz.Height() ) )
aSz.setHeight( aMinSz.Height() );
else
aSz = aMinSz;
}
}
return vcl::unohelper::ConvertToAWTSize(aSz);
}
void VCLXButton::setProperty( const OUString& PropertyName, const css::uno::Any& Value)
{
SolarMutexGuard aGuard;
VclPtr< Button > pButton = GetAs< Button >();
if ( !pButton )
return ;
sal_uInt16 nPropType = GetPropertyId( PropertyName );
switch ( nPropType )
{
case BASEPROPERTY_FOCUSONCLICK:
::toolkit::adjustBooleanWindowStyle( Value, pButton, WB_NOPOINTERFOCUS, true );
break ;
case BASEPROPERTY_TOGGLE:
::toolkit::adjustBooleanWindowStyle( Value, pButton, WB_TOGGLE, false );
break ;
case BASEPROPERTY_DEFAULTBUTTON:
{
WinBits nStyle = pButton->GetStyle() | WB_DEFBUTTON;
bool b = bool ();
if ( ( Value >>= b ) && !b )
nStyle &= ~WB_DEFBUTTON;
pButton->SetStyle( nStyle );
}
break ;
case BASEPROPERTY_STATE:
{
if ( GetWindow()->GetType() == WindowType::PUSHBUTTON )
{
sal_Int16 n = sal_Int16();
if ( Value >>= n )
static_cast <PushButton*>(pButton.get())->SetState( static_cast <TriState>(n) );
}
}
break ;
default :
{
VCLXGraphicControl::setProperty( PropertyName, Value );
}
}
}
css::uno::Any VCLXButton::getProperty( const OUString& PropertyName )
{
SolarMutexGuard aGuard;
css::uno::Any aProp;
VclPtr< Button > pButton = GetAs< Button >();
if ( pButton )
{
sal_uInt16 nPropType = GetPropertyId( PropertyName );
switch ( nPropType )
{
case BASEPROPERTY_FOCUSONCLICK:
aProp <<= ( ( pButton->GetStyle() & WB_NOPOINTERFOCUS ) == 0 );
break ;
case BASEPROPERTY_TOGGLE:
aProp <<= ( ( pButton->GetStyle() & WB_TOGGLE ) != 0 );
break ;
case BASEPROPERTY_DEFAULTBUTTON:
{
aProp <<= ( pButton->GetStyle() & WB_DEFBUTTON ) != 0;
}
break ;
case BASEPROPERTY_STATE:
{
if ( GetWindow()->GetType() == WindowType::PUSHBUTTON )
{
aProp <<= static_cast <sal_Int16>(static_cast <PushButton*>(pButton.get())->GetState());
}
}
break ;
default :
{
aProp = VCLXGraphicControl::getProperty( PropertyName );
}
}
}
return aProp;
}
void VCLXButton::ProcessWindowEvent( const VclWindowEvent& rVclWindowEvent )
{
switch ( rVclWindowEvent.GetId() )
{
case VclEventId::ButtonClick:
{
css::uno::Reference< css::awt::XWindow > xKeepAlive( this );
// since we call listeners below, there is a potential that we will be destroyed
// during the listener call. To prevent the resulting crashes, we keep us
// alive as long as we're here
if ( maActionListeners.getLength() )
{
css::awt::ActionEvent aEvent;
aEvent.Source = getXWeak();
aEvent.ActionCommand = maActionCommand;
Callback aCallback = [ this , aEvent=std::move(aEvent) ]()
{ this->maActionListeners.actionPerformed( aEvent ); };
ImplExecuteAsyncWithoutSolarLock( aCallback );
}
}
break ;
case VclEventId::PushbuttonToggle:
{
PushButton& rButton = dynamic_cast < PushButton& >( *rVclWindowEvent.GetWindow() );
css::uno::Reference< css::awt::XWindow > xKeepAlive( this );
if ( maItemListeners.getLength() )
{
css::awt::ItemEvent aEvent;
aEvent.Source = getXWeak();
aEvent.Selected = ( rButton.GetState() == TRISTATE_TRUE ) ? 1 : 0;
maItemListeners.itemStateChanged( aEvent );
}
}
break ;
default :
VCLXGraphicControl::ProcessWindowEvent( rVclWindowEvent );
break ;
}
}
void VCLXImageControl::ImplGetPropertyIds( std::vector< sal_uInt16 > &rIds )
{
PushPropertyIds( rIds,
BASEPROPERTY_BACKGROUNDCOLOR,
BASEPROPERTY_BORDER,
BASEPROPERTY_BORDERCOLOR,
BASEPROPERTY_DEFAULTCONTROL,
BASEPROPERTY_ENABLED,
BASEPROPERTY_ENABLEVISIBLE,
BASEPROPERTY_GRAPHIC,
BASEPROPERTY_HELPTEXT,
BASEPROPERTY_HELPURL,
BASEPROPERTY_IMAGEURL,
BASEPROPERTY_PRINTABLE,
BASEPROPERTY_SCALEIMAGE,
BASEPROPERTY_IMAGE_SCALE_MODE,
BASEPROPERTY_TABSTOP,
BASEPROPERTY_WRITING_MODE,
BASEPROPERTY_CONTEXT_WRITING_MODE,
0);
VCLXGraphicControl::ImplGetPropertyIds( rIds );
}
VCLXImageControl::VCLXImageControl()
{
}
VCLXImageControl::~VCLXImageControl()
{
}
void VCLXImageControl::ImplSetNewImage()
{
OSL_PRECOND( GetWindow(), "VCLXImageControl::ImplSetNewImage: window is required to be not-NULL!" );
VclPtr<ImageControl> pControl = GetAs< ImageControl >();
pControl->SetImage( GetImage() );
}
css::awt::Size VCLXImageControl::getMinimumSize( )
{
SolarMutexGuard aGuard;
Size aSz = GetImage().GetSizePixel();
aSz = ImplCalcWindowSize( aSz );
return vcl::unohelper::ConvertToAWTSize(aSz);
}
css::awt::Size VCLXImageControl::getPreferredSize( )
{
return getMinimumSize();
}
css::awt::Size VCLXImageControl::calcAdjustedSize( const css::awt::Size& rNewSize )
{
SolarMutexGuard aGuard;
css::awt::Size aSz = rNewSize;
css::awt::Size aMinSz = getMinimumSize();
if ( aSz.Width < aMinSz.Width )
aSz.Width = aMinSz.Width;
if ( aSz.Height < aMinSz.Height )
aSz.Height = aMinSz.Height;
return aSz;
}
void VCLXImageControl::setProperty( const OUString& PropertyName, const css::uno::Any& Value)
{
SolarMutexGuard aGuard;
VclPtr< ImageControl > pImageControl = GetAs< ImageControl >();
sal_uInt16 nPropType = GetPropertyId( PropertyName );
switch ( nPropType )
{
case BASEPROPERTY_IMAGE_SCALE_MODE:
{
sal_Int16 nScaleMode( ImageScaleMode::ANISOTROPIC );
if ( pImageControl && ( Value >>= nScaleMode ) )
{
pImageControl->SetScaleMode( nScaleMode );
}
}
break ;
case BASEPROPERTY_SCALEIMAGE:
{
// this is for compatibility only, nowadays, the ImageScaleMode property should be used
bool bScaleImage = false ;
if ( pImageControl && ( Value >>= bScaleImage ) )
{
pImageControl->SetScaleMode( bScaleImage ? ImageScaleMode::ANISOTROPIC : ImageScaleMode::NONE );
}
}
break ;
default :
VCLXGraphicControl::setProperty( PropertyName, Value );
break ;
}
}
css::uno::Any VCLXImageControl::getProperty( const OUString& PropertyName )
{
SolarMutexGuard aGuard;
css::uno::Any aProp;
VclPtr< ImageControl > pImageControl = GetAs< ImageControl >();
sal_uInt16 nPropType = GetPropertyId( PropertyName );
switch ( nPropType )
{
case BASEPROPERTY_IMAGE_SCALE_MODE:
aProp <<= ( pImageControl ? pImageControl->GetScaleMode() : ImageScaleMode::ANISOTROPIC );
break ;
case BASEPROPERTY_SCALEIMAGE:
aProp <<= ( pImageControl && pImageControl->GetScaleMode() != ImageScaleMode::NONE );
break ;
default :
aProp = VCLXGraphicControl::getProperty( PropertyName );
break ;
}
return aProp;
}
void VCLXCheckBox::ImplGetPropertyIds( std::vector< sal_uInt16 > &rIds )
{
PushPropertyIds( rIds,
BASEPROPERTY_DEFAULTCONTROL,
BASEPROPERTY_ENABLED,
BASEPROPERTY_ENABLEVISIBLE,
BASEPROPERTY_FONTDESCRIPTOR,
BASEPROPERTY_GRAPHIC,
BASEPROPERTY_HELPTEXT,
BASEPROPERTY_HELPURL,
BASEPROPERTY_IMAGEPOSITION,
BASEPROPERTY_IMAGEURL,
BASEPROPERTY_LABEL,
BASEPROPERTY_PRINTABLE,
BASEPROPERTY_STATE,
BASEPROPERTY_TABSTOP,
BASEPROPERTY_TRISTATE,
BASEPROPERTY_VISUALEFFECT,
BASEPROPERTY_MULTILINE,
BASEPROPERTY_BACKGROUNDCOLOR,
BASEPROPERTY_ALIGN,
BASEPROPERTY_VERTICALALIGN,
BASEPROPERTY_WRITING_MODE,
BASEPROPERTY_CONTEXT_WRITING_MODE,
BASEPROPERTY_REFERENCE_DEVICE,
0);
VCLXGraphicControl::ImplGetPropertyIds( rIds );
}
VCLXCheckBox::VCLXCheckBox() : maActionListeners( *this ), maItemListeners( *this )
{
}
void VCLXCheckBox::dispose()
{
SolarMutexGuard aGuard;
css::lang::EventObject aObj;
aObj.Source = getXWeak();
maItemListeners.disposeAndClear( aObj );
VCLXGraphicControl::dispose();
}
void VCLXCheckBox::addItemListener( const css::uno::Reference< css::awt::XItemListener > & l )
{
SolarMutexGuard aGuard;
maItemListeners.addInterface( l );
}
void VCLXCheckBox::removeItemListener( const css::uno::Reference< css::awt::XItemListener > & l )
{
SolarMutexGuard aGuard;
maItemListeners.removeInterface( l );
}
void VCLXCheckBox::addActionListener( const css::uno::Reference< css::awt::XActionListener > & l )
{
SolarMutexGuard aGuard;
maActionListeners.addInterface( l );
}
void VCLXCheckBox::removeActionListener( const css::uno::Reference< css::awt::XActionListener > & l )
{
SolarMutexGuard aGuard;
maActionListeners.removeInterface( l );
}
void VCLXCheckBox::setActionCommand( const OUString& rCommand )
{
SolarMutexGuard aGuard;
maActionCommand = rCommand;
}
void VCLXCheckBox::setLabel( const OUString& rLabel )
{
SolarMutexGuard aGuard;
VclPtr<vcl::Window> pWindow = GetWindow();
if ( pWindow )
pWindow->SetText( rLabel );
}
void VCLXCheckBox::setState( sal_Int16 n )
{
SolarMutexGuard aGuard;
VclPtr< CheckBox> pCheckBox = GetAs< CheckBox >();
if ( !pCheckBox)
return ;
TriState eState;
switch ( n )
{
case 0: eState = TRISTATE_FALSE; break ;
case 1: eState = TRISTATE_TRUE; break ;
case 2: eState = TRISTATE_INDET; break ;
default : eState = TRISTATE_FALSE;
}
pCheckBox->SetState( eState );
// #105198# call C++ click listeners (needed for accessibility)
// pCheckBox->GetClickHdl().Call( pCheckBox );
// #107218# Call same virtual methods and listeners like VCL would do after user interaction
SetSynthesizingVCLEvent( true );
pCheckBox->Toggle();
pCheckBox->Click();
SetSynthesizingVCLEvent( false );
}
sal_Int16 VCLXCheckBox::getState()
{
SolarMutexGuard aGuard;
sal_Int16 nState = -1;
VclPtr< CheckBox > pCheckBox = GetAs< CheckBox >();
if ( pCheckBox )
{
switch ( pCheckBox->GetState() )
{
case TRISTATE_FALSE: nState = 0; break ;
case TRISTATE_TRUE: nState = 1; break ;
case TRISTATE_INDET: nState = 2; break ;
default : OSL_FAIL( "VCLXCheckBox::getState(): unknown TriState!" );
}
}
return nState;
}
void VCLXCheckBox::enableTriState( sal_Bool b )
{
SolarMutexGuard aGuard;
VclPtr< CheckBox > pCheckBox = GetAs< CheckBox >();
if ( pCheckBox)
pCheckBox->EnableTriState( b );
}
css::awt::Size VCLXCheckBox::getMinimumSize()
{
SolarMutexGuard aGuard;
Size aSz;
VclPtr< CheckBox > pCheckBox = GetAs< CheckBox >();
if ( pCheckBox )
aSz = pCheckBox->CalcMinimumSize();
return vcl::unohelper::ConvertToAWTSize(aSz);
}
css::awt::Size VCLXCheckBox::getPreferredSize()
{
return getMinimumSize();
}
css::awt::Size VCLXCheckBox::calcAdjustedSize( const css::awt::Size& rNewSize )
{
SolarMutexGuard aGuard;
Size aSz = vcl::unohelper::ConvertToVCLSize(rNewSize);
VclPtr< CheckBox > pCheckBox = GetAs< CheckBox >();
if ( pCheckBox )
{
Size aMinSz = pCheckBox->CalcMinimumSize(rNewSize.Width);
if ( ( aSz.Width() > aMinSz.Width() ) && ( aSz.Height() < aMinSz.Height() ) )
aSz.setHeight( aMinSz.Height() );
else
aSz = aMinSz;
}
return vcl::unohelper::ConvertToAWTSize(aSz);
}
void VCLXCheckBox::setProperty( const OUString& PropertyName, const css::uno::Any& Value)
{
SolarMutexGuard aGuard;
VclPtr< CheckBox > pCheckBox = GetAs< CheckBox >();
if ( !pCheckBox )
return ;
sal_uInt16 nPropType = GetPropertyId( PropertyName );
switch ( nPropType )
{
case BASEPROPERTY_VISUALEFFECT:
::toolkit::setVisualEffect( Value, pCheckBox );
break ;
case BASEPROPERTY_TRISTATE:
{
bool b = bool ();
if ( Value >>= b )
pCheckBox->EnableTriState( b );
}
break ;
case BASEPROPERTY_STATE:
{
sal_Int16 n = sal_Int16();
if ( Value >>= n )
setState( n );
}
break ;
default :
{
VCLXGraphicControl::setProperty( PropertyName, Value );
}
}
}
css::uno::Any VCLXCheckBox::getProperty( const OUString& PropertyName )
{
SolarMutexGuard aGuard;
css::uno::Any aProp;
VclPtr< CheckBox > pCheckBox = GetAs< CheckBox >();
if ( pCheckBox )
{
sal_uInt16 nPropType = GetPropertyId( PropertyName );
switch ( nPropType )
{
case BASEPROPERTY_VISUALEFFECT:
aProp = ::toolkit::getVisualEffect( pCheckBox );
break ;
case BASEPROPERTY_TRISTATE:
aProp <<= pCheckBox->IsTriStateEnabled();
break ;
case BASEPROPERTY_STATE:
aProp <<= static_cast <sal_Int16>(pCheckBox->GetState());
break ;
default :
{
aProp = VCLXGraphicControl::getProperty( PropertyName );
}
}
}
return aProp;
}
void VCLXCheckBox::ProcessWindowEvent( const VclWindowEvent& rVclWindowEvent )
{
switch ( rVclWindowEvent.GetId() )
{
case VclEventId::CheckboxToggle:
{
css::uno::Reference< css::awt::XWindow > xKeepAlive( this );
// since we call listeners below, there is a potential that we will be destroyed
// in during the listener call. To prevent the resulting crashes, we keep us
// alive as long as we're here
VclPtr< CheckBox > pCheckBox = GetAs< CheckBox >();
if ( pCheckBox )
{
if ( maItemListeners.getLength() )
{
css::awt::ItemEvent aEvent;
aEvent.Source = getXWeak();
aEvent.Highlighted = 0;
aEvent.Selected = pCheckBox->GetState();
maItemListeners.itemStateChanged( aEvent );
}
if ( !IsSynthesizingVCLEvent() && maActionListeners.getLength() )
{
css::awt::ActionEvent aEvent;
aEvent.Source = getXWeak();
aEvent.ActionCommand = maActionCommand;
maActionListeners.actionPerformed( aEvent );
}
}
}
break ;
default :
VCLXGraphicControl::ProcessWindowEvent( rVclWindowEvent );
break ;
}
}
void VCLXRadioButton::ImplGetPropertyIds( std::vector< sal_uInt16 > &rIds )
{
PushPropertyIds( rIds,
BASEPROPERTY_DEFAULTCONTROL,
BASEPROPERTY_ENABLED,
BASEPROPERTY_ENABLEVISIBLE,
BASEPROPERTY_FONTDESCRIPTOR,
BASEPROPERTY_GRAPHIC,
BASEPROPERTY_HELPTEXT,
BASEPROPERTY_HELPURL,
BASEPROPERTY_IMAGEPOSITION,
BASEPROPERTY_IMAGEURL,
BASEPROPERTY_LABEL,
BASEPROPERTY_PRINTABLE,
BASEPROPERTY_STATE,
BASEPROPERTY_TABSTOP,
BASEPROPERTY_VISUALEFFECT,
BASEPROPERTY_MULTILINE,
BASEPROPERTY_BACKGROUNDCOLOR,
BASEPROPERTY_ALIGN,
BASEPROPERTY_VERTICALALIGN,
BASEPROPERTY_WRITING_MODE,
BASEPROPERTY_CONTEXT_WRITING_MODE,
BASEPROPERTY_REFERENCE_DEVICE,
BASEPROPERTY_GROUPNAME,
0);
VCLXGraphicControl::ImplGetPropertyIds( rIds );
}
VCLXRadioButton::VCLXRadioButton() : maItemListeners( *this ), maActionListeners( *this )
{
}
void VCLXRadioButton::dispose()
{
SolarMutexGuard aGuard;
css::lang::EventObject aObj;
aObj.Source = getXWeak();
maItemListeners.disposeAndClear( aObj );
VCLXGraphicControl::dispose();
}
void VCLXRadioButton::setProperty( const OUString& PropertyName, const css::uno::Any& Value)
{
SolarMutexGuard aGuard;
VclPtr< RadioButton > pButton = GetAs< RadioButton >();
if ( !pButton )
return ;
sal_uInt16 nPropType = GetPropertyId( PropertyName );
switch ( nPropType )
{
case BASEPROPERTY_VISUALEFFECT:
::toolkit::setVisualEffect( Value, pButton );
break ;
case BASEPROPERTY_STATE:
{
sal_Int16 n = sal_Int16();
if ( Value >>= n )
{
bool b = n != 0;
if ( pButton->IsRadioCheckEnabled() )
pButton->Check( b );
else
pButton->SetState( b );
}
}
break ;
case BASEPROPERTY_AUTOTOGGLE:
{
bool b = bool ();
if ( Value >>= b )
pButton->EnableRadioCheck( b );
}
break ;
default :
{
VCLXGraphicControl::setProperty( PropertyName, Value );
}
}
}
css::uno::Any VCLXRadioButton::getProperty( const OUString& PropertyName )
{
SolarMutexGuard aGuard;
css::uno::Any aProp;
VclPtr< RadioButton > pButton = GetAs< RadioButton >();
if ( pButton )
{
sal_uInt16 nPropType = GetPropertyId( PropertyName );
switch ( nPropType )
{
case BASEPROPERTY_VISUALEFFECT:
aProp = ::toolkit::getVisualEffect( pButton );
break ;
case BASEPROPERTY_STATE:
aProp <<= static_cast <sal_Int16>( pButton->IsChecked() ? 1 : 0 );
break ;
case BASEPROPERTY_AUTOTOGGLE:
aProp <<= pButton->IsRadioCheckEnabled();
break ;
default :
{
aProp = VCLXGraphicControl::getProperty( PropertyName );
}
}
}
return aProp;
}
void VCLXRadioButton::addItemListener( const css::uno::Reference< css::awt::XItemListener > & l )
{
SolarMutexGuard aGuard;
maItemListeners.addInterface( l );
}
void VCLXRadioButton::removeItemListener( const css::uno::Reference< css::awt::XItemListener > & l )
{
SolarMutexGuard aGuard;
maItemListeners.removeInterface( l );
}
void VCLXRadioButton::addActionListener( const css::uno::Reference< css::awt::XActionListener > & l )
{
SolarMutexGuard aGuard;
maActionListeners.addInterface( l );
}
void VCLXRadioButton::removeActionListener( const css::uno::Reference< css::awt::XActionListener > & l )
{
SolarMutexGuard aGuard;
maActionListeners.removeInterface( l );
}
void VCLXRadioButton::setLabel( const OUString& rLabel )
{
SolarMutexGuard aGuard;
VclPtr<vcl::Window> pWindow = GetWindow();
if ( pWindow )
pWindow->SetText( rLabel );
}
void VCLXRadioButton::setActionCommand( const OUString& rCommand )
{
SolarMutexGuard aGuard;
maActionCommand = rCommand;
}
void VCLXRadioButton::setState( sal_Bool b )
{
SolarMutexGuard aGuard;
VclPtr< RadioButton > pRadioButton = GetAs< RadioButton >();
if ( pRadioButton)
{
pRadioButton->Check( b );
// #102717# item listeners are called, but not C++ click listeners in StarOffice code => call click hdl
// But this is needed in old code because Accessibility API uses it.
// pRadioButton->GetClickHdl().Call( pRadioButton );
// #107218# Call same virtual methods and listeners like VCL would do after user interaction
SetSynthesizingVCLEvent( true );
pRadioButton->Click();
SetSynthesizingVCLEvent( false );
}
}
sal_Bool VCLXRadioButton::getState()
{
SolarMutexGuard aGuard;
VclPtr< RadioButton > pRadioButton = GetAs< RadioButton >();
return pRadioButton && pRadioButton->IsChecked();
}
css::awt::Size VCLXRadioButton::getMinimumSize( )
{
SolarMutexGuard aGuard;
Size aSz;
VclPtr< RadioButton > pRadioButton = GetAs< RadioButton >();
if ( pRadioButton )
aSz = pRadioButton->CalcMinimumSize();
return vcl::unohelper::ConvertToAWTSize(aSz);
}
css::awt::Size VCLXRadioButton::getPreferredSize( )
{
return getMinimumSize();
}
css::awt::Size VCLXRadioButton::calcAdjustedSize( const css::awt::Size& rNewSize )
{
SolarMutexGuard aGuard;
Size aSz = vcl::unohelper::ConvertToVCLSize(rNewSize);
VclPtr< RadioButton > pRadioButton = GetAs< RadioButton >();
if ( pRadioButton )
{
Size aMinSz = pRadioButton->CalcMinimumSize(rNewSize.Width);
if ( ( aSz.Width() > aMinSz.Width() ) && ( aSz.Height() < aMinSz.Height() ) )
aSz.setHeight( aMinSz.Height() );
else
aSz = aMinSz;
}
return vcl::unohelper::ConvertToAWTSize(aSz);
}
void VCLXRadioButton::ProcessWindowEvent( const VclWindowEvent& rVclWindowEvent )
{
css::uno::Reference< css::awt::XWindow > xKeepAlive( this );
// since we call listeners below, there is a potential that we will be destroyed
// in during the listener call. To prevent the resulting crashes, we keep us
// alive as long as we're here
switch ( rVclWindowEvent.GetId() )
{
case VclEventId::ButtonClick:
if ( !IsSynthesizingVCLEvent() && maActionListeners.getLength() )
{
css::awt::ActionEvent aEvent;
aEvent.Source = getXWeak();
aEvent.ActionCommand = maActionCommand;
maActionListeners.actionPerformed( aEvent );
}
ImplClickedOrToggled( false );
break ;
case VclEventId::RadiobuttonToggle:
ImplClickedOrToggled( true );
break ;
default :
VCLXGraphicControl::ProcessWindowEvent( rVclWindowEvent );
break ;
}
}
void VCLXRadioButton::ImplClickedOrToggled( bool bToggled )
{
// In the forms, RadioChecked is not enabled, call itemStateChanged only for click
// In the dialog editor, RadioChecked is enabled, call itemStateChanged only for bToggled
VclPtr< RadioButton > pRadioButton = GetAs< RadioButton >();
if ( pRadioButton && ( pRadioButton->IsRadioCheckEnabled() == bToggled ) && ( bToggled || pRadioButton->IsStateChanged() ) && maItemListeners.getLength() )
{
css::awt::ItemEvent aEvent;
aEvent.Source = getXWeak();
aEvent.Highlighted = 0;
aEvent.Selected = pRadioButton->IsChecked() ? 1 : 0;
maItemListeners.itemStateChanged( aEvent );
}
}
void VCLXSpinField::ImplGetPropertyIds( std::vector< sal_uInt16 > &rIds )
{
PushPropertyIds( rIds,
BASEPROPERTY_MOUSE_WHEEL_BEHAVIOUR,
0 );
VCLXEdit::ImplGetPropertyIds( rIds );
}
VCLXSpinField::VCLXSpinField() : maSpinListeners( *this )
{
}
void VCLXSpinField::addSpinListener( const css::uno::Reference< css::awt::XSpinListener > & l )
{
SolarMutexGuard aGuard;
maSpinListeners.addInterface( l );
}
void VCLXSpinField::removeSpinListener( const css::uno::Reference< css::awt::XSpinListener > & l )
{
SolarMutexGuard aGuard;
maSpinListeners.removeInterface( l );
}
void VCLXSpinField::up()
{
SolarMutexGuard aGuard;
VclPtr< SpinField > pSpinField = GetAs< SpinField >();
if ( pSpinField )
pSpinField->Up();
}
void VCLXSpinField::down()
{
SolarMutexGuard aGuard;
VclPtr< SpinField > pSpinField = GetAs< SpinField >();
if ( pSpinField )
pSpinField->Down();
}
void VCLXSpinField::first()
{
SolarMutexGuard aGuard;
VclPtr< SpinField > pSpinField = GetAs< SpinField >();
if ( pSpinField )
pSpinField->First();
}
void VCLXSpinField::last()
{
SolarMutexGuard aGuard;
VclPtr< SpinField > pSpinField = GetAs< SpinField >();
if ( pSpinField )
pSpinField->Last();
}
void VCLXSpinField::enableRepeat( sal_Bool bRepeat )
{
SolarMutexGuard aGuard;
VclPtr<vcl::Window> pWindow = GetWindow();
if ( pWindow )
{
WinBits nStyle = pWindow->GetStyle();
if ( bRepeat )
nStyle |= WB_REPEAT;
else
nStyle &= ~WB_REPEAT;
pWindow->SetStyle( nStyle );
}
}
void VCLXSpinField::ProcessWindowEvent( const VclWindowEvent& rVclWindowEvent )
{
switch ( rVclWindowEvent.GetId() )
{
case VclEventId::SpinfieldUp:
case VclEventId::SpinfieldDown:
case VclEventId::SpinfieldFirst:
case VclEventId::SpinfieldLast:
{
css::uno::Reference< css::awt::XWindow > xKeepAlive( this );
// since we call listeners below, there is a potential that we will be destroyed
// in during the listener call. To prevent the resulting crashes, we keep us
// alive as long as we're here
if ( maSpinListeners.getLength() )
{
css::awt::SpinEvent aEvent;
aEvent.Source = getXWeak();
switch ( rVclWindowEvent.GetId() )
{
case VclEventId::SpinfieldUp: maSpinListeners.up( aEvent );
break ;
case VclEventId::SpinfieldDown: maSpinListeners.down( aEvent );
break ;
case VclEventId::SpinfieldFirst: maSpinListeners.first( aEvent );
break ;
case VclEventId::SpinfieldLast: maSpinListeners.last( aEvent );
break ;
default : break ;
}
}
}
break ;
default :
VCLXEdit::ProcessWindowEvent( rVclWindowEvent );
break ;
}
}
void VCLXListBox::ImplGetPropertyIds( std::vector< sal_uInt16 > &rIds )
{
PushPropertyIds( rIds,
BASEPROPERTY_BACKGROUNDCOLOR,
BASEPROPERTY_BORDER,
BASEPROPERTY_BORDERCOLOR,
BASEPROPERTY_DEFAULTCONTROL,
BASEPROPERTY_DROPDOWN,
BASEPROPERTY_ENABLED,
BASEPROPERTY_ENABLEVISIBLE,
BASEPROPERTY_FONTDESCRIPTOR,
BASEPROPERTY_HELPTEXT,
BASEPROPERTY_HELPURL,
BASEPROPERTY_LINECOUNT,
BASEPROPERTY_MULTISELECTION,
BASEPROPERTY_MULTISELECTION_SIMPLEMODE,
BASEPROPERTY_ITEM_SEPARATOR_POS,
BASEPROPERTY_PRINTABLE,
BASEPROPERTY_SELECTEDITEMS,
BASEPROPERTY_STRINGITEMLIST,
BASEPROPERTY_TYPEDITEMLIST,
BASEPROPERTY_TABSTOP,
BASEPROPERTY_READONLY,
BASEPROPERTY_ALIGN,
BASEPROPERTY_WRITING_MODE,
BASEPROPERTY_CONTEXT_WRITING_MODE,
BASEPROPERTY_REFERENCE_DEVICE,
BASEPROPERTY_MOUSE_WHEEL_BEHAVIOUR,
BASEPROPERTY_HIGHLIGHT_COLOR,
BASEPROPERTY_HIGHLIGHT_TEXT_COLOR,
0);
VCLXWindow::ImplGetPropertyIds( rIds );
}
VCLXListBox::VCLXListBox()
: maActionListeners( *this ),
maItemListeners( *this )
{
}
void VCLXListBox::dispose()
{
SolarMutexGuard aGuard;
css::lang::EventObject aObj;
aObj.Source = getXWeak();
maItemListeners.disposeAndClear( aObj );
maActionListeners.disposeAndClear( aObj );
VCLXWindow::dispose();
}
void VCLXListBox::addItemListener( const css::uno::Reference< css::awt::XItemListener > & l )
{
SolarMutexGuard aGuard;
maItemListeners.addInterface( l );
}
void VCLXListBox::removeItemListener( const css::uno::Reference< css::awt::XItemListener > & l )
{
SolarMutexGuard aGuard;
maItemListeners.removeInterface( l );
}
void VCLXListBox::addActionListener( const css::uno::Reference< css::awt::XActionListener > & l )
{
SolarMutexGuard aGuard;
maActionListeners.addInterface( l );
}
void VCLXListBox::removeActionListener( const css::uno::Reference< css::awt::XActionListener > & l )
{
SolarMutexGuard aGuard;
maActionListeners.removeInterface( l );
}
void VCLXListBox::addItem( const OUString& aItem, sal_Int16 nPos )
{
SolarMutexGuard aGuard;
VclPtr< ListBox > pBox = GetAs< ListBox >();
if ( pBox )
pBox->InsertEntry( aItem, nPos );
}
void VCLXListBox::addItems( const css::uno::Sequence< OUString>& aItems, sal_Int16 nPos )
{
SolarMutexGuard aGuard;
VclPtr< ListBox > pBox = GetAs< ListBox >();
if ( !pBox )
return ;
sal_uInt16 nP = nPos;
for ( auto const & item : aItems )
{
if ( nP == 0xFFFF )
{
OSL_FAIL( "VCLXListBox::addItems: too many entries!" );
// skip remaining entries, list cannot hold them, anyway
break ;
}
pBox->InsertEntry( item, nP++ );
}
}
void VCLXListBox::removeItems( sal_Int16 nPos, sal_Int16 nCount )
{
SolarMutexGuard aGuard;
VclPtr< ListBox > pBox = GetAs< ListBox >();
if ( pBox )
{
for ( sal_Int16 n = nCount; n; )
pBox->RemoveEntry( nPos + (--n) );
}
}
sal_Int16 VCLXListBox::getItemCount()
{
SolarMutexGuard aGuard;
VclPtr< ListBox > pBox = GetAs< ListBox >();
return pBox ? pBox->GetEntryCount() : 0;
}
OUString VCLXListBox::getItem( sal_Int16 nPos )
{
SolarMutexGuard aGuard;
OUString aItem;
VclPtr< ListBox > pBox = GetAs< ListBox >();
if ( pBox )
aItem = pBox->GetEntry( nPos );
return aItem;
}
css::uno::Sequence< OUString> VCLXListBox::getItems()
{
SolarMutexGuard aGuard;
css::uno::Sequence< OUString> aSeq;
VclPtr< ListBox > pBox = GetAs< ListBox >();
if ( pBox )
{
auto n = pBox->GetEntryCount();
aSeq = css::uno::Sequence< OUString>( n );
while (n)
{
--n;
aSeq.getArray()[n] = pBox->GetEntry( n );
}
}
return aSeq;
}
sal_Int16 VCLXListBox::getSelectedItemPos()
{
SolarMutexGuard aGuard;
VclPtr< ListBox > pBox = GetAs< ListBox >();
if (!pBox)
return -1; // nothing selected
sal_Int32 nPos = pBox->GetSelectedEntryPos();
if (nPos == LISTBOX_ENTRY_NOTFOUND)
return -1; // nothing selected
assert(nPos <= SAL_MAX_INT16 && "nPos is out of the range we can represent" );
return nPos;
}
css::uno::Sequence<sal_Int16> VCLXListBox::getSelectedItemsPos()
{
SolarMutexGuard aGuard;
css::uno::Sequence<sal_Int16> aSeq;
VclPtr< ListBox > pBox = GetAs< ListBox >();
if ( pBox )
{
const sal_Int32 nSelEntries = pBox->GetSelectedEntryCount();
aSeq = css::uno::Sequence<sal_Int16>( nSelEntries );
for ( sal_Int32 n = 0; n < nSelEntries; ++n )
aSeq.getArray()[n] = pBox->GetSelectedEntryPos( n );
}
return aSeq;
}
OUString VCLXListBox::getSelectedItem()
{
SolarMutexGuard aGuard;
OUString aItem;
VclPtr< ListBox > pBox = GetAs< ListBox >();
if ( pBox )
aItem = pBox->GetSelectedEntry();
return aItem;
}
css::uno::Sequence< OUString> VCLXListBox::getSelectedItems()
{
SolarMutexGuard aGuard;
css::uno::Sequence< OUString> aSeq;
VclPtr< ListBox > pBox = GetAs< ListBox >();
if ( pBox )
{
const sal_Int32 nSelEntries = pBox->GetSelectedEntryCount();
aSeq = css::uno::Sequence< OUString>( nSelEntries );
for ( sal_Int32 n = 0; n < nSelEntries; ++n )
aSeq.getArray()[n] = pBox->GetSelectedEntry( n );
}
return aSeq;
}
void VCLXListBox::selectItemPos( sal_Int16 nPos, sal_Bool bSelect )
{
SolarMutexGuard aGuard;
VclPtr< ListBox > pBox = GetAs< ListBox >();
if ( pBox && ( pBox->IsEntryPosSelected( nPos ) != bool (bSelect) ) )
{
pBox->SelectEntryPos( nPos, bSelect );
// VCL doesn't call select handler after API call.
// ImplCallItemListeners();
// #107218# Call same listeners like VCL would do after user interaction
SetSynthesizingVCLEvent( true );
pBox->Select();
SetSynthesizingVCLEvent( false );
}
}
void VCLXListBox::selectItemsPos( const css::uno::Sequence<sal_Int16>& aPositions, sal_Bool bSelect )
{
SolarMutexGuard aGuard;
VclPtr< ListBox > pBox = GetAs< ListBox >();
if ( !pBox )
return ;
std::vector<sal_Int32> aPositionVec;
aPositionVec.reserve(aPositions.getLength());
bool bChanged = false ;
for ( auto n = aPositions.getLength(); n; )
{
const auto nPos = aPositions.getConstArray()[--n];
if ( pBox->IsEntryPosSelected( nPos ) != bool (bSelect) )
{
aPositionVec.push_back(nPos);
bChanged = true ;
}
}
if ( !bChanged )
return ;
bool bOrigUpdateMode = pBox->IsUpdateMode();
pBox->SetUpdateMode(false );
pBox->SelectEntriesPos(aPositionVec, bSelect);
pBox->SetUpdateMode(bOrigUpdateMode);
// VCL doesn't call select handler after API call.
// ImplCallItemListeners();
// #107218# Call same listeners like VCL would do after user interaction
SetSynthesizingVCLEvent( true );
pBox->Select();
SetSynthesizingVCLEvent( false );
}
void VCLXListBox::selectItem( const OUString& rItemText, sal_Bool bSelect )
{
SolarMutexGuard aGuard;
VclPtr< ListBox > pBox = GetAs< ListBox >();
if ( pBox )
{
selectItemPos( pBox->GetEntryPos( rItemText ), bSelect );
}
}
void VCLXListBox::setDropDownLineCount( sal_Int16 nLines )
{
SolarMutexGuard aGuard;
VclPtr< ListBox > pBox = GetAs< ListBox >();
if ( pBox )
pBox->SetDropDownLineCount( nLines );
}
sal_Int16 VCLXListBox::getDropDownLineCount()
{
SolarMutexGuard aGuard;
sal_Int16 nLines = 0;
VclPtr< ListBox > pBox = GetAs< ListBox >();
if ( pBox )
nLines = pBox->GetDropDownLineCount();
return nLines;
}
sal_Bool VCLXListBox::isMutipleMode()
{
SolarMutexGuard aGuard;
bool bMulti = false ;
VclPtr< ListBox > pBox = GetAs< ListBox >();
if ( pBox )
bMulti = pBox->IsMultiSelectionEnabled();
return bMulti;
}
void VCLXListBox::setMultipleMode( sal_Bool bMulti )
{
SolarMutexGuard aGuard;
VclPtr< ListBox > pBox = GetAs< ListBox >();
if ( pBox )
pBox->EnableMultiSelection( bMulti );
}
void VCLXListBox::makeVisible( sal_Int16 nEntry )
{
SolarMutexGuard aGuard;
VclPtr< ListBox > pBox = GetAs< ListBox >();
if ( pBox )
pBox->SetTopEntry( nEntry );
}
void VCLXListBox::ProcessWindowEvent( const VclWindowEvent& rVclWindowEvent )
{
css::uno::Reference< css::awt::XWindow > xKeepAlive( this );
// since we call listeners below, there is a potential that we will be destroyed
// in during the listener call. To prevent the resulting crashes, we keep us
// alive as long as we're here
switch ( rVclWindowEvent.GetId() )
{
case VclEventId::ListboxSelect:
{
VclPtr< ListBox > pListBox = GetAs< ListBox >();
if ( pListBox )
{
bool bDropDown = ( pListBox->GetStyle() & WB_DROPDOWN ) != 0;
if ( bDropDown && !IsSynthesizingVCLEvent() && maActionListeners.getLength() )
{
// Call ActionListener on DropDown event
css::awt::ActionEvent aEvent;
aEvent.Source = getXWeak();
aEvent.ActionCommand = pListBox->GetSelectedEntry();
maActionListeners.actionPerformed( aEvent );
}
if ( maItemListeners.getLength() )
{
ImplCallItemListeners();
}
}
}
break ;
case VclEventId::ListboxDoubleClick:
if ( GetWindow() && maActionListeners.getLength() )
{
css::awt::ActionEvent aEvent;
aEvent.Source = getXWeak();
aEvent.ActionCommand = GetAs<ListBox>()->GetSelectedEntry();
maActionListeners.actionPerformed( aEvent );
}
break ;
default :
VCLXWindow::ProcessWindowEvent( rVclWindowEvent );
break ;
}
}
void VCLXListBox::setProperty( const OUString& PropertyName, const css::uno::Any& Value)
{
SolarMutexGuard aGuard;
VclPtr< ListBox > pListBox = GetAs< ListBox >();
if ( !pListBox )
return ;
sal_uInt16 nPropType = GetPropertyId( PropertyName );
switch ( nPropType )
{
case BASEPROPERTY_ITEM_SEPARATOR_POS:
{
sal_Int16 nSeparatorPos(0);
if ( Value >>= nSeparatorPos )
pListBox->SetSeparatorPos( nSeparatorPos );
}
break ;
case BASEPROPERTY_READONLY:
{
bool b = false ;
if ( Value >>= b )
pListBox->SetReadOnly( b);
}
break ;
case BASEPROPERTY_MULTISELECTION:
{
bool b = false ;
if ( Value >>= b )
pListBox->EnableMultiSelection( b );
}
break ;
case BASEPROPERTY_MULTISELECTION_SIMPLEMODE:
::toolkit::adjustBooleanWindowStyle( Value, pListBox, WB_SIMPLEMODE, false );
break ;
case BASEPROPERTY_LINECOUNT:
{
sal_Int16 n = 0;
if ( Value >>= n )
pListBox->SetDropDownLineCount( n );
}
break ;
case BASEPROPERTY_STRINGITEMLIST:
{
css::uno::Sequence< OUString> aItems;
if ( Value >>= aItems )
{
pListBox->Clear();
addItems( aItems, 0 );
}
}
break ;
case BASEPROPERTY_SELECTEDITEMS:
{
css::uno::Sequence<sal_Int16> aItems;
if ( Value >>= aItems )
{
for ( auto n = pListBox->GetEntryCount(); n; )
pListBox->SelectEntryPos( --n, false );
if ( aItems.hasElements() )
selectItemsPos( aItems, true );
else
pListBox->SetNoSelection();
if ( !pListBox->GetSelectedEntryCount() )
pListBox->SetTopEntry( 0 );
}
}
break ;
case BASEPROPERTY_HIGHLIGHT_COLOR:
{
Color nColor = 0;
bool bVoid = Value.getValueTypeClass() == css::uno::TypeClass_VOID;
if (bVoid)
{
nColor = Application::GetSettings().GetStyleSettings().GetHighlightColor();
}
else
{
if (!(Value >>= nColor))
break ;
}
pListBox->SetHighlightColor(nColor);
}
break ;
case BASEPROPERTY_HIGHLIGHT_TEXT_COLOR:
{
Color nColor = 0;
bool bVoid = Value.getValueTypeClass() == css::uno::TypeClass_VOID;
if (bVoid)
{
nColor = Application::GetSettings().GetStyleSettings().GetHighlightTextColor();
}
else
{
if (!(Value >>= nColor))
break ;
}
pListBox->SetHighlightTextColor(nColor);
}
break ;
default :
{
VCLXWindow::setProperty( PropertyName, Value );
}
}
}
css::uno::Any VCLXListBox::getProperty( const OUString& PropertyName )
{
SolarMutexGuard aGuard;
css::uno::Any aProp;
VclPtr< ListBox > pListBox = GetAs< ListBox >();
if ( pListBox )
{
sal_uInt16 nPropType = GetPropertyId( PropertyName );
switch ( nPropType )
{
case BASEPROPERTY_ITEM_SEPARATOR_POS:
aProp <<= sal_Int16( pListBox->GetSeparatorPos() );
break ;
case BASEPROPERTY_READONLY:
{
aProp <<= pListBox->IsReadOnly();
}
break ;
case BASEPROPERTY_MULTISELECTION:
{
aProp <<= pListBox->IsMultiSelectionEnabled();
}
break ;
case BASEPROPERTY_MULTISELECTION_SIMPLEMODE:
{
aProp <<= ( ( pListBox->GetStyle() & WB_SIMPLEMODE ) == 0 );
}
break ;
case BASEPROPERTY_LINECOUNT:
{
aProp <<= static_cast <sal_Int16>(pListBox->GetDropDownLineCount());
}
break ;
case BASEPROPERTY_STRINGITEMLIST:
{
const sal_Int32 nItems = pListBox->GetEntryCount();
css::uno::Sequence< OUString> aSeq( nItems );
OUString* pStrings = aSeq.getArray();
for ( sal_Int32 n = 0; n < nItems; ++n )
pStrings[n] = pListBox->GetEntry( n );
aProp <<= aSeq;
}
break ;
default :
{
aProp = VCLXWindow::getProperty( PropertyName );
}
}
}
return aProp;
}
css::awt::Size VCLXListBox::getMinimumSize( )
{
SolarMutexGuard aGuard;
Size aSz;
VclPtr< ListBox > pListBox = GetAs< ListBox >();
if ( pListBox )
aSz = pListBox->CalcMinimumSize();
return vcl::unohelper::ConvertToAWTSize(aSz);
}
css::awt::Size VCLXListBox::getPreferredSize( )
{
SolarMutexGuard aGuard;
Size aSz;
VclPtr< ListBox > pListBox = GetAs< ListBox >();
if ( pListBox )
{
aSz = pListBox->CalcMinimumSize();
if ( pListBox->GetStyle() & WB_DROPDOWN )
aSz.AdjustHeight(4 );
}
return vcl::unohelper::ConvertToAWTSize(aSz);
}
css::awt::Size VCLXListBox::calcAdjustedSize( const css::awt::Size& rNewSize )
{
SolarMutexGuard aGuard;
Size aSz = vcl::unohelper::ConvertToVCLSize(rNewSize);
VclPtr< ListBox > pListBox = GetAs< ListBox >();
if ( pListBox )
aSz = pListBox->CalcAdjustedSize( aSz );
return vcl::unohelper::ConvertToAWTSize(aSz);
}
css::awt::Size VCLXListBox::getMinimumSize( sal_Int16 nCols, sal_Int16 nLines )
{
SolarMutexGuard aGuard;
Size aSz;
VclPtr< ListBox > pListBox = GetAs< ListBox >();
if ( pListBox )
aSz = pListBox->CalcBlockSize( nCols, nLines );
return vcl::unohelper::ConvertToAWTSize(aSz);
}
void VCLXListBox::getColumnsAndLines( sal_Int16& nCols, sal_Int16& nLines )
{
SolarMutexGuard aGuard;
nCols = nLines = 0;
VclPtr< ListBox > pListBox = GetAs< ListBox >();
if ( pListBox )
{
sal_uInt16 nC, nL;
pListBox->GetMaxVisColumnsAndLines( nC, nL );
nCols = nC;
nLines = nL;
}
}
void VCLXListBox::ImplCallItemListeners()
{
VclPtr< ListBox > pListBox = GetAs< ListBox >();
if ( pListBox && maItemListeners.getLength() )
{
css::awt::ItemEvent aEvent;
aEvent.Source = getXWeak();
aEvent.Highlighted = 0;
// Set to 0xFFFF on multiple selection, selected entry ID otherwise
aEvent.Selected = (pListBox->GetSelectedEntryCount() == 1 ) ? pListBox->GetSelectedEntryPos() : 0xFFFF;
maItemListeners.itemStateChanged( aEvent );
}
}
namespace
{
Image lcl_getImageFromURL( const OUString& i_rImageURL )
{
if ( i_rImageURL.isEmpty() )
return Image();
try
{
const Reference< uno::XComponentContext >& xContext( ::comphelper::getProcessComponentContext() );
Reference< XGraphicProvider > xProvider(graphic::GraphicProvider::create(xContext));
::comphelper::NamedValueCollection aMediaProperties;
aMediaProperties.put( u"URL" _ustr, i_rImageURL );
Reference< XGraphic > xGraphic = xProvider->queryGraphic( aMediaProperties.getPropertyValues() );
return Image( xGraphic );
}
catch ( const uno::Exception& )
{
DBG_UNHANDLED_EXCEPTION("toolkit" );
}
return Image();
}
}
void SAL_CALL VCLXListBox::listItemInserted( const ItemListEvent& i_rEvent )
{
SolarMutexGuard aGuard;
VclPtr< ListBox > pListBox = GetAs< ListBox >();
ENSURE_OR_RETURN_VOID( pListBox, "VCLXListBox::listItemInserted: no ListBox?!" );
ENSURE_OR_RETURN_VOID( ( i_rEvent.ItemPosition >= 0 ) && ( i_rEvent.ItemPosition <= pListBox->GetEntryCount() ),
"VCLXListBox::listItemInserted: illegal (inconsistent) item position!" );
pListBox->InsertEntry(
i_rEvent.ItemText.IsPresent ? i_rEvent.ItemText.Value : OUString(),
i_rEvent.ItemImageURL.IsPresent ? TkResMgr::getImageFromURL( i_rEvent.ItemImageURL.Value ) : Image(),
i_rEvent.ItemPosition );
}
void SAL_CALL VCLXListBox::listItemRemoved( const ItemListEvent& i_rEvent )
{
SolarMutexGuard aGuard;
VclPtr< ListBox > pListBox = GetAs< ListBox >();
ENSURE_OR_RETURN_VOID( pListBox, "VCLXListBox::listItemRemoved: no ListBox?!" );
ENSURE_OR_RETURN_VOID( ( i_rEvent.ItemPosition >= 0 ) && ( i_rEvent.ItemPosition < pListBox->GetEntryCount() ),
"VCLXListBox::listItemRemoved: illegal (inconsistent) item position!" );
pListBox->RemoveEntry( i_rEvent.ItemPosition );
}
void SAL_CALL VCLXListBox::listItemModified( const ItemListEvent& i_rEvent )
{
SolarMutexGuard aGuard;
VclPtr< ListBox > pListBox = GetAs< ListBox >();
ENSURE_OR_RETURN_VOID( pListBox, "VCLXListBox::listItemModified: no ListBox?!" );
ENSURE_OR_RETURN_VOID( ( i_rEvent.ItemPosition >= 0 ) && ( i_rEvent.ItemPosition < pListBox->GetEntryCount() ),
"VCLXListBox::listItemModified: illegal (inconsistent) item position!" );
// VCL's ListBox does not support changing an entry's text or image, so remove and re-insert
const OUString sNewText = i_rEvent.ItemText.IsPresent ? i_rEvent.ItemText.Value : pListBox->GetEntry( i_rEvent.ItemPosition );
const Image aNewImage( i_rEvent.ItemImageURL.IsPresent ? TkResMgr::getImageFromURL( i_rEvent.ItemImageURL.Value ) : pListBox->GetEntryImage( i_rEvent.ItemPosition ) );
pListBox->RemoveEntry( i_rEvent.ItemPosition );
pListBox->InsertEntry( sNewText, aNewImage, i_rEvent.ItemPosition );
}
void SAL_CALL VCLXListBox::allItemsRemoved( const EventObject& )
{
SolarMutexGuard aGuard;
VclPtr< ListBox > pListBox = GetAs< ListBox >();
ENSURE_OR_RETURN_VOID( pListBox, "VCLXListBox::listItemModified: no ListBox?!" );
pListBox->Clear();
}
void SAL_CALL VCLXListBox::itemListChanged( const EventObject& i_rEvent )
{
SolarMutexGuard aGuard;
VclPtr< ListBox > pListBox = GetAs< ListBox >();
ENSURE_OR_RETURN_VOID( pListBox, "VCLXListBox::listItemModified: no ListBox?!" );
pListBox->Clear();
uno::Reference< beans::XPropertySet > xPropSet( i_rEvent.Source, uno::UNO_QUERY_THROW );
uno::Reference< beans::XPropertySetInfo > xPSI( xPropSet->getPropertySetInfo(), uno::UNO_SET_THROW );
uno::Reference< resource::XStringResourceResolver > xStringResourceResolver;
if ( xPSI->hasPropertyByName(u"ResourceResolver" _ustr) )
{
xStringResourceResolver.set(
xPropSet->getPropertyValue(u"ResourceResolver" _ustr),
uno::UNO_QUERY
);
}
Reference< XItemList > xItemList( i_rEvent.Source, uno::UNO_QUERY_THROW );
const uno::Sequence< beans::Pair< OUString, OUString > > aItems = xItemList->getAllItems();
for ( const auto & rItem : aItems )
{
OUString aLocalizationKey( rItem.First );
if ( xStringResourceResolver.is() && aLocalizationKey.startsWith("&" ) )
{
aLocalizationKey = xStringResourceResolver->resolveString(aLocalizationKey.copy( 1 ));
}
--> --------------------
--> maximum size reached
--> --------------------
Messung V0.5 C=94 H=98 G=95
¤ Dauer der Verarbeitung: 0.29 Sekunden
(vorverarbeitet)
¤
*© Formatika GbR, Deutschland
2026-04-04