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

Generated by: LCOV version 1.10