Quellcodebibliothek Statistik Leitseite products/Sources/formale Sprachen/C/LibreOffice/toolkit/source/awt/   (Office von Apache Version 25.8.3.2©)  Datei vom 5.10.2025 mit Größe 217 kB image not shown  

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& _rColorValue )
    {
        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 > &&nbsp;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&&nbsp;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&&nbsp;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;
                    defaultbreak;
                }

            }
        }
        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 > &&nbsp;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&&nbsp;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 );
        }
        catchconst 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.23 Sekunden  (vorverarbeitet)  ¤

*© Formatika GbR, Deutschland






Wurzel

Suchen

Beweissystem der NASA

Beweissystem Isabelle

NIST Cobol Testsuite

Cephes Mathematical Library

Wiener Entwicklungsmethode

Haftungshinweis

Die Informationen auf dieser Webseite wurden nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit, noch Qualität der bereit gestellten Informationen zugesichert.

Bemerkung:

Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.