/**************************************************************
 * 
 * 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 "componenttools.hxx"
#include "FormComponent.hxx"
#include "frm_resource.hrc"
#include "frm_resource.hxx"
#include "property.hrc"
#include "services.hxx"

/** === begin UNO includes === **/
#include <com/sun/star/awt/XTextComponent.hpp>
#include <com/sun/star/awt/XVclWindowPeer.hpp>
#include <com/sun/star/awt/XWindow.hpp>
#include <com/sun/star/form/XForm.hpp>
#include <com/sun/star/form/XLoadable.hpp>
#include <com/sun/star/io/XMarkableStream.hpp>
#include <com/sun/star/lang/DisposedException.hpp>
#include <com/sun/star/sdb/XRowSetChangeBroadcaster.hpp>
#include <com/sun/star/sdb/XRowSetSupplier.hpp>
#include <com/sun/star/sdbc/ColumnValue.hpp>
#include <com/sun/star/sdbc/DataType.hpp>
#include <com/sun/star/util/XModifyBroadcaster.hpp>
/** === end UNO includes === **/

#include <comphelper/basicio.hxx>
#include <comphelper/guarding.hxx>
#include <comphelper/listenernotification.hxx>
#include <comphelper/property.hxx>
#include <connectivity/dbtools.hxx>
#include <cppuhelper/queryinterface.hxx>
#include <rtl/logfile.hxx>
#include <toolkit/helper/emptyfontdescriptor.hxx>
#include <tools/debug.hxx>
#include <tools/diagnose_ex.h>

#include <functional>
#include <algorithm>

#include <functional>
#include <algorithm>


//... namespace frm .......................................................
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 namespace ::com::sun::star::form::binding;
    using namespace ::com::sun::star::form::validation;
    using namespace ::dbtools;
    using namespace ::comphelper;

    //=========================================================================
    //= FieldChangeNotifier
    //=========================================================================
    //-------------------------------------------------------------------------
    void ControlModelLock::impl_notifyAll_nothrow()
    {
        m_rModel.firePropertyChanges( m_aHandles, m_aOldValues, m_aNewValues, OControlModel::LockAccess() );
    }

    //-------------------------------------------------------------------------
    void ControlModelLock::addPropertyNotification( const sal_Int32 _nHandle, const Any& _rOldValue, const Any& _rNewValue )
    {
        sal_Int32 nOldLength = m_aHandles.getLength();
        if  (   ( nOldLength != m_aOldValues.getLength() )
            ||  ( nOldLength != m_aNewValues.getLength() )
            )
            throw RuntimeException( ::rtl::OUString(), m_rModel );

        m_aHandles.realloc( nOldLength + 1 );
        m_aHandles[ nOldLength ] = _nHandle;
        m_aOldValues.realloc( nOldLength + 1 );
        m_aOldValues[ nOldLength ] = _rOldValue;
        m_aNewValues.realloc( nOldLength + 1 );
        m_aNewValues[ nOldLength ] = _rNewValue;
    }

    //=========================================================================
    //= FieldChangeNotifier
    //=========================================================================
    //-------------------------------------------------------------------------
    class FieldChangeNotifier
    {
    public:
        FieldChangeNotifier( ControlModelLock& _rLock )
            :m_rLock( _rLock )
            ,m_rModel( dynamic_cast< OBoundControlModel& >( _rLock.getModel() ) )
        {
            m_xOldField = m_rModel.getField();
        }

        ~FieldChangeNotifier()
        {
            Reference< XPropertySet > xNewField( m_rModel.getField() );
            if ( m_xOldField != xNewField )
                m_rLock.addPropertyNotification( PROPERTY_ID_BOUNDFIELD, makeAny( m_xOldField ), makeAny( xNewField ) );
        }

    private:
        ControlModelLock&           m_rLock;
        OBoundControlModel&         m_rModel;
        Reference< XPropertySet >   m_xOldField;
    };

//=============================================================================
//= base class for form layer controls
//=============================================================================
DBG_NAME(frm_OControl)
//------------------------------------------------------------------------------
OControl::OControl( const Reference< XMultiServiceFactory >& _rxFactory, const rtl::OUString& _rAggregateService, const sal_Bool _bSetDelegator )
			:OComponentHelper(m_aMutex)
            ,m_aContext( _rxFactory )
{
	DBG_CTOR(frm_OControl, NULL);
	// VCL-Control aggregieren
	// bei Aggregation den Refcount um eins erhoehen da im setDelegator
	// das Aggregat selbst den Refcount erhoeht
	increment( m_refCount );
	{
		m_xAggregate = m_xAggregate.query( _rxFactory->createInstance( _rAggregateService ) );
		m_xControl = m_xControl.query( m_xAggregate );
	}
	decrement( m_refCount );

    if ( _bSetDelegator )
        doSetDelegator();
}

//------------------------------------------------------------------------------
OControl::~OControl()
{
	DBG_DTOR(frm_OControl, NULL);
    doResetDelegator();
}

//------------------------------------------------------------------------------
void OControl::doResetDelegator()
{
	if ( m_xAggregate.is() )
		m_xAggregate->setDelegator( NULL );
}

//------------------------------------------------------------------------------
void OControl::doSetDelegator()
{
	increment( m_refCount );
	if ( m_xAggregate.is() )
	{   // those brackets are important for some compilers, don't remove!
        // (they ensure that the temporary object created in the line below
        // is destroyed *before* the refcount-decrement)
		m_xAggregate->setDelegator( static_cast< XWeak* >( this ) );
	}
	decrement( m_refCount );
}

// UNO Anbindung
//------------------------------------------------------------------------------
Any SAL_CALL OControl::queryAggregation( const Type& _rType ) throw(RuntimeException)
{
	// ask the base class
	Any aReturn( OComponentHelper::queryAggregation(_rType) );
	// ask our own interfaces
	if (!aReturn.hasValue())
	{
		aReturn = OControl_BASE::queryInterface(_rType);
		// ask our aggregate
		if (!aReturn.hasValue() && m_xAggregate.is())
			aReturn = m_xAggregate->queryAggregation(_rType);
	}

	return aReturn;
}

//------------------------------------------------------------------------------
Sequence<sal_Int8> SAL_CALL OControl::getImplementationId() throw(RuntimeException)
{
	return OImplementationIds::getImplementationId(getTypes());
}

//------------------------------------------------------------------------------
Sequence<Type> SAL_CALL OControl::getTypes() throw(RuntimeException)
{
    TypeBag aTypes( _getTypes() );

    Reference< XTypeProvider > xProv;
	if ( query_aggregation( m_xAggregate, xProv ) )
        aTypes.addTypes( xProv->getTypes() );

    return aTypes.getTypes();
}

//------------------------------------------------------------------------------
Sequence<Type> OControl::_getTypes()
{
    return TypeBag( OComponentHelper::getTypes(), OControl_BASE::getTypes() ).getTypes();
}

//------------------------------------------------------------------------------
void OControl::initFormControlPeer( const Reference< XWindowPeer >& /*_rxPeer*/ )
{
    // nothing to do here
}

// OComponentHelper
//------------------------------------------------------------------------------
void OControl::disposing()
{
	OComponentHelper::disposing();

    m_aWindowStateGuard.attach( NULL, NULL );

    Reference< XComponent > xComp;
	if (query_aggregation(m_xAggregate, xComp))
		xComp->dispose();
}

// XServiceInfo
//------------------------------------------------------------------------------
sal_Bool SAL_CALL OControl::supportsService(const rtl::OUString& _rsServiceName) throw ( RuntimeException)
{
    Sequence<rtl::OUString> aSupported = getSupportedServiceNames();
	const rtl::OUString* pSupported = aSupported.getConstArray();
	for (sal_Int32 i=0; i<aSupported.getLength(); ++i, ++pSupported)
		if (pSupported->equals(_rsServiceName))
			return sal_True;
	return sal_False;
}

//------------------------------------------------------------------------------
Sequence< ::rtl::OUString > OControl::getAggregateServiceNames()
{
    Sequence< ::rtl::OUString > aAggServices;
    Reference< XServiceInfo > xInfo;
	if ( query_aggregation( m_xAggregate, xInfo ) )
		aAggServices = xInfo->getSupportedServiceNames();
    return aAggServices;
}

//------------------------------------------------------------------------------
Sequence<rtl::OUString> SAL_CALL OControl::getSupportedServiceNames() throw(RuntimeException)
{
    return ::comphelper::concatSequences(
        getAggregateServiceNames(),
        getSupportedServiceNames_Static()
   );
}

//------------------------------------------------------------------------------
Sequence< ::rtl::OUString > SAL_CALL OControl::getSupportedServiceNames_Static() throw( RuntimeException )
{
    // no own supported service names
    return Sequence< ::rtl::OUString >();
}

// XEventListener
//------------------------------------------------------------------------------
void SAL_CALL OControl::disposing(const com::sun::star::lang::EventObject& _rEvent) throw (RuntimeException)
{
	Reference< XInterface > xAggAsIface;
	query_aggregation(m_xAggregate, xAggAsIface);

	// does the disposing come from the aggregate ?
    if (xAggAsIface != Reference< XInterface >(_rEvent.Source, UNO_QUERY))
	{	// no -> forward it
                Reference<com::sun::star::lang::XEventListener> xListener;
		if (query_aggregation(m_xAggregate, xListener))
			xListener->disposing(_rEvent);
	}
}

// XControl
//------------------------------------------------------------------------------
void SAL_CALL OControl::setContext(const Reference< XInterface >& Context) throw (RuntimeException)
{
	if (m_xControl.is())
		m_xControl->setContext(Context);
}

//------------------------------------------------------------------------------
Reference< XInterface > SAL_CALL OControl::getContext() throw (RuntimeException)
{
	return m_xControl.is() ? m_xControl->getContext() : Reference< XInterface >();
}

//------------------------------------------------------------------------------
void OControl::impl_resetStateGuard_nothrow()
{
    Reference< XWindow2 > xWindow;
    Reference< XControlModel > xModel;
    try
    {
        xWindow.set( getPeer(), UNO_QUERY );
        xModel.set( getModel(), UNO_QUERY );
    }
    catch( const Exception& )
    {
    	DBG_UNHANDLED_EXCEPTION();
    }
    m_aWindowStateGuard.attach( xWindow, xModel );
}

//------------------------------------------------------------------------------
void SAL_CALL OControl::createPeer(const Reference<XToolkit>& _rxToolkit, const Reference<XWindowPeer>& _rxParent) throw (RuntimeException)
{
	if ( m_xControl.is() )
    {
		m_xControl->createPeer( _rxToolkit, _rxParent );

        initFormControlPeer( getPeer() );

        impl_resetStateGuard_nothrow();
    }
}

//------------------------------------------------------------------------------
Reference<XWindowPeer> SAL_CALL OControl::getPeer() throw ( RuntimeException)
{
    return m_xControl.is() ? m_xControl->getPeer() : Reference<XWindowPeer>();
}

//------------------------------------------------------------------------------
sal_Bool SAL_CALL OControl::setModel(const Reference<XControlModel>& Model) throw ( RuntimeException)
{
    if ( !m_xControl.is() )
        return sal_False;

    sal_Bool bSuccess = m_xControl->setModel( Model );
    impl_resetStateGuard_nothrow();
	return bSuccess;
}

//------------------------------------------------------------------------------
Reference<XControlModel> SAL_CALL OControl::getModel() throw ( RuntimeException)
{
    return m_xControl.is() ? m_xControl->getModel() : Reference<XControlModel>();
}

//------------------------------------------------------------------------------
Reference<XView> SAL_CALL OControl::getView() throw ( RuntimeException)
{
    return m_xControl.is() ? m_xControl->getView() : Reference<XView>();
}

//------------------------------------------------------------------------------
void SAL_CALL OControl::setDesignMode(sal_Bool bOn) throw ( RuntimeException)
{
	if (m_xControl.is())
		m_xControl->setDesignMode(bOn);
}

//------------------------------------------------------------------------------
sal_Bool SAL_CALL OControl::isDesignMode() throw ( RuntimeException)
{
	return m_xControl.is() ? m_xControl->isDesignMode() : sal_True;
}

//------------------------------------------------------------------------------
sal_Bool SAL_CALL OControl::isTransparent() throw ( RuntimeException)
{
	return m_xControl.is() ? m_xControl->isTransparent() : sal_True;
}

//==================================================================
//= OBoundControl
//==================================================================
DBG_NAME(frm_OBoundControl);
//------------------------------------------------------------------
OBoundControl::OBoundControl( const Reference< XMultiServiceFactory >& _rxFactory,
            const ::rtl::OUString& _rAggregateService, const sal_Bool _bSetDelegator )
    :OControl( _rxFactory, _rAggregateService, _bSetDelegator )
    ,m_bLocked(sal_False)
    ,m_aOriginalFont( EmptyFontDescriptor() )
    ,m_nOriginalTextLineColor( 0 )
{
	DBG_CTOR(frm_OBoundControl, NULL);
}

//------------------------------------------------------------------
OBoundControl::~OBoundControl()
{
	DBG_DTOR(frm_OBoundControl, NULL);
}
// -----------------------------------------------------------------------------
Sequence< Type>	OBoundControl::_getTypes()
{
    return TypeBag( OControl::_getTypes(), OBoundControl_BASE::getTypes() ).getTypes();
}
//------------------------------------------------------------------
Any SAL_CALL OBoundControl::queryAggregation(const Type& _rType) throw(RuntimeException)
{
    Any aReturn;

    // XTypeProvider first - don't ask the OBoundControl_BASE, it would deliver incomplete types
    if ( _rType.equals( ::getCppuType( static_cast< Reference< XTypeProvider >* >( NULL ) ) ) )
        aReturn = OControl::queryAggregation( _rType );

	// ask our own interfaces
    // (do this first (except XTypeProvider ) - we want to "overwrite" XPropertiesChangeListener)
    if ( !aReturn.hasValue() )
	    aReturn = OBoundControl_BASE::queryInterface( _rType );

    // ask the base class
	if ( !aReturn.hasValue() )
    	aReturn = OControl::queryAggregation( _rType );

	return aReturn;
}

//------------------------------------------------------------------
sal_Bool SAL_CALL OBoundControl::getLock() throw(RuntimeException)
{
	return m_bLocked;
}

