/**************************************************************
 *
 * 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
 *
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied.  See the License for the
 * specific language governing permissions and limitations
 * under the License.
 *
 *************************************************************/



// MARKER(update_precomp.py): autogen include statement, do not remove
#include "precompiled_toolkit.hxx"
#include <toolkit/awt/vclxwindows.hxx>
#include <com/sun/star/awt/ScrollBarOrientation.hpp>
#include <com/sun/star/graphic/XGraphicProvider.hpp>
#include <toolkit/helper/vclunohelper.hxx>
#include <toolkit/helper/macros.hxx>
#include <toolkit/helper/property.hxx>
#include <toolkit/helper/convert.hxx>
#include <toolkit/helper/imagealign.hxx>
#include <toolkit/helper/accessibilityclient.hxx>
#include <toolkit/helper/fixedhyperbase.hxx>
#include <toolkit/helper/tkresmgr.hxx>
#include <cppuhelper/typeprovider.hxx>
#include <com/sun/star/awt/VisualEffect.hpp>
#include <com/sun/star/lang/XMultiServiceFactory.hpp>
#include <com/sun/star/system/SystemShellExecute.hpp>
#include <com/sun/star/system/SystemShellExecuteFlags.hpp>
#include <com/sun/star/resource/XStringResourceResolver.hpp>
#include <com/sun/star/awt/ImageScaleMode.hpp>
#include <com/sun/star/awt/XItemList.hpp>
#include <comphelper/componentcontext.hxx>
#include <comphelper/namedvaluecollection.hxx>
#include <comphelper/processfactory.hxx>

#ifndef _SV_BUTTON_HXX
#include <vcl/button.hxx>
#endif
#include <vcl/lstbox.hxx>
#include <vcl/combobox.hxx>
#include <vcl/field.hxx>
#include <vcl/longcurr.hxx>
#include <vcl/imgctrl.hxx>
#include <vcl/dialog.hxx>
#include <vcl/msgbox.hxx>
#include <vcl/scrbar.hxx>
#include <vcl/svapp.hxx>
#include <vcl/tabpage.hxx>
#include <vcl/tabctrl.hxx>
#include <tools/diagnose_ex.h>

#include <boost/bind.hpp>
#include <boost/function.hpp>

using ::com::sun::star::uno::Any;
using ::com::sun::star::uno::Reference;
using ::com::sun::star::uno::makeAny;
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( Window* _pWindow, const ::com::sun::star::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
        {
			sal_Int32 nBackgroundColor = 0;
            _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 aBackground( nBackgroundColor );
            aBackground.SetRed( ( aBackground.GetRed() + aWhite.GetRed() ) / 2 );
            aBackground.SetGreen( ( aBackground.GetGreen() + aWhite.GetGreen() ) / 2 );
            aBackground.SetBlue( ( aBackground.GetBlue() + aWhite.GetBlue() ) / 2 );
            aStyleSettings.SetCheckedColor( aBackground );

            sal_Int32 nBackgroundLuminance = Color( nBackgroundColor ).GetLuminance();
            sal_Int32 nWhiteLuminance = Color( COL_WHITE ).GetLuminance();

            Color aLightShadow( nBackgroundColor );
            aLightShadow.IncreaseLuminance( (sal_uInt8)( ( nWhiteLuminance - nBackgroundLuminance ) * 2 / 3 ) );
            aStyleSettings.SetLightBorderColor( aLightShadow );

            Color aLight( nBackgroundColor );
            aLight.IncreaseLuminance( (sal_uInt8)( ( nWhiteLuminance - nBackgroundLuminance ) * 1 / 3 ) );
            aStyleSettings.SetLightColor( aLight );

            Color aShadow( nBackgroundColor );
            aShadow.DecreaseLuminance( (sal_uInt8)( nBackgroundLuminance * 1 / 3 ) );
            aStyleSettings.SetShadowColor( aShadow );

            Color aDarkShadow( nBackgroundColor );
            aDarkShadow.DecreaseLuminance( (sal_uInt8)( nBackgroundLuminance * 2 / 3 ) );
            aStyleSettings.SetDarkShadowColor( aDarkShadow );
        }

        aSettings.SetStyleSettings( aStyleSettings );
        _pWindow->SetSettings( aSettings, sal_True );
    }

    Any getButtonLikeFaceColor( const Window* _pWindow )
    {
		sal_Int32 nBackgroundColor = _pWindow->GetSettings().GetStyleSettings().GetFaceColor().GetColor();
        return makeAny( nBackgroundColor );
    }

    static void adjustBooleanWindowStyle( const Any& _rValue, Window* _pWindow, WinBits _nBits, sal_Bool _bInverseSemantics )
    {
        WinBits nStyle = _pWindow->GetStyle();
        sal_Bool bValue( sal_False );
        OSL_VERIFY( _rValue >>= bValue );
        if ( bValue != _bInverseSemantics )
            nStyle |= _nBits;
        else
            nStyle &= ~_nBits;
        _pWindow->SetStyle( nStyle );
    }

    static void setVisualEffect( const Any& _rValue, 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() & ~STYLE_OPTION_MONO );
            break;
        case LOOK3D:
        default:
            aStyleSettings.SetOptions( aStyleSettings.GetOptions() | STYLE_OPTION_MONO );
        }
        aSettings.SetStyleSettings( aStyleSettings );
        _pWindow->SetSettings( aSettings );
    }

    static Any getVisualEffect( Window* _pWindow )
    {
        Any aEffect;

        StyleSettings aStyleSettings = _pWindow->GetSettings().GetStyleSettings();
        if ( (aStyleSettings.GetOptions() & STYLE_OPTION_MONO) )
            aEffect <<= (sal_Int16)FLAT;
        else
            aEffect <<= (sal_Int16)LOOK3D;
        return aEffect;
    }
}

//	----------------------------------------------------
//	class VCLXGraphicControl
//	----------------------------------------------------

void VCLXGraphicControl::ImplGetPropertyIds( std::list< sal_uInt16 > &rIds )
{
    VCLXWindow::ImplGetPropertyIds( rIds );
}

void VCLXGraphicControl::ImplSetNewImage()
{
    OSL_PRECOND( GetWindow(), "VCLXGraphicControl::ImplSetNewImage: window is required to be not-NULL!" );
	Button* pButton = static_cast< Button* >( GetWindow() );
	pButton->SetModeImage( GetImage() );
}

void VCLXGraphicControl::setPosSize( sal_Int32 X, sal_Int32 Y, sal_Int32 Width, sal_Int32 Height, short Flags ) throw(::com::sun::star::uno::RuntimeException)
{
	::vos::OGuard aGuard( GetMutex() );

	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 ::rtl::OUString& PropertyName, const ::com::sun::star::uno::Any& Value) throw(::com::sun::star::uno::RuntimeException)
{
	::vos::OGuard aGuard( GetMutex() );

	Button* pButton = static_cast< Button* >( GetWindow() );
    if ( !pButton )
        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 == WINDOW_PUSHBUTTON )
               || ( eType == WINDOW_RADIOBUTTON )
               || ( eType == WINDOW_CHECKBOX )
               )
            {
                sal_Int16 nAlignment = sal_Int16();
                if ( Value >>= nAlignment )
                    pButton->SetImageAlign( static_cast< ImageAlign >( nAlignment ) );
            }
        }
        break;
        case BASEPROPERTY_IMAGEPOSITION:
        {
            WindowType eType = GetWindow()->GetType();
            if (  ( eType == WINDOW_PUSHBUTTON )
               || ( eType == WINDOW_RADIOBUTTON )
               || ( eType == WINDOW_CHECKBOX )
               )
            {
                sal_Int16 nImagePosition = 2;
                OSL_VERIFY( Value >>= nImagePosition );
                pButton->SetImageAlign( ::toolkit::translateImagePosition( nImagePosition ) );
            }
        }
        break;
        default:
            VCLXWindow::setProperty( PropertyName, Value );
            break;
	}
}

::com::sun::star::uno::Any VCLXGraphicControl::getProperty( const ::rtl::OUString& PropertyName ) throw(::com::sun::star::uno::RuntimeException)
{
	::vos::OGuard aGuard( GetMutex() );

	::com::sun::star::uno::Any aProp;
    if ( !GetWindow() )
        return aProp;

    sal_uInt16 nPropType = GetPropertyId( PropertyName );
	switch ( nPropType )
	{
        case BASEPROPERTY_GRAPHIC:
            aProp <<= maImage.GetXGraphic();
            break;
		case BASEPROPERTY_IMAGEALIGN:
		{
            WindowType eType = GetWindow()->GetType();
            if  (  ( eType == WINDOW_PUSHBUTTON )
                || ( eType == WINDOW_RADIOBUTTON )
                || ( eType == WINDOW_CHECKBOX )
                )
            {
 				aProp <<= ::toolkit::getCompatibleImageAlign( static_cast< Button* >( GetWindow() )->GetImageAlign() );
            }
		}
		break;
		case BASEPROPERTY_IMAGEPOSITION:
        {
            WindowType eType = GetWindow()->GetType();
            if  (  ( eType == WINDOW_PUSHBUTTON )
                || ( eType == WINDOW_RADIOBUTTON )
                || ( eType == WINDOW_CHECKBOX )
                )
            {
                aProp <<= ::toolkit::translateImagePosition( static_cast< Button* >( GetWindow() )->GetImageAlign() );
            }
        }
        break;
		default:
		{
			aProp <<= VCLXWindow::getProperty( PropertyName );
		}
        break;
	}
	return aProp;
}

//--------------------------------------------------------------------
//	class VCLXButton
//	----------------------------------------------------

void VCLXButton::ImplGetPropertyIds( std::list< 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()
{
}

::com::sun::star::uno::Reference< ::com::sun::star::accessibility::XAccessibleContext > VCLXButton::CreateAccessibleContext()
{
    return getAccessibleFactory().createAccessibleContext( this );
}

void VCLXButton::dispose() throw(::com::sun::star::uno::RuntimeException)
{
	::vos::OGuard aGuard( GetMutex() );

	::com::sun::star::lang::EventObject aObj;
	aObj.Source = (::cppu::OWeakObject*)this;
	maActionListeners.disposeAndClear( aObj );
	maItemListeners.disposeAndClear( aObj );
	VCLXGraphicControl::dispose();
}

void VCLXButton::addActionListener( const ::com::sun::star::uno::Reference< ::com::sun::star::awt::XActionListener > & l  )throw(::com::sun::star::uno::RuntimeException)
{
	::vos::OGuard aGuard( GetMutex() );
	maActionListeners.addInterface( l );
}

void VCLXButton::removeActionListener( const ::com::sun::star::uno::Reference< ::com::sun::star::awt::XActionListener > & l ) throw(::com::sun::star::uno::RuntimeException)
{
	::vos::OGuard aGuard( GetMutex() );
	maActionListeners.removeInterface( l );
}

void VCLXButton::addItemListener( const ::com::sun::star::uno::Reference< ::com::sun::star::awt::XItemListener > & l  )throw(::com::sun::star::uno::RuntimeException)
{
	::vos::OGuard aGuard( GetMutex() );
	maItemListeners.addInterface( l );
}

void VCLXButton::removeItemListener( const ::com::sun::star::uno::Reference< ::com::sun::star::awt::XItemListener > & l ) throw(::com::sun::star::uno::RuntimeException)
{
	::vos::OGuard aGuard( GetMutex() );
	maItemListeners.removeInterface( l );
}

void VCLXButton::setLabel( const ::rtl::OUString& rLabel ) throw(::com::sun::star::uno::RuntimeException)
{
	::vos::OGuard aGuard( GetMutex() );

	Window* pWindow = GetWindow();
	if ( pWindow )
		pWindow->SetText( rLabel );
}

void VCLXButton::setActionCommand( const ::rtl::OUString& rCommand ) throw(::com::sun::star::uno::RuntimeException)
{
	::vos::OGuard aGuard( GetMutex() );

	maActionCommand = rCommand;
}

::com::sun::star::awt::Size VCLXButton::getMinimumSize(  ) throw(::com::sun::star::uno::RuntimeException)
{
	::vos::OGuard aGuard( GetMutex() );

	Size aSz;
	PushButton* pButton = (PushButton*) GetWindow();
	if ( pButton )
		aSz = pButton->CalcMinimumSize();
	return AWTSize(aSz);
}

::com::sun::star::awt::Size VCLXButton::getPreferredSize(  ) throw(::com::sun::star::uno::RuntimeException)
{
	::com::sun::star::awt::Size aSz = getMinimumSize();
	aSz.Width += 16;
	aSz.Height += 10;
	return aSz;
}

::com::sun::star::awt::Size VCLXButton::calcAdjustedSize( const ::com::sun::star::awt::Size& rNewSize ) throw(::com::sun::star::uno::RuntimeException)
{
	::vos::OGuard aGuard( GetMutex() );

	Size aSz = VCLSize(rNewSize);
	PushButton* pButton = (PushButton*) GetWindow();
	if ( pButton )
	{
		Size aMinSz = pButton->CalcMinimumSize();
		// Kein Text, also Image
		if ( !pButton->GetText().Len() )
		{
			if ( aSz.Width() < aMinSz.Width() )
				aSz.Width() = aMinSz.Width();
			if ( aSz.Height() < aMinSz.Height() )
				aSz.Height() = aMinSz.Height();
		}
		else
		{
			if ( ( aSz.Width() > aMinSz.Width() ) && ( aSz.Height() < aMinSz.Height() ) )
				aSz.Height() = aMinSz.Height();
			else
				aSz = aMinSz;
		}
	}
	return AWTSize(aSz);
}

void VCLXButton::setProperty( const ::rtl::OUString& PropertyName, const ::com::sun::star::uno::Any& Value) throw(::com::sun::star::uno::RuntimeException)
{
	::vos::OGuard aGuard( GetMutex() );

	Button* pButton = (Button*)GetWindow();
	if ( pButton )
	{
		sal_uInt16 nPropType = GetPropertyId( PropertyName );
		switch ( nPropType )
		{
            case BASEPROPERTY_FOCUSONCLICK:
                ::toolkit::adjustBooleanWindowStyle( Value, pButton, WB_NOPOINTERFOCUS, sal_True );
                break;

            case BASEPROPERTY_TOGGLE:
                ::toolkit::adjustBooleanWindowStyle( Value, pButton, WB_TOGGLE, sal_False );
                break;

            case BASEPROPERTY_DEFAULTBUTTON:
			{
				WinBits nStyle = pButton->GetStyle() | WB_DEFBUTTON;
				sal_Bool b = sal_Bool();
				if ( ( Value >>= b ) && !b )
					nStyle &= ~WB_DEFBUTTON;
				pButton->SetStyle( nStyle );
			}
			break;
			case BASEPROPERTY_STATE:
			{
                if ( GetWindow()->GetType() == WINDOW_PUSHBUTTON )
                {
				    sal_Int16 n = sal_Int16();
				    if ( Value >>= n )
					    ((PushButton*)pButton)->SetState( (TriState)n );
                }
			}
			break;
			default:
			{
				VCLXGraphicControl::setProperty( PropertyName, Value );
			}
		}
	}
}

::com::sun::star::uno::Any VCLXButton::getProperty( const ::rtl::OUString& PropertyName ) throw(::com::sun::star::uno::RuntimeException)
{
	::vos::OGuard aGuard( GetMutex() );

	::com::sun::star::uno::Any aProp;
	Button* pButton = (Button*)GetWindow();
	if ( pButton )
	{
		sal_uInt16 nPropType = GetPropertyId( PropertyName );
		switch ( nPropType )
		{
            case BASEPROPERTY_FOCUSONCLICK:
                aProp <<= (sal_Bool)( ( pButton->GetStyle() & WB_NOPOINTERFOCUS ) == 0 );
                break;

            case BASEPROPERTY_TOGGLE:
                aProp <<= (sal_Bool)( ( pButton->GetStyle() & WB_TOGGLE ) != 0 );
                break;

			case BASEPROPERTY_DEFAULTBUTTON:
			{
				aProp <<= (sal_Bool) ( ( pButton->GetStyle() & WB_DEFBUTTON ) ? sal_True : sal_False );
			}
			break;
			case BASEPROPERTY_STATE:
			{
                if ( GetWindow()->GetType() == WINDOW_PUSHBUTTON )
                {
 				    aProp <<= (sal_Int16)((PushButton*)pButton)->GetState();
                }
			}
			break;
			default:
			{
				aProp <<= VCLXGraphicControl::getProperty( PropertyName );
			}
		}
	}
	return aProp;
}

void VCLXButton::ProcessWindowEvent( const VclWindowEvent& rVclWindowEvent )
{
	switch ( rVclWindowEvent.GetId() )
	{
		case VCLEVENT_BUTTON_CLICK:
        {
            ::com::sun::star::uno::Reference< ::com::sun::star::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 crashs, we keep us
                // alive as long as we're here
                // #20178# - 2003-10-01 - fs@openoffice.org

			if ( maActionListeners.getLength() )
			{
				::com::sun::star::awt::ActionEvent aEvent;
				aEvent.Source = (::cppu::OWeakObject*)this;
				aEvent.ActionCommand = maActionCommand;

                Callback aCallback = ::boost::bind(
                    &ActionListenerMultiplexer::actionPerformed,
                    &maActionListeners,
                    aEvent
                );
                ImplExecuteAsyncWithoutSolarLock( aCallback );
			}
        }
		break;

        case VCLEVENT_PUSHBUTTON_TOGGLE:
        {
	        PushButton& rButton = dynamic_cast< PushButton& >( *rVclWindowEvent.GetWindow() );

            ::com::sun::star::uno::Reference< ::com::sun::star::awt::XWindow > xKeepAlive( this );
			if ( maItemListeners.getLength() )
			{
				::com::sun::star::awt::ItemEvent aEvent;
				aEvent.Source = (::cppu::OWeakObject*)this;
                aEvent.Selected = ( rButton.GetState() == STATE_CHECK ) ? 1 : 0;
				maItemListeners.itemStateChanged( aEvent );
			}
        }
		break;

		default:
			VCLXGraphicControl::ProcessWindowEvent( rVclWindowEvent );
			break;
	}
}

//	----------------------------------------------------
//	class VCLXImageControl
//	----------------------------------------------------

void VCLXImageControl::ImplGetPropertyIds( std::list< 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!" );
	ImageControl* pControl = static_cast< ImageControl* >( GetWindow() );
	pControl->SetImage( GetImage() );
}

::com::sun::star::awt::Size VCLXImageControl::getMinimumSize(  ) throw(::com::sun::star::uno::RuntimeException)
{
	::vos::OGuard aGuard( GetMutex() );

	Size aSz = GetImage().GetSizePixel();
	aSz = ImplCalcWindowSize( aSz );

	return AWTSize(aSz);
}

::com::sun::star::awt::Size VCLXImageControl::getPreferredSize(  ) throw(::com::sun::star::uno::RuntimeException)
{
	return getMinimumSize();
}

::com::sun::star::awt::Size VCLXImageControl::calcAdjustedSize( const ::com::sun::star::awt::Size& rNewSize ) throw(::com::sun::star::uno::RuntimeException)
{
	::vos::OGuard aGuard( GetMutex() );

	::com::sun::star::awt::Size aSz = rNewSize;
	::com::sun::star::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 ::rtl::OUString& PropertyName, const ::com::sun::star::uno::Any& Value) throw(::com::sun::star::uno::RuntimeException)
{
	::vos::OGuard aGuard( GetMutex() );

	ImageControl* pImageControl = (ImageControl*)GetWindow();

    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
			sal_Bool bScaleImage = sal_False;
            if ( pImageControl && ( Value >>= bScaleImage ) )
            {
                pImageControl->SetScaleMode( bScaleImage ? ImageScaleMode::ANISOTROPIC : ImageScaleMode::NONE );
            }
		}
		break;

        default:
			VCLXGraphicControl::setProperty( PropertyName, Value );
            break;
	}
}

::com::sun::star::uno::Any VCLXImageControl::getProperty( const ::rtl::OUString& PropertyName ) throw(::com::sun::star::uno::RuntimeException)
{
	::vos::OGuard aGuard( GetMutex() );

	::com::sun::star::uno::Any aProp;
	ImageControl* pImageControl = (ImageControl*)GetWindow();
	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 ) ? sal_True : sal_False;
		    break;

		default:
			aProp = VCLXGraphicControl::getProperty( PropertyName );
            break;
	}
	return aProp;
}

//	----------------------------------------------------
//	class VCLXCheckBox
//	----------------------------------------------------


void VCLXCheckBox::ImplGetPropertyIds( std::list< 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 )
{
}

// ::com::sun::star::uno::XInterface
::com::sun::star::uno::Any VCLXCheckBox::queryInterface( const ::com::sun::star::uno::Type & rType ) throw(::com::sun::star::uno::RuntimeException)
{
	::com::sun::star::uno::Any aRet = ::cppu::queryInterface( rType,
										SAL_STATIC_CAST( ::com::sun::star::awt::XButton*, this ),
										SAL_STATIC_CAST( ::com::sun::star::awt::XCheckBox*, this ) );
	return (aRet.hasValue() ? aRet : VCLXGraphicControl::queryInterface( rType ));
}

// ::com::sun::star::lang::XTypeProvider
IMPL_XTYPEPROVIDER_START( VCLXCheckBox )
	getCppuType( ( ::com::sun::star::uno::Reference< ::com::sun::star::awt::XButton>* ) NULL ),
	getCppuType( ( ::com::sun::star::uno::Reference< ::com::sun::star::awt::XCheckBox>* ) NULL ),
	VCLXGraphicControl::getTypes()
IMPL_XTYPEPROVIDER_END

::com::sun::star::uno::Reference< ::com::sun::star::accessibility::XAccessibleContext > VCLXCheckBox::CreateAccessibleContext()
{
    return getAccessibleFactory().createAccessibleContext( this );
}

void VCLXCheckBox::dispose() throw(::com::sun::star::uno::RuntimeException)
{
	::vos::OGuard aGuard( GetMutex() );

	::com::sun::star::lang::EventObject aObj;
	aObj.Source = (::cppu::OWeakObject*)this;
	maItemListeners.disposeAndClear( aObj );
	VCLXGraphicControl::dispose();
}

void VCLXCheckBox::addItemListener( const ::com::sun::star::uno::Reference< ::com::sun::star::awt::XItemListener > & l ) throw(::com::sun::star::uno::RuntimeException)
{
	::vos::OGuard aGuard( GetMutex() );
	maItemListeners.addInterface( l );
}

void VCLXCheckBox::removeItemListener( const ::com::sun::star::uno::Reference< ::com::sun::star::awt::XItemListener > & l ) throw(::com::sun::star::uno::RuntimeException)
{
	::vos::OGuard aGuard( GetMutex() );
	maItemListeners.removeInterface( l );
}

void VCLXCheckBox::addActionListener( const ::com::sun::star::uno::Reference< ::com::sun::star::awt::XActionListener > & l  )throw(::com::sun::star::uno::RuntimeException)
{
	::vos::OGuard aGuard( GetMutex() );
	maActionListeners.addInterface( l );
}

void VCLXCheckBox::removeActionListener( const ::com::sun::star::uno::Reference< ::com::sun::star::awt::XActionListener > & l ) throw(::com::sun::star::uno::RuntimeException)
{
	::vos::OGuard aGuard( GetMutex() );
	maActionListeners.removeInterface( l );
}

void VCLXCheckBox::setActionCommand( const ::rtl::OUString& rCommand ) throw(::com::sun::star::uno::RuntimeException)
{
	::vos::OGuard aGuard( GetMutex() );
	maActionCommand = rCommand;
}

void VCLXCheckBox::setLabel( const ::rtl::OUString& rLabel ) throw(::com::sun::star::uno::RuntimeException)
{
	::vos::OGuard aGuard( GetMutex() );

	Window* pWindow = GetWindow();
	if ( pWindow )
		pWindow->SetText( rLabel );
}

void VCLXCheckBox::setState( short n ) throw(::com::sun::star::uno::RuntimeException)
{
	::vos::OGuard aGuard( GetMutex() );

	CheckBox* pCheckBox = (CheckBox*)GetWindow();
	if ( pCheckBox)
	{
        TriState eState;
        switch ( n )
        {
            case 0:     eState = STATE_NOCHECK;     break;
            case 1:     eState = STATE_CHECK;       break;
            case 2:     eState = STATE_DONTKNOW;    break;
            default:    eState = STATE_NOCHECK;
        }
		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( sal_True );
        pCheckBox->Toggle();
        pCheckBox->Click();
        SetSynthesizingVCLEvent( sal_False );
	}
}

short VCLXCheckBox::getState() throw(::com::sun::star::uno::RuntimeException)
{
    ::vos::OGuard aGuard( GetMutex() );

    short nState = -1;
    CheckBox* pCheckBox = (CheckBox*)GetWindow();
    if ( pCheckBox )
    {
        switch ( pCheckBox->GetState() )
        {
            case STATE_NOCHECK:     nState = 0; break;
            case STATE_CHECK:       nState = 1; break;
            case STATE_DONTKNOW:    nState = 2; break;
            default:                DBG_ERROR( "VCLXCheckBox::getState(): unknown TriState!" );
        }
    }

    return nState;
}

void VCLXCheckBox::enableTriState( sal_Bool b ) throw(::com::sun::star::uno::RuntimeException)
{
	::vos::OGuard aGuard( GetMutex() );

	CheckBox* pCheckBox = (CheckBox*)GetWindow();
	if ( pCheckBox)
		pCheckBox->EnableTriState( b );
}

::com::sun::star::awt::Size VCLXCheckBox::getMinimumSize(  ) throw(::com::sun::star::uno::RuntimeException)
{
	::vos::OGuard aGuard( GetMutex() );

	Size aSz;
	CheckBox* pCheckBox = (CheckBox*) GetWindow();
	if ( pCheckBox )
		aSz = pCheckBox->CalcMinimumSize();
	return AWTSize(aSz);
}

::com::sun::star::awt::Size VCLXCheckBox::getPreferredSize(  ) throw(::com::sun::star::uno::RuntimeException)
{
	return getMinimumSize();
}

::com::sun::star::awt::Size VCLXCheckBox::calcAdjustedSize( const ::com::sun::star::awt::Size& rNewSize ) throw(::com::sun::star::uno::RuntimeException)
{
	::vos::OGuard aGuard( GetMutex() );

	Size aSz = VCLSize(rNewSize);
	CheckBox* pCheckBox = (CheckBox*) GetWindow();
	if ( pCheckBox )
	{
		Size aMinSz = pCheckBox->CalcMinimumSize();
		if ( ( aSz.Width() > aMinSz.Width() ) && ( aSz.Height() < aMinSz.Height() ) )
			aSz.Height() = aMinSz.Height();
		else
			aSz = aMinSz;
	}
	return AWTSize(aSz);
}

void VCLXCheckBox::setProperty( const ::rtl::OUString& PropertyName, const ::com::sun::star::uno::Any& Value) throw(::com::sun::star::uno::RuntimeException)
{
	::vos::OGuard aGuard( GetMutex() );

	CheckBox* pCheckBox = (CheckBox*)GetWindow();
	if ( pCheckBox )
	{
		sal_uInt16 nPropType = GetPropertyId( PropertyName );
		switch ( nPropType )
		{
            case BASEPROPERTY_VISUALEFFECT:
                ::toolkit::setVisualEffect( Value, pCheckBox );
                break;

			case BASEPROPERTY_TRISTATE:
			{
				sal_Bool b = sal_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 );
			}
		}
	}
}

::com::sun::star::uno::Any VCLXCheckBox::getProperty( const ::rtl::OUString& PropertyName ) throw(::com::sun::star::uno::RuntimeException)
{
	::vos::OGuard aGuard( GetMutex() );

	::com::sun::star::uno::Any aProp;
	CheckBox* pCheckBox = (CheckBox*)GetWindow();
	if ( pCheckBox )
	{
		sal_uInt16 nPropType = GetPropertyId( PropertyName );
		switch ( nPropType )
		{
            case BASEPROPERTY_VISUALEFFECT:
                aProp = ::toolkit::getVisualEffect( pCheckBox );
                break;
			case BASEPROPERTY_TRISTATE:
 				aProp <<= (sal_Bool)pCheckBox->IsTriStateEnabled();
    			break;
			case BASEPROPERTY_STATE:
 				aProp <<= (sal_Int16)pCheckBox->GetState();
    			break;
			default:
			{
				aProp <<= VCLXGraphicControl::getProperty( PropertyName );
			}
		}
	}
	return aProp;
}

void VCLXCheckBox::ProcessWindowEvent( const VclWindowEvent& rVclWindowEvent )
{
	switch ( rVclWindowEvent.GetId() )
	{
		case VCLEVENT_CHECKBOX_TOGGLE:
        {
            ::com::sun::star::uno::Reference< ::com::sun::star::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 crashs, we keep us
                // alive as long as we're here
                // #20178# - 2003-10-01 - fs@openoffice.org

			CheckBox* pCheckBox = (CheckBox*)GetWindow();
			if ( pCheckBox )
			{
    			if ( maItemListeners.getLength() )
    			{
    				::com::sun::star::awt::ItemEvent aEvent;
    				aEvent.Source = (::cppu::OWeakObject*)this;
    				aEvent.Highlighted = sal_False;
    				aEvent.Selected = pCheckBox->GetState();
    				maItemListeners.itemStateChanged( aEvent );
    			}
    			if ( !IsSynthesizingVCLEvent() && maActionListeners.getLength() )
    			{
    				::com::sun::star::awt::ActionEvent aEvent;
    				aEvent.Source = (::cppu::OWeakObject*)this;
    				aEvent.ActionCommand = maActionCommand;
    				maActionListeners.actionPerformed( aEvent );
    			}
			}
		}
		break;

		default:
			VCLXGraphicControl::ProcessWindowEvent( rVclWindowEvent );
			break;
	}
}

//	----------------------------------------------------
//	class VCLXRadioButton
//	----------------------------------------------------
void VCLXRadioButton::ImplGetPropertyIds( std::list< 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,
                     0);
    VCLXGraphicControl::ImplGetPropertyIds( rIds );
}


VCLXRadioButton::VCLXRadioButton() : maItemListeners( *this ), maActionListeners( *this )
{
}

// ::com::sun::star::uno::XInterface
::com::sun::star::uno::Any VCLXRadioButton::queryInterface( const ::com::sun::star::uno::Type & rType ) throw(::com::sun::star::uno::RuntimeException)
{
	::com::sun::star::uno::Any aRet = ::cppu::queryInterface( rType,
										SAL_STATIC_CAST( ::com::sun::star::awt::XRadioButton*, this ),
										SAL_STATIC_CAST( ::com::sun::star::awt::XButton*, this ) );
	return (aRet.hasValue() ? aRet : VCLXGraphicControl::queryInterface( rType ));
}

// ::com::sun::star::lang::XTypeProvider
IMPL_XTYPEPROVIDER_START( VCLXRadioButton )
	getCppuType( ( ::com::sun::star::uno::Reference< ::com::sun::star::awt::XRadioButton>* ) NULL ),
	getCppuType( ( ::com::sun::star::uno::Reference< ::com::sun::star::awt::XButton>* ) NULL ),
	VCLXGraphicControl::getTypes()
IMPL_XTYPEPROVIDER_END

::com::sun::star::uno::Reference< ::com::sun::star::accessibility::XAccessibleContext > VCLXRadioButton::CreateAccessibleContext()
{
    return getAccessibleFactory().createAccessibleContext( this );
}

void VCLXRadioButton::dispose() throw(::com::sun::star::uno::RuntimeException)
{
	::vos::OGuard aGuard( GetMutex() );

	::com::sun::star::lang::EventObject aObj;
	aObj.Source = (::cppu::OWeakObject*)this;
	maItemListeners.disposeAndClear( aObj );
	VCLXGraphicControl::dispose();
}

void VCLXRadioButton::setProperty( const ::rtl::OUString& PropertyName, const ::com::sun::star::uno::Any& Value) throw(::com::sun::star::uno::RuntimeException)
{
	::vos::OGuard aGuard( GetMutex() );

	RadioButton* pButton = (RadioButton*)GetWindow();
	if ( pButton )
	{
		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 )
				{
					sal_Bool b = n ? sal_True : sal_False;
					if ( pButton->IsRadioCheckEnabled() )
						pButton->Check( b );
					else
						pButton->SetState( b );
				}
			}
			break;
			case BASEPROPERTY_AUTOTOGGLE:
			{
				sal_Bool b = sal_Bool();
				if ( Value >>= b )
					pButton->EnableRadioCheck( b );
			}
			break;
			default:
			{
				VCLXGraphicControl::setProperty( PropertyName, Value );
			}
		}
	}
}

::com::sun::star::uno::Any VCLXRadioButton::getProperty( const ::rtl::OUString& PropertyName ) throw(::com::sun::star::uno::RuntimeException)
{
	::vos::OGuard aGuard( GetMutex() );

	::com::sun::star::uno::Any aProp;
	RadioButton* pButton = (RadioButton*)GetWindow();
	if ( pButton )
	{
		sal_uInt16 nPropType = GetPropertyId( PropertyName );
		switch ( nPropType )
		{
            case BASEPROPERTY_VISUALEFFECT:
                aProp = ::toolkit::getVisualEffect( pButton );
                break;
			case BASEPROPERTY_STATE:
				aProp <<= (sal_Int16) ( pButton->IsChecked() ? 1 : 0 );
    			break;
			case BASEPROPERTY_AUTOTOGGLE:
				aProp <<= (sal_Bool) pButton->IsRadioCheckEnabled();
    			break;
			default:
			{
				aProp <<= VCLXGraphicControl::getProperty( PropertyName );
			}
		}
	}
	return aProp;
}

void VCLXRadioButton::addItemListener( const ::com::sun::star::uno::Reference< ::com::sun::star::awt::XItemListener > & l ) throw(::com::sun::star::uno::RuntimeException)
{
	::vos::OGuard aGuard( GetMutex() );
	maItemListeners.addInterface( l );
}

void VCLXRadioButton::removeItemListener( const ::com::sun::star::uno::Reference< ::com::sun::star::awt::XItemListener > & l ) throw(::com::sun::star::uno::RuntimeException)
{
	::vos::OGuard aGuard( GetMutex() );
	maItemListeners.removeInterface( l );
}

void VCLXRadioButton::addActionListener( const ::com::sun::star::uno::Reference< ::com::sun::star::awt::XActionListener > & l  )throw(::com::sun::star::uno::RuntimeException)
{
	::vos::OGuard aGuard( GetMutex() );
	maActionListeners.addInterface( l );
}

void VCLXRadioButton::removeActionListener( const ::com::sun::star::uno::Reference< ::com::sun::star::awt::XActionListener > & l ) throw(::com::sun::star::uno::RuntimeException)
{
	::vos::OGuard aGuard( GetMutex() );
	maActionListeners.removeInterface( l );
}

void VCLXRadioButton::setLabel( const ::rtl::OUString& rLabel ) throw(::com::sun::star::uno::RuntimeException)
{
	::vos::OGuard aGuard( GetMutex() );

	Window* pWindow = GetWindow();
	if ( pWindow )
		pWindow->SetText( rLabel );
}

void VCLXRadioButton::setActionCommand( const ::rtl::OUString& rCommand ) throw(::com::sun::star::uno::RuntimeException)
{
	::vos::OGuard aGuard( GetMutex() );
	maActionCommand = rCommand;
}

void VCLXRadioButton::setState( sal_Bool b ) throw(::com::sun::star::uno::RuntimeException)
{
	::vos::OGuard aGuard( GetMutex() );

	RadioButton* pRadioButton = (RadioButton*)GetWindow();
	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( sal_True );
        pRadioButton->Click();
        SetSynthesizingVCLEvent( sal_False );
    }
}

sal_Bool VCLXRadioButton::getState() throw(::com::sun::star::uno::RuntimeException)
{
	::vos::OGuard aGuard( GetMutex() );

	RadioButton* pRadioButton = (RadioButton*)GetWindow();
	return pRadioButton ? pRadioButton->IsChecked() : sal_False;
}

::com::sun::star::awt::Size VCLXRadioButton::getMinimumSize(  ) throw(::com::sun::star::uno::RuntimeException)
{
	::vos::OGuard aGuard( GetMutex() );

	Size aSz;
	RadioButton* pRadioButton = (RadioButton*) GetWindow();
	if ( pRadioButton )
		aSz = pRadioButton->CalcMinimumSize();
	return AWTSize(aSz);
}

::com::sun::star::awt::Size VCLXRadioButton::getPreferredSize(  ) throw(::com::sun::star::uno::RuntimeException)
{
	return getMinimumSize();
}

::com::sun::star::awt::Size VCLXRadioButton::calcAdjustedSize( const ::com::sun::star::awt::Size& rNewSize ) throw(::com::sun::star::uno::RuntimeException)
{
	::vos::OGuard aGuard( GetMutex() );

	Size aSz = VCLSize(rNewSize);
	RadioButton* pRadioButton = (RadioButton*) GetWindow();
	if ( pRadioButton )
	{
		Size aMinSz = pRadioButton->CalcMinimumSize();
		if ( ( aSz.Width() > aMinSz.Width() ) && ( aSz.Height() < aMinSz.Height() ) )
			aSz.Height() = aMinSz.Height();
		else
			aSz = aMinSz;
	}
	return AWTSize(aSz);
}

void VCLXRadioButton::ProcessWindowEvent( const VclWindowEvent& rVclWindowEvent )
{
    ::com::sun::star::uno::Reference< ::com::sun::star::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 crashs, we keep us
        // alive as long as we're here
        // #20178# - 2003-10-01 - fs@openoffice.org

	switch ( rVclWindowEvent.GetId() )
	{
		case VCLEVENT_BUTTON_CLICK:
			if ( !IsSynthesizingVCLEvent() && maActionListeners.getLength() )
			{
				::com::sun::star::awt::ActionEvent aEvent;
				aEvent.Source = (::cppu::OWeakObject*)this;
				aEvent.ActionCommand = maActionCommand;
				maActionListeners.actionPerformed( aEvent );
			}
			ImplClickedOrToggled( sal_False );
            break;

		case VCLEVENT_RADIOBUTTON_TOGGLE:
		    ImplClickedOrToggled( sal_True );
            break;

		default:
			VCLXGraphicControl::ProcessWindowEvent( rVclWindowEvent );
			break;
	}
}

void VCLXRadioButton::ImplClickedOrToggled( sal_Bool bToggled )
{
	// In the formulars, RadioChecked is not enabled, call itemStateChanged only for click
	// In the dialog editor, RadioChecked is enabled, call itemStateChanged only for bToggled
	RadioButton* pRadioButton = (RadioButton*)GetWindow();
	if ( pRadioButton && ( pRadioButton->IsRadioCheckEnabled() == bToggled ) && ( bToggled || pRadioButton->IsStateChanged() ) && maItemListeners.getLength() )
	{
		::com::sun::star::awt::ItemEvent aEvent;
		aEvent.Source = (::cppu::OWeakObject*)this;
		aEvent.Highlighted = sal_False;
		aEvent.Selected = pRadioButton->IsChecked();
		maItemListeners.itemStateChanged( aEvent );
	}
}

::com::sun::star::uno::Reference< ::com::sun::star::uno::XInterface > VCLXRadioButton::getFirstActionListener ()
{
    if (!maItemListeners.getLength ())
        return ::com::sun::star::uno::Reference< ::com::sun::star::uno::XInterface > ();
    return maActionListeners.getElements()[0];
}

//	----------------------------------------------------
//	class VCLXSpinField
//	----------------------------------------------------
void VCLXSpinField::ImplGetPropertyIds( std::list< sal_uInt16 > &rIds )
{
    PushPropertyIds( rIds,
                     BASEPROPERTY_MOUSE_WHEEL_BEHAVIOUR,
                     0 );
    VCLXEdit::ImplGetPropertyIds( rIds );
}

VCLXSpinField::VCLXSpinField() : maSpinListeners( *this )
{
}

// ::com::sun::star::uno::XInterface
::com::sun::star::uno::Any VCLXSpinField::queryInterface( const ::com::sun::star::uno::Type & rType ) throw(::com::sun::star::uno::RuntimeException)
{
	::com::sun::star::uno::Any aRet = ::cppu::queryInterface( rType,
										SAL_STATIC_CAST( ::com::sun::star::awt::XSpinField*, this ) );
	return (aRet.hasValue() ? aRet : VCLXEdit::queryInterface( rType ));
}

// ::com::sun::star::lang::XTypeProvider
IMPL_XTYPEPROVIDER_START( VCLXSpinField )
	getCppuType( ( ::com::sun::star::uno::Reference< ::com::sun::star::awt::XSpinField>* ) NULL ),
	VCLXEdit::getTypes()
IMPL_XTYPEPROVIDER_END

void VCLXSpinField::addSpinListener( const ::com::sun::star::uno::Reference< ::com::sun::star::awt::XSpinListener > & l ) throw(::com::sun::star::uno::RuntimeException)
{
	::vos::OGuard aGuard( GetMutex() );
	maSpinListeners.addInterface( l );
}

void VCLXSpinField::removeSpinListener( const ::com::sun::star::uno::Reference< ::com::sun::star::awt::XSpinListener > & l ) throw(::com::sun::star::uno::RuntimeException)
{
	::vos::OGuard aGuard( GetMutex() );
	maSpinListeners.removeInterface( l );
}

void VCLXSpinField::up() throw(::com::sun::star::uno::RuntimeException)
{
	::vos::OGuard aGuard( GetMutex() );

	SpinField* pSpinField = (SpinField*) GetWindow();
	if ( pSpinField )
		pSpinField->Up();
}

void VCLXSpinField::down() throw(::com::sun::star::uno::RuntimeException)
{
	::vos::OGuard aGuard( GetMutex() );

	SpinField* pSpinField = (SpinField*) GetWindow();
	if ( pSpinField )
		pSpinField->Down();
}

void VCLXSpinField::first() throw(::com::sun::star::uno::RuntimeException)
{
	::vos::OGuard aGuard( GetMutex() );

	SpinField* pSpinField = (SpinField*) GetWindow();
	if ( pSpinField )
		pSpinField->First();
}

void VCLXSpinField::last() throw(::com::sun::star::uno::RuntimeException)
{
	::vos::OGuard aGuard( GetMutex() );

	SpinField* pSpinField = (SpinField*) GetWindow();
	if ( pSpinField )
		pSpinField->Last();
}

void VCLXSpinField::enableRepeat( sal_Bool bRepeat ) throw(::com::sun::star::uno::RuntimeException)
{
	::vos::OGuard aGuard( GetMutex() );

	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 VCLEVENT_SPINFIELD_UP:
		case VCLEVENT_SPINFIELD_DOWN:
		case VCLEVENT_SPINFIELD_FIRST:
		case VCLEVENT_SPINFIELD_LAST:
        {
            ::com::sun::star::uno::Reference< ::com::sun::star::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 crashs, we keep us
                // alive as long as we're here
                // #20178# - 2003-10-01 - fs@openoffice.org

			if ( maSpinListeners.getLength() )
			{
				::com::sun::star::awt::SpinEvent aEvent;
				aEvent.Source = (::cppu::OWeakObject*)this;
				switch ( rVclWindowEvent.GetId() )
				{
					case VCLEVENT_SPINFIELD_UP:     maSpinListeners.up( aEvent );
													break;
					case VCLEVENT_SPINFIELD_DOWN:   maSpinListeners.down( aEvent );
													break;
					case VCLEVENT_SPINFIELD_FIRST:  maSpinListeners.first( aEvent );
													break;
					case VCLEVENT_SPINFIELD_LAST:   maSpinListeners.last( aEvent );
													break;
				}

			}
		}
		break;

		default:
			VCLXEdit::ProcessWindowEvent( rVclWindowEvent );
			break;
	}
}


//	----------------------------------------------------
//	class VCLXListBox
//	----------------------------------------------------
void VCLXListBox::ImplGetPropertyIds( std::list< 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_TABSTOP,
                     BASEPROPERTY_READONLY,
                     BASEPROPERTY_ALIGN,
                     BASEPROPERTY_WRITING_MODE,
                     BASEPROPERTY_CONTEXT_WRITING_MODE,
                     BASEPROPERTY_REFERENCE_DEVICE,
                     BASEPROPERTY_MOUSE_WHEEL_BEHAVIOUR,
                     0);
    VCLXWindow::ImplGetPropertyIds( rIds );
}


VCLXListBox::VCLXListBox()
	: maActionListeners( *this ),
	  maItemListeners( *this )
{
}

void VCLXListBox::dispose() throw(::com::sun::star::uno::RuntimeException)
{
	::vos::OGuard aGuard( GetMutex() );

	::com::sun::star::lang::EventObject aObj;
	aObj.Source = (::cppu::OWeakObject*)this;
	maItemListeners.disposeAndClear( aObj );
	maActionListeners.disposeAndClear( aObj );
	VCLXWindow::dispose();
}

void VCLXListBox::addItemListener( const ::com::sun::star::uno::Reference< ::com::sun::star::awt::XItemListener > & l ) throw(::com::sun::star::uno::RuntimeException)
{
	::vos::OGuard aGuard( GetMutex() );
	maItemListeners.addInterface( l );
}

void VCLXListBox::removeItemListener( const ::com::sun::star::uno::Reference< ::com::sun::star::awt::XItemListener > & l ) throw(::com::sun::star::uno::RuntimeException)
{
	::vos::OGuard aGuard( GetMutex() );
	maItemListeners.removeInterface( l );
}

void VCLXListBox::addActionListener( const ::com::sun::star::uno::Reference< ::com::sun::star::awt::XActionListener > & l ) throw(::com::sun::star::uno::RuntimeException)
{
	::vos::OGuard aGuard( GetMutex() );
	maActionListeners.addInterface( l );
}

void VCLXListBox::removeActionListener( const ::com::sun::star::uno::Reference< ::com::sun::star::awt::XActionListener > & l ) throw(::com::sun::star::uno::RuntimeException)
{
	::vos::OGuard aGuard( GetMutex() );
	maActionListeners.removeInterface( l );
}

void VCLXListBox::addItem( const ::rtl::OUString& aItem, sal_Int16 nPos ) throw(::com::sun::star::uno::RuntimeException)
{
	::vos::OGuard aGuard( GetMutex() );

	ListBox* pBox = (ListBox*) GetWindow();
	if ( pBox )
		pBox->InsertEntry( aItem, nPos );
}

void VCLXListBox::addItems( const ::com::sun::star::uno::Sequence< ::rtl::OUString>& aItems, sal_Int16 nPos ) throw(::com::sun::star::uno::RuntimeException)
{
	::vos::OGuard aGuard( GetMutex() );

	ListBox* pBox = (ListBox*) GetWindow();
	if ( pBox )
	{
	    sal_uInt16 nP = nPos;
        const ::rtl::OUString* pItems = aItems.getConstArray();
        const ::rtl::OUString* pItemsEnd = aItems.getConstArray() + aItems.getLength();
		while ( pItems != pItemsEnd )
		{
			if ( (sal_uInt16)nP == 0xFFFF )
            {
                OSL_ENSURE( false, "VCLXListBox::addItems: too many entries!" );
                // skip remaining entries, list cannot hold them, anyway
                break;
            }

            pBox->InsertEntry( *pItems++, nP++ );
		}
	}
}

void VCLXListBox::removeItems( sal_Int16 nPos, sal_Int16 nCount ) throw(::com::sun::star::uno::RuntimeException)
{
	::vos::OGuard aGuard( GetMutex() );

	ListBox* pBox = (ListBox*) GetWindow();
	if ( pBox )
	{
		for ( sal_uInt16 n = nCount; n; )
			pBox->RemoveEntry( nPos + (--n) );
	}
}

sal_Int16 VCLXListBox::getItemCount() throw(::com::sun::star::uno::RuntimeException)
{
	::vos::OGuard aGuard( GetMutex() );

	ListBox* pBox = (ListBox*) GetWindow();
	return pBox ? pBox->GetEntryCount() : 0;
}

::rtl::OUString VCLXListBox::getItem( sal_Int16 nPos ) throw(::com::sun::star::uno::RuntimeException)
{
	::vos::OGuard aGuard( GetMutex() );

	String aItem;
	ListBox* pBox = (ListBox*) GetWindow();
	if ( pBox )
		aItem = pBox->GetEntry( nPos );
	return aItem;
}

::com::sun::star::uno::Sequence< ::rtl::OUString> VCLXListBox::getItems() throw(::com::sun::star::uno::RuntimeException)
{
	::vos::OGuard aGuard( GetMutex() );

	::com::sun::star::uno::Sequence< ::rtl::OUString> aSeq;
	ListBox* pBox = (ListBox*) GetWindow();
	if ( pBox )
	{
		sal_uInt16 nEntries = pBox->GetEntryCount();
		aSeq = ::com::sun::star::uno::Sequence< ::rtl::OUString>( nEntries );
		for ( sal_uInt16 n = nEntries; n; )
		{
			--n;
			aSeq.getArray()[n] = ::rtl::OUString( pBox->GetEntry( n ) );
		}
	}
	return aSeq;
}

sal_Int16 VCLXListBox::getSelectedItemPos() throw(::com::sun::star::uno::RuntimeException)
{
	::vos::OGuard aGuard( GetMutex() );

	ListBox* pBox = (ListBox*) GetWindow();
	return pBox ? pBox->GetSelectEntryPos() : 0;
}

::com::sun::star::uno::Sequence<sal_Int16> VCLXListBox::getSelectedItemsPos() throw(::com::sun::star::uno::RuntimeException)
{
	::vos::OGuard aGuard( GetMutex() );

	::com::sun::star::uno::Sequence<sal_Int16> aSeq;
	ListBox* pBox = (ListBox*) GetWindow();
	if ( pBox )
	{
		sal_uInt16 nSelEntries = pBox->GetSelectEntryCount();
		aSeq = ::com::sun::star::uno::Sequence<sal_Int16>( nSelEntries );
		for ( sal_uInt16 n = 0; n < nSelEntries; n++ )
			aSeq.getArray()[n] = pBox->GetSelectEntryPos( n );
	}
	return aSeq;
}

::rtl::OUString VCLXListBox::getSelectedItem() throw(::com::sun::star::uno::RuntimeException)
{
	::vos::OGuard aGuard( GetMutex() );

	String aItem;
	ListBox* pBox = (ListBox*) GetWindow();
	if ( pBox )
		aItem = pBox->GetSelectEntry();
	return aItem;
}

::com::sun::star::uno::Sequence< ::rtl::OUString> VCLXListBox::getSelectedItems() throw(::com::sun::star::uno::RuntimeException)
{
	::vos::OGuard aGuard( GetMutex() );

	::com::sun::star::uno::Sequence< ::rtl::OUString> aSeq;
	ListBox* pBox = (ListBox*) GetWindow();
	if ( pBox )
	{
		sal_uInt16 nSelEntries = pBox->GetSelectEntryCount();
		aSeq = ::com::sun::star::uno::Sequence< ::rtl::OUString>( nSelEntries );
		for ( sal_uInt16 n = 0; n < nSelEntries; n++ )
			aSeq.getArray()[n] = ::rtl::OUString( pBox->GetSelectEntry( n ) );
	}
	return aSeq;
}

