/**************************************************************
 *
 * 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_forms.hxx"

#include "Button.hxx"

#include <com/sun/star/awt/XVclWindowPeer.hpp>

#include <comphelper/streamsection.hxx>
#include <comphelper/basicio.hxx>
#include <tools/diagnose_ex.h>
#include <tools/debug.hxx>
#include <tools/urlobj.hxx>
#include <vcl/svapp.hxx>
#include <vos/mutex.hxx>

//.........................................................................
namespace frm
{
//.........................................................................

using namespace ::com::sun::star::uno;
using namespace ::com::sun::star::sdb;
using namespace ::com::sun::star::sdbc;
using namespace ::com::sun::star::sdbcx;
using namespace ::com::sun::star::beans;
using namespace ::com::sun::star::container;
using namespace ::com::sun::star::form;
using namespace ::com::sun::star::awt;
using namespace ::com::sun::star::io;
using namespace ::com::sun::star::lang;
using namespace ::com::sun::star::util;
using ::com::sun::star::frame::XDispatchProviderInterceptor;

//==================================================================
//= OButtonModel
//==================================================================
DBG_NAME(OButtonModel)
//------------------------------------------------------------------
InterfaceRef SAL_CALL OButtonModel_CreateInstance(const Reference<XMultiServiceFactory>& _rxFactory)
{
	return *(new OButtonModel(_rxFactory));
}

//------------------------------------------------------------------
OButtonModel::OButtonModel(const Reference<XMultiServiceFactory>& _rxFactory)
    :OClickableImageBaseModel( _rxFactory, VCL_CONTROLMODEL_COMMANDBUTTON, FRM_SUN_CONTROL_COMMANDBUTTON )
									// use the old control name for compatibility reasons
    ,m_aResetHelper( *this, m_aMutex )
    ,m_eDefaultState( STATE_NOCHECK )
{
	DBG_CTOR( OButtonModel, NULL );
	m_nClassId = FormComponentType::COMMANDBUTTON;
}

//------------------------------------------------------------------
Any SAL_CALL OButtonModel::queryAggregation( const Type& _type ) throw(RuntimeException)
{
    Any aReturn = OClickableImageBaseModel::queryAggregation( _type );
    if ( !aReturn.hasValue() )
        aReturn = OButtonModel_Base::queryInterface( _type );
    return aReturn;
}

//------------------------------------------------------------------
Sequence< Type > OButtonModel::_getTypes()
{
    return ::comphelper::concatSequences(
        OClickableImageBaseModel::_getTypes(),
        OButtonModel_Base::getTypes()
    );
}

//------------------------------------------------------------------
OButtonModel::OButtonModel( const OButtonModel* _pOriginal, const Reference<XMultiServiceFactory>& _rxFactory )
	:OClickableImageBaseModel( _pOriginal, _rxFactory )
    ,m_aResetHelper( *this, m_aMutex )
    ,m_eDefaultState( _pOriginal->m_eDefaultState )
{
	DBG_CTOR( OButtonModel, NULL );
	m_nClassId = FormComponentType::COMMANDBUTTON;

    implInitializeImageURL();
}

//------------------------------------------------------------------------------
OButtonModel::~OButtonModel()
{
	DBG_DTOR(OButtonModel, NULL);
}

//------------------------------------------------------------------------------
void OButtonModel::describeFixedProperties( Sequence< Property >& _rProps ) const
{
    BEGIN_DESCRIBE_PROPERTIES( 6, OClickableImageBaseModel )
        DECL_PROP1( BUTTONTYPE,		        FormButtonType,				BOUND );
        DECL_PROP1( DEFAULT_STATE,          sal_Int16,                  BOUND );
        DECL_PROP1( DISPATCHURLINTERNAL,	sal_Bool,				    BOUND );
        DECL_PROP1( TARGET_URL,		        ::rtl::OUString,			BOUND );
        DECL_PROP1( TARGET_FRAME,	        ::rtl::OUString,			BOUND );
        DECL_PROP1( TABINDEX,		        sal_Int16,					BOUND );
    END_DESCRIBE_PROPERTIES();
}

//------------------------------------------------------------------------------
IMPLEMENT_DEFAULT_CLONING( OButtonModel )

// XServiceInfo
//------------------------------------------------------------------------------
StringSequence	OButtonModel::getSupportedServiceNames() throw()
{
	StringSequence aSupported = OClickableImageBaseModel::getSupportedServiceNames();
	aSupported.realloc( aSupported.getLength() + 1 );

	::rtl::OUString* pArray = aSupported.getArray();
	pArray[ aSupported.getLength() - 1 ] = FRM_SUN_COMPONENT_COMMANDBUTTON;

    return aSupported;
}

//------------------------------------------------------------------------------
::rtl::OUString OButtonModel::getServiceName() throw ( ::com::sun::star::uno::RuntimeException)
{
	return FRM_COMPONENT_COMMANDBUTTON;	// old (non-sun) name for compatibility !
}

//------------------------------------------------------------------------------
void OButtonModel::write(const Reference<XObjectOutputStream>& _rxOutStream) throw (::com::sun::star::io::IOException, ::com::sun::star::uno::RuntimeException)
{
	OClickableImageBaseModel::write(_rxOutStream);

	_rxOutStream->writeShort(0x0003); 	// Version

	{
		OStreamSection aSection( _rxOutStream.get() );
			// this will allow readers to skip unknown bytes in their dtor

		_rxOutStream->writeShort( (sal_uInt16)m_eButtonType );

		::rtl::OUString sTmp = INetURLObject::decode( m_sTargetURL, '%', INetURLObject::DECODE_UNAMBIGUOUS);
		_rxOutStream << sTmp;
		_rxOutStream << m_sTargetFrame;
		writeHelpTextCompatibly(_rxOutStream);
		_rxOutStream << isDispatchUrlInternal();
	}
}

//------------------------------------------------------------------------------
void OButtonModel::read(const Reference<XObjectInputStream>& _rxInStream) throw (::com::sun::star::io::IOException, ::com::sun::star::uno::RuntimeException)
{
	OClickableImageBaseModel::read(_rxInStream);

	sal_uInt16 nVersion = _rxInStream->readShort(); 	// Version
	switch (nVersion)
	{
		case 0x0001:
		{
			m_eButtonType = (FormButtonType)_rxInStream->readShort();

			_rxInStream >> m_sTargetURL;
			_rxInStream >> m_sTargetFrame;
		}
		break;

		case 0x0002:
		{
			m_eButtonType = (FormButtonType)_rxInStream->readShort();

			_rxInStream >> m_sTargetURL;
			_rxInStream >> m_sTargetFrame;
			readHelpTextCompatibly(_rxInStream);
		}
		break;

		case 0x0003:
		{
			OStreamSection aSection( _rxInStream.get() );
				// this will skip any unknown bytes in it's dtor

			// button type
			m_eButtonType = (FormButtonType)_rxInStream->readShort();

			// URL
			_rxInStream >> m_sTargetURL;

			// target frame
			_rxInStream >> m_sTargetFrame;

			// help text
			readHelpTextCompatibly(_rxInStream);

			// DispatchInternal
			sal_Bool bDispath;
			_rxInStream >> bDispath;
			setDispatchUrlInternal(bDispath);
		}
		break;

		default:
			DBG_ERROR("OButtonModel::read : unknown version !");
			m_eButtonType = FormButtonType_PUSH;
			m_sTargetURL = ::rtl::OUString();
			m_sTargetFrame = ::rtl::OUString();
			break;
	}
}

//--------------------------------------------------------------------
void SAL_CALL OButtonModel::disposing()
{
    m_aResetHelper.disposing();
    OClickableImageBaseModel::disposing();
}

//--------------------------------------------------------------------
void SAL_CALL OButtonModel::reset() throw (RuntimeException)
{
    if ( !m_aResetHelper.approveReset() )
        return;

    impl_resetNoBroadcast_nothrow();

    m_aResetHelper.notifyResetted();
}

//--------------------------------------------------------------------
void SAL_CALL OButtonModel::addResetListener( const Reference< XResetListener >& _listener ) throw (RuntimeException)
{
    m_aResetHelper.addResetListener( _listener );
}

//--------------------------------------------------------------------
void SAL_CALL OButtonModel::removeResetListener( const Reference< XResetListener >& _listener ) throw (RuntimeException)
{
    m_aResetHelper.removeResetListener( _listener );
}

//--------------------------------------------------------------------
void SAL_CALL OButtonModel::getFastPropertyValue( Any& _rValue, sal_Int32 _nHandle ) const
{
    switch ( _nHandle )
    {
    case PROPERTY_ID_DEFAULT_STATE:
        _rValue <<= (sal_Int16)m_eDefaultState;
        break;

    default:
        OClickableImageBaseModel::getFastPropertyValue( _rValue, _nHandle );
        break;
    }
}

//--------------------------------------------------------------------
void SAL_CALL OButtonModel::setFastPropertyValue_NoBroadcast( sal_Int32 _nHandle, const Any& _rValue ) throw (Exception)
{
    switch ( _nHandle )
    {
    case PROPERTY_ID_DEFAULT_STATE:
    {
        sal_Int16 nDefaultState( (sal_Int16)STATE_NOCHECK );
        OSL_VERIFY( _rValue >>= nDefaultState );
        m_eDefaultState = (ToggleState)nDefaultState;
        impl_resetNoBroadcast_nothrow();
    }
    break;

    default:
        OClickableImageBaseModel::setFastPropertyValue_NoBroadcast( _nHandle, _rValue );
        break;
    }
}

//--------------------------------------------------------------------
sal_Bool SAL_CALL OButtonModel::convertFastPropertyValue( Any& _rConvertedValue, Any& _rOldValue, sal_Int32 _nHandle, const Any& _rValue ) throw (IllegalArgumentException)
{
    sal_Bool bModified = sal_False;
    switch ( _nHandle )
    {
    case PROPERTY_ID_DEFAULT_STATE:
        bModified = tryPropertyValue( _rConvertedValue, _rOldValue, _rValue, (sal_Int16)m_eDefaultState );
        break;

    default:
        bModified = OClickableImageBaseModel::convertFastPropertyValue( _rConvertedValue, _rOldValue, _nHandle, _rValue );
        break;
    }
    return bModified;
}

//--------------------------------------------------------------------
Any OButtonModel::getPropertyDefaultByHandle( sal_Int32 _nHandle ) const
{
    Any aDefault;
    switch ( _nHandle )
    {
    case PROPERTY_ID_DEFAULT_STATE:
        aDefault <<= (sal_Int16)STATE_NOCHECK;
        break;

    default:
        aDefault = OClickableImageBaseModel::getPropertyDefaultByHandle( _nHandle );
        break;
    }
    return aDefault;
}

//--------------------------------------------------------------------
void OButtonModel::impl_resetNoBroadcast_nothrow()
{
    try
    {
        setPropertyValue( PROPERTY_STATE, getPropertyValue( PROPERTY_DEFAULT_STATE ) );
    }
    catch( const Exception& )
    {
    	DBG_UNHANDLED_EXCEPTION();
    }
}

//==================================================================
// OButtonControl
//==================================================================
//------------------------------------------------------------------
InterfaceRef SAL_CALL OButtonControl_CreateInstance(const Reference<XMultiServiceFactory>& _rxFactory)
{
	return *(new OButtonControl(_rxFactory));
}

//------------------------------------------------------------------------------
Sequence<Type> OButtonControl::_getTypes()
{
	return ::comphelper::concatSequences(
		OButtonControl_BASE::getTypes(),
        OClickableImageBaseControl::_getTypes(),
        OFormNavigationHelper::getTypes()
	);
}

//------------------------------------------------------------------------------
StringSequence	OButtonControl::getSupportedServiceNames() throw()
{
	StringSequence aSupported = OClickableImageBaseControl::getSupportedServiceNames();
	aSupported.realloc(aSupported.getLength() + 1);

	::rtl::OUString*pArray = aSupported.getArray();
	pArray[aSupported.getLength()-1] = FRM_SUN_CONTROL_COMMANDBUTTON;
	return aSupported;
}

//------------------------------------------------------------------------------
OButtonControl::OButtonControl(const Reference<XMultiServiceFactory>& _rxFactory)
				 :OClickableImageBaseControl(_rxFactory, VCL_CONTROL_COMMANDBUTTON)
                 ,OFormNavigationHelper( _rxFactory )
				 ,m_nClickEvent( 0 )
                 ,m_nTargetUrlFeatureId( -1 )
                 ,m_bEnabledByPropertyValue( sal_False )
{
	increment(m_refCount);
	{
		// als ActionListener anmelden
		Reference<XButton>  xButton;
		query_aggregation( m_xAggregate, xButton);
		if (xButton.is())
			xButton->addActionListener(this);
	}
	// Refcount bei 1 fuer Listener
	decrement(m_refCount);
}

//------------------------------------------------------------------------------
OButtonControl::~OButtonControl()
{
	if (m_nClickEvent)
		Application::RemoveUserEvent(m_nClickEvent);
}

// UNO Anbindung
//------------------------------------------------------------------------------
Any SAL_CALL OButtonControl::queryAggregation(const Type& _rType) throw (RuntimeException)
{
	// if asked for the XTypeProvider, don't let OButtonControl_BASE do this
	Any aReturn;
	if ( !_rType.equals( ::getCppuType( static_cast< Reference< XTypeProvider >* >( NULL ) ) ) )
		aReturn = OButtonControl_BASE::queryInterface( _rType );

	if ( !aReturn.hasValue() )
		aReturn = OClickableImageBaseControl::queryAggregation( _rType );

    if ( !aReturn.hasValue() )
		aReturn = OFormNavigationHelper::queryInterface( _rType );

	return aReturn;
}

//------------------------------------------------------------------------------
void SAL_CALL OButtonControl::disposing()
{
    startOrStopModelPropertyListening( false );

    OClickableImageBaseControl::disposing();
    OFormNavigationHelper::dispose();
}

//------------------------------------------------------------------------------
void SAL_CALL OButtonControl::disposing( const EventObject& _rSource ) throw( RuntimeException )
{
    OControl::disposing( _rSource );
    OFormNavigationHelper::disposing( _rSource );
}

// ActionListener
//------------------------------------------------------------------------------
void OButtonControl::actionPerformed(const ActionEvent& /*rEvent*/) throw ( ::com::sun::star::uno::RuntimeException)
{
	// Asynchron fuer starutil::URL-Button
	sal_uLong n = Application::PostUserEvent( LINK(this, OButtonControl,OnClick) );
	{
		::osl::MutexGuard aGuard( m_aMutex );
		m_nClickEvent = n;
	}
}