//------------------------------------------------------------------
void SAL_CALL OBoundControl::setLock(sal_Bool _bLock) throw(RuntimeException)
{
	if (m_bLocked == _bLock)
		return;

	osl::MutexGuard aGuard(m_aMutex);
	_setLock(_bLock);
	m_bLocked = _bLock;
}

//------------------------------------------------------------------
void OBoundControl::_setLock(sal_Bool _bLock)
{
	// try to set the text component to readonly
    Reference< XWindowPeer > xPeer = getPeer();
    Reference< XTextComponent > xText( xPeer, UNO_QUERY );

	if ( xText.is() )
		xText->setEditable( !_bLock );
	else
	{
		// disable the window
        Reference< XWindow > xComp( xPeer, UNO_QUERY );
		if ( xComp.is() )
			xComp->setEnable( !_bLock );
	}
}

//--------------------------------------------------------------------
sal_Bool SAL_CALL OBoundControl::setModel( const Reference< XControlModel >& _rxModel ) throw (RuntimeException)
{
    return OControl::setModel( _rxModel );
}

//--------------------------------------------------------------------
void SAL_CALL OBoundControl::disposing(const EventObject& Source) throw (RuntimeException)
{
    // just disambiguate
    OControl::disposing(Source);
}

//--------------------------------------------------------------------
void OBoundControl::disposing()
{
    OControl::disposing();
}

//==================================================================
//= OControlModel
//==================================================================
DBG_NAME(OControlModel)
//------------------------------------------------------------------
Sequence<sal_Int8> SAL_CALL OControlModel::getImplementationId() throw(RuntimeException)
{
	return OImplementationIds::getImplementationId(getTypes());
}

//------------------------------------------------------------------
Sequence<Type> SAL_CALL OControlModel::getTypes() throw(RuntimeException)
{
    TypeBag aTypes( _getTypes() );

    Reference< XTypeProvider > xProv;
	if ( query_aggregation( m_xAggregate, xProv ) )
        aTypes.addTypes( xProv->getTypes() );

    return aTypes.getTypes();
}

//------------------------------------------------------------------------------
Sequence<Type> OControlModel::_getTypes()
{
    return TypeBag( OComponentHelper::getTypes(),
        OPropertySetAggregationHelper::getTypes(),
        OControlModel_BASE::getTypes()
    ).getTypes();
}

//------------------------------------------------------------------
Any SAL_CALL OControlModel::queryAggregation(const Type& _rType) throw (RuntimeException)
{
	// base class 1
	Any aReturn(OComponentHelper::queryAggregation(_rType));

	// base class 2
	if (!aReturn.hasValue())
	{
		aReturn = OControlModel_BASE::queryInterface(_rType);

		// our own interfaces
		if (!aReturn.hasValue())
		{
			aReturn = OPropertySetAggregationHelper::queryInterface(_rType);
			// our aggregate
			if (!aReturn.hasValue() && m_xAggregate.is() && !_rType.equals(::getCppuType(static_cast< Reference< XCloneable>* >(NULL))))
				aReturn = m_xAggregate->queryAggregation(_rType);
		}
	}
	return aReturn;
}

//------------------------------------------------------------------------------
void OControlModel::readHelpTextCompatibly(const staruno::Reference< stario::XObjectInputStream >& _rxInStream)
{
	::rtl::OUString sHelpText;
	::comphelper::operator>>( _rxInStream, sHelpText);
	try
	{
		if (m_xAggregateSet.is())
			m_xAggregateSet->setPropertyValue(PROPERTY_HELPTEXT, makeAny(sHelpText));
	}
	catch(const Exception&)
	{
		OSL_ENSURE(sal_False, "OControlModel::readHelpTextCompatibly: could not forward the property value to the aggregate!");
	}
}

//------------------------------------------------------------------------------
void OControlModel::writeHelpTextCompatibly(const staruno::Reference< stario::XObjectOutputStream >& _rxOutStream)
{
	::rtl::OUString sHelpText;
	try
	{
		if (m_xAggregateSet.is())
			m_xAggregateSet->getPropertyValue(PROPERTY_HELPTEXT) >>= sHelpText;
	}
	catch(const Exception&)
	{
		OSL_ENSURE(sal_False, "OControlModel::writeHelpTextCompatibly: could not retrieve the property value from the aggregate!");
	}
	::comphelper::operator<<( _rxOutStream, sHelpText);
}

//------------------------------------------------------------------
OControlModel::OControlModel(
                        const Reference<com::sun::star::lang::XMultiServiceFactory>& _rxFactory,
			const ::rtl::OUString& _rUnoControlModelTypeName,
			const ::rtl::OUString& rDefault, const sal_Bool _bSetDelegator)
	:OComponentHelper(m_aMutex)
	,OPropertySetAggregationHelper(OComponentHelper::rBHelper)
    ,m_aContext( _rxFactory )
    ,m_lockCount( 0 )
    ,m_aPropertyBagHelper( *this )
	,m_nTabIndex(FRM_DEFAULT_TABINDEX)
	,m_nClassId(FormComponentType::CONTROL)
    ,m_bNativeLook( sal_False )
	,m_nControlTypeinMSO(0) // 0 : default value is create from AOO
	,m_nObjIDinMSO(INVALID_OBJ_ID_IN_MSO)
        // form controls are usually embedded into documents, not dialogs, and in documents
        // the native look is ugly ....
        // #i37342# / 2004-11-19 / frank.schoenheit@sun.com
{
	DBG_CTOR(OControlModel, NULL);
	if (_rUnoControlModelTypeName.getLength())	// the is a model we have to aggregate
	{
		increment(m_refCount);

		{
			m_xAggregate = Reference<XAggregation>(_rxFactory->createInstance(_rUnoControlModelTypeName), UNO_QUERY);
			setAggregation(m_xAggregate);

			if ( m_xAggregateSet.is() )
            {
                try
                {
                    if ( rDefault.getLength() )
	    			    m_xAggregateSet->setPropertyValue( PROPERTY_DEFAULTCONTROL, makeAny( rDefault ) );
                }
                catch( const Exception& )
                {
                	OSL_ENSURE( sal_False, "OControlModel::OControlModel: caught an exception!" );
                }
            }
		}

		if (_bSetDelegator)
			doSetDelegator();

		// Refcount wieder bei NULL
		decrement(m_refCount);
	}
}

//------------------------------------------------------------------
OControlModel::OControlModel( const OControlModel* _pOriginal, const Reference< XMultiServiceFactory>& _rxFactory, const sal_Bool _bCloneAggregate, const sal_Bool _bSetDelegator )
	:OComponentHelper( m_aMutex )
	,OPropertySetAggregationHelper( OComponentHelper::rBHelper )
    ,m_aContext( _rxFactory )
    ,m_lockCount( 0 )
    ,m_aPropertyBagHelper( *this )
	,m_nTabIndex( FRM_DEFAULT_TABINDEX )
	,m_nClassId( FormComponentType::CONTROL )
{
	DBG_CTOR( OControlModel, NULL );
	DBG_ASSERT( _pOriginal, "OControlModel::OControlModel: invalid original!" );

	// copy members
	m_aName = _pOriginal->m_aName;
	m_aTag = _pOriginal->m_aTag;
	m_nTabIndex = _pOriginal->m_nTabIndex;
	m_nClassId = _pOriginal->m_nClassId;
    m_bNativeLook = _pOriginal->m_bNativeLook;
	m_nControlTypeinMSO = _pOriginal->m_nControlTypeinMSO;
	m_nObjIDinMSO = _pOriginal->m_nObjIDinMSO;

    if ( _bCloneAggregate )
    {
	    // temporarily increment refcount because of temporary references to ourself in the following
	    increment( m_refCount );

	    {
		    // transfer the (only, at the very moment!) ref count
		    m_xAggregate = createAggregateClone( _pOriginal );

		    // set aggregation (retrieve other direct interfaces of the aggregate)
		    setAggregation( m_xAggregate );
	    }

	    // set the delegator, if allowed by our derived class
	    if ( _bSetDelegator )
		    doSetDelegator();

	    // decrement ref count
	    decrement( m_refCount );
    }
}

//------------------------------------------------------------------
OControlModel::~OControlModel()
{
    // release the aggregate
    doResetDelegator( );

    DBG_DTOR(OControlModel, NULL);
}

//------------------------------------------------------------------
void OControlModel::clonedFrom( const OControlModel* /*_pOriginal*/ )
{
    // nothing to do in this base class
}

//------------------------------------------------------------------------------
void OControlModel::doResetDelegator()
{
	if (m_xAggregate.is())
		m_xAggregate->setDelegator(NULL);
}

//------------------------------------------------------------------------------
void OControlModel::doSetDelegator()
{
	increment(m_refCount);
	if (m_xAggregate.is())
	{
		m_xAggregate->setDelegator(static_cast<XWeak*>(this));
	}
	decrement(m_refCount);
}

// XChild
//------------------------------------------------------------------------------
Reference< XInterface > SAL_CALL OControlModel::getParent() throw(RuntimeException)
{
	return m_xParent;
}

//------------------------------------------------------------------------------
void SAL_CALL OControlModel::setParent(const Reference< XInterface >& _rxParent) throw(com::sun::star::lang::NoSupportException, RuntimeException)
{
	osl::MutexGuard aGuard(m_aMutex);

	Reference<XComponent> xComp(m_xParent, UNO_QUERY);
	if (xComp.is())
		xComp->removeEventListener(static_cast<XPropertiesChangeListener*>(this));

	m_xParent = _rxParent;
	xComp = xComp.query( m_xParent );

	if ( xComp.is() )
		xComp->addEventListener(static_cast<XPropertiesChangeListener*>(this));
}

// XNamed
//------------------------------------------------------------------------------
::rtl::OUString SAL_CALL OControlModel::getName() throw(RuntimeException)
{
	::rtl::OUString aReturn;
	OPropertySetHelper::getFastPropertyValue(PROPERTY_ID_NAME) >>= aReturn;
	return aReturn;
}

//------------------------------------------------------------------------------
void SAL_CALL OControlModel::setName(const ::rtl::OUString& _rName) throw(RuntimeException)
{
        setFastPropertyValue(PROPERTY_ID_NAME, makeAny(_rName));
}

// XServiceInfo
//------------------------------------------------------------------------------
sal_Bool SAL_CALL OControlModel::supportsService(const rtl::OUString& _rServiceName) throw ( RuntimeException)
{
    Sequence<rtl::OUString> aSupported = getSupportedServiceNames();
	const rtl::OUString* pSupported = aSupported.getConstArray();
	for (sal_Int32 i=0; i<aSupported.getLength(); ++i, ++pSupported)
		if (pSupported->equals(_rServiceName))
			return sal_True;
	return sal_False;
}

//------------------------------------------------------------------------------
Sequence< ::rtl::OUString > OControlModel::getAggregateServiceNames()
{
    Sequence< ::rtl::OUString > aAggServices;
    Reference< XServiceInfo > xInfo;
	if ( query_aggregation( m_xAggregate, xInfo ) )
		aAggServices = xInfo->getSupportedServiceNames();
    return aAggServices;
}

//------------------------------------------------------------------------------
Sequence<rtl::OUString> SAL_CALL OControlModel::getSupportedServiceNames() throw(RuntimeException)
{
    return ::comphelper::concatSequences(
        getAggregateServiceNames(),
        getSupportedServiceNames_Static()
    );
}

//------------------------------------------------------------------------------
Sequence< ::rtl::OUString > SAL_CALL OControlModel::getSupportedServiceNames_Static() throw( RuntimeException )
{
    Sequence< ::rtl::OUString > aServiceNames( 2 );
	aServiceNames[ 0 ] = FRM_SUN_FORMCOMPONENT;
	aServiceNames[ 1 ] = ::rtl::OUString::createFromAscii( "com.sun.star.form.FormControlModel" );
    return aServiceNames;
}

// XEventListener
//------------------------------------------------------------------------------
void SAL_CALL OControlModel::disposing(const com::sun::star::lang::EventObject& _rSource) throw (RuntimeException)
{
	// release the parent
	if (_rSource.Source == m_xParent)
	{
		osl::MutexGuard aGuard(m_aMutex);
		m_xParent = NULL;
	}
	else
	{
		Reference<com::sun::star::lang::XEventListener> xEvtLst;
		if (query_aggregation(m_xAggregate, xEvtLst))
		{
			osl::MutexGuard aGuard(m_aMutex);
			xEvtLst->disposing(_rSource);
		}
	}
}

// OComponentHelper
//-----------------------------------------------------------------------------
void OControlModel::disposing()
{
	OPropertySetAggregationHelper::disposing();

	Reference<com::sun::star::lang::XComponent> xComp;
	if (query_aggregation(m_xAggregate, xComp))
		xComp->dispose();

	setParent(Reference<XFormComponent>());

    m_aPropertyBagHelper.dispose();
}

//------------------------------------------------------------------------------
void OControlModel::writeAggregate( const Reference< XObjectOutputStream >& _rxOutStream ) const
{
	Reference< XPersistObject > xPersist;
	if ( query_aggregation( m_xAggregate, xPersist ) )
		xPersist->write( _rxOutStream );
}

//------------------------------------------------------------------------------
void OControlModel::readAggregate( const Reference< XObjectInputStream >& _rxInStream )
{
	Reference< XPersistObject > xPersist;
	if ( query_aggregation( m_xAggregate, xPersist ) )
		xPersist->read( _rxInStream );
}

//------------------------------------------------------------------------------
void SAL_CALL OControlModel::write(const Reference<stario::XObjectOutputStream>& _rxOutStream)
                        throw(stario::IOException, RuntimeException)
{
	osl::MutexGuard aGuard(m_aMutex);

	// 1. Schreiben des UnoControls
	Reference<stario::XMarkableStream> xMark(_rxOutStream, UNO_QUERY);
	if ( !xMark.is() )
	{
		throw IOException(
			FRM_RES_STRING( RID_STR_INVALIDSTREAM ),
			static_cast< ::cppu::OWeakObject* >( this )
		);
	}

	sal_Int32 nMark = xMark->createMark();
	sal_Int32 nLen = 0;

	_rxOutStream->writeLong(nLen);

    writeAggregate( _rxOutStream );

    // feststellen der Laenge
	nLen = xMark->offsetToMark(nMark) - 4;
	xMark->jumpToMark(nMark);
	_rxOutStream->writeLong(nLen);
	xMark->jumpToFurthest();
	xMark->deleteMark(nMark);

	// 2. Schreiben einer VersionsNummer
	_rxOutStream->writeShort(0x0003);

	// 3. Schreiben der allgemeinen Properties
	::comphelper::operator<<( _rxOutStream, m_aName);
	_rxOutStream->writeShort(m_nTabIndex);
	::comphelper::operator<<( _rxOutStream, m_aTag); // 3. version

	// !!! IMPORTANT NOTE !!!
	// don't write any new members here : this wouldn't be compatible with older versions, as OControlModel
	// is a base class which is called in derived classes "read" method. So if you increment the version
	// and write new stuff, older office versions will read this in the _derived_ classes, which may result
	// in anything from data loss to crash.
	// !!! EOIN !!!
}

//------------------------------------------------------------------------------
void OControlModel::read(const Reference<stario::XObjectInputStream>& InStream) throw (::com::sun::star::io::IOException, RuntimeException)
{
	osl::MutexGuard aGuard(m_aMutex);

	Reference<stario::XMarkableStream> xMark(InStream, UNO_QUERY);
	if ( !xMark.is() )
	{
		throw IOException(
			FRM_RES_STRING( RID_STR_INVALIDSTREAM ),
			static_cast< ::cppu::OWeakObject* >( this )
		);
	}

	// 1. Lesen des UnoControls
	sal_Int32 nLen = InStream->readLong();
	if (nLen)
	{
		sal_Int32 nMark = xMark->createMark();

        try
        {
            readAggregate( InStream );
        }
        catch( const Exception& )
        {
            DBG_UNHANDLED_EXCEPTION();
        }

		xMark->jumpToMark(nMark);
		InStream->skipBytes(nLen);
		xMark->deleteMark(nMark);
	}

	// 2. Lesen des Versionsnummer
	sal_uInt16 nVersion = InStream->readShort();

	// 3. Lesen der allgemeinen Properties
	::comphelper::operator>>( InStream, m_aName);
	m_nTabIndex  = InStream->readShort();

	if (nVersion > 0x0002)
		::comphelper::operator>>( InStream, m_aTag);

	// we had a version where we wrote the help text
	if (nVersion == 0x0004)
		readHelpTextCompatibly(InStream);

	DBG_ASSERT(nVersion < 5, "OControlModel::read : suspicious version number !");
	// 4 was the version where we wrote the help text
	// later versions shouldn't exist (see write for a detailed comment)
}

//------------------------------------------------------------------------------
PropertyState OControlModel::getPropertyStateByHandle( sal_Int32 _nHandle )
{
	// simply compare the current and the default value
	Any aCurrentValue = getPropertyDefaultByHandle( _nHandle );
	Any aDefaultValue;  getFastPropertyValue( aDefaultValue, _nHandle );

	sal_Bool bEqual = uno_type_equalData(
			const_cast< void* >( aCurrentValue.getValue() ), aCurrentValue.getValueType().getTypeLibType(),
			const_cast< void* >( aDefaultValue.getValue() ), aDefaultValue.getValueType().getTypeLibType(),
			reinterpret_cast< uno_QueryInterfaceFunc >(cpp_queryInterface),
            reinterpret_cast< uno_ReleaseFunc >(cpp_release)
		);
    return bEqual ? PropertyState_DEFAULT_VALUE : PropertyState_DIRECT_VALUE;
}

//------------------------------------------------------------------------------
void OControlModel::setPropertyToDefaultByHandle( sal_Int32 _nHandle)
{
	Any aDefault = getPropertyDefaultByHandle( _nHandle );

	Any aConvertedValue, aOldValue;
	if ( convertFastPropertyValue( aConvertedValue, aOldValue, _nHandle, aDefault ) )
	{
		setFastPropertyValue_NoBroadcast( _nHandle, aConvertedValue );
		// TODO: fire the property change
	}
}

//------------------------------------------------------------------------------
Any OControlModel::getPropertyDefaultByHandle( sal_Int32 _nHandle ) const
{
	Any aReturn;
	switch ( _nHandle )
	{
		case PROPERTY_ID_NAME:
		case PROPERTY_ID_TAG:
			aReturn <<= ::rtl::OUString();
			break;

		case PROPERTY_ID_CLASSID:
			aReturn <<= (sal_Int16)FormComponentType::CONTROL;
			break;

		case PROPERTY_ID_TABINDEX:
			aReturn <<= (sal_Int16)FRM_DEFAULT_TABINDEX;
			break;

        case PROPERTY_ID_NATIVE_LOOK:
			aReturn <<= (sal_Bool)sal_True;
			break;
		//added for exporting OCX control
		case PROPERTY_ID_CONTROL_TYPE_IN_MSO:
			aReturn <<= (sal_Int16)0;
			break;
		case PROPERTY_ID_OBJ_ID_IN_MSO:
			aReturn <<= (sal_uInt16)INVALID_OBJ_ID_IN_MSO;
			break;
        default:
            if ( m_aPropertyBagHelper.hasDynamicPropertyByHandle( _nHandle ) )
                m_aPropertyBagHelper.getDynamicPropertyDefaultByHandle( _nHandle, aReturn );
            else
                OSL_ENSURE( false, "OControlModel::convertFastPropertyValue: unknown handle!" );
	}
	return aReturn;
}

//------------------------------------------------------------------------------
void OControlModel::getFastPropertyValue( Any& _rValue, sal_Int32 _nHandle ) const
{
	switch ( _nHandle )
	{
		case PROPERTY_ID_NAME:
			_rValue <<= m_aName;
			break;
		case PROPERTY_ID_TAG:
			_rValue <<= m_aTag;
			break;
		case PROPERTY_ID_CLASSID:
			_rValue <<= m_nClassId;
			break;
		case PROPERTY_ID_TABINDEX:
			_rValue <<= m_nTabIndex;
			break;
        case PROPERTY_ID_NATIVE_LOOK:
			_rValue <<= (sal_Bool)m_bNativeLook;
			break;
		//added for exporting OCX control
		case PROPERTY_ID_CONTROL_TYPE_IN_MSO:
			_rValue <<= (sal_Int16)m_nControlTypeinMSO;
			break;
		case PROPERTY_ID_OBJ_ID_IN_MSO:
			_rValue <<= (sal_uInt16)m_nObjIDinMSO;
			break;
		default:
            if ( m_aPropertyBagHelper.hasDynamicPropertyByHandle( _nHandle ) )
                m_aPropertyBagHelper.getDynamicFastPropertyValue( _nHandle, _rValue );
            else
			    OPropertySetAggregationHelper::getFastPropertyValue( _rValue, _nHandle );
            break;
	}
}

//------------------------------------------------------------------------------
sal_Bool OControlModel::convertFastPropertyValue(
                        Any& _rConvertedValue, Any& _rOldValue, sal_Int32 _nHandle, const Any& _rValue)
                        throw (com::sun::star::lang::IllegalArgumentException)
{
	sal_Bool bModified(sal_False);
	switch (_nHandle)
	{
		case PROPERTY_ID_NAME:
			bModified = tryPropertyValue(_rConvertedValue, _rOldValue, _rValue, m_aName);
			break;
		case PROPERTY_ID_TAG:
			bModified = tryPropertyValue(_rConvertedValue, _rOldValue, _rValue, m_aTag);
			break;
		case PROPERTY_ID_TABINDEX:
			bModified = tryPropertyValue(_rConvertedValue, _rOldValue, _rValue, m_nTabIndex);
			break;
        case PROPERTY_ID_NATIVE_LOOK:
			bModified = tryPropertyValue(_rConvertedValue, _rOldValue, _rValue, m_bNativeLook);
			break;
		//added for exporting OCX control
		case PROPERTY_ID_CONTROL_TYPE_IN_MSO:
			bModified = tryPropertyValue(_rConvertedValue, _rOldValue, _rValue, m_nControlTypeinMSO);
			break;
		case PROPERTY_ID_OBJ_ID_IN_MSO:
			bModified = tryPropertyValue(_rConvertedValue, _rOldValue, _rValue, m_nObjIDinMSO);
			break;
        default:
            if ( m_aPropertyBagHelper.hasDynamicPropertyByHandle( _nHandle ) )
                bModified = m_aPropertyBagHelper.convertDynamicFastPropertyValue( _nHandle, _rValue, _rConvertedValue, _rOldValue );
            else
                OSL_ENSURE( false, "OControlModel::convertFastPropertyValue: unknown handle!" );
            break;
	}
	return bModified;
}

//------------------------------------------------------------------------------
void OControlModel::setFastPropertyValue_NoBroadcast(sal_Int32 _nHandle, const Any& _rValue)
                        throw (Exception)
{
	switch (_nHandle)
	{
		case PROPERTY_ID_NAME:
			DBG_ASSERT(_rValue.getValueType() == getCppuType((const ::rtl::OUString*)NULL),
				"OControlModel::setFastPropertyValue_NoBroadcast : invalid type" );
			_rValue >>= m_aName;
			break;
		case PROPERTY_ID_TAG:
			DBG_ASSERT(_rValue.getValueType() == getCppuType((const ::rtl::OUString*)NULL),
				"OControlModel::setFastPropertyValue_NoBroadcast : invalid type" );
			_rValue >>= m_aTag;
			break;
		case PROPERTY_ID_TABINDEX:
			DBG_ASSERT(_rValue.getValueType() == getCppuType((const sal_Int16*)NULL),
				"OControlModel::setFastPropertyValue_NoBroadcast : invalid type" );
			_rValue >>= m_nTabIndex;
			break;
        case PROPERTY_ID_NATIVE_LOOK:
            OSL_VERIFY( _rValue >>= m_bNativeLook );
			break;
		//added for exporting OCX control
		case PROPERTY_ID_CONTROL_TYPE_IN_MSO:
			OSL_VERIFY( _rValue >>= m_nControlTypeinMSO );
			break;
		case PROPERTY_ID_OBJ_ID_IN_MSO:
			OSL_VERIFY( _rValue >>= m_nObjIDinMSO );
			break;
        default:
            if ( m_aPropertyBagHelper.hasDynamicPropertyByHandle( _nHandle ) )
                m_aPropertyBagHelper.setDynamicFastPropertyValue( _nHandle, _rValue );
            else
                OSL_ENSURE( false, "OControlModel::setFastPropertyValue_NoBroadcast: unknown handle!" );
            break;
	}
}

//------------------------------------------------------------------------------
void OControlModel::describeFixedProperties( Sequence< Property >& _rProps ) const
{
	//BEGIN_DESCRIBE_BASE_PROPERTIES( 4 )
    BEGIN_DESCRIBE_BASE_PROPERTIES( 6 )
        DECL_PROP2      (CLASSID,     sal_Int16,        READONLY, TRANSIENT);
        DECL_PROP1      (NAME,        ::rtl::OUString,  BOUND);
        DECL_BOOL_PROP2 (NATIVE_LOOK,                   BOUND, TRANSIENT);
        DECL_PROP1      (TAG,         ::rtl::OUString,  BOUND);
        DECL_PROP1      (CONTROL_TYPE_IN_MSO,sal_Int16,		BOUND);
        DECL_PROP1      (OBJ_ID_IN_MSO,sal_uInt16,		BOUND);
    END_DESCRIBE_PROPERTIES()
}

//------------------------------------------------------------------------------
void OControlModel::describeAggregateProperties( Sequence< Property >& /* [out] */ _rAggregateProps ) const
{
    if ( m_xAggregateSet.is() )
    {
        Reference< XPropertySetInfo > xPSI( m_xAggregateSet->getPropertySetInfo() );
        if ( xPSI.is() )
            _rAggregateProps = xPSI->getProperties();
    }
}

//------------------------------------------------------------------------------
::osl::Mutex& OControlModel::getMutex()
{
    return m_aMutex;
}

//------------------------------------------------------------------------------
void OControlModel::describeFixedAndAggregateProperties( Sequence< Property >& _out_rFixedProperties, Sequence< Property >& _out_rAggregateProperties ) const
{
    describeFixedProperties( _out_rFixedProperties );
    describeAggregateProperties( _out_rAggregateProperties );
}

//------------------------------------------------------------------------------
Reference< XMultiPropertySet > OControlModel::getPropertiesInterface()
{
    return Reference< XMultiPropertySet >( *this, UNO_QUERY );
}

//------------------------------------------------------------------------------
Reference< XPropertySetInfo> SAL_CALL OControlModel::getPropertySetInfo() throw( RuntimeException)
{
	return createPropertySetInfo( getInfoHelper() );
}

//------------------------------------------------------------------------------
::cppu::IPropertyArrayHelper& OControlModel::getInfoHelper()
{
    return m_aPropertyBagHelper.getInfoHelper();
}

//--------------------------------------------------------------------
void SAL_CALL OControlModel::addProperty( const ::rtl::OUString& _rName, ::sal_Int16 _nAttributes, const Any& _rInitialValue ) throw (PropertyExistException, IllegalTypeException, IllegalArgumentException, RuntimeException)
{
    m_aPropertyBagHelper.addProperty( _rName, _nAttributes, _rInitialValue );
}

//--------------------------------------------------------------------
void SAL_CALL OControlModel::removeProperty( const ::rtl::OUString& _rName ) throw (UnknownPropertyException, NotRemoveableException, RuntimeException)
{
    m_aPropertyBagHelper.removeProperty( _rName );
}

//--------------------------------------------------------------------
Sequence< PropertyValue > SAL_CALL OControlModel::getPropertyValues() throw (RuntimeException)
{
    return m_aPropertyBagHelper.getPropertyValues();
}

//--------------------------------------------------------------------
void SAL_CALL OControlModel::setPropertyValues( const Sequence< PropertyValue >& _rProps ) throw (UnknownPropertyException, PropertyVetoException, IllegalArgumentException, WrappedTargetException, RuntimeException)
{
    m_aPropertyBagHelper.setPropertyValues( _rProps );
}

//--------------------------------------------------------------------
void OControlModel::lockInstance( LockAccess )
{
    m_aMutex.acquire();
    osl_incrementInterlockedCount( &m_lockCount );
}

//--------------------------------------------------------------------
oslInterlockedCount OControlModel::unlockInstance( LockAccess )
{
    OSL_ENSURE( m_lockCount > 0, "OControlModel::unlockInstance: not locked!" );
    oslInterlockedCount lockCount = osl_decrementInterlockedCount( &m_lockCount );
    m_aMutex.release();
    return lockCount;
}