void VCLXListBox::selectItemPos( sal_Int16 nPos, sal_Bool bSelect ) throw(::com::sun::star::uno::RuntimeException)
{
	::vos::OGuard aGuard( GetMutex() );

	ListBox* pBox = (ListBox*) GetWindow();
	if ( pBox && ( pBox->IsEntryPosSelected( nPos ) != 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( sal_True );
        pBox->Select();
        SetSynthesizingVCLEvent( sal_False );
    }
}

void VCLXListBox::selectItemsPos( const ::com::sun::star::uno::Sequence<sal_Int16>& aPositions, sal_Bool bSelect ) throw(::com::sun::star::uno::RuntimeException)
{
	::vos::OGuard aGuard( GetMutex() );

	ListBox* pBox = (ListBox*) GetWindow();
	if ( pBox )
	{
        sal_Bool bChanged = sal_False;
		for ( sal_uInt16 n = (sal_uInt16)aPositions.getLength(); n; )
        {
            sal_uInt16 nPos = (sal_uInt16) aPositions.getConstArray()[--n];
            if ( pBox->IsEntryPosSelected( nPos ) != bSelect )
            {
			    pBox->SelectEntryPos( nPos, bSelect );
                bChanged = sal_True;
            }
        }

        if ( bChanged )
        {
            // VCL doesn't call select handler after API call.
            // ImplCallItemListeners();

            // #107218# Call same listeners like VCL would do after user interaction
            SetSynthesizingVCLEvent( sal_True );
            pBox->Select();
            SetSynthesizingVCLEvent( sal_False );
        }
	}
}

void VCLXListBox::selectItem( const ::rtl::OUString& rItemText, sal_Bool bSelect ) throw(::com::sun::star::uno::RuntimeException)
{
	::vos::OGuard aGuard( GetMutex() );

	ListBox* pBox = (ListBox*) GetWindow();
	if ( pBox )
    {
        String aItemText( rItemText );
		selectItemPos( pBox->GetEntryPos( aItemText ), bSelect );
    }
}


void VCLXListBox::setDropDownLineCount( sal_Int16 nLines ) throw(::com::sun::star::uno::RuntimeException)
{
	::vos::OGuard aGuard( GetMutex() );

	ListBox* pBox = (ListBox*) GetWindow();
	if ( pBox )
		pBox->SetDropDownLineCount( nLines );
}

sal_Int16 VCLXListBox::getDropDownLineCount() throw(::com::sun::star::uno::RuntimeException)
{
	::vos::OGuard aGuard( GetMutex() );

	sal_Int16 nLines = 0;
	ListBox* pBox = (ListBox*) GetWindow();
	if ( pBox )
		nLines = pBox->GetDropDownLineCount();
	return nLines;
}

sal_Bool VCLXListBox::isMutipleMode() throw(::com::sun::star::uno::RuntimeException)
{
	::vos::OGuard aGuard( GetMutex() );

	sal_Bool bMulti = sal_False;
	ListBox* pBox = (ListBox*) GetWindow();
	if ( pBox )
		bMulti = pBox->IsMultiSelectionEnabled();
	return bMulti;
}

void VCLXListBox::setMultipleMode( sal_Bool bMulti ) throw(::com::sun::star::uno::RuntimeException)
{
	::vos::OGuard aGuard( GetMutex() );

	ListBox* pBox = (ListBox*) GetWindow();
	if ( pBox )
		pBox->EnableMultiSelection( bMulti );
}

void VCLXListBox::makeVisible( sal_Int16 nEntry ) throw(::com::sun::star::uno::RuntimeException)
{
	::vos::OGuard aGuard( GetMutex() );

	ListBox* pBox = (ListBox*) GetWindow();
	if ( pBox )
		pBox->SetTopEntry( nEntry );
}

void VCLXListBox::ProcessWindowEvent( const VclWindowEvent& rVclWindowEvent )
{
    ::com::sun::star::uno::Reference< ::com::sun::star::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 crashs, we keep us
        // alive as long as we're here
        // #20178# - 2003-10-01 - fs@openoffice.org

	switch ( rVclWindowEvent.GetId() )
	{
		case VCLEVENT_LISTBOX_SELECT:
		{
			ListBox* pListBox = (ListBox*)GetWindow();

            if( pListBox )
            {
			    sal_Bool bDropDown = ( pListBox->GetStyle() & WB_DROPDOWN ) ? sal_True : sal_False;
			    if ( bDropDown && !IsSynthesizingVCLEvent() && maActionListeners.getLength() )
			    {
				    // Bei DropDown den ActionListener rufen...
				    ::com::sun::star::awt::ActionEvent aEvent;
				    aEvent.Source = (::cppu::OWeakObject*)this;
				    aEvent.ActionCommand = pListBox->GetSelectEntry();
				    maActionListeners.actionPerformed( aEvent );
			    }

			    if ( maItemListeners.getLength() )
			    {
                    ImplCallItemListeners();
			    }
            }
		}
		break;

		case VCLEVENT_LISTBOX_DOUBLECLICK:
			if ( GetWindow() && maActionListeners.getLength() )
			{
				::com::sun::star::awt::ActionEvent aEvent;
				aEvent.Source = (::cppu::OWeakObject*)this;
				aEvent.ActionCommand = ((ListBox*)GetWindow())->GetSelectEntry();
				maActionListeners.actionPerformed( aEvent );
			}
    		break;

		default:
            VCLXWindow::ProcessWindowEvent( rVclWindowEvent );
			break;
	}
}

::com::sun::star::uno::Reference< ::com::sun::star::accessibility::XAccessibleContext > VCLXListBox::CreateAccessibleContext()
{
	::vos::OGuard aGuard( GetMutex() );

    return getAccessibleFactory().createAccessibleContext( this );
}

void VCLXListBox::setProperty( const ::rtl::OUString& PropertyName, const ::com::sun::star::uno::Any& Value) throw(::com::sun::star::uno::RuntimeException)
{
	::vos::OGuard aGuard( GetMutex() );

	ListBox* pListBox = (ListBox*)GetWindow();
	if ( pListBox )
	{
		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:
			{
				sal_Bool b = sal_Bool();
				if ( Value >>= b )
 					pListBox->SetReadOnly( b);
			}
			break;
			case BASEPROPERTY_MULTISELECTION:
			{
				sal_Bool b = sal_Bool();
				if ( Value >>= b )
 					pListBox->EnableMultiSelection( b );
			}
			break;
			case BASEPROPERTY_MULTISELECTION_SIMPLEMODE:
                ::toolkit::adjustBooleanWindowStyle( Value, pListBox, WB_SIMPLEMODE, sal_False );
			    break;
			case BASEPROPERTY_LINECOUNT:
			{
				sal_Int16 n = sal_Int16();
				if ( Value >>= n )
 					pListBox->SetDropDownLineCount( n );
			}
			break;
			case BASEPROPERTY_STRINGITEMLIST:
			{
				::com::sun::star::uno::Sequence< ::rtl::OUString> aItems;
				if ( Value >>= aItems )
				{
					pListBox->Clear();
					addItems( aItems, 0 );
				}
			}
			break;
			case BASEPROPERTY_SELECTEDITEMS:
			{
				::com::sun::star::uno::Sequence<sal_Int16> aItems;
				if ( Value >>= aItems )
				{
					for ( sal_uInt16 n = pListBox->GetEntryCount(); n; )
						pListBox->SelectEntryPos( --n, sal_False );

                    if ( aItems.getLength() )
					    selectItemsPos( aItems, sal_True );
                    else
                        pListBox->SetNoSelection();

					if ( !pListBox->GetSelectEntryCount() )
						pListBox->SetTopEntry( 0 );
				}
			}
			break;
			default:
			{
				VCLXWindow::setProperty( PropertyName, Value );
			}
		}
	}
}

::com::sun::star::uno::Any VCLXListBox::getProperty( const ::rtl::OUString& PropertyName ) throw(::com::sun::star::uno::RuntimeException)
{
	::vos::OGuard aGuard( GetMutex() );

	::com::sun::star::uno::Any aProp;
	ListBox* pListBox = (ListBox*)GetWindow();
	if ( pListBox )
	{
		sal_uInt16 nPropType = GetPropertyId( PropertyName );
		switch ( nPropType )
		{
            case BASEPROPERTY_ITEM_SEPARATOR_POS:
                aProp <<= sal_Int16( pListBox->GetSeparatorPos() );
                break;
			case BASEPROPERTY_READONLY:
			{
 				aProp <<= (sal_Bool) pListBox->IsReadOnly();
			}
			break;
			case BASEPROPERTY_MULTISELECTION:
			{
 				aProp <<= (sal_Bool) pListBox->IsMultiSelectionEnabled();
			}
			break;
			case BASEPROPERTY_MULTISELECTION_SIMPLEMODE:
            {
                aProp <<= (sal_Bool)( ( pListBox->GetStyle() & WB_SIMPLEMODE ) == 0 );
            }
            break;
			case BASEPROPERTY_LINECOUNT:
			{
 				aProp <<= (sal_Int16) pListBox->GetDropDownLineCount();
			}
			break;
			case BASEPROPERTY_STRINGITEMLIST:
			{
				sal_uInt16 nItems = pListBox->GetEntryCount();
				::com::sun::star::uno::Sequence< ::rtl::OUString> aSeq( nItems );
				::rtl::OUString* pStrings = aSeq.getArray();
				for ( sal_uInt16 n = 0; n < nItems; n++ )
					pStrings[n] = pListBox->GetEntry( n );
				aProp <<= aSeq;

			}
			break;
			default:
			{
				aProp <<= VCLXWindow::getProperty( PropertyName );
			}
		}
	}
	return aProp;
}

::com::sun::star::awt::Size VCLXListBox::getMinimumSize(  ) throw(::com::sun::star::uno::RuntimeException)
{
	::vos::OGuard aGuard( GetMutex() );

	Size aSz;
	ListBox* pListBox = (ListBox*) GetWindow();
	if ( pListBox )
		aSz = pListBox->CalcMinimumSize();
	return AWTSize(aSz);
}

::com::sun::star::awt::Size VCLXListBox::getPreferredSize(  ) throw(::com::sun::star::uno::RuntimeException)
{
	::vos::OGuard aGuard( GetMutex() );

	Size aSz;
	ListBox* pListBox = (ListBox*) GetWindow();
	if ( pListBox )
	{
		aSz = pListBox->CalcMinimumSize();
		if ( pListBox->GetStyle() & WB_DROPDOWN )
			aSz.Height() += 4;
	}
	return AWTSize(aSz);
}

::com::sun::star::awt::Size VCLXListBox::calcAdjustedSize( const ::com::sun::star::awt::Size& rNewSize ) throw(::com::sun::star::uno::RuntimeException)
{
	::vos::OGuard aGuard( GetMutex() );

	Size aSz = VCLSize(rNewSize);
	ListBox* pListBox = (ListBox*) GetWindow();
	if ( pListBox )
		aSz = pListBox->CalcAdjustedSize( aSz );
	return AWTSize(aSz);
}

::com::sun::star::awt::Size VCLXListBox::getMinimumSize( sal_Int16 nCols, sal_Int16 nLines ) throw(::com::sun::star::uno::RuntimeException)
{
	::vos::OGuard aGuard( GetMutex() );

	Size aSz;
	ListBox* pListBox = (ListBox*) GetWindow();
	if ( pListBox )
		aSz = pListBox->CalcSize( nCols, nLines );
	return AWTSize(aSz);
}

void VCLXListBox::getColumnsAndLines( sal_Int16& nCols, sal_Int16& nLines ) throw(::com::sun::star::uno::RuntimeException)
{
	::vos::OGuard aGuard( GetMutex() );

	nCols = nLines = 0;
	ListBox* pListBox = (ListBox*) GetWindow();
	if ( pListBox )
	{
		sal_uInt16 nC, nL;
		pListBox->GetMaxVisColumnsAndLines( nC, nL );
		nCols = nC;
		nLines = nL;
	}
}

void VCLXListBox::ImplCallItemListeners()
{
	ListBox* pListBox = (ListBox*) GetWindow();
    if ( pListBox && maItemListeners.getLength() )
    {
	    ::com::sun::star::awt::ItemEvent aEvent;
	    aEvent.Source = (::cppu::OWeakObject*)this;
	    aEvent.Highlighted = sal_False;

	    // Bei Mehrfachselektion 0xFFFF, sonst die ID
	    aEvent.Selected = (pListBox->GetSelectEntryCount() == 1 ) ? pListBox->GetSelectEntryPos() : 0xFFFF;

	    maItemListeners.itemStateChanged( aEvent );
    }
}
namespace
{
	 Image lcl_getImageFromURL( const ::rtl::OUString& i_rImageURL )
	 {
		 if ( !i_rImageURL.getLength() )
			 return Image();

		try
		{
			 ::comphelper::ComponentContext aContext( ::comphelper::getProcessServiceFactory() );
			 Reference< XGraphicProvider > xProvider;
			 if ( aContext.createComponent( "com.sun.star.graphic.GraphicProvider", xProvider ) )
			 {
				 ::comphelper::NamedValueCollection aMediaProperties;
				 aMediaProperties.put( "URL", i_rImageURL );
				 Reference< XGraphic > xGraphic = xProvider->queryGraphic( aMediaProperties.getPropertyValues() );
				return Image( xGraphic );
			 }
		 }
		 catch( const uno::Exception& )
		 {
			 DBG_UNHANDLED_EXCEPTION();
		 }
		 return Image();
	 }
}
void SAL_CALL VCLXListBox::listItemInserted( const ItemListEvent& i_rEvent ) throw (RuntimeException)
{
	::vos::OGuard aGuard( GetMutex() );

    ListBox* pListBox = dynamic_cast< ListBox* >( GetWindow() );

    ENSURE_OR_RETURN_VOID( pListBox, "VCLXListBox::listItemInserted: no ListBox?!" );
    ENSURE_OR_RETURN_VOID( ( i_rEvent.ItemPosition >= 0 ) && ( i_rEvent.ItemPosition <= sal_Int32( pListBox->GetEntryCount() ) ),
        "VCLXListBox::listItemInserted: illegal (inconsistent) item position!" );
    pListBox->InsertEntry(
        i_rEvent.ItemText.IsPresent ? i_rEvent.ItemText.Value : ::rtl::OUString(),
        i_rEvent.ItemImageURL.IsPresent ? TkResMgr::getImageFromURL( i_rEvent.ItemImageURL.Value ) : Image(),
        i_rEvent.ItemPosition );
}

void SAL_CALL VCLXListBox::listItemRemoved( const ItemListEvent& i_rEvent ) throw (RuntimeException)
{
	::vos::OGuard aGuard( GetMutex() );

    ListBox* pListBox = dynamic_cast< ListBox* >( GetWindow() );

    ENSURE_OR_RETURN_VOID( pListBox, "VCLXListBox::listItemRemoved: no ListBox?!" );
    ENSURE_OR_RETURN_VOID( ( i_rEvent.ItemPosition >= 0 ) && ( i_rEvent.ItemPosition < sal_Int32( pListBox->GetEntryCount() ) ),
        "VCLXListBox::listItemRemoved: illegal (inconsistent) item position!" );

    pListBox->RemoveEntry( i_rEvent.ItemPosition );
}

void SAL_CALL VCLXListBox::listItemModified( const ItemListEvent& i_rEvent ) throw (RuntimeException)
{
	::vos::OGuard aGuard( GetMutex() );

    ListBox* pListBox = dynamic_cast< ListBox* >( GetWindow() );

    ENSURE_OR_RETURN_VOID( pListBox, "VCLXListBox::listItemModified: no ListBox?!" );
    ENSURE_OR_RETURN_VOID( ( i_rEvent.ItemPosition >= 0 ) && ( i_rEvent.ItemPosition < sal_Int32( 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 ::rtl::OUString sNewText = i_rEvent.ItemText.IsPresent ? i_rEvent.ItemText.Value : ::rtl::OUString( 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& i_rEvent ) throw (RuntimeException)
{
	::vos::OGuard aGuard( GetMutex() );

    ListBox* pListBox = dynamic_cast< ListBox* >( GetWindow() );
    ENSURE_OR_RETURN_VOID( pListBox, "VCLXListBox::listItemModified: no ListBox?!" );

    pListBox->Clear();

    (void)i_rEvent;
}

void SAL_CALL VCLXListBox::itemListChanged( const EventObject& i_rEvent ) throw (RuntimeException)
{
	::vos::OGuard aGuard( GetMutex() );

    ListBox* pListBox = dynamic_cast< ListBox* >( GetWindow() );
    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_QUERY_THROW );
    uno::Reference< resource::XStringResourceResolver > xStringResourceResolver;
    if ( xPSI->hasPropertyByName( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "ResourceResolver" ) ) ) )
    {
        xStringResourceResolver.set(
            xPropSet->getPropertyValue( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "ResourceResolver" ) ) ),
            uno::UNO_QUERY
        );
    }


    Reference< XItemList > xItemList( i_rEvent.Source, uno::UNO_QUERY_THROW );
    uno::Sequence< beans::Pair< ::rtl::OUString, ::rtl::OUString > > aItems = xItemList->getAllItems();
    for ( sal_Int32 i=0; i<aItems.getLength(); ++i )
    {
        ::rtl::OUString aLocalizationKey( aItems[i].First );
        if ( xStringResourceResolver.is() && aLocalizationKey.getLength() != 0 && aLocalizationKey[0] == '&' )
        {
            aLocalizationKey = xStringResourceResolver->resolveString(aLocalizationKey.copy( 1 ));
        }
        pListBox->InsertEntry( aLocalizationKey, lcl_getImageFromURL( aItems[i].Second ) );
    }
}

void SAL_CALL VCLXListBox::disposing( const EventObject& i_rEvent ) throw (RuntimeException)
{
    // just disambiguate
    VCLXWindow::disposing( i_rEvent );
}

//	----------------------------------------------------
//	class VCLXMessageBox
//	----------------------------------------------------

void VCLXMessageBox::ImplGetPropertyIds( std::list< sal_uInt16 > &rIds )
{
    VCLXTopWindow::ImplGetPropertyIds( rIds );
}

VCLXMessageBox::VCLXMessageBox()
{
}

VCLXMessageBox::~VCLXMessageBox()
{
}

// ::com::sun::star::uno::XInterface
::com::sun::star::uno::Any VCLXMessageBox::queryInterface( const ::com::sun::star::uno::Type & rType ) throw(::com::sun::star::uno::RuntimeException)
{
	::com::sun::star::uno::Any aRet = ::cppu::queryInterface( rType,
										SAL_STATIC_CAST( ::com::sun::star::awt::XMessageBox*, this ) );
	return (aRet.hasValue() ? aRet : VCLXTopWindow::queryInterface( rType ));
}

// ::com::sun::star::lang::XTypeProvider
IMPL_XTYPEPROVIDER_START( VCLXMessageBox )
	getCppuType( ( ::com::sun::star::uno::Reference< ::com::sun::star::awt::XMessageBox>* ) NULL ),
	VCLXTopWindow::getTypes()
IMPL_XTYPEPROVIDER_END

void VCLXMessageBox::setCaptionText( const ::rtl::OUString& rText ) throw(::com::sun::star::uno::RuntimeException)
{
	::vos::OGuard aGuard( GetMutex() );

	Window* pWindow = GetWindow();
	if ( pWindow )
		pWindow->SetText( rText );
}

::rtl::OUString VCLXMessageBox::getCaptionText() throw(::com::sun::star::uno::RuntimeException)
{
	::vos::OGuard aGuard( GetMutex() );

	String aText;
	Window* pWindow = GetWindow();
	if ( pWindow )
		aText = pWindow->GetText();
	return aText;
}

void VCLXMessageBox::setMessageText( const ::rtl::OUString& rText ) throw(::com::sun::star::uno::RuntimeException)
{
	::vos::OGuard aGuard( GetMutex() );

	MessBox* pBox = (MessBox*)GetWindow();
	if ( pBox )
		pBox->SetMessText( rText );
}

::rtl::OUString VCLXMessageBox::getMessageText() throw(::com::sun::star::uno::RuntimeException)
{
	::vos::OGuard aGuard( GetMutex() );

	::rtl::OUString aText;
	MessBox* pBox = (MessBox*)GetWindow();
	if ( pBox )
		aText = pBox->GetMessText();
	return aText;
}

sal_Int16 VCLXMessageBox::execute() throw(::com::sun::star::uno::RuntimeException)
{
	::vos::OGuard aGuard( GetMutex() );

	MessBox* pBox = (MessBox*)GetWindow();
	return pBox ? pBox->Execute() : 0;
}

::com::sun::star::awt::Size SAL_CALL VCLXMessageBox::getMinimumSize() throw(::com::sun::star::uno::RuntimeException)
{
    ::vos::OGuard aGuard( GetMutex() );
    return ::com::sun::star::awt::Size( 250, 100 );
}

//	----------------------------------------------------
//	class VCLXDialog
//	----------------------------------------------------
void VCLXDialog::ImplGetPropertyIds( std::list< sal_uInt16 > &rIds )
{
    VCLXTopWindow::ImplGetPropertyIds( rIds );
}

VCLXDialog::VCLXDialog()
{
}

VCLXDialog::~VCLXDialog()
{
#ifndef __SUNPRO_CC
    OSL_TRACE ("%s", __FUNCTION__);
#endif
}

// ::com::sun::star::uno::XInterface
::com::sun::star::uno::Any VCLXDialog::queryInterface( const ::com::sun::star::uno::Type & rType ) throw(::com::sun::star::uno::RuntimeException)
{
	::com::sun::star::uno::Any aRet = ::cppu::queryInterface( rType,
										SAL_STATIC_CAST( ::com::sun::star::awt::XDialog2*, this ),
										SAL_STATIC_CAST( ::com::sun::star::awt::XDialog*, this ) );
	return (aRet.hasValue() ? aRet : VCLXTopWindow::queryInterface( rType ));
}

// ::com::sun::star::lang::XTypeProvider
IMPL_XTYPEPROVIDER_START( VCLXDialog )
	getCppuType( ( ::com::sun::star::uno::Reference< ::com::sun::star::awt::XDialog2>* ) NULL ),
	getCppuType( ( ::com::sun::star::uno::Reference< ::com::sun::star::awt::XDialog>* ) NULL ),
	VCLXTopWindow::getTypes()
IMPL_XTYPEPROVIDER_END

void SAL_CALL VCLXDialog::endDialog( ::sal_Int32 i_result ) throw (RuntimeException)
{
    ::vos::OGuard aGuard( GetMutex() );

    Dialog* pDialog = dynamic_cast< Dialog* >( GetWindow() );
    if ( pDialog )
        pDialog->EndDialog( i_result );
}

void SAL_CALL VCLXDialog::setHelpId( const ::rtl::OUString& rId ) throw (RuntimeException)
{
    ::vos::OGuard aGuard( GetMutex() );

    Window* pWindow = GetWindow();
    if ( pWindow )
        pWindow->SetHelpId( rtl::OUStringToOString( rId, RTL_TEXTENCODING_UTF8 ) );
}

void VCLXDialog::setTitle( const ::rtl::OUString& Title ) throw(::com::sun::star::uno::RuntimeException)
{
	::vos::OGuard aGuard( GetMutex() );

	Window* pWindow = GetWindow();
	if ( pWindow )
		pWindow->SetText( Title );
}

::rtl::OUString VCLXDialog::getTitle() throw(::com::sun::star::uno::RuntimeException)
{
	::vos::OGuard aGuard( GetMutex() );

	::rtl::OUString aTitle;
	Window* pWindow = GetWindow();
	if ( pWindow )
		aTitle = pWindow->GetText();
	return aTitle;
}

sal_Int16 VCLXDialog::execute() throw(::com::sun::star::uno::RuntimeException)
{
	::vos::OGuard aGuard( GetMutex() );

	sal_Int16 nRet = 0;
	if ( GetWindow() )
	{
		Dialog* pDlg = (Dialog*) GetWindow();
		Window* pParent = pDlg->GetWindow( WINDOW_PARENTOVERLAP );
		Window* pOldParent = NULL;
        Window* pSetParent = NULL;
		if ( pParent && !pParent->IsReallyVisible() )
		{
			pOldParent = pDlg->GetParent();
            Window* pFrame = pDlg->GetWindow( WINDOW_FRAME );
            if( pFrame != pDlg )
            {
                pDlg->SetParent( pFrame );
                pSetParent = pFrame;
            }
		}

		nRet = pDlg->Execute();

        // set the parent back only in case no new parent was set from outside
        // in other words, revert only own changes
		if ( pOldParent && pDlg->GetParent() == pSetParent )
			pDlg->SetParent( pOldParent );
	}
	return nRet;
}

void VCLXDialog::endExecute() throw(::com::sun::star::uno::RuntimeException)
{
    endDialog(0);
}

void SAL_CALL VCLXDialog::draw( sal_Int32 nX, sal_Int32 nY ) throw(::com::sun::star::uno::RuntimeException)
{
	::vos::OGuard aGuard( GetMutex() );
	Window* pWindow = GetWindow();

	if ( pWindow )
	{
		OutputDevice* pDev = VCLUnoHelper::GetOutputDevice( getGraphics() );
		if ( !pDev )
			pDev = pWindow->GetParent();

		Size aSize = pDev->PixelToLogic( pWindow->GetSizePixel() );
		Point aPos = pDev->PixelToLogic( Point( nX, nY ) );

		pWindow->Draw( pDev, aPos, aSize, WINDOW_DRAW_NOCONTROLS );
    }
}

::com::sun::star::awt::DeviceInfo VCLXDialog::getInfo() throw(::com::sun::star::uno::RuntimeException)
{
	::com::sun::star::awt::DeviceInfo aInfo = VCLXDevice::getInfo();

	::vos::OGuard aGuard( GetMutex() );
	Dialog* pDlg = (Dialog*) GetWindow();
	if ( pDlg )
	    pDlg->GetDrawWindowBorder( aInfo.LeftInset, aInfo.TopInset, aInfo.RightInset, aInfo.BottomInset );

	return aInfo;
}


void SAL_CALL VCLXDialog::setProperty(
    const ::rtl::OUString& PropertyName,
    const ::com::sun::star::uno::Any& Value )
throw(::com::sun::star::uno::RuntimeException)
{
	::vos::OGuard aGuard( GetMutex() );

	Dialog* pDialog = (Dialog*)GetWindow();
	if ( pDialog )
	{
		sal_Bool bVoid = Value.getValueType().getTypeClass() == ::com::sun::star::uno::TypeClass_VOID;

		sal_uInt16 nPropType = GetPropertyId( PropertyName );
		switch ( nPropType )
		{
			case BASEPROPERTY_GRAPHIC:
            {
                Reference< XGraphic > xGraphic;
                if (( Value >>= xGraphic ) && xGraphic.is() )
                {
                    Image aImage( xGraphic );

                    Wallpaper aWallpaper( aImage.GetBitmapEx());
                    aWallpaper.SetStyle( WALLPAPER_SCALE );
                    pDialog->SetBackground( aWallpaper );
                }
                else if ( bVoid || !xGraphic.is() )
                {
                    Color aColor = pDialog->GetControlBackground().GetColor();
                    if ( aColor == COL_AUTO )
                        aColor = pDialog->GetSettings().GetStyleSettings().GetDialogColor();

                    Wallpaper aWallpaper( aColor );
                    pDialog->SetBackground( aWallpaper );
                }
            }
            break;

            default:
			{
				VCLXWindow::setProperty( PropertyName, Value );
			}
        }
    }
}

//	----------------------------------------------------
//	class VCLXTabPage
//	----------------------------------------------------
VCLXTabPage::VCLXTabPage()
{
}

VCLXTabPage::~VCLXTabPage()
{
}

::com::sun::star::uno::Any SAL_CALL VCLXTabPage::queryInterface(const ::com::sun::star::uno::Type & rType )
throw(::com::sun::star::uno::RuntimeException)
{
	return VCLXContainer::queryInterface( rType );
}

// ::com::sun::star::lang::XTypeProvider
IMPL_XTYPEPROVIDER_START( VCLXTabPage )
	VCLXContainer::getTypes()
IMPL_XTYPEPROVIDER_END

// ::com::sun::star::awt::XView
void SAL_CALL VCLXTabPage::draw( sal_Int32 nX, sal_Int32 nY )
throw(::com::sun::star::uno::RuntimeException)
{
	::vos::OGuard aGuard( GetMutex() );
	Window* pWindow = GetWindow();

	if ( pWindow )
	{
		OutputDevice* pDev = VCLUnoHelper::GetOutputDevice( getGraphics() );
		if ( !pDev )
			pDev = pWindow->GetParent();

		Size aSize = pDev->PixelToLogic( pWindow->GetSizePixel() );
		Point aPos = pDev->PixelToLogic( Point( nX, nY ) );

		pWindow->Draw( pDev, aPos, aSize, WINDOW_DRAW_NOCONTROLS );
    }
}

// ::com::sun::star::awt::XDevice,
::com::sun::star::awt::DeviceInfo SAL_CALL VCLXTabPage::getInfo()
throw(::com::sun::star::uno::RuntimeException)
{
	::com::sun::star::awt::DeviceInfo aInfo = VCLXDevice::getInfo();
	return aInfo;
}

void SAL_CALL VCLXTabPage::setProperty(
    const ::rtl::OUString& PropertyName,
    const ::com::sun::star::uno::Any& Value )
throw(::com::sun::star::uno::RuntimeException)
{
	::vos::OGuard aGuard( GetMutex() );

	TabPage* pTabPage = (TabPage*)GetWindow();
	if ( pTabPage )
	{
		sal_Bool bVoid = Value.getValueType().getTypeClass() == ::com::sun::star::uno::TypeClass_VOID;

		sal_uInt16 nPropType = GetPropertyId( PropertyName );
		switch ( nPropType )
		{
			case BASEPROPERTY_GRAPHIC:
            {
                Reference< XGraphic > xGraphic;
                if (( Value >>= xGraphic ) && xGraphic.is() )
                {
                    Image aImage( xGraphic );

                    Wallpaper aWallpaper( aImage.GetBitmapEx());
                    aWallpaper.SetStyle( WALLPAPER_SCALE );
                    pTabPage->SetBackground( aWallpaper );
                }
                else if ( bVoid || !xGraphic.is() )
                {
                    Color aColor = pTabPage->GetControlBackground().GetColor();
                    if ( aColor == COL_AUTO )
                        aColor = pTabPage->GetSettings().GetStyleSettings().GetDialogColor();

                    Wallpaper aWallpaper( aColor );
                    pTabPage->SetBackground( aWallpaper );
                }
            }
            break;
            case BASEPROPERTY_TITLE:
                {
                    ::rtl::OUString sTitle;
                    if ( Value >>= sTitle )
                    {
                        pTabPage->SetText(sTitle);
                    }
                }
                break;

            default:
			{
				VCLXContainer::setProperty( PropertyName, Value );
			}
        }
    }
}

//	----------------------------------------------------
//  class VCLXFixedHyperlink
//	----------------------------------------------------
VCLXFixedHyperlink::VCLXFixedHyperlink() :

    maActionListeners( *this )

{
}

VCLXFixedHyperlink::~VCLXFixedHyperlink()
{
}

// ::com::sun::star::uno::XInterface
::com::sun::star::uno::Any VCLXFixedHyperlink::queryInterface( const ::com::sun::star::uno::Type & rType ) throw(::com::sun::star::uno::RuntimeException)
{
	::com::sun::star::uno::Any aRet = ::cppu::queryInterface( rType,
                                        SAL_STATIC_CAST( ::com::sun::star::awt::XFixedHyperlink*, this ) );
	return (aRet.hasValue() ? aRet : VCLXWindow::queryInterface( rType ));
}

void VCLXFixedHyperlink::dispose() throw(::com::sun::star::uno::RuntimeException)
{
        ::vos::OGuard aGuard( GetMutex() );

        ::com::sun::star::lang::EventObject aObj;
        aObj.Source = (::cppu::OWeakObject*)this;
        maActionListeners.disposeAndClear( aObj );
        VCLXWindow::dispose();
}

// ::com::sun::star::lang::XTypeProvider
IMPL_XTYPEPROVIDER_START( VCLXFixedHyperlink )
    getCppuType( ( ::com::sun::star::uno::Reference< ::com::sun::star::awt::XFixedHyperlink>* ) NULL ),
	VCLXWindow::getTypes()
IMPL_XTYPEPROVIDER_END

void VCLXFixedHyperlink::ProcessWindowEvent( const VclWindowEvent& rVclWindowEvent )
{
    switch ( rVclWindowEvent.GetId() )
    {
        case VCLEVENT_BUTTON_CLICK:
        {
            if ( maActionListeners.getLength() )
            {
                ::com::sun::star::awt::ActionEvent aEvent;
                aEvent.Source = (::cppu::OWeakObject*)this;
                maActionListeners.actionPerformed( aEvent );
            }
            else
            {
                // open the URL
                ::rtl::OUString sURL;
                ::toolkit::FixedHyperlinkBase* pBase = (::toolkit::FixedHyperlinkBase*)GetWindow();
                if ( pBase )
                    sURL = pBase->GetURL();
                Reference< ::com::sun::star::system::XSystemShellExecute > xSystemShellExecute(
                    ::com::sun::star::system::SystemShellExecute::create(
                        ::comphelper::getProcessComponentContext() ) );
                if ( sURL.getLength() > 0 && xSystemShellExecute.is() )
                {
                    try
                    {
                        // start browser
                        xSystemShellExecute->execute(
                            sURL, ::rtl::OUString(), ::com::sun::star::system::SystemShellExecuteFlags::DEFAULTS );
                    }
                    catch( uno::Exception& )
                    {
                    }
                }
            }
        }

        default:
            VCLXWindow::ProcessWindowEvent( rVclWindowEvent );
            break;
    }
}

::com::sun::star::uno::Reference< ::com::sun::star::accessibility::XAccessibleContext > VCLXFixedHyperlink::CreateAccessibleContext()
{
    return getAccessibleFactory().createAccessibleContext( this );
}

void VCLXFixedHyperlink::setText( const ::rtl::OUString& Text ) throw(::com::sun::star::uno::RuntimeException)
{
	::vos::OGuard aGuard( GetMutex() );

    ::toolkit::FixedHyperlinkBase* pBase = (::toolkit::FixedHyperlinkBase*)GetWindow();
    if ( pBase )
        pBase->SetDescription( Text );
}

::rtl::OUString VCLXFixedHyperlink::getText() throw(::com::sun::star::uno::RuntimeException)
{
	::vos::OGuard aGuard( GetMutex() );

	::rtl::OUString aText;
    Window* pWindow = GetWindow();
    if ( pWindow )
        aText = pWindow->GetText();
	return aText;
}

void VCLXFixedHyperlink::setURL( const ::rtl::OUString& URL ) throw(::com::sun::star::uno::RuntimeException)
{
    ::vos::OGuard aGuard( GetMutex() );

    ::toolkit::FixedHyperlinkBase* pBase = (::toolkit::FixedHyperlinkBase*)GetWindow();
    if ( pBase )
        pBase->SetURL( URL );
}

::rtl::OUString VCLXFixedHyperlink::getURL(  ) throw(::com::sun::star::uno::RuntimeException)
{
    ::vos::OGuard aGuard( GetMutex() );

    ::rtl::OUString aText;
    ::toolkit::FixedHyperlinkBase* pBase = (::toolkit::FixedHyperlinkBase*)GetWindow();
    if ( pBase )
        aText = pBase->GetURL();
    return aText;
}

void VCLXFixedHyperlink::setAlignment( short nAlign ) throw(::com::sun::star::uno::RuntimeException)
{
	::vos::OGuard aGuard( GetMutex() );

	Window* pWindow = GetWindow();
	if ( pWindow )
	{
		WinBits nNewBits = 0;
		if ( nAlign == ::com::sun::star::awt::TextAlign::LEFT )
			nNewBits = WB_LEFT;
		else if ( nAlign == ::com::sun::star::awt::TextAlign::CENTER )
			nNewBits = WB_CENTER;
		else
			nNewBits = WB_RIGHT;

		WinBits nStyle = pWindow->GetStyle();
		nStyle &= ~(WB_LEFT|WB_CENTER|WB_RIGHT);
		pWindow->SetStyle( nStyle | nNewBits );
	}
}

short VCLXFixedHyperlink::getAlignment() throw(::com::sun::star::uno::RuntimeException)
{
	::vos::OGuard aGuard( GetMutex() );

	short nAlign = 0;
	Window* pWindow = GetWindow();
	if ( pWindow )
	{
		WinBits nStyle = pWindow->GetStyle();
		if ( nStyle & WB_LEFT )
			nAlign = ::com::sun::star::awt::TextAlign::LEFT;
		else if ( nStyle & WB_CENTER )
			nAlign = ::com::sun::star::awt::TextAlign::CENTER;
		else
			nAlign = ::com::sun::star::awt::TextAlign::RIGHT;
	}
	return nAlign;
}

void VCLXFixedHyperlink::addActionListener( const ::com::sun::star::uno::Reference< ::com::sun::star::awt::XActionListener > & l  )throw(::com::sun::star::uno::RuntimeException)
{
        ::vos::OGuard aGuard( GetMutex() );
        maActionListeners.addInterface( l );
}

void VCLXFixedHyperlink::removeActionListener( const ::com::sun::star::uno::Reference< ::com::sun::star::awt::XActionListener > & l ) throw(::com::sun::star::uno::RuntimeException)
{
        ::vos::OGuard aGuard( GetMutex() );
        maActionListeners.removeInterface( l );
}

::com::sun::star::awt::Size VCLXFixedHyperlink::getMinimumSize(  ) throw(::com::sun::star::uno::RuntimeException)
{
	::vos::OGuard aGuard( GetMutex() );

	Size aSz;
    FixedText* pFixedText = (FixedText*)GetWindow();
    if ( pFixedText )
        aSz = pFixedText->CalcMinimumSize();
	return AWTSize(aSz);
}

::com::sun::star::awt::Size VCLXFixedHyperlink::getPreferredSize(  ) throw(::com::sun::star::uno::RuntimeException)
{
	return getMinimumSize();
}

::com::sun::star::awt::Size VCLXFixedHyperlink::calcAdjustedSize( const ::com::sun::star::awt::Size& rNewSize ) throw(::com::sun::star::uno::RuntimeException)
{
	::vos::OGuard aGuard( GetMutex() );

	::com::sun::star::awt::Size aSz = rNewSize;
	::com::sun::star::awt::Size aMinSz = getMinimumSize();
	if ( aSz.Height != aMinSz.Height )
		aSz.Height = aMinSz.Height;

	return aSz;
}

void VCLXFixedHyperlink::setProperty( const ::rtl::OUString& PropertyName, const ::com::sun::star::uno::Any& Value) throw(::com::sun::star::uno::RuntimeException)
{
    ::vos::OGuard aGuard( GetMutex() );

    ::toolkit::FixedHyperlinkBase* pBase = (::toolkit::FixedHyperlinkBase*)GetWindow();
    if ( pBase )
    {
        sal_uInt16 nPropType = GetPropertyId( PropertyName );
        switch ( nPropType )
        {
            case BASEPROPERTY_LABEL:
            {
                ::rtl::OUString sNewLabel;
                if ( Value >>= sNewLabel )
                    pBase->SetDescription( sNewLabel );
                break;
            }

            case BASEPROPERTY_URL:
            {
                ::rtl::OUString sNewURL;
                if ( Value >>= sNewURL )
                    pBase->SetURL( sNewURL );
                break;
            }

            default:
            {
                VCLXWindow::setProperty( PropertyName, Value );
            }
        }
    }
}

::com::sun::star::uno::Any VCLXFixedHyperlink::getProperty( const ::rtl::OUString& PropertyName ) throw(::com::sun::star::uno::RuntimeException)
{
    ::vos::OGuard aGuard( GetMutex() );

    ::com::sun::star::uno::Any aProp;
    ::toolkit::FixedHyperlinkBase* pBase = (::toolkit::FixedHyperlinkBase*)GetWindow();
    if ( pBase )
    {
        sal_uInt16 nPropType = GetPropertyId( PropertyName );
        switch ( nPropType )
        {
            case BASEPROPERTY_URL:
            {
                aProp = makeAny( ::rtl::OUString( pBase->GetURL() ) );
                break;
            }

            default:
            {
                aProp <<= VCLXWindow::getProperty( PropertyName );
            }
        }
    }
    return aProp;
}

void VCLXFixedHyperlink::ImplGetPropertyIds( std::list< sal_uInt16 > &rIds )
{
    PushPropertyIds( rIds,
                     BASEPROPERTY_ALIGN,
                     BASEPROPERTY_BACKGROUNDCOLOR,
                     BASEPROPERTY_BORDER,
                     BASEPROPERTY_BORDERCOLOR,
                     BASEPROPERTY_DEFAULTCONTROL,
                     BASEPROPERTY_ENABLED,
                     BASEPROPERTY_ENABLEVISIBLE,
                     BASEPROPERTY_FONTDESCRIPTOR,
                     BASEPROPERTY_HELPTEXT,
                     BASEPROPERTY_HELPURL,
                     BASEPROPERTY_LABEL,
                     BASEPROPERTY_MULTILINE,
                     BASEPROPERTY_NOLABEL,
                     BASEPROPERTY_PRINTABLE,
                     BASEPROPERTY_TABSTOP,
                     BASEPROPERTY_VERTICALALIGN,
                     BASEPROPERTY_URL,
                     BASEPROPERTY_WRITING_MODE,
                     BASEPROPERTY_CONTEXT_WRITING_MODE,
                     0);
    VCLXWindow::ImplGetPropertyIds( rIds );
}

//  ----------------------------------------------------
//  class VCLXFixedText
//  ----------------------------------------------------
void VCLXFixedText::ImplGetPropertyIds( std::list< sal_uInt16 > &rIds )
{
    PushPropertyIds( rIds,
                     BASEPROPERTY_ALIGN,
                     BASEPROPERTY_BACKGROUNDCOLOR,
                     BASEPROPERTY_BORDER,
                     BASEPROPERTY_BORDERCOLOR,
                     BASEPROPERTY_DEFAULTCONTROL,
                     BASEPROPERTY_ENABLED,
                     BASEPROPERTY_ENABLEVISIBLE,
                     BASEPROPERTY_FONTDESCRIPTOR,
                     BASEPROPERTY_HELPTEXT,
                     BASEPROPERTY_HELPURL,
                     BASEPROPERTY_LABEL,
                     BASEPROPERTY_MULTILINE,
                     BASEPROPERTY_NOLABEL,
                     BASEPROPERTY_PRINTABLE,
                     BASEPROPERTY_TABSTOP,
                     BASEPROPERTY_VERTICALALIGN,
                     BASEPROPERTY_WRITING_MODE,
                     BASEPROPERTY_CONTEXT_WRITING_MODE,
                     BASEPROPERTY_REFERENCE_DEVICE,
                     0);
    VCLXWindow::ImplGetPropertyIds( rIds );
}

VCLXFixedText::VCLXFixedText()
{
}

VCLXFixedText::~VCLXFixedText()
{
}

// ::com::sun::star::uno::XInterface
::com::sun::star::uno::Any VCLXFixedText::queryInterface( const ::com::sun::star::uno::Type & rType ) throw(::com::sun::star::uno::RuntimeException)
{
    ::com::sun::star::uno::Any aRet = ::cppu::queryInterface( rType,
                                        SAL_STATIC_CAST( ::com::sun::star::awt::XFixedText*, this ) );
    return (aRet.hasValue() ? aRet : VCLXWindow::queryInterface( rType ));
}

// ::com::sun::star::lang::XTypeProvider
IMPL_XTYPEPROVIDER_START( VCLXFixedText )
    getCppuType( ( ::com::sun::star::uno::Reference< ::com::sun::star::awt::XFixedText>* ) NULL ),
    VCLXWindow::getTypes()
IMPL_XTYPEPROVIDER_END

::com::sun::star::uno::Reference< ::com::sun::star::accessibility::XAccessibleContext > VCLXFixedText::CreateAccessibleContext()
{
    return getAccessibleFactory().createAccessibleContext( this );
}

void VCLXFixedText::setText( const ::rtl::OUString& Text ) throw(::com::sun::star::uno::RuntimeException)
{
    ::vos::OGuard aGuard( GetMutex() );

    Window* pWindow = GetWindow();
    if ( pWindow )
        pWindow->SetText( Text );
}

::rtl::OUString VCLXFixedText::getText() throw(::com::sun::star::uno::RuntimeException)
{
    ::vos::OGuard aGuard( GetMutex() );

    ::rtl::OUString aText;
    Window* pWindow = GetWindow();
    if ( pWindow )
        aText = pWindow->GetText();
    return aText;
}

void VCLXFixedText::setAlignment( short nAlign ) throw(::com::sun::star::uno::RuntimeException)
{
    ::vos::OGuard aGuard( GetMutex() );

    Window* pWindow = GetWindow();
    if ( pWindow )
    {
        WinBits nNewBits = 0;
        if ( nAlign == ::com::sun::star::awt::TextAlign::LEFT )
            nNewBits = WB_LEFT;
        else if ( nAlign == ::com::sun::star::awt::TextAlign::CENTER )
            nNewBits = WB_CENTER;
        else
            nNewBits = WB_RIGHT;

        WinBits nStyle = pWindow->GetStyle();
        nStyle &= ~(WB_LEFT|WB_CENTER|WB_RIGHT);
        pWindow->SetStyle( nStyle | nNewBits );
    }
}

short VCLXFixedText::getAlignment() throw(::com::sun::star::uno::RuntimeException)
{
    ::vos::OGuard aGuard( GetMutex() );

    short nAlign = 0;
    Window* pWindow = GetWindow();
    if ( pWindow )
    {
        WinBits nStyle = pWindow->GetStyle();
        if ( nStyle & WB_LEFT )
            nAlign = ::com::sun::star::awt::TextAlign::LEFT;
        else if ( nStyle & WB_CENTER )
            nAlign = ::com::sun::star::awt::TextAlign::CENTER;
        else
            nAlign = ::com::sun::star::awt::TextAlign::RIGHT;
    }
    return nAlign;
}

::com::sun::star::awt::Size VCLXFixedText::getMinimumSize(  ) throw(::com::sun::star::uno::RuntimeException)
{
    ::vos::OGuard aGuard( GetMutex() );

    Size aSz;
    FixedText* pFixedText = (FixedText*)GetWindow();
    if ( pFixedText )
        aSz = pFixedText->CalcMinimumSize();
    return AWTSize(aSz);
}

::com::sun::star::awt::Size VCLXFixedText::getPreferredSize(  ) throw(::com::sun::star::uno::RuntimeException)
{
    return getMinimumSize();
}

::com::sun::star::awt::Size VCLXFixedText::calcAdjustedSize( const ::com::sun::star::awt::Size& rMaxSize ) throw(::com::sun::star::uno::RuntimeException)
{
    ::vos::OGuard aGuard( GetMutex() );

    Size aAdjustedSize( VCLUnoHelper::ConvertToVCLSize( rMaxSize ) );
    FixedText* pFixedText = (FixedText*)GetWindow();
    if ( pFixedText )
        aAdjustedSize = pFixedText->CalcMinimumSize( rMaxSize.Width );
    return VCLUnoHelper::ConvertToAWTSize( aAdjustedSize );
}

//	----------------------------------------------------
//	class VCLXScrollBar
//	----------------------------------------------------
void VCLXScrollBar::ImplGetPropertyIds( std::list< sal_uInt16 > &rIds )
{
    PushPropertyIds( rIds,
                     BASEPROPERTY_BACKGROUNDCOLOR,
                     BASEPROPERTY_BLOCKINCREMENT,
                     BASEPROPERTY_BORDER,
                     BASEPROPERTY_BORDERCOLOR,
                     BASEPROPERTY_DEFAULTCONTROL,
                     BASEPROPERTY_ENABLED,
                     BASEPROPERTY_ENABLEVISIBLE,
                     BASEPROPERTY_HELPTEXT,
                     BASEPROPERTY_HELPURL,
                     BASEPROPERTY_LINEINCREMENT,
                     BASEPROPERTY_LIVE_SCROLL,
                     BASEPROPERTY_ORIENTATION,
                     BASEPROPERTY_PRINTABLE,
                     BASEPROPERTY_REPEAT_DELAY,
                     BASEPROPERTY_SCROLLVALUE,
                     BASEPROPERTY_SCROLLVALUE_MAX,
                     BASEPROPERTY_SCROLLVALUE_MIN,
                     BASEPROPERTY_SYMBOL_COLOR,
                     BASEPROPERTY_TABSTOP,
                     BASEPROPERTY_VISIBLESIZE,
                     BASEPROPERTY_WRITING_MODE,
                     BASEPROPERTY_CONTEXT_WRITING_MODE,
                     0);
    VCLXWindow::ImplGetPropertyIds( rIds );
}

VCLXScrollBar::VCLXScrollBar() : maAdjustmentListeners( *this )
{
}

// ::com::sun::star::uno::XInterface
::com::sun::star::uno::Any VCLXScrollBar::queryInterface( const ::com::sun::star::uno::Type & rType ) throw(::com::sun::star::uno::RuntimeException)
{
	::com::sun::star::uno::Any aRet = ::cppu::queryInterface( rType,
										SAL_STATIC_CAST( ::com::sun::star::awt::XScrollBar*, this ) );
	return (aRet.hasValue() ? aRet : VCLXWindow::queryInterface( rType ));
}

// ::com::sun::star::lang::XTypeProvider
IMPL_XTYPEPROVIDER_START( VCLXScrollBar )
	getCppuType( ( ::com::sun::star::uno::Reference< ::com::sun::star::awt::XScrollBar>* ) NULL ),
	VCLXWindow::getTypes()
IMPL_XTYPEPROVIDER_END

::com::sun::star::uno::Reference< ::com::sun::star::accessibility::XAccessibleContext > VCLXScrollBar::CreateAccessibleContext()
{
    return getAccessibleFactory().createAccessibleContext( this );
}

// ::com::sun::star::lang::XComponent
void VCLXScrollBar::dispose() throw(::com::sun::star::uno::RuntimeException)
{
	::vos::OGuard aGuard( GetMutex() );

	::com::sun::star::lang::EventObject aObj;
	aObj.Source = (::cppu::OWeakObject*)this;
	maAdjustmentListeners.disposeAndClear( aObj );
	VCLXWindow::dispose();
}

// ::com::sun::star::awt::XScrollbar
void VCLXScrollBar::addAdjustmentListener( const ::com::sun::star::uno::Reference< ::com::sun::star::awt::XAdjustmentListener > & l ) throw(::com::sun::star::uno::RuntimeException)
{
	::vos::OGuard aGuard( GetMutex() );
	maAdjustmentListeners.addInterface( l );
}

void VCLXScrollBar::removeAdjustmentListener( const ::com::sun::star::uno::Reference< ::com::sun::star::awt::XAdjustmentListener > & l ) throw(::com::sun::star::uno::RuntimeException)
{
	::vos::OGuard aGuard( GetMutex() );
	maAdjustmentListeners.removeInterface( l );
}

void VCLXScrollBar::setValue( sal_Int32 n ) throw(::com::sun::star::uno::RuntimeException)
{
	::vos::OGuard aGuard( GetMutex() );

	ScrollBar* pScrollBar = (ScrollBar*) GetWindow();
	if ( pScrollBar )
		pScrollBar->DoScroll( n );
}

void VCLXScrollBar::setValues( sal_Int32 nValue, sal_Int32 nVisible, sal_Int32 nMax ) throw(::com::sun::star::uno::RuntimeException)
{
	::vos::OGuard aGuard( GetMutex() );

	ScrollBar* pScrollBar = (ScrollBar*) GetWindow();
	if ( pScrollBar )
	{
		pScrollBar->SetVisibleSize( nVisible );
		pScrollBar->SetRangeMax( nMax );
		pScrollBar->DoScroll( nValue );
	}
}

sal_Int32 VCLXScrollBar::getValue() throw(::com::sun::star::uno::RuntimeException)
{
	::vos::OGuard aGuard( GetMutex() );

	ScrollBar* pScrollBar = (ScrollBar*) GetWindow();
	return pScrollBar ? pScrollBar->GetThumbPos() : 0;
}

void VCLXScrollBar::setMaximum( sal_Int32 n ) throw(::com::sun::star::uno::RuntimeException)
{
	::vos::OGuard aGuard( GetMutex() );

	ScrollBar* pScrollBar = (ScrollBar*) GetWindow();
	if ( pScrollBar )
		pScrollBar->SetRangeMax( n );
}

sal_Int32 VCLXScrollBar::getMaximum() throw(::com::sun::star::uno::RuntimeException)
{
	::vos::OGuard aGuard( GetMutex() );

	ScrollBar* pScrollBar = (ScrollBar*) GetWindow();
	return pScrollBar ? pScrollBar->GetRangeMax() : 0;
}

void VCLXScrollBar::setMinimum( sal_Int32 n ) throw(::com::sun::star::uno::RuntimeException)
{
	::vos::OGuard aGuard( GetMutex() );

	ScrollBar* pScrollBar = static_cast< ScrollBar* >( GetWindow() );
	if ( pScrollBar )
		pScrollBar->SetRangeMin( n );
}

sal_Int32 VCLXScrollBar::getMinimum() throw(::com::sun::star::uno::RuntimeException)
{
	::vos::OGuard aGuard( GetMutex() );

	ScrollBar* pScrollBar = static_cast< ScrollBar* >( GetWindow() );
	return pScrollBar ? pScrollBar->GetRangeMin() : 0;
}

void VCLXScrollBar::setLineIncrement( sal_Int32 n ) throw(::com::sun::star::uno::RuntimeException)
{
	::vos::OGuard aGuard( GetMutex() );

	ScrollBar* pScrollBar = (ScrollBar*) GetWindow();
	if ( pScrollBar )
		pScrollBar->SetLineSize( n );
}

sal_Int32 VCLXScrollBar::getLineIncrement() throw(::com::sun::star::uno::RuntimeException)
{
	::vos::OGuard aGuard( GetMutex() );

	ScrollBar* pScrollBar = (ScrollBar*) GetWindow();
	return pScrollBar ? pScrollBar->GetLineSize() : 0;
}

void VCLXScrollBar::setBlockIncrement( sal_Int32 n ) throw(::com::sun::star::uno::RuntimeException)
{
	::vos::OGuard aGuard( GetMutex() );

	ScrollBar* pScrollBar = (ScrollBar*) GetWindow();
	if ( pScrollBar )
		pScrollBar->SetPageSize( n );
}

sal_Int32 VCLXScrollBar::getBlockIncrement() throw(::com::sun::star::uno::RuntimeException)
{
	::vos::OGuard aGuard( GetMutex() );

	ScrollBar* pScrollBar = (ScrollBar*) GetWindow();
	return pScrollBar ? pScrollBar->GetPageSize() : 0;
}

void VCLXScrollBar::setVisibleSize( sal_Int32 n ) throw(::com::sun::star::uno::RuntimeException)
{
	::vos::OGuard aGuard( GetMutex() );

	ScrollBar* pScrollBar = (ScrollBar*) GetWindow();
	if ( pScrollBar )
		pScrollBar->SetVisibleSize( n );
}

sal_Int32 VCLXScrollBar::getVisibleSize() throw(::com::sun::star::uno::RuntimeException)
{
	::vos::OGuard aGuard( GetMutex() );

	ScrollBar* pScrollBar = (ScrollBar*) GetWindow();
	return pScrollBar ? pScrollBar->GetVisibleSize() : 0;
}

void VCLXScrollBar::setOrientation( sal_Int32 n ) throw(::com::sun::star::uno::RuntimeException)
{
	::vos::OGuard aGuard( GetMutex() );

	Window* pWindow = GetWindow();
	if ( pWindow )
	{
		WinBits nStyle = pWindow->GetStyle();
		nStyle &= ~(WB_HORZ|WB_VERT);
		if ( n == ::com::sun::star::awt::ScrollBarOrientation::HORIZONTAL )
			nStyle |= WB_HORZ;
		else
			nStyle |= WB_VERT;

		pWindow->SetStyle( nStyle );
        pWindow->Resize();
	}
}

sal_Int32 VCLXScrollBar::getOrientation() throw(::com::sun::star::uno::RuntimeException)
{
	::vos::OGuard aGuard( GetMutex() );

	sal_Int32 n = 0;
	Window* pWindow = GetWindow();
	if ( pWindow )
	{
		WinBits nStyle = pWindow->GetStyle();
		if ( nStyle & WB_HORZ )
			n = ::com::sun::star::awt::ScrollBarOrientation::HORIZONTAL;
		else
			n = ::com::sun::star::awt::ScrollBarOrientation::VERTICAL;
	}
	return n;

}

// ::com::sun::star::awt::VclWindowPeer
void VCLXScrollBar::setProperty( const ::rtl::OUString& PropertyName, const ::com::sun::star::uno::Any& Value) throw(::com::sun::star::uno::RuntimeException)
{
	::vos::OGuard aGuard( GetMutex() );

	ScrollBar* pScrollBar = (ScrollBar*)GetWindow();
	if ( pScrollBar )
	{
		sal_Bool bVoid = Value.getValueType().getTypeClass() == ::com::sun::star::uno::TypeClass_VOID;

		sal_uInt16 nPropType = GetPropertyId( PropertyName );
		switch ( nPropType )
		{
			case BASEPROPERTY_LIVE_SCROLL:
            {
                sal_Bool bDo = sal_False;
                if ( !bVoid )
                {
                    OSL_VERIFY( Value >>= bDo );
                }
                AllSettings aSettings( pScrollBar->GetSettings() );
                StyleSettings aStyle( aSettings.GetStyleSettings() );
                sal_uLong nDragOptions = aStyle.GetDragFullOptions();
                if ( bDo )
                    nDragOptions |= DRAGFULL_OPTION_SCROLL;
                else
                    nDragOptions &= ~DRAGFULL_OPTION_SCROLL;
                aStyle.SetDragFullOptions( nDragOptions );
                aSettings.SetStyleSettings( aStyle );
                pScrollBar->SetSettings( aSettings );
            }
            break;

			case BASEPROPERTY_SCROLLVALUE:
			{
				if ( !bVoid )
				{
					sal_Int32 n = 0;
					if ( Value >>= n )
						setValue( n );
				}
			}
			break;
			case BASEPROPERTY_SCROLLVALUE_MAX:
            case BASEPROPERTY_SCROLLVALUE_MIN:
			{
				if ( !bVoid )
				{
					sal_Int32 n = 0;
					if ( Value >>= n )
                    {
                        if ( nPropType == BASEPROPERTY_SCROLLVALUE_MAX )
						    setMaximum( n );
                        else
						    setMinimum( n );
                    }
				}
			}
			break;
			case BASEPROPERTY_LINEINCREMENT:
			{
				if ( !bVoid )
				{
					sal_Int32 n = 0;
					if ( Value >>= n )
						setLineIncrement( n );
				}
			}
			break;
			case BASEPROPERTY_BLOCKINCREMENT:
			{
				if ( !bVoid )
				{
					sal_Int32 n = 0;
					if ( Value >>= n )
						setBlockIncrement( n );
				}
			}
			break;
			case BASEPROPERTY_VISIBLESIZE:
			{
				if ( !bVoid )
				{
					sal_Int32 n = 0;
					if ( Value >>= n )
						setVisibleSize( n );
				}
			}
			break;
			case BASEPROPERTY_ORIENTATION:
			{
				if ( !bVoid )
				{
					sal_Int32 n = 0;
					if ( Value >>= n )
						setOrientation( n );
				}
			}
			break;

            case BASEPROPERTY_BACKGROUNDCOLOR:
            {
                // the default implementation of the base class doesn't work here, since our
                // interpretation for this property is slightly different
                ::toolkit::setButtonLikeFaceColor( pScrollBar, Value);
            }
            break;

			default:
			{
				VCLXWindow::setProperty( PropertyName, Value );
			}
		}
	}
}

::com::sun::star::uno::Any VCLXScrollBar::getProperty( const ::rtl::OUString& PropertyName ) throw(::com::sun::star::uno::RuntimeException)
{
	::vos::OGuard aGuard( GetMutex() );

	::com::sun::star::uno::Any aProp;
	ScrollBar* pScrollBar = (ScrollBar*)GetWindow();
	if ( pScrollBar )
	{
		sal_uInt16 nPropType = GetPropertyId( PropertyName );

		switch ( nPropType )
		{
			case BASEPROPERTY_LIVE_SCROLL:
            {
                aProp <<= (sal_Bool)( 0 != ( pScrollBar->GetSettings().GetStyleSettings().GetDragFullOptions() & DRAGFULL_OPTION_SCROLL ) );
            }
            break;
			case BASEPROPERTY_SCROLLVALUE:
			{
				aProp <<= (sal_Int32) getValue();
			}
			break;
			case BASEPROPERTY_SCROLLVALUE_MAX:
			{
				aProp <<= (sal_Int32) getMaximum();
			}
			break;
            case BASEPROPERTY_SCROLLVALUE_MIN:
			{
				aProp <<= (sal_Int32) getMinimum();
			}
			break;
			case BASEPROPERTY_LINEINCREMENT:
			{
				aProp <<= (sal_Int32) getLineIncrement();
			}
			break;
			case BASEPROPERTY_BLOCKINCREMENT:
			{
				aProp <<= (sal_Int32) getBlockIncrement();
			}
			break;
			case BASEPROPERTY_VISIBLESIZE:
			{
				aProp <<= (sal_Int32) getVisibleSize();
			}
			break;
			case BASEPROPERTY_ORIENTATION:
			{
				aProp <<= (sal_Int32) getOrientation();
			}
			break;
            case BASEPROPERTY_BACKGROUNDCOLOR:
            {
                // the default implementation of the base class doesn't work here, since our
                // interpretation for this property is slightly different
                aProp = ::toolkit::getButtonLikeFaceColor( pScrollBar );
            }
            break;

			default:
			{
				aProp <<= VCLXWindow::getProperty( PropertyName );
			}
		}
	}
	return aProp;
}

void VCLXScrollBar::ProcessWindowEvent( const VclWindowEvent& rVclWindowEvent )
{
	switch ( rVclWindowEvent.GetId() )
	{
		case VCLEVENT_SCROLLBAR_SCROLL:
        {
            ::com::sun::star::uno::Reference< ::com::sun::star::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 crashs, we keep us
                // alive as long as we're here
                // #20178# - 2003-10-01 - fs@openoffice.org

			if ( maAdjustmentListeners.getLength() )
			{
    			ScrollBar* pScrollBar = (ScrollBar*)GetWindow();

                if( pScrollBar )
                {
				    ::com::sun::star::awt::AdjustmentEvent aEvent;
				    aEvent.Source = (::cppu::OWeakObject*)this;
				    aEvent.Value = pScrollBar->GetThumbPos();

				    // set adjustment type
				    ScrollType aType = pScrollBar->GetType();
				    if ( aType == SCROLL_LINEUP || aType == SCROLL_LINEDOWN )
				    {
					    aEvent.Type = ::com::sun::star::awt::AdjustmentType_ADJUST_LINE;
				    }
				    else if ( aType == SCROLL_PAGEUP || aType == SCROLL_PAGEDOWN )
				    {
					    aEvent.Type = ::com::sun::star::awt::AdjustmentType_ADJUST_PAGE;
				    }
				    else if ( aType == SCROLL_DRAG )
				    {
					    aEvent.Type = ::com::sun::star::awt::AdjustmentType_ADJUST_ABS;
				    }

				    maAdjustmentListeners.adjustmentValueChanged( aEvent );
                }
			}
        }
        break;

		default:
			VCLXWindow::ProcessWindowEvent( rVclWindowEvent );
			break;
	}
}

::com::sun::star::awt::Size SAL_CALL VCLXScrollBar::implGetMinimumSize( Window* p ) throw(::com::sun::star::uno::RuntimeException)
{
    long n = p->GetSettings().GetStyleSettings().GetScrollBarSize();
    return ::com::sun::star::awt::Size( n, n );
}

::com::sun::star::awt::Size SAL_CALL VCLXScrollBar::getMinimumSize() throw(::com::sun::star::uno::RuntimeException)
{
	::vos::OGuard aGuard( GetMutex() );
    return implGetMinimumSize( GetWindow() );
}


//	----------------------------------------------------
//	class VCLXEdit
//	----------------------------------------------------

void VCLXEdit::ImplGetPropertyIds( std::list< sal_uInt16 > &rIds )
{
    PushPropertyIds( rIds,
                     BASEPROPERTY_ALIGN,
                     BASEPROPERTY_BACKGROUNDCOLOR,
                     BASEPROPERTY_BORDER,
                     BASEPROPERTY_BORDERCOLOR,
                     BASEPROPERTY_DEFAULTCONTROL,
                     BASEPROPERTY_ECHOCHAR,
                     BASEPROPERTY_ENABLED,
                     BASEPROPERTY_ENABLEVISIBLE,
                     BASEPROPERTY_FONTDESCRIPTOR,
                     BASEPROPERTY_HARDLINEBREAKS,
                     BASEPROPERTY_HELPTEXT,
                     BASEPROPERTY_HELPURL,
                     BASEPROPERTY_HSCROLL,
                     BASEPROPERTY_LINE_END_FORMAT,
                     BASEPROPERTY_MAXTEXTLEN,
                     BASEPROPERTY_MULTILINE,
                     BASEPROPERTY_PRINTABLE,
                     BASEPROPERTY_READONLY,
                     BASEPROPERTY_TABSTOP,
                     BASEPROPERTY_TEXT,
                     BASEPROPERTY_VSCROLL,
                     BASEPROPERTY_HIDEINACTIVESELECTION,
                     BASEPROPERTY_PAINTTRANSPARENT,
                     BASEPROPERTY_AUTOHSCROLL,
                     BASEPROPERTY_AUTOVSCROLL,
                     BASEPROPERTY_VERTICALALIGN,
                     BASEPROPERTY_WRITING_MODE,
                     BASEPROPERTY_CONTEXT_WRITING_MODE,
                     0);
    VCLXWindow::ImplGetPropertyIds( rIds );
}

VCLXEdit::VCLXEdit() : maTextListeners( *this )
{
}

// ::com::sun::star::uno::XInterface
::com::sun::star::uno::Any VCLXEdit::queryInterface( const ::com::sun::star::uno::Type & rType ) throw(::com::sun::star::uno::RuntimeException)
{
	::com::sun::star::uno::Any aRet = ::cppu::queryInterface( rType,
										SAL_STATIC_CAST( ::com::sun::star::awt::XTextComponent*, this ),
										SAL_STATIC_CAST( ::com::sun::star::awt::XTextEditField*, this ),
										SAL_STATIC_CAST( ::com::sun::star::awt::XTextLayoutConstrains*, this ) );
	return (aRet.hasValue() ? aRet : VCLXWindow::queryInterface( rType ));
}

// ::com::sun::star::lang::XTypeProvider
IMPL_XTYPEPROVIDER_START( VCLXEdit )
	getCppuType( ( ::com::sun::star::uno::Reference< ::com::sun::star::awt::XTextComponent>* ) NULL ),
	getCppuType( ( ::com::sun::star::uno::Reference< ::com::sun::star::awt::XTextEditField>* ) NULL ),
	getCppuType( ( ::com::sun::star::uno::Reference< ::com::sun::star::awt::XTextLayoutConstrains>* ) NULL ),
	VCLXWindow::getTypes()
IMPL_XTYPEPROVIDER_END

::com::sun::star::uno::Reference< ::com::sun::star::accessibility::XAccessibleContext > VCLXEdit::CreateAccessibleContext()
{
    return getAccessibleFactory().createAccessibleContext( this );
}

void VCLXEdit::dispose() throw(::com::sun::star::uno::RuntimeException)
{
	::vos::OGuard aGuard( GetMutex() );

	::com::sun::star::lang::EventObject aObj;
	aObj.Source = (::cppu::OWeakObject*)this;
	maTextListeners.disposeAndClear( aObj );
	VCLXWindow::dispose();
}

void VCLXEdit::addTextListener( const ::com::sun::star::uno::Reference< ::com::sun::star::awt::XTextListener > & l ) throw(::com::sun::star::uno::RuntimeException)
{
	::vos::OGuard aGuard( GetMutex() );
	GetTextListeners().addInterface( l );
}

void VCLXEdit::removeTextListener( const ::com::sun::star::uno::Reference< ::com::sun::star::awt::XTextListener > & l ) throw(::com::sun::star::uno::RuntimeException)
{
	::vos::OGuard aGuard( GetMutex() );
	GetTextListeners().removeInterface( l );
}

void VCLXEdit::setText( const ::rtl::OUString& aText ) throw(::com::sun::star::uno::RuntimeException)
{
	::vos::OGuard aGuard( GetMutex() );

	Edit* pEdit = (Edit*)GetWindow();
	if ( pEdit )
	{
		pEdit->SetText( aText );

        // #107218# Call same listeners like VCL would do after user interaction
        SetSynthesizingVCLEvent( sal_True );
        pEdit->SetModifyFlag();
        pEdit->Modify();
        SetSynthesizingVCLEvent( sal_False );
	}
}

void VCLXEdit::insertText( const ::com::sun::star::awt::Selection& rSel, const ::rtl::OUString& aText ) throw(::com::sun::star::uno::RuntimeException)
{
	::vos::OGuard aGuard( GetMutex() );

	Edit* pEdit = (Edit*)GetWindow();
	if ( pEdit )
	{
		pEdit->SetSelection( Selection( rSel.Min, rSel.Max ) );
		pEdit->ReplaceSelected( aText );

        // #107218# Call same listeners like VCL would do after user interaction
        SetSynthesizingVCLEvent( sal_True );
        pEdit->SetModifyFlag();
        pEdit->Modify();
        SetSynthesizingVCLEvent( sal_False );
	}
}

::rtl::OUString VCLXEdit::getText() throw(::com::sun::star::uno::RuntimeException)
{
	::vos::OGuard aGuard( GetMutex() );

	::rtl::OUString aText;
	Window* pWindow = GetWindow();
	if ( pWindow )
		aText = pWindow->GetText();
	return aText;
}

::rtl::OUString VCLXEdit::getSelectedText() throw(::com::sun::star::uno::RuntimeException)
{
	::vos::OGuard aGuard( GetMutex() );

	::rtl::OUString aText;
	Edit* pEdit = (Edit*) GetWindow();
	if ( pEdit)
		aText = pEdit->GetSelected();
	return aText;

}

void VCLXEdit::setSelection( const ::com::sun::star::awt::Selection& aSelection ) throw(::com::sun::star::uno::RuntimeException)
{
	::vos::OGuard aGuard( GetMutex() );

	Edit* pEdit = (Edit*) GetWindow();
	if ( pEdit )
		pEdit->SetSelection( Selection( aSelection.Min, aSelection.Max ) );
}

::com::sun::star::awt::Selection VCLXEdit::getSelection() throw(::com::sun::star::uno::RuntimeException)
{
	::vos::OGuard aGuard( GetMutex() );

	Selection aSel;
	Edit* pEdit = (Edit*) GetWindow();
	if ( pEdit )
		aSel = pEdit->GetSelection();
	return ::com::sun::star::awt::Selection( aSel.Min(), aSel.Max() );
}

sal_Bool VCLXEdit::isEditable() throw(::com::sun::star::uno::RuntimeException)
{
	::vos::OGuard aGuard( GetMutex() );

	Edit* pEdit = (Edit*) GetWindow();
	return ( pEdit && !pEdit->IsReadOnly() && pEdit->IsEnabled() ) ? sal_True : sal_False;
}

void VCLXEdit::setEditable( sal_Bool bEditable ) throw(::com::sun::star::uno::RuntimeException)
{
	::vos::OGuard aGuard( GetMutex() );

	Edit* pEdit = (Edit*) GetWindow();
	if ( pEdit )
		pEdit->SetReadOnly( !bEditable );
}


void VCLXEdit::setMaxTextLen( sal_Int16 nLen ) throw(::com::sun::star::uno::RuntimeException)
{
	::vos::OGuard aGuard( GetMutex() );

	Edit* pEdit = (Edit*) GetWindow();
	if ( pEdit )
		pEdit->SetMaxTextLen( nLen );
}

sal_Int16 VCLXEdit::getMaxTextLen() throw(::com::sun::star::uno::RuntimeException)
{
	::vos::OGuard aGuard( GetMutex() );

	Edit* pEdit = (Edit*) GetWindow();
	return pEdit ? pEdit->GetMaxTextLen() : 0;
}

void VCLXEdit::setEchoChar( sal_Unicode cEcho ) throw(::com::sun::star::uno::RuntimeException)
{
	::vos::OGuard aGuard( GetMutex() );

	Edit* pEdit = (Edit*) GetWindow();
	if ( pEdit )
		pEdit->SetEchoChar( cEcho );
}

void VCLXEdit::setProperty( const ::rtl::OUString& PropertyName, const ::com::sun::star::uno::Any& Value) throw(::com::sun::star::uno::RuntimeException)
{
	::vos::OGuard aGuard( GetMutex() );

	Edit* pEdit = (Edit*)GetWindow();
	if ( pEdit )
	{
		sal_uInt16 nPropType = GetPropertyId( PropertyName );
		switch ( nPropType )
		{
            case BASEPROPERTY_HIDEINACTIVESELECTION:
                ::toolkit::adjustBooleanWindowStyle( Value, pEdit, WB_NOHIDESELECTION, sal_True );
                if ( pEdit->GetSubEdit() )
                    ::toolkit::adjustBooleanWindowStyle( Value, pEdit->GetSubEdit(), WB_NOHIDESELECTION, sal_True );
                break;

            case BASEPROPERTY_READONLY:
			{
				sal_Bool b = sal_Bool();
				if ( Value >>= b )
 					pEdit->SetReadOnly( b );
			}
			break;
			case BASEPROPERTY_ECHOCHAR:
			{
				sal_Int16 n = sal_Int16();
				if ( Value >>= n )
 					pEdit->SetEchoChar( n );
			}
			break;
			case BASEPROPERTY_MAXTEXTLEN:
			{
				sal_Int16 n = sal_Int16();
				if ( Value >>= n )
 					pEdit->SetMaxTextLen( n );
			}
			break;
			default:
			{
				VCLXWindow::setProperty( PropertyName, Value );
			}
		}
	}
}

::com::sun::star::uno::Any VCLXEdit::getProperty( const ::rtl::OUString& PropertyName ) throw(::com::sun::star::uno::RuntimeException)
{
	::vos::OGuard aGuard( GetMutex() );

	::com::sun::star::uno::Any aProp;
	Edit* pEdit = (Edit*)GetWindow();
	if ( pEdit )
	{
		sal_uInt16 nPropType = GetPropertyId( PropertyName );
		switch ( nPropType )
		{
            case BASEPROPERTY_HIDEINACTIVESELECTION:
                aProp <<= (sal_Bool)( ( pEdit->GetStyle() & WB_NOHIDESELECTION ) == 0 );
                break;
			case BASEPROPERTY_READONLY:
 				aProp <<= (sal_Bool) pEdit->IsReadOnly();
    			break;
			case BASEPROPERTY_ECHOCHAR:
 				aProp <<= (sal_Int16) pEdit->GetEchoChar();
    			break;
			case BASEPROPERTY_MAXTEXTLEN:
 				aProp <<= (sal_Int16) pEdit->GetMaxTextLen();
    			break;
			default:
			{
				aProp = VCLXWindow::getProperty( PropertyName );
			}
		}
	}
	return aProp;
}

::com::sun::star::awt::Size VCLXEdit::getMinimumSize(  ) throw(::com::sun::star::uno::RuntimeException)
{
	::vos::OGuard aGuard( GetMutex() );

	Size aSz;
	Edit* pEdit = (Edit*) GetWindow();
	if ( pEdit )
		aSz = pEdit->CalcMinimumSize();
	return AWTSize(aSz);
}

::com::sun::star::awt::Size VCLXEdit::getPreferredSize(  ) throw(::com::sun::star::uno::RuntimeException)
{
	::vos::OGuard aGuard( GetMutex() );

	Size aSz;
	Edit* pEdit = (Edit*) GetWindow();
	if ( pEdit )
	{
		aSz = pEdit->CalcMinimumSize();
		aSz.Height() += 4;
	}
	return AWTSize(aSz);
}

::com::sun::star::awt::Size VCLXEdit::calcAdjustedSize( const ::com::sun::star::awt::Size& rNewSize ) throw(::com::sun::star::uno::RuntimeException)
{
	::vos::OGuard aGuard( GetMutex() );

	::com::sun::star::awt::Size aSz = rNewSize;
	::com::sun::star::awt::Size aMinSz = getMinimumSize();
	if ( aSz.Height != aMinSz.Height )
		aSz.Height = aMinSz.Height;

	return aSz;
}

::com::sun::star::awt::Size VCLXEdit::getMinimumSize( sal_Int16 nCols, sal_Int16 ) throw(::com::sun::star::uno::RuntimeException)
{
	::vos::OGuard aGuard( GetMutex() );

	Size aSz;
	Edit* pEdit = (Edit*) GetWindow();
	if ( pEdit )
	{
		if ( nCols )
			aSz = pEdit->CalcSize( nCols );
		else
			aSz = pEdit->CalcMinimumSize();
	}
	return AWTSize(aSz);
}

void VCLXEdit::getColumnsAndLines( sal_Int16& nCols, sal_Int16& nLines ) throw(::com::sun::star::uno::RuntimeException)
{
	::vos::OGuard aGuard( GetMutex() );

	nLines = 1;
	nCols = 0;
	Edit* pEdit = (Edit*) GetWindow();
	if ( pEdit )
		nCols = pEdit->GetMaxVisChars();
}

void VCLXEdit::ProcessWindowEvent( const VclWindowEvent& rVclWindowEvent )
{
	switch ( rVclWindowEvent.GetId() )
	{
		case VCLEVENT_EDIT_MODIFY:
        {
            ::com::sun::star::uno::Reference< ::com::sun::star::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 crashs, we keep us
                // alive as long as we're here
                // #20178# - 2003-10-01 - fs@openoffice.org

			if ( GetTextListeners().getLength() )
			{
				::com::sun::star::awt::TextEvent aEvent;
				aEvent.Source = (::cppu::OWeakObject*)this;
				GetTextListeners().textChanged( aEvent );
			}
        }
		break;

		default:
			VCLXWindow::ProcessWindowEvent( rVclWindowEvent );
			break;
	}
}

//	----------------------------------------------------
//	class VCLXComboBox
//	----------------------------------------------------

void VCLXComboBox::ImplGetPropertyIds( std::list< sal_uInt16 > &rIds )
{
    PushPropertyIds( rIds,
                     BASEPROPERTY_AUTOCOMPLETE,
                     BASEPROPERTY_BACKGROUNDCOLOR,
                     BASEPROPERTY_BORDER,
                     BASEPROPERTY_BORDERCOLOR,
                     BASEPROPERTY_DEFAULTCONTROL,
                     BASEPROPERTY_DROPDOWN,
                     BASEPROPERTY_ENABLED,
                     BASEPROPERTY_ENABLEVISIBLE,
                     BASEPROPERTY_FONTDESCRIPTOR,
                     BASEPROPERTY_HELPTEXT,
                     BASEPROPERTY_HELPURL,
                     BASEPROPERTY_LINECOUNT,
                     BASEPROPERTY_MAXTEXTLEN,
                     BASEPROPERTY_PRINTABLE,
                     BASEPROPERTY_READONLY,
                     BASEPROPERTY_STRINGITEMLIST,
                     BASEPROPERTY_TABSTOP,
                     BASEPROPERTY_TEXT,
                     BASEPROPERTY_HIDEINACTIVESELECTION,
                     BASEPROPERTY_ALIGN,
                     BASEPROPERTY_WRITING_MODE,
                     BASEPROPERTY_CONTEXT_WRITING_MODE,
                     BASEPROPERTY_REFERENCE_DEVICE,
                     BASEPROPERTY_MOUSE_WHEEL_BEHAVIOUR,
                     0);
    // no, don't call VCLXEdit here - it has properties which we do *not* want to have at at combo box
    // #i92690# / 2008-08-12 / frank.schoenheit@sun.com
    // VCLXEdit::ImplGetPropertyIds( rIds );
    VCLXWindow::ImplGetPropertyIds( rIds );
}

VCLXComboBox::VCLXComboBox()
	: maActionListeners( *this ), maItemListeners( *this )
{
}

VCLXComboBox::~VCLXComboBox()
{
#ifndef __SUNPRO_CC
    OSL_TRACE ("%s", __FUNCTION__);
#endif
}

::com::sun::star::uno::Reference< ::com::sun::star::accessibility::XAccessibleContext > VCLXComboBox::CreateAccessibleContext()
{
	::vos::OGuard aGuard( GetMutex() );

    return getAccessibleFactory().createAccessibleContext( this );
}

void VCLXComboBox::dispose() throw(::com::sun::star::uno::RuntimeException)
{
	::vos::OGuard aGuard( GetMutex() );

	::com::sun::star::lang::EventObject aObj;
	aObj.Source = (::cppu::OWeakObject*)this;
	maItemListeners.disposeAndClear( aObj );
	maActionListeners.disposeAndClear( aObj );
	VCLXEdit::dispose();
}


void VCLXComboBox::addItemListener( const ::com::sun::star::uno::Reference< ::com::sun::star::awt::XItemListener > & l ) throw(::com::sun::star::uno::RuntimeException)
{
	::vos::OGuard aGuard( GetMutex() );
	maItemListeners.addInterface( l );
}

void VCLXComboBox::removeItemListener( const ::com::sun::star::uno::Reference< ::com::sun::star::awt::XItemListener > & l ) throw(::com::sun::star::uno::RuntimeException)
{
	::vos::OGuard aGuard( GetMutex() );
	maItemListeners.removeInterface( l );
}

void VCLXComboBox::addActionListener( const ::com::sun::star::uno::Reference< ::com::sun::star::awt::XActionListener > & l ) throw(::com::sun::star::uno::RuntimeException)
{
	::vos::OGuard aGuard( GetMutex() );
	maActionListeners.addInterface( l );
}

void VCLXComboBox::removeActionListener( const ::com::sun::star::uno::Reference< ::com::sun::star::awt::XActionListener > & l ) throw(::com::sun::star::uno::RuntimeException)
{
	::vos::OGuard aGuard( GetMutex() );
	maActionListeners.removeInterface( l );
}

void VCLXComboBox::addItem( const ::rtl::OUString& aItem, sal_Int16 nPos ) throw(::com::sun::star::uno::RuntimeException)
{
	::vos::OGuard aGuard( GetMutex() );

	ComboBox* pBox = (ComboBox*) GetWindow();
	if ( pBox )
		pBox->InsertEntry( aItem, nPos );
}

void VCLXComboBox::addItems( const ::com::sun::star::uno::Sequence< ::rtl::OUString>& aItems, sal_Int16 nPos ) throw(::com::sun::star::uno::RuntimeException)
{
	::vos::OGuard aGuard( GetMutex() );

	ComboBox* pBox = (ComboBox*) GetWindow();
	if ( pBox )
	{
		sal_uInt16 nP = nPos;
		for ( sal_uInt16 n = 0; n < aItems.getLength(); n++ )
		{
			pBox->InsertEntry( aItems.getConstArray()[n], nP );
			if ( nP == 0xFFFF )
            {
                OSL_ENSURE( false, "VCLXComboBox::addItems: too many entries!" );
                // skip remaining entries, list cannot hold them, anyway
                break;
            }
		}
	}
}

void VCLXComboBox::removeItems( sal_Int16 nPos, sal_Int16 nCount ) throw(::com::sun::star::uno::RuntimeException)
{
	::vos::OGuard aGuard( GetMutex() );

	ComboBox* pBox = (ComboBox*) GetWindow();
	if ( pBox )
	{
		for ( sal_uInt16 n = nCount; n; )
			pBox->RemoveEntry( nPos + (--n) );
	}
}

sal_Int16 VCLXComboBox::getItemCount() throw(::com::sun::star::uno::RuntimeException)
{
	::vos::OGuard aGuard( GetMutex() );

	ComboBox* pBox = (ComboBox*) GetWindow();
	return pBox ? pBox->GetEntryCount() : 0;
}

::rtl::OUString VCLXComboBox::getItem( sal_Int16 nPos ) throw(::com::sun::star::uno::RuntimeException)
{
	::vos::OGuard aGuard( GetMutex() );

	::rtl::OUString aItem;
	ComboBox* pBox = (ComboBox*) GetWindow();
	if ( pBox )
		aItem = pBox->GetEntry( nPos );
	return aItem;
}

::com::sun::star::uno::Sequence< ::rtl::OUString> VCLXComboBox::getItems() throw(::com::sun::star::uno::RuntimeException)
{
	::vos::OGuard aGuard( GetMutex() );

	::com::sun::star::uno::Sequence< ::rtl::OUString> aSeq;
	ComboBox* pBox = (ComboBox*) GetWindow();
	if ( pBox )
	{
		sal_uInt16 nEntries = pBox->GetEntryCount();
		aSeq = ::com::sun::star::uno::Sequence< ::rtl::OUString>( nEntries );
		for ( sal_uInt16 n = nEntries; n; )
		{
			--n;
			aSeq.getArray()[n] = pBox->GetEntry( n );
		}
	}
	return aSeq;
}

void VCLXComboBox::setDropDownLineCount( sal_Int16 nLines ) throw(::com::sun::star::uno::RuntimeException)
{
	::vos::OGuard aGuard( GetMutex() );

	ComboBox* pBox = (ComboBox*) GetWindow();
	if ( pBox )
		pBox->SetDropDownLineCount( nLines );
}