//------------------------------------------------------------------------------
IMPL_LINK( OButtonControl, OnClick, void*, EMPTYARG )
{
	::osl::ClearableMutexGuard aGuard( m_aMutex );
	m_nClickEvent = 0;

	if (m_aApproveActionListeners.getLength())
	{
		// if there are listeners, start the action in an own thread, to not allow
        // them to block us here (we're in the application's main thread)
        getImageProducerThread()->addEvent();
	}
	else
	{
		// Sonst nicht. Dann darf man aber auf keinen Fal die Listener
		// benachrichtigen, auch dann nicht, wenn er spaeter hinzukommt.
		aGuard.clear();

		// recognize the button type
		Reference<XPropertySet>  xSet(getModel(), UNO_QUERY);
		if (!xSet.is())
			return 0L;

		if (FormButtonType_PUSH == *(FormButtonType*)xSet->getPropertyValue(PROPERTY_BUTTONTYPE).getValue())
		{
			// notify the action listeners for a push button
			::cppu::OInterfaceIteratorHelper aIter(m_aActionListeners);
			ActionEvent aEvt(static_cast<XWeak*>(this), m_aActionCommand);
			while(aIter.hasMoreElements() )
			{
				// catch exceptions
				// and catch them on a per-listener basis - if one listener fails, the others still need
				// to get notified
				// 97676 - 21.02.2002 - fs@openoffice.org
				try
				{
					static_cast< XActionListener* >( aIter.next() )->actionPerformed(aEvt);
				}
#ifdef DBG_UTIL
				catch( const RuntimeException& )
				{
					// silent this
				}
#endif
				catch( const Exception& )
				{
					DBG_ERROR( "OButtonControl::OnClick: caught a exception other than RuntimeException!" );
				}
			}
		}
		else
			actionPerformed_Impl( sal_False, ::com::sun::star::awt::MouseEvent() );
	}
	return 0L;
}

//------------------------------------------------------------------------------
void OButtonControl::actionPerformed_Impl( sal_Bool _bNotifyListener, const ::com::sun::star::awt::MouseEvent& _rEvt )
{
    {
        sal_Int16 nFeatureId = -1;
        {
            ::osl::MutexGuard aGuard( m_aMutex );
            nFeatureId = m_nTargetUrlFeatureId;
        }

        if ( nFeatureId != -1 )
        {
            if ( !approveAction() )
                return;

            ::vos::OGuard aGuard( Application::GetSolarMutex() );
            dispatch( nFeatureId );
            return;
        }
    }

    OClickableImageBaseControl::actionPerformed_Impl( _bNotifyListener, _rEvt );
}

// XButton
//------------------------------------------------------------------------------
void OButtonControl::setLabel(const ::rtl::OUString& Label) throw( RuntimeException )
{
	Reference<XButton>  xButton;
	query_aggregation( m_xAggregate, xButton );
	if (xButton.is())
		xButton->setLabel(Label);
}

//------------------------------------------------------------------------------
void SAL_CALL OButtonControl::setActionCommand(const ::rtl::OUString& _rCommand) throw( RuntimeException )
{
	{
		::osl::MutexGuard aGuard( m_aMutex );
		m_aActionCommand = _rCommand;
	}

	Reference<XButton>  xButton;
	query_aggregation( m_xAggregate, xButton);
	if (xButton.is())
		xButton->setActionCommand(_rCommand);
}

//------------------------------------------------------------------------------
void SAL_CALL OButtonControl::addActionListener(const Reference<XActionListener>& _rxListener) throw( RuntimeException )
{
	m_aActionListeners.addInterface(_rxListener);
}

//------------------------------------------------------------------------------
void SAL_CALL OButtonControl::removeActionListener(const Reference<XActionListener>& _rxListener) throw( RuntimeException )
{
	m_aActionListeners.removeInterface(_rxListener);
}

//------------------------------------------------------------------------------
class DoPropertyListening
{
private:
    Reference< XPropertySet >               m_xProps;
    Reference< XPropertyChangeListener >    m_xListener;
    bool                                    m_bStartListening;

public:
    DoPropertyListening(
        const Reference< XInterface >& _rxComponent,
        const Reference< XPropertyChangeListener >& _rxListener,
        bool _bStart
    );

    void    handleListening( const ::rtl::OUString& _rPropertyName );
};

//..............................................................................
DoPropertyListening::DoPropertyListening(
        const Reference< XInterface >& _rxComponent, const Reference< XPropertyChangeListener >& _rxListener,
        bool _bStart )
    :m_xProps( _rxComponent, UNO_QUERY )
    ,m_xListener( _rxListener )
    ,m_bStartListening( _bStart )
{
    DBG_ASSERT( m_xProps.is() || !_rxComponent.is(), "DoPropertyListening::DoPropertyListening: valid component, but no property set!" );
    DBG_ASSERT( m_xListener.is(), "DoPropertyListening::DoPropertyListening: invalid listener!" );
}

