LCOV - code coverage report
Current view: top level - forms/source/component - FormComponent.cxx (source / functions) Hit Total Coverage
Test: commit 10e77ab3ff6f4314137acd6e2702a6e5c1ce1fae Lines: 1009 1296 77.9 %
Date: 2014-11-03 Functions: 157 178 88.2 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
       2             : /*
       3             :  * This file is part of the LibreOffice project.
       4             :  *
       5             :  * This Source Code Form is subject to the terms of the Mozilla Public
       6             :  * License, v. 2.0. If a copy of the MPL was not distributed with this
       7             :  * file, You can obtain one at http://mozilla.org/MPL/2.0/.
       8             :  *
       9             :  * This file incorporates work covered by the following license notice:
      10             :  *
      11             :  *   Licensed to the Apache Software Foundation (ASF) under one or more
      12             :  *   contributor license agreements. See the NOTICE file distributed
      13             :  *   with this work for additional information regarding copyright
      14             :  *   ownership. The ASF licenses this file to you under the Apache
      15             :  *   License, Version 2.0 (the "License"); you may not use this file
      16             :  *   except in compliance with the License. You may obtain a copy of
      17             :  *   the License at http://www.apache.org/licenses/LICENSE-2.0 .
      18             :  */
      19             : #include "componenttools.hxx"
      20             : #include "FormComponent.hxx"
      21             : #include "frm_resource.hrc"
      22             : #include "frm_resource.hxx"
      23             : #include "property.hrc"
      24             : #include "services.hxx"
      25             : 
      26             : #include <com/sun/star/awt/XTextComponent.hpp>
      27             : #include <com/sun/star/awt/XVclWindowPeer.hpp>
      28             : #include <com/sun/star/awt/XWindow.hpp>
      29             : #include <com/sun/star/form/XForm.hpp>
      30             : #include <com/sun/star/form/XLoadable.hpp>
      31             : #include <com/sun/star/io/XMarkableStream.hpp>
      32             : #include <com/sun/star/lang/DisposedException.hpp>
      33             : #include <com/sun/star/lang/WrappedTargetRuntimeException.hpp>
      34             : #include <com/sun/star/sdb/XRowSetChangeBroadcaster.hpp>
      35             : #include <com/sun/star/sdb/XRowSetSupplier.hpp>
      36             : #include <com/sun/star/sdbc/ColumnValue.hpp>
      37             : #include <com/sun/star/sdbc/DataType.hpp>
      38             : #include <com/sun/star/util/XModifyBroadcaster.hpp>
      39             : 
      40             : #include <comphelper/basicio.hxx>
      41             : #include <comphelper/guarding.hxx>
      42             : #include <comphelper/listenernotification.hxx>
      43             : #include <comphelper/property.hxx>
      44             : #include <connectivity/dbtools.hxx>
      45             : #include <cppuhelper/exc_hlp.hxx>
      46             : #include <cppuhelper/queryinterface.hxx>
      47             : #include <cppuhelper/supportsservice.hxx>
      48             : #include <toolkit/helper/emptyfontdescriptor.hxx>
      49             : #include <tools/debug.hxx>
      50             : #include <tools/diagnose_ex.h>
      51             : 
      52             : #include <functional>
      53             : #include <algorithm>
      54             : 
      55             : namespace frm
      56             : {
      57             : using namespace ::com::sun::star::uno;
      58             : using namespace ::com::sun::star::sdb;
      59             : using namespace ::com::sun::star::sdbc;
      60             : using namespace ::com::sun::star::sdbcx;
      61             : using namespace ::com::sun::star::beans;
      62             : using namespace ::com::sun::star::container;
      63             : using namespace ::com::sun::star::form;
      64             : using namespace ::com::sun::star::awt;
      65             : using namespace ::com::sun::star::io;
      66             : using namespace ::com::sun::star::lang;
      67             : using namespace ::com::sun::star::util;
      68             : using namespace ::com::sun::star::form::binding;
      69             : using namespace ::com::sun::star::form::validation;
      70             : using namespace ::dbtools;
      71             : using namespace ::comphelper;
      72             : 
      73             : // FieldChangeNotifier
      74        2580 : void ControlModelLock::impl_notifyAll_nothrow()
      75             : {
      76        2580 :     m_rModel.firePropertyChanges( m_aHandles, m_aOldValues, m_aNewValues, OControlModel::LockAccess() );
      77        2580 : }
      78             : 
      79          62 : void ControlModelLock::addPropertyNotification( const sal_Int32 _nHandle, const Any& _rOldValue, const Any& _rNewValue )
      80             : {
      81          62 :     sal_Int32 nOldLength = m_aHandles.getLength();
      82         124 :     if  (   ( nOldLength != m_aOldValues.getLength() )
      83          62 :         ||  ( nOldLength != m_aNewValues.getLength() )
      84             :         )
      85           0 :         throw RuntimeException( OUString(), m_rModel );
      86             : 
      87          62 :     m_aHandles.realloc( nOldLength + 1 );
      88          62 :     m_aHandles[ nOldLength ] = _nHandle;
      89          62 :     m_aOldValues.realloc( nOldLength + 1 );
      90          62 :     m_aOldValues[ nOldLength ] = _rOldValue;
      91          62 :     m_aNewValues.realloc( nOldLength + 1 );
      92          62 :     m_aNewValues[ nOldLength ] = _rNewValue;
      93          62 : }
      94             : 
      95             : class FieldChangeNotifier
      96             : {
      97             : public:
      98        1370 :     FieldChangeNotifier( ControlModelLock& _rLock )
      99             :         :m_rLock( _rLock )
     100        1370 :         ,m_rModel( dynamic_cast< OBoundControlModel& >( _rLock.getModel() ) )
     101             :     {
     102        1370 :         m_xOldField = m_rModel.getField();
     103        1370 :     }
     104             : 
     105        1370 :     ~FieldChangeNotifier()
     106        1370 :     {
     107        1370 :         Reference< XPropertySet > xNewField( m_rModel.getField() );
     108        1370 :         if ( m_xOldField != xNewField )
     109          62 :             m_rLock.addPropertyNotification( PROPERTY_ID_BOUNDFIELD, makeAny( m_xOldField ), makeAny( xNewField ) );
     110        1370 :     }
     111             : 
     112             : private:
     113             :     ControlModelLock&           m_rLock;
     114             :     OBoundControlModel&         m_rModel;
     115             :     Reference< XPropertySet >   m_xOldField;
     116             : };
     117             : 
     118             : // base class for form layer controls
     119         602 : OControl::OControl( const Reference< XComponentContext >& _rxContext, const OUString& _rAggregateService, const bool _bSetDelegator )
     120             :             :OComponentHelper(m_aMutex)
     121         602 :             ,m_xContext( _rxContext )
     122             : {
     123             :     // Aggregate VCL Control
     124             :     // Increment the RefCount for aggregates, because the aggregate by itself increments the RefCount in the setDelegator
     125         602 :     increment( m_refCount );
     126             :     {
     127         602 :         m_xAggregate.set(_rxContext->getServiceManager()->createInstanceWithContext(_rAggregateService, _rxContext), css::uno::UNO_QUERY);
     128         602 :         m_xControl.set(m_xAggregate, css::uno::UNO_QUERY);
     129             :     }
     130         602 :     decrement( m_refCount );
     131             : 
     132         602 :     if ( _bSetDelegator )
     133         566 :         doSetDelegator();
     134         602 : }
     135             : 
     136        1048 : OControl::~OControl()
     137             : {
     138         524 :     doResetDelegator();
     139         524 : }
     140             : 
     141         536 : void OControl::doResetDelegator()
     142             : {
     143         536 :     if ( m_xAggregate.is() )
     144         536 :         m_xAggregate->setDelegator( NULL );
     145         536 : }
     146             : 
     147         602 : void OControl::doSetDelegator()
     148             : {
     149         602 :     increment( m_refCount );
     150         602 :     if ( m_xAggregate.is() )
     151             :     {   // those brackets are important for some compilers, don't remove!
     152             :         // (they ensure that the temporary object created in the line below
     153             :         // is destroyed *before* the refcount-decrement)
     154         602 :         m_xAggregate->setDelegator( static_cast< XWeak* >( this ) );
     155             :     }
     156         602 :     decrement( m_refCount );
     157         602 : }
     158             : 
     159             : // UNO Binding
     160       22091 : Any SAL_CALL OControl::queryAggregation( const Type& _rType ) throw(RuntimeException, std::exception)
     161             : {
     162             :     // ask the base class
     163       22091 :     Any aReturn( OComponentHelper::queryAggregation(_rType) );
     164             :     // ask our own interfaces
     165       22091 :     if (!aReturn.hasValue())
     166             :     {
     167       20564 :         aReturn = OControl_BASE::queryInterface(_rType);
     168             :         // ask our aggregate
     169       20564 :         if (!aReturn.hasValue() && m_xAggregate.is())
     170        9792 :             aReturn = m_xAggregate->queryAggregation(_rType);
     171             :     }
     172             : 
     173       22091 :     return aReturn;
     174             : }
     175             : 
     176           0 : Sequence<sal_Int8> SAL_CALL OControl::getImplementationId() throw(RuntimeException, std::exception)
     177             : {
     178           0 :     return css::uno::Sequence<sal_Int8>();
     179             : }
     180             : 
     181         264 : Sequence<Type> SAL_CALL OControl::getTypes() throw(RuntimeException, std::exception)
     182             : {
     183         264 :     TypeBag aTypes( _getTypes() );
     184             : 
     185         528 :     Reference< XTypeProvider > xProv;
     186         264 :     if ( query_aggregation( m_xAggregate, xProv ) )
     187         264 :         aTypes.addTypes( xProv->getTypes() );
     188             : 
     189         528 :     return aTypes.getTypes();
     190             : }
     191             : 
     192         148 : Sequence<Type> OControl::_getTypes()
     193             : {
     194         148 :     return TypeBag( OComponentHelper::getTypes(), OControl_BASE::getTypes() ).getTypes();
     195             : }
     196             : 
     197         855 : void OControl::initFormControlPeer( const Reference< XWindowPeer >& /*_rxPeer*/ )
     198             : {
     199             :     // nothing to do here
     200         855 : }
     201             : 
     202             : // OComponentHelper
     203         530 : void OControl::disposing()
     204             : {
     205         530 :     OComponentHelper::disposing();
     206             : 
     207         530 :     m_aWindowStateGuard.attach( NULL, NULL );
     208             : 
     209         530 :     Reference< XComponent > xComp;
     210         530 :     if (query_aggregation(m_xAggregate, xComp))
     211         530 :         xComp->dispose();
     212         530 : }
     213             : 
     214             : // XServiceInfo
     215           0 : sal_Bool SAL_CALL OControl::supportsService(const OUString& _rsServiceName) throw ( RuntimeException, std::exception)
     216             : {
     217           0 :     return cppu::supportsService(this, _rsServiceName);
     218             : }
     219             : 
     220           0 : Sequence< OUString > OControl::getAggregateServiceNames()
     221             : {
     222           0 :     Sequence< OUString > aAggServices;
     223           0 :     Reference< XServiceInfo > xInfo;
     224           0 :     if ( query_aggregation( m_xAggregate, xInfo ) )
     225           0 :         aAggServices = xInfo->getSupportedServiceNames();
     226             : 
     227           0 :     return aAggServices;
     228             : }
     229             : 
     230           0 : Sequence<OUString> SAL_CALL OControl::getSupportedServiceNames() throw(RuntimeException, std::exception)
     231             : {
     232             :     return ::comphelper::concatSequences(
     233             :         getAggregateServiceNames(),
     234             :         getSupportedServiceNames_Static()
     235           0 :    );
     236             : }
     237             : 
     238           0 : Sequence< OUString > SAL_CALL OControl::getSupportedServiceNames_Static() throw( RuntimeException )
     239             : {
     240             :     // no own supported service names
     241           0 :     return Sequence< OUString >();
     242             : }
     243             : 
     244             : // XEventListener
     245        1539 : void SAL_CALL OControl::disposing(const com::sun::star::lang::EventObject& _rEvent) throw (RuntimeException, std::exception)
     246             : {
     247        1539 :     Reference< XInterface > xAggAsIface;
     248        1539 :     query_aggregation(m_xAggregate, xAggAsIface);
     249             : 
     250             :     // does the disposing come from the aggregate?
     251        1539 :     if (xAggAsIface != Reference< XInterface >(_rEvent.Source, UNO_QUERY))
     252             :     {   // no -> forward it
     253        1107 :         Reference<com::sun::star::lang::XEventListener> xListener;
     254        1107 :         if (query_aggregation(m_xAggregate, xListener))
     255        1107 :             xListener->disposing(_rEvent);
     256        1539 :     }
     257        1539 : }
     258             : 
     259             : // XControl
     260         728 : void SAL_CALL OControl::setContext(const Reference< XInterface >& Context) throw (RuntimeException, std::exception)
     261             : {
     262         728 :     if (m_xControl.is())
     263         728 :         m_xControl->setContext(Context);
     264         728 : }
     265             : 
     266          26 : Reference< XInterface > SAL_CALL OControl::getContext() throw (RuntimeException, std::exception)
     267             : {
     268          26 :     return m_xControl.is() ? m_xControl->getContext() : Reference< XInterface >();
     269             : }
     270             : 
     271        1183 : void OControl::impl_resetStateGuard_nothrow()
     272             : {
     273        1183 :     Reference< XWindow2 > xWindow;
     274        2366 :     Reference< XControlModel > xModel;
     275             :     try
     276             :     {
     277        1183 :         xWindow.set( getPeer(), UNO_QUERY );
     278        1183 :         xModel.set( getModel(), UNO_QUERY );
     279             :     }
     280           0 :     catch( const Exception& )
     281             :     {
     282             :         DBG_UNHANDLED_EXCEPTION();
     283             :     }
     284        2366 :     m_aWindowStateGuard.attach( xWindow, xModel );
     285        1183 : }
     286             : 
     287         651 : void SAL_CALL OControl::createPeer(const Reference<XToolkit>& _rxToolkit, const Reference<XWindowPeer>& _rxParent) throw (RuntimeException, std::exception)
     288             : {
     289         651 :     if ( m_xControl.is() )
     290             :     {
     291         651 :         m_xControl->createPeer( _rxToolkit, _rxParent );
     292         651 :         initFormControlPeer( getPeer() );
     293         651 :         impl_resetStateGuard_nothrow();
     294             :     }
     295         651 : }
     296             : 
     297        5014 : Reference<XWindowPeer> SAL_CALL OControl::getPeer() throw ( RuntimeException, std::exception)
     298             : {
     299        5014 :     return m_xControl.is() ? m_xControl->getPeer() : Reference<XWindowPeer>();
     300             : }
     301             : 
     302         532 : sal_Bool SAL_CALL OControl::setModel(const Reference<XControlModel>& Model) throw ( RuntimeException, std::exception)
     303             : {
     304         532 :     if ( !m_xControl.is() )
     305           0 :         return sal_False;
     306             : 
     307         532 :     bool bSuccess = m_xControl->setModel( Model );
     308         532 :     impl_resetStateGuard_nothrow();
     309         532 :     return bSuccess;
     310             : }
     311             : 
     312        3733 : Reference<XControlModel> SAL_CALL OControl::getModel() throw ( RuntimeException, std::exception)
     313             : {
     314        3733 :     return m_xControl.is() ? m_xControl->getModel() : Reference<XControlModel>();
     315             : }
     316             : 
     317          26 : Reference<XView> SAL_CALL OControl::getView() throw ( RuntimeException, std::exception)
     318             : {
     319          26 :     return m_xControl.is() ? m_xControl->getView() : Reference<XView>();
     320             : }
     321             : 
     322         397 : void SAL_CALL OControl::setDesignMode(sal_Bool bOn) throw ( RuntimeException, std::exception)
     323             : {
     324         397 :     if (m_xControl.is())
     325         397 :         m_xControl->setDesignMode(bOn);
     326         397 : }
     327             : 
     328       18976 : sal_Bool SAL_CALL OControl::isDesignMode() throw ( RuntimeException, std::exception)
     329             : {
     330       18976 :     return m_xControl.is() ? m_xControl->isDesignMode() : sal_True;
     331             : }
     332             : 
     333          26 : sal_Bool SAL_CALL OControl::isTransparent() throw ( RuntimeException, std::exception)
     334             : {
     335          26 :     return m_xControl.is() ? m_xControl->isTransparent() : sal_True;
     336             : }
     337             : 
     338         326 : OBoundControl::OBoundControl( const Reference< XComponentContext >& _rxContext,
     339             :             const OUString& _rAggregateService, const bool _bSetDelegator )
     340             :     :OControl( _rxContext, _rAggregateService, _bSetDelegator )
     341             :     ,m_bLocked(false)
     342             :     ,m_aOriginalFont( EmptyFontDescriptor() )
     343         326 :     ,m_nOriginalTextLineColor( 0 )
     344             : {
     345         326 : }
     346             : 
     347         264 : OBoundControl::~OBoundControl()
     348             : {
     349         264 : }
     350             : 
     351         140 : Sequence< Type> OBoundControl::_getTypes()
     352             : {
     353         140 :     return TypeBag( OControl::_getTypes(), OBoundControl_BASE::getTypes() ).getTypes();
     354             : }
     355             : 
     356       18823 : Any SAL_CALL OBoundControl::queryAggregation(const Type& _rType) throw(RuntimeException, std::exception)
     357             : {
     358       18823 :     Any aReturn;
     359             : 
     360             :     // XTypeProvider first - don't ask the OBoundControl_BASE, it would deliver incomplete types
     361       18823 :     if ( _rType.equals( cppu::UnoType<XTypeProvider>::get() ) )
     362          70 :         aReturn = OControl::queryAggregation( _rType );
     363             : 
     364             :     // ask our own interfaces
     365             :     // (do this first (except XTypeProvider ) - we want to "overwrite" XPropertiesChangeListener)
     366       18823 :     if ( !aReturn.hasValue() )
     367       18753 :         aReturn = OBoundControl_BASE::queryInterface( _rType );
     368             : 
     369             :     // ask the base class
     370       18823 :     if ( !aReturn.hasValue() )
     371       16119 :         aReturn = OControl::queryAggregation( _rType );
     372             : 
     373       18823 :     return aReturn;
     374             : }
     375             : 
     376          44 : sal_Bool SAL_CALL OBoundControl::getLock() throw(RuntimeException, std::exception)
     377             : {
     378          44 :     return m_bLocked;
     379             : }
     380             : 
     381          44 : void SAL_CALL OBoundControl::setLock(sal_Bool _bLock) throw(RuntimeException, std::exception)
     382             : {
     383          44 :     if ((m_bLocked ? 1 : 0) == _bLock)
     384          44 :         return;
     385             : 
     386          44 :     osl::MutexGuard aGuard(m_aMutex);
     387          44 :     _setLock(_bLock);
     388          44 :     m_bLocked = _bLock;
     389             : }
     390             : 
     391          44 : void OBoundControl::_setLock(bool _bLock)
     392             : {
     393             :     // try to set the text component to readonly
     394          44 :     Reference< XWindowPeer > xPeer = getPeer();
     395          88 :     Reference< XTextComponent > xText( xPeer, UNO_QUERY );
     396             : 
     397          44 :     if ( xText.is() )
     398          32 :         xText->setEditable( !_bLock );
     399             :     else
     400             :     {
     401             :         // disable the window
     402          12 :         Reference< XWindow > xComp( xPeer, UNO_QUERY );
     403          12 :         if ( xComp.is() )
     404          12 :             xComp->setEnable( !_bLock );
     405          44 :     }
     406          44 : }
     407             : 
     408         262 : sal_Bool SAL_CALL OBoundControl::setModel( const Reference< XControlModel >& _rxModel ) throw (RuntimeException, std::exception)
     409             : {
     410         262 :     return OControl::setModel( _rxModel );
     411             : }
     412             : 
     413         674 : void SAL_CALL OBoundControl::disposing(const EventObject& Source) throw (RuntimeException, std::exception)
     414             : {
     415             :     // just disambiguate
     416         674 :     OControl::disposing(Source);
     417         674 : }
     418             : 
     419         270 : void OBoundControl::disposing()
     420             : {
     421         270 :     OControl::disposing();
     422         270 : }
     423             : 
     424             : // OControlModel
     425          64 : Sequence<sal_Int8> SAL_CALL OControlModel::getImplementationId() throw(RuntimeException, std::exception)
     426             : {
     427          64 :     return css::uno::Sequence<sal_Int8>();
     428             : }
     429             : 
     430         172 : Sequence<Type> SAL_CALL OControlModel::getTypes() throw(RuntimeException, std::exception)
     431             : {
     432         172 :     TypeBag aTypes( _getTypes() );
     433             : 
     434         344 :     Reference< XTypeProvider > xProv;
     435             : 
     436         172 :     if ( query_aggregation( m_xAggregate, xProv ) )
     437         172 :         aTypes.addTypes( xProv->getTypes() );
     438             : 
     439         344 :     return aTypes.getTypes();
     440             : }
     441             : 
     442         172 : Sequence<Type> OControlModel::_getTypes()
     443             : {
     444             :     return TypeBag( OComponentHelper::getTypes(),
     445             :         OPropertySetAggregationHelper::getTypes(),
     446             :         OControlModel_BASE::getTypes()
     447         172 :     ).getTypes();
     448             : }
     449             : 
     450      211616 : Any SAL_CALL OControlModel::queryAggregation(const Type& _rType) throw (RuntimeException, std::exception)
     451             : {
     452             :     // base class 1
     453      211616 :     Any aReturn(OComponentHelper::queryAggregation(_rType));
     454             : 
     455             :     // base class 2
     456      211616 :     if (!aReturn.hasValue())
     457             :     {
     458      156606 :         aReturn = OControlModel_BASE::queryInterface(_rType);
     459             : 
     460             :         // our own interfaces
     461      156606 :         if (!aReturn.hasValue())
     462             :         {
     463      147324 :             aReturn = OPropertySetAggregationHelper::queryInterface(_rType);
     464             :             // our aggregate
     465      147324 :             if (!aReturn.hasValue() && m_xAggregate.is() && !_rType.equals(cppu::UnoType<XCloneable>::get()))
     466       87017 :                 aReturn = m_xAggregate->queryAggregation(_rType);
     467             :         }
     468             :     }
     469      211616 :     return aReturn;
     470             : }
     471             : 
     472          36 : void OControlModel::readHelpTextCompatibly(const css::uno::Reference< css::io::XObjectInputStream >& _rxInStream)
     473             : {
     474          36 :     OUString sHelpText;
     475          36 :     ::comphelper::operator>>( _rxInStream, sHelpText);
     476             :     try
     477             :     {
     478          36 :         if (m_xAggregateSet.is())
     479          36 :             m_xAggregateSet->setPropertyValue(PROPERTY_HELPTEXT, makeAny(sHelpText));
     480             :     }
     481           0 :     catch(const Exception&)
     482             :     {
     483             :         SAL_WARN("forms.component", "OControlModel::readHelpTextCompatibly: could not forward the property value to the aggregate!");
     484             :         DBG_UNHANDLED_EXCEPTION();
     485          36 :     }
     486          36 : }
     487             : 
     488          36 : void OControlModel::writeHelpTextCompatibly(const css::uno::Reference< css::io::XObjectOutputStream >& _rxOutStream)
     489             : {
     490          36 :     OUString sHelpText;
     491             :     try
     492             :     {
     493          36 :         if (m_xAggregateSet.is())
     494          36 :             m_xAggregateSet->getPropertyValue(PROPERTY_HELPTEXT) >>= sHelpText;
     495             :     }
     496           0 :     catch(const Exception&)
     497             :     {
     498             :         SAL_WARN("forms.component", "OControlModel::writeHelpTextCompatibly: could not retrieve the property value from the aggregate!");
     499             :         DBG_UNHANDLED_EXCEPTION();
     500             :     }
     501          36 :     ::comphelper::operator<<( _rxOutStream, sHelpText);
     502          36 : }
     503             : 
     504        1134 : OControlModel::OControlModel(
     505             :             const Reference<XComponentContext>& _rxContext,
     506             :             const OUString& _rUnoControlModelTypeName,
     507             :             const OUString& rDefault, const bool _bSetDelegator)
     508             :     :OComponentHelper(m_aMutex)
     509             :     ,OPropertySetAggregationHelper(OComponentHelper::rBHelper)
     510             :     ,m_xContext( _rxContext )
     511             :     ,m_lockCount( 0 )
     512             :     ,m_aPropertyBagHelper( *this )
     513             :     ,m_nTabIndex(FRM_DEFAULT_TABINDEX)
     514             :     ,m_nClassId(FormComponentType::CONTROL)
     515             :     ,m_bNativeLook( false )
     516             :     ,m_bGenerateVbEvents( false )
     517             :     ,m_nControlTypeinMSO(0) // 0 : default value is create from AOO
     518        1134 :     ,m_nObjIDinMSO(INVALID_OBJ_ID_IN_MSO)
     519             :     // form controls are usually embedded into documents, not dialogs, and in documents
     520             :     // the native look is ugly...
     521             :     // #i37342#
     522             : {
     523        1134 :     if (!_rUnoControlModelTypeName.isEmpty())  // the is a model we have to aggregate
     524             :     {
     525         868 :         increment(m_refCount);
     526             :         {
     527         868 :             m_xAggregate = Reference<XAggregation>(m_xContext->getServiceManager()->createInstanceWithContext(_rUnoControlModelTypeName, m_xContext), UNO_QUERY);
     528         868 :             setAggregation(m_xAggregate);
     529             : 
     530         868 :             if ( m_xAggregateSet.is() )
     531             :             {
     532             :                 try
     533             :                 {
     534         868 :                     if ( !rDefault.isEmpty() )
     535         734 :                         m_xAggregateSet->setPropertyValue( PROPERTY_DEFAULTCONTROL, makeAny( rDefault ) );
     536             :                 }
     537           0 :                 catch( const Exception& )
     538             :                 {
     539             :                     SAL_WARN("forms.component",  "OControlModel::OControlModel: caught an exception!");
     540             :                     DBG_UNHANDLED_EXCEPTION();
     541             :                 }
     542             :             }
     543             :         }
     544         868 :         if (_bSetDelegator)
     545         286 :             doSetDelegator();
     546             : 
     547             :         // Refcount is at NULL again
     548         868 :         decrement(m_refCount);
     549             :     }
     550        1134 : }
     551             : 
     552          44 : OControlModel::OControlModel( const OControlModel* _pOriginal, const Reference< XComponentContext>& _rxFactory, const bool _bCloneAggregate, const bool _bSetDelegator )
     553             :     :OComponentHelper( m_aMutex )
     554             :     ,OPropertySetAggregationHelper( OComponentHelper::rBHelper )
     555             :     ,m_xContext( _rxFactory )
     556             :     ,m_lockCount( 0 )
     557             :     ,m_aPropertyBagHelper( *this )
     558             :     ,m_nTabIndex( FRM_DEFAULT_TABINDEX )
     559          44 :     ,m_nClassId( FormComponentType::CONTROL )
     560             : {
     561             :     DBG_ASSERT( _pOriginal, "OControlModel::OControlModel: invalid original!" );
     562             : 
     563             :     // copy members
     564          44 :     m_aName = _pOriginal->m_aName;
     565          44 :     m_aTag = _pOriginal->m_aTag;
     566          44 :     m_nTabIndex = _pOriginal->m_nTabIndex;
     567          44 :     m_nClassId = _pOriginal->m_nClassId;
     568          44 :     m_bNativeLook = _pOriginal->m_bNativeLook;
     569          44 :     m_bGenerateVbEvents = _pOriginal->m_bGenerateVbEvents;
     570          44 :     m_nControlTypeinMSO = _pOriginal->m_nControlTypeinMSO;
     571          44 :     m_nObjIDinMSO = _pOriginal->m_nObjIDinMSO;
     572             : 
     573          44 :     if ( _bCloneAggregate )
     574             :     {
     575             :         // temporarily increment refcount because of temporary references to ourself in the following
     576          40 :         increment( m_refCount );
     577             :         {
     578             :             // transfer the (only, at the very moment!) ref count
     579          40 :             m_xAggregate = createAggregateClone( _pOriginal );
     580             : 
     581             :             // set aggregation (retrieve other direct interfaces of the aggregate)
     582          40 :             setAggregation( m_xAggregate );
     583             :         }
     584             : 
     585             :         // set the delegator, if allowed by our derived class
     586          40 :         if ( _bSetDelegator )
     587          10 :             doSetDelegator();
     588             : 
     589             :         // decrement ref count
     590          40 :         decrement( m_refCount );
     591             :     }
     592          44 : }
     593             : 
     594        2224 : OControlModel::~OControlModel()
     595             : {
     596             :     // release the aggregate
     597        1112 :     doResetDelegator( );
     598        1112 : }
     599             : 
     600          14 : void OControlModel::clonedFrom( const OControlModel* /*_pOriginal*/ )
     601             : {
     602             :     // nothing to do in this base class
     603          14 : }
     604             : 
     605        1690 : void OControlModel::doResetDelegator()
     606             : {
     607        1690 :     if (m_xAggregate.is())
     608        1632 :         m_xAggregate->setDelegator(NULL);
     609        1690 : }
     610             : 
     611        1120 : void OControlModel::doSetDelegator()
     612             : {
     613        1120 :     increment(m_refCount);
     614        1120 :     if (m_xAggregate.is())
     615             :     {
     616        1116 :         m_xAggregate->setDelegator(static_cast<XWeak*>(this));
     617             :     }
     618        1120 :     decrement(m_refCount);
     619        1120 : }
     620             : 
     621             : // XChild
     622        9106 : Reference< XInterface > SAL_CALL OControlModel::getParent() throw(RuntimeException, std::exception)
     623             : {
     624        9106 :     return m_xParent;
     625             : }
     626             : 
     627        1748 : void SAL_CALL OControlModel::setParent(const Reference< XInterface >& _rxParent) throw(com::sun::star::lang::NoSupportException, RuntimeException, std::exception)
     628             : {
     629        1748 :     osl::MutexGuard aGuard(m_aMutex);
     630             : 
     631        3496 :     Reference<XComponent> xComp(m_xParent, UNO_QUERY);
     632        1748 :     if (xComp.is())
     633         518 :         xComp->removeEventListener(static_cast<XPropertiesChangeListener*>(this));
     634             : 
     635        1748 :     m_xParent = _rxParent;
     636        1748 :     xComp.set(m_xParent, css::uno::UNO_QUERY);
     637             : 
     638        1748 :     if ( xComp.is() )
     639        2486 :         xComp->addEventListener(static_cast<XPropertiesChangeListener*>(this));
     640        1748 : }
     641             : 
     642             : // XNamed
     643         376 : OUString SAL_CALL OControlModel::getName() throw(RuntimeException, std::exception)
     644             : {
     645         376 :     OUString aReturn;
     646         376 :     OPropertySetHelper::getFastPropertyValue(PROPERTY_ID_NAME) >>= aReturn;
     647         376 :     return aReturn;
     648             : }
     649             : 
     650          76 : void SAL_CALL OControlModel::setName(const OUString& _rName) throw(RuntimeException, std::exception)
     651             : {
     652             :     try
     653             :     {
     654          76 :         setFastPropertyValue(PROPERTY_ID_NAME, makeAny(_rName));
     655             :     }
     656           0 :     catch (const css::beans::UnknownPropertyException&)
     657             :     {
     658           0 :         css::uno::Any a(cppu::getCaughtException());
     659             :         throw WrappedTargetRuntimeException(
     660             :             "OControlModel::setName",
     661             :             *const_cast< OControlModel* >( this ),
     662             :             a
     663           0 :         );
     664             :     }
     665          76 : }
     666             : 
     667             : // XServiceInfo
     668         582 : sal_Bool SAL_CALL OControlModel::supportsService(const OUString& _rServiceName) throw ( RuntimeException, std::exception)
     669             : {
     670         582 :     return cppu::supportsService(this, _rServiceName);
     671             : }
     672             : 
     673         668 : Sequence< OUString > OControlModel::getAggregateServiceNames()
     674             : {
     675         668 :     Sequence< OUString > aAggServices;
     676        1336 :     Reference< XServiceInfo > xInfo;
     677         668 :     if ( query_aggregation( m_xAggregate, xInfo ) )
     678         658 :         aAggServices = xInfo->getSupportedServiceNames();
     679        1336 :     return aAggServices;
     680             : }
     681             : 
     682          38 : Sequence<OUString> SAL_CALL OControlModel::getSupportedServiceNames() throw(RuntimeException, std::exception)
     683             : {
     684             :     return ::comphelper::concatSequences(
     685             :         getAggregateServiceNames(),
     686             :         getSupportedServiceNames_Static()
     687          38 :     );
     688             : }
     689             : 
     690         838 : Sequence< OUString > SAL_CALL OControlModel::getSupportedServiceNames_Static() throw( RuntimeException )
     691             : {
     692         838 :     Sequence< OUString > aServiceNames( 2 );
     693         838 :     aServiceNames[ 0 ] = FRM_SUN_FORMCOMPONENT;
     694         838 :     aServiceNames[ 1 ] = "com.sun.star.form.FormControlModel";
     695         838 :     return aServiceNames;
     696             : }
     697             : 
     698             : // XEventListener
     699         526 : void SAL_CALL OControlModel::disposing(const com::sun::star::lang::EventObject& _rSource) throw (RuntimeException, std::exception)
     700             : {
     701             :     // release the parent
     702         526 :     if (_rSource.Source == m_xParent)
     703             :     {
     704         212 :         osl::MutexGuard aGuard(m_aMutex);
     705         212 :         m_xParent = NULL;
     706             :     }
     707             :     else
     708             :     {
     709         314 :         Reference<com::sun::star::lang::XEventListener> xEvtLst;
     710         314 :         if (query_aggregation(m_xAggregate, xEvtLst))
     711             :         {
     712          92 :             osl::MutexGuard aGuard(m_aMutex);
     713          92 :             xEvtLst->disposing(_rSource);
     714         314 :         }
     715             :     }
     716         526 : }
     717             : 
     718             : // OComponentHelper
     719        1114 : void OControlModel::disposing()
     720             : {
     721        1114 :     OPropertySetAggregationHelper::disposing();
     722             : 
     723        1114 :     Reference<com::sun::star::lang::XComponent> xComp;
     724        1114 :     if (query_aggregation(m_xAggregate, xComp))
     725         860 :         xComp->dispose();
     726             : 
     727        1114 :     setParent(Reference<XFormComponent>());
     728             : 
     729        1114 :     m_aPropertyBagHelper.dispose();
     730        1114 : }
     731             : 
     732          38 : void OControlModel::writeAggregate( const Reference< XObjectOutputStream >& _rxOutStream ) const
     733             : {
     734          38 :     Reference< XPersistObject > xPersist;
     735          38 :     if ( query_aggregation( m_xAggregate, xPersist ) )
     736          32 :         xPersist->write( _rxOutStream );
     737          38 : }
     738             : 
     739          32 : void OControlModel::readAggregate( const Reference< XObjectInputStream >& _rxInStream )
     740             : {
     741          32 :     Reference< XPersistObject > xPersist;
     742          32 :     if ( query_aggregation( m_xAggregate, xPersist ) )
     743          32 :         xPersist->read( _rxInStream );
     744          32 : }
     745             : 
     746          42 : void SAL_CALL OControlModel::write(const Reference<css::io::XObjectOutputStream>& _rxOutStream)
     747             :                         throw(css::io::IOException, RuntimeException, std::exception)
     748             : {
     749          42 :     osl::MutexGuard aGuard(m_aMutex);
     750             : 
     751             :     // 1. writing the UnoControls
     752          84 :     Reference<css::io::XMarkableStream> xMark(_rxOutStream, UNO_QUERY);
     753          42 :     if ( !xMark.is() )
     754             :     {
     755             :         throw IOException(
     756             :             FRM_RES_STRING( RID_STR_INVALIDSTREAM ),
     757             :             static_cast< ::cppu::OWeakObject* >( this )
     758           0 :         );
     759             :     }
     760             : 
     761          42 :     sal_Int32 nMark = xMark->createMark();
     762          42 :     sal_Int32 nLen = 0;
     763             : 
     764          42 :     _rxOutStream->writeLong(nLen);
     765             : 
     766          42 :     writeAggregate( _rxOutStream );
     767             : 
     768             :     // determining the length
     769          42 :     nLen = xMark->offsetToMark(nMark) - 4;
     770          42 :     xMark->jumpToMark(nMark);
     771          42 :     _rxOutStream->writeLong(nLen);
     772          42 :     xMark->jumpToFurthest();
     773          42 :     xMark->deleteMark(nMark);
     774             : 
     775             :     // 2. writing a version number
     776          42 :     _rxOutStream->writeShort(0x0003);
     777             : 
     778             :     // 3. writing the general properties
     779          42 :     ::comphelper::operator<<( _rxOutStream, m_aName);
     780          42 :     _rxOutStream->writeShort(m_nTabIndex);
     781          84 :     ::comphelper::operator<<( _rxOutStream, m_aTag); // 3rd version
     782             : 
     783             :     // IMPORTANT NOTE!
     784             :     // don't write any new members here: this wouldn't be compatible with older versions, as OControlModel
     785             :     // is a base class which is called in derived classes "read" method. So if you increment the version
     786             :     // and write new stuff, older office versions will read this in the _derived_ classes, which may result
     787             :     // in anything from data loss to crash.
     788             :     // EOIN!
     789          42 : }
     790             : 
     791          42 : void OControlModel::read(const Reference<css::io::XObjectInputStream>& InStream) throw (::com::sun::star::io::IOException, RuntimeException, std::exception)
     792             : {
     793          42 :     osl::MutexGuard aGuard(m_aMutex);
     794             : 
     795          84 :     Reference<css::io::XMarkableStream> xMark(InStream, UNO_QUERY);
     796          42 :     if ( !xMark.is() )
     797             :     {
     798             :         throw IOException(
     799             :             FRM_RES_STRING( RID_STR_INVALIDSTREAM ),
     800             :             static_cast< ::cppu::OWeakObject* >( this )
     801           0 :         );
     802             :     }
     803             : 
     804             :     // 1. reading the UnoControls
     805          42 :     sal_Int32 nLen = InStream->readLong();
     806          42 :     if (nLen)
     807             :     {
     808          36 :         sal_Int32 nMark = xMark->createMark();
     809             : 
     810             :         try
     811             :         {
     812          36 :             readAggregate( InStream );
     813             :         }
     814             : 
     815           0 :         catch( const Exception& )
     816             :         {
     817             :             DBG_UNHANDLED_EXCEPTION();
     818             :         }
     819             : 
     820          36 :         xMark->jumpToMark(nMark);
     821          36 :         InStream->skipBytes(nLen);
     822          36 :         xMark->deleteMark(nMark);
     823             :     }
     824             : 
     825             :     // 2. reading the version number
     826          42 :     sal_uInt16 nVersion = InStream->readShort();
     827             : 
     828             :     // 3. reading the general properties
     829          42 :     ::comphelper::operator>>( InStream, m_aName);
     830          42 :     m_nTabIndex  = InStream->readShort();
     831             : 
     832          42 :     if (nVersion > 0x0002)
     833          42 :         ::comphelper::operator>>( InStream, m_aTag);
     834             : 
     835             :     // we had a version where we wrote the help text
     836          42 :     if (nVersion == 0x0004)
     837           0 :         readHelpTextCompatibly(InStream);
     838             : 
     839          42 :     DBG_ASSERT(nVersion < 5, "OControlModel::read : suspicious version number !");
     840             :     // 4 was the version where we wrote the help text
     841             :     // later versions shouldn't exist (see write for a detailed comment)
     842          42 : }
     843             : 
     844          16 : PropertyState OControlModel::getPropertyStateByHandle( sal_Int32 _nHandle )
     845             : {
     846             :     // simply compare the current and the default value
     847          16 :     Any aCurrentValue = getPropertyDefaultByHandle( _nHandle );
     848          32 :     Any aDefaultValue;  getFastPropertyValue( aDefaultValue, _nHandle );
     849             : 
     850             :     bool bEqual = uno_type_equalData(
     851          32 :             const_cast< void* >( aCurrentValue.getValue() ), aCurrentValue.getValueType().getTypeLibType(),
     852          32 :             const_cast< void* >( aDefaultValue.getValue() ), aDefaultValue.getValueType().getTypeLibType(),
     853             :             reinterpret_cast< uno_QueryInterfaceFunc >(cpp_queryInterface),
     854             :             reinterpret_cast< uno_ReleaseFunc >(cpp_release)
     855          48 :         );
     856          32 :     return bEqual ? PropertyState_DEFAULT_VALUE : PropertyState_DIRECT_VALUE;
     857             : }
     858             : 
     859           6 : void OControlModel::setPropertyToDefaultByHandle( sal_Int32 _nHandle)
     860             : {
     861           6 :     Any aDefault = getPropertyDefaultByHandle( _nHandle );
     862             : 
     863          12 :     Any aConvertedValue, aOldValue;
     864           6 :     if ( convertFastPropertyValue( aConvertedValue, aOldValue, _nHandle, aDefault ) )
     865             :     {
     866           0 :         setFastPropertyValue_NoBroadcast( _nHandle, aConvertedValue );
     867             :         // TODO: fire the property change
     868           6 :     }
     869           6 : }
     870             : 
     871           0 : Any OControlModel::getPropertyDefaultByHandle( sal_Int32 _nHandle ) const
     872             : {
     873           0 :     Any aReturn;
     874           0 :     switch ( _nHandle )
     875             :     {
     876             :         case PROPERTY_ID_NAME:
     877             :         case PROPERTY_ID_TAG:
     878           0 :             aReturn <<= OUString();
     879           0 :             break;
     880             :         case PROPERTY_ID_CLASSID:
     881           0 :             aReturn <<= (sal_Int16)FormComponentType::CONTROL;
     882           0 :             break;
     883             :         case PROPERTY_ID_TABINDEX:
     884           0 :             aReturn <<= (sal_Int16)FRM_DEFAULT_TABINDEX;
     885           0 :             break;
     886             :         case PROPERTY_ID_NATIVE_LOOK:
     887           0 :             aReturn <<= true;
     888           0 :             break;
     889             :         case PROPERTY_ID_GENERATEVBAEVENTS:
     890           0 :             aReturn <<= false;
     891           0 :             break;
     892             :         // added for exporting OCX control
     893             :         case PROPERTY_ID_CONTROL_TYPE_IN_MSO:
     894           0 :             aReturn <<= (sal_Int16)0;
     895           0 :             break;
     896             :         case PROPERTY_ID_OBJ_ID_IN_MSO:
     897           0 :             aReturn <<= (sal_uInt16)INVALID_OBJ_ID_IN_MSO;
     898           0 :             break;
     899             :         default:
     900           0 :             if ( m_aPropertyBagHelper.hasDynamicPropertyByHandle( _nHandle ) )
     901           0 :                 m_aPropertyBagHelper.getDynamicPropertyDefaultByHandle( _nHandle, aReturn );
     902             :             else
     903             :                 SAL_WARN("forms.component",  "OControlModel::convertFastPropertyValue: unknown handle " << _nHandle);
     904             :     }
     905           0 :     return aReturn;
     906             : }
     907             : 
     908      114788 : void OControlModel::getFastPropertyValue( Any& _rValue, sal_Int32 _nHandle ) const
     909             : {
     910      114788 :     switch ( _nHandle )
     911             :     {
     912             :         case PROPERTY_ID_NAME:
     913        9336 :             _rValue <<= m_aName;
     914        9336 :             break;
     915             :         case PROPERTY_ID_TAG:
     916        2830 :             _rValue <<= m_aTag;
     917        2830 :             break;
     918             :         case PROPERTY_ID_CLASSID:
     919        3633 :             _rValue <<= m_nClassId;
     920        3633 :             break;
     921             :         case PROPERTY_ID_TABINDEX:
     922        5056 :             _rValue <<= m_nTabIndex;
     923        5056 :             break;
     924             :         case PROPERTY_ID_NATIVE_LOOK:
     925        2556 :             _rValue <<= m_bNativeLook;
     926        2556 :             break;
     927             :         case PROPERTY_ID_GENERATEVBAEVENTS:
     928        1763 :             _rValue <<= m_bGenerateVbEvents;
     929             :         // added for exporting OCX control
     930             :         case PROPERTY_ID_CONTROL_TYPE_IN_MSO:
     931        4315 :             _rValue <<= (sal_Int16)m_nControlTypeinMSO;
     932        4315 :             break;
     933             :         case PROPERTY_ID_OBJ_ID_IN_MSO:
     934        2551 :             _rValue <<= (sal_uInt16)m_nObjIDinMSO;
     935        2551 :             break;
     936             :         default:
     937       84511 :             if ( m_aPropertyBagHelper.hasDynamicPropertyByHandle( _nHandle ) )
     938           0 :                 m_aPropertyBagHelper.getDynamicFastPropertyValue( _nHandle, _rValue );
     939             :             else
     940       84511 :                 OPropertySetAggregationHelper::getFastPropertyValue( _rValue, _nHandle );
     941       84511 :             break;
     942             :     }
     943      114788 : }
     944             : 
     945       10311 : sal_Bool OControlModel::convertFastPropertyValue(
     946             :                         Any& _rConvertedValue, Any& _rOldValue, sal_Int32 _nHandle, const Any& _rValue)
     947             :                         throw (com::sun::star::lang::IllegalArgumentException)
     948             : {
     949       10311 :     bool bModified(false);
     950       10311 :     switch (_nHandle)
     951             :     {
     952             :         case PROPERTY_ID_NAME:
     953        2519 :             bModified = tryPropertyValue(_rConvertedValue, _rOldValue, _rValue, m_aName);
     954        2517 :             break;
     955             :         case PROPERTY_ID_TAG:
     956        1594 :             bModified = tryPropertyValue(_rConvertedValue, _rOldValue, _rValue, m_aTag);
     957        1594 :             break;
     958             :         case PROPERTY_ID_TABINDEX:
     959        1504 :             bModified = tryPropertyValue(_rConvertedValue, _rOldValue, _rValue, m_nTabIndex);
     960        1504 :             break;
     961             :         case PROPERTY_ID_NATIVE_LOOK:
     962        1460 :             bModified = tryPropertyValue(_rConvertedValue, _rOldValue, _rValue, m_bNativeLook);
     963        1460 :             break;
     964             :         case PROPERTY_ID_GENERATEVBAEVENTS:
     965         188 :             bModified = tryPropertyValue(_rConvertedValue, _rOldValue, _rValue, m_bGenerateVbEvents);
     966         188 :             break;
     967             :         // added for exporting OCX control
     968             :         case PROPERTY_ID_CONTROL_TYPE_IN_MSO:
     969        1528 :             bModified = tryPropertyValue(_rConvertedValue, _rOldValue, _rValue, m_nControlTypeinMSO);
     970        1528 :             break;
     971             :         case PROPERTY_ID_OBJ_ID_IN_MSO:
     972        1518 :             bModified = tryPropertyValue(_rConvertedValue, _rOldValue, _rValue, m_nObjIDinMSO);
     973        1518 :             break;
     974             :         default:
     975           0 :             if ( m_aPropertyBagHelper.hasDynamicPropertyByHandle( _nHandle ) )
     976           0 :                 bModified = m_aPropertyBagHelper.convertDynamicFastPropertyValue( _nHandle, _rValue, _rConvertedValue, _rOldValue );
     977             :             else
     978             :                 SAL_WARN("forms.component",  "OControlModel::convertFastPropertyValue: unknown handle " << _nHandle);
     979           0 :             break;
     980             :     }
     981       10309 :     return bModified;
     982             : }
     983             : 
     984        3101 : void OControlModel::setFastPropertyValue_NoBroadcast(sal_Int32 _nHandle, const Any& _rValue)
     985             :                         throw (Exception, std::exception)
     986             : {
     987        3101 :     switch (_nHandle)
     988             :     {
     989             :         case PROPERTY_ID_NAME:
     990             :             DBG_ASSERT(_rValue.getValueType() == cppu::UnoType<OUString>::get(),
     991             :                 "OControlModel::setFastPropertyValue_NoBroadcast : invalid type" );
     992        1243 :             _rValue >>= m_aName;
     993        1243 :             break;
     994             :         case PROPERTY_ID_TAG:
     995             :             DBG_ASSERT(_rValue.getValueType() == cppu::UnoType<OUString>::get(),
     996             :                 "OControlModel::setFastPropertyValue_NoBroadcast : invalid type" );
     997         384 :             _rValue >>= m_aTag;
     998         384 :             break;
     999             :         case PROPERTY_ID_TABINDEX:
    1000             :             DBG_ASSERT(_rValue.getValueType() == getCppuType((const sal_Int16*)NULL),
    1001             :                 "OControlModel::setFastPropertyValue_NoBroadcast : invalid type" );
    1002         354 :             _rValue >>= m_nTabIndex;
    1003         354 :             break;
    1004             :         case PROPERTY_ID_NATIVE_LOOK:
    1005         286 :             OSL_VERIFY( _rValue >>= m_bNativeLook );
    1006         286 :             break;
    1007             :         case PROPERTY_ID_GENERATEVBAEVENTS:
    1008         136 :             OSL_VERIFY( _rValue >>= m_bGenerateVbEvents );
    1009         136 :             break;
    1010             :         // added for exporting OCX control
    1011             :         case PROPERTY_ID_CONTROL_TYPE_IN_MSO:
    1012         354 :             OSL_VERIFY( _rValue >>= m_nControlTypeinMSO );
    1013         354 :             break;
    1014             :         case PROPERTY_ID_OBJ_ID_IN_MSO:
    1015         344 :             OSL_VERIFY( _rValue >>= m_nObjIDinMSO );
    1016         344 :             break;
    1017             :         default:
    1018           0 :             if ( m_aPropertyBagHelper.hasDynamicPropertyByHandle( _nHandle ) )
    1019           0 :                 m_aPropertyBagHelper.setDynamicFastPropertyValue( _nHandle, _rValue );
    1020             :             else
    1021             :                 SAL_WARN("forms.component",  "OControlModel::setFastPropertyValue_NoBroadcast: unknown handle " << _nHandle );
    1022           0 :             break;
    1023             :     }
    1024        3101 : }
    1025             : 
    1026        1164 : void OControlModel::describeFixedProperties( Sequence< Property >& _rProps ) const
    1027             : {
    1028        1164 :     BEGIN_DESCRIBE_BASE_PROPERTIES( 7 )
    1029        1164 :         DECL_PROP2      (CLASSID,     sal_Int16,        READONLY, TRANSIENT);
    1030        1164 :         DECL_PROP1      (NAME,        OUString,  BOUND);
    1031        1164 :         DECL_BOOL_PROP2 (NATIVE_LOOK,                   BOUND, TRANSIENT);
    1032        1164 :         DECL_PROP1      (TAG,         OUString,  BOUND);
    1033        1164 :         DECL_PROP1      (GENERATEVBAEVENTS,         sal_Bool,  TRANSIENT);
    1034        1164 :         DECL_PROP1      (CONTROL_TYPE_IN_MSO,sal_Int16,     BOUND);
    1035        1164 :         DECL_PROP1      (OBJ_ID_IN_MSO,sal_uInt16,      BOUND);
    1036             :     END_DESCRIBE_PROPERTIES()
    1037        1164 : }
    1038             : 
    1039        1206 : void OControlModel::describeAggregateProperties( Sequence< Property >& /* [out] */ _rAggregateProps ) const
    1040             : {
    1041        1206 :     if ( m_xAggregateSet.is() )
    1042             :     {
    1043        1140 :         Reference< XPropertySetInfo > xPSI( m_xAggregateSet->getPropertySetInfo() );
    1044        1140 :         if ( xPSI.is() )
    1045        1140 :             _rAggregateProps = xPSI->getProperties();
    1046             :     }
    1047        1206 : }
    1048             : 
    1049        1624 : ::osl::Mutex& OControlModel::getMutex()
    1050             : {
    1051        1624 :     return m_aMutex;
    1052             : }
    1053             : 
    1054        1206 : void OControlModel::describeFixedAndAggregateProperties( Sequence< Property >& _out_rFixedProperties, Sequence< Property >& _out_rAggregateProperties ) const
    1055             : {
    1056        1206 :     describeFixedProperties( _out_rFixedProperties );
    1057        1206 :     describeAggregateProperties( _out_rAggregateProperties );
    1058        1206 : }
    1059             : 
    1060         304 : Reference< XMultiPropertySet > OControlModel::getPropertiesInterface()
    1061             : {
    1062         304 :     return Reference< XMultiPropertySet >( *this, UNO_QUERY );
    1063             : }
    1064             : 
    1065       41655 : Reference< XPropertySetInfo> SAL_CALL OControlModel::getPropertySetInfo() throw( RuntimeException, std::exception)
    1066             : {
    1067       41655 :     return createPropertySetInfo( getInfoHelper() );
    1068             : }
    1069             : 
    1070      339310 : ::cppu::IPropertyArrayHelper& OControlModel::getInfoHelper()
    1071             : {
    1072      339310 :     return m_aPropertyBagHelper.getInfoHelper();
    1073             : }
    1074             : 
    1075         152 : void SAL_CALL OControlModel::addProperty( const OUString& _rName, ::sal_Int16 _nAttributes, const Any& _rInitialValue ) throw (PropertyExistException, IllegalTypeException, IllegalArgumentException, RuntimeException, std::exception)
    1076             : {
    1077         152 :     m_aPropertyBagHelper.addProperty( _rName, _nAttributes, _rInitialValue );
    1078          38 : }
    1079             : 
    1080         114 : void SAL_CALL OControlModel::removeProperty( const OUString& _rName ) throw (UnknownPropertyException, NotRemoveableException, RuntimeException, std::exception)
    1081             : {
    1082         114 :     m_aPropertyBagHelper.removeProperty( _rName );
    1083          38 : }
    1084             : 
    1085          38 : Sequence< PropertyValue > SAL_CALL OControlModel::getPropertyValues() throw (RuntimeException, std::exception)
    1086             : {
    1087          38 :     return m_aPropertyBagHelper.getPropertyValues();
    1088             : }
    1089             : 
    1090         114 : void SAL_CALL OControlModel::setPropertyValues( const Sequence< PropertyValue >& _rProps ) throw (UnknownPropertyException, PropertyVetoException, IllegalArgumentException, WrappedTargetException, RuntimeException, std::exception)
    1091             : {
    1092         114 :     m_aPropertyBagHelper.setPropertyValues( _rProps );
    1093          38 : }
    1094             : 
    1095        2632 : void OControlModel::lockInstance( LockAccess )
    1096             : {
    1097        2632 :     m_aMutex.acquire();
    1098        2632 :     osl_atomic_increment( &m_lockCount );
    1099        2632 : }
    1100             : 
    1101        2632 : oslInterlockedCount OControlModel::unlockInstance( LockAccess )
    1102             : {
    1103             :     OSL_ENSURE( m_lockCount > 0, "OControlModel::unlockInstance: not locked!" );
    1104        2632 :     oslInterlockedCount lockCount = osl_atomic_decrement( &m_lockCount );
    1105        2632 :     m_aMutex.release();
    1106        2632 :     return lockCount;
    1107             : }
    1108             : 
    1109        2580 : void OControlModel::firePropertyChanges( const Sequence< sal_Int32 >& _rHandles, const Sequence< Any >& _rOldValues,
    1110             :                                         const Sequence< Any >& _rNewValues, LockAccess )
    1111             : {
    1112             :     OPropertySetHelper::fire(
    1113             :         const_cast< Sequence< sal_Int32 >& >( _rHandles ).getArray(),
    1114             :         _rNewValues.getConstArray(),
    1115             :         _rOldValues.getConstArray(),
    1116             :         _rHandles.getLength(),
    1117             :         sal_False
    1118        2580 :     );
    1119        2580 : }
    1120             : 
    1121             : // OBoundControlModel
    1122      159695 : Any SAL_CALL OBoundControlModel::queryAggregation( const Type& _rType ) throw (RuntimeException, std::exception)
    1123             : {
    1124      159695 :     Any aReturn( OControlModel::queryAggregation(_rType) );
    1125      159695 :     if (!aReturn.hasValue())
    1126             :     {
    1127        5242 :         aReturn = OBoundControlModel_BASE1::queryInterface(_rType);
    1128             : 
    1129        5242 :         if ( !aReturn.hasValue() && m_bCommitable )
    1130        3924 :             aReturn = OBoundControlModel_COMMITTING::queryInterface( _rType );
    1131             : 
    1132        5242 :         if ( !aReturn.hasValue() && m_bSupportsExternalBinding )
    1133        4352 :             aReturn = OBoundControlModel_BINDING::queryInterface( _rType );
    1134             : 
    1135        5242 :         if ( !aReturn.hasValue() && m_bSupportsValidation )
    1136        4086 :             aReturn = OBoundControlModel_VALIDATION::queryInterface( _rType );
    1137             :     }
    1138      159695 :     return aReturn;
    1139             : }
    1140             : 
    1141         582 : OBoundControlModel::OBoundControlModel(
    1142             :         const Reference< XComponentContext>& _rxFactory,
    1143             :         const OUString& _rUnoControlModelTypeName, const OUString& _rDefault,
    1144             :         const bool _bCommitable, const bool _bSupportExternalBinding, const bool _bSupportsValidation )
    1145             :     :OControlModel( _rxFactory, _rUnoControlModelTypeName, _rDefault, false )
    1146             :     ,OPropertyChangeListener( m_aMutex )
    1147             :     ,m_xField()
    1148             :     ,m_xAmbientForm()
    1149             :     ,m_nValuePropertyAggregateHandle( -1 )
    1150             :     ,m_nFieldType( DataType::OTHER )
    1151             :     ,m_bValuePropertyMayBeVoid( false )
    1152             :     ,m_aResetHelper( *this, m_aMutex )
    1153             :     ,m_aUpdateListeners(m_aMutex)
    1154             :     ,m_aFormComponentListeners( m_aMutex )
    1155             :     ,m_bInputRequired( true )
    1156             :     ,m_pAggPropMultiplexer( NULL )
    1157             :     ,m_bFormListening( false )
    1158             :     ,m_bLoaded(false)
    1159             :     ,m_bRequired(false)
    1160             :     ,m_bCommitable(_bCommitable)
    1161             :     ,m_bSupportsExternalBinding( _bSupportExternalBinding )
    1162             :     ,m_bSupportsValidation( _bSupportsValidation )
    1163             :     ,m_bForwardValueChanges(true)
    1164             :     ,m_bTransferingValue( false )
    1165             :     ,m_bIsCurrentValueValid( true )
    1166             :     ,m_bBindingControlsRO( false )
    1167             :     ,m_bBindingControlsEnable( false )
    1168             :     ,m_eControlValueChangeInstigator( eOther )
    1169         582 :     ,m_aLabelServiceName(FRM_SUN_COMPONENT_FIXEDTEXT)
    1170             : {
    1171             :     // start property listening at the aggregate
    1172         582 :     implInitAggMultiplexer( );
    1173         582 : }
    1174             : 
    1175          30 : OBoundControlModel::OBoundControlModel(
    1176             :         const OBoundControlModel* _pOriginal, const Reference< XComponentContext>& _rxFactory )
    1177             :     :OControlModel( _pOriginal, _rxFactory, true, false )
    1178             :     ,OPropertyChangeListener( m_aMutex )
    1179             :     ,m_xField()
    1180             :     ,m_xAmbientForm()
    1181             :     ,m_nValuePropertyAggregateHandle( _pOriginal->m_nValuePropertyAggregateHandle )
    1182             :     ,m_nFieldType( DataType::OTHER )
    1183             :     ,m_bValuePropertyMayBeVoid( _pOriginal->m_bValuePropertyMayBeVoid )
    1184             :     ,m_aResetHelper( *this, m_aMutex )
    1185             :     ,m_aUpdateListeners( m_aMutex )
    1186             :     ,m_aFormComponentListeners( m_aMutex )
    1187             :     ,m_xValidator( _pOriginal->m_xValidator )
    1188             :     ,m_bInputRequired( true )
    1189             :     ,m_pAggPropMultiplexer( NULL )
    1190             :     ,m_bFormListening( false )
    1191             :     ,m_bLoaded( false )
    1192             :     ,m_bRequired( false )
    1193             :     ,m_bCommitable( _pOriginal->m_bCommitable )
    1194             :     ,m_bSupportsExternalBinding( _pOriginal->m_bSupportsExternalBinding )
    1195             :     ,m_bSupportsValidation( _pOriginal->m_bSupportsValidation )
    1196             :     ,m_bForwardValueChanges( true )
    1197             :     ,m_bTransferingValue( false )
    1198             :     ,m_bIsCurrentValueValid( _pOriginal->m_bIsCurrentValueValid )
    1199             :     ,m_bBindingControlsRO( false )
    1200             :     ,m_bBindingControlsEnable( false )
    1201          30 :     ,m_eControlValueChangeInstigator( eOther )
    1202             : {
    1203             :     // start property listening at the aggregate
    1204          30 :     implInitAggMultiplexer( );
    1205          30 :     m_aLabelServiceName = _pOriginal->m_aLabelServiceName;
    1206          30 :     m_sValuePropertyName = _pOriginal->m_sValuePropertyName;
    1207          30 :     m_nValuePropertyAggregateHandle = _pOriginal->m_nValuePropertyAggregateHandle;
    1208          30 :     m_bValuePropertyMayBeVoid = _pOriginal->m_bValuePropertyMayBeVoid;
    1209          30 :     m_aValuePropertyType = _pOriginal->m_aValuePropertyType;
    1210          30 :     m_aControlSource = _pOriginal->m_aControlSource;
    1211          30 :     m_bInputRequired = _pOriginal->m_bInputRequired;
    1212             :     // m_xLabelControl, though being a property, is not to be cloned, not even the reference will be transferred.
    1213             :     // (the former should be clear - a clone of the object we're only referencing does not make sense)
    1214             :     // (the second would violate the restriction for label controls that they're part of the
    1215             :     // same form component hierarchy - we ourself are no part, yet, so we can't have a label control)
    1216             :     // start listening for changes at the value property
    1217          30 :     implInitValuePropertyListening( );
    1218          30 : }
    1219             : 
    1220        1156 : OBoundControlModel::~OBoundControlModel()
    1221             : {
    1222         578 :     if ( !OComponentHelper::rBHelper.bDisposed )
    1223             :     {
    1224           0 :         acquire();
    1225           0 :         dispose();
    1226             :     }
    1227             : 
    1228         578 :     doResetDelegator( );
    1229             :     OSL_ENSURE( m_pAggPropMultiplexer, "OBoundControlModel::~OBoundControlModel: what about my property multiplexer?" );
    1230         578 :     if ( m_pAggPropMultiplexer )
    1231             :     {
    1232         578 :         m_pAggPropMultiplexer->dispose();
    1233         578 :         m_pAggPropMultiplexer->release();
    1234         578 :         m_pAggPropMultiplexer = NULL;
    1235             :     }
    1236         578 : }
    1237             : 
    1238          30 : void OBoundControlModel::clonedFrom( const OControlModel* _pOriginal )
    1239             : {
    1240          30 :     const OBoundControlModel* pBoundOriginal = static_cast< const OBoundControlModel* >( _pOriginal );
    1241             :     // the value binding can be handled as if somebody called setValueBinding here
    1242             :     // By definition, bindings can be share between bindables
    1243          30 :     if ( pBoundOriginal && pBoundOriginal->m_xExternalBinding.is() )
    1244             :     {
    1245             :         try
    1246             :         {
    1247           0 :             setValueBinding( pBoundOriginal->m_xExternalBinding );
    1248             :         }
    1249             : 
    1250           0 :         catch( const Exception& )
    1251             :         {
    1252             :             DBG_UNHANDLED_EXCEPTION();
    1253             :         }
    1254             : 
    1255             :     }
    1256          30 : }
    1257             : 
    1258         612 : void OBoundControlModel::implInitAggMultiplexer( )
    1259             : {
    1260         612 :     increment( m_refCount );
    1261         612 :     if ( m_xAggregateSet.is() )
    1262             :     {
    1263         612 :         m_pAggPropMultiplexer = new OPropertyChangeMultiplexer( this, m_xAggregateSet, false );
    1264         612 :         m_pAggPropMultiplexer->acquire();
    1265             :     }
    1266             : 
    1267         612 :     decrement( m_refCount );
    1268         612 :     doSetDelegator();
    1269         612 : }
    1270             : 
    1271         594 : void OBoundControlModel::implInitValuePropertyListening( ) const
    1272             : {
    1273             :     // start listening for changes at the value property
    1274             :     // There are three pre-requisites for this to be done:
    1275             :     // 1. We support external value bindings. In this case, the changes in the control value need to
    1276             :     //    be propagated to the external binding immediately when they happen
    1277             :     // 2. We support external validation. In this case, we need to listen for changes in the value
    1278             :     //    property, since we need to revalidate then.
    1279             :     // 3. We are not committable. In this case, changes in the control value need to be propagated
    1280             :     //    to the database column immediately when they happen.
    1281         594 :     if ( m_bSupportsExternalBinding || m_bSupportsValidation || !m_bCommitable )
    1282             :     {
    1283             :         OSL_ENSURE( m_pAggPropMultiplexer, "OBoundControlModel::implInitValuePropertyListening: no multiplexer!" );
    1284         574 :         if ( m_pAggPropMultiplexer && !m_sValuePropertyName.isEmpty() )
    1285         574 :             m_pAggPropMultiplexer->addProperty( m_sValuePropertyName );
    1286             :     }
    1287         594 : }
    1288             : 
    1289          18 : void OBoundControlModel::initOwnValueProperty( const OUString& i_rValuePropertyName )
    1290             : {
    1291             :     OSL_PRECOND( m_sValuePropertyName.isEmpty() && -1 == m_nValuePropertyAggregateHandle,
    1292             :         "OBoundControlModel::initOwnValueProperty: value property is already initialized!" );
    1293             :     OSL_ENSURE( !i_rValuePropertyName.isEmpty(), "OBoundControlModel::initOwnValueProperty: invalid property name!" );
    1294          18 :     m_sValuePropertyName = i_rValuePropertyName;
    1295          18 : }
    1296             : 
    1297         564 : void OBoundControlModel::initValueProperty( const OUString& _rValuePropertyName, sal_Int32 _nValuePropertyExternalHandle )
    1298             : {
    1299             :     OSL_PRECOND( m_sValuePropertyName.isEmpty() && -1 == m_nValuePropertyAggregateHandle,
    1300             :         "OBoundControlModel::initValueProperty: value property is already initialized!" );
    1301             :     OSL_ENSURE( !_rValuePropertyName.isEmpty(), "OBoundControlModel::initValueProperty: invalid property name!" );
    1302             :     OSL_ENSURE( _nValuePropertyExternalHandle != -1, "OBoundControlModel::initValueProperty: invalid property handle!" );
    1303             : 
    1304         564 :     m_sValuePropertyName = _rValuePropertyName;
    1305         564 :     m_nValuePropertyAggregateHandle = getOriginalHandle( _nValuePropertyExternalHandle );
    1306             :     OSL_ENSURE( m_nValuePropertyAggregateHandle != -1, "OBoundControlModel::initValueProperty: unable to find the original handle!" );
    1307             : 
    1308         564 :     if ( m_nValuePropertyAggregateHandle != -1 )
    1309             :     {
    1310         564 :         Reference< XPropertySetInfo > xPropInfo( m_xAggregateSet->getPropertySetInfo(), UNO_SET_THROW );
    1311        1128 :         Property aValuePropDesc = xPropInfo->getPropertyByName( m_sValuePropertyName );
    1312         564 :         m_aValuePropertyType = aValuePropDesc.Type;
    1313        1128 :         m_bValuePropertyMayBeVoid = ( aValuePropDesc.Attributes & PropertyAttribute::MAYBEVOID ) != 0;
    1314             :     }
    1315             : 
    1316             :     // start listening for changes at the value property
    1317         564 :     implInitValuePropertyListening( );
    1318         564 : }
    1319             : 
    1320          40 : void OBoundControlModel::suspendValueListening( )
    1321             : {
    1322             :     OSL_PRECOND( !m_sValuePropertyName.isEmpty(), "OBoundControlModel::suspendValueListening: don't have a value property!" );
    1323             :     OSL_PRECOND( m_pAggPropMultiplexer, "OBoundControlModel::suspendValueListening: I *am* not listening!" );
    1324             : 
    1325          40 : if ( m_pAggPropMultiplexer )
    1326          40 :         m_pAggPropMultiplexer->lock();
    1327          40 : }
    1328             : 
    1329          40 : void OBoundControlModel::resumeValueListening( )
    1330             : {
    1331             :     OSL_PRECOND( !m_sValuePropertyName.isEmpty(), "OBoundControlModel::resumeValueListening: don't have a value property!" );
    1332             :     OSL_PRECOND( m_pAggPropMultiplexer, "OBoundControlModel::resumeValueListening: I *am* not listening at all!" );
    1333             :     OSL_PRECOND( !m_pAggPropMultiplexer || m_pAggPropMultiplexer->locked(), "OBoundControlModel::resumeValueListening: listening not suspended currently!" );
    1334          40 :     if ( m_pAggPropMultiplexer )
    1335          40 :         m_pAggPropMultiplexer->unlock();
    1336          40 : }
    1337             : 
    1338         128 : Sequence< Type > OBoundControlModel::_getTypes()
    1339             : {
    1340             :     TypeBag aTypes(
    1341             :         OControlModel::_getTypes(),
    1342             :         OBoundControlModel_BASE1::getTypes()
    1343         128 :     );
    1344             : 
    1345         128 :     if ( m_bCommitable )
    1346          88 :         aTypes.addTypes( OBoundControlModel_COMMITTING::getTypes() );
    1347             : 
    1348         128 :     if ( m_bSupportsExternalBinding )
    1349         128 :         aTypes.addTypes( OBoundControlModel_BINDING::getTypes() );
    1350             : 
    1351         128 :     if ( m_bSupportsValidation )
    1352         128 :         aTypes.addTypes( OBoundControlModel_VALIDATION::getTypes() );
    1353         128 :     return aTypes.getTypes();
    1354             : }
    1355             : 
    1356             : // OComponentHelper
    1357         580 : void OBoundControlModel::disposing()
    1358             : {
    1359         580 :     OControlModel::disposing();
    1360             : 
    1361         580 :     ::osl::ClearableMutexGuard aGuard(m_aMutex);
    1362             : 
    1363         580 :     if ( m_pAggPropMultiplexer )
    1364         580 :         m_pAggPropMultiplexer->dispose();
    1365             : 
    1366             :     // notify all our listeners
    1367        1160 :     com::sun::star::lang::EventObject aEvt( static_cast< XWeak* >( this ) );
    1368         580 :     m_aUpdateListeners.disposeAndClear( aEvt );
    1369         580 :     m_aResetHelper.disposing();
    1370             : 
    1371             :     // disconnect from our database column
    1372             :     // TODO: could we replace the following 5 lines with a call to impl_disconnectDatabaseColumn_noNotify?
    1373             :     // The only more thing which it does is calling onDisconnectedDbColumn - could this
    1374             :     // cause trouble? At least when we continue to call OControlModel::disposing before, it *may*.
    1375         580 :     if ( hasField() )
    1376             :     {
    1377           0 :         getField()->removePropertyChangeListener( PROPERTY_VALUE, this );
    1378           0 :         resetField();
    1379             :     }
    1380             : 
    1381         580 :     m_xCursor = NULL;
    1382        1160 :     Reference< XComponent > xComp( m_xLabelControl, UNO_QUERY );
    1383         580 :     if ( xComp.is() )
    1384           0 :         xComp->removeEventListener(static_cast< XEventListener* >( static_cast< XPropertyChangeListener* >( this ) ) );
    1385             :     // disconnect from our external value binding
    1386         580 :     if ( hasExternalValueBinding() )
    1387          18 :         disconnectExternalValueBinding();
    1388             :     // dito for the validator
    1389         580 :     if ( hasValidator() )
    1390         616 :         disconnectValidator( );
    1391         580 : }
    1392             : 
    1393         648 : void OBoundControlModel::onValuePropertyChange( ControlModelLock& i_rControLock )
    1394             : {
    1395         648 :     if ( hasExternalValueBinding() )
    1396             :     {
    1397             :         // the control value changed, while we have an external value binding
    1398             :         // -> forward the value to it
    1399           8 :         if ( m_eControlValueChangeInstigator != eExternalBinding )
    1400           0 :             transferControlValueToExternal( i_rControLock );
    1401             :     }
    1402             : 
    1403         640 :     else if ( !m_bCommitable && m_xColumnUpdate.is() )
    1404             :     {
    1405             :         // the control value changed, while we are  bound to a database column,
    1406             :         // but not committable (which means changes in the control have to be reflected to
    1407             :         // the underlying database column immediately)
    1408             :         // -> forward the value to the database column
    1409           0 :         if ( m_eControlValueChangeInstigator != eDbColumnBinding )
    1410           0 :             commitControlValueToDbColumn( false );
    1411             :     }
    1412             : 
    1413             :     // validate the new value
    1414         648 :     if ( m_bSupportsValidation )
    1415         593 :         recheckValidity( true );
    1416         648 : }
    1417             : 
    1418         638 : void OBoundControlModel::_propertyChanged( const PropertyChangeEvent& _rEvt ) throw ( RuntimeException )
    1419             : {
    1420         638 :     ControlModelLock aLock( *this );
    1421             :     OSL_ENSURE( _rEvt.PropertyName == m_sValuePropertyName,
    1422             :         "OBoundControlModel::_propertyChanged: where did this come from (1)?" );
    1423             :     OSL_ENSURE( m_pAggPropMultiplexer && !m_pAggPropMultiplexer->locked(),
    1424             :         "OBoundControlModel::_propertyChanged: where did this come from (2)?" );
    1425         638 :     if ( _rEvt.PropertyName == m_sValuePropertyName )
    1426             :     {
    1427         638 :         onValuePropertyChange( aLock );
    1428         638 :     }
    1429         638 : }
    1430             : 
    1431         128 : void OBoundControlModel::startAggregatePropertyListening( const OUString& _rPropertyName )
    1432             : {
    1433             :     OSL_PRECOND( m_pAggPropMultiplexer, "OBoundControlModel::startAggregatePropertyListening: no multiplexer!" );
    1434             :     OSL_ENSURE( !_rPropertyName.isEmpty(), "OBoundControlModel::startAggregatePropertyListening: invalid property name!" );
    1435         128 :     if ( m_pAggPropMultiplexer && !_rPropertyName.isEmpty() )
    1436             :     {
    1437         128 :         m_pAggPropMultiplexer->addProperty( _rPropertyName );
    1438             :     }
    1439         128 : }
    1440             : 
    1441        1016 : void OBoundControlModel::doFormListening( const bool _bStart )
    1442             : {
    1443             :     OSL_PRECOND( !hasExternalValueBinding(), "OBoundControlModel::doFormListening: external value binding should overrule the database binding!" );
    1444        1016 :     if ( isFormListening() == _bStart )
    1445        1016 :         return;
    1446        1016 :     if ( m_xAmbientForm.is() )
    1447         722 :         _bStart ? m_xAmbientForm->addLoadListener( this ) : m_xAmbientForm->removeLoadListener( this );
    1448        1016 :     Reference< XLoadable > xParentLoadable( getParent(), UNO_QUERY );
    1449        1016 :     if ( getParent().is() && !xParentLoadable.is() )
    1450             :     {
    1451             :         // if our parent does not directly support the XLoadable interface, then it might support the
    1452             :         // XRowSetSupplier/XRowSetChangeBroadcaster interfaces. In this case we have to listen for changes
    1453             :         // broadcasted by the latter.
    1454         162 :         Reference< XRowSetChangeBroadcaster > xRowSetBroadcaster( getParent(), UNO_QUERY );
    1455         162 :         if ( xRowSetBroadcaster.is() )
    1456         162 :             _bStart ? xRowSetBroadcaster->addRowSetChangeListener( this ) : xRowSetBroadcaster->removeRowSetChangeListener( this );
    1457             :     }
    1458             : 
    1459        1016 :     m_bFormListening = _bStart && m_xAmbientForm.is();
    1460             : }
    1461             : 
    1462             : // XChild
    1463        1254 : void SAL_CALL OBoundControlModel::setParent(const Reference<XInterface>& _rxParent) throw(com::sun::star::lang::NoSupportException, RuntimeException, std::exception)
    1464             : {
    1465        1254 :     ControlModelLock aLock( *this );
    1466        1928 :     FieldChangeNotifier aBoundFieldNotifier( aLock );
    1467        1254 :     if ( getParent() == _rxParent )
    1468        1834 :         return;
    1469             :     // disconnect from database column (which is controlled by parent, directly or indirectly)
    1470         674 :     if ( hasField() )
    1471           0 :         impl_disconnectDatabaseColumn_noNotify();
    1472             :     // log off old listeners
    1473         674 :     if ( isFormListening() )
    1474         250 :         doFormListening( false );
    1475             :     // actually set the new parent
    1476         674 :     OControlModel::setParent( _rxParent );
    1477             :     // a new parent means a new ambient form
    1478         674 :     impl_determineAmbientForm_nothrow();
    1479         674 :     if ( !hasExternalValueBinding() )
    1480             :     {
    1481             :         // log on new listeners
    1482         658 :         doFormListening( true );
    1483             :         // re-connect to database column of the new parent
    1484         658 :         if ( m_xAmbientForm.is() && m_xAmbientForm->isLoaded() )
    1485          62 :             impl_connectDatabaseColumn_noNotify( false );
    1486         674 :     }
    1487             : }
    1488             : 
    1489             : // XEventListener
    1490         390 : void SAL_CALL OBoundControlModel::disposing(const com::sun::star::lang::EventObject& _rEvent) throw (RuntimeException, std::exception)
    1491             : {
    1492         390 :     ControlModelLock aLock( *this );
    1493         390 :     if ( _rEvent.Source == getField() )
    1494             :     {
    1495          62 :         resetField();
    1496             :     }
    1497             : 
    1498         328 :     else if ( _rEvent.Source == m_xLabelControl )
    1499             :     {
    1500           0 :         Reference<XPropertySet> xOldValue = m_xLabelControl;
    1501           0 :         m_xLabelControl = NULL;
    1502             :         // fire a propertyChanged (when we leave aLock's scope)
    1503           0 :         aLock.addPropertyNotification( PROPERTY_ID_CONTROLLABEL, makeAny( xOldValue ), makeAny( m_xLabelControl ) );
    1504             :     }
    1505             : 
    1506         328 :     else if ( _rEvent.Source == m_xExternalBinding )
    1507             :     {   // *first* check for the external binding
    1508           0 :         disconnectExternalValueBinding( );
    1509             :     }
    1510             : 
    1511         328 :     else if ( _rEvent.Source == m_xValidator )
    1512             :     {   // *then* check for the validator. Reason is that bindings may also act as validator at the same
    1513             :         // time, in this case, the validator is automatically revoked when the binding is revoked
    1514           0 :         disconnectValidator( );
    1515             :     }
    1516             : 
    1517             :     else
    1518         328 :         OControlModel::disposing(_rEvent);
    1519         390 : }
    1520             : 
    1521             : // XServiceInfo
    1522         504 : StringSequence SAL_CALL OBoundControlModel::getSupportedServiceNames() throw(RuntimeException, std::exception)
    1523             : {
    1524             :     return ::comphelper::concatSequences(
    1525             :         getAggregateServiceNames(),
    1526             :         getSupportedServiceNames_Static()
    1527         504 :     );
    1528             : }
    1529             : 
    1530         504 : Sequence< OUString > SAL_CALL OBoundControlModel::getSupportedServiceNames_Static() throw( RuntimeException )
    1531             : {
    1532         504 :     Sequence< OUString > aOwnServiceNames( 1 );
    1533         504 :     aOwnServiceNames[ 0 ] = "com.sun.star.form.DataAwareControlModel";
    1534             :     return ::comphelper::concatSequences(
    1535             :         OControlModel::getSupportedServiceNames_Static(),
    1536             :         aOwnServiceNames
    1537         504 :     );
    1538             : }
    1539             : 
    1540             : // XPersist
    1541          30 : void SAL_CALL OBoundControlModel::write( const Reference<css::io::XObjectOutputStream>& _rxOutStream ) throw(css::io::IOException, RuntimeException, std::exception)
    1542             : {
    1543          30 :     OControlModel::write(_rxOutStream);
    1544          30 :     osl::MutexGuard aGuard(m_aMutex);
    1545             :     // Version
    1546          30 :     _rxOutStream->writeShort(0x0002);
    1547             :     // Controlsource
    1548          30 :     ::comphelper::operator<<( _rxOutStream, m_aControlSource);
    1549             :     // !!! IMPORTANT NOTE !!!
    1550             :     // don't write any new members here: this wouldn't be compatible with older versions, as OBoundControlModel
    1551             :     // is a base class which is called in derived classes "read" method. So if you increment the version
    1552             :     // and write new stuff, older office versions will read this in the _derived_ classes, which may result
    1553             :     // in anything from data loss to crash.
    1554             :     // (use writeCommonProperties instead, this is called in derived classes write-method)
    1555             :     // !!! EOIN !!!
    1556          30 : }
    1557             : 
    1558           0 : void OBoundControlModel::defaultCommonProperties()
    1559             : {
    1560           0 :     Reference<com::sun::star::lang::XComponent> xComp(m_xLabelControl, UNO_QUERY);
    1561           0 :     if (xComp.is())
    1562           0 :         xComp->removeEventListener(static_cast<com::sun::star::lang::XEventListener*>(static_cast<XPropertyChangeListener*>(this)));
    1563           0 :     m_xLabelControl = NULL;
    1564           0 : }
    1565             : 
    1566          26 : void OBoundControlModel::readCommonProperties(const Reference<css::io::XObjectInputStream>& _rxInStream)
    1567             : {
    1568          26 :     sal_Int32 nLen = _rxInStream->readLong();
    1569          26 :     Reference<css::io::XMarkableStream> xMark(_rxInStream, UNO_QUERY);
    1570             :     DBG_ASSERT(xMark.is(), "OBoundControlModel::readCommonProperties : can only work with markable streams !");
    1571          26 :     sal_Int32 nMark = xMark->createMark();
    1572             :     // read the reference to the label control
    1573          52 :     Reference<css::io::XPersistObject> xPersist;
    1574             :     sal_Int32 nUsedFlag;
    1575          26 :     nUsedFlag = _rxInStream->readLong();
    1576          26 :     if (nUsedFlag)
    1577           0 :         xPersist = _rxInStream->readObject();
    1578          26 :     m_xLabelControl.set(xPersist, css::uno::UNO_QUERY);
    1579          52 :     Reference< XComponent > xComp( m_xLabelControl, UNO_QUERY );
    1580          26 :     if (xComp.is())
    1581           0 :         xComp->addEventListener(static_cast<com::sun::star::lang::XEventListener*>(static_cast<XPropertyChangeListener*>(this)));
    1582             :     // read any other new common properties here
    1583             :     // skip the remaining bytes
    1584          26 :     xMark->jumpToMark(nMark);
    1585          26 :     _rxInStream->skipBytes(nLen);
    1586          52 :     xMark->deleteMark(nMark);
    1587          26 : }
    1588             : 
    1589          26 : void OBoundControlModel::writeCommonProperties(const Reference<css::io::XObjectOutputStream>& _rxOutStream)
    1590             : {
    1591          26 :     Reference<css::io::XMarkableStream> xMark(_rxOutStream, UNO_QUERY);
    1592             :     DBG_ASSERT(xMark.is(), "OBoundControlModel::writeCommonProperties : can only work with markable streams !");
    1593          26 :     sal_Int32 nMark = xMark->createMark();
    1594             :     // a placeholder where we will write the overall length (later in this method)
    1595          26 :     sal_Int32 nLen = 0;
    1596          26 :     _rxOutStream->writeLong(nLen);
    1597             :     // write the reference to the label control
    1598          52 :     Reference<css::io::XPersistObject> xPersist(m_xLabelControl, UNO_QUERY);
    1599          26 :     sal_Int32 nUsedFlag = 0;
    1600          26 :     if (xPersist.is())
    1601           0 :         nUsedFlag = 1;
    1602          26 :     _rxOutStream->writeLong(nUsedFlag);
    1603          26 :     if (xPersist.is())
    1604           0 :         _rxOutStream->writeObject(xPersist);
    1605             :     // write any other new common properties here
    1606             :     // write the correct length at the beginning of the block
    1607          26 :     nLen = xMark->offsetToMark(nMark) - sizeof(nLen);
    1608          26 :     xMark->jumpToMark(nMark);
    1609          26 :     _rxOutStream->writeLong(nLen);
    1610          26 :     xMark->jumpToFurthest();
    1611          52 :     xMark->deleteMark(nMark);
    1612          26 : }
    1613             : 
    1614          30 : void SAL_CALL OBoundControlModel::read( const Reference< css::io::XObjectInputStream >& _rxInStream ) throw(css::io::IOException, RuntimeException, std::exception)
    1615             : {
    1616          30 :     OControlModel::read(_rxInStream);
    1617          30 :     osl::MutexGuard aGuard(m_aMutex);
    1618          30 :     sal_uInt16 nVersion = _rxInStream->readShort(); (void)nVersion;
    1619          30 :     ::comphelper::operator>>( _rxInStream, m_aControlSource);
    1620          30 : }
    1621             : 
    1622      107822 : void OBoundControlModel::getFastPropertyValue(Any& rValue, sal_Int32 nHandle) const
    1623             : {
    1624      107822 :     switch (nHandle)
    1625             :     {
    1626             :         case PROPERTY_ID_INPUT_REQUIRED:
    1627        1920 :             rValue <<= m_bInputRequired;
    1628        1920 :             break;
    1629             :         case PROPERTY_ID_CONTROLSOURCEPROPERTY:
    1630        3742 :             rValue <<= m_sValuePropertyName;
    1631        3742 :             break;
    1632             :         case PROPERTY_ID_CONTROLSOURCE:
    1633        2270 :             rValue <<= m_aControlSource;
    1634        2270 :             break;
    1635             :         case PROPERTY_ID_BOUNDFIELD:
    1636         809 :             rValue <<= getField();
    1637         809 :             break;
    1638             :         case PROPERTY_ID_CONTROLLABEL:
    1639         652 :             if (!m_xLabelControl.is())
    1640         652 :                 rValue.clear();
    1641             :             else
    1642           0 :                 rValue <<= m_xLabelControl;
    1643         652 :             break;
    1644             :         default:
    1645       98429 :             OControlModel::getFastPropertyValue(rValue, nHandle);
    1646             :     }
    1647      107822 : }
    1648             : 
    1649       10782 : sal_Bool OBoundControlModel::convertFastPropertyValue(
    1650             :                                 Any& _rConvertedValue, Any& _rOldValue,
    1651             :                 sal_Int32 _nHandle,
    1652             :                                 const Any& _rValue)
    1653             :                 throw (com::sun::star::lang::IllegalArgumentException)
    1654             : {
    1655       10782 :     bool bModified(false);
    1656       10782 :     switch (_nHandle)
    1657             :     {
    1658             :         case PROPERTY_ID_INPUT_REQUIRED:
    1659        1136 :             bModified = tryPropertyValue( _rConvertedValue, _rOldValue, _rValue, m_bInputRequired );
    1660        1136 :             break;
    1661             :         case PROPERTY_ID_CONTROLSOURCE:
    1662        1319 :             bModified = tryPropertyValue(_rConvertedValue, _rOldValue, _rValue, m_aControlSource);
    1663        1319 :             break;
    1664             :         case PROPERTY_ID_BOUNDFIELD:
    1665             :             SAL_WARN("forms.component",  "OBoundControlModel::convertFastPropertyValue: BoundField should be a read-only property !" );
    1666           0 :             throw com::sun::star::lang::IllegalArgumentException();
    1667             :         case PROPERTY_ID_CONTROLLABEL:
    1668           0 :             if (!_rValue.hasValue())
    1669             :             {   // property set to void
    1670           0 :                 _rConvertedValue = Any();
    1671           0 :                 getFastPropertyValue(_rOldValue, _nHandle);
    1672           0 :                 bModified = m_xLabelControl.is();
    1673             :             }
    1674             : 
    1675             :             else
    1676             :             {
    1677           0 :                 bModified = tryPropertyValue(_rConvertedValue, _rOldValue, _rValue, m_xLabelControl);
    1678           0 :                 if (!m_xLabelControl.is())
    1679             :                     // an empty interface is interpreted as VOID
    1680           0 :                     _rOldValue.clear();
    1681             :             }
    1682             : 
    1683           0 :             break;
    1684             :         default:
    1685        8327 :             bModified = OControlModel::convertFastPropertyValue(_rConvertedValue, _rOldValue, _nHandle, _rValue);
    1686             :     }
    1687       10782 :     return bModified;
    1688             : }
    1689             : 
    1690           4 : Any OBoundControlModel::getPropertyDefaultByHandle( sal_Int32 _nHandle ) const
    1691             : {
    1692           4 :     Any aDefault;
    1693           4 :     switch ( _nHandle )
    1694             :     {
    1695             :         case PROPERTY_ID_INPUT_REQUIRED:
    1696           0 :             aDefault <<= true;
    1697           0 :             break;
    1698             :         case PROPERTY_ID_CONTROLSOURCE:
    1699           0 :             aDefault <<= OUString();
    1700           0 :             break;
    1701             :         case PROPERTY_ID_CONTROLLABEL:
    1702           0 :             aDefault <<= Reference< XPropertySet >();
    1703           0 :             break;
    1704             :     }
    1705           4 :     return aDefault;
    1706             : }
    1707             : 
    1708        2688 : void OBoundControlModel::setFastPropertyValue_NoBroadcast( sal_Int32 nHandle, const Any& rValue ) throw (Exception, std::exception)
    1709             : {
    1710        2688 :     switch (nHandle)
    1711             :     {
    1712             :         case PROPERTY_ID_INPUT_REQUIRED:
    1713         196 :             OSL_VERIFY( rValue >>= m_bInputRequired );
    1714         196 :             break;
    1715             :         case PROPERTY_ID_CONTROLSOURCE:
    1716         377 :             OSL_VERIFY( rValue >>= m_aControlSource );
    1717         377 :             break;
    1718             :         case PROPERTY_ID_BOUNDFIELD:
    1719             :             SAL_WARN("forms.component", "OBoundControlModel::setFastPropertyValue_NoBroadcast : BoundField should be a read-only property !");
    1720           0 :             throw com::sun::star::lang::IllegalArgumentException();
    1721             :         case PROPERTY_ID_CONTROLLABEL:
    1722             :         {
    1723           0 :             if ( rValue.hasValue() && ( rValue.getValueTypeClass() != TypeClass_INTERFACE ) )
    1724           0 :                 throw com::sun::star::lang::IllegalArgumentException();
    1725           0 :             Reference< XInterface > xNewValue( rValue, UNO_QUERY );
    1726           0 :             if ( !xNewValue.is() )
    1727             :             {   // set property to "void"
    1728           0 :                 Reference< XComponent > xComp( m_xLabelControl, UNO_QUERY );
    1729           0 :                 if ( xComp.is() )
    1730           0 :                     xComp->removeEventListener( static_cast< XPropertyChangeListener* >( this ) );
    1731           0 :                 m_xLabelControl = NULL;
    1732           0 :                 break;
    1733             :             }
    1734             : 
    1735           0 :             Reference< XControlModel >  xAsModel        ( xNewValue,        UNO_QUERY );
    1736           0 :             Reference< XServiceInfo >   xAsServiceInfo  ( xAsModel,         UNO_QUERY );
    1737           0 :             Reference< XPropertySet >   xAsPropSet      ( xAsServiceInfo,   UNO_QUERY );
    1738           0 :             Reference< XChild >         xAsChild        ( xAsPropSet,       UNO_QUERY );
    1739           0 :             if ( !xAsChild.is() || !xAsServiceInfo->supportsService( m_aLabelServiceName ) )
    1740             :             {
    1741           0 :                 throw com::sun::star::lang::IllegalArgumentException();
    1742             :             }
    1743             : 
    1744             :             // Check if we and the given model have a common ancestor (up to the forms collection)
    1745           0 :             Reference<XChild> xCont;
    1746           0 :             query_interface(static_cast<XWeak*>(this), xCont);
    1747           0 :             Reference< XInterface > xMyTopLevel = xCont->getParent();
    1748           0 :             while (xMyTopLevel.is())
    1749             :             {
    1750           0 :                 Reference<XForm> xAsForm(xMyTopLevel, UNO_QUERY);
    1751           0 :                 if (!xAsForm.is())
    1752             :                     // found my root
    1753           0 :                     break;
    1754           0 :                 Reference<XChild> xLoopAsChild(xMyTopLevel, UNO_QUERY);
    1755           0 :                 xMyTopLevel = xLoopAsChild.is() ? xLoopAsChild->getParent() : Reference< XInterface >();
    1756           0 :             }
    1757             : 
    1758           0 :             Reference< XInterface > xNewTopLevel = xAsChild->getParent();
    1759           0 :             while (xNewTopLevel.is())
    1760             :             {
    1761           0 :                 Reference<XForm> xAsForm(xNewTopLevel, UNO_QUERY);
    1762           0 :                 if (!xAsForm.is())
    1763           0 :                     break;
    1764           0 :                 Reference<XChild> xLoopAsChild(xNewTopLevel, UNO_QUERY);
    1765           0 :                 xNewTopLevel = xLoopAsChild.is() ? xLoopAsChild->getParent() : Reference< XInterface >();
    1766           0 :             }
    1767             : 
    1768           0 :             if (xNewTopLevel != xMyTopLevel)
    1769             :             {
    1770             :                 // the both objects don't belong to the same forms collection -> not acceptable
    1771           0 :                 throw com::sun::star::lang::IllegalArgumentException();
    1772             :             }
    1773             : 
    1774           0 :             m_xLabelControl = xAsPropSet;
    1775           0 :             Reference<com::sun::star::lang::XComponent> xComp(m_xLabelControl, UNO_QUERY);
    1776           0 :             if (xComp.is())
    1777           0 :                 xComp->addEventListener(static_cast<com::sun::star::lang::XEventListener*>(static_cast<XPropertyChangeListener*>(this)));
    1778             :         }
    1779             : 
    1780           0 :         break;
    1781             :         default:
    1782        2115 :             OControlModel::setFastPropertyValue_NoBroadcast(nHandle, rValue );
    1783             :     }
    1784        2688 : }
    1785             : 
    1786             : // XPropertyChangeListener
    1787           0 : void SAL_CALL OBoundControlModel::propertyChange( const PropertyChangeEvent& evt ) throw(RuntimeException, std::exception)
    1788             : {
    1789             :     // if the DBColumn value changed, transfer it to the control
    1790           0 :     if ( evt.PropertyName.equals( PROPERTY_VALUE ) )
    1791             :     {
    1792             :         OSL_ENSURE( evt.Source == getField(), "OBoundControlModel::propertyChange: value changes from components other than our database column?" );
    1793           0 :         osl::MutexGuard aGuard(m_aMutex);
    1794           0 :         if ( m_bForwardValueChanges && m_xColumn.is() )
    1795           0 :             transferDbValueToControl();
    1796             :     }
    1797             : 
    1798             :     else
    1799             :     {
    1800             :         OSL_ENSURE( evt.Source == m_xExternalBinding, "OBoundControlModel::propertyChange: where did this come from?" );
    1801             :         // our binding has properties which can control properties of ourself
    1802           0 :         OUString sBindingControlledProperty;
    1803           0 :         bool bForwardToLabelControl = false;
    1804           0 :         if ( evt.PropertyName.equals( PROPERTY_READONLY ) )
    1805             :         {
    1806           0 :             sBindingControlledProperty = PROPERTY_READONLY;
    1807             :         }
    1808             : 
    1809           0 :         else if ( evt.PropertyName.equals( PROPERTY_RELEVANT ) )
    1810             :         {
    1811           0 :             sBindingControlledProperty = PROPERTY_ENABLED;
    1812           0 :             bForwardToLabelControl = true;
    1813             :         }
    1814             : 
    1815             :         else
    1816           0 :             return;
    1817             :         try
    1818             :         {
    1819           0 :             setPropertyValue( sBindingControlledProperty, evt.NewValue );
    1820           0 :             if ( bForwardToLabelControl && m_xLabelControl.is() )
    1821           0 :                 m_xLabelControl->setPropertyValue( sBindingControlledProperty, evt.NewValue );
    1822             :         }
    1823             : 
    1824           0 :         catch( const Exception& )
    1825             :         {
    1826             :             SAL_WARN("forms.component",  "OBoundControlModel::propertyChange: could not adjust my binding-controlled property!");
    1827             :             DBG_UNHANDLED_EXCEPTION();
    1828           0 :         }
    1829             : 
    1830             :     }
    1831             : }
    1832             : 
    1833          20 : void SAL_CALL OBoundControlModel::onRowSetChanged( const EventObject& /*i_Event*/ ) throw (RuntimeException, std::exception)
    1834             : {
    1835          20 :     ControlModelLock aLock( *this );
    1836          40 :     FieldChangeNotifier aBoundFieldNotifier( aLock );
    1837             :     // disconnect from database column (which is controlled by parent, directly or indirectly)
    1838          20 :     if ( hasField() )
    1839           0 :         impl_disconnectDatabaseColumn_noNotify();
    1840             :     // log off old listeners
    1841          20 :     if ( isFormListening() )
    1842          20 :         doFormListening( false );
    1843             :     // determine the new ambient form
    1844          20 :     impl_determineAmbientForm_nothrow();
    1845             :     // log on new listeners
    1846          20 :     doFormListening( true );
    1847             :     // re-connect to database column if needed and possible
    1848          20 :     if ( m_xAmbientForm.is() && m_xAmbientForm->isLoaded() )
    1849          20 :         impl_connectDatabaseColumn_noNotify( false );
    1850          20 : }
    1851             : 
    1852             : // XBoundComponent
    1853           0 : void SAL_CALL OBoundControlModel::addUpdateListener(const Reference<XUpdateListener>& _rxListener) throw(RuntimeException, std::exception)
    1854             : {
    1855           0 :     m_aUpdateListeners.addInterface(_rxListener);
    1856           0 : }
    1857             : 
    1858           0 : void SAL_CALL OBoundControlModel::removeUpdateListener(const Reference< XUpdateListener>& _rxListener) throw(RuntimeException, std::exception)
    1859             : {
    1860           0 :     m_aUpdateListeners.removeInterface(_rxListener);
    1861           0 : }
    1862             : 
    1863          16 : sal_Bool SAL_CALL OBoundControlModel::commit() throw(RuntimeException, std::exception)
    1864             : {
    1865          16 :     ControlModelLock aLock( *this );
    1866             :     OSL_PRECOND( m_bCommitable, "OBoundControlModel::commit: invalid call (I'm not commitable !) " );
    1867          16 :     if ( hasExternalValueBinding() )
    1868             :     {
    1869             :         // in most cases, no action is required: For most derivees, we know the value property of
    1870             :         // our control (see initValueProperty), and when an external binding is active, we
    1871             :         // instantly forward all changes in this property to the external binding.
    1872           0 :         if ( m_sValuePropertyName.isEmpty() )
    1873             :             // but for those derivees which did not use this feature, we need an
    1874             :             // explicit transfer
    1875           0 :             transferControlValueToExternal( aLock );
    1876           0 :         return sal_True;
    1877             :     }
    1878             : 
    1879             :     OSL_ENSURE( !hasExternalValueBinding(), "OBoundControlModel::commit: control flow broken!" );
    1880             :         // we reach this only if we're not working with an external binding
    1881          16 :     if ( !hasField() )
    1882          16 :         return sal_True;
    1883           0 :     ::cppu::OInterfaceIteratorHelper aIter( m_aUpdateListeners );
    1884           0 :     EventObject aEvent;
    1885           0 :     aEvent.Source = static_cast< XWeak* >( this );
    1886           0 :     bool bSuccess = true;
    1887           0 :     aLock.release();
    1888             :     // UNSAFE >
    1889           0 :     while (aIter.hasMoreElements() && bSuccess)
    1890           0 :         bSuccess = static_cast< XUpdateListener* >( aIter.next() )->approveUpdate( aEvent );
    1891             :     // < UNSAFE
    1892           0 :     aLock.acquire();
    1893           0 :     if ( bSuccess )
    1894             :     {
    1895             :         try
    1896             :         {
    1897           0 :             if ( m_xColumnUpdate.is() )
    1898           0 :                 bSuccess = commitControlValueToDbColumn( false );
    1899             :         }
    1900             : 
    1901           0 :         catch(const Exception&)
    1902             :         {
    1903           0 :             bSuccess = false;
    1904             :         }
    1905             : 
    1906             :     }
    1907             : 
    1908           0 :     if ( bSuccess )
    1909             :     {
    1910           0 :         aLock.release();
    1911           0 :         m_aUpdateListeners.notifyEach( &XUpdateListener::updated, aEvent );
    1912             :     }
    1913          16 :     return bSuccess;
    1914             : }
    1915             : 
    1916          62 : void OBoundControlModel::resetField()
    1917             : {
    1918          62 :     m_xColumnUpdate.clear();
    1919          62 :     m_xColumn.clear();
    1920          62 :     m_xField.clear();
    1921          62 :     m_nFieldType = DataType::OTHER;
    1922          62 : }
    1923             : 
    1924          62 : bool OBoundControlModel::connectToField(const Reference<XRowSet>& rForm)
    1925             : {
    1926             :     OSL_PRECOND( !hasExternalValueBinding(), "OBoundControlModel::connectToField: invalid call (have an external binding)!" );
    1927             :     // if there's a connection to the database
    1928          62 :     if (rForm.is() && getConnection(rForm).is())
    1929             :     {
    1930             :         // determine field and PropertyChangeListener
    1931          62 :         m_xCursor = rForm;
    1932          62 :         Reference<XPropertySet> xFieldCandidate;
    1933          62 :         if (m_xCursor.is())
    1934             :         {
    1935          62 :             Reference<XColumnsSupplier> xColumnsSupplier(m_xCursor, UNO_QUERY);
    1936             :             DBG_ASSERT(xColumnsSupplier.is(), "OBoundControlModel::connectToField : the row set should support the com::sun::star::sdb::ResultSet service !");
    1937          62 :             if (xColumnsSupplier.is())
    1938             :             {
    1939          62 :                 Reference<XNameAccess> xColumns(xColumnsSupplier->getColumns(), UNO_QUERY);
    1940          62 :                 if (xColumns.is() && xColumns->hasByName(m_aControlSource))
    1941             :                 {
    1942          62 :                     OSL_VERIFY( xColumns->getByName(m_aControlSource) >>= xFieldCandidate );
    1943          62 :                 }
    1944             : 
    1945          62 :             }
    1946             : 
    1947             :         }
    1948             : 
    1949             :         try
    1950             :         {
    1951          62 :             sal_Int32 nFieldType = DataType::OTHER;
    1952          62 :             if ( xFieldCandidate.is() )
    1953             :             {
    1954          62 :                 xFieldCandidate->getPropertyValue( PROPERTY_FIELDTYPE ) >>= nFieldType;
    1955          62 :                 if ( approveDbColumnType( nFieldType ) )
    1956          62 :                     impl_setField_noNotify( xFieldCandidate );
    1957             :             }
    1958             : 
    1959             :             else
    1960           0 :                 impl_setField_noNotify( NULL );
    1961          62 :             if ( m_xField.is() )
    1962             :             {
    1963          62 :                 if ( m_xField->getPropertySetInfo()->hasPropertyByName( PROPERTY_VALUE ) )
    1964             :                 {
    1965          62 :                     m_nFieldType = nFieldType;
    1966             :                     // listen to changing values
    1967          62 :                     m_xField->addPropertyChangeListener( PROPERTY_VALUE, this );
    1968          62 :                     m_xColumnUpdate = Reference< XColumnUpdate >( m_xField, UNO_QUERY );
    1969          62 :                     m_xColumn = Reference< XColumn >( m_xField, UNO_QUERY );
    1970          62 :                     sal_Int32 nNullableFlag = ColumnValue::NO_NULLS;
    1971          62 :                     m_xField->getPropertyValue(PROPERTY_ISNULLABLE) >>= nNullableFlag;
    1972          62 :                     m_bRequired = (ColumnValue::NO_NULLS == nNullableFlag);
    1973             :                     // we're optimistic: in case of ColumnValue_NULLABLE_UNKNOWN we assume nullability...
    1974             :                 }
    1975             : 
    1976             :                 else
    1977             :                 {
    1978             :                     SAL_WARN("forms.component", "OBoundControlModel::connectToField: property " PROPERTY_VALUE " not supported!");
    1979           0 :                     impl_setField_noNotify( NULL );
    1980             :                 }
    1981             : 
    1982             :             }
    1983             : 
    1984             :         }
    1985             : 
    1986           0 :         catch( const Exception& )
    1987             :         {
    1988             :             DBG_UNHANDLED_EXCEPTION();
    1989           0 :             resetField();
    1990          62 :         }
    1991             : 
    1992             :     }
    1993          62 :     return hasField();
    1994             : }
    1995             : 
    1996          62 : void OBoundControlModel::initFromField( const Reference< XRowSet >& _rxRowSet )
    1997             : {
    1998             :     // but only if the rowset if posisitioned on a valid record
    1999          62 :     if ( hasField() && _rxRowSet.is() )
    2000             :     {
    2001          62 :         if ( !_rxRowSet->isBeforeFirst() && !_rxRowSet->isAfterLast() )
    2002          62 :             transferDbValueToControl();
    2003             :         else
    2004             :             // reset the field if the row set is empty
    2005             :             // #i30661#
    2006           0 :             resetNoBroadcast();
    2007             :     }
    2008          62 : }
    2009             : 
    2010          62 : bool OBoundControlModel::approveDbColumnType(sal_Int32 _nColumnType)
    2011             : {
    2012             :     OSL_PRECOND( !hasExternalValueBinding(), "OBoundControlModel::approveDbColumnType: invalid call (have an external binding)!" );
    2013          62 :     if ((_nColumnType == DataType::BINARY) || (_nColumnType == DataType::VARBINARY)
    2014          62 :         || (_nColumnType == DataType::LONGVARBINARY) || (_nColumnType == DataType::OTHER)
    2015          62 :         || (_nColumnType == DataType::OBJECT) || (_nColumnType == DataType::DISTINCT)
    2016          62 :         || (_nColumnType == DataType::STRUCT) || (_nColumnType == DataType::ARRAY)
    2017          62 :         || (_nColumnType == DataType::BLOB) /*|| (_nColumnType == DataType::CLOB)*/
    2018          62 :         || (_nColumnType == DataType::REF) || (_nColumnType == DataType::SQLNULL))
    2019           0 :         return false;
    2020          62 :     return true;
    2021             : }
    2022             : 
    2023         694 : void OBoundControlModel::impl_determineAmbientForm_nothrow()
    2024             : {
    2025         694 :     Reference< XInterface > xParent( const_cast< OBoundControlModel* >( this )->getParent() );
    2026         694 :     m_xAmbientForm.set( xParent, UNO_QUERY );
    2027         694 :     if ( !m_xAmbientForm.is() )
    2028             :     {
    2029         396 :         Reference< XRowSetSupplier > xSupRowSet( xParent, UNO_QUERY );
    2030         396 :         if ( xSupRowSet.is() )
    2031         126 :             m_xAmbientForm.set( xSupRowSet->getRowSet(), UNO_QUERY );
    2032         694 :     }
    2033         694 : }
    2034             : 
    2035          62 : void OBoundControlModel::impl_connectDatabaseColumn_noNotify( bool _bFromReload )
    2036             : {
    2037             :     OSL_PRECOND( !hasExternalValueBinding(), "OBoundControlModel::impl_connectDatabaseColumn_noNotify: not to be called with an external value binding!" );
    2038             :     // consistency checks
    2039             :     DBG_ASSERT( !( hasField() && !_bFromReload ),
    2040             :         "OBoundControlModel::impl_connectDatabaseColumn_noNotify: the form is just *loaded*, but we already have a field!" );
    2041             :     (void)_bFromReload;
    2042          62 :     Reference< XRowSet > xRowSet( m_xAmbientForm, UNO_QUERY );
    2043             :     OSL_ENSURE( xRowSet.is(), "OBoundControlModel::impl_connectDatabaseColumn_noNotify: no row set!" );
    2044          62 :     if ( !xRowSet.is() )
    2045          62 :         return;
    2046          62 :     if ( !hasField() )
    2047             :     {
    2048             :         // connect to the column
    2049          62 :         connectToField( xRowSet );
    2050             :     }
    2051             : 
    2052             :     // now that we're connected (more or less, even if we did not find a column),
    2053             :     // we definitely want to forward any potentially occurring value changes
    2054          62 :     m_bForwardValueChanges = true;
    2055             :     // let derived classes react on this new connection
    2056          62 :     m_bLoaded = true;
    2057          62 :     onConnectedDbColumn( xRowSet );
    2058             :     // initially transfer the db column value to the control, if we successfully connected to a database column
    2059          62 :     if ( hasField() )
    2060          62 :         initFromField( xRowSet );
    2061             : }
    2062             : 
    2063          62 : void OBoundControlModel::impl_disconnectDatabaseColumn_noNotify()
    2064             : {
    2065             :     OSL_PRECOND( !hasExternalValueBinding(), "OBoundControlModel::impl_disconnectDatabaseColumn_noNotify: not to be called with an external value binding!" );
    2066             :     // let derived classes react on this
    2067          62 :     onDisconnectedDbColumn();
    2068          62 :     if ( hasField() )
    2069             :     {
    2070           0 :         getField()->removePropertyChangeListener( PROPERTY_VALUE, this );
    2071           0 :         resetField();
    2072             :     }
    2073             : 
    2074          62 :     m_xCursor = NULL;
    2075          62 :     m_bLoaded = false;
    2076          62 : }
    2077             : 
    2078             : // XLoadListener
    2079           0 : void SAL_CALL OBoundControlModel::loaded( const EventObject& _rEvent ) throw(RuntimeException, std::exception)
    2080             : {
    2081           0 :     ControlModelLock aLock( *this );
    2082           0 :     FieldChangeNotifier aBoundFieldNotifier( aLock );
    2083             :     OSL_ENSURE( _rEvent.Source == m_xAmbientForm, "OBoundControlModel::loaded: where does this come from?" );
    2084             :     (void)_rEvent;
    2085             :     OSL_PRECOND( !hasExternalValueBinding(), "OBoundControlModel::loaded: we should never reach this with an external value binding!" );
    2086           0 :     if ( hasExternalValueBinding() )
    2087           0 :         return;
    2088           0 :     impl_connectDatabaseColumn_noNotify( false );
    2089             : }
    2090             : 
    2091          62 : void SAL_CALL OBoundControlModel::unloaded( const com::sun::star::lang::EventObject& /*aEvent*/ ) throw(RuntimeException, std::exception)
    2092             : {
    2093             :     OSL_PRECOND( !hasExternalValueBinding(), "OBoundControlModel::unloaded: we should never reach this with an external value binding!" );
    2094          62 : }
    2095             : 
    2096           0 : void SAL_CALL OBoundControlModel::reloading( const com::sun::star::lang::EventObject& /*aEvent*/ ) throw(RuntimeException, std::exception)
    2097             : {
    2098             :     OSL_PRECOND( !hasExternalValueBinding(), "OBoundControlModel::reloading: we should never reach this with an external value binding!" );
    2099           0 :     if ( hasExternalValueBinding() )
    2100           0 :         return;
    2101           0 :     osl::MutexGuard aGuard(m_aMutex);
    2102           0 :     m_bForwardValueChanges = false;
    2103             : }
    2104             : 
    2105          62 : void SAL_CALL OBoundControlModel::unloading(const com::sun::star::lang::EventObject& /*aEvent*/) throw(RuntimeException, std::exception)
    2106             : {
    2107          62 :     ControlModelLock aLock( *this );
    2108         124 :     FieldChangeNotifier aBoundFieldNotifier( aLock );
    2109             :     OSL_PRECOND( !hasExternalValueBinding(), "OBoundControlModel::unloading: we should never reach this with an external value binding!" );
    2110          62 :     if ( hasExternalValueBinding() )
    2111          62 :         return;
    2112         124 :     impl_disconnectDatabaseColumn_noNotify();
    2113             : }
    2114             : 
    2115           0 : void SAL_CALL OBoundControlModel::reloaded( const EventObject& _rEvent ) throw(RuntimeException, std::exception)
    2116             : {
    2117           0 :     ControlModelLock aLock( *this );
    2118           0 :     FieldChangeNotifier aBoundFieldNotifier( aLock );
    2119             :     OSL_ENSURE( _rEvent.Source == m_xAmbientForm, "OBoundControlModel::reloaded: where does this come from?" );
    2120             :     (void)_rEvent;
    2121             :     OSL_PRECOND( !hasExternalValueBinding(), "OBoundControlModel::reloaded: we should never reach this with an external value binding!" );
    2122           0 :     if ( hasExternalValueBinding() )
    2123           0 :         return;
    2124           0 :     impl_connectDatabaseColumn_noNotify( true );
    2125             : }
    2126             : 
    2127         466 : void OBoundControlModel::setControlValue( const Any& _rValue, ValueChangeInstigator _eInstigator )
    2128             : {
    2129         466 :     m_eControlValueChangeInstigator = _eInstigator;
    2130         466 :     doSetControlValue( _rValue );
    2131         466 :     m_eControlValueChangeInstigator = eOther;
    2132         466 : }
    2133             : 
    2134         454 : void OBoundControlModel::doSetControlValue( const Any& _rValue )
    2135             : {
    2136             :     OSL_PRECOND( m_xAggregateFastSet.is() && m_xAggregateSet.is(),
    2137             :         "OBoundControlModel::doSetControlValue: invalid aggregate !" );
    2138             :     OSL_PRECOND( !m_sValuePropertyName.isEmpty() || ( m_nValuePropertyAggregateHandle != -1 ),
    2139             :         "OBoundControlModel::doSetControlValue: please override if you have own value property handling!" );
    2140             :     try
    2141             :     {
    2142             :         // release our mutex once (it's acquired in one of the calling methods), as setting aggregate properties
    2143             :         // may cause any uno controls belonging to us to lock the solar mutex, which is potentially dangerous with
    2144             :         // our own mutex locked
    2145         454 :         MutexRelease aRelease( m_aMutex );
    2146         454 :         if ( ( m_nValuePropertyAggregateHandle != -1 ) && m_xAggregateFastSet.is() )
    2147             :         {
    2148         454 :             m_xAggregateFastSet->setFastPropertyValue( m_nValuePropertyAggregateHandle, _rValue );
    2149             :         }
    2150             : 
    2151           0 :         else if ( !m_sValuePropertyName.isEmpty() && m_xAggregateSet.is() )
    2152             :         {
    2153           0 :             m_xAggregateSet->setPropertyValue( m_sValuePropertyName, _rValue );
    2154         454 :         }
    2155             : 
    2156             :     }
    2157             : 
    2158          12 :     catch( const Exception& )
    2159             :     {
    2160             :         SAL_WARN("forms.component",  "OBoundControlModel::doSetControlValue: caught an exception!");
    2161             :         DBG_UNHANDLED_EXCEPTION();
    2162             :     }
    2163         454 : }
    2164             : 
    2165          36 : void OBoundControlModel::onConnectedValidator( )
    2166             : {
    2167             :     try
    2168             :     {
    2169             :         // if we have an external validator, we do not want the control to force invalid
    2170             :         // inputs to the default value. Instead, invalid inputs should be translated
    2171             :         // to NaN (not a number)
    2172          36 :         Reference< XPropertySetInfo > xAggregatePropertyInfo;
    2173          36 :         if ( m_xAggregateSet.is() )
    2174          36 :             xAggregatePropertyInfo = m_xAggregateSet->getPropertySetInfo();
    2175          36 :         if ( xAggregatePropertyInfo.is() && xAggregatePropertyInfo->hasPropertyByName( PROPERTY_ENFORCE_FORMAT ) )
    2176          16 :             m_xAggregateSet->setPropertyValue( PROPERTY_ENFORCE_FORMAT, makeAny( false ) );
    2177             :     }
    2178             : 
    2179           0 :     catch( const Exception& )
    2180             :     {
    2181             :         SAL_WARN("forms.component",  "OBoundControlModel::onConnectedValidator: caught an exception!");
    2182             :         DBG_UNHANDLED_EXCEPTION();
    2183             :     }
    2184             : 
    2185          36 :     recheckValidity( false );
    2186          36 : }
    2187             : 
    2188          36 : void OBoundControlModel::onDisconnectedValidator( )
    2189             : {
    2190             :     try
    2191             :     {
    2192          36 :         Reference< XPropertySetInfo > xAggregatePropertyInfo;
    2193          36 :         if ( m_xAggregateSet.is() )
    2194          36 :             xAggregatePropertyInfo = m_xAggregateSet->getPropertySetInfo();
    2195          36 :         if ( xAggregatePropertyInfo.is() && xAggregatePropertyInfo->hasPropertyByName( PROPERTY_ENFORCE_FORMAT ) )
    2196          16 :             m_xAggregateSet->setPropertyValue( PROPERTY_ENFORCE_FORMAT, makeAny( true ) );
    2197             :     }
    2198             : 
    2199           0 :     catch( const Exception& )
    2200             :     {
    2201             :         SAL_WARN("forms.component",  "OBoundControlModel::onDisconnectedValidator: caught an exception!");
    2202             :         DBG_UNHANDLED_EXCEPTION();
    2203             :     }
    2204             : 
    2205          36 :     recheckValidity( false );
    2206          36 : }
    2207             : 
    2208          34 : void OBoundControlModel::onConnectedExternalValue( )
    2209             : {
    2210          34 :     calculateExternalValueType();
    2211          34 : }
    2212             : 
    2213          34 : void OBoundControlModel::onDisconnectedExternalValue( )
    2214             : {
    2215          34 : }
    2216             : 
    2217          28 : void OBoundControlModel::onConnectedDbColumn( const Reference< XInterface >& /*_rxForm*/ )
    2218             : {
    2219             :     OSL_PRECOND( !hasExternalValueBinding(), "OBoundControlModel::onConnectedDbColumn: how this? There's an external value binding!" );
    2220          28 : }
    2221             : 
    2222          62 : void OBoundControlModel::onDisconnectedDbColumn()
    2223             : {
    2224             :     OSL_PRECOND( !hasExternalValueBinding(), "OBoundControlModel::onDisconnectedDbColumn: how this? There's an external value binding!" );
    2225          62 : }
    2226             : 
    2227             : // XReset
    2228           0 : Any OBoundControlModel::getDefaultForReset() const
    2229             : {
    2230           0 :     return Any();
    2231             : }
    2232             : 
    2233         293 : void OBoundControlModel::resetNoBroadcast()
    2234             : {
    2235         293 :     setControlValue( getDefaultForReset(), eOther );
    2236         293 : }
    2237             : 
    2238          78 : void OBoundControlModel::addResetListener(const Reference<XResetListener>& l) throw (RuntimeException, std::exception)
    2239             : {
    2240          78 :     m_aResetHelper.addResetListener( l );
    2241          78 : }
    2242             : 
    2243          52 : void OBoundControlModel::removeResetListener(const Reference<XResetListener>& l) throw (RuntimeException, std::exception)
    2244             : {
    2245          52 :     m_aResetHelper.removeResetListener( l );
    2246          52 : }
    2247             : 
    2248          86 : void OBoundControlModel::reset() throw (RuntimeException, std::exception)
    2249             : {
    2250          86 :     if ( !m_aResetHelper.approveReset() )
    2251         112 :        return;
    2252          60 :     ControlModelLock aLock( *this );
    2253             :     // on a new record?
    2254          60 :     bool bIsNewRecord = false;
    2255         120 :     Reference<XPropertySet> xSet( m_xCursor, UNO_QUERY );
    2256          60 :     if ( xSet.is() )
    2257             :     {
    2258             :         try
    2259             :         {
    2260           0 :             xSet->getPropertyValue( PROPERTY_ISNEW ) >>= bIsNewRecord;
    2261             :         }
    2262             : 
    2263           0 :         catch( const Exception& )
    2264             :         {
    2265             :             DBG_UNHANDLED_EXCEPTION();
    2266             :         }
    2267             : 
    2268             :     }
    2269             : 
    2270             :     // cursor on an invalid row?
    2271          60 :     bool bInvalidCursorPosition = true;
    2272             :     try
    2273             :     {
    2274          60 :         bInvalidCursorPosition =    m_xCursor.is()
    2275           0 :                                 &&  (  m_xCursor->isAfterLast()
    2276           0 :                                     || m_xCursor->isBeforeFirst()
    2277             :                                     )
    2278          60 :                                 &&  !bIsNewRecord;
    2279             :     }
    2280             : 
    2281           0 :     catch( const SQLException& )
    2282             :     {
    2283             :         SAL_WARN("forms.component",  "OBoundControlModel::reset: caught an SQL exception!" );
    2284             :         DBG_UNHANDLED_EXCEPTION();
    2285             :     }
    2286             : 
    2287             :     // #i24495# - don't count the insert row as "invalid"
    2288             :     bool bSimpleReset =
    2289          60 :                         (   !m_xColumn.is()                     // no connection to a database column
    2290           0 :                         ||  (   m_xCursor.is()                  // OR   we have an improperly positioned cursor
    2291           0 :                             &&  bInvalidCursorPosition
    2292             :                             )
    2293          60 :                         ||  hasExternalValueBinding()           // OR we have an external value binding
    2294          60 :                         );
    2295          60 :     if ( !bSimpleReset )
    2296             :     {
    2297             :         // The default values will be set if and only if the current value of the field which we're bound
    2298             :         // to is NULL.
    2299             :         // Else, the current field value should be refreshed
    2300             :         // This behaviour is not completely ... "matured": What should happen if the field as well as the
    2301             :         // control have a default value?
    2302           0 :         bool bIsNull = true;
    2303             :         // we have to access the field content at least once to get a reliable result by XColumn::wasNull
    2304             :         try
    2305             :         {
    2306             :             // normally, we'd do a getString here. However, this is extremely expensive in the case
    2307             :             // of binary fields. Unfortunately, getString is the only method which is guaranteed
    2308             :             // to *always* succeed, all other getXXX methods may fail if the column is asked for a
    2309             :             // non-convertible type
    2310           0 :             sal_Int32 nFieldType = DataType::OBJECT;
    2311           0 :             getField()->getPropertyValue( PROPERTY_FIELDTYPE ) >>= nFieldType;
    2312           0 :             if  (  ( nFieldType == DataType::BINARY        )
    2313           0 :                 || ( nFieldType == DataType::VARBINARY     )
    2314           0 :                 || ( nFieldType == DataType::LONGVARBINARY )
    2315           0 :                 || ( nFieldType == DataType::OBJECT        )
    2316             :                 /*|| ( nFieldType == DataType::CLOB          )*/
    2317             :                 )
    2318           0 :                 m_xColumn->getBinaryStream();
    2319           0 :             else if ( nFieldType == DataType::BLOB          )
    2320           0 :                 m_xColumn->getBlob();
    2321             :             else
    2322           0 :                 m_xColumn->getString();
    2323           0 :             bIsNull = m_xColumn->wasNull();
    2324             :         }
    2325             : 
    2326           0 :         catch(const Exception&)
    2327             :         {
    2328             :             SAL_WARN("forms.component", "OBoundControlModel::reset: this should have succeeded in all cases!");
    2329             :             DBG_UNHANDLED_EXCEPTION();
    2330             :         }
    2331             : 
    2332           0 :         bool bNeedValueTransfer = true;
    2333           0 :         if ( bIsNull )
    2334             :         {
    2335           0 :             if ( bIsNewRecord )
    2336             :             {
    2337             :                 // reset the control to it's default
    2338           0 :                 resetNoBroadcast();
    2339             :                 // and immediately commit the changes to the DB column, to keep consistency
    2340           0 :                 commitControlValueToDbColumn( true );
    2341           0 :                 bNeedValueTransfer = false;
    2342             :             }
    2343             : 
    2344             :         }
    2345             : 
    2346           0 :         if ( bNeedValueTransfer )
    2347           0 :             transferDbValueToControl();
    2348             :     }
    2349             : 
    2350             :     else
    2351             :     {
    2352          60 :         resetNoBroadcast();
    2353             :         // transfer to the external binding, if necessary
    2354          60 :         if ( hasExternalValueBinding() )
    2355           0 :             transferControlValueToExternal( aLock );
    2356             :     }
    2357             : 
    2358             :     // revalidate, if necessary
    2359          60 :     if ( hasValidator() )
    2360          36 :         recheckValidity( true );
    2361          60 :     aLock.release();
    2362         120 :     m_aResetHelper.notifyResetted();
    2363             : }
    2364             : 
    2365          62 : void OBoundControlModel::impl_setField_noNotify( const Reference< XPropertySet>& _rxField )
    2366             : {
    2367             :     DBG_ASSERT( !hasExternalValueBinding(), "OBoundControlModel::impl_setField_noNotify: We have an external value binding!" );
    2368          62 :     m_xField = _rxField;
    2369          62 : }
    2370             : 
    2371          34 : bool OBoundControlModel::impl_approveValueBinding_nolock( const Reference< XValueBinding >& _rxBinding )
    2372             : {
    2373          34 :     if ( !_rxBinding.is() )
    2374           0 :         return false;
    2375          34 :     Sequence< Type > aTypeCandidates;
    2376             :     {
    2377             :         // SYNCHRONIZED >
    2378          34 :         ::osl::MutexGuard aGuard( m_aMutex );
    2379          34 :         aTypeCandidates = getSupportedBindingTypes();
    2380             :         // < SYNCHRONIZED
    2381             :     }
    2382             : 
    2383          68 :     for (   const Type* pType = aTypeCandidates.getConstArray();
    2384          34 :             pType != aTypeCandidates.getConstArray() + aTypeCandidates.getLength();
    2385             :             ++pType
    2386             :         )
    2387             :     {
    2388          34 :         if ( _rxBinding->supportsType( *pType ) )
    2389          34 :             return true;
    2390             :     }
    2391           0 :     return false;
    2392             : }
    2393             : 
    2394          34 : void OBoundControlModel::connectExternalValueBinding(
    2395             :         const Reference< XValueBinding >& _rxBinding, ControlModelLock& _rInstanceLock )
    2396             : {
    2397             :     OSL_PRECOND( _rxBinding.is(), "OBoundControlModel::connectExternalValueBinding: invalid binding instance!" );
    2398             :     OSL_PRECOND( !hasExternalValueBinding( ), "OBoundControlModel::connectExternalValueBinding: precond not met (currently have a binding)!" );
    2399             :     // if we're connected to a database column, suspend this
    2400          34 :     if ( hasField() )
    2401           0 :         impl_disconnectDatabaseColumn_noNotify();
    2402             :     // suspend listening for load-related events at out ambient form.
    2403             :     // This is because an external value binding overrules a possible database binding.
    2404          34 :     if ( isFormListening() )
    2405          34 :         doFormListening( false );
    2406             :     // remember this new binding
    2407          34 :     m_xExternalBinding = _rxBinding;
    2408             :     // tell the derivee
    2409          34 :     onConnectedExternalValue();
    2410             :     try
    2411             :     {
    2412             :         // add as value listener so we get notified when the value changes
    2413          34 :         Reference< XModifyBroadcaster > xModifiable( m_xExternalBinding, UNO_QUERY );
    2414          34 :         if ( xModifiable.is() )
    2415           2 :             xModifiable->addModifyListener( this );
    2416             :         // add as property change listener for some (possibly present) properties we're
    2417             :         // interested in
    2418          68 :         Reference< XPropertySet > xBindingProps( m_xExternalBinding, UNO_QUERY );
    2419          68 :         Reference< XPropertySetInfo > xBindingPropsInfo( xBindingProps.is() ? xBindingProps->getPropertySetInfo() : Reference< XPropertySetInfo >() );
    2420          34 :         if ( xBindingPropsInfo.is() )
    2421             :         {
    2422           2 :             if ( xBindingPropsInfo->hasPropertyByName( PROPERTY_READONLY ) )
    2423             :             {
    2424           0 :                 xBindingProps->addPropertyChangeListener( PROPERTY_READONLY, this );
    2425           0 :                 m_bBindingControlsRO = true;
    2426             :             }
    2427             : 
    2428           2 :             if ( xBindingPropsInfo->hasPropertyByName( PROPERTY_RELEVANT ) )
    2429             :             {
    2430           0 :                 xBindingProps->addPropertyChangeListener( PROPERTY_RELEVANT, this );
    2431           0 :                 m_bBindingControlsEnable = true;
    2432             :             }
    2433             : 
    2434          34 :         }
    2435             : 
    2436             :     }
    2437             : 
    2438           0 :     catch( const Exception& )
    2439             :     {
    2440             :         DBG_UNHANDLED_EXCEPTION();
    2441             :     }
    2442             : 
    2443             :     // propagate our new value
    2444          34 :     transferExternalValueToControl( _rInstanceLock );
    2445             :     // if the binding is also a validator, use it, too. This is a constraint of the
    2446             :     // com.sun.star.form.binding.ValidatableBindableFormComponent service
    2447          34 :     if ( m_bSupportsValidation )
    2448             :     {
    2449             :         try
    2450             :         {
    2451          34 :             Reference< XValidator > xAsValidator( _rxBinding, UNO_QUERY );
    2452          34 :             if ( xAsValidator.is() )
    2453           0 :                 setValidator( xAsValidator );
    2454             :         }
    2455             : 
    2456           0 :         catch( const Exception& )
    2457             :         {
    2458             :             DBG_UNHANDLED_EXCEPTION();
    2459             :         }
    2460             : 
    2461             :     }
    2462          34 : }
    2463             : 
    2464          34 : void OBoundControlModel::disconnectExternalValueBinding( )
    2465             : {
    2466             :     try
    2467             :     {
    2468             :         // not listening at the binding anymore
    2469          34 :         Reference< XModifyBroadcaster > xModifiable( m_xExternalBinding, UNO_QUERY );
    2470          34 :         if ( xModifiable.is() )
    2471           2 :             xModifiable->removeModifyListener( this );
    2472             :         // remove as property change listener
    2473          68 :         Reference< XPropertySet > xBindingProps( m_xExternalBinding, UNO_QUERY );
    2474          34 :         if ( m_bBindingControlsRO )
    2475           0 :             xBindingProps->removePropertyChangeListener( PROPERTY_READONLY, this );
    2476          34 :         if ( m_bBindingControlsEnable )
    2477          34 :             xBindingProps->removePropertyChangeListener( PROPERTY_RELEVANT, this );
    2478             :     }
    2479             : 
    2480           0 :     catch( const Exception& )
    2481             :     {
    2482             :         SAL_WARN("forms.component",  "OBoundControlModel::disconnectExternalValueBinding: caught an exception!");
    2483             :         DBG_UNHANDLED_EXCEPTION();
    2484             :     }
    2485             : 
    2486             :     // if the binding also acts as our validator, disconnect the validator, too
    2487          34 :     if ( ( m_xExternalBinding == m_xValidator ) && m_xValidator.is() )
    2488           0 :         disconnectValidator( );
    2489             :     // no binding anymore
    2490          34 :     m_xExternalBinding.clear();
    2491             :     // be a load listener at our form, again. This was suspended while we had
    2492             :     // an external value binding in place.
    2493          34 :     doFormListening( true );
    2494             :     // re-connect to database column of the new parent
    2495          34 :     if ( m_xAmbientForm.is() && m_xAmbientForm->isLoaded() )
    2496           0 :         impl_connectDatabaseColumn_noNotify( false );
    2497             :     // tell the derivee
    2498          34 :     onDisconnectedExternalValue();
    2499          34 : }
    2500             : 
    2501          34 : void SAL_CALL OBoundControlModel::setValueBinding( const Reference< XValueBinding >& _rxBinding ) throw (IncompatibleTypesException, RuntimeException, std::exception)
    2502             : {
    2503             :     OSL_PRECOND( m_bSupportsExternalBinding, "OBoundControlModel::setValueBinding: How did you reach this method?" );
    2504             :     // the interface for this method should not have been exposed if we do not
    2505             :     // support binding to external data
    2506             :     // allow reset
    2507          34 :     if ( _rxBinding.is() && !impl_approveValueBinding_nolock( _rxBinding ) )
    2508             :     {
    2509             :         throw IncompatibleTypesException(
    2510             :             FRM_RES_STRING( RID_STR_INCOMPATIBLE_TYPES ),
    2511             :             *this
    2512           0 :         );
    2513             :     }
    2514             : 
    2515          34 :     ControlModelLock aLock( *this );
    2516             :     // since a ValueBinding overrules any potentially active database binding, the change in a ValueBinding
    2517             :     // might trigger a change in our BoundField.
    2518          68 :     FieldChangeNotifier aBoundFieldNotifier( aLock );
    2519             :     // disconnect from the old binding
    2520          34 :     if ( hasExternalValueBinding() )
    2521          16 :         disconnectExternalValueBinding( );
    2522             :     // connect to the new binding
    2523          34 :     if ( _rxBinding.is() )
    2524          68 :         connectExternalValueBinding( _rxBinding, aLock );
    2525          34 : }
    2526             : 
    2527         316 : Reference< XValueBinding > SAL_CALL OBoundControlModel::getValueBinding(  ) throw (RuntimeException, std::exception)
    2528             : {
    2529         316 :     ::osl::MutexGuard aGuard( m_aMutex );
    2530             :     OSL_PRECOND( m_bSupportsExternalBinding, "OBoundControlModel::getValueBinding: How did you reach this method?" );
    2531             :     // the interface for this method should not have been exposed if we do not
    2532             :     // support binding to external data
    2533         316 :     return m_xExternalBinding;
    2534             : }
    2535             : 
    2536           0 : void SAL_CALL OBoundControlModel::modified( const EventObject& _rEvent ) throw ( RuntimeException, std::exception )
    2537             : {
    2538           0 :     ControlModelLock aLock( *this );
    2539             :     OSL_PRECOND( hasExternalValueBinding(), "OBoundControlModel::modified: Where did this come from?" );
    2540           0 :     if ( !m_bTransferingValue && ( m_xExternalBinding == _rEvent.Source ) && m_xExternalBinding.is() )
    2541             :     {
    2542           0 :         transferExternalValueToControl( aLock );
    2543           0 :     }
    2544           0 : }
    2545             : 
    2546          62 : void OBoundControlModel::transferDbValueToControl( )
    2547             : {
    2548             :     try
    2549             :     {
    2550          62 :         setControlValue( translateDbColumnToControlValue(), eDbColumnBinding );
    2551             :     }
    2552             : 
    2553           0 :     catch( const Exception& )
    2554             :     {
    2555             :         DBG_UNHANDLED_EXCEPTION();
    2556             :     }
    2557          62 : }
    2558             : 
    2559          34 : void OBoundControlModel::transferExternalValueToControl( ControlModelLock& _rInstanceLock )
    2560             : {
    2561          34 :         Reference< XValueBinding > xExternalBinding( m_xExternalBinding );
    2562          68 :         Type aValueExchangeType( getExternalValueType() );
    2563          34 :         _rInstanceLock.release();
    2564             :         // UNSAFE >
    2565          68 :         Any aExternalValue;
    2566             :         try
    2567             :         {
    2568          34 :             aExternalValue = xExternalBinding->getValue( aValueExchangeType );
    2569             :         }
    2570             : 
    2571           0 :         catch( const Exception& )
    2572             :         {
    2573             :             DBG_UNHANDLED_EXCEPTION();
    2574             :         }
    2575             :         // < UNSAFE
    2576          34 :         _rInstanceLock.acquire();
    2577          68 :         setControlValue( translateExternalValueToControlValue( aExternalValue ), eExternalBinding );
    2578          34 : }
    2579             : 
    2580           0 : void OBoundControlModel::transferControlValueToExternal( ControlModelLock& _rInstanceLock )
    2581             : {
    2582             :     OSL_PRECOND( m_bSupportsExternalBinding && hasExternalValueBinding(),
    2583             :         "OBoundControlModel::transferControlValueToExternal: precondition not met!" );
    2584           0 :     if ( m_xExternalBinding.is() )
    2585             :     {
    2586           0 :         Any aExternalValue( translateControlValueToExternalValue() );
    2587           0 :         m_bTransferingValue = true;
    2588           0 :         _rInstanceLock.release();
    2589             :          // UNSAFE >
    2590             :         try
    2591             :         {
    2592           0 :             m_xExternalBinding->setValue( aExternalValue );
    2593             :         }
    2594             : 
    2595           0 :         catch( const Exception& )
    2596             :         {
    2597             :             DBG_UNHANDLED_EXCEPTION();
    2598             :         }
    2599             : 
    2600             :         // < UNSAFE
    2601           0 :         _rInstanceLock.acquire();
    2602           0 :         m_bTransferingValue = false;
    2603             :     }
    2604           0 : }
    2605             : 
    2606          24 : Sequence< Type > OBoundControlModel::getSupportedBindingTypes()
    2607             : {
    2608          24 :     return Sequence< Type >( &m_aValuePropertyType, 1 );
    2609             : }
    2610             : 
    2611          86 : void OBoundControlModel::calculateExternalValueType()
    2612             : {
    2613          86 :     m_aExternalValueType = Type();
    2614          86 :     if ( !m_xExternalBinding.is() )
    2615         138 :         return;
    2616          34 :     Sequence< Type > aTypeCandidates( getSupportedBindingTypes() );
    2617          68 :     for (   const Type* pTypeCandidate = aTypeCandidates.getConstArray();
    2618          34 :             pTypeCandidate != aTypeCandidates.getConstArray() + aTypeCandidates.getLength();
    2619             :             ++pTypeCandidate
    2620             :         )
    2621             :     {
    2622          34 :         if ( m_xExternalBinding->supportsType( *pTypeCandidate ) )
    2623             :         {
    2624          34 :             m_aExternalValueType = *pTypeCandidate;
    2625          34 :             break;
    2626             :         }
    2627          34 :     }
    2628             : }
    2629             : 
    2630          12 : Any OBoundControlModel::translateExternalValueToControlValue( const Any& _rExternalValue ) const
    2631             : {
    2632             :     OSL_PRECOND( m_bSupportsExternalBinding && hasExternalValueBinding(),
    2633             :         "OBoundControlModel::translateExternalValueToControlValue: precondition not met!" );
    2634          12 :     Any aControlValue( _rExternalValue );
    2635             :     // if the external value is VOID, and our value property is not allowed to be VOID,
    2636             :     // then default-construct a value
    2637          12 :     if ( !aControlValue.hasValue() && !m_bValuePropertyMayBeVoid )
    2638           0 :         aControlValue.setValue( NULL, m_aValuePropertyType );
    2639             :     // out of here
    2640          12 :     return aControlValue;
    2641             : }
    2642             : 
    2643           0 : Any OBoundControlModel::translateControlValueToExternalValue( ) const
    2644             : {
    2645           0 :     return getControlValue( );
    2646             : }
    2647             : 
    2648          90 : Any OBoundControlModel::translateControlValueToValidatableValue( ) const
    2649             : {
    2650             :     OSL_PRECOND( m_xValidator.is(), "OBoundControlModel::translateControlValueToValidatableValue: no validator, so why should I?" );
    2651          90 :     if ( ( m_xValidator == m_xExternalBinding ) && m_xValidator.is() )
    2652           0 :         return translateControlValueToExternalValue();
    2653          90 :     return getControlValue();
    2654             : }
    2655             : 
    2656         527 : Any OBoundControlModel::getControlValue( ) const
    2657             : {
    2658             :     OSL_PRECOND( m_xAggregateFastSet.is() && m_xAggregateSet.is(),
    2659             :         "OBoundControlModel::getControlValue: invalid aggregate !" );
    2660             :     OSL_PRECOND( !m_sValuePropertyName.isEmpty() || ( m_nValuePropertyAggregateHandle != -1 ),
    2661             :         "OBoundControlModel::getControlValue: please override if you have own value property handling!" );
    2662             :     // determine the current control value
    2663         527 :     Any aControlValue;
    2664         527 :     if ( ( m_nValuePropertyAggregateHandle != -1 ) && m_xAggregateFastSet.is() )
    2665             :     {
    2666         527 :         aControlValue = m_xAggregateFastSet->getFastPropertyValue( m_nValuePropertyAggregateHandle );
    2667             :     }
    2668             : 
    2669           0 :     else if ( !m_sValuePropertyName.isEmpty() && m_xAggregateSet.is() )
    2670             :     {
    2671           0 :         aControlValue = m_xAggregateSet->getPropertyValue( m_sValuePropertyName );
    2672             :     }
    2673         527 :     return aControlValue;
    2674             : }
    2675             : 
    2676          36 : void OBoundControlModel::connectValidator( const Reference< XValidator >& _rxValidator )
    2677             : {
    2678             :     OSL_PRECOND( _rxValidator.is(), "OBoundControlModel::connectValidator: invalid validator instance!" );
    2679             :     OSL_PRECOND( !hasValidator( ), "OBoundControlModel::connectValidator: precond not met (have a validator currently)!" );
    2680          36 :     m_xValidator = _rxValidator;
    2681             : 
    2682             :     // add as value listener so we get notified when the value changes
    2683          36 :     if ( m_xValidator.is() )
    2684             :     {
    2685             :         try
    2686             :         {
    2687          36 :             m_xValidator->addValidityConstraintListener( this );
    2688             :         }
    2689             : 
    2690           0 :         catch( const RuntimeException& )
    2691             :         {
    2692             :         }
    2693             :     }
    2694          36 :     onConnectedValidator( );
    2695          36 : }
    2696             : 
    2697          36 : void OBoundControlModel::disconnectValidator( )
    2698             : {
    2699             :     OSL_PRECOND( hasValidator( ), "OBoundControlModel::connectValidator: precond not met (don't have a validator currently)!" );
    2700             : 
    2701             :     // add as value listener so we get notified when the value changes
    2702          36 :     if ( m_xValidator.is() )
    2703             :     {
    2704             :         try
    2705             :         {
    2706          36 :             m_xValidator->removeValidityConstraintListener( this );
    2707             :         }
    2708             : 
    2709           0 :         catch( const RuntimeException& )
    2710             :         {
    2711             :         }
    2712             :     }
    2713             : 
    2714          36 :     m_xValidator.clear();
    2715             : 
    2716          36 :     onDisconnectedValidator( );
    2717          36 : }
    2718             : 
    2719          36 : void SAL_CALL OBoundControlModel::setValidator( const Reference< XValidator >& _rxValidator ) throw (VetoException,RuntimeException, std::exception)
    2720             : {
    2721          36 :     ::osl::ClearableMutexGuard aGuard( m_aMutex );
    2722             :     OSL_PRECOND( m_bSupportsValidation, "OBoundControlModel::setValidator: How did you reach this method?" );
    2723             :     // the interface for this method should not have been exposed if we do not
    2724             :     // support validation
    2725             : 
    2726             :     // early out if the validator does not change
    2727          36 :     if ( _rxValidator == m_xValidator )
    2728          36 :         return;
    2729             : 
    2730          36 :     if ( m_xValidator.is() && ( m_xValidator == m_xExternalBinding ) )
    2731             :         throw VetoException(
    2732             :             FRM_RES_STRING( RID_STR_INVALID_VALIDATOR ),
    2733             :             *this
    2734           0 :         );
    2735             : 
    2736             :     // disconnect from the old validator
    2737          36 :     if ( hasValidator() )
    2738           0 :         disconnectValidator( );
    2739             : 
    2740             :     // connect to the new validator
    2741          36 :     if ( _rxValidator.is() )
    2742          36 :         connectValidator( _rxValidator );
    2743             : }
    2744             : 
    2745          80 : Reference< XValidator > SAL_CALL OBoundControlModel::getValidator(  ) throw (RuntimeException, std::exception)
    2746             : {
    2747          80 :     ::osl::MutexGuard aGuard( m_aMutex );
    2748             :     OSL_PRECOND( m_bSupportsValidation, "OBoundControlModel::getValidator: How did you reach this method?" );
    2749             :     // the interface for this method should not have been exposed if we do not
    2750             :     // support validation
    2751             : 
    2752          80 :     return m_xValidator;
    2753             : }
    2754             : 
    2755          18 : void SAL_CALL OBoundControlModel::validityConstraintChanged( const EventObject& /*Source*/ ) throw (RuntimeException, std::exception)
    2756             : {
    2757          18 :     ::osl::ClearableMutexGuard aGuard( m_aMutex );
    2758             :     OSL_PRECOND( m_bSupportsValidation, "OBoundControlModel::validityConstraintChanged: How did you reach this method?" );
    2759             :     // the interface for this method should not have been exposed if we do not
    2760             :     // support validation
    2761             : 
    2762          18 :     recheckValidity( false );
    2763          18 : }
    2764             : 
    2765          80 : sal_Bool SAL_CALL OBoundControlModel::isValid(  ) throw (RuntimeException, std::exception)
    2766             : {
    2767          80 :     return m_bIsCurrentValueValid;
    2768             : }
    2769             : 
    2770          16 : ::com::sun::star::uno::Any OBoundControlModel::getCurrentFormComponentValue() const
    2771             : {
    2772          16 :     if ( hasValidator() )
    2773           0 :         return translateControlValueToValidatableValue();
    2774          16 :     return getControlValue();
    2775             : }
    2776             : 
    2777          18 : Any SAL_CALL OBoundControlModel::getCurrentValue(  ) throw (RuntimeException, std::exception)
    2778             : {
    2779          18 :     ::osl::MutexGuard aGuard( m_aMutex );
    2780          18 :     return getCurrentFormComponentValue();
    2781             : }
    2782             : 
    2783          42 : void SAL_CALL OBoundControlModel::addFormComponentValidityListener( const Reference< validation::XFormComponentValidityListener >& Listener ) throw (NullPointerException, RuntimeException, std::exception)
    2784             : {
    2785          42 :     if ( Listener.is() )
    2786          42 :         m_aFormComponentListeners.addInterface( Listener );
    2787          42 : }
    2788             : 
    2789          42 : void SAL_CALL OBoundControlModel::removeFormComponentValidityListener( const Reference< validation::XFormComponentValidityListener >& Listener ) throw (NullPointerException, RuntimeException, std::exception)
    2790             : {
    2791          42 :     if ( Listener.is() )
    2792          42 :         m_aFormComponentListeners.removeInterface( Listener );
    2793          42 : }
    2794             : 
    2795         719 : void OBoundControlModel::recheckValidity( bool _bForceNotification )
    2796             : {
    2797             :     try
    2798             :     {
    2799         719 :         bool bIsCurrentlyValid = true;
    2800         719 :         if ( hasValidator() )
    2801         200 :             bIsCurrentlyValid = m_xValidator->isValid( translateControlValueToValidatableValue() );
    2802             : 
    2803         719 :         if ( ( bIsCurrentlyValid != m_bIsCurrentValueValid ) || _bForceNotification )
    2804             :         {
    2805         665 :             m_bIsCurrentValueValid = bIsCurrentlyValid;
    2806             : 
    2807             :             // release our mutex for the notifications
    2808         665 :             MutexRelease aRelease( m_aMutex );
    2809         665 :             m_aFormComponentListeners.notifyEach( &validation::XFormComponentValidityListener::componentValidityChanged, EventObject( *this ) );
    2810             :         }
    2811             : 
    2812             :     }
    2813             : 
    2814           0 :     catch( const Exception& )
    2815             :     {
    2816             :         SAL_WARN("forms.component",  "OBoundControlModel::recheckValidity: caught an exception!");
    2817             :         DBG_UNHANDLED_EXCEPTION();
    2818             :     }
    2819         719 : }
    2820             : 
    2821         610 : void OBoundControlModel::describeFixedProperties( Sequence< Property >& _rProps ) const
    2822             : {
    2823         610 :     BEGIN_DESCRIBE_PROPERTIES( 5, OControlModel )
    2824         610 :         DECL_PROP1      ( CONTROLSOURCE,           OUString,     BOUND );
    2825         610 :         DECL_IFACE_PROP3( BOUNDFIELD,               XPropertySet,       BOUND, READONLY, TRANSIENT );
    2826         610 :         DECL_IFACE_PROP2( CONTROLLABEL,             XPropertySet,       BOUND, MAYBEVOID );
    2827         610 :         DECL_PROP2      ( CONTROLSOURCEPROPERTY,    OUString,    READONLY, TRANSIENT );
    2828         610 :         DECL_BOOL_PROP1 ( INPUT_REQUIRED,                               BOUND );
    2829             :     END_DESCRIBE_PROPERTIES()
    2830         610 : }
    2831             : }
    2832             : 
    2833             : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.10