sal_Int16 VCLXComboBox::getDropDownLineCount() throw(::com::sun::star::uno::RuntimeException)
{
	::vos::OGuard aGuard( GetMutex() );

	sal_Int16 nLines = 0;
	ComboBox* pBox = (ComboBox*) GetWindow();
	if ( pBox )
		nLines = pBox->GetDropDownLineCount();
	return nLines;
}

void VCLXComboBox::setProperty( const ::rtl::OUString& PropertyName, const ::com::sun::star::uno::Any& Value) throw(::com::sun::star::uno::RuntimeException)
{
	::vos::OGuard aGuard( GetMutex() );

	ComboBox* pComboBox = (ComboBox*)GetWindow();
	if ( pComboBox )
	{
		sal_uInt16 nPropType = GetPropertyId( PropertyName );
		switch ( nPropType )
		{
			case BASEPROPERTY_LINECOUNT:
			{
				sal_Int16 n = sal_Int16();
				if ( Value >>= n )
 					pComboBox->SetDropDownLineCount( n );
			}
			break;
			case BASEPROPERTY_AUTOCOMPLETE:
			{
				sal_Int16 n = sal_Int16();
				if ( Value >>= n )
 					pComboBox->EnableAutocomplete( n != 0 );
 				else
 				{
					sal_Bool b = sal_Bool();
					if ( Value >>= b )
						pComboBox->EnableAutocomplete( b );
				}
			}
			break;
			case BASEPROPERTY_STRINGITEMLIST:
			{
                ::com::sun::star::uno::Sequence< ::rtl::OUString> aItems;
				if ( Value >>= aItems )
				{
					pComboBox->Clear();
					addItems( aItems, 0 );
				}
			}
			break;
			default:
			{
				VCLXEdit::setProperty( PropertyName, Value );

				// #109385# SetBorderStyle is not virtual
				if ( nPropType == BASEPROPERTY_BORDER )
				{
					sal_uInt16 nBorder = sal_uInt16();
					if ( (Value >>= nBorder) && nBorder != 0 )
						pComboBox->SetBorderStyle( nBorder );
				}
			}
		}
	}
}

::com::sun::star::uno::Any VCLXComboBox::getProperty( const ::rtl::OUString& PropertyName ) throw(::com::sun::star::uno::RuntimeException)
{
	::vos::OGuard aGuard( GetMutex() );

	::com::sun::star::uno::Any aProp;
	ComboBox* pComboBox = (ComboBox*)GetWindow();
	if ( pComboBox )
	{
		sal_uInt16 nPropType = GetPropertyId( PropertyName );
		switch ( nPropType )
		{
			case BASEPROPERTY_LINECOUNT:
			{
 				aProp <<= (sal_Int16)  pComboBox->GetDropDownLineCount();
			}
			break;
			case BASEPROPERTY_AUTOCOMPLETE:
			{
 				aProp <<= (sal_Bool) pComboBox->IsAutocompleteEnabled();
			}
			break;
			case BASEPROPERTY_STRINGITEMLIST:
			{
				sal_uInt16 nItems = pComboBox->GetEntryCount();
				::com::sun::star::uno::Sequence< ::rtl::OUString> aSeq( nItems );
				::rtl::OUString* pStrings = aSeq.getArray();
				for ( sal_uInt16 n = 0; n < nItems; n++ )
					pStrings[n] = pComboBox->GetEntry( n );
				aProp <<= aSeq;

			}
			break;
			default:
			{
				aProp <<= VCLXEdit::getProperty( PropertyName );
			}
		}
	}
	return aProp;
}

void VCLXComboBox::ProcessWindowEvent( const VclWindowEvent& rVclWindowEvent )
{
    ::com::sun::star::uno::Reference< ::com::sun::star::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 crashs, we keep us
        // alive as long as we're here
        // #20178# - 2003-10-01 - fs@openoffice.org

	switch ( rVclWindowEvent.GetId() )
	{
		case VCLEVENT_COMBOBOX_SELECT:
			if ( maItemListeners.getLength() )
			{
				ComboBox* pComboBox = (ComboBox*)GetWindow();
                if( pComboBox )
                {
				    if ( !pComboBox->IsTravelSelect() )
				    {
					    ::com::sun::star::awt::ItemEvent aEvent;
					    aEvent.Source = (::cppu::OWeakObject*)this;
					    aEvent.Highlighted = sal_False;

					    // Bei Mehrfachselektion 0xFFFF, sonst die ID
					    aEvent.Selected = pComboBox->GetEntryPos( pComboBox->GetText() );

					    maItemListeners.itemStateChanged( aEvent );
				    }
                }
			}
			break;

		case VCLEVENT_COMBOBOX_DOUBLECLICK:
			if ( maActionListeners.getLength() )
			{
				::com::sun::star::awt::ActionEvent aEvent;
				aEvent.Source = (::cppu::OWeakObject*)this;
//				aEvent.ActionCommand = ...;
				maActionListeners.actionPerformed( aEvent );
			}
			break;

		default:
			VCLXEdit::ProcessWindowEvent( rVclWindowEvent );
			break;
	}
}

::com::sun::star::awt::Size VCLXComboBox::getMinimumSize(  ) throw(::com::sun::star::uno::RuntimeException)
{
	::vos::OGuard aGuard( GetMutex() );

	Size aSz;
	ComboBox* pComboBox = (ComboBox*) GetWindow();
	if ( pComboBox )
		aSz = pComboBox->CalcMinimumSize();
	return AWTSize(aSz);
}

::com::sun::star::awt::Size VCLXComboBox::getPreferredSize(  ) throw(::com::sun::star::uno::RuntimeException)
{
	::vos::OGuard aGuard( GetMutex() );

	Size aSz;
	ComboBox* pComboBox = (ComboBox*) GetWindow();
	if ( pComboBox )
	{
		aSz = pComboBox->CalcMinimumSize();
		if ( pComboBox->GetStyle() & WB_DROPDOWN )
			aSz.Height() += 4;
	}
	return AWTSize(aSz);
}

::com::sun::star::awt::Size VCLXComboBox::calcAdjustedSize( const ::com::sun::star::awt::Size& rNewSize ) throw(::com::sun::star::uno::RuntimeException)
{
	::vos::OGuard aGuard( GetMutex() );

	Size aSz = VCLSize(rNewSize);
	ComboBox* pComboBox = (ComboBox*) GetWindow();
	if ( pComboBox )
		aSz = pComboBox->CalcAdjustedSize( aSz );
	return AWTSize(aSz);
}

::com::sun::star::awt::Size VCLXComboBox::getMinimumSize( sal_Int16 nCols, sal_Int16 nLines ) throw(::com::sun::star::uno::RuntimeException)
{
	::vos::OGuard aGuard( GetMutex() );

	Size aSz;
	ComboBox* pComboBox = (ComboBox*) GetWindow();
	if ( pComboBox )
		aSz = pComboBox->CalcSize( nCols, nLines );
	return AWTSize(aSz);
}

void VCLXComboBox::getColumnsAndLines( sal_Int16& nCols, sal_Int16& nLines ) throw(::com::sun::star::uno::RuntimeException)
{
	::vos::OGuard aGuard( GetMutex() );

	nCols = nLines = 0;
	ComboBox* pComboBox = (ComboBox*) GetWindow();
	if ( pComboBox )
	{
		sal_uInt16 nC, nL;
		pComboBox->GetMaxVisColumnsAndLines( nC, nL );
		nCols = nC;
		nLines = nL;
	}
}
void SAL_CALL VCLXComboBox::listItemInserted( const ItemListEvent& i_rEvent ) throw (RuntimeException)
{
	::vos::OGuard aGuard( GetMutex() );

    ComboBox* pComboBox = dynamic_cast< ComboBox* >( GetWindow() );

    ENSURE_OR_RETURN_VOID( pComboBox, "VCLXComboBox::listItemInserted: no ComboBox?!" );
    ENSURE_OR_RETURN_VOID( ( i_rEvent.ItemPosition >= 0 ) && ( i_rEvent.ItemPosition <= sal_Int32( pComboBox->GetEntryCount() ) ),
        "VCLXComboBox::listItemInserted: illegal (inconsistent) item position!" );
    pComboBox->InsertEntry(
        i_rEvent.ItemText.IsPresent ? i_rEvent.ItemText.Value : ::rtl::OUString(),
        i_rEvent.ItemImageURL.IsPresent ? lcl_getImageFromURL( i_rEvent.ItemImageURL.Value ) : Image(),
        i_rEvent.ItemPosition );
}

void SAL_CALL VCLXComboBox::listItemRemoved( const ItemListEvent& i_rEvent ) throw (RuntimeException)
{
	::vos::OGuard aGuard( GetMutex() );

    ComboBox* pComboBox = dynamic_cast< ComboBox* >( GetWindow() );

    ENSURE_OR_RETURN_VOID( pComboBox, "VCLXComboBox::listItemRemoved: no ComboBox?!" );
    ENSURE_OR_RETURN_VOID( ( i_rEvent.ItemPosition >= 0 ) && ( i_rEvent.ItemPosition < sal_Int32( pComboBox->GetEntryCount() ) ),
        "VCLXComboBox::listItemRemoved: illegal (inconsistent) item position!" );

    pComboBox->RemoveEntry( i_rEvent.ItemPosition );
}

void SAL_CALL VCLXComboBox::listItemModified( const ItemListEvent& i_rEvent ) throw (RuntimeException)
{
	::vos::OGuard aGuard( GetMutex() );

    ComboBox* pComboBox = dynamic_cast< ComboBox* >( GetWindow() );

    ENSURE_OR_RETURN_VOID( pComboBox, "VCLXComboBox::listItemModified: no ComboBox?!" );
    ENSURE_OR_RETURN_VOID( ( i_rEvent.ItemPosition >= 0 ) && ( i_rEvent.ItemPosition < sal_Int32( pComboBox->GetEntryCount() ) ),
        "VCLXComboBox::listItemModified: illegal (inconsistent) item position!" );

    // VCL's ComboBox does not support changing an entry's text or image, so remove and re-insert

    const ::rtl::OUString sNewText = i_rEvent.ItemText.IsPresent ? i_rEvent.ItemText.Value : ::rtl::OUString( pComboBox->GetEntry( i_rEvent.ItemPosition ) );
    const Image aNewImage( i_rEvent.ItemImageURL.IsPresent ? lcl_getImageFromURL( i_rEvent.ItemImageURL.Value ) : pComboBox->GetEntryImage( i_rEvent.ItemPosition  ) );

    pComboBox->RemoveEntry( i_rEvent.ItemPosition );
    pComboBox->InsertEntry( sNewText, aNewImage, i_rEvent.ItemPosition );
}

void SAL_CALL VCLXComboBox::allItemsRemoved( const EventObject& i_rEvent ) throw (RuntimeException)
{
	::vos::OGuard aGuard( GetMutex() );

    ComboBox* pComboBox = dynamic_cast< ComboBox* >( GetWindow() );
    ENSURE_OR_RETURN_VOID( pComboBox, "VCLXComboBox::listItemModified: no ComboBox?!" );

    pComboBox->Clear();

    (void)i_rEvent;
}

void SAL_CALL VCLXComboBox::itemListChanged( const EventObject& i_rEvent ) throw (RuntimeException)
{
	::vos::OGuard aGuard( GetMutex() );

    ComboBox* pComboBox = dynamic_cast< ComboBox* >( GetWindow() );
    ENSURE_OR_RETURN_VOID( pComboBox, "VCLXComboBox::listItemModified: no ComboBox?!" );

    pComboBox->Clear();

    uno::Reference< beans::XPropertySet > xPropSet( i_rEvent.Source, uno::UNO_QUERY_THROW );
    uno::Reference< beans::XPropertySetInfo > xPSI( xPropSet->getPropertySetInfo(), uno::UNO_QUERY_THROW );
    // bool localize = xPSI->hasPropertyByName( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "ResourceResolver" ) ) );
    uno::Reference< resource::XStringResourceResolver > xStringResourceResolver;
    if ( xPSI->hasPropertyByName( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "ResourceResolver" ) ) ) )
    {
        xStringResourceResolver.set(
            xPropSet->getPropertyValue( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "ResourceResolver" ) ) ),
            uno::UNO_QUERY
        );
    }


    Reference< XItemList > xItemList( i_rEvent.Source, uno::UNO_QUERY_THROW );
    uno::Sequence< beans::Pair< ::rtl::OUString, ::rtl::OUString > > aItems = xItemList->getAllItems();
    for ( sal_Int32 i=0; i<aItems.getLength(); ++i )
    {
        ::rtl::OUString aLocalizationKey( aItems[i].First );
        if ( xStringResourceResolver.is() && aLocalizationKey.getLength() != 0 && aLocalizationKey[0] == '&' )
        {
            aLocalizationKey = xStringResourceResolver->resolveString(aLocalizationKey.copy( 1 ));
        }
        pComboBox->InsertEntry( aLocalizationKey, lcl_getImageFromURL( aItems[i].Second ) );
    }
}
void SAL_CALL VCLXComboBox::disposing( const EventObject& i_rEvent ) throw (RuntimeException)
{
    // just disambiguate
    VCLXEdit::disposing( i_rEvent );
}

//	----------------------------------------------------
//	class VCLXFormattedSpinField
//	----------------------------------------------------
void VCLXFormattedSpinField::ImplGetPropertyIds( std::list< sal_uInt16 > &rIds )
{
    // Interestingly in the UnoControl API this is
    // - not derived from XEdit ultimately, (correct ?) - so cut this here ...
//    VCLXSpinField::ImplGetPropertyIds( rIds );
    VCLXWindow::ImplGetPropertyIds( rIds );
}

VCLXFormattedSpinField::VCLXFormattedSpinField()
{
}

VCLXFormattedSpinField::~VCLXFormattedSpinField()
{
}

void VCLXFormattedSpinField::setStrictFormat( sal_Bool bStrict )
{
	::vos::OGuard aGuard( GetMutex() );

	FormatterBase* pFormatter = GetFormatter();
	if ( pFormatter )
		pFormatter->SetStrictFormat( bStrict );
}

sal_Bool VCLXFormattedSpinField::isStrictFormat()
{
	FormatterBase* pFormatter = GetFormatter();
	return pFormatter ? pFormatter->IsStrictFormat() : sal_False;
}


void VCLXFormattedSpinField::setProperty( const ::rtl::OUString& PropertyName, const ::com::sun::star::uno::Any& Value) throw(::com::sun::star::uno::RuntimeException)
{
	::vos::OGuard aGuard( GetMutex() );

	FormatterBase* pFormatter = GetFormatter();
	if ( pFormatter )
	{
		sal_uInt16 nPropType = GetPropertyId( PropertyName );
		switch ( nPropType )
		{
			case BASEPROPERTY_SPIN:
			{
				sal_Bool b = sal_Bool();
				if ( Value >>= b )
				{
					WinBits nStyle = GetWindow()->GetStyle() | WB_SPIN;
					if ( !b )
						nStyle &= ~WB_SPIN;
					GetWindow()->SetStyle( nStyle );
				}
			}
			break;
			case BASEPROPERTY_STRICTFORMAT:
			{
				sal_Bool b = sal_Bool();
				if ( Value >>= b )
				{
	 				pFormatter->SetStrictFormat( b );
				}
			}
			break;
			default:
			{
				VCLXSpinField::setProperty( PropertyName, Value );
			}
		}
	}
}

::com::sun::star::uno::Any VCLXFormattedSpinField::getProperty( const ::rtl::OUString& PropertyName ) throw(::com::sun::star::uno::RuntimeException)
{
	::vos::OGuard aGuard( GetMutex() );

	::com::sun::star::uno::Any aProp;
	FormatterBase* pFormatter = GetFormatter();
	if ( pFormatter )
	{
		sal_uInt16 nPropType = GetPropertyId( PropertyName );
		switch ( nPropType )
		{
			case BASEPROPERTY_TABSTOP:
			{
                aProp <<= (sal_Bool) ( ( GetWindow()->GetStyle() & WB_SPIN ) ? sal_True : sal_False );
			}
			break;
			case BASEPROPERTY_STRICTFORMAT:
			{
				aProp <<= (sal_Bool) pFormatter->IsStrictFormat();
			}
			break;
			default:
			{
				aProp <<= VCLXSpinField::getProperty( PropertyName );
			}
		}
	}
	return aProp;
}


//	----------------------------------------------------
//	class VCLXDateField
//	----------------------------------------------------

void VCLXDateField::ImplGetPropertyIds( std::list< sal_uInt16 > &rIds )
{
    PushPropertyIds( rIds,
                     BASEPROPERTY_ALIGN,
                     BASEPROPERTY_BACKGROUNDCOLOR,
                     BASEPROPERTY_BORDER,
                     BASEPROPERTY_BORDERCOLOR,
                     BASEPROPERTY_DATE,
                     BASEPROPERTY_DATEMAX,
                     BASEPROPERTY_DATEMIN,
                     BASEPROPERTY_DATESHOWCENTURY,
                     BASEPROPERTY_DEFAULTCONTROL,
                     BASEPROPERTY_DROPDOWN,
                     BASEPROPERTY_ENABLED,
                     BASEPROPERTY_ENABLEVISIBLE,
                     BASEPROPERTY_EXTDATEFORMAT,
                     BASEPROPERTY_FONTDESCRIPTOR,
                     BASEPROPERTY_HELPTEXT,
                     BASEPROPERTY_HELPURL,
                     BASEPROPERTY_PRINTABLE,
                     BASEPROPERTY_READONLY,
                     BASEPROPERTY_REPEAT,
                     BASEPROPERTY_REPEAT_DELAY,
                     BASEPROPERTY_SPIN,
                     BASEPROPERTY_STRICTFORMAT,
                     BASEPROPERTY_TABSTOP,
                     BASEPROPERTY_ENFORCE_FORMAT,
                     BASEPROPERTY_TEXT,
                     BASEPROPERTY_HIDEINACTIVESELECTION,
                     BASEPROPERTY_VERTICALALIGN,
                     BASEPROPERTY_WRITING_MODE,
                     BASEPROPERTY_CONTEXT_WRITING_MODE,
                     BASEPROPERTY_MOUSE_WHEEL_BEHAVIOUR,
                     0);
    VCLXFormattedSpinField::ImplGetPropertyIds( rIds );
}

VCLXDateField::VCLXDateField()
{
}

VCLXDateField::~VCLXDateField()
{
}

//change the window type here to match the role
::com::sun::star::uno::Reference< ::com::sun::star::accessibility::XAccessibleContext > VCLXDateField::CreateAccessibleContext()
{
	Window* pWindow = GetWindow();
	if ( pWindow )
	{
		pWindow->SetType( WINDOW_DATEFIELD );
	}
	return getAccessibleFactory().createAccessibleContext( this );
}

// ::com::sun::star::uno::XInterface
::com::sun::star::uno::Any VCLXDateField::queryInterface( const ::com::sun::star::uno::Type & rType ) throw(::com::sun::star::uno::RuntimeException)
{
	::com::sun::star::uno::Any aRet = ::cppu::queryInterface( rType,
										SAL_STATIC_CAST( ::com::sun::star::awt::XDateField*, this ) );
	return (aRet.hasValue() ? aRet : VCLXFormattedSpinField::queryInterface( rType ));
}

// ::com::sun::star::lang::XTypeProvider
IMPL_XTYPEPROVIDER_START( VCLXDateField )
	getCppuType( ( ::com::sun::star::uno::Reference< ::com::sun::star::awt::XDateField>* ) NULL ),
	VCLXFormattedSpinField::getTypes()
IMPL_XTYPEPROVIDER_END

void VCLXDateField::setProperty( const ::rtl::OUString& PropertyName, const ::com::sun::star::uno::Any& Value) throw(::com::sun::star::uno::RuntimeException)
{
	::vos::OGuard aGuard( GetMutex() );

	if ( GetWindow() )
	{
		sal_Bool bVoid = Value.getValueType().getTypeClass() == ::com::sun::star::uno::TypeClass_VOID;

		sal_uInt16 nPropType = GetPropertyId( PropertyName );
		switch ( nPropType )
		{
			case BASEPROPERTY_DATE:
			{
				if ( bVoid )
				{
					((DateField*)GetWindow())->EnableEmptyFieldValue( sal_True );
					((DateField*)GetWindow())->SetEmptyFieldValue();
				}
				else
				{
					sal_Int32 n = 0;
					if ( Value >>= n )
 						setDate( n );
				}
			}
			break;
			case BASEPROPERTY_DATEMIN:
			{
				sal_Int32 n = 0;
				if ( Value >>= n )
 					setMin( n );
			}
			break;
			case BASEPROPERTY_DATEMAX:
			{
				sal_Int32 n = 0;
				if ( Value >>= n )
 					setMax( n );
			}
			break;
			case BASEPROPERTY_EXTDATEFORMAT:
			{
				sal_Int16 n = sal_Int16();
				if ( Value >>= n )
					((DateField*)GetWindow())->SetExtDateFormat( (ExtDateFieldFormat) n );
			}
			break;
			case BASEPROPERTY_DATESHOWCENTURY:
			{
				sal_Bool b = sal_Bool();
				if ( Value >>= b )
 					((DateField*)GetWindow())->SetShowDateCentury( b );
			}
			break;
            case BASEPROPERTY_ENFORCE_FORMAT:
            {
				sal_Bool bEnforce( sal_True );
				OSL_VERIFY( Value >>= bEnforce );
                static_cast< DateField* >( GetWindow() )->EnforceValidValue( bEnforce );
            }
            break;
			default:
			{
				VCLXFormattedSpinField::setProperty( PropertyName, Value );
			}
		}
	}
}

::com::sun::star::uno::Any VCLXDateField::getProperty( const ::rtl::OUString& PropertyName ) throw(::com::sun::star::uno::RuntimeException)
{
	::vos::OGuard aGuard( GetMutex() );

	::com::sun::star::uno::Any aProp;
	FormatterBase* pFormatter = GetFormatter();
	if ( pFormatter )
	{
		sal_uInt16 nPropType = GetPropertyId( PropertyName );
		switch ( nPropType )
		{
			case BASEPROPERTY_DATE:
			{
				aProp <<= (sal_Int32) getDate();
			}
			break;
			case BASEPROPERTY_DATEMIN:
			{
				aProp <<= (sal_Int32) getMin();
			}
			break;
			case BASEPROPERTY_DATEMAX:
			{
				aProp <<= (sal_Int32) getMax();
			}
			break;
			case BASEPROPERTY_DATESHOWCENTURY:
			{
			    aProp <<= ((DateField*)GetWindow())->IsShowDateCentury();
			}
			break;
            case BASEPROPERTY_ENFORCE_FORMAT:
            {
                aProp <<= (sal_Bool)static_cast< DateField* >( GetWindow() )->IsEnforceValidValue( );
            }
            break;
			default:
			{
				aProp <<= VCLXFormattedSpinField::getProperty( PropertyName );
			}
		}
	}
	return aProp;
}


void VCLXDateField::setDate( sal_Int32 nDate ) throw(::com::sun::star::uno::RuntimeException)
{
	::vos::OGuard aGuard( GetMutex() );

	DateField* pDateField = (DateField*) GetWindow();
	if ( pDateField )
    {
		pDateField->SetDate( nDate );

        // #107218# Call same listeners like VCL would do after user interaction
        SetSynthesizingVCLEvent( sal_True );
        pDateField->SetModifyFlag();
        pDateField->Modify();
        SetSynthesizingVCLEvent( sal_False );
    }
}

sal_Int32 VCLXDateField::getDate() throw(::com::sun::star::uno::RuntimeException)
{
	::vos::OGuard aGuard( GetMutex() );

	sal_Int32 nDate = 0;
	DateField* pDateField = (DateField*) GetWindow();
	if ( pDateField )
		nDate = pDateField->GetDate().GetDate();

	return nDate;
}

void VCLXDateField::setMin( sal_Int32 nDate ) throw(::com::sun::star::uno::RuntimeException)
{
	::vos::OGuard aGuard( GetMutex() );

	DateField* pDateField = (DateField*) GetWindow();
	if ( pDateField )
		pDateField->SetMin( nDate );
}

sal_Int32 VCLXDateField::getMin() throw(::com::sun::star::uno::RuntimeException)
{
	::vos::OGuard aGuard( GetMutex() );

	sal_Int32 nDate = 0;
	DateField* pDateField = (DateField*) GetWindow();
	if ( pDateField )
		nDate = pDateField->GetMin().GetDate();

	return nDate;
}

void VCLXDateField::setMax( sal_Int32 nDate ) throw(::com::sun::star::uno::RuntimeException)
{
	::vos::OGuard aGuard( GetMutex() );

	DateField* pDateField = (DateField*) GetWindow();
	if ( pDateField )
		pDateField->SetMax( nDate );
}

sal_Int32 VCLXDateField::getMax() throw(::com::sun::star::uno::RuntimeException)
{
	::vos::OGuard aGuard( GetMutex() );

	sal_Int32 nDate = 0;
	DateField* pDateField = (DateField*) GetWindow();
	if ( pDateField )
		nDate = pDateField->GetMax().GetDate();

	return nDate;
}

void VCLXDateField::setFirst( sal_Int32 nDate ) throw(::com::sun::star::uno::RuntimeException)
{
	::vos::OGuard aGuard( GetMutex() );

	DateField* pDateField = (DateField*) GetWindow();
	if ( pDateField )
		pDateField->SetFirst( nDate );
}

sal_Int32 VCLXDateField::getFirst() throw(::com::sun::star::uno::RuntimeException)
{
	::vos::OGuard aGuard( GetMutex() );

	sal_Int32 nDate = 0;
	DateField* pDateField = (DateField*) GetWindow();
	if ( pDateField )
		nDate = pDateField->GetFirst().GetDate();

	return nDate;
}

void VCLXDateField::setLast( sal_Int32 nDate ) throw(::com::sun::star::uno::RuntimeException)
{
	::vos::OGuard aGuard( GetMutex() );

	DateField* pDateField = (DateField*) GetWindow();
	if ( pDateField )
		pDateField->SetLast( nDate );
}

sal_Int32 VCLXDateField::getLast() throw(::com::sun::star::uno::RuntimeException)
{
	::vos::OGuard aGuard( GetMutex() );

	sal_Int32 nDate = 0;
	DateField* pDateField = (DateField*) GetWindow();
	if ( pDateField )
		nDate = pDateField->GetLast().GetDate();

	return nDate;
}

void VCLXDateField::setLongFormat( sal_Bool bLong ) throw(::com::sun::star::uno::RuntimeException)
{
	::vos::OGuard aGuard( GetMutex() );

	DateField* pDateField = (DateField*) GetWindow();
	if ( pDateField )
		pDateField->SetLongFormat( bLong );
}

sal_Bool VCLXDateField::isLongFormat() throw(::com::sun::star::uno::RuntimeException)
{
	::vos::OGuard aGuard( GetMutex() );

	DateField* pDateField = (DateField*) GetWindow();
	return pDateField ? pDateField->IsLongFormat() : sal_False;
}

void VCLXDateField::setEmpty() throw(::com::sun::star::uno::RuntimeException)
{
	::vos::OGuard aGuard( GetMutex() );

	DateField* pDateField = (DateField*) GetWindow();
	if ( pDateField )
    {
		pDateField->SetEmptyDate();

        // #107218# Call same listeners like VCL would do after user interaction
        SetSynthesizingVCLEvent( sal_True );
        pDateField->SetModifyFlag();
        pDateField->Modify();
        SetSynthesizingVCLEvent( sal_False );
    }
}

sal_Bool VCLXDateField::isEmpty() throw(::com::sun::star::uno::RuntimeException)
{
	::vos::OGuard aGuard( GetMutex() );

	DateField* pDateField = (DateField*) GetWindow();
	return pDateField ? pDateField->IsEmptyDate() : sal_False;
}

void VCLXDateField::setStrictFormat( sal_Bool bStrict ) throw(::com::sun::star::uno::RuntimeException)
{
	VCLXFormattedSpinField::setStrictFormat( bStrict );
}

sal_Bool VCLXDateField::isStrictFormat() throw(::com::sun::star::uno::RuntimeException)
{
	return VCLXFormattedSpinField::isStrictFormat();
}


//	----------------------------------------------------
//	class VCLXTimeField
//	----------------------------------------------------

void VCLXTimeField::ImplGetPropertyIds( std::list< sal_uInt16 > &rIds )
{
    PushPropertyIds( rIds,
                     BASEPROPERTY_ALIGN,
                     BASEPROPERTY_BACKGROUNDCOLOR,
                     BASEPROPERTY_BORDER,
                     BASEPROPERTY_BORDERCOLOR,
                     BASEPROPERTY_DEFAULTCONTROL,
                     BASEPROPERTY_ENABLED,
                     BASEPROPERTY_ENABLEVISIBLE,
                     BASEPROPERTY_EXTTIMEFORMAT,
                     BASEPROPERTY_FONTDESCRIPTOR,
                     BASEPROPERTY_HELPTEXT,
                     BASEPROPERTY_HELPURL,
                     BASEPROPERTY_PRINTABLE,
                     BASEPROPERTY_READONLY,
                     BASEPROPERTY_REPEAT,
                     BASEPROPERTY_REPEAT_DELAY,
                     BASEPROPERTY_SPIN,
                     BASEPROPERTY_STRICTFORMAT,
                     BASEPROPERTY_TABSTOP,
                     BASEPROPERTY_TIME,
                     BASEPROPERTY_TIMEMAX,
                     BASEPROPERTY_TIMEMIN,
                     BASEPROPERTY_ENFORCE_FORMAT,
                     BASEPROPERTY_TEXT,
                     BASEPROPERTY_HIDEINACTIVESELECTION,
                     BASEPROPERTY_VERTICALALIGN,
                     BASEPROPERTY_WRITING_MODE,
                     BASEPROPERTY_CONTEXT_WRITING_MODE,
                     BASEPROPERTY_MOUSE_WHEEL_BEHAVIOUR,
                     0);
    VCLXFormattedSpinField::ImplGetPropertyIds( rIds );
}

VCLXTimeField::VCLXTimeField()
{
}

VCLXTimeField::~VCLXTimeField()
{
}
//change the window type here to match the role
::com::sun::star::uno::Reference< ::com::sun::star::accessibility::XAccessibleContext > VCLXTimeField::CreateAccessibleContext()
{
	Window* pWindow = GetWindow();
	if ( pWindow )
	{
		pWindow->SetType( WINDOW_TIMEFIELD );
	}
	return getAccessibleFactory().createAccessibleContext( this );
}

// ::com::sun::star::uno::XInterface
::com::sun::star::uno::Any VCLXTimeField::queryInterface( const ::com::sun::star::uno::Type & rType ) throw(::com::sun::star::uno::RuntimeException)
{
	::com::sun::star::uno::Any aRet = ::cppu::queryInterface( rType,
										SAL_STATIC_CAST( ::com::sun::star::awt::XTimeField*, this ) );
	return (aRet.hasValue() ? aRet : VCLXFormattedSpinField::queryInterface( rType ));
}

// ::com::sun::star::lang::XTypeProvider
IMPL_XTYPEPROVIDER_START( VCLXTimeField )
	getCppuType( ( ::com::sun::star::uno::Reference< ::com::sun::star::awt::XTimeField>* ) NULL ),
	VCLXFormattedSpinField::getTypes()
IMPL_XTYPEPROVIDER_END

void VCLXTimeField::setTime( sal_Int32 nTime ) throw(::com::sun::star::uno::RuntimeException)
{
	::vos::OGuard aGuard( GetMutex() );

	TimeField* pTimeField = (TimeField*) GetWindow();
	if ( pTimeField )
    {
		pTimeField->SetTime( nTime );

        // #107218# Call same listeners like VCL would do after user interaction
        SetSynthesizingVCLEvent( sal_True );
        pTimeField->SetModifyFlag();
        pTimeField->Modify();
        SetSynthesizingVCLEvent( sal_False );
    }
}

sal_Int32 VCLXTimeField::getTime() throw(::com::sun::star::uno::RuntimeException)
{
	::vos::OGuard aGuard( GetMutex() );

	sal_Int32 nTime = 0;
	TimeField* pTimeField = (TimeField*) GetWindow();
	if ( pTimeField )
		nTime = pTimeField->GetTime().GetTime();

	return nTime;
}

void VCLXTimeField::setMin( sal_Int32 nTime ) throw(::com::sun::star::uno::RuntimeException)
{
	::vos::OGuard aGuard( GetMutex() );

	TimeField* pTimeField = (TimeField*) GetWindow();
	if ( pTimeField )
		pTimeField->SetMin( nTime );
}

sal_Int32 VCLXTimeField::getMin() throw(::com::sun::star::uno::RuntimeException)
{
	::vos::OGuard aGuard( GetMutex() );

	sal_Int32 nTime = 0;
	TimeField* pTimeField = (TimeField*) GetWindow();
	if ( pTimeField )
		nTime = pTimeField->GetMin().GetTime();

	return nTime;
}

void VCLXTimeField::setMax( sal_Int32 nTime ) throw(::com::sun::star::uno::RuntimeException)
{
	::vos::OGuard aGuard( GetMutex() );

	TimeField* pTimeField = (TimeField*) GetWindow();
	if ( pTimeField )
		pTimeField->SetMax( nTime );
}

sal_Int32 VCLXTimeField::getMax() throw(::com::sun::star::uno::RuntimeException)
{
	::vos::OGuard aGuard( GetMutex() );

	sal_Int32 nTime = 0;
	TimeField* pTimeField = (TimeField*) GetWindow();
	if ( pTimeField )
		nTime = pTimeField->GetMax().GetTime();

	return nTime;
}

void VCLXTimeField::setFirst( sal_Int32 nTime ) throw(::com::sun::star::uno::RuntimeException)
{
	::vos::OGuard aGuard( GetMutex() );

	TimeField* pTimeField = (TimeField*) GetWindow();
	if ( pTimeField )
		pTimeField->SetFirst( nTime );
}

sal_Int32 VCLXTimeField::getFirst() throw(::com::sun::star::uno::RuntimeException)
{
	::vos::OGuard aGuard( GetMutex() );

	sal_Int32 nTime = 0;
	TimeField* pTimeField = (TimeField*) GetWindow();
	if ( pTimeField )
		nTime = pTimeField->GetFirst().GetTime();

	return nTime;
}

void VCLXTimeField::setLast( sal_Int32 nTime ) throw(::com::sun::star::uno::RuntimeException)
{
	::vos::OGuard aGuard( GetMutex() );

	TimeField* pTimeField = (TimeField*) GetWindow();
	if ( pTimeField )
		pTimeField->SetLast( nTime );
}

sal_Int32 VCLXTimeField::getLast() throw(::com::sun::star::uno::RuntimeException)
{
	::vos::OGuard aGuard( GetMutex() );

	sal_Int32 nTime = 0;
	TimeField* pTimeField = (TimeField*) GetWindow();
	if ( pTimeField )
		nTime = pTimeField->GetLast().GetTime();

	return nTime;
}

void VCLXTimeField::setEmpty() throw(::com::sun::star::uno::RuntimeException)
{
	::vos::OGuard aGuard( GetMutex() );

	TimeField* pTimeField = (TimeField*) GetWindow();
	if ( pTimeField )
		pTimeField->SetEmptyTime();
}

sal_Bool VCLXTimeField::isEmpty() throw(::com::sun::star::uno::RuntimeException)
{
	::vos::OGuard aGuard( GetMutex() );

	TimeField* pTimeField = (TimeField*) GetWindow();
	return pTimeField ? pTimeField->IsEmptyTime() : sal_False;
}

void VCLXTimeField::setStrictFormat( sal_Bool bStrict ) throw(::com::sun::star::uno::RuntimeException)
{
	VCLXFormattedSpinField::setStrictFormat( bStrict );
}

sal_Bool VCLXTimeField::isStrictFormat() throw(::com::sun::star::uno::RuntimeException)
{
	return VCLXFormattedSpinField::isStrictFormat();
}


void VCLXTimeField::setProperty( const ::rtl::OUString& PropertyName, const ::com::sun::star::uno::Any& Value) throw(::com::sun::star::uno::RuntimeException)
{
	::vos::OGuard aGuard( GetMutex() );

	if ( GetWindow() )
	{
		sal_Bool bVoid = Value.getValueType().getTypeClass() == ::com::sun::star::uno::TypeClass_VOID;

		sal_uInt16 nPropType = GetPropertyId( PropertyName );
		switch ( nPropType )
		{
			case BASEPROPERTY_TIME:
			{
				if ( bVoid )
				{
					((TimeField*)GetWindow())->EnableEmptyFieldValue( sal_True );
					((TimeField*)GetWindow())->SetEmptyFieldValue();
				}
				else
				{
					sal_Int32 n = 0;
					if ( Value >>= n )
 						setTime( n );
				}
			}
			break;
			case BASEPROPERTY_TIMEMIN:
			{
				sal_Int32 n = 0;
				if ( Value >>= n )
 					setMin( n );
			}
			break;
			case BASEPROPERTY_TIMEMAX:
			{
				sal_Int32 n = 0;
				if ( Value >>= n )
 					setMax( n );
			}
			break;
			case BASEPROPERTY_EXTTIMEFORMAT:
			{
				sal_Int16 n = sal_Int16();
				if ( Value >>= n )
					((TimeField*)GetWindow())->SetExtFormat( (ExtTimeFieldFormat) n );
			}
			break;
            case BASEPROPERTY_ENFORCE_FORMAT:
            {
				sal_Bool bEnforce( sal_True );
				OSL_VERIFY( Value >>= bEnforce );
                static_cast< TimeField* >( GetWindow() )->EnforceValidValue( bEnforce );
            }
            break;
			default:
			{
				VCLXFormattedSpinField::setProperty( PropertyName, Value );
			}
		}
	}
}

::com::sun::star::uno::Any VCLXTimeField::getProperty( const ::rtl::OUString& PropertyName ) throw(::com::sun::star::uno::RuntimeException)
{
	::vos::OGuard aGuard( GetMutex() );

	::com::sun::star::uno::Any aProp;
	if ( GetWindow() )
	{
		sal_uInt16 nPropType = GetPropertyId( PropertyName );
		switch ( nPropType )
		{
			case BASEPROPERTY_TIME:
			{
				aProp <<= (sal_Int32) getTime();
			}
			break;
			case BASEPROPERTY_TIMEMIN:
			{
				aProp <<= (sal_Int32) getMin();
			}
			break;
			case BASEPROPERTY_TIMEMAX:
			{
				aProp <<= (sal_Int32) getMax();
			}
			break;
            case BASEPROPERTY_ENFORCE_FORMAT:
            {
                aProp <<= (sal_Bool)static_cast< TimeField* >( GetWindow() )->IsEnforceValidValue( );
            }
            break;
			default:
			{
				aProp <<= VCLXFormattedSpinField::getProperty( PropertyName );
			}
		}
	}
	return aProp;
}

//	----------------------------------------------------
//	class VCLXNumericField
//	----------------------------------------------------

void VCLXNumericField::ImplGetPropertyIds( std::list< sal_uInt16 > &rIds )
{
    PushPropertyIds( rIds,
                     BASEPROPERTY_ALIGN,
                     BASEPROPERTY_BACKGROUNDCOLOR,
                     BASEPROPERTY_BORDER,
                     BASEPROPERTY_BORDERCOLOR,
                     BASEPROPERTY_DECIMALACCURACY,
                     BASEPROPERTY_DEFAULTCONTROL,
                     BASEPROPERTY_ENABLED,
                     BASEPROPERTY_ENABLEVISIBLE,
                     BASEPROPERTY_FONTDESCRIPTOR,
                     BASEPROPERTY_HELPTEXT,
                     BASEPROPERTY_HELPURL,
                     BASEPROPERTY_NUMSHOWTHOUSANDSEP,
                     BASEPROPERTY_PRINTABLE,
                     BASEPROPERTY_READONLY,
                     BASEPROPERTY_REPEAT,
                     BASEPROPERTY_REPEAT_DELAY,
                     BASEPROPERTY_SPIN,
                     BASEPROPERTY_STRICTFORMAT,
                     BASEPROPERTY_TABSTOP,
                     BASEPROPERTY_VALUEMAX_DOUBLE,
                     BASEPROPERTY_VALUEMIN_DOUBLE,
                     BASEPROPERTY_VALUESTEP_DOUBLE,
                     BASEPROPERTY_VALUE_DOUBLE,
                     BASEPROPERTY_ENFORCE_FORMAT,
                     BASEPROPERTY_HIDEINACTIVESELECTION,
                     BASEPROPERTY_VERTICALALIGN,
                     BASEPROPERTY_WRITING_MODE,
                     BASEPROPERTY_CONTEXT_WRITING_MODE,
                     BASEPROPERTY_MOUSE_WHEEL_BEHAVIOUR,
                     0);
    VCLXFormattedSpinField::ImplGetPropertyIds( rIds );
}

VCLXNumericField::VCLXNumericField()
{
}

VCLXNumericField::~VCLXNumericField()
{
}

// ::com::sun::star::uno::XInterface
::com::sun::star::uno::Any VCLXNumericField::queryInterface( const ::com::sun::star::uno::Type & rType ) throw(::com::sun::star::uno::RuntimeException)
{
	::com::sun::star::uno::Any aRet = ::cppu::queryInterface( rType,
										SAL_STATIC_CAST( ::com::sun::star::awt::XNumericField*, this ) );
	return (aRet.hasValue() ? aRet : VCLXFormattedSpinField::queryInterface( rType ));
}

// ::com::sun::star::lang::XTypeProvider
IMPL_XTYPEPROVIDER_START( VCLXNumericField )
	getCppuType( ( ::com::sun::star::uno::Reference< ::com::sun::star::awt::XNumericField>* ) NULL ),
	VCLXFormattedSpinField::getTypes()
IMPL_XTYPEPROVIDER_END

void VCLXNumericField::setValue( double Value ) throw(::com::sun::star::uno::RuntimeException)
{
	::vos::OGuard aGuard( GetMutex() );

	NumericFormatter* pNumericFormatter = (NumericFormatter*) GetFormatter();
	if ( pNumericFormatter )
	{
		// z.B. 105, 2 Digits => 1,05
		// ein float 1,05 muss also eine 105 einstellen...
		pNumericFormatter->SetValue(
			(long)ImplCalcLongValue( Value, pNumericFormatter->GetDecimalDigits() ) );

        // #107218# Call same listeners like VCL would do after user interaction
	    Edit* pEdit = (Edit*)GetWindow();
	    if ( pEdit )
        {
            SetSynthesizingVCLEvent( sal_True );
            pEdit->SetModifyFlag();
            pEdit->Modify();
            SetSynthesizingVCLEvent( sal_False );
        }
	}
}

double VCLXNumericField::getValue() throw(::com::sun::star::uno::RuntimeException)
{
	::vos::OGuard aGuard( GetMutex() );

	NumericFormatter* pNumericFormatter = (NumericFormatter*) GetFormatter();
	return pNumericFormatter
		? ImplCalcDoubleValue( (double)pNumericFormatter->GetValue(), pNumericFormatter->GetDecimalDigits() )
		: 0;
}

void VCLXNumericField::setMin( double Value ) throw(::com::sun::star::uno::RuntimeException)
{
	::vos::OGuard aGuard( GetMutex() );

	NumericFormatter* pNumericFormatter = (NumericFormatter*) GetFormatter();
	if ( pNumericFormatter )
		pNumericFormatter->SetMin(
			(long)ImplCalcLongValue( Value, pNumericFormatter->GetDecimalDigits() ) );
}

double VCLXNumericField::getMin() throw(::com::sun::star::uno::RuntimeException)
{
	::vos::OGuard aGuard( GetMutex() );

	NumericFormatter* pNumericFormatter = (NumericFormatter*) GetFormatter();
	return pNumericFormatter
		? ImplCalcDoubleValue( (double)pNumericFormatter->GetMin(), pNumericFormatter->GetDecimalDigits() )
		: 0;
}

void VCLXNumericField::setMax( double Value ) throw(::com::sun::star::uno::RuntimeException)
{
	::vos::OGuard aGuard( GetMutex() );

	NumericFormatter* pNumericFormatter = (NumericFormatter*) GetFormatter();
	if ( pNumericFormatter )
		pNumericFormatter->SetMax(
			(long)ImplCalcLongValue( Value, pNumericFormatter->GetDecimalDigits() ) );
}

double VCLXNumericField::getMax() throw(::com::sun::star::uno::RuntimeException)
{
	::vos::OGuard aGuard( GetMutex() );

	NumericFormatter* pNumericFormatter = (NumericFormatter*) GetFormatter();
	return pNumericFormatter
		? ImplCalcDoubleValue( (double)pNumericFormatter->GetMax(), pNumericFormatter->GetDecimalDigits() )
		: 0;
}

void VCLXNumericField::setFirst( double Value ) throw(::com::sun::star::uno::RuntimeException)
{
	::vos::OGuard aGuard( GetMutex() );

	NumericField* pNumericField = (NumericField*) GetWindow();
	if ( pNumericField )
		pNumericField->SetFirst(
			(long)ImplCalcLongValue( Value, pNumericField->GetDecimalDigits() ) );
}

double VCLXNumericField::getFirst() throw(::com::sun::star::uno::RuntimeException)
{
	::vos::OGuard aGuard( GetMutex() );

	NumericField* pNumericField = (NumericField*) GetWindow();
	return pNumericField
		? ImplCalcDoubleValue( (double)pNumericField->GetFirst(), pNumericField->GetDecimalDigits() )
		: 0;
}

void VCLXNumericField::setLast( double Value ) throw(::com::sun::star::uno::RuntimeException)
{
	::vos::OGuard aGuard( GetMutex() );

	NumericField* pNumericField = (NumericField*) GetWindow();
	if ( pNumericField )
		pNumericField->SetLast(
			(long)ImplCalcLongValue( Value, pNumericField->GetDecimalDigits() ) );
}

double VCLXNumericField::getLast() throw(::com::sun::star::uno::RuntimeException)
{
	::vos::OGuard aGuard( GetMutex() );

	NumericField* pNumericField = (NumericField*) GetWindow();
	return pNumericField
		? ImplCalcDoubleValue( (double)pNumericField->GetLast(), pNumericField->GetDecimalDigits() )
		: 0;
}

void VCLXNumericField::setStrictFormat( sal_Bool bStrict ) throw(::com::sun::star::uno::RuntimeException)
{
	VCLXFormattedSpinField::setStrictFormat( bStrict );
}

sal_Bool VCLXNumericField::isStrictFormat() throw(::com::sun::star::uno::RuntimeException)
{
	return VCLXFormattedSpinField::isStrictFormat();
}


void VCLXNumericField::setSpinSize( double Value ) throw(::com::sun::star::uno::RuntimeException)
{
	::vos::OGuard aGuard( GetMutex() );

	NumericField* pNumericField = (NumericField*) GetWindow();
	if ( pNumericField )
		pNumericField->SetSpinSize(
			(long)ImplCalcLongValue( Value, pNumericField->GetDecimalDigits() ) );
}

double VCLXNumericField::getSpinSize() throw(::com::sun::star::uno::RuntimeException)
{
	::vos::OGuard aGuard( GetMutex() );

	NumericField* pNumericField = (NumericField*) GetWindow();
	return pNumericField
		? ImplCalcDoubleValue( (double)pNumericField->GetSpinSize(), pNumericField->GetDecimalDigits() )
		: 0;
}

void VCLXNumericField::setDecimalDigits( sal_Int16 Value ) throw(::com::sun::star::uno::RuntimeException)
{
	::vos::OGuard aGuard( GetMutex() );

	NumericFormatter* pNumericFormatter = (NumericFormatter*) GetFormatter();
	if ( pNumericFormatter )
	{
		double n = getValue();
		pNumericFormatter->SetDecimalDigits( Value );
		setValue( n );
   	}
}

sal_Int16 VCLXNumericField::getDecimalDigits() throw(::com::sun::star::uno::RuntimeException)
{
	::vos::OGuard aGuard( GetMutex() );

	NumericFormatter* pNumericFormatter = (NumericFormatter*) GetFormatter();
	return pNumericFormatter ? pNumericFormatter->GetDecimalDigits() : 0;
}

void VCLXNumericField::setProperty( const ::rtl::OUString& PropertyName, const ::com::sun::star::uno::Any& Value) throw(::com::sun::star::uno::RuntimeException)
{
	::vos::OGuard aGuard( GetMutex() );

	if ( GetWindow() )
	{
		sal_Bool bVoid = Value.getValueType().getTypeClass() == ::com::sun::star::uno::TypeClass_VOID;

		sal_uInt16 nPropType = GetPropertyId( PropertyName );
		switch ( nPropType )
		{
			case BASEPROPERTY_VALUE_DOUBLE:
			{
				if ( bVoid )
				{
					((NumericField*)GetWindow())->EnableEmptyFieldValue( sal_True );
					((NumericField*)GetWindow())->SetEmptyFieldValue();
				}
				else
				{
					double d = 0;
					if ( Value >>= d )
 						setValue( d );
				}
			}
			break;
			case BASEPROPERTY_VALUEMIN_DOUBLE:
			{
				double d = 0;
				if ( Value >>= d )
 					setMin( d );
			}
			break;
			case BASEPROPERTY_VALUEMAX_DOUBLE:
			{
				double d = 0;
				if ( Value >>= d )
 					setMax( d );
			}
			break;
			case BASEPROPERTY_VALUESTEP_DOUBLE:
			{
				double d = 0;
				if ( Value >>= d )
 					setSpinSize( d );
			}
			break;
			case BASEPROPERTY_DECIMALACCURACY:
			{
				sal_Int16 n = sal_Int16();
				if ( Value >>= n )
 					setDecimalDigits( n );
			}
			break;
			case BASEPROPERTY_NUMSHOWTHOUSANDSEP:
			{
				sal_Bool b = sal_Bool();
				if ( Value >>= b )
 					((NumericField*)GetWindow())->SetUseThousandSep( b );
			}
			break;
			default:
			{
				VCLXFormattedSpinField::setProperty( PropertyName, Value );
			}
		}
	}
}

::com::sun::star::uno::Any VCLXNumericField::getProperty( const ::rtl::OUString& PropertyName ) throw(::com::sun::star::uno::RuntimeException)
{
	::vos::OGuard aGuard( GetMutex() );

	::com::sun::star::uno::Any aProp;
	FormatterBase* pFormatter = GetFormatter();
	if ( pFormatter )
	{
		sal_uInt16 nPropType = GetPropertyId( PropertyName );
		switch ( nPropType )
		{
			case BASEPROPERTY_VALUE_DOUBLE:
			{
				aProp <<= (double) getValue();
			}
			break;
			case BASEPROPERTY_VALUEMIN_DOUBLE:
			{
				aProp <<= (double) getMin();
			}
			break;
			case BASEPROPERTY_VALUEMAX_DOUBLE:
			{
				aProp <<= (double) getMax();
			}
			break;
			case BASEPROPERTY_VALUESTEP_DOUBLE:
			{
				aProp <<= (double) getSpinSize();
			}
			break;
			case BASEPROPERTY_NUMSHOWTHOUSANDSEP:
			{
			    aProp <<= (sal_Bool) ((NumericField*)GetWindow())->IsUseThousandSep();
			}
			break;
			default:
			{
				aProp <<= VCLXFormattedSpinField::getProperty( PropertyName );
			}
		}
	}
	return aProp;
}


//    ----------------------------------------------------
//    class VCLXMetricField
//    ----------------------------------------------------

void VCLXMetricField::ImplGetPropertyIds( std::list< sal_uInt16 > &rIds )
{
    PushPropertyIds( rIds,
                     BASEPROPERTY_ALIGN,
                     BASEPROPERTY_BACKGROUNDCOLOR,
                     BASEPROPERTY_BORDER,
                     BASEPROPERTY_BORDERCOLOR,
                     BASEPROPERTY_DECIMALACCURACY,
                     BASEPROPERTY_DEFAULTCONTROL,
                     BASEPROPERTY_ENABLED,
                     BASEPROPERTY_ENABLEVISIBLE,
                     BASEPROPERTY_FONTDESCRIPTOR,
                     BASEPROPERTY_HELPTEXT,
                     BASEPROPERTY_HELPURL,
                     BASEPROPERTY_NUMSHOWTHOUSANDSEP,
                     BASEPROPERTY_PRINTABLE,
                     BASEPROPERTY_READONLY,
                     BASEPROPERTY_REPEAT,
                     BASEPROPERTY_REPEAT_DELAY,
                     BASEPROPERTY_SPIN,
                     BASEPROPERTY_STRICTFORMAT,
                     BASEPROPERTY_TABSTOP,
                     BASEPROPERTY_ENFORCE_FORMAT,
                     BASEPROPERTY_HIDEINACTIVESELECTION,
                     BASEPROPERTY_UNIT,
                     BASEPROPERTY_CUSTOMUNITTEXT,
                     BASEPROPERTY_WRITING_MODE,
                     BASEPROPERTY_CONTEXT_WRITING_MODE,
                     BASEPROPERTY_MOUSE_WHEEL_BEHAVIOUR,
                     0);
    VCLXFormattedSpinField::ImplGetPropertyIds( rIds );
}

VCLXMetricField::VCLXMetricField()
{
}

VCLXMetricField::~VCLXMetricField()
{
}

MetricFormatter *VCLXMetricField::GetMetricFormatter() throw(::com::sun::star::uno::RuntimeException)
{
    MetricFormatter *pFormatter = (MetricFormatter *) GetFormatter();
    if (!pFormatter)
        throw ::com::sun::star::uno::RuntimeException();
    return pFormatter;
}

MetricField *VCLXMetricField::GetMetricField() throw(::com::sun::star::uno::RuntimeException)
{
    MetricField *pField = (MetricField *) GetWindow();
    if (!pField)
        throw ::com::sun::star::uno::RuntimeException();
    return pField;
}

// ::com::sun::star::uno::XInterface
::com::sun::star::uno::Any VCLXMetricField::queryInterface( const ::com::sun::star::uno::Type & rType ) throw(::com::sun::star::uno::RuntimeException)
{
    ::com::sun::star::uno::Any aRet = ::cppu::queryInterface( rType,
                                                              SAL_STATIC_CAST( ::com::sun::star::awt::XMetricField*, this ) );
    return (aRet.hasValue() ? aRet : VCLXFormattedSpinField::queryInterface( rType ));
}

// ::com::sun::star::lang::XTypeProvider
IMPL_XTYPEPROVIDER_START( VCLXMetricField )
    getCppuType( ( ::com::sun::star::uno::Reference< ::com::sun::star::awt::XMetricField>* ) NULL ),
    VCLXFormattedSpinField::getTypes()
IMPL_XTYPEPROVIDER_END

// FIXME: later ...
#define MetricUnitUnoToVcl(a) ((FieldUnit)(a))