//..............................................................................
void DoPropertyListening::handleListening( const ::rtl::OUString& _rPropertyName )
{
    if ( m_xProps.is() )
    {
        if ( m_bStartListening )
            m_xProps->addPropertyChangeListener( _rPropertyName, m_xListener );
        else
            m_xProps->removePropertyChangeListener( _rPropertyName, m_xListener );
    }
}

//------------------------------------------------------------------------------
void OButtonControl::startOrStopModelPropertyListening( bool _bStart )
{
    DoPropertyListening aListeningHandler( getModel(), this, _bStart );
    aListeningHandler.handleListening( PROPERTY_TARGET_URL );
    aListeningHandler.handleListening( PROPERTY_BUTTONTYPE );
    aListeningHandler.handleListening( PROPERTY_ENABLED );
}

//------------------------------------------------------------------------------
sal_Bool SAL_CALL OButtonControl::setModel( const Reference< XControlModel >& _rxModel ) throw ( RuntimeException )
{
    startOrStopModelPropertyListening( false );
    sal_Bool bResult = OClickableImageBaseControl::setModel( _rxModel );
    startOrStopModelPropertyListening( true );

    m_bEnabledByPropertyValue = sal_True;
    Reference< XPropertySet > xModelProps( _rxModel, UNO_QUERY );
    if ( xModelProps.is() )
        xModelProps->getPropertyValue( PROPERTY_ENABLED ) >>= m_bEnabledByPropertyValue;

    modelFeatureUrlPotentiallyChanged( );

    return bResult;
}

//------------------------------------------------------------------------------
void OButtonControl::modelFeatureUrlPotentiallyChanged( )
{
    sal_Int16 nOldUrlFeatureId = m_nTargetUrlFeatureId;

    // doe we have another TargetURL now? If so, we need to update our dispatches
    m_nTargetUrlFeatureId = getModelUrlFeatureId( );
    if ( nOldUrlFeatureId != m_nTargetUrlFeatureId )
    {
        invalidateSupportedFeaturesSet();
        if ( !isDesignMode() )
            updateDispatches( );
    }
}

//------------------------------------------------------------------------------
void SAL_CALL OButtonControl::propertyChange( const PropertyChangeEvent& _rEvent ) throw ( RuntimeException )
{
	if  (   _rEvent.PropertyName.equals( PROPERTY_TARGET_URL )
        ||  _rEvent.PropertyName.equals( PROPERTY_BUTTONTYPE )
        )
    {
        modelFeatureUrlPotentiallyChanged( );
    }
    else if ( _rEvent.PropertyName.equals( PROPERTY_ENABLED ) )
    {
        _rEvent.NewValue >>= m_bEnabledByPropertyValue;
    }
}

//------------------------------------------------------------------------------
namespace
{
    bool isFormControllerURL( const ::rtl::OUString& _rURL )
    {
        const sal_Int32 nPrefixLen = URL_CONTROLLER_PREFIX.length;
        return  ( _rURL.getLength() > nPrefixLen )
            &&  ( _rURL.compareToAscii( URL_CONTROLLER_PREFIX, nPrefixLen ) == 0 );
    }
}