//--------------------------------------------------------------------
void OControlModel::firePropertyChanges( const Sequence< sal_Int32 >& _rHandles, const Sequence< Any >& _rOldValues,
                                        const Sequence< Any >& _rNewValues, LockAccess )
{
    OPropertySetHelper::fire(
        const_cast< Sequence< sal_Int32 >& >( _rHandles ).getArray(),
        _rNewValues.getConstArray(),
        _rOldValues.getConstArray(),
        _rHandles.getLength(),
        sal_False
    );
}

//==================================================================
//= OBoundControlModel
//==================================================================
DBG_NAME(frm_OBoundControlModel);
//------------------------------------------------------------------
Any SAL_CALL OBoundControlModel::queryAggregation( const Type& _rType ) throw (RuntimeException)
{
	Any aReturn( OControlModel::queryAggregation(_rType) );
	if (!aReturn.hasValue())
	{
		aReturn = OBoundControlModel_BASE1::queryInterface(_rType);

        if ( !aReturn.hasValue() && m_bCommitable )
			aReturn = OBoundControlModel_COMMITTING::queryInterface( _rType );

        if ( !aReturn.hasValue() && m_bSupportsExternalBinding )
			aReturn = OBoundControlModel_BINDING::queryInterface( _rType );

        if ( !aReturn.hasValue() && m_bSupportsValidation )
			aReturn = OBoundControlModel_VALIDATION::queryInterface( _rType );
	}

	return aReturn;
}

//------------------------------------------------------------------
OBoundControlModel::OBoundControlModel(
        const Reference< XMultiServiceFactory>& _rxFactory,
		const ::rtl::OUString& _rUnoControlModelTypeName, const ::rtl::OUString& _rDefault,
		const sal_Bool _bCommitable, const sal_Bool _bSupportExternalBinding, const sal_Bool _bSupportsValidation )
	:OControlModel( _rxFactory, _rUnoControlModelTypeName, _rDefault, sal_False )
	,OPropertyChangeListener( m_aMutex )
    ,m_xField()
    ,m_xAmbientForm()
    ,m_nValuePropertyAggregateHandle( -1 )
    ,m_nFieldType( DataType::OTHER )
    ,m_bValuePropertyMayBeVoid( false )
    ,m_aResetHelper( *this, m_aMutex )
    ,m_aUpdateListeners(m_aMutex)
    ,m_aFormComponentListeners( m_aMutex )
    ,m_bInputRequired( sal_True )
    ,m_pAggPropMultiplexer( NULL )
    ,m_bFormListening( false )
    ,m_bLoaded(sal_False)
    ,m_bRequired(sal_False)
	,m_bCommitable(_bCommitable)
    ,m_bSupportsExternalBinding( _bSupportExternalBinding )
    ,m_bSupportsValidation( _bSupportsValidation )
    ,m_bForwardValueChanges(sal_True)
    ,m_bTransferingValue( sal_False )
    ,m_bIsCurrentValueValid( sal_True )
    ,m_bBindingControlsRO( sal_False )
    ,m_bBindingControlsEnable( sal_False )
	,m_eControlValueChangeInstigator( eOther )
    ,m_aLabelServiceName(FRM_SUN_COMPONENT_FIXEDTEXT)
{
	DBG_CTOR(frm_OBoundControlModel, NULL);

    // start property listening at the aggregate
    implInitAggMultiplexer( );
}

//------------------------------------------------------------------
OBoundControlModel::OBoundControlModel(
		const OBoundControlModel* _pOriginal, const Reference< XMultiServiceFactory>& _rxFactory )
	:OControlModel( _pOriginal, _rxFactory, sal_True, sal_False )
	,OPropertyChangeListener( m_aMutex )
    ,m_xField()
    ,m_xAmbientForm()
    ,m_nValuePropertyAggregateHandle( _pOriginal->m_nValuePropertyAggregateHandle )
    ,m_nFieldType( DataType::OTHER )
    ,m_bValuePropertyMayBeVoid( _pOriginal->m_bValuePropertyMayBeVoid )
    ,m_aResetHelper( *this, m_aMutex )
    ,m_aUpdateListeners( m_aMutex )
    ,m_aFormComponentListeners( m_aMutex )
    ,m_xValidator( _pOriginal->m_xValidator )
    ,m_bInputRequired( sal_True )
    ,m_pAggPropMultiplexer( NULL )
    ,m_bFormListening( false )
    ,m_bLoaded( sal_False )
	,m_bRequired( sal_False )
	,m_bCommitable( _pOriginal->m_bCommitable )
    ,m_bSupportsExternalBinding( _pOriginal->m_bSupportsExternalBinding )
    ,m_bSupportsValidation( _pOriginal->m_bSupportsValidation )
	,m_bForwardValueChanges( sal_True )
    ,m_bTransferingValue( sal_False )
    ,m_bIsCurrentValueValid( _pOriginal->m_bIsCurrentValueValid )
    ,m_bBindingControlsRO( sal_False )
    ,m_bBindingControlsEnable( sal_False )
    ,m_eControlValueChangeInstigator( eOther )
{
	DBG_CTOR(frm_OBoundControlModel, NULL);

    // start property listening at the aggregate
    implInitAggMultiplexer( );

	m_aLabelServiceName = _pOriginal->m_aLabelServiceName;
	m_sValuePropertyName = _pOriginal->m_sValuePropertyName;
    m_nValuePropertyAggregateHandle = _pOriginal->m_nValuePropertyAggregateHandle;
    m_bValuePropertyMayBeVoid = _pOriginal->m_bValuePropertyMayBeVoid;
    m_aValuePropertyType = _pOriginal->m_aValuePropertyType;
	m_aControlSource = _pOriginal->m_aControlSource;
	m_bInputRequired = _pOriginal->m_bInputRequired;
	// m_xLabelControl, though being a property, is not to be cloned, not even the reference will be transferred.
	// (the former should be clear - a clone of the object we're only referencing does not make sense)
	// (the second would violate the restriction for label controls that they're part of the
	// same form component hierarchy - we ourself are no part, yet, so we can't have a label control)

    // start listening for changes at the value property
    implInitValuePropertyListening( );
}

//------------------------------------------------------------------
OBoundControlModel::~OBoundControlModel()
{
	if ( !OComponentHelper::rBHelper.bDisposed )
	{
		acquire();
		dispose();
	}

    doResetDelegator( );

    OSL_ENSURE( m_pAggPropMultiplexer, "OBoundControlModel::~OBoundControlModel: what about my property multiplexer?" );
	if ( m_pAggPropMultiplexer )
	{
		m_pAggPropMultiplexer->dispose();
		m_pAggPropMultiplexer->release();
		m_pAggPropMultiplexer = NULL;
	}

    DBG_DTOR(frm_OBoundControlModel, NULL);
}

//------------------------------------------------------------------
void OBoundControlModel::clonedFrom( const OControlModel* _pOriginal )
{
    const OBoundControlModel* pBoundOriginal = static_cast< const OBoundControlModel* >( _pOriginal );
    // the value binding can be handled as if somebody called setValueBinding here
    // By definition, bindings can be share between bindables
    if ( pBoundOriginal && pBoundOriginal->m_xExternalBinding.is() )
    {
        try
        {
            setValueBinding( pBoundOriginal->m_xExternalBinding );
        }
        catch( const Exception& )
        {
        	DBG_UNHANDLED_EXCEPTION();
        }
    }
}

//-----------------------------------------------------------------------------
void OBoundControlModel::implInitAggMultiplexer( )
{
	increment( m_refCount );
	if ( m_xAggregateSet.is() )
	{
		m_pAggPropMultiplexer = new OPropertyChangeMultiplexer( this, m_xAggregateSet, sal_False );
		m_pAggPropMultiplexer->acquire();
	}
	decrement( m_refCount );

   	doSetDelegator();
}

//-----------------------------------------------------------------------------
void OBoundControlModel::implInitValuePropertyListening( ) const
{
    // start listening for changes at the value property
    // There are three pre-requisites for this to be done:
    // 1. We support external value bindings. In this case, the changes in the control value need to
    //    be propagated to the external binding immediately when they happen
    // 2. We support external validation. In this case, we need to listen for changes in the value
    //    property, since we need to revalidate then.
    // 3. We are not committable. In this case, changes in the control value need to be propagated
    //    to the database column immediately when they happen.
    if ( m_bSupportsExternalBinding || m_bSupportsValidation || !m_bCommitable )
    {
        OSL_ENSURE( m_pAggPropMultiplexer, "OBoundControlModel::implInitValuePropertyListening: no multiplexer!" );
        if ( m_pAggPropMultiplexer && m_sValuePropertyName.getLength() )
            m_pAggPropMultiplexer->addProperty( m_sValuePropertyName );
    }
}

//-----------------------------------------------------------------------------
void OBoundControlModel::initOwnValueProperty( const ::rtl::OUString& i_rValuePropertyName )
{
    OSL_PRECOND( !m_sValuePropertyName.getLength() && -1 == m_nValuePropertyAggregateHandle,
        "OBoundControlModel::initOwnValueProperty: value property is already initialized!" );
    OSL_ENSURE( i_rValuePropertyName.getLength(), "OBoundControlModel::initOwnValueProperty: invalid property name!" );
    m_sValuePropertyName = i_rValuePropertyName;
}

//-----------------------------------------------------------------------------
void OBoundControlModel::initValueProperty( const ::rtl::OUString& _rValuePropertyName, sal_Int32 _nValuePropertyExternalHandle )
{
    OSL_PRECOND( !m_sValuePropertyName.getLength() && -1 == m_nValuePropertyAggregateHandle,
        "OBoundControlModel::initValueProperty: value property is already initialized!" );
    OSL_ENSURE( _rValuePropertyName.getLength(), "OBoundControlModel::initValueProperty: invalid property name!" );
    OSL_ENSURE( _nValuePropertyExternalHandle != -1, "OBoundControlModel::initValueProperty: invalid property handle!" );

    m_sValuePropertyName = _rValuePropertyName;
	m_nValuePropertyAggregateHandle = getOriginalHandle( _nValuePropertyExternalHandle );
    OSL_ENSURE( m_nValuePropertyAggregateHandle != -1, "OBoundControlModel::initValueProperty: unable to find the original handle!" );

    if ( m_nValuePropertyAggregateHandle != -1 )
    {
        Reference< XPropertySetInfo > xPropInfo( m_xAggregateSet->getPropertySetInfo(), UNO_SET_THROW );
        Property aValuePropDesc = xPropInfo->getPropertyByName( m_sValuePropertyName );
        m_aValuePropertyType = aValuePropDesc.Type;
        m_bValuePropertyMayBeVoid = ( aValuePropDesc.Attributes & PropertyAttribute::MAYBEVOID ) != 0;
    }

    // start listening for changes at the value property
    implInitValuePropertyListening( );
}

//-----------------------------------------------------------------------------
void OBoundControlModel::suspendValueListening( )
{
    OSL_PRECOND( m_sValuePropertyName.getLength(), "OBoundControlModel::suspendValueListening: don't have a value property!" );
    OSL_PRECOND( m_pAggPropMultiplexer, "OBoundControlModel::suspendValueListening: I *am* not listening!" );

    if ( m_pAggPropMultiplexer )
        m_pAggPropMultiplexer->lock();
}

//-----------------------------------------------------------------------------
void OBoundControlModel::resumeValueListening( )
{
    OSL_PRECOND( m_sValuePropertyName.getLength(), "OBoundControlModel::resumeValueListening: don't have a value property!" );
    OSL_PRECOND( m_pAggPropMultiplexer, "OBoundControlModel::resumeValueListening: I *am* not listening at all!" );
    OSL_PRECOND( !m_pAggPropMultiplexer || m_pAggPropMultiplexer->locked(), "OBoundControlModel::resumeValueListening: listening not suspended currently!" );

    if ( m_pAggPropMultiplexer )
        m_pAggPropMultiplexer->unlock();
}

//-----------------------------------------------------------------------------
Sequence< Type > OBoundControlModel::_getTypes()
{
    TypeBag aTypes(
        OControlModel::_getTypes(),
        OBoundControlModel_BASE1::getTypes()
    );

	if ( m_bCommitable )
        aTypes.addTypes( OBoundControlModel_COMMITTING::getTypes() );

	if ( m_bSupportsExternalBinding )
        aTypes.addTypes( OBoundControlModel_BINDING::getTypes() );

    if ( m_bSupportsValidation )
        aTypes.addTypes( OBoundControlModel_VALIDATION::getTypes() );

	return aTypes.getTypes();
}

// OComponentHelper
//-----------------------------------------------------------------------------
void OBoundControlModel::disposing()
{
	OControlModel::disposing();

    ::osl::ClearableMutexGuard aGuard(m_aMutex);

	if ( m_pAggPropMultiplexer )
		m_pAggPropMultiplexer->dispose();

    // notify all our listeners
    com::sun::star::lang::EventObject aEvt( static_cast< XWeak* >( this ) );
	m_aUpdateListeners.disposeAndClear( aEvt );
    m_aResetHelper.disposing();

    // disconnect from our database column
    // TODO: could we replace the following 5 lines with a call to impl_disconnectDatabaseColumn_noNotify?
    // The only more thing which it does is calling onDisconnectedDbColumn - could this
    // cause trouble? At least when we continue to call OControlModel::disposing before, it *may*.
	if ( hasField() )
	{
		getField()->removePropertyChangeListener( PROPERTY_VALUE, this );
		resetField();
	}
	m_xCursor = NULL;

    Reference< XComponent > xComp( m_xLabelControl, UNO_QUERY );
	if ( xComp.is() )
        xComp->removeEventListener(static_cast< XEventListener* >( static_cast< XPropertyChangeListener* >( this ) ) );

    // disconnect from our external value binding
    if ( hasExternalValueBinding() )
        disconnectExternalValueBinding();

    // dito for the validator
    if ( hasValidator() )
        disconnectValidator( );
}

//------------------------------------------------------------------------------
void OBoundControlModel::onValuePropertyChange( ControlModelLock& i_rControLock )
{
    if ( hasExternalValueBinding() )
    {   // the control value changed, while we have an external value binding
        // -> forward the value to it
        if ( m_eControlValueChangeInstigator != eExternalBinding )
            transferControlValueToExternal( i_rControLock );
    }
    else if ( !m_bCommitable && m_xColumnUpdate.is() )
    {   // the control value changed, while we are  bound to a database column,
        // but not committable (which means changes in the control have to be reflected to
        // the underlying database column immediately)
        // -> forward the value to the database column
        if ( m_eControlValueChangeInstigator != eDbColumnBinding )
            commitControlValueToDbColumn( false );
    }

    // validate the new value
    if ( m_bSupportsValidation )
        recheckValidity( true );
}

//------------------------------------------------------------------------------
void OBoundControlModel::_propertyChanged( const PropertyChangeEvent& _rEvt ) throw ( RuntimeException )
{
    ControlModelLock aLock( *this );

    OSL_ENSURE( _rEvt.PropertyName == m_sValuePropertyName,
        "OBoundControlModel::_propertyChanged: where did this come from (1)?" );
    OSL_ENSURE( m_pAggPropMultiplexer && !m_pAggPropMultiplexer->locked(),
        "OBoundControlModel::_propertyChanged: where did this come from (2)?" );

    if ( _rEvt.PropertyName == m_sValuePropertyName )
    {
        onValuePropertyChange( aLock );
    }
}

//------------------------------------------------------------------------------
void OBoundControlModel::startAggregatePropertyListening( const ::rtl::OUString& _rPropertyName )
{
    OSL_PRECOND( m_pAggPropMultiplexer, "OBoundControlModel::startAggregatePropertyListening: no multiplexer!" );
    OSL_ENSURE( _rPropertyName.getLength(), "OBoundControlModel::startAggregatePropertyListening: invalid property name!" );

    if ( m_pAggPropMultiplexer && _rPropertyName.getLength() )
    {
        m_pAggPropMultiplexer->addProperty( _rPropertyName );
    }
}

//------------------------------------------------------------------------------
void OBoundControlModel::doFormListening( const bool _bStart )
{
    OSL_PRECOND( !hasExternalValueBinding(), "OBoundControlModel::doFormListening: external value binding should overrule the database binding!" );

    if ( isFormListening() == _bStart )
        return;

	if ( m_xAmbientForm.is() )
        _bStart ? m_xAmbientForm->addLoadListener( this ) : m_xAmbientForm->removeLoadListener( this );

    Reference< XLoadable > xParentLoadable( getParent(), UNO_QUERY );
    if ( getParent().is() && !xParentLoadable.is() )
    {
        // if our parent does not directly support the XLoadable interface, then it might support the
        // XRowSetSupplier/XRowSetChangeBroadcaster interfaces. In this case we have to listen for changes
        // broadcasted by the latter.
        Reference< XRowSetChangeBroadcaster > xRowSetBroadcaster( getParent(), UNO_QUERY );
        if ( xRowSetBroadcaster.is() )
            _bStart ? xRowSetBroadcaster->addRowSetChangeListener( this ) : xRowSetBroadcaster->removeRowSetChangeListener( this );
    }

    m_bFormListening = _bStart && m_xAmbientForm.is();
}

// XChild
//------------------------------------------------------------------------------
void SAL_CALL OBoundControlModel::setParent(const Reference<XInterface>& _rxParent) throw(com::sun::star::lang::NoSupportException, RuntimeException)
{
    ControlModelLock aLock( *this );
    FieldChangeNotifier aBoundFieldNotifier( aLock );

    if ( getParent() == _rxParent )
        return;

    // disconnect from database column (which is controlled by parent, directly or indirectly)
    if ( hasField() )
        impl_disconnectDatabaseColumn_noNotify();

	// log off old listeners
    if ( isFormListening() )
        doFormListening( false );

    // actually set the new parent
	OControlModel::setParent( _rxParent );

    // a new parent means a new ambient form
    impl_determineAmbientForm_nothrow();

    if ( !hasExternalValueBinding() )
    {
        // log on new listeners
        doFormListening( true );

        // re-connect to database column of the new parent
        if ( m_xAmbientForm.is() && m_xAmbientForm->isLoaded() )
            impl_connectDatabaseColumn_noNotify( false );
    }
}

// XEventListener
//------------------------------------------------------------------------------
void SAL_CALL OBoundControlModel::disposing(const com::sun::star::lang::EventObject& _rEvent) throw (RuntimeException)
{
    ControlModelLock aLock( *this );

    if ( _rEvent.Source == getField() )
	{
		resetField();
	}
	else if ( _rEvent.Source == m_xLabelControl )
	{
		Reference<XPropertySet> xOldValue = m_xLabelControl;
		m_xLabelControl = NULL;

        // fire a propertyChanged (when we leave aLock's scope)
        aLock.addPropertyNotification( PROPERTY_ID_CONTROLLABEL, makeAny( xOldValue ), makeAny( m_xLabelControl ) );
	}
	else if ( _rEvent.Source == m_xExternalBinding )
    {   // *first* check for the external binding
        disconnectExternalValueBinding( );
    }
    else if ( _rEvent.Source == m_xValidator )
    {   // *then* check for the validator. Reason is that bindings may also act as validator at the same
        // time, in this case, the validator is automatically revoked when the binding is revoked
        disconnectValidator( );
    }
    else
		OControlModel::disposing(_rEvent);
}

// XServiceInfo
//------------------------------------------------------------------------------
StringSequence SAL_CALL OBoundControlModel::getSupportedServiceNames() throw(RuntimeException)
{
    return ::comphelper::concatSequences(
        getAggregateServiceNames(),
        getSupportedServiceNames_Static()
    );
}

//------------------------------------------------------------------------------
Sequence< ::rtl::OUString > SAL_CALL OBoundControlModel::getSupportedServiceNames_Static() throw( RuntimeException )
{
    Sequence< ::rtl::OUString > aOwnServiceNames( 1 );
	aOwnServiceNames[ 0 ] = ::rtl::OUString::createFromAscii( "com.sun.star.form.DataAwareControlModel" );

    return ::comphelper::concatSequences(
        OControlModel::getSupportedServiceNames_Static(),
        aOwnServiceNames
    );
}

// XPersist
//------------------------------------------------------------------------------
void SAL_CALL OBoundControlModel::write( const Reference<stario::XObjectOutputStream>& _rxOutStream ) throw(stario::IOException, RuntimeException)
{
	OControlModel::write(_rxOutStream);

	osl::MutexGuard aGuard(m_aMutex);

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

	// Controlsource
	::comphelper::operator<<( _rxOutStream, m_aControlSource);

	// !!! IMPORTANT NOTE !!!
	// don't write any new members here : this wouldn't be compatible with older versions, as OBoundControlModel
	// is a base class which is called in derived classes "read" method. So if you increment the version
	// and write new stuff, older office versions will read this in the _derived_ classes, which may result
	// in anything from data loss to crash.
	// (use writeCommonProperties instead, this is called in derived classes write-method)
	// !!! EOIN !!!
	// FS - 68876 - 28.09.1999
}

//------------------------------------------------------------------------------
void OBoundControlModel::defaultCommonProperties()
{
    Reference<com::sun::star::lang::XComponent> xComp(m_xLabelControl, UNO_QUERY);
	if (xComp.is())
        xComp->removeEventListener(static_cast<com::sun::star::lang::XEventListener*>(static_cast<XPropertyChangeListener*>(this)));
	m_xLabelControl = NULL;
}

//------------------------------------------------------------------------------
void OBoundControlModel::readCommonProperties(const Reference<stario::XObjectInputStream>& _rxInStream)
{
	sal_Int32 nLen = _rxInStream->readLong();

    Reference<stario::XMarkableStream> xMark(_rxInStream, UNO_QUERY);
	DBG_ASSERT(xMark.is(), "OBoundControlModel::readCommonProperties : can only work with markable streams !");
	sal_Int32 nMark = xMark->createMark();

	// read the reference to the label control
    Reference<stario::XPersistObject> xPersist;
	sal_Int32 nUsedFlag;
	nUsedFlag = _rxInStream->readLong();
	if (nUsedFlag)
		xPersist = _rxInStream->readObject();
    m_xLabelControl = m_xLabelControl.query( xPersist );
    Reference< XComponent > xComp( m_xLabelControl, UNO_QUERY );
	if (xComp.is())
        xComp->addEventListener(static_cast<com::sun::star::lang::XEventListener*>(static_cast<XPropertyChangeListener*>(this)));

	// read any other new common properties here

	// skip the remaining bytes
	xMark->jumpToMark(nMark);
	_rxInStream->skipBytes(nLen);
	xMark->deleteMark(nMark);
}

//------------------------------------------------------------------------------
void OBoundControlModel::writeCommonProperties(const Reference<stario::XObjectOutputStream>& _rxOutStream)
{
    Reference<stario::XMarkableStream> xMark(_rxOutStream, UNO_QUERY);
	DBG_ASSERT(xMark.is(), "OBoundControlModel::writeCommonProperties : can only work with markable streams !");
	sal_Int32 nMark = xMark->createMark();

	// a placeholder where we will write the overall length (later in this method)
	sal_Int32 nLen = 0;
	_rxOutStream->writeLong(nLen);

	// write the reference to the label control
    Reference<stario::XPersistObject> xPersist(m_xLabelControl, UNO_QUERY);
	sal_Int32 nUsedFlag = 0;
	if (xPersist.is())
		nUsedFlag = 1;
	_rxOutStream->writeLong(nUsedFlag);
	if (xPersist.is())
		_rxOutStream->writeObject(xPersist);

	// write any other new common properties here

	// write the correct length at the beginning of the block
	nLen = xMark->offsetToMark(nMark) - sizeof(nLen);
	xMark->jumpToMark(nMark);
	_rxOutStream->writeLong(nLen);
	xMark->jumpToFurthest();
	xMark->deleteMark(nMark);
}

//------------------------------------------------------------------------------
void SAL_CALL OBoundControlModel::read( const Reference< stario::XObjectInputStream >& _rxInStream ) throw(stario::IOException, RuntimeException)
{
	OControlModel::read(_rxInStream);

	osl::MutexGuard aGuard(m_aMutex);
	sal_uInt16 nVersion = _rxInStream->readShort(); (void)nVersion;
	::comphelper::operator>>( _rxInStream, m_aControlSource);
}

//------------------------------------------------------------------------------
void OBoundControlModel::getFastPropertyValue(Any& rValue, sal_Int32 nHandle) const
{
	switch (nHandle)
	{
        case PROPERTY_ID_INPUT_REQUIRED:
            rValue <<= m_bInputRequired;
            break;
		case PROPERTY_ID_CONTROLSOURCEPROPERTY:
			rValue <<= m_sValuePropertyName;
			break;
		case PROPERTY_ID_CONTROLSOURCE:
			rValue <<= m_aControlSource;
			break;
		case PROPERTY_ID_BOUNDFIELD:
			rValue <<= getField();
			break;
		case PROPERTY_ID_CONTROLLABEL:
			if (!m_xLabelControl.is())
				rValue.clear();
			else
				rValue <<= m_xLabelControl;
			break;
		default:
			OControlModel::getFastPropertyValue(rValue, nHandle);
	}
}

//------------------------------------------------------------------------------
sal_Bool OBoundControlModel::convertFastPropertyValue(
                                Any& _rConvertedValue, Any& _rOldValue,
				sal_Int32 _nHandle,
                                const Any& _rValue)
                throw (com::sun::star::lang::IllegalArgumentException)
{
	sal_Bool bModified(sal_False);
	switch (_nHandle)
	{
        case PROPERTY_ID_INPUT_REQUIRED:
            bModified = tryPropertyValue( _rConvertedValue, _rOldValue, _rValue, m_bInputRequired );
            break;
		case PROPERTY_ID_CONTROLSOURCE:
			bModified = tryPropertyValue(_rConvertedValue, _rOldValue, _rValue, m_aControlSource);
			break;
		case PROPERTY_ID_BOUNDFIELD:
			DBG_ERROR( "OBoundControlModel::convertFastPropertyValue: BoundField should be a read-only property !" );
            throw com::sun::star::lang::IllegalArgumentException();
		case PROPERTY_ID_CONTROLLABEL:
			if (!_rValue.hasValue())
			{	// property set to void
                _rConvertedValue = Any();
				getFastPropertyValue(_rOldValue, _nHandle);
				bModified = m_xLabelControl.is();
			}
			else
			{
				bModified = tryPropertyValue(_rConvertedValue, _rOldValue, _rValue, m_xLabelControl);
				if (!m_xLabelControl.is())
					// an empty interface is interpreted as VOID
					_rOldValue.clear();
			}
			break;
		default:
			bModified = OControlModel::convertFastPropertyValue(_rConvertedValue, _rOldValue, _nHandle, _rValue);
	}
	return bModified;
}

//------------------------------------------------------------------------------
Any OBoundControlModel::getPropertyDefaultByHandle( sal_Int32 _nHandle ) const
{
    Any aDefault;
    switch ( _nHandle )
    {
        case PROPERTY_ID_INPUT_REQUIRED:
			aDefault <<= sal_Bool( sal_True );
            break;

		case PROPERTY_ID_CONTROLSOURCE:
            aDefault <<= ::rtl::OUString();
			break;

        case PROPERTY_ID_CONTROLLABEL:
            aDefault <<= Reference< XPropertySet >();
            break;
    }
    return aDefault;
}

//------------------------------------------------------------------------------
void OBoundControlModel::setFastPropertyValue_NoBroadcast( sal_Int32 nHandle, const Any& rValue ) throw (Exception)
{
	switch (nHandle)
	{
        case PROPERTY_ID_INPUT_REQUIRED:
			OSL_VERIFY( rValue >>= m_bInputRequired );
            break;
		case PROPERTY_ID_CONTROLSOURCE:
			OSL_VERIFY( rValue >>= m_aControlSource );
			break;
		case PROPERTY_ID_BOUNDFIELD:
			DBG_ERROR("OBoundControlModel::setFastPropertyValue_NoBroadcast : BoundField should be a read-only property !");
            throw com::sun::star::lang::IllegalArgumentException();
		case PROPERTY_ID_CONTROLLABEL:
		{
            if ( rValue.hasValue() && ( rValue.getValueTypeClass() != TypeClass_INTERFACE ) )
				throw com::sun::star::lang::IllegalArgumentException();

            Reference< XInterface > xNewValue( rValue, UNO_QUERY );
			if ( !xNewValue.is() )
			{	// set property to "void"
                Reference< XComponent > xComp( m_xLabelControl, UNO_QUERY );
				if ( xComp.is() )
                    xComp->removeEventListener( static_cast< XPropertyChangeListener* >( this ) );
				m_xLabelControl = NULL;
				break;
			}

            Reference< XControlModel >  xAsModel        ( xNewValue,        UNO_QUERY );
            Reference< XServiceInfo >   xAsServiceInfo  ( xAsModel,         UNO_QUERY );
            Reference< XPropertySet >   xAsPropSet      ( xAsServiceInfo,   UNO_QUERY );
            Reference< XChild >         xAsChild        ( xAsPropSet,       UNO_QUERY );
            if ( !xAsChild.is() || !xAsServiceInfo->supportsService( m_aLabelServiceName ) )
            {
				throw com::sun::star::lang::IllegalArgumentException();
            }

			// check if weself and the given model have a common anchestor (up to the forms collection)
            Reference<XChild> xCont;
            query_interface(static_cast<XWeak*>(this), xCont);
			Reference< XInterface > xMyTopLevel = xCont->getParent();
			while (xMyTopLevel.is())
			{
                Reference<XForm> xAsForm(xMyTopLevel, UNO_QUERY);
				if (!xAsForm.is())
					// found my root
					break;

                Reference<XChild> xLoopAsChild(xMyTopLevel, UNO_QUERY);
				xMyTopLevel = xLoopAsChild.is() ? xLoopAsChild->getParent() : Reference< XInterface >();
			}
			Reference< XInterface > xNewTopLevel = xAsChild->getParent();
			while (xNewTopLevel.is())
			{
                Reference<XForm> xAsForm(xNewTopLevel, UNO_QUERY);
				if (!xAsForm.is())
					break;

                Reference<XChild> xLoopAsChild(xNewTopLevel, UNO_QUERY);
				xNewTopLevel = xLoopAsChild.is() ? xLoopAsChild->getParent() : Reference< XInterface >();
			}
			if (xNewTopLevel != xMyTopLevel)
			{
				// the both objects don't belong to the same forms collection -> not acceptable
                throw com::sun::star::lang::IllegalArgumentException();
			}

			m_xLabelControl = xAsPropSet;
            Reference<com::sun::star::lang::XComponent> xComp(m_xLabelControl, UNO_QUERY);
			if (xComp.is())
                xComp->addEventListener(static_cast<com::sun::star::lang::XEventListener*>(static_cast<XPropertyChangeListener*>(this)));
		}
		break;
		default:
			OControlModel::setFastPropertyValue_NoBroadcast(nHandle, rValue );
	}
}

// XPropertyChangeListener
//------------------------------------------------------------------------------
void SAL_CALL OBoundControlModel::propertyChange( const PropertyChangeEvent& evt ) throw(RuntimeException)
{
	// if the DBColumn value changed, transfer it to the control
	if ( evt.PropertyName.equals( PROPERTY_VALUE ) )
	{
        OSL_ENSURE( evt.Source == getField(), "OBoundControlModel::propertyChange: value changes from components other than our database column?" );
		osl::MutexGuard aGuard(m_aMutex);
		if ( m_bForwardValueChanges && m_xColumn.is() )
			transferDbValueToControl();
	}
    else
    {
        OSL_ENSURE( evt.Source == m_xExternalBinding, "OBoundControlModel::propertyChange: where did this come from?" );

        // our binding has properties which can control properties of ourself 
        ::rtl::OUString sBindingControlledProperty;
        bool bForwardToLabelControl = false;
        if ( evt.PropertyName.equals( PROPERTY_READONLY ) )
        {
            sBindingControlledProperty = PROPERTY_READONLY;
        }
        else if ( evt.PropertyName.equals( PROPERTY_RELEVANT ) )
        {
            sBindingControlledProperty = PROPERTY_ENABLED;
            bForwardToLabelControl = true;
        }
        else
            return;

        try
        {
            setPropertyValue( sBindingControlledProperty, evt.NewValue );
            if ( bForwardToLabelControl && m_xLabelControl.is() )
                m_xLabelControl->setPropertyValue( sBindingControlledProperty, evt.NewValue );
        }
        catch( const Exception& )
        {
        	OSL_ENSURE( sal_False, "OBoundControlModel::propertyChange: could not adjust my binding-controlled property!" );
        }
    }
}

//------------------------------------------------------------------------------
void SAL_CALL OBoundControlModel::onRowSetChanged( const EventObject& /*i_Event*/ ) throw (RuntimeException)
{
    ControlModelLock aLock( *this );
    FieldChangeNotifier aBoundFieldNotifier( aLock );

    // disconnect from database column (which is controlled by parent, directly or indirectly)
    if ( hasField() )
        impl_disconnectDatabaseColumn_noNotify();

	// log off old listeners
    if ( isFormListening() )
        doFormListening( false );

    // determine the new ambient form
    impl_determineAmbientForm_nothrow();

    // log on new listeners
    doFormListening( true );

    // re-connect to database column if needed and possible
    if ( m_xAmbientForm.is() && m_xAmbientForm->isLoaded() )
        impl_connectDatabaseColumn_noNotify( false );
}

// XBoundComponent
//------------------------------------------------------------------------------
void SAL_CALL OBoundControlModel::addUpdateListener(const Reference<XUpdateListener>& _rxListener) throw(RuntimeException)
{
	m_aUpdateListeners.addInterface(_rxListener);
}

//------------------------------------------------------------------------------
void SAL_CALL OBoundControlModel::removeUpdateListener(const Reference< XUpdateListener>& _rxListener) throw(RuntimeException)
{
	m_aUpdateListeners.removeInterface(_rxListener);
}

//------------------------------------------------------------------------------
sal_Bool SAL_CALL OBoundControlModel::commit() throw(RuntimeException)
{
    ControlModelLock aLock( *this );

    OSL_PRECOND( m_bCommitable, "OBoundControlModel::commit: invalid call (I'm not commitable !) " );
    if ( hasExternalValueBinding() )
    {
        // in most cases, no action is required: For most derivees, we know the value property of
        // our control (see initValueProperty), and when an external binding is active, we
        // instantly forward all changes in this property to the external binding.
        if ( !m_sValuePropertyName.getLength() )
            // but for those derivees which did not use this feature, we need an
            // explicit transfer
            transferControlValueToExternal( aLock );
        return sal_True;
    }

    OSL_ENSURE( !hasExternalValueBinding(), "OBoundControlModel::commit: control flow broken!" );
        // we reach this only if we're not working with an external binding

	if ( !hasField() )
		return sal_True;

    ::cppu::OInterfaceIteratorHelper aIter( m_aUpdateListeners );
    EventObject aEvent;
    aEvent.Source = static_cast< XWeak* >( this );
	sal_Bool bSuccess = sal_True;

    aLock.release();
    // >>>>>>>> ----- UNSAFE ----- >>>>>>>>
	while (aIter.hasMoreElements() && bSuccess)
        bSuccess = static_cast< XUpdateListener* >( aIter.next() )->approveUpdate( aEvent );
    // <<<<<<<< ----- UNSAFE ----- <<<<<<<<
    aLock.acquire();

	if ( bSuccess )
	{
		try
		{
            if ( m_xColumnUpdate.is() )
                bSuccess = commitControlValueToDbColumn( sal_False );
		}
		catch(Exception&)
		{
			bSuccess = sal_False;
		}
	}

	if ( bSuccess )
    {
        aLock.release();
        m_aUpdateListeners.notifyEach( &XUpdateListener::updated, aEvent );
    }

	return bSuccess;
}

//------------------------------------------------------------------------------
void OBoundControlModel::resetField()
{
    m_xColumnUpdate.clear();
    m_xColumn.clear();
    m_xField.clear();
    m_nFieldType = DataType::OTHER;
}

//------------------------------------------------------------------------------
sal_Bool OBoundControlModel::connectToField(const Reference<XRowSet>& rForm)
{
    OSL_PRECOND( !hasExternalValueBinding(), "OBoundControlModel::connectToField: invalid call (have an external binding)!" );

	// wenn eine Verbindung zur Datenbank existiert
	if (rForm.is() && getConnection(rForm).is())
	{
		// Feld bestimmen und PropertyChangeListener
		m_xCursor = rForm;
        Reference<XPropertySet> xFieldCandidate;

		if (m_xCursor.is())
		{
            Reference<XColumnsSupplier> xColumnsSupplier(m_xCursor, UNO_QUERY);
			DBG_ASSERT(xColumnsSupplier.is(), "OBoundControlModel::connectToField : the row set should support the com::sun::star::sdb::ResultSet service !");
			if (xColumnsSupplier.is())
			{
                Reference<XNameAccess> xColumns(xColumnsSupplier->getColumns(), UNO_QUERY);
				if (xColumns.is() && xColumns->hasByName(m_aControlSource))
				{
					OSL_VERIFY( xColumns->getByName(m_aControlSource) >>= xFieldCandidate );
				}
			}
		}

        try
        {
            sal_Int32 nFieldType = DataType::OTHER;
		    if ( xFieldCandidate.is() )
		    {
			    xFieldCandidate->getPropertyValue( PROPERTY_FIELDTYPE ) >>= nFieldType;
			    if ( approveDbColumnType( nFieldType ) )
			        impl_setField_noNotify( xFieldCandidate );
            }
            else
                impl_setField_noNotify( NULL );

            if ( m_xField.is() )
            {
			    if( m_xField->getPropertySetInfo()->hasPropertyByName( PROPERTY_VALUE ) )
			    {
                    m_nFieldType = nFieldType;

				    // an wertaenderungen horchen
				    m_xField->addPropertyChangeListener( PROPERTY_VALUE, this );
                    m_xColumnUpdate = Reference< XColumnUpdate >( m_xField, UNO_QUERY );
                    m_xColumn = Reference< XColumn >( m_xField, UNO_QUERY );

                    sal_Int32 nNullableFlag = ColumnValue::NO_NULLS;
                    m_xField->getPropertyValue(PROPERTY_ISNULLABLE) >>= nNullableFlag;
				    m_bRequired = (ColumnValue::NO_NULLS == nNullableFlag);
					    // we're optimistic : in case of ColumnValue_NULLABLE_UNKNOWN we assume nullability ....
			    }
			    else
			    {
				    OSL_ENSURE(sal_False, "OBoundControlModel::connectToField: property NAME not supported!");
				    impl_setField_noNotify( NULL );
			    }
            }
        }
        catch( const Exception& )
        {
        	DBG_UNHANDLED_EXCEPTION();
            resetField();
        }
	}
	return hasField();
}

//------------------------------------------------------------------------------
void OBoundControlModel::initFromField( const Reference< XRowSet >& _rxRowSet )
{
	// but only if the rowset if posisitioned on a valid record
	if ( hasField() && _rxRowSet.is() )
	{
		if ( !_rxRowSet->isBeforeFirst() && !_rxRowSet->isAfterLast() )
			transferDbValueToControl();
        else
            // reset the field if the row set is empty
            // #i30661# / 2004-12-16 / frank.schoenheit@sun.com
            resetNoBroadcast();
	}
}

//------------------------------------------------------------------------------
sal_Bool OBoundControlModel::approveDbColumnType(sal_Int32 _nColumnType)
{
    OSL_PRECOND( !hasExternalValueBinding(), "OBoundControlModel::approveDbColumnType: invalid call (have an external binding)!" );

    if ((_nColumnType == DataType::BINARY) || (_nColumnType == DataType::VARBINARY)
		|| (_nColumnType == DataType::LONGVARBINARY) || (_nColumnType == DataType::OTHER)
		|| (_nColumnType == DataType::OBJECT) || (_nColumnType == DataType::DISTINCT)
		|| (_nColumnType == DataType::STRUCT) || (_nColumnType == DataType::ARRAY)
		|| (_nColumnType == DataType::BLOB) /*|| (_nColumnType == DataType::CLOB)*/
		|| (_nColumnType == DataType::REF) || (_nColumnType == DataType::SQLNULL))
		return sal_False;

	return sal_True;
}

//------------------------------------------------------------------------------
void OBoundControlModel::impl_determineAmbientForm_nothrow()
{
    Reference< XInterface > xParent( const_cast< OBoundControlModel* >( this )->getParent() );

    m_xAmbientForm.set( xParent, UNO_QUERY );
    if ( !m_xAmbientForm.is() )
    {
        Reference< XRowSetSupplier > xSupRowSet( xParent, UNO_QUERY );
        if ( xSupRowSet.is() )
            m_xAmbientForm.set( xSupRowSet->getRowSet(), UNO_QUERY );
    }
}

//------------------------------------------------------------------------------
void OBoundControlModel::impl_connectDatabaseColumn_noNotify( bool _bFromReload )
{
    OSL_PRECOND( !hasExternalValueBinding(), "OBoundControlModel::impl_connectDatabaseColumn_noNotify: not to be called with an external value binding!" );

    // consistency checks
    DBG_ASSERT( !( hasField() && !_bFromReload ),
        "OBoundControlModel::impl_connectDatabaseColumn_noNotify: the form is just *loaded*, but we already have a field!" );
    (void)_bFromReload;

    Reference< XRowSet > xRowSet( m_xAmbientForm, UNO_QUERY );
    OSL_ENSURE( xRowSet.is(), "OBoundControlModel::impl_connectDatabaseColumn_noNotify: no row set!" );
    if ( !xRowSet.is() )
        return;

	if ( !hasField() )
	{
        // connect to the column
	    connectToField( xRowSet );
    }

    // now that we're connected (more or less, even if we did not find a column),
    // we definitely want to forward any potentially occurring value changes
    m_bForwardValueChanges = sal_True;

    // let derived classes react on this new connection
	m_bLoaded = sal_True;
	onConnectedDbColumn( xRowSet );

    // initially transfer the db column value to the control, if we successfully connected to a database column
	if ( hasField() )
        initFromField( xRowSet );
}

//------------------------------------------------------------------------------
void OBoundControlModel::impl_disconnectDatabaseColumn_noNotify()
{
    OSL_PRECOND( !hasExternalValueBinding(), "OBoundControlModel::impl_disconnectDatabaseColumn_noNotify: not to be called with an external value binding!" );

    // let derived classes react on this
    onDisconnectedDbColumn();

	if ( hasField() )
	{
		getField()->removePropertyChangeListener( PROPERTY_VALUE, this );
		resetField();
	}

    m_xCursor = NULL;
	m_bLoaded = sal_False;
}

//==============================================================================
// XLoadListener
//------------------------------------------------------------------------------
void SAL_CALL OBoundControlModel::loaded( const EventObject& _rEvent ) throw(RuntimeException)
{
    ControlModelLock aLock( *this );
    FieldChangeNotifier aBoundFieldNotifier( aLock );

    OSL_ENSURE( _rEvent.Source == m_xAmbientForm, "OBoundControlModel::loaded: where does this come from?" );
    (void)_rEvent;

    OSL_PRECOND( !hasExternalValueBinding(), "OBoundControlModel::loaded: we should never reach this with an external value binding!" );
    if ( hasExternalValueBinding() )
        return;

    impl_connectDatabaseColumn_noNotify( false );
}


//------------------------------------------------------------------------------
void SAL_CALL OBoundControlModel::unloaded( const com::sun::star::lang::EventObject& /*aEvent*/ ) throw(RuntimeException)
{
    OSL_PRECOND( !hasExternalValueBinding(), "OBoundControlModel::unloaded: we should never reach this with an external value binding!" );
}

//------------------------------------------------------------------------------
void SAL_CALL OBoundControlModel::reloading( const com::sun::star::lang::EventObject& /*aEvent*/ ) throw(RuntimeException)
{
    OSL_PRECOND( !hasExternalValueBinding(), "OBoundControlModel::reloading: we should never reach this with an external value binding!" );
    if ( hasExternalValueBinding() )
        return;

	osl::MutexGuard aGuard(m_aMutex);
	m_bForwardValueChanges = sal_False;
}

//------------------------------------------------------------------------------
void SAL_CALL OBoundControlModel::unloading(const com::sun::star::lang::EventObject& /*aEvent*/) throw(RuntimeException)
{
    ControlModelLock aLock( *this );
    FieldChangeNotifier aBoundFieldNotifier( aLock );

    OSL_PRECOND( !hasExternalValueBinding(), "OBoundControlModel::unloading: we should never reach this with an external value binding!" );
    if ( hasExternalValueBinding() )
        return;

    impl_disconnectDatabaseColumn_noNotify();
}

//------------------------------------------------------------------------------
void SAL_CALL OBoundControlModel::reloaded( const EventObject& _rEvent ) throw(RuntimeException)
{
    ControlModelLock aLock( *this );
    FieldChangeNotifier aBoundFieldNotifier( aLock );

    OSL_ENSURE( _rEvent.Source == m_xAmbientForm, "OBoundControlModel::reloaded: where does this come from?" );
    (void)_rEvent;

    OSL_PRECOND( !hasExternalValueBinding(), "OBoundControlModel::reloaded: we should never reach this with an external value binding!" );
    if ( hasExternalValueBinding() )
        return;

    impl_connectDatabaseColumn_noNotify( true );
}

//------------------------------------------------------------------------------
void OBoundControlModel::setControlValue( const Any& _rValue, ValueChangeInstigator _eInstigator )
{
	m_eControlValueChangeInstigator = _eInstigator;
    doSetControlValue( _rValue );
	m_eControlValueChangeInstigator = eOther;
}

//------------------------------------------------------------------------------
void OBoundControlModel::doSetControlValue( const Any& _rValue )
{
	OSL_PRECOND( m_xAggregateFastSet.is() && m_xAggregateSet.is(),
        "OBoundControlModel::doSetControlValue: invalid aggregate !" );
    OSL_PRECOND( m_sValuePropertyName.getLength() || ( m_nValuePropertyAggregateHandle != -1 ),
        "OBoundControlModel::doSetControlValue: please override if you have own value property handling!" );

    try
    {
        // release our mutex once (it's acquired in one of the the calling methods), as setting aggregate properties
	    // may cause any uno controls belonging to us to lock the solar mutex, which is potentially dangerous with
	    // our own mutex locked
	    // #72451# / 2000-01-31 / frank.schoenheit@sun.com
        MutexRelease aRelease( m_aMutex );
        if ( ( m_nValuePropertyAggregateHandle != -1 ) && m_xAggregateFastSet.is() )
        {
            m_xAggregateFastSet->setFastPropertyValue( m_nValuePropertyAggregateHandle, _rValue );
        }
        else if ( m_sValuePropertyName.getLength() && m_xAggregateSet.is() )
        {
            m_xAggregateSet->setPropertyValue( m_sValuePropertyName, _rValue );
        }
    }
    catch( const Exception& )
    {
    	OSL_ENSURE( sal_False, "OBoundControlModel::doSetControlValue: caught an exception!" );
    }
}

//------------------------------------------------------------------------------
void OBoundControlModel::onConnectedValidator( )
{
    try
    {
        // if we have an external validator, we do not want the control to force invalid
        // inputs to the default value. Instead, invalid inputs should be translated
        // to NaN (not a number)
        Reference< XPropertySetInfo > xAggregatePropertyInfo;
        if ( m_xAggregateSet.is() )
            xAggregatePropertyInfo = m_xAggregateSet->getPropertySetInfo();
        if ( xAggregatePropertyInfo.is() && xAggregatePropertyInfo->hasPropertyByName( PROPERTY_ENFORCE_FORMAT ) )
            m_xAggregateSet->setPropertyValue( PROPERTY_ENFORCE_FORMAT, makeAny( (sal_Bool)sal_False ) );
    }
    catch( const Exception& )
    {
    	OSL_ENSURE( sal_False, "OBoundControlModel::onConnectedValidator: caught an exception!" );
    }
    recheckValidity( false );
}

//------------------------------------------------------------------------------
void OBoundControlModel::onDisconnectedValidator( )
{
    try
    {
        Reference< XPropertySetInfo > xAggregatePropertyInfo;
        if ( m_xAggregateSet.is() )
            xAggregatePropertyInfo = m_xAggregateSet->getPropertySetInfo();
        if ( xAggregatePropertyInfo.is() && xAggregatePropertyInfo->hasPropertyByName( PROPERTY_ENFORCE_FORMAT ) )
            m_xAggregateSet->setPropertyValue( PROPERTY_ENFORCE_FORMAT, makeAny( (sal_Bool)sal_True ) );
    }
    catch( const Exception& )
    {
    	OSL_ENSURE( sal_False, "OBoundControlModel::onDisconnectedValidator: caught an exception!" );
    }
    recheckValidity( false );
}

//------------------------------------------------------------------------------
void OBoundControlModel::onConnectedExternalValue( )
{
    calculateExternalValueType();
}

//------------------------------------------------------------------------------
void OBoundControlModel::onDisconnectedExternalValue( )
{
}

//------------------------------------------------------------------------------
void OBoundControlModel::onConnectedDbColumn( const Reference< XInterface >& /*_rxForm*/ )
{
    OSL_PRECOND( !hasExternalValueBinding(), "OBoundControlModel::onConnectedDbColumn: how this? There's an external value binding!" );
}

//------------------------------------------------------------------------------
void OBoundControlModel::onDisconnectedDbColumn()
{
    OSL_PRECOND( !hasExternalValueBinding(), "OBoundControlModel::onDisconnectedDbColumn: how this? There's an external value binding!" );
}

// XReset
//-----------------------------------------------------------------------------
Any OBoundControlModel::getDefaultForReset() const
{
    return Any();
}

//-----------------------------------------------------------------------------
void OBoundControlModel::resetNoBroadcast()
{
    setControlValue( getDefaultForReset(), eOther );
}

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

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

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

    ControlModelLock aLock( *this );

    // on a new record?
    sal_Bool bIsNewRecord = sal_False;
	Reference<XPropertySet> xSet( m_xCursor, UNO_QUERY );
    if ( xSet.is() )
    {
        try
        {
		    xSet->getPropertyValue( PROPERTY_ISNEW ) >>= bIsNewRecord;
        }
        catch( const Exception& )
        {
            DBG_UNHANDLED_EXCEPTION();
        }
    }

    // cursor on an invalid row?
    sal_Bool bInvalidCursorPosition = sal_True;
    try
    {
        bInvalidCursorPosition =    m_xCursor.is()
                                &&  (  m_xCursor->isAfterLast()
                                    || m_xCursor->isBeforeFirst()
                                    )
                                &&  !bIsNewRecord;
    }
    catch( const SQLException& )
    {
        OSL_ENSURE( sal_False, "OBoundControlModel::reset: caught an SQL exception!" );
    }
    // don't count the insert row as "invalid"
    // @since  #i24495#
    // @date   2004-05-14
    // @author fs@openoffice.org

	sal_Bool bSimpleReset =
                        (   !m_xColumn.is()						// no connection to a database column
						||	(	m_xCursor.is()					// OR	we have an improperly positioned cursor
							&&	bInvalidCursorPosition
							)
                        ||  hasExternalValueBinding()           // OR we have an external value binding
                        );

	if ( !bSimpleReset )
	{
		// The default values will be set if and only if the current value of the field which we're bound
		// to is NULL.
		// Else, the current field value should be refreshed
		// This behaviour is not completely ... "matured": What should happen if the field as well as the
		// control have a default value?

		sal_Bool bIsNull = sal_True;
		// we have to access the field content at least once to get a reliable result by XColumn::wasNull
		try
		{
            // normally, we'd do a getString here. However, this is extremely expensive in the case
            // of binary fields. Unfortunately, getString is the only method which is guaranteed
            // to *always* succeed, all other getXXX methods may fail if the column is asked for a
            // non-convertible type
            sal_Int32 nFieldType = DataType::OBJECT;
            getField()->getPropertyValue( PROPERTY_FIELDTYPE ) >>= nFieldType;
            if  (  ( nFieldType == DataType::BINARY        )
                || ( nFieldType == DataType::VARBINARY     )
                || ( nFieldType == DataType::LONGVARBINARY )
                || ( nFieldType == DataType::OBJECT        )
                /*|| ( nFieldType == DataType::CLOB          )*/
                )
                m_xColumn->getBinaryStream();
            else if ( nFieldType == DataType::BLOB          )
                m_xColumn->getBlob();
            else
                m_xColumn->getString();

            bIsNull = m_xColumn->wasNull();
		}
		catch(Exception&)
		{
			DBG_ERROR("OBoundControlModel::reset: this should have succeeded in all cases!");
		}

        sal_Bool bNeedValueTransfer = sal_True;

		if ( bIsNull )
		{
            if ( bIsNewRecord )
			{
                // reset the control to it's default
				resetNoBroadcast();
                // and immediately commit the changes to the DB column, to keep consistency
                commitControlValueToDbColumn( sal_True );

                bNeedValueTransfer = sal_False;
			}
		}

        if ( bNeedValueTransfer )
			transferDbValueToControl();
	}
	else
    {
		resetNoBroadcast();

        // transfer to the external binding, if necessary
        if ( hasExternalValueBinding() )
            transferControlValueToExternal( aLock );
    }

    // revalidate, if necessary
    if ( hasValidator() )
        recheckValidity( true );

    aLock.release();

    m_aResetHelper.notifyResetted();
}

// -----------------------------------------------------------------------------
void OBoundControlModel::impl_setField_noNotify( const Reference< XPropertySet>& _rxField )
{
    DBG_ASSERT( !hasExternalValueBinding(), "OBoundControlModel::impl_setField_noNotify: We have an external value binding!" );
	m_xField = _rxField;
}

//--------------------------------------------------------------------
sal_Bool OBoundControlModel::impl_approveValueBinding_nolock( const Reference< XValueBinding >& _rxBinding )
{
    if ( !_rxBinding.is() )
        return sal_False;

    Sequence< Type > aTypeCandidates;
    {
        // SYNCHRONIZED -->
        ::osl::MutexGuard aGuard( m_aMutex );
        aTypeCandidates = getSupportedBindingTypes();
        // <-- SYNCHRONIZED
    }

    for (   const Type* pType = aTypeCandidates.getConstArray();
            pType != aTypeCandidates.getConstArray() + aTypeCandidates.getLength();
            ++pType
        )
    {
        if ( _rxBinding->supportsType( *pType ) )
            return sal_True;
    }

    return sal_False;
}

//--------------------------------------------------------------------
void OBoundControlModel::connectExternalValueBinding(
        const Reference< XValueBinding >& _rxBinding, ControlModelLock& _rInstanceLock )
{
    OSL_PRECOND( _rxBinding.is(), "OBoundControlModel::connectExternalValueBinding: invalid binding instance!" );
    OSL_PRECOND( !hasExternalValueBinding( ), "OBoundControlModel::connectExternalValueBinding: precond not met (currently have a binding)!" );

    // if we're connected to a database column, suspend this
    if ( hasField() )
        impl_disconnectDatabaseColumn_noNotify();

    // suspend listening for load-related events at out ambient form.
    // This is because an external value binding overrules a possible database binding.
    if ( isFormListening() )
        doFormListening( false );

    // remember this new binding
    m_xExternalBinding = _rxBinding;

    // tell the derivee
    onConnectedExternalValue();

    try
    {
        // add as value listener so we get notified when the value changes
        Reference< XModifyBroadcaster > xModifiable( m_xExternalBinding, UNO_QUERY );
        if ( xModifiable.is() )
            xModifiable->addModifyListener( this );

        // add as property change listener for some (possibly present) properties we're
        // interested in
        Reference< XPropertySet > xBindingProps( m_xExternalBinding, UNO_QUERY );
        Reference< XPropertySetInfo > xBindingPropsInfo( xBindingProps.is() ? xBindingProps->getPropertySetInfo() : Reference< XPropertySetInfo >() );
        if ( xBindingPropsInfo.is() )
        {
            if ( xBindingPropsInfo->hasPropertyByName( PROPERTY_READONLY ) )
            {
                xBindingProps->addPropertyChangeListener( PROPERTY_READONLY, this );
                m_bBindingControlsRO = sal_True;
            }
            if ( xBindingPropsInfo->hasPropertyByName( PROPERTY_RELEVANT ) )
            {
                xBindingProps->addPropertyChangeListener( PROPERTY_RELEVANT, this );
                m_bBindingControlsEnable = sal_True;
            }
        }
    }
    catch( const Exception& )
    {
        DBG_UNHANDLED_EXCEPTION();
    }

    // propagate our new value
    transferExternalValueToControl( _rInstanceLock );

    // if the binding is also a validator, use it, too. This is a constraint of the
    // com.sun.star.form.binding.ValidatableBindableFormComponent service
    if ( m_bSupportsValidation )
    {
        try
        {
            Reference< XValidator > xAsValidator( _rxBinding, UNO_QUERY );
            if ( xAsValidator.is() )
                setValidator( xAsValidator );
        }
        catch( const Exception& )
        {
            DBG_UNHANDLED_EXCEPTION();
        }
    }
}