#define METRIC_MAP_PAIR(method,parent) \
    sal_Int64 VCLXMetricField::get##method( sal_Int16 nUnit ) throw (::com::sun::star::uno::RuntimeException) \
    { \
        ::vos::OGuard aGuard( GetMutex() ); \
        return GetMetric##parent()->Get##method( MetricUnitUnoToVcl( nUnit ) ); \
    } \
    void VCLXMetricField::set##method( sal_Int64 nValue, sal_Int16 nUnit ) throw (::com::sun::star::uno::RuntimeException) \
    { \
        ::vos::OGuard aGuard( GetMutex() ); \
        GetMetric##parent()->Set##method( nValue, MetricUnitUnoToVcl( nUnit ) ); \
    }

METRIC_MAP_PAIR(Min, Formatter)
METRIC_MAP_PAIR(Max, Formatter)
METRIC_MAP_PAIR(First, Field)
METRIC_MAP_PAIR(Last,  Field)

#undef METRIC_MAP_PAIR

::sal_Int64 VCLXMetricField::getValue( ::sal_Int16 nUnit ) throw (::com::sun::star::uno::RuntimeException)
{
    ::vos::OGuard aGuard( GetMutex() );
    return GetMetricFormatter()->GetValue( MetricUnitUnoToVcl( nUnit ) );
}

::sal_Int64 VCLXMetricField::getCorrectedValue( ::sal_Int16 nUnit ) throw (::com::sun::star::uno::RuntimeException)
{
    ::vos::OGuard aGuard( GetMutex() );
    return GetMetricFormatter()->GetCorrectedValue( MetricUnitUnoToVcl( nUnit ) );
}

// FIXME: acute cut/paste evilness - move this to the parent Edit class ?
void VCLXMetricField::CallListeners()
{
    // #107218# Call same listeners like VCL would do after user interaction
    Edit* pEdit = (Edit*)GetWindow();
    if ( pEdit )
    {
        SetSynthesizingVCLEvent( sal_True );
        pEdit->SetModifyFlag();
        pEdit->Modify();
        SetSynthesizingVCLEvent( sal_False );
    }
}

void VCLXMetricField::setValue( ::sal_Int64 Value, ::sal_Int16 Unit ) throw (::com::sun::star::uno::RuntimeException)
{
    ::vos::OGuard aGuard( GetMutex() );
    GetMetricFormatter()->SetValue( Value, MetricUnitUnoToVcl( Unit ) );
    CallListeners();
}

void VCLXMetricField::setUserValue( ::sal_Int64 Value, ::sal_Int16 Unit ) throw (::com::sun::star::uno::RuntimeException)
{
    ::vos::OGuard aGuard( GetMutex() );
    GetMetricFormatter()->SetUserValue( Value, MetricUnitUnoToVcl( Unit ) );
    CallListeners();
}

void VCLXMetricField::setStrictFormat( sal_Bool bStrict ) throw(::com::sun::star::uno::RuntimeException)
{
    VCLXFormattedSpinField::setStrictFormat( bStrict );
}

sal_Bool VCLXMetricField::isStrictFormat() throw(::com::sun::star::uno::RuntimeException)
{
    return VCLXFormattedSpinField::isStrictFormat();
}

void VCLXMetricField::setSpinSize( sal_Int64 Value ) throw(::com::sun::star::uno::RuntimeException)
{
    ::vos::OGuard aGuard( GetMutex() );
    GetMetricField()->SetSpinSize( Value );
}

sal_Int64 VCLXMetricField::getSpinSize() throw(::com::sun::star::uno::RuntimeException)
{
    ::vos::OGuard aGuard( GetMutex() );
    return GetMetricField()->GetSpinSize();
}

void VCLXMetricField::setDecimalDigits( sal_Int16 Value ) throw(::com::sun::star::uno::RuntimeException)
{
    ::vos::OGuard aGuard( GetMutex() );
    GetMetricFormatter()->SetDecimalDigits( Value );
}

sal_Int16 VCLXMetricField::getDecimalDigits() throw(::com::sun::star::uno::RuntimeException)
{
    ::vos::OGuard aGuard( GetMutex() );

    NumericFormatter* pNumericFormatter = (NumericFormatter*) GetFormatter();
    return pNumericFormatter ? pNumericFormatter->GetDecimalDigits() : 0;
}

void VCLXMetricField::setProperty( const ::rtl::OUString& PropertyName, const ::com::sun::star::uno::Any& Value) throw(::com::sun::star::uno::RuntimeException)
{
    ::vos::OGuard aGuard( GetMutex() );

    if ( GetWindow() )
    {
        sal_uInt16 nPropType = GetPropertyId( PropertyName );
        switch ( nPropType )
        {
            case BASEPROPERTY_DECIMALACCURACY:
            {
                sal_Int16 n = 0;
                if ( Value >>= n )
                     setDecimalDigits( n );
                break;
            }
            case BASEPROPERTY_NUMSHOWTHOUSANDSEP:
            {
                sal_Bool b = sal_False;
                if ( Value >>= b )
                     ((NumericField*)GetWindow())->SetUseThousandSep( b );
            }
            break;
            case BASEPROPERTY_UNIT:
            {
                sal_uInt16 nVal = 0;
                if ( Value >>= nVal )
                    ((MetricField*)GetWindow())->SetUnit( (FieldUnit) nVal );
                break;
            }
            case BASEPROPERTY_CUSTOMUNITTEXT:
            {
                rtl::OUString aStr;
                if ( Value >>= aStr )
                    ((MetricField*)GetWindow())->SetCustomUnitText( aStr );
                break;
            }
            default:
            {
                VCLXFormattedSpinField::setProperty( PropertyName, Value );
                break;
            }
        }
    }
}

::com::sun::star::uno::Any VCLXMetricField::getProperty( const ::rtl::OUString& PropertyName ) throw(::com::sun::star::uno::RuntimeException)
{
    ::vos::OGuard aGuard( GetMutex() );

    ::com::sun::star::uno::Any aProp;
    FormatterBase* pFormatter = GetFormatter();
    if ( pFormatter )
    {
        sal_uInt16 nPropType = GetPropertyId( PropertyName );
        switch ( nPropType )
        {
            case BASEPROPERTY_NUMSHOWTHOUSANDSEP:
                aProp <<= (sal_Bool) ((NumericField*)GetWindow())->IsUseThousandSep();
                break;
            case BASEPROPERTY_UNIT:
                aProp <<= (sal_uInt16) ((MetricField*)GetWindow())->GetUnit();
                break;
            case BASEPROPERTY_CUSTOMUNITTEXT:
                aProp <<= rtl::OUString (((MetricField*)GetWindow())->GetCustomUnitText());
                break;
            default:
            {
                aProp <<= VCLXFormattedSpinField::getProperty( PropertyName );
                break;
            }
        }
    }
    return aProp;
}


//	----------------------------------------------------
//	class VCLXCurrencyField
//	----------------------------------------------------

void VCLXCurrencyField::ImplGetPropertyIds( std::list< sal_uInt16 > &rIds )
{
    PushPropertyIds( rIds,
                     BASEPROPERTY_ALIGN,
                     BASEPROPERTY_BACKGROUNDCOLOR,
                     BASEPROPERTY_BORDER,
                     BASEPROPERTY_BORDERCOLOR,
                     BASEPROPERTY_CURRENCYSYMBOL,
                     BASEPROPERTY_CURSYM_POSITION,
                     BASEPROPERTY_DECIMALACCURACY,
                     BASEPROPERTY_DEFAULTCONTROL,
                     BASEPROPERTY_ENABLED,
                     BASEPROPERTY_ENABLEVISIBLE,
                     BASEPROPERTY_FONTDESCRIPTOR,
                     BASEPROPERTY_HELPTEXT,
                     BASEPROPERTY_HELPURL,
                     BASEPROPERTY_NUMSHOWTHOUSANDSEP,
                     BASEPROPERTY_PRINTABLE,
                     BASEPROPERTY_READONLY,
                     BASEPROPERTY_REPEAT,
                     BASEPROPERTY_REPEAT_DELAY,
                     BASEPROPERTY_SPIN,
                     BASEPROPERTY_STRICTFORMAT,
                     BASEPROPERTY_TABSTOP,
                     BASEPROPERTY_VALUEMAX_DOUBLE,
                     BASEPROPERTY_VALUEMIN_DOUBLE,
                     BASEPROPERTY_VALUESTEP_DOUBLE,
                     BASEPROPERTY_VALUE_DOUBLE,
                     BASEPROPERTY_ENFORCE_FORMAT,
                     BASEPROPERTY_HIDEINACTIVESELECTION,
                     BASEPROPERTY_VERTICALALIGN,
                     BASEPROPERTY_WRITING_MODE,
                     BASEPROPERTY_CONTEXT_WRITING_MODE,
                     BASEPROPERTY_MOUSE_WHEEL_BEHAVIOUR,
                     0);
    VCLXFormattedSpinField::ImplGetPropertyIds( rIds );
}

VCLXCurrencyField::VCLXCurrencyField()
{
}

VCLXCurrencyField::~VCLXCurrencyField()
{
}

// ::com::sun::star::uno::XInterface
::com::sun::star::uno::Any VCLXCurrencyField::queryInterface( const ::com::sun::star::uno::Type & rType ) throw(::com::sun::star::uno::RuntimeException)
{
	::com::sun::star::uno::Any aRet = ::cppu::queryInterface( rType,
										SAL_STATIC_CAST( ::com::sun::star::awt::XCurrencyField*, this ) );
	return (aRet.hasValue() ? aRet : VCLXFormattedSpinField::queryInterface( rType ));
}

// ::com::sun::star::lang::XTypeProvider
IMPL_XTYPEPROVIDER_START( VCLXCurrencyField )
	getCppuType( ( ::com::sun::star::uno::Reference< ::com::sun::star::awt::XCurrencyField>* ) NULL ),
	VCLXFormattedSpinField::getTypes()
IMPL_XTYPEPROVIDER_END

void VCLXCurrencyField::setValue( double Value ) throw(::com::sun::star::uno::RuntimeException)
{
	::vos::OGuard aGuard( GetMutex() );

	LongCurrencyFormatter* pCurrencyFormatter = (LongCurrencyFormatter*) GetFormatter();
	if ( pCurrencyFormatter )
	{
		// z.B. 105, 2 Digits => 1,05
		// ein float 1,05 muss also eine 105 einstellen...
		pCurrencyFormatter->SetValue(
			ImplCalcLongValue( Value, pCurrencyFormatter->GetDecimalDigits() ) );

        // #107218# Call same listeners like VCL would do after user interaction
	    Edit* pEdit = (Edit*)GetWindow();
	    if ( pEdit )
        {
            SetSynthesizingVCLEvent( sal_True );
            pEdit->SetModifyFlag();
            pEdit->Modify();
            SetSynthesizingVCLEvent( sal_False );
        }
	}
}

double VCLXCurrencyField::getValue() throw(::com::sun::star::uno::RuntimeException)
{
	::vos::OGuard aGuard( GetMutex() );

	LongCurrencyFormatter* pCurrencyFormatter = (LongCurrencyFormatter*) GetFormatter();
	return pCurrencyFormatter
		? ImplCalcDoubleValue( (double)pCurrencyFormatter->GetValue(), pCurrencyFormatter->GetDecimalDigits() )
		: 0;
}

void VCLXCurrencyField::setMin( double Value ) throw(::com::sun::star::uno::RuntimeException)
{
	::vos::OGuard aGuard( GetMutex() );

	LongCurrencyFormatter* pCurrencyFormatter = (LongCurrencyFormatter*) GetFormatter();
	if ( pCurrencyFormatter )
		pCurrencyFormatter->SetMin(
			ImplCalcLongValue( Value, pCurrencyFormatter->GetDecimalDigits() ) );
}

double VCLXCurrencyField::getMin() throw(::com::sun::star::uno::RuntimeException)
{
	::vos::OGuard aGuard( GetMutex() );

	LongCurrencyFormatter* pCurrencyFormatter = (LongCurrencyFormatter*) GetFormatter();
	return pCurrencyFormatter
		? ImplCalcDoubleValue( (double)pCurrencyFormatter->GetMin(), pCurrencyFormatter->GetDecimalDigits() )
		: 0;
}

void VCLXCurrencyField::setMax( double Value ) throw(::com::sun::star::uno::RuntimeException)
{
	::vos::OGuard aGuard( GetMutex() );

	LongCurrencyFormatter* pCurrencyFormatter = (LongCurrencyFormatter*) GetFormatter();
	if ( pCurrencyFormatter )
		pCurrencyFormatter->SetMax(
			ImplCalcLongValue( Value, pCurrencyFormatter->GetDecimalDigits() ) );
}

double VCLXCurrencyField::getMax() throw(::com::sun::star::uno::RuntimeException)
{
	::vos::OGuard aGuard( GetMutex() );

	LongCurrencyFormatter* pCurrencyFormatter = (LongCurrencyFormatter*) GetFormatter();
	return pCurrencyFormatter
		? ImplCalcDoubleValue( (double)pCurrencyFormatter->GetMax(), pCurrencyFormatter->GetDecimalDigits() )
		: 0;
}

void VCLXCurrencyField::setFirst( double Value ) throw(::com::sun::star::uno::RuntimeException)
{
	::vos::OGuard aGuard( GetMutex() );

	LongCurrencyField* pCurrencyField = (LongCurrencyField*) GetWindow();
	if ( pCurrencyField )
		pCurrencyField->SetFirst(
			ImplCalcLongValue( Value, pCurrencyField->GetDecimalDigits() ) );
}

double VCLXCurrencyField::getFirst() throw(::com::sun::star::uno::RuntimeException)
{
	::vos::OGuard aGuard( GetMutex() );

	LongCurrencyField* pCurrencyField = (LongCurrencyField*) GetWindow();
	return pCurrencyField
		? ImplCalcDoubleValue( (double)pCurrencyField->GetFirst(), pCurrencyField->GetDecimalDigits() )
		: 0;
}

void VCLXCurrencyField::setLast( double Value ) throw(::com::sun::star::uno::RuntimeException)
{
	::vos::OGuard aGuard( GetMutex() );

	LongCurrencyField* pCurrencyField = (LongCurrencyField*) GetWindow();
	if ( pCurrencyField )
		pCurrencyField->SetLast(
			ImplCalcLongValue( Value, pCurrencyField->GetDecimalDigits() ) );
}

double VCLXCurrencyField::getLast() throw(::com::sun::star::uno::RuntimeException)
{
	::vos::OGuard aGuard( GetMutex() );

	LongCurrencyField* pCurrencyField = (LongCurrencyField*) GetWindow();
	return pCurrencyField
		? ImplCalcDoubleValue( (double)pCurrencyField->GetLast(), pCurrencyField->GetDecimalDigits() )
		: 0;
}

void VCLXCurrencyField::setSpinSize( double Value ) throw(::com::sun::star::uno::RuntimeException)
{
	::vos::OGuard aGuard( GetMutex() );

	LongCurrencyField* pCurrencyField = (LongCurrencyField*) GetWindow();
	if ( pCurrencyField )
		pCurrencyField->SetSpinSize(
			ImplCalcLongValue( Value, pCurrencyField->GetDecimalDigits() ) );
}

double VCLXCurrencyField::getSpinSize() throw(::com::sun::star::uno::RuntimeException)
{
	::vos::OGuard aGuard( GetMutex() );

	LongCurrencyField* pCurrencyField = (LongCurrencyField*) GetWindow();
	return pCurrencyField
		? ImplCalcDoubleValue( (double)pCurrencyField->GetSpinSize(), pCurrencyField->GetDecimalDigits() )
		: 0;
}

void VCLXCurrencyField::setStrictFormat( sal_Bool bStrict ) throw(::com::sun::star::uno::RuntimeException)
{
	VCLXFormattedSpinField::setStrictFormat( bStrict );
}

sal_Bool VCLXCurrencyField::isStrictFormat() throw(::com::sun::star::uno::RuntimeException)
{
	return VCLXFormattedSpinField::isStrictFormat();
}


void VCLXCurrencyField::setDecimalDigits( sal_Int16 Value ) throw(::com::sun::star::uno::RuntimeException)
{
	::vos::OGuard aGuard( GetMutex() );

	LongCurrencyFormatter* pCurrencyFormatter = (LongCurrencyFormatter*) GetFormatter();
	if ( pCurrencyFormatter )
	{
		double n = getValue();
		pCurrencyFormatter->SetDecimalDigits( Value );
		setValue( n );
   	}
}

sal_Int16 VCLXCurrencyField::getDecimalDigits() throw(::com::sun::star::uno::RuntimeException)
{
	::vos::OGuard aGuard( GetMutex() );

	LongCurrencyFormatter* pCurrencyFormatter = (LongCurrencyFormatter*) GetFormatter();
	return pCurrencyFormatter ? pCurrencyFormatter->GetDecimalDigits() : 0;
}

void VCLXCurrencyField::setProperty( const ::rtl::OUString& PropertyName, const ::com::sun::star::uno::Any& Value) throw(::com::sun::star::uno::RuntimeException)
{
	::vos::OGuard aGuard( GetMutex() );

	if ( GetWindow() )
	{
		sal_Bool bVoid = Value.getValueType().getTypeClass() == ::com::sun::star::uno::TypeClass_VOID;

		sal_uInt16 nPropType = GetPropertyId( PropertyName );
		switch ( nPropType )
		{
			case BASEPROPERTY_VALUE_DOUBLE:
			{
				if ( bVoid )
				{
					((LongCurrencyField*)GetWindow())->EnableEmptyFieldValue( sal_True );
					((LongCurrencyField*)GetWindow())->SetEmptyFieldValue();
				}
				else
				{
					double d = 0;
					if ( Value >>= d )
 						setValue( d );
				}
			}
			break;
			case BASEPROPERTY_VALUEMIN_DOUBLE:
			{
				double d = 0;
				if ( Value >>= d )
 					setMin( d );
			}
			break;
			case BASEPROPERTY_VALUEMAX_DOUBLE:
			{
				double d = 0;
				if ( Value >>= d )
 					setMax( d );
			}
			break;
			case BASEPROPERTY_VALUESTEP_DOUBLE:
			{
				double d = 0;
				if ( Value >>= d )
 					setSpinSize( d );
			}
			break;
			case BASEPROPERTY_DECIMALACCURACY:
			{
				sal_Int16 n = sal_Int16();
				if ( Value >>= n )
 					setDecimalDigits( n );
			}
			break;
			case BASEPROPERTY_CURRENCYSYMBOL:
			{
				::rtl::OUString aString;
				if ( Value >>= aString )
 					((LongCurrencyField*)GetWindow())->SetCurrencySymbol( aString );
			}
			break;
			case BASEPROPERTY_NUMSHOWTHOUSANDSEP:
			{
				sal_Bool b = sal_Bool();
				if ( Value >>= b )
 					((LongCurrencyField*)GetWindow())->SetUseThousandSep( b );
			}
			break;
			default:
			{
				VCLXFormattedSpinField::setProperty( PropertyName, Value );
			}
		}
	}
}

::com::sun::star::uno::Any VCLXCurrencyField::getProperty( const ::rtl::OUString& PropertyName ) throw(::com::sun::star::uno::RuntimeException)
{
	::vos::OGuard aGuard( GetMutex() );

	::com::sun::star::uno::Any aProp;
	FormatterBase* pFormatter = GetFormatter();
	if ( pFormatter )
	{
		sal_uInt16 nPropType = GetPropertyId( PropertyName );
		switch ( nPropType )
		{
			case BASEPROPERTY_VALUE_DOUBLE:
			{
				aProp <<= (double) getValue();
			}
			break;
			case BASEPROPERTY_VALUEMIN_DOUBLE:
			{
				aProp <<= (double) getMin();
			}
			break;
			case BASEPROPERTY_VALUEMAX_DOUBLE:
			{
				aProp <<= (double) getMax();
			}
			break;
			case BASEPROPERTY_VALUESTEP_DOUBLE:
			{
				aProp <<= (double) getSpinSize();
			}
			break;
			case BASEPROPERTY_CURRENCYSYMBOL:
			{
			    aProp <<= ::rtl::OUString( ((LongCurrencyField*)GetWindow())->GetCurrencySymbol() );
			}
			break;
			case BASEPROPERTY_NUMSHOWTHOUSANDSEP:
			{
			    aProp <<= (sal_Bool) ((LongCurrencyField*)GetWindow())->IsUseThousandSep();
			}
			break;
			default:
			{
				aProp <<= VCLXFormattedSpinField::getProperty( PropertyName );
			}
		}
	}
	return aProp;
}

//	----------------------------------------------------
//	class VCLXPatternField
//	----------------------------------------------------

void VCLXPatternField::ImplGetPropertyIds( std::list< sal_uInt16 > &rIds )
{
    PushPropertyIds( rIds,
                     BASEPROPERTY_ALIGN,
                     BASEPROPERTY_BACKGROUNDCOLOR,
                     BASEPROPERTY_BORDER,
                     BASEPROPERTY_BORDERCOLOR,
                     BASEPROPERTY_DEFAULTCONTROL,
                     BASEPROPERTY_EDITMASK,
                     BASEPROPERTY_ENABLED,
                     BASEPROPERTY_ENABLEVISIBLE,
                     BASEPROPERTY_FONTDESCRIPTOR,
                     BASEPROPERTY_HELPTEXT,
                     BASEPROPERTY_HELPURL,
                     BASEPROPERTY_LITERALMASK,
                     BASEPROPERTY_MAXTEXTLEN,
                     BASEPROPERTY_PRINTABLE,
                     BASEPROPERTY_READONLY,
                     BASEPROPERTY_STRICTFORMAT,
                     BASEPROPERTY_TABSTOP,
                     BASEPROPERTY_TEXT,
                     BASEPROPERTY_HIDEINACTIVESELECTION,
                     BASEPROPERTY_VERTICALALIGN,
                     BASEPROPERTY_WRITING_MODE,
                     BASEPROPERTY_CONTEXT_WRITING_MODE,
                     BASEPROPERTY_MOUSE_WHEEL_BEHAVIOUR,
                     0);
    VCLXFormattedSpinField::ImplGetPropertyIds( rIds );
}

VCLXPatternField::VCLXPatternField()
{
}

VCLXPatternField::~VCLXPatternField()
{
}

// ::com::sun::star::uno::XInterface
::com::sun::star::uno::Any VCLXPatternField::queryInterface( const ::com::sun::star::uno::Type & rType ) throw(::com::sun::star::uno::RuntimeException)
{
	::com::sun::star::uno::Any aRet = ::cppu::queryInterface( rType,
										SAL_STATIC_CAST( ::com::sun::star::awt::XPatternField*, this ) );
	return (aRet.hasValue() ? aRet : VCLXFormattedSpinField::queryInterface( rType ));
}

// ::com::sun::star::lang::XTypeProvider
IMPL_XTYPEPROVIDER_START( VCLXPatternField )
	getCppuType( ( ::com::sun::star::uno::Reference< ::com::sun::star::awt::XPatternField>* ) NULL ),
	VCLXFormattedSpinField::getTypes()
IMPL_XTYPEPROVIDER_END

void VCLXPatternField::setMasks( const ::rtl::OUString& EditMask, const ::rtl::OUString& LiteralMask ) throw(::com::sun::star::uno::RuntimeException)
{
	::vos::OGuard aGuard( GetMutex() );

	PatternField* pPatternField = (PatternField*) GetWindow();
	if ( pPatternField )
	{
		pPatternField->SetMask(	ByteString( UniString( EditMask ), RTL_TEXTENCODING_ASCII_US ), LiteralMask );
	}
}

void VCLXPatternField::getMasks( ::rtl::OUString& EditMask, ::rtl::OUString& LiteralMask ) throw(::com::sun::star::uno::RuntimeException)
{
	::vos::OGuard aGuard( GetMutex() );

	PatternField* pPatternField = (PatternField*) GetWindow();
	if ( pPatternField )
	{
		EditMask = String( pPatternField->GetEditMask(), RTL_TEXTENCODING_ASCII_US );
		LiteralMask = pPatternField->GetLiteralMask();
	}
}

void VCLXPatternField::setString( const ::rtl::OUString& Str ) throw(::com::sun::star::uno::RuntimeException)
{
	::vos::OGuard aGuard( GetMutex() );

	PatternField* pPatternField = (PatternField*) GetWindow();
	if ( pPatternField )
	{
		pPatternField->SetString( Str );
	}
}

::rtl::OUString VCLXPatternField::getString() throw(::com::sun::star::uno::RuntimeException)
{
	::vos::OGuard aGuard( GetMutex() );

	::rtl::OUString aString;
	PatternField* pPatternField = (PatternField*) GetWindow();
	if ( pPatternField )
		aString = pPatternField->GetString();
	return aString;
}

void VCLXPatternField::setStrictFormat( sal_Bool bStrict ) throw(::com::sun::star::uno::RuntimeException)
{
	VCLXFormattedSpinField::setStrictFormat( bStrict );
}

sal_Bool VCLXPatternField::isStrictFormat() throw(::com::sun::star::uno::RuntimeException)
{
	return VCLXFormattedSpinField::isStrictFormat();
}

void VCLXPatternField::setProperty( const ::rtl::OUString& PropertyName, const ::com::sun::star::uno::Any& Value) throw(::com::sun::star::uno::RuntimeException)
{
	::vos::OGuard aGuard( GetMutex() );

	if ( GetWindow() )
	{
		sal_uInt16 nPropType = GetPropertyId( PropertyName );
		switch ( nPropType )
		{
			case BASEPROPERTY_EDITMASK:
			case BASEPROPERTY_LITERALMASK:
			{
				::rtl::OUString aString;
				if ( Value >>= aString )
				{
					::rtl::OUString aEditMask, aLiteralMask;
					getMasks( aEditMask, aLiteralMask );
					if ( nPropType == BASEPROPERTY_EDITMASK )
						aEditMask = aString;
					else
						aLiteralMask = aString;
 					setMasks( aEditMask, aLiteralMask );
				}
			}
			break;
			default:
			{
				VCLXFormattedSpinField::setProperty( PropertyName, Value );
			}
		}
	}
}

::com::sun::star::uno::Any VCLXPatternField::getProperty( const ::rtl::OUString& PropertyName ) throw(::com::sun::star::uno::RuntimeException)
{
	::vos::OGuard aGuard( GetMutex() );

	::com::sun::star::uno::Any aProp;
	if ( GetWindow() )
	{
		sal_uInt16 nPropType = GetPropertyId( PropertyName );
		switch ( nPropType )
		{
			case BASEPROPERTY_EDITMASK:
			case BASEPROPERTY_LITERALMASK:
			{
				::rtl::OUString aEditMask, aLiteralMask;
				getMasks( aEditMask, aLiteralMask );
				if ( nPropType == BASEPROPERTY_EDITMASK )
					aProp <<= aEditMask;
				else
					aProp <<= aLiteralMask;
			}
			break;
			default:
			{
				aProp <<= VCLXFormattedSpinField::getProperty( PropertyName );
			}
		}
	}
	return aProp;
}

//	----------------------------------------------------
//	class VCLXToolBox
//	----------------------------------------------------
VCLXToolBox::VCLXToolBox()
{
}

VCLXToolBox::~VCLXToolBox()
{
}

::com::sun::star::uno::Reference< ::com::sun::star::accessibility::XAccessibleContext > VCLXToolBox::CreateAccessibleContext()
{
    return getAccessibleFactory().createAccessibleContext( this );
}