//------------------------------------------------------------------------------
sal_Int16 OButtonControl::getModelUrlFeatureId( ) const
{
    sal_Int16 nFeatureId = -1;

    // some URL related properties of the model
    ::rtl::OUString sUrl;
    FormButtonType eButtonType = FormButtonType_PUSH;

    Reference< XPropertySet > xModelProps( const_cast< OButtonControl* >( this )->getModel(), UNO_QUERY );
    if ( xModelProps.is() )
    {
        xModelProps->getPropertyValue( PROPERTY_TARGET_URL ) >>= sUrl;
        xModelProps->getPropertyValue( PROPERTY_BUTTONTYPE ) >>= eButtonType;
    }

    // are we an URL button?
    if ( eButtonType == FormButtonType_URL )
    {
        // is it a feature URL?
        if ( isFormControllerURL( sUrl ) )
        {
            OFormNavigationMapper aMapper( m_aContext.getLegacyServiceFactory() );
            nFeatureId = aMapper.getFeatureId( sUrl );
        }
    }

    return nFeatureId;
}

//------------------------------------------------------------------
void SAL_CALL OButtonControl::setDesignMode( sal_Bool _bOn ) throw( RuntimeException )
{
    OClickableImageBaseControl::setDesignMode( _bOn  );

    if ( _bOn )
		disconnectDispatchers();
	else
		connectDispatchers();
        // this will connect if not already connected and just update else
}

//------------------------------------------------------------------------------
void OButtonControl::getSupportedFeatures( ::std::vector< sal_Int16 >& /* [out] */ _rFeatureIds )
{
    if ( -1 != m_nTargetUrlFeatureId )
        _rFeatureIds.push_back( m_nTargetUrlFeatureId );
}

//------------------------------------------------------------------
void OButtonControl::featureStateChanged( sal_Int16 _nFeatureId, sal_Bool _bEnabled )
{
    if ( _nFeatureId == m_nTargetUrlFeatureId )
    {
        // enable or disable our peer, according to the new state
        Reference< XVclWindowPeer > xPeer( getPeer(), UNO_QUERY );
        if ( xPeer.is() )
            xPeer->setProperty( PROPERTY_ENABLED, makeAny( m_bEnabledByPropertyValue ? _bEnabled : sal_False ) );
            // if we're disabled according to our model's property, then
            // we don't care for the feature state, but *are* disabled.
            // If the model's property states that we're enabled, then we *do*
            // care for the feature state
    }

    // base class
    OFormNavigationHelper::featureStateChanged( _nFeatureId, _bEnabled );
}

//------------------------------------------------------------------
void OButtonControl::allFeatureStatesChanged( )
{
    if ( -1 != m_nTargetUrlFeatureId )
        // we have only one supported feature, so simulate it has changed ...
        featureStateChanged( m_nTargetUrlFeatureId, isEnabled( m_nTargetUrlFeatureId ) );

    // base class
    OFormNavigationHelper::allFeatureStatesChanged( );
}

//------------------------------------------------------------------
bool OButtonControl::isEnabled( sal_Int16 _nFeatureId ) const
{
    if ( const_cast< OButtonControl* >( this )->isDesignMode() )
        // TODO: the model property?
       return true;

    return OFormNavigationHelper::isEnabled( _nFeatureId );
}

//--------------------------------------------------------------------
void SAL_CALL OButtonControl::registerDispatchProviderInterceptor( const Reference< XDispatchProviderInterceptor >& _rxInterceptor ) throw (RuntimeException)
{
    OClickableImageBaseControl::registerDispatchProviderInterceptor( _rxInterceptor );
    OFormNavigationHelper::registerDispatchProviderInterceptor( _rxInterceptor );
}

//--------------------------------------------------------------------
void SAL_CALL OButtonControl::releaseDispatchProviderInterceptor( const Reference< XDispatchProviderInterceptor >& _rxInterceptor ) throw (RuntimeException)
{
    OClickableImageBaseControl::releaseDispatchProviderInterceptor( _rxInterceptor );
    OFormNavigationHelper::releaseDispatchProviderInterceptor( _rxInterceptor );
}

//.........................................................................
}	// namespace frm
//.........................................................................