//--------------------------------------------------------------------
void OBoundControlModel::disconnectExternalValueBinding( )
{
    try
    {
        // not listening at the binding anymore
        Reference< XModifyBroadcaster > xModifiable( m_xExternalBinding, UNO_QUERY );
        if ( xModifiable.is() )
            xModifiable->removeModifyListener( this );

        // remove as property change listener
        Reference< XPropertySet > xBindingProps( m_xExternalBinding, UNO_QUERY );
        if ( m_bBindingControlsRO )
            xBindingProps->removePropertyChangeListener( PROPERTY_READONLY, this );
        if ( m_bBindingControlsEnable )
            xBindingProps->removePropertyChangeListener( PROPERTY_RELEVANT, this );
    }
    catch( const Exception& )
    {
    	OSL_ENSURE( sal_False, "OBoundControlModel::disconnectExternalValueBinding: caught an exception!" );
    }

    // if the binding also acts as our validator, disconnect the validator, too
    if ( ( m_xExternalBinding == m_xValidator ) && m_xValidator.is() )
        disconnectValidator( );

    // no binding anymore
    m_xExternalBinding.clear();

    // be a load listener at our form, again. This was suspended while we had
    // an external value binding in place.
    doFormListening( true );

    // re-connect to database column of the new parent
    if ( m_xAmbientForm.is() && m_xAmbientForm->isLoaded() )
        impl_connectDatabaseColumn_noNotify( false );

    // tell the derivee
    onDisconnectedExternalValue();
}

//--------------------------------------------------------------------
void SAL_CALL OBoundControlModel::setValueBinding( const Reference< XValueBinding >& _rxBinding ) throw (IncompatibleTypesException, RuntimeException)
{
    OSL_PRECOND( m_bSupportsExternalBinding, "OBoundControlModel::setValueBinding: How did you reach this method?" );
        // the interface for this method should not have been exposed if we do not
        // support binding to external data

    if ( !impl_approveValueBinding_nolock( _rxBinding ) )
    {
        throw IncompatibleTypesException(
            FRM_RES_STRING( RID_STR_INCOMPATIBLE_TYPES ),
            *this
        );
    }

    ControlModelLock aLock( *this );

    // since a ValueBinding overrules any potentially active database binding, the change in a ValueBinding
    // might trigger a change in our BoundField.
    FieldChangeNotifier aBoundFieldNotifier( aLock );

    // disconnect from the old binding
    if ( hasExternalValueBinding() )
        disconnectExternalValueBinding( );

    // connect to the new binding
    if ( _rxBinding.is() )
        connectExternalValueBinding( _rxBinding, aLock );
}

//--------------------------------------------------------------------
Reference< XValueBinding > SAL_CALL OBoundControlModel::getValueBinding(  ) throw (RuntimeException)
{
    ::osl::MutexGuard aGuard( m_aMutex );
    OSL_PRECOND( m_bSupportsExternalBinding, "OBoundControlModel::getValueBinding: How did you reach this method?" );
        // the interface for this method should not have been exposed if we do not
        // support binding to external data

    return m_xExternalBinding;
}

//--------------------------------------------------------------------
void SAL_CALL OBoundControlModel::modified( const EventObject& _rEvent ) throw ( RuntimeException )
{
    ControlModelLock aLock( *this );

    OSL_PRECOND( hasExternalValueBinding(), "OBoundControlModel::modified: Where did this come from?" );
    if ( !m_bTransferingValue && ( m_xExternalBinding == _rEvent.Source ) && m_xExternalBinding.is() )
    {
        transferExternalValueToControl( aLock );
    }
}

//--------------------------------------------------------------------
void OBoundControlModel::transferDbValueToControl( )
{
    try
    {
        setControlValue( translateDbColumnToControlValue(), eDbColumnBinding );
    }
    catch( const Exception& )
    {
    	DBG_UNHANDLED_EXCEPTION();
    }
}

//------------------------------------------------------------------------------
void OBoundControlModel::transferExternalValueToControl( ControlModelLock& _rInstanceLock )
{
        Reference< XValueBinding > xExternalBinding( m_xExternalBinding );
        Type aValueExchangeType( getExternalValueType() );

        _rInstanceLock.release();
        // >>>>>>>> ----- UNSAFE ----- >>>>>>>>
        Any aExternalValue;
        try
        {
            aExternalValue = xExternalBinding->getValue( aValueExchangeType );
        }
        catch( const Exception& )
        {
            DBG_UNHANDLED_EXCEPTION();
        }
        // <<<<<<<< ----- UNSAFE ----- <<<<<<<<
        _rInstanceLock.acquire();

        setControlValue( translateExternalValueToControlValue( aExternalValue ), eExternalBinding );
}

//------------------------------------------------------------------------------
void OBoundControlModel::transferControlValueToExternal( ControlModelLock& _rInstanceLock )
{
    OSL_PRECOND( m_bSupportsExternalBinding && hasExternalValueBinding(),
        "OBoundControlModel::transferControlValueToExternal: precondition not met!" );

    if ( m_xExternalBinding.is() )
    {
        Any aExternalValue( translateControlValueToExternalValue() );
        m_bTransferingValue = sal_True;

        _rInstanceLock.release();
         // >>>>>>>> ----- UNSAFE ----- >>>>>>>>
        try
        {
            m_xExternalBinding->setValue( aExternalValue );
        }
        catch( const Exception& )
        {
        	DBG_UNHANDLED_EXCEPTION();
        }
        // <<<<<<<< ----- UNSAFE ----- <<<<<<<<
        _rInstanceLock.acquire();

        m_bTransferingValue = sal_False;
    }
}

// -----------------------------------------------------------------------------
Sequence< Type > OBoundControlModel::getSupportedBindingTypes()
{
    return Sequence< Type >( &m_aValuePropertyType, 1 );
}

//-----------------------------------------------------------------------------
void OBoundControlModel::calculateExternalValueType()
{
    m_aExternalValueType = Type();
    if ( !m_xExternalBinding.is() )
        return;

    Sequence< Type > aTypeCandidates( getSupportedBindingTypes() );
    for (   const Type* pTypeCandidate = aTypeCandidates.getConstArray();
            pTypeCandidate != aTypeCandidates.getConstArray() + aTypeCandidates.getLength();
            ++pTypeCandidate
        )
    {
        if ( m_xExternalBinding->supportsType( *pTypeCandidate ) )
        {
            m_aExternalValueType = *pTypeCandidate;
            break;
        }
    }
}

//-----------------------------------------------------------------------------
Any OBoundControlModel::translateExternalValueToControlValue( const Any& _rExternalValue ) const
{
    OSL_PRECOND( m_bSupportsExternalBinding && hasExternalValueBinding(),
        "OBoundControlModel::translateExternalValueToControlValue: precondition not met!" );

    Any aControlValue( _rExternalValue );

    // if the external value is VOID, and our value property is not allowed to be VOID,
    // then default-construct a value
    if ( !aControlValue.hasValue() && !m_bValuePropertyMayBeVoid )
        aControlValue.setValue( NULL, m_aValuePropertyType );

    // outta here
    return aControlValue;
}

//------------------------------------------------------------------------------
Any OBoundControlModel::translateControlValueToExternalValue( ) const
{
    return getControlValue( );
}

//------------------------------------------------------------------------------
Any OBoundControlModel::translateControlValueToValidatableValue( ) const
{
    OSL_PRECOND( m_xValidator.is(), "OBoundControlModel::translateControlValueToValidatableValue: no validator, so why should I?" );
    if ( ( m_xValidator == m_xExternalBinding ) && m_xValidator.is() )
        return translateControlValueToExternalValue();
    return getControlValue();
}

//------------------------------------------------------------------------------
Any OBoundControlModel::getControlValue( ) const
{
	OSL_PRECOND( m_xAggregateFastSet.is() && m_xAggregateSet.is(),
        "OBoundControlModel::getControlValue: invalid aggregate !" );
    OSL_PRECOND( m_sValuePropertyName.getLength() || ( m_nValuePropertyAggregateHandle != -1 ),
        "OBoundControlModel::getControlValue: please override if you have own value property handling!" );

    // determine the current control value
    Any aControlValue;
    if ( ( m_nValuePropertyAggregateHandle != -1 ) && m_xAggregateFastSet.is() )
    {
        aControlValue = m_xAggregateFastSet->getFastPropertyValue( m_nValuePropertyAggregateHandle );
    }
    else if ( m_sValuePropertyName.getLength() && m_xAggregateSet.is() )
    {
        aControlValue = m_xAggregateSet->getPropertyValue( m_sValuePropertyName );
    }

    return aControlValue;
}

//--------------------------------------------------------------------
void OBoundControlModel::connectValidator( const Reference< XValidator >& _rxValidator )
{
    OSL_PRECOND( _rxValidator.is(), "OBoundControlModel::connectValidator: invalid validator instance!" );
    OSL_PRECOND( !hasValidator( ), "OBoundControlModel::connectValidator: precond not met (have a validator currently)!" );

    m_xValidator = _rxValidator;

    // add as value listener so we get notified when the value changes
    if ( m_xValidator.is() )
    {
        try
        {
            m_xValidator->addValidityConstraintListener( this );
        }
        catch( const RuntimeException& )
        {
        }
    }

    onConnectedValidator( );
}

//--------------------------------------------------------------------
void OBoundControlModel::disconnectValidator( )
{
    OSL_PRECOND( hasValidator( ), "OBoundControlModel::connectValidator: precond not met (don't have a validator currently)!" );

    // add as value listener so we get notified when the value changes
    if ( m_xValidator.is() )
    {
        try
        {
            m_xValidator->removeValidityConstraintListener( this );
        }
        catch( const RuntimeException& )
        {
        }
    }

    m_xValidator.clear();

    onDisconnectedValidator( );
}

//--------------------------------------------------------------------
void SAL_CALL OBoundControlModel::setValidator( const Reference< XValidator >& _rxValidator ) throw (VetoException,RuntimeException)
{
    ::osl::ClearableMutexGuard aGuard( m_aMutex );
    OSL_PRECOND( m_bSupportsValidation, "OBoundControlModel::setValidator: How did you reach this method?" );
        // the interface for this method should not have been exposed if we do not
        // support validation

    // early out if the validator does not change
    if( _rxValidator == m_xValidator )
        return;

    if ( m_xValidator.is() && ( m_xValidator == m_xExternalBinding ) )
        throw VetoException(
            FRM_RES_STRING( RID_STR_INVALID_VALIDATOR ),
            *this
        );

    // disconnect from the old validator
    if ( hasValidator() )
        disconnectValidator( );

    // connect to the new validator
    if ( _rxValidator.is() )
        connectValidator( _rxValidator );
}

//--------------------------------------------------------------------
Reference< XValidator > SAL_CALL OBoundControlModel::getValidator(  ) throw (RuntimeException)
{
    ::osl::MutexGuard aGuard( m_aMutex );
    OSL_PRECOND( m_bSupportsValidation, "OBoundControlModel::getValidator: How did you reach this method?" );
        // the interface for this method should not have been exposed if we do not
        // support validation

    return m_xValidator;
}

//--------------------------------------------------------------------
void SAL_CALL OBoundControlModel::validityConstraintChanged( const EventObject& /*Source*/ ) throw (RuntimeException)
{
    ::osl::ClearableMutexGuard aGuard( m_aMutex );
    OSL_PRECOND( m_bSupportsValidation, "OBoundControlModel::validityConstraintChanged: How did you reach this method?" );
        // the interface for this method should not have been exposed if we do not
        // support validation

    recheckValidity( false );
}

//--------------------------------------------------------------------
sal_Bool SAL_CALL OBoundControlModel::isValid(  ) throw (RuntimeException)
{
    return m_bIsCurrentValueValid;
}

//--------------------------------------------------------------------
::com::sun::star::uno::Any OBoundControlModel::getCurrentFormComponentValue() const
{
    if ( hasValidator() )
        return translateControlValueToValidatableValue();
    return getControlValue();
}

//--------------------------------------------------------------------
Any SAL_CALL OBoundControlModel::getCurrentValue(  ) throw (RuntimeException)
{
    ::osl::MutexGuard aGuard( m_aMutex );
    return getCurrentFormComponentValue();
}

//--------------------------------------------------------------------
void SAL_CALL OBoundControlModel::addFormComponentValidityListener( const Reference< validation::XFormComponentValidityListener >& Listener ) throw (NullPointerException, RuntimeException)
{
    if ( Listener.is() )
        m_aFormComponentListeners.addInterface( Listener );
}

//--------------------------------------------------------------------
void SAL_CALL OBoundControlModel::removeFormComponentValidityListener( const Reference< validation::XFormComponentValidityListener >& Listener ) throw (NullPointerException, RuntimeException)
{
    if ( Listener.is() )
        m_aFormComponentListeners.removeInterface( Listener );
}

//--------------------------------------------------------------------
void OBoundControlModel::recheckValidity( bool _bForceNotification )
{
    try
    {
        sal_Bool bIsCurrentlyValid = sal_True;
        if ( hasValidator() )
            bIsCurrentlyValid = m_xValidator->isValid( translateControlValueToValidatableValue() );

        if ( ( bIsCurrentlyValid != m_bIsCurrentValueValid ) || _bForceNotification )
        {
            m_bIsCurrentValueValid = bIsCurrentlyValid;

            // release our mutex for the notifications
            MutexRelease aRelease( m_aMutex );
            m_aFormComponentListeners.notifyEach( &validation::XFormComponentValidityListener::componentValidityChanged, EventObject( *this ) );
        }
    }
    catch( const Exception& )
    {
    	OSL_ENSURE( sal_False, "OBoundControlModel::recheckValidity: caught an exception!" );
    }
}

//------------------------------------------------------------------------------
void OBoundControlModel::describeFixedProperties( Sequence< Property >& _rProps ) const
{
    BEGIN_DESCRIBE_PROPERTIES( 5, OControlModel )
        DECL_PROP1      ( CONTROLSOURCE,           ::rtl::OUString,     BOUND );
        DECL_IFACE_PROP3( BOUNDFIELD,               XPropertySet,       BOUND, READONLY, TRANSIENT );
        DECL_IFACE_PROP2( CONTROLLABEL,             XPropertySet,       BOUND, MAYBEVOID );
        DECL_PROP2      ( CONTROLSOURCEPROPERTY,    ::rtl::OUString,    READONLY, TRANSIENT );
        DECL_BOOL_PROP1 ( INPUT_REQUIRED,                               BOUND );
    END_DESCRIBE_PROPERTIES()
}

// -----------------------------------------------------------------------------

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

