1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: FormComponent.cxx,v $
10 * $Revision: 1.62.8.2 $
12 * This file is part of OpenOffice.org.
14 * OpenOffice.org is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU Lesser General Public License version 3
16 * only, as published by the Free Software Foundation.
18 * OpenOffice.org is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Lesser General Public License version 3 for more details
22 * (a copy is included in the LICENSE file that accompanied this code).
24 * You should have received a copy of the GNU Lesser General Public License
25 * version 3 along with OpenOffice.org. If not, see
26 * <http://www.openoffice.org/license.html>
27 * for a copy of the LGPLv3 License.
29 ************************************************************************/
31 // MARKER(update_precomp.py): autogen include statement, do not remove
32 #include "precompiled_forms.hxx"
34 #include "componenttools.hxx"
35 #include "FormComponent.hxx"
36 #include "frm_resource.hrc"
37 #include "frm_resource.hxx"
38 #include "property.hrc"
39 #include "services.hxx"
41 /** === begin UNO includes === **/
42 #include <com/sun/star/awt/XTextComponent.hpp>
43 #include <com/sun/star/awt/XVclWindowPeer.hpp>
44 #include <com/sun/star/awt/XWindow.hpp>
45 #include <com/sun/star/form/XForm.hpp>
46 #include <com/sun/star/form/XLoadable.hpp>
47 #include <com/sun/star/io/XMarkableStream.hpp>
48 #include <com/sun/star/lang/DisposedException.hpp>
49 #include <com/sun/star/sdb/XRowSetChangeBroadcaster.hpp>
50 #include <com/sun/star/sdb/XRowSetSupplier.hpp>
51 #include <com/sun/star/sdbc/ColumnValue.hpp>
52 #include <com/sun/star/sdbc/DataType.hpp>
53 #include <com/sun/star/util/XModifyBroadcaster.hpp>
54 /** === end UNO includes === **/
56 #include <comphelper/basicio.hxx>
57 #include <comphelper/guarding.hxx>
58 #include <comphelper/listenernotification.hxx>
59 #include <comphelper/property.hxx>
60 #include <connectivity/dbtools.hxx>
61 #include <cppuhelper/queryinterface.hxx>
62 #include <rtl/logfile.hxx>
63 #include <toolkit/helper/emptyfontdescriptor.hxx>
64 #include <tools/debug.hxx>
65 #include <tools/diagnose_ex.h>
74 //... namespace frm .......................................................
77 //.........................................................................
79 using namespace ::com::sun::star::uno
;
80 using namespace ::com::sun::star::sdb
;
81 using namespace ::com::sun::star::sdbc
;
82 using namespace ::com::sun::star::sdbcx
;
83 using namespace ::com::sun::star::beans
;
84 using namespace ::com::sun::star::container
;
85 using namespace ::com::sun::star::form
;
86 using namespace ::com::sun::star::awt
;
87 using namespace ::com::sun::star::io
;
88 using namespace ::com::sun::star::lang
;
89 using namespace ::com::sun::star::util
;
90 using namespace ::com::sun::star::form::binding
;
91 using namespace ::com::sun::star::form::validation
;
92 using namespace ::dbtools
;
93 using namespace ::comphelper
;
95 //=========================================================================
96 //= FieldChangeNotifier
97 //=========================================================================
98 //-------------------------------------------------------------------------
99 void ControlModelLock::impl_notifyAll_nothrow()
101 m_rModel
.firePropertyChanges( m_aHandles
, m_aOldValues
, m_aNewValues
, OControlModel::LockAccess() );
104 //-------------------------------------------------------------------------
105 void ControlModelLock::addPropertyNotification( const sal_Int32 _nHandle
, const Any
& _rOldValue
, const Any
& _rNewValue
)
107 sal_Int32 nOldLength
= m_aHandles
.getLength();
108 if ( ( nOldLength
!= m_aOldValues
.getLength() )
109 || ( nOldLength
!= m_aNewValues
.getLength() )
111 throw RuntimeException( ::rtl::OUString(), m_rModel
);
113 m_aHandles
.realloc( nOldLength
+ 1 );
114 m_aHandles
[ nOldLength
] = _nHandle
;
115 m_aOldValues
.realloc( nOldLength
+ 1 );
116 m_aOldValues
[ nOldLength
] = _rOldValue
;
117 m_aNewValues
.realloc( nOldLength
+ 1 );
118 m_aNewValues
[ nOldLength
] = _rNewValue
;
121 //=========================================================================
122 //= FieldChangeNotifier
123 //=========================================================================
124 //-------------------------------------------------------------------------
125 class FieldChangeNotifier
128 FieldChangeNotifier( ControlModelLock
& _rLock
)
130 ,m_rModel( dynamic_cast< OBoundControlModel
& >( _rLock
.getModel() ) )
132 m_xOldField
= m_rModel
.getField();
135 ~FieldChangeNotifier()
137 Reference
< XPropertySet
> xNewField( m_rModel
.getField() );
138 if ( m_xOldField
!= xNewField
)
139 m_rLock
.addPropertyNotification( PROPERTY_ID_BOUNDFIELD
, makeAny( m_xOldField
), makeAny( xNewField
) );
143 ControlModelLock
& m_rLock
;
144 OBoundControlModel
& m_rModel
;
145 Reference
< XPropertySet
> m_xOldField
;
148 //=============================================================================
149 //= base class for form layer controls
150 //=============================================================================
151 DBG_NAME(frm_OControl
)
152 //------------------------------------------------------------------------------
153 OControl::OControl( const Reference
< XMultiServiceFactory
>& _rxFactory
, const rtl::OUString
& _rAggregateService
, const sal_Bool _bSetDelegator
)
154 :OComponentHelper(m_aMutex
)
155 ,m_aContext( _rxFactory
)
157 DBG_CTOR(frm_OControl
, NULL
);
158 // VCL-Control aggregieren
159 // bei Aggregation den Refcount um eins erhoehen da im setDelegator
160 // das Aggregat selbst den Refcount erhoeht
161 increment( m_refCount
);
163 m_xAggregate
= m_xAggregate
.query( _rxFactory
->createInstance( _rAggregateService
) );
164 m_xControl
= m_xControl
.query( m_xAggregate
);
166 decrement( m_refCount
);
168 if ( _bSetDelegator
)
172 //------------------------------------------------------------------------------
173 OControl::~OControl()
175 DBG_DTOR(frm_OControl
, NULL
);
179 //------------------------------------------------------------------------------
180 void OControl::doResetDelegator()
182 if ( m_xAggregate
.is() )
183 m_xAggregate
->setDelegator( NULL
);
186 //------------------------------------------------------------------------------
187 void OControl::doSetDelegator()
189 increment( m_refCount
);
190 if ( m_xAggregate
.is() )
191 { // those brackets are important for some compilers, don't remove!
192 // (they ensure that the temporary object created in the line below
193 // is destroyed *before* the refcount-decrement)
194 m_xAggregate
->setDelegator( static_cast< XWeak
* >( this ) );
196 decrement( m_refCount
);
200 //------------------------------------------------------------------------------
201 Any SAL_CALL
OControl::queryAggregation( const Type
& _rType
) throw(RuntimeException
)
203 // ask the base class
204 Any
aReturn( OComponentHelper::queryAggregation(_rType
) );
205 // ask our own interfaces
206 if (!aReturn
.hasValue())
208 aReturn
= OControl_BASE::queryInterface(_rType
);
210 if (!aReturn
.hasValue() && m_xAggregate
.is())
211 aReturn
= m_xAggregate
->queryAggregation(_rType
);
217 //------------------------------------------------------------------------------
218 Sequence
<sal_Int8
> SAL_CALL
OControl::getImplementationId() throw(RuntimeException
)
220 return OImplementationIds::getImplementationId(getTypes());
223 //------------------------------------------------------------------------------
224 Sequence
<Type
> SAL_CALL
OControl::getTypes() throw(RuntimeException
)
226 TypeBag
aTypes( _getTypes() );
228 Reference
< XTypeProvider
> xProv
;
229 if ( query_aggregation( m_xAggregate
, xProv
) )
230 aTypes
.addTypes( xProv
->getTypes() );
232 return aTypes
.getTypes();
235 //------------------------------------------------------------------------------
236 Sequence
<Type
> OControl::_getTypes()
238 return TypeBag( OComponentHelper::getTypes(), OControl_BASE::getTypes() ).getTypes();
241 //------------------------------------------------------------------------------
242 void OControl::initFormControlPeer( const Reference
< XWindowPeer
>& /*_rxPeer*/ )
244 // nothing to do here
248 //------------------------------------------------------------------------------
249 void OControl::disposing()
251 OComponentHelper::disposing();
253 m_aWindowStateGuard
.attach( NULL
, NULL
);
255 Reference
< XComponent
> xComp
;
256 if (query_aggregation(m_xAggregate
, xComp
))
261 //------------------------------------------------------------------------------
262 sal_Bool SAL_CALL
OControl::supportsService(const rtl::OUString
& _rsServiceName
) throw ( RuntimeException
)
264 Sequence
<rtl::OUString
> aSupported
= getSupportedServiceNames();
265 const rtl::OUString
* pSupported
= aSupported
.getConstArray();
266 for (sal_Int32 i
=0; i
<aSupported
.getLength(); ++i
, ++pSupported
)
267 if (pSupported
->equals(_rsServiceName
))
272 //------------------------------------------------------------------------------
273 Sequence
< ::rtl::OUString
> OControl::getAggregateServiceNames()
275 Sequence
< ::rtl::OUString
> aAggServices
;
276 Reference
< XServiceInfo
> xInfo
;
277 if ( query_aggregation( m_xAggregate
, xInfo
) )
278 aAggServices
= xInfo
->getSupportedServiceNames();
282 //------------------------------------------------------------------------------
283 Sequence
<rtl::OUString
> SAL_CALL
OControl::getSupportedServiceNames() throw(RuntimeException
)
285 return ::comphelper::concatSequences(
286 getAggregateServiceNames(),
287 getSupportedServiceNames_Static()
291 //------------------------------------------------------------------------------
292 Sequence
< ::rtl::OUString
> SAL_CALL
OControl::getSupportedServiceNames_Static() throw( RuntimeException
)
294 // no own supported service names
295 return Sequence
< ::rtl::OUString
>();
299 //------------------------------------------------------------------------------
300 void SAL_CALL
OControl::disposing(const com::sun::star::lang::EventObject
& _rEvent
) throw (RuntimeException
)
302 InterfaceRef xAggAsIface
;
303 query_aggregation(m_xAggregate
, xAggAsIface
);
305 // does the disposing come from the aggregate ?
306 if (xAggAsIface
!= InterfaceRef(_rEvent
.Source
, UNO_QUERY
))
307 { // no -> forward it
308 Reference
<com::sun::star::lang::XEventListener
> xListener
;
309 if (query_aggregation(m_xAggregate
, xListener
))
310 xListener
->disposing(_rEvent
);
315 //------------------------------------------------------------------------------
316 void SAL_CALL
OControl::setContext(const InterfaceRef
& Context
) throw (RuntimeException
)
319 m_xControl
->setContext(Context
);
322 //------------------------------------------------------------------------------
323 InterfaceRef SAL_CALL
OControl::getContext() throw (RuntimeException
)
325 return m_xControl
.is() ? m_xControl
->getContext() : InterfaceRef();
328 //------------------------------------------------------------------------------
329 void OControl::impl_resetStateGuard_nothrow()
331 Reference
< XWindow2
> xWindow
;
332 Reference
< XControlModel
> xModel
;
335 xWindow
.set( getPeer(), UNO_QUERY
);
336 xModel
.set( getModel(), UNO_QUERY
);
338 catch( const Exception
& )
340 DBG_UNHANDLED_EXCEPTION();
342 m_aWindowStateGuard
.attach( xWindow
, xModel
);
345 //------------------------------------------------------------------------------
346 void SAL_CALL
OControl::createPeer(const Reference
<XToolkit
>& _rxToolkit
, const Reference
<XWindowPeer
>& _rxParent
) throw (RuntimeException
)
348 if ( m_xControl
.is() )
350 m_xControl
->createPeer( _rxToolkit
, _rxParent
);
352 initFormControlPeer( getPeer() );
354 impl_resetStateGuard_nothrow();
358 //------------------------------------------------------------------------------
359 Reference
<XWindowPeer
> SAL_CALL
OControl::getPeer() throw ( RuntimeException
)
361 return m_xControl
.is() ? m_xControl
->getPeer() : Reference
<XWindowPeer
>();
364 //------------------------------------------------------------------------------
365 sal_Bool SAL_CALL
OControl::setModel(const Reference
<XControlModel
>& Model
) throw ( RuntimeException
)
367 if ( !m_xControl
.is() )
370 sal_Bool bSuccess
= m_xControl
->setModel( Model
);
371 impl_resetStateGuard_nothrow();
375 //------------------------------------------------------------------------------
376 Reference
<XControlModel
> SAL_CALL
OControl::getModel() throw ( RuntimeException
)
378 return m_xControl
.is() ? m_xControl
->getModel() : Reference
<XControlModel
>();
381 //------------------------------------------------------------------------------
382 Reference
<XView
> SAL_CALL
OControl::getView() throw ( RuntimeException
)
384 return m_xControl
.is() ? m_xControl
->getView() : Reference
<XView
>();
387 //------------------------------------------------------------------------------
388 void SAL_CALL
OControl::setDesignMode(sal_Bool bOn
) throw ( RuntimeException
)
391 m_xControl
->setDesignMode(bOn
);
394 //------------------------------------------------------------------------------
395 sal_Bool SAL_CALL
OControl::isDesignMode() throw ( RuntimeException
)
397 return m_xControl
.is() ? m_xControl
->isDesignMode() : sal_True
;
400 //------------------------------------------------------------------------------
401 sal_Bool SAL_CALL
OControl::isTransparent() throw ( RuntimeException
)
403 return m_xControl
.is() ? m_xControl
->isTransparent() : sal_True
;
406 //==================================================================
408 //==================================================================
409 DBG_NAME(frm_OBoundControl
);
410 //------------------------------------------------------------------
411 OBoundControl::OBoundControl( const Reference
< XMultiServiceFactory
>& _rxFactory
,
412 const ::rtl::OUString
& _rAggregateService
, const sal_Bool _bSetDelegator
)
413 :OControl( _rxFactory
, _rAggregateService
, _bSetDelegator
)
414 ,m_bLocked(sal_False
)
415 ,m_aOriginalFont( EmptyFontDescriptor() )
416 ,m_nOriginalTextLineColor( 0 )
418 DBG_CTOR(frm_OBoundControl
, NULL
);
421 //------------------------------------------------------------------
422 OBoundControl::~OBoundControl()
424 DBG_DTOR(frm_OBoundControl
, NULL
);
426 // -----------------------------------------------------------------------------
427 Sequence
< Type
> OBoundControl::_getTypes()
429 return TypeBag( OControl::_getTypes(), OBoundControl_BASE::getTypes() ).getTypes();
431 //------------------------------------------------------------------
432 Any SAL_CALL
OBoundControl::queryAggregation(const Type
& _rType
) throw(RuntimeException
)
436 // XTypeProvider first - don't ask the OBoundControl_BASE, it would deliver incomplete types
437 if ( _rType
.equals( ::getCppuType( static_cast< Reference
< XTypeProvider
>* >( NULL
) ) ) )
438 aReturn
= OControl::queryAggregation( _rType
);
440 // ask our own interfaces
441 // (do this first (except XTypeProvider ) - we want to "overwrite" XPropertiesChangeListener)
442 if ( !aReturn
.hasValue() )
443 aReturn
= OBoundControl_BASE::queryInterface( _rType
);
445 // ask the base class
446 if ( !aReturn
.hasValue() )
447 aReturn
= OControl::queryAggregation( _rType
);
452 //------------------------------------------------------------------
453 sal_Bool SAL_CALL
OBoundControl::getLock() throw(RuntimeException
)
458 //------------------------------------------------------------------
459 void SAL_CALL
OBoundControl::setLock(sal_Bool _bLock
) throw(RuntimeException
)
461 if (m_bLocked
== _bLock
)
464 osl::MutexGuard
aGuard(m_aMutex
);
469 //------------------------------------------------------------------
470 void OBoundControl::_setLock(sal_Bool _bLock
)
472 // try to set the text component to readonly
473 Reference
< XWindowPeer
> xPeer
= getPeer();
474 Reference
< XTextComponent
> xText( xPeer
, UNO_QUERY
);
477 xText
->setEditable( !_bLock
);
480 // disable the window
481 Reference
< XWindow
> xComp( xPeer
, UNO_QUERY
);
483 xComp
->setEnable( !_bLock
);
487 //--------------------------------------------------------------------
488 sal_Bool SAL_CALL
OBoundControl::setModel( const Reference
< XControlModel
>& _rxModel
) throw (RuntimeException
)
490 return OControl::setModel( _rxModel
);
493 //--------------------------------------------------------------------
494 void SAL_CALL
OBoundControl::disposing(const EventObject
& Source
) throw (RuntimeException
)
497 OControl::disposing(Source
);
500 //--------------------------------------------------------------------
501 void OBoundControl::disposing()
503 OControl::disposing();
506 //==================================================================
508 //==================================================================
509 DBG_NAME(OControlModel
)
510 //------------------------------------------------------------------
511 Sequence
<sal_Int8
> SAL_CALL
OControlModel::getImplementationId() throw(RuntimeException
)
513 // RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "forms", "dev@dba.openoffice.org", "OControlModel::getImplementationId" );
514 return OImplementationIds::getImplementationId(getTypes());
517 //------------------------------------------------------------------
518 Sequence
<Type
> SAL_CALL
OControlModel::getTypes() throw(RuntimeException
)
520 // RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "forms", "dev@dba.openoffice.org", "OControlModel::getTypes" );
521 TypeBag
aTypes( _getTypes() );
523 Reference
< XTypeProvider
> xProv
;
524 if ( query_aggregation( m_xAggregate
, xProv
) )
525 aTypes
.addTypes( xProv
->getTypes() );
527 return aTypes
.getTypes();
530 //------------------------------------------------------------------------------
531 Sequence
<Type
> OControlModel::_getTypes()
533 // RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "forms", "dev@dba.openoffice.org", "OControlModel::_getTypes" );
534 return TypeBag( OComponentHelper::getTypes(),
535 OPropertySetAggregationHelper::getTypes(),
536 OControlModel_BASE::getTypes()
540 //------------------------------------------------------------------
541 Any SAL_CALL
OControlModel::queryAggregation(const Type
& _rType
) throw (RuntimeException
)
543 // RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "forms", "dev@dba.openoffice.org", "OControlModel::queryAggregation" );
545 Any
aReturn(OComponentHelper::queryAggregation(_rType
));
548 if (!aReturn
.hasValue())
550 aReturn
= OControlModel_BASE::queryInterface(_rType
);
552 // our own interfaces
553 if (!aReturn
.hasValue())
555 aReturn
= OPropertySetAggregationHelper::queryInterface(_rType
);
557 if (!aReturn
.hasValue() && m_xAggregate
.is() && !_rType
.equals(::getCppuType(static_cast< Reference
< XCloneable
>* >(NULL
))))
558 aReturn
= m_xAggregate
->queryAggregation(_rType
);
564 //------------------------------------------------------------------------------
565 void OControlModel::readHelpTextCompatibly(const staruno::Reference
< stario::XObjectInputStream
>& _rxInStream
)
567 // RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "forms", "dev@dba.openoffice.org", "OControlModel::readHelpTextCompatibly" );
568 ::rtl::OUString sHelpText
;
569 ::comphelper::operator>>( _rxInStream
, sHelpText
);
572 if (m_xAggregateSet
.is())
573 m_xAggregateSet
->setPropertyValue(PROPERTY_HELPTEXT
, makeAny(sHelpText
));
575 catch(const Exception
&)
577 OSL_ENSURE(sal_False
, "OControlModel::readHelpTextCompatibly: could not forward the property value to the aggregate!");
581 //------------------------------------------------------------------------------
582 void OControlModel::writeHelpTextCompatibly(const staruno::Reference
< stario::XObjectOutputStream
>& _rxOutStream
)
584 // RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "forms", "dev@dba.openoffice.org", "OControlModel::writeHelpTextCompatibly" );
585 ::rtl::OUString sHelpText
;
588 if (m_xAggregateSet
.is())
589 m_xAggregateSet
->getPropertyValue(PROPERTY_HELPTEXT
) >>= sHelpText
;
591 catch(const Exception
&)
593 OSL_ENSURE(sal_False
, "OControlModel::writeHelpTextCompatibly: could not retrieve the property value from the aggregate!");
595 ::comphelper::operator<<( _rxOutStream
, sHelpText
);
598 //------------------------------------------------------------------
599 OControlModel::OControlModel(
600 const Reference
<com::sun::star::lang::XMultiServiceFactory
>& _rxFactory
,
601 const ::rtl::OUString
& _rUnoControlModelTypeName
,
602 const ::rtl::OUString
& rDefault
, const sal_Bool _bSetDelegator
)
603 :OComponentHelper(m_aMutex
)
604 ,OPropertySetAggregationHelper(OComponentHelper::rBHelper
)
605 ,m_aContext( _rxFactory
)
607 ,m_aPropertyBagHelper( *this )
608 ,m_nTabIndex(FRM_DEFAULT_TABINDEX
)
609 ,m_nClassId(FormComponentType::CONTROL
)
610 ,m_bNativeLook( sal_False
)
611 // form controls are usually embedded into documents, not dialogs, and in documents
612 // the native look is ugly ....
613 // #i37342# / 2004-11-19 / frank.schoenheit@sun.com
615 // RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "forms", "dev@dba.openoffice.org", "OControlModel::OControlModel" );
616 DBG_CTOR(OControlModel
, NULL
);
617 if (_rUnoControlModelTypeName
.getLength()) // the is a model we have to aggregate
619 increment(m_refCount
);
622 m_xAggregate
= Reference
<XAggregation
>(_rxFactory
->createInstance(_rUnoControlModelTypeName
), UNO_QUERY
);
623 setAggregation(m_xAggregate
);
625 if ( m_xAggregateSet
.is() )
629 if ( rDefault
.getLength() )
630 m_xAggregateSet
->setPropertyValue( PROPERTY_DEFAULTCONTROL
, makeAny( rDefault
) );
632 catch( const Exception
& )
634 OSL_ENSURE( sal_False
, "OControlModel::OControlModel: caught an exception!" );
642 // Refcount wieder bei NULL
643 decrement(m_refCount
);
647 //------------------------------------------------------------------
648 OControlModel::OControlModel( const OControlModel
* _pOriginal
, const Reference
< XMultiServiceFactory
>& _rxFactory
, const sal_Bool _bCloneAggregate
, const sal_Bool _bSetDelegator
)
649 :OComponentHelper( m_aMutex
)
650 ,OPropertySetAggregationHelper( OComponentHelper::rBHelper
)
651 ,m_aContext( _rxFactory
)
653 ,m_aPropertyBagHelper( *this )
654 ,m_nTabIndex( FRM_DEFAULT_TABINDEX
)
655 ,m_nClassId( FormComponentType::CONTROL
)
657 // RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "forms", "dev@dba.openoffice.org", "OControlModel::OControlModel(copy)" );
658 DBG_CTOR( OControlModel
, NULL
);
659 DBG_ASSERT( _pOriginal
, "OControlModel::OControlModel: invalid original!" );
662 m_aName
= _pOriginal
->m_aName
;
663 m_aTag
= _pOriginal
->m_aTag
;
664 m_nTabIndex
= _pOriginal
->m_nTabIndex
;
665 m_nClassId
= _pOriginal
->m_nClassId
;
666 m_bNativeLook
= _pOriginal
->m_bNativeLook
;
668 if ( _bCloneAggregate
)
670 // temporarily increment refcount because of temporary references to ourself in the following
671 increment( m_refCount
);
674 // transfer the (only, at the very moment!) ref count
675 m_xAggregate
= createAggregateClone( _pOriginal
);
677 // set aggregation (retrieve other direct interfaces of the aggregate)
678 setAggregation( m_xAggregate
);
681 // set the delegator, if allowed by our derived class
682 if ( _bSetDelegator
)
685 // decrement ref count
686 decrement( m_refCount
);
690 //------------------------------------------------------------------
691 OControlModel::~OControlModel()
693 // release the aggregate
696 DBG_DTOR(OControlModel
, NULL
);
699 //------------------------------------------------------------------
700 void OControlModel::clonedFrom( const OControlModel
* /*_pOriginal*/ )
702 // RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "forms", "dev@dba.openoffice.org", "OControlModel::clonedFrom" );
703 // nothing to do in this base class
706 //------------------------------------------------------------------------------
707 void OControlModel::doResetDelegator()
709 // RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "forms", "dev@dba.openoffice.org", "OControlModel::doResetDelegator" );
710 if (m_xAggregate
.is())
711 m_xAggregate
->setDelegator(NULL
);
714 //------------------------------------------------------------------------------
715 void OControlModel::doSetDelegator()
717 // RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "forms", "dev@dba.openoffice.org", "OControlModel::doSetDelegator" );
718 increment(m_refCount
);
719 if (m_xAggregate
.is())
721 m_xAggregate
->setDelegator(static_cast<XWeak
*>(this));
723 decrement(m_refCount
);
727 //------------------------------------------------------------------------------
728 InterfaceRef SAL_CALL
OControlModel::getParent() throw(RuntimeException
)
730 // RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "forms", "dev@dba.openoffice.org", "OControlModel::getParent" );
734 //------------------------------------------------------------------------------
735 void SAL_CALL
OControlModel::setParent(const InterfaceRef
& _rxParent
) throw(com::sun::star::lang::NoSupportException
, RuntimeException
)
737 // RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "forms", "dev@dba.openoffice.org", "OControlModel::setParent" );
738 osl::MutexGuard
aGuard(m_aMutex
);
740 Reference
<XComponent
> xComp(m_xParent
, UNO_QUERY
);
742 xComp
->removeEventListener(static_cast<XPropertiesChangeListener
*>(this));
744 m_xParent
= _rxParent
;
745 xComp
= xComp
.query( m_xParent
);
748 xComp
->addEventListener(static_cast<XPropertiesChangeListener
*>(this));
752 //------------------------------------------------------------------------------
753 ::rtl::OUString SAL_CALL
OControlModel::getName() throw(RuntimeException
)
755 // RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "forms", "dev@dba.openoffice.org", "OControlModel::getName" );
756 ::rtl::OUString aReturn
;
757 OPropertySetHelper::getFastPropertyValue(PROPERTY_ID_NAME
) >>= aReturn
;
761 //------------------------------------------------------------------------------
762 void SAL_CALL
OControlModel::setName(const ::rtl::OUString
& _rName
) throw(RuntimeException
)
764 // RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "forms", "dev@dba.openoffice.org", "OControlModel::setName" );
765 setFastPropertyValue(PROPERTY_ID_NAME
, makeAny(_rName
));
769 //------------------------------------------------------------------------------
770 sal_Bool SAL_CALL
OControlModel::supportsService(const rtl::OUString
& _rServiceName
) throw ( RuntimeException
)
772 // RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "forms", "dev@dba.openoffice.org", "OControlModel::supportsService" );
773 Sequence
<rtl::OUString
> aSupported
= getSupportedServiceNames();
774 const rtl::OUString
* pSupported
= aSupported
.getConstArray();
775 for (sal_Int32 i
=0; i
<aSupported
.getLength(); ++i
, ++pSupported
)
776 if (pSupported
->equals(_rServiceName
))
781 //------------------------------------------------------------------------------
782 Sequence
< ::rtl::OUString
> OControlModel::getAggregateServiceNames()
784 // RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "forms", "dev@dba.openoffice.org", "OControlModel::getAggregateServiceNames" );
785 Sequence
< ::rtl::OUString
> aAggServices
;
786 Reference
< XServiceInfo
> xInfo
;
787 if ( query_aggregation( m_xAggregate
, xInfo
) )
788 aAggServices
= xInfo
->getSupportedServiceNames();
792 //------------------------------------------------------------------------------
793 Sequence
<rtl::OUString
> SAL_CALL
OControlModel::getSupportedServiceNames() throw(RuntimeException
)
795 // RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "forms", "dev@dba.openoffice.org", "OControlModel::getSupportedServiceNames" );
796 return ::comphelper::concatSequences(
797 getAggregateServiceNames(),
798 getSupportedServiceNames_Static()
802 //------------------------------------------------------------------------------
803 Sequence
< ::rtl::OUString
> SAL_CALL
OControlModel::getSupportedServiceNames_Static() throw( RuntimeException
)
805 // RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "forms", "dev@dba.openoffice.org", "OControlModel::getSupportedServiceNames_Static" );
806 Sequence
< ::rtl::OUString
> aServiceNames( 2 );
807 aServiceNames
[ 0 ] = FRM_SUN_FORMCOMPONENT
;
808 aServiceNames
[ 1 ] = ::rtl::OUString::createFromAscii( "com.sun.star.form.FormControlModel" );
809 return aServiceNames
;
813 //------------------------------------------------------------------------------
814 void SAL_CALL
OControlModel::disposing(const com::sun::star::lang::EventObject
& _rSource
) throw (RuntimeException
)
816 // RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "forms", "dev@dba.openoffice.org", "OControlModel::disposing" );
817 // release the parent
818 if (_rSource
.Source
== m_xParent
)
820 osl::MutexGuard
aGuard(m_aMutex
);
825 Reference
<com::sun::star::lang::XEventListener
> xEvtLst
;
826 if (query_aggregation(m_xAggregate
, xEvtLst
))
828 osl::MutexGuard
aGuard(m_aMutex
);
829 xEvtLst
->disposing(_rSource
);
835 //-----------------------------------------------------------------------------
836 void OControlModel::disposing()
838 // RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "forms", "dev@dba.openoffice.org", "OControlModel::disposing" );
839 OPropertySetAggregationHelper::disposing();
841 Reference
<com::sun::star::lang::XComponent
> xComp
;
842 if (query_aggregation(m_xAggregate
, xComp
))
845 setParent(Reference
<XFormComponent
>());
847 m_aPropertyBagHelper
.dispose();
850 //------------------------------------------------------------------------------
851 void OControlModel::writeAggregate( const Reference
< XObjectOutputStream
>& _rxOutStream
) const
853 // RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "forms", "dev@dba.openoffice.org", "OControlModel::writeAggregate" );
854 Reference
< XPersistObject
> xPersist
;
855 if ( query_aggregation( m_xAggregate
, xPersist
) )
856 xPersist
->write( _rxOutStream
);
859 //------------------------------------------------------------------------------
860 void OControlModel::readAggregate( const Reference
< XObjectInputStream
>& _rxInStream
)
862 // RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "forms", "dev@dba.openoffice.org", "OControlModel::readAggregate" );
863 Reference
< XPersistObject
> xPersist
;
864 if ( query_aggregation( m_xAggregate
, xPersist
) )
865 xPersist
->read( _rxInStream
);
868 //------------------------------------------------------------------------------
869 void SAL_CALL
OControlModel::write(const Reference
<stario::XObjectOutputStream
>& _rxOutStream
)
870 throw(stario::IOException
, RuntimeException
)
872 // RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "forms", "dev@dba.openoffice.org", "OControlModel::write" );
873 osl::MutexGuard
aGuard(m_aMutex
);
875 // 1. Schreiben des UnoControls
876 Reference
<stario::XMarkableStream
> xMark(_rxOutStream
, UNO_QUERY
);
880 FRM_RES_STRING( RID_STR_INVALIDSTREAM
),
881 static_cast< ::cppu::OWeakObject
* >( this )
885 sal_Int32 nMark
= xMark
->createMark();
888 _rxOutStream
->writeLong(nLen
);
890 writeAggregate( _rxOutStream
);
892 // feststellen der Laenge
893 nLen
= xMark
->offsetToMark(nMark
) - 4;
894 xMark
->jumpToMark(nMark
);
895 _rxOutStream
->writeLong(nLen
);
896 xMark
->jumpToFurthest();
897 xMark
->deleteMark(nMark
);
899 // 2. Schreiben einer VersionsNummer
900 _rxOutStream
->writeShort(0x0003);
902 // 3. Schreiben der allgemeinen Properties
903 ::comphelper::operator<<( _rxOutStream
, m_aName
);
904 _rxOutStream
->writeShort(m_nTabIndex
);
905 ::comphelper::operator<<( _rxOutStream
, m_aTag
); // 3. version
907 // !!! IMPORTANT NOTE !!!
908 // don't write any new members here : this wouldn't be compatible with older versions, as OControlModel
909 // is a base class which is called in derived classes "read" method. So if you increment the version
910 // and write new stuff, older office versions will read this in the _derived_ classes, which may result
911 // in anything from data loss to crash.
915 //------------------------------------------------------------------------------
916 void OControlModel::read(const Reference
<stario::XObjectInputStream
>& InStream
) throw (::com::sun::star::io::IOException
, RuntimeException
)
918 // RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "forms", "dev@dba.openoffice.org", "OControlModel::read" );
919 osl::MutexGuard
aGuard(m_aMutex
);
921 Reference
<stario::XMarkableStream
> xMark(InStream
, UNO_QUERY
);
925 FRM_RES_STRING( RID_STR_INVALIDSTREAM
),
926 static_cast< ::cppu::OWeakObject
* >( this )
930 // 1. Lesen des UnoControls
931 sal_Int32 nLen
= InStream
->readLong();
934 sal_Int32 nMark
= xMark
->createMark();
938 readAggregate( InStream
);
940 catch( const Exception
& )
942 DBG_UNHANDLED_EXCEPTION();
945 xMark
->jumpToMark(nMark
);
946 InStream
->skipBytes(nLen
);
947 xMark
->deleteMark(nMark
);
950 // 2. Lesen des Versionsnummer
951 UINT16 nVersion
= InStream
->readShort();
953 // 3. Lesen der allgemeinen Properties
954 ::comphelper::operator>>( InStream
, m_aName
);
955 m_nTabIndex
= InStream
->readShort();
957 if (nVersion
> 0x0002)
958 ::comphelper::operator>>( InStream
, m_aTag
);
960 // we had a version where we wrote the help text
961 if (nVersion
== 0x0004)
962 readHelpTextCompatibly(InStream
);
964 DBG_ASSERT(nVersion
< 5, "OControlModel::read : suspicious version number !");
965 // 4 was the version where we wrote the help text
966 // later versions shouldn't exist (see write for a detailed comment)
969 //------------------------------------------------------------------------------
970 PropertyState
OControlModel::getPropertyStateByHandle( sal_Int32 _nHandle
)
972 // RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "forms", "dev@dba.openoffice.org", "OControlModel::getPropertyStateByHandle" );
973 // simply compare the current and the default value
974 Any aCurrentValue
= getPropertyDefaultByHandle( _nHandle
);
975 Any aDefaultValue
; getFastPropertyValue( aDefaultValue
, _nHandle
);
977 sal_Bool bEqual
= uno_type_equalData(
978 const_cast< void* >( aCurrentValue
.getValue() ), aCurrentValue
.getValueType().getTypeLibType(),
979 const_cast< void* >( aDefaultValue
.getValue() ), aDefaultValue
.getValueType().getTypeLibType(),
980 reinterpret_cast< uno_QueryInterfaceFunc
>(cpp_queryInterface
),
981 reinterpret_cast< uno_ReleaseFunc
>(cpp_release
)
983 return bEqual
? PropertyState_DEFAULT_VALUE
: PropertyState_DIRECT_VALUE
;
986 //------------------------------------------------------------------------------
987 void OControlModel::setPropertyToDefaultByHandle( sal_Int32 _nHandle
)
989 // RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "forms", "dev@dba.openoffice.org", "OControlModel::setPropertyToDefaultByHandle" );
990 Any aDefault
= getPropertyDefaultByHandle( _nHandle
);
992 Any aConvertedValue
, aOldValue
;
993 if ( convertFastPropertyValue( aConvertedValue
, aOldValue
, _nHandle
, aDefault
) )
995 setFastPropertyValue_NoBroadcast( _nHandle
, aConvertedValue
);
996 // TODO: fire the property change
1000 //------------------------------------------------------------------------------
1001 Any
OControlModel::getPropertyDefaultByHandle( sal_Int32 _nHandle
) const
1003 // RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "forms", "dev@dba.openoffice.org", "OControlModel::getPropertyDefaultByHandle" );
1007 case PROPERTY_ID_NAME
:
1008 case PROPERTY_ID_TAG
:
1009 aReturn
<<= ::rtl::OUString();
1012 case PROPERTY_ID_CLASSID
:
1013 aReturn
<<= (sal_Int16
)FormComponentType::CONTROL
;
1016 case PROPERTY_ID_TABINDEX
:
1017 aReturn
<<= (sal_Int16
)FRM_DEFAULT_TABINDEX
;
1020 case PROPERTY_ID_NATIVE_LOOK
:
1021 aReturn
<<= (sal_Bool
)sal_True
;
1025 if ( m_aPropertyBagHelper
.hasDynamicPropertyByHandle( _nHandle
) )
1026 m_aPropertyBagHelper
.getDynamicPropertyDefaultByHandle( _nHandle
, aReturn
);
1028 OSL_ENSURE( false, "OControlModel::convertFastPropertyValue: unknown handle!" );
1033 //------------------------------------------------------------------------------
1034 void OControlModel::getFastPropertyValue( Any
& _rValue
, sal_Int32 _nHandle
) const
1036 // RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "forms", "dev@dba.openoffice.org", "OControlModel::getFastPropertyValue" );
1039 case PROPERTY_ID_NAME
:
1040 _rValue
<<= m_aName
;
1042 case PROPERTY_ID_TAG
:
1045 case PROPERTY_ID_CLASSID
:
1046 _rValue
<<= m_nClassId
;
1048 case PROPERTY_ID_TABINDEX
:
1049 _rValue
<<= m_nTabIndex
;
1051 case PROPERTY_ID_NATIVE_LOOK
:
1052 _rValue
<<= (sal_Bool
)m_bNativeLook
;
1055 if ( m_aPropertyBagHelper
.hasDynamicPropertyByHandle( _nHandle
) )
1056 m_aPropertyBagHelper
.getDynamicFastPropertyValue( _nHandle
, _rValue
);
1058 OPropertySetAggregationHelper::getFastPropertyValue( _rValue
, _nHandle
);
1063 //------------------------------------------------------------------------------
1064 sal_Bool
OControlModel::convertFastPropertyValue(
1065 Any
& _rConvertedValue
, Any
& _rOldValue
, sal_Int32 _nHandle
, const Any
& _rValue
)
1066 throw (com::sun::star::lang::IllegalArgumentException
)
1068 // RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "forms", "dev@dba.openoffice.org", "OControlModel::convertFastPropertyValue" );
1069 sal_Bool
bModified(sal_False
);
1072 case PROPERTY_ID_NAME
:
1073 bModified
= tryPropertyValue(_rConvertedValue
, _rOldValue
, _rValue
, m_aName
);
1075 case PROPERTY_ID_TAG
:
1076 bModified
= tryPropertyValue(_rConvertedValue
, _rOldValue
, _rValue
, m_aTag
);
1078 case PROPERTY_ID_TABINDEX
:
1079 bModified
= tryPropertyValue(_rConvertedValue
, _rOldValue
, _rValue
, m_nTabIndex
);
1081 case PROPERTY_ID_NATIVE_LOOK
:
1082 bModified
= tryPropertyValue(_rConvertedValue
, _rOldValue
, _rValue
, m_bNativeLook
);
1085 if ( m_aPropertyBagHelper
.hasDynamicPropertyByHandle( _nHandle
) )
1086 bModified
= m_aPropertyBagHelper
.convertDynamicFastPropertyValue( _nHandle
, _rValue
, _rConvertedValue
, _rOldValue
);
1088 OSL_ENSURE( false, "OControlModel::convertFastPropertyValue: unknown handle!" );
1094 //------------------------------------------------------------------------------
1095 void OControlModel::setFastPropertyValue_NoBroadcast(sal_Int32 _nHandle
, const Any
& _rValue
)
1098 // RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "forms", "dev@dba.openoffice.org", "OControlModel::setFastPropertyValue_NoBroadcast" );
1101 case PROPERTY_ID_NAME
:
1102 DBG_ASSERT(_rValue
.getValueType() == getCppuType((const ::rtl::OUString
*)NULL
),
1103 "OControlModel::setFastPropertyValue_NoBroadcast : invalid type" );
1104 _rValue
>>= m_aName
;
1106 case PROPERTY_ID_TAG
:
1107 DBG_ASSERT(_rValue
.getValueType() == getCppuType((const ::rtl::OUString
*)NULL
),
1108 "OControlModel::setFastPropertyValue_NoBroadcast : invalid type" );
1111 case PROPERTY_ID_TABINDEX
:
1112 DBG_ASSERT(_rValue
.getValueType() == getCppuType((const sal_Int16
*)NULL
),
1113 "OControlModel::setFastPropertyValue_NoBroadcast : invalid type" );
1114 _rValue
>>= m_nTabIndex
;
1116 case PROPERTY_ID_NATIVE_LOOK
:
1117 OSL_VERIFY( _rValue
>>= m_bNativeLook
);
1120 if ( m_aPropertyBagHelper
.hasDynamicPropertyByHandle( _nHandle
) )
1121 m_aPropertyBagHelper
.setDynamicFastPropertyValue( _nHandle
, _rValue
);
1123 OSL_ENSURE( false, "OControlModel::setFastPropertyValue_NoBroadcast: unknown handle!" );
1128 //------------------------------------------------------------------------------
1129 void OControlModel::describeFixedProperties( Sequence
< Property
>& _rProps
) const
1131 // RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "forms", "dev@dba.openoffice.org", "OControlModel::describeFixedProperties" );
1132 BEGIN_DESCRIBE_BASE_PROPERTIES( 4 )
1133 DECL_PROP2 (CLASSID
, sal_Int16
, READONLY
, TRANSIENT
);
1134 DECL_PROP1 (NAME
, ::rtl::OUString
, BOUND
);
1135 DECL_BOOL_PROP2 (NATIVE_LOOK
, BOUND
, TRANSIENT
);
1136 DECL_PROP1 (TAG
, ::rtl::OUString
, BOUND
);
1137 END_DESCRIBE_PROPERTIES()
1140 //------------------------------------------------------------------------------
1141 void OControlModel::describeAggregateProperties( Sequence
< Property
>& /* [out] */ _rAggregateProps
) const
1143 // RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "forms", "dev@dba.openoffice.org", "OControlModel::describeAggregateProperties" );
1144 if ( m_xAggregateSet
.is() )
1146 Reference
< XPropertySetInfo
> xPSI( m_xAggregateSet
->getPropertySetInfo() );
1148 _rAggregateProps
= xPSI
->getProperties();
1152 //------------------------------------------------------------------------------
1153 ::osl::Mutex
& OControlModel::getMutex()
1155 // RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "forms", "dev@dba.openoffice.org", "OControlModel::getMutex" );
1159 //------------------------------------------------------------------------------
1160 void OControlModel::describeFixedAndAggregateProperties( Sequence
< Property
>& _out_rFixedProperties
, Sequence
< Property
>& _out_rAggregateProperties
) const
1162 // RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "forms", "dev@dba.openoffice.org", "OControlModel::describeFixedAndAggregateProperties" );
1163 describeFixedProperties( _out_rFixedProperties
);
1164 describeAggregateProperties( _out_rAggregateProperties
);
1167 //------------------------------------------------------------------------------
1168 Reference
< XMultiPropertySet
> OControlModel::getPropertiesInterface()
1170 // RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "forms", "dev@dba.openoffice.org", "OControlModel::getPropertiesInterface" );
1171 return Reference
< XMultiPropertySet
>( *this, UNO_QUERY
);
1174 //------------------------------------------------------------------------------
1175 Reference
< XPropertySetInfo
> SAL_CALL
OControlModel::getPropertySetInfo() throw( RuntimeException
)
1177 // RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "forms", "dev@dba.openoffice.org", "OControlModel::getPropertySetInfo" );
1178 return createPropertySetInfo( getInfoHelper() );
1181 //------------------------------------------------------------------------------
1182 ::cppu::IPropertyArrayHelper
& OControlModel::getInfoHelper()
1184 // RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "forms", "dev@dba.openoffice.org", "OControlModel::getInfoHelper" );
1185 return m_aPropertyBagHelper
.getInfoHelper();
1188 //--------------------------------------------------------------------
1189 void SAL_CALL
OControlModel::addProperty( const ::rtl::OUString
& _rName
, ::sal_Int16 _nAttributes
, const Any
& _rInitialValue
) throw (PropertyExistException
, IllegalTypeException
, IllegalArgumentException
, RuntimeException
)
1191 // RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "forms", "dev@dba.openoffice.org", "OControlModel::addProperty" );
1192 m_aPropertyBagHelper
.addProperty( _rName
, _nAttributes
, _rInitialValue
);
1195 //--------------------------------------------------------------------
1196 void SAL_CALL
OControlModel::removeProperty( const ::rtl::OUString
& _rName
) throw (UnknownPropertyException
, NotRemoveableException
, RuntimeException
)
1198 // RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "forms", "dev@dba.openoffice.org", "OControlModel::removeProperty" );
1199 m_aPropertyBagHelper
.removeProperty( _rName
);
1202 //--------------------------------------------------------------------
1203 Sequence
< PropertyValue
> SAL_CALL
OControlModel::getPropertyValues() throw (RuntimeException
)
1205 // RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "forms", "dev@dba.openoffice.org", "OControlModel::getPropertyValues" );
1206 return m_aPropertyBagHelper
.getPropertyValues();
1209 //--------------------------------------------------------------------
1210 void SAL_CALL
OControlModel::setPropertyValues( const Sequence
< PropertyValue
>& _rProps
) throw (UnknownPropertyException
, PropertyVetoException
, IllegalArgumentException
, WrappedTargetException
, RuntimeException
)
1212 // RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "forms", "dev@dba.openoffice.org", "OControlModel::setPropertyValues" );
1213 m_aPropertyBagHelper
.setPropertyValues( _rProps
);
1216 //--------------------------------------------------------------------
1217 void OControlModel::lockInstance( LockAccess
)
1220 osl_incrementInterlockedCount( &m_lockCount
);
1223 //--------------------------------------------------------------------
1224 oslInterlockedCount
OControlModel::unlockInstance( LockAccess
)
1226 OSL_ENSURE( m_lockCount
> 0, "OControlModel::unlockInstance: not locked!" );
1227 oslInterlockedCount lockCount
= osl_decrementInterlockedCount( &m_lockCount
);
1232 //--------------------------------------------------------------------
1233 void OControlModel::firePropertyChanges( const Sequence
< sal_Int32
>& _rHandles
, const Sequence
< Any
>& _rOldValues
,
1234 const Sequence
< Any
>& _rNewValues
, LockAccess
)
1236 OPropertySetHelper::fire(
1237 const_cast< Sequence
< sal_Int32
>& >( _rHandles
).getArray(),
1238 _rNewValues
.getConstArray(),
1239 _rOldValues
.getConstArray(),
1240 _rHandles
.getLength(),
1245 //==================================================================
1246 //= OBoundControlModel
1247 //==================================================================
1248 DBG_NAME(frm_OBoundControlModel
);
1249 //------------------------------------------------------------------
1250 Any SAL_CALL
OBoundControlModel::queryAggregation( const Type
& _rType
) throw (RuntimeException
)
1252 Any
aReturn( OControlModel::queryAggregation(_rType
) );
1253 if (!aReturn
.hasValue())
1255 // RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "forms", "dev@dba.openoffice.org", "OControlModel::queryAggregation" );
1256 aReturn
= OBoundControlModel_BASE1::queryInterface(_rType
);
1258 if ( !aReturn
.hasValue() && m_bCommitable
)
1259 aReturn
= OBoundControlModel_COMMITTING::queryInterface( _rType
);
1261 if ( !aReturn
.hasValue() && m_bSupportsExternalBinding
)
1262 aReturn
= OBoundControlModel_BINDING::queryInterface( _rType
);
1264 if ( !aReturn
.hasValue() && m_bSupportsValidation
)
1265 aReturn
= OBoundControlModel_VALIDATION::queryInterface( _rType
);
1271 //------------------------------------------------------------------
1272 OBoundControlModel::OBoundControlModel(
1273 const Reference
< XMultiServiceFactory
>& _rxFactory
,
1274 const ::rtl::OUString
& _rUnoControlModelTypeName
, const ::rtl::OUString
& _rDefault
,
1275 const sal_Bool _bCommitable
, const sal_Bool _bSupportExternalBinding
, const sal_Bool _bSupportsValidation
)
1276 :OControlModel( _rxFactory
, _rUnoControlModelTypeName
, _rDefault
, sal_False
)
1277 ,OPropertyChangeListener( m_aMutex
)
1280 ,m_nValuePropertyAggregateHandle( -1 )
1281 ,m_nFieldType( DataType::OTHER
)
1282 ,m_bValuePropertyMayBeVoid( false )
1283 ,m_aResetHelper( *this, m_aMutex
)
1284 ,m_aUpdateListeners(m_aMutex
)
1285 ,m_aFormComponentListeners( m_aMutex
)
1286 ,m_bInputRequired( sal_True
)
1287 ,m_pAggPropMultiplexer( NULL
)
1288 ,m_bFormListening( false )
1289 ,m_bLoaded(sal_False
)
1290 ,m_bRequired(sal_False
)
1291 ,m_bCommitable(_bCommitable
)
1292 ,m_bSupportsExternalBinding( _bSupportExternalBinding
)
1293 ,m_bSupportsValidation( _bSupportsValidation
)
1294 ,m_bForwardValueChanges(sal_True
)
1295 ,m_bTransferingValue( sal_False
)
1296 ,m_bIsCurrentValueValid( sal_True
)
1297 ,m_bBindingControlsRO( sal_False
)
1298 ,m_bBindingControlsEnable( sal_False
)
1299 ,m_eControlValueChangeInstigator( eOther
)
1300 ,m_aLabelServiceName(FRM_SUN_COMPONENT_FIXEDTEXT
)
1302 DBG_CTOR(frm_OBoundControlModel
, NULL
);
1304 // start property listening at the aggregate
1305 implInitAggMultiplexer( );
1308 //------------------------------------------------------------------
1309 OBoundControlModel::OBoundControlModel(
1310 const OBoundControlModel
* _pOriginal
, const Reference
< XMultiServiceFactory
>& _rxFactory
)
1311 :OControlModel( _pOriginal
, _rxFactory
, sal_True
, sal_False
)
1312 ,OPropertyChangeListener( m_aMutex
)
1315 ,m_nValuePropertyAggregateHandle( _pOriginal
->m_nValuePropertyAggregateHandle
)
1316 ,m_nFieldType( DataType::OTHER
)
1317 ,m_bValuePropertyMayBeVoid( _pOriginal
->m_bValuePropertyMayBeVoid
)
1318 ,m_aResetHelper( *this, m_aMutex
)
1319 ,m_aUpdateListeners( m_aMutex
)
1320 ,m_aFormComponentListeners( m_aMutex
)
1321 ,m_xValidator( _pOriginal
->m_xValidator
)
1322 ,m_bInputRequired( sal_True
)
1323 ,m_pAggPropMultiplexer( NULL
)
1324 ,m_bFormListening( false )
1325 ,m_bLoaded( sal_False
)
1326 ,m_bRequired( sal_False
)
1327 ,m_bCommitable( _pOriginal
->m_bCommitable
)
1328 ,m_bSupportsExternalBinding( _pOriginal
->m_bSupportsExternalBinding
)
1329 ,m_bSupportsValidation( _pOriginal
->m_bSupportsValidation
)
1330 ,m_bForwardValueChanges( sal_True
)
1331 ,m_bTransferingValue( sal_False
)
1332 ,m_bIsCurrentValueValid( _pOriginal
->m_bIsCurrentValueValid
)
1333 ,m_bBindingControlsRO( sal_False
)
1334 ,m_bBindingControlsEnable( sal_False
)
1335 ,m_eControlValueChangeInstigator( eOther
)
1337 DBG_CTOR(frm_OBoundControlModel
, NULL
);
1339 // start property listening at the aggregate
1340 implInitAggMultiplexer( );
1342 m_aLabelServiceName
= _pOriginal
->m_aLabelServiceName
;
1343 m_sValuePropertyName
= _pOriginal
->m_sValuePropertyName
;
1344 m_nValuePropertyAggregateHandle
= _pOriginal
->m_nValuePropertyAggregateHandle
;
1345 m_bValuePropertyMayBeVoid
= _pOriginal
->m_bValuePropertyMayBeVoid
;
1346 m_aValuePropertyType
= _pOriginal
->m_aValuePropertyType
;
1347 m_aControlSource
= _pOriginal
->m_aControlSource
;
1348 m_bInputRequired
= _pOriginal
->m_bInputRequired
;
1349 // m_xLabelControl, though being a property, is not to be cloned, not even the reference will be transfered.
1350 // (the former should be clear - a clone of the object we're only referencing does not make sense)
1351 // (the second would violate the restriction for label controls that they're part of the
1352 // same form component hierarchy - we ourself are no part, yet, so we can't have a label control)
1354 // start listening for changes at the value property
1355 implInitValuePropertyListening( );
1358 //------------------------------------------------------------------
1359 OBoundControlModel::~OBoundControlModel()
1361 if ( !OComponentHelper::rBHelper
.bDisposed
)
1367 doResetDelegator( );
1369 OSL_ENSURE( m_pAggPropMultiplexer
, "OBoundControlModel::~OBoundControlModel: what about my property multiplexer?" );
1370 if ( m_pAggPropMultiplexer
)
1372 m_pAggPropMultiplexer
->dispose();
1373 m_pAggPropMultiplexer
->release();
1374 m_pAggPropMultiplexer
= NULL
;
1377 DBG_DTOR(frm_OBoundControlModel
, NULL
);
1380 //------------------------------------------------------------------
1381 void OBoundControlModel::clonedFrom( const OControlModel
* _pOriginal
)
1383 const OBoundControlModel
* pBoundOriginal
= static_cast< const OBoundControlModel
* >( _pOriginal
);
1384 // the value binding can be handled as if somebody called setValueBinding here
1385 // By definition, bindings can be share between bindables
1386 if ( pBoundOriginal
&& pBoundOriginal
->m_xExternalBinding
.is() )
1390 setValueBinding( pBoundOriginal
->m_xExternalBinding
);
1392 catch( const Exception
& )
1394 DBG_UNHANDLED_EXCEPTION();
1399 //-----------------------------------------------------------------------------
1400 void OBoundControlModel::implInitAggMultiplexer( )
1402 increment( m_refCount
);
1403 if ( m_xAggregateSet
.is() )
1405 m_pAggPropMultiplexer
= new OPropertyChangeMultiplexer( this, m_xAggregateSet
, sal_False
);
1406 m_pAggPropMultiplexer
->acquire();
1408 decrement( m_refCount
);
1413 //-----------------------------------------------------------------------------
1414 void OBoundControlModel::implInitValuePropertyListening( ) const
1416 // start listening for changes at the value property
1417 // There are three pre-requisites for this to be done:
1418 // 1. We support external value bindings. In this case, the changes in the control value need to
1419 // be propagated to the external binding immediately when they happen
1420 // 2. We support external validation. In this case, we need to listen for changes in the value
1421 // property, since we need to revalidate then.
1422 // 3. We are not committable. In this case, changes in the control value need to be propagated
1423 // to the database column immediately when they happen.
1424 if ( m_bSupportsExternalBinding
|| m_bSupportsValidation
|| !m_bCommitable
)
1426 OSL_ENSURE( m_pAggPropMultiplexer
, "OBoundControlModel::implInitValuePropertyListening: no multiplexer!" );
1427 if ( m_pAggPropMultiplexer
&& m_sValuePropertyName
.getLength() )
1428 m_pAggPropMultiplexer
->addProperty( m_sValuePropertyName
);
1432 //-----------------------------------------------------------------------------
1433 void OBoundControlModel::initValueProperty( const ::rtl::OUString
& _rValuePropertyName
, sal_Int32 _nValuePropertyExternalHandle
)
1435 OSL_PRECOND( !m_sValuePropertyName
.getLength() && -1 == m_nValuePropertyAggregateHandle
,
1436 "OBoundControlModel::initValueProperty: already called before!" );
1437 OSL_ENSURE( _rValuePropertyName
.getLength(), "OBoundControlModel::initValueProperty: invalid property name!" );
1438 OSL_ENSURE( _nValuePropertyExternalHandle
!= -1, "OBoundControlModel::initValueProperty: invalid property handle!" );
1440 m_sValuePropertyName
= _rValuePropertyName
;
1441 m_nValuePropertyAggregateHandle
= getOriginalHandle( _nValuePropertyExternalHandle
);
1442 OSL_ENSURE( m_nValuePropertyAggregateHandle
!= -1, "OBoundControlModel::initValueProperty: unable to find the original handle!" );
1444 if ( m_nValuePropertyAggregateHandle
!= -1 )
1446 Reference
< XPropertySetInfo
> xPropInfo( m_xAggregateSet
->getPropertySetInfo(), UNO_SET_THROW
);
1447 Property aValuePropDesc
= xPropInfo
->getPropertyByName( m_sValuePropertyName
);
1448 m_aValuePropertyType
= aValuePropDesc
.Type
;
1449 m_bValuePropertyMayBeVoid
= ( aValuePropDesc
.Attributes
& PropertyAttribute::MAYBEVOID
) != 0;
1452 // start listening for changes at the value property
1453 implInitValuePropertyListening( );
1456 //-----------------------------------------------------------------------------
1457 void OBoundControlModel::suspendValueListening( )
1459 OSL_PRECOND( m_sValuePropertyName
.getLength(), "OBoundControlModel::suspendValueListening: don't have a value property!" );
1460 OSL_PRECOND( m_pAggPropMultiplexer
, "OBoundControlModel::suspendValueListening: I *am* not listening!" );
1462 if ( m_pAggPropMultiplexer
)
1463 m_pAggPropMultiplexer
->lock();
1466 //-----------------------------------------------------------------------------
1467 void OBoundControlModel::resumeValueListening( )
1469 OSL_PRECOND( m_sValuePropertyName
.getLength(), "OBoundControlModel::resumeValueListening: don't have a value property!" );
1470 OSL_PRECOND( m_pAggPropMultiplexer
, "OBoundControlModel::resumeValueListening: I *am* not listening at all!" );
1471 OSL_PRECOND( !m_pAggPropMultiplexer
|| m_pAggPropMultiplexer
->locked(), "OBoundControlModel::resumeValueListening: listening not suspended currently!" );
1473 if ( m_pAggPropMultiplexer
)
1474 m_pAggPropMultiplexer
->unlock();
1477 //-----------------------------------------------------------------------------
1478 Sequence
< Type
> OBoundControlModel::_getTypes()
1481 OControlModel::_getTypes(),
1482 OBoundControlModel_BASE1::getTypes()
1485 if ( m_bCommitable
)
1486 aTypes
.addTypes( OBoundControlModel_COMMITTING::getTypes() );
1488 if ( m_bSupportsExternalBinding
)
1489 aTypes
.addTypes( OBoundControlModel_BINDING::getTypes() );
1491 if ( m_bSupportsValidation
)
1492 aTypes
.addTypes( OBoundControlModel_VALIDATION::getTypes() );
1494 return aTypes
.getTypes();
1498 //-----------------------------------------------------------------------------
1499 void OBoundControlModel::disposing()
1501 // RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "forms", "dev@dba.openoffice.org", "OControlModel::_getTypes" );
1502 OControlModel::disposing();
1504 ::osl::ClearableMutexGuard
aGuard(m_aMutex
);
1506 if ( m_pAggPropMultiplexer
)
1507 m_pAggPropMultiplexer
->dispose();
1509 // notify all our listeners
1510 com::sun::star::lang::EventObject
aEvt( static_cast< XWeak
* >( this ) );
1511 m_aUpdateListeners
.disposeAndClear( aEvt
);
1512 m_aResetHelper
.disposing();
1514 // disconnect from our database column
1515 // TODO: could we replace the following 5 lines with a call to impl_disconnectDatabaseColumn_noNotify?
1516 // The only more thing which it does is calling onDisconnectedDbColumn - could this
1517 // cause trouble? At least when we continue to call OControlModel::disposing before, it *may*.
1520 getField()->removePropertyChangeListener( PROPERTY_VALUE
, this );
1525 Reference
< XComponent
> xComp( m_xLabelControl
, UNO_QUERY
);
1527 xComp
->removeEventListener(static_cast< XEventListener
* >( static_cast< XPropertyChangeListener
* >( this ) ) );
1529 // disconnect from our external value binding
1530 if ( hasExternalValueBinding() )
1531 disconnectExternalValueBinding();
1533 // dito for the validator
1534 if ( hasValidator() )
1535 disconnectValidator( );
1538 //------------------------------------------------------------------------------
1539 void OBoundControlModel::_propertyChanged( const PropertyChangeEvent
& _rEvt
) throw ( RuntimeException
)
1541 ControlModelLock
aLock( *this );
1543 OSL_ENSURE( _rEvt
.PropertyName
== m_sValuePropertyName
,
1544 "OBoundControlModel::_propertyChanged: where did this come from (1)?" );
1545 OSL_ENSURE( m_pAggPropMultiplexer
&& !m_pAggPropMultiplexer
->locked(),
1546 "OBoundControlModel::_propertyChanged: where did this come from (2)?" );
1548 if ( _rEvt
.PropertyName
== m_sValuePropertyName
)
1549 { // our control value changed
1551 if ( hasExternalValueBinding() )
1552 { // the control value changed, while we have an external value binding
1553 // -> forward the value to it
1554 if ( m_eControlValueChangeInstigator
!= eExternalBinding
)
1555 transferControlValueToExternal( aLock
);
1557 else if ( !m_bCommitable
&& m_xColumnUpdate
.is() )
1558 { // the control value changed, while we are bound to a database column,
1559 // but not committable (which means changes in the control have to be reflected to
1560 // the underlying database column immediately)
1561 // -> forward the value to the database column
1562 if ( m_eControlValueChangeInstigator
!= eDbColumnBinding
)
1563 commitControlValueToDbColumn( false );
1566 // validate the new value
1567 if ( m_bSupportsValidation
)
1568 recheckValidity( true );
1572 //------------------------------------------------------------------------------
1573 void OBoundControlModel::startAggregatePropertyListening( const ::rtl::OUString
& _rPropertyName
)
1575 OSL_PRECOND( m_pAggPropMultiplexer
, "OBoundControlModel::startAggregatePropertyListening: no multiplexer!" );
1576 OSL_ENSURE( _rPropertyName
.getLength(), "OBoundControlModel::startAggregatePropertyListening: invalid property name!" );
1578 if ( m_pAggPropMultiplexer
&& _rPropertyName
.getLength() )
1580 m_pAggPropMultiplexer
->addProperty( _rPropertyName
);
1584 //------------------------------------------------------------------------------
1585 void OBoundControlModel::doFormListening( const bool _bStart
)
1587 OSL_PRECOND( !hasExternalValueBinding(), "OBoundControlModel::doFormListening: external value binding should overrule the database binding!" );
1589 if ( isFormListening() == _bStart
)
1592 if ( m_xAmbientForm
.is() )
1593 _bStart
? m_xAmbientForm
->addLoadListener( this ) : m_xAmbientForm
->removeLoadListener( this );
1595 Reference
< XLoadable
> xParentLoadable( getParent(), UNO_QUERY
);
1596 if ( getParent().is() && !xParentLoadable
.is() )
1598 // if our parent does not directly support the XLoadable interface, then it might support the
1599 // XRowSetSupplier/XRowSetChangeBroadcaster interfaces. In this case we have to listen for changes
1600 // broadcasted by the latter.
1601 Reference
< XRowSetChangeBroadcaster
> xRowSetBroadcaster( getParent(), UNO_QUERY
);
1602 if ( xRowSetBroadcaster
.is() )
1603 _bStart
? xRowSetBroadcaster
->addRowSetChangeListener( this ) : xRowSetBroadcaster
->removeRowSetChangeListener( this );
1606 m_bFormListening
= _bStart
&& m_xAmbientForm
.is();
1610 //------------------------------------------------------------------------------
1611 void SAL_CALL
OBoundControlModel::setParent(const Reference
<XInterface
>& _rxParent
) throw(com::sun::star::lang::NoSupportException
, RuntimeException
)
1613 ControlModelLock
aLock( *this );
1614 FieldChangeNotifier
aBoundFieldNotifier( aLock
);
1616 if ( getParent() == _rxParent
)
1619 // disconnect from database column (which is controlled by parent, directly or indirectly)
1621 impl_disconnectDatabaseColumn_noNotify();
1623 // log off old listeners
1624 if ( isFormListening() )
1625 doFormListening( false );
1627 // actually set the new parent
1628 OControlModel::setParent( _rxParent
);
1630 // a new parent means a new ambient form
1631 impl_determineAmbientForm_nothrow();
1633 if ( !hasExternalValueBinding() )
1635 // log on new listeners
1636 doFormListening( true );
1638 // re-connect to database column of the new parent
1639 if ( m_xAmbientForm
.is() && m_xAmbientForm
->isLoaded() )
1640 impl_connectDatabaseColumn_noNotify( false );
1645 //------------------------------------------------------------------------------
1646 void SAL_CALL
OBoundControlModel::disposing(const com::sun::star::lang::EventObject
& _rEvent
) throw (RuntimeException
)
1648 ControlModelLock
aLock( *this );
1650 if ( _rEvent
.Source
== getField() )
1654 else if ( _rEvent
.Source
== m_xLabelControl
)
1656 Reference
<XPropertySet
> xOldValue
= m_xLabelControl
;
1657 m_xLabelControl
= NULL
;
1659 // fire a propertyChanged (when we leave aLock's scope)
1660 aLock
.addPropertyNotification( PROPERTY_ID_CONTROLLABEL
, makeAny( xOldValue
), makeAny( m_xLabelControl
) );
1662 else if ( _rEvent
.Source
== m_xExternalBinding
)
1663 { // *first* check for the external binding
1664 disconnectExternalValueBinding( );
1666 else if ( _rEvent
.Source
== m_xValidator
)
1667 { // *then* check for the validator. Reason is that bindings may also act as validator at the same
1668 // time, in this case, the validator is automatically revoked when the binding is revoked
1669 disconnectValidator( );
1672 OControlModel::disposing(_rEvent
);
1676 //------------------------------------------------------------------------------
1677 StringSequence SAL_CALL
OBoundControlModel::getSupportedServiceNames() throw(RuntimeException
)
1679 // RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "forms", "dev@dba.openoffice.org", "OControlModel::disposing" );
1680 return ::comphelper::concatSequences(
1681 getAggregateServiceNames(),
1682 getSupportedServiceNames_Static()
1686 //------------------------------------------------------------------------------
1687 Sequence
< ::rtl::OUString
> SAL_CALL
OBoundControlModel::getSupportedServiceNames_Static() throw( RuntimeException
)
1689 Sequence
< ::rtl::OUString
> aOwnServiceNames( 1 );
1690 aOwnServiceNames
[ 0 ] = ::rtl::OUString::createFromAscii( "com.sun.star.form.DataAwareControlModel" );
1692 return ::comphelper::concatSequences(
1693 OControlModel::getSupportedServiceNames_Static(),
1699 //------------------------------------------------------------------------------
1700 void SAL_CALL
OBoundControlModel::write( const Reference
<stario::XObjectOutputStream
>& _rxOutStream
) throw(stario::IOException
, RuntimeException
)
1702 // RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "forms", "dev@dba.openoffice.org", "OControlModel::getSupportedServiceNames_Static" );
1703 OControlModel::write(_rxOutStream
);
1705 osl::MutexGuard
aGuard(m_aMutex
);
1708 _rxOutStream
->writeShort(0x0002);
1711 ::comphelper::operator<<( _rxOutStream
, m_aControlSource
);
1713 // !!! IMPORTANT NOTE !!!
1714 // don't write any new members here : this wouldn't be compatible with older versions, as OBoundControlModel
1715 // is a base class which is called in derived classes "read" method. So if you increment the version
1716 // and write new stuff, older office versions will read this in the _derived_ classes, which may result
1717 // in anything from data loss to crash.
1718 // (use writeCommonProperties instead, this is called in derived classes write-method)
1720 // FS - 68876 - 28.09.1999
1723 //------------------------------------------------------------------------------
1724 void OBoundControlModel::defaultCommonProperties()
1726 Reference
<com::sun::star::lang::XComponent
> xComp(m_xLabelControl
, UNO_QUERY
);
1728 xComp
->removeEventListener(static_cast<com::sun::star::lang::XEventListener
*>(static_cast<XPropertyChangeListener
*>(this)));
1729 m_xLabelControl
= NULL
;
1732 //------------------------------------------------------------------------------
1733 void OBoundControlModel::readCommonProperties(const Reference
<stario::XObjectInputStream
>& _rxInStream
)
1735 sal_Int32 nLen
= _rxInStream
->readLong();
1737 Reference
<stario::XMarkableStream
> xMark(_rxInStream
, UNO_QUERY
);
1738 DBG_ASSERT(xMark
.is(), "OBoundControlModel::readCommonProperties : can only work with markable streams !");
1739 sal_Int32 nMark
= xMark
->createMark();
1741 // read the reference to the label control
1742 Reference
<stario::XPersistObject
> xPersist
;
1743 sal_Int32 nUsedFlag
;
1744 nUsedFlag
= _rxInStream
->readLong();
1746 xPersist
= _rxInStream
->readObject();
1747 m_xLabelControl
= m_xLabelControl
.query( xPersist
);
1748 Reference
< XComponent
> xComp( m_xLabelControl
, UNO_QUERY
);
1750 xComp
->addEventListener(static_cast<com::sun::star::lang::XEventListener
*>(static_cast<XPropertyChangeListener
*>(this)));
1752 // read any other new common properties here
1754 // skip the remaining bytes
1755 xMark
->jumpToMark(nMark
);
1756 _rxInStream
->skipBytes(nLen
);
1757 xMark
->deleteMark(nMark
);
1760 //------------------------------------------------------------------------------
1761 void OBoundControlModel::writeCommonProperties(const Reference
<stario::XObjectOutputStream
>& _rxOutStream
)
1763 Reference
<stario::XMarkableStream
> xMark(_rxOutStream
, UNO_QUERY
);
1764 DBG_ASSERT(xMark
.is(), "OBoundControlModel::writeCommonProperties : can only work with markable streams !");
1765 sal_Int32 nMark
= xMark
->createMark();
1767 // a placeholder where we will write the overall length (later in this method)
1769 _rxOutStream
->writeLong(nLen
);
1771 // write the reference to the label control
1772 Reference
<stario::XPersistObject
> xPersist(m_xLabelControl
, UNO_QUERY
);
1773 sal_Int32 nUsedFlag
= 0;
1776 _rxOutStream
->writeLong(nUsedFlag
);
1778 _rxOutStream
->writeObject(xPersist
);
1780 // write any other new common properties here
1782 // write the correct length at the beginning of the block
1783 nLen
= xMark
->offsetToMark(nMark
) - sizeof(nLen
);
1784 xMark
->jumpToMark(nMark
);
1785 _rxOutStream
->writeLong(nLen
);
1786 xMark
->jumpToFurthest();
1787 xMark
->deleteMark(nMark
);
1790 //------------------------------------------------------------------------------
1791 void SAL_CALL
OBoundControlModel::read( const Reference
< stario::XObjectInputStream
>& _rxInStream
) throw(stario::IOException
, RuntimeException
)
1793 OControlModel::read(_rxInStream
);
1795 osl::MutexGuard
aGuard(m_aMutex
);
1796 UINT16 nVersion
= _rxInStream
->readShort(); (void)nVersion
;
1797 ::comphelper::operator>>( _rxInStream
, m_aControlSource
);
1800 //------------------------------------------------------------------------------
1801 void OBoundControlModel::getFastPropertyValue(Any
& rValue
, sal_Int32 nHandle
) const
1803 // RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "forms", "dev@dba.openoffice.org", "OBoundControlModel::getFastPropertyValue" );
1806 case PROPERTY_ID_INPUT_REQUIRED
:
1807 rValue
<<= m_bInputRequired
;
1809 case PROPERTY_ID_CONTROLSOURCEPROPERTY
:
1810 rValue
<<= m_sValuePropertyName
;
1812 case PROPERTY_ID_CONTROLSOURCE
:
1813 rValue
<<= m_aControlSource
;
1815 case PROPERTY_ID_BOUNDFIELD
:
1816 rValue
<<= getField();
1818 case PROPERTY_ID_CONTROLLABEL
:
1819 if (!m_xLabelControl
.is())
1822 rValue
<<= m_xLabelControl
;
1825 OControlModel::getFastPropertyValue(rValue
, nHandle
);
1829 //------------------------------------------------------------------------------
1830 sal_Bool
OBoundControlModel::convertFastPropertyValue(
1831 Any
& _rConvertedValue
, Any
& _rOldValue
,
1834 throw (com::sun::star::lang::IllegalArgumentException
)
1836 sal_Bool
bModified(sal_False
);
1839 case PROPERTY_ID_INPUT_REQUIRED
:
1840 bModified
= tryPropertyValue( _rConvertedValue
, _rOldValue
, _rValue
, m_bInputRequired
);
1842 case PROPERTY_ID_CONTROLSOURCE
:
1843 bModified
= tryPropertyValue(_rConvertedValue
, _rOldValue
, _rValue
, m_aControlSource
);
1845 case PROPERTY_ID_BOUNDFIELD
:
1846 DBG_ERROR( "OBoundControlModel::convertFastPropertyValue: BoundField should be a read-only property !" );
1847 throw com::sun::star::lang::IllegalArgumentException();
1848 case PROPERTY_ID_CONTROLLABEL
:
1849 if (!_rValue
.hasValue())
1850 { // property set to void
1851 _rConvertedValue
= Any();
1852 getFastPropertyValue(_rOldValue
, _nHandle
);
1853 bModified
= m_xLabelControl
.is();
1857 bModified
= tryPropertyValue(_rConvertedValue
, _rOldValue
, _rValue
, m_xLabelControl
);
1858 if (!m_xLabelControl
.is())
1859 // an empty interface is interpreted as VOID
1864 bModified
= OControlModel::convertFastPropertyValue(_rConvertedValue
, _rOldValue
, _nHandle
, _rValue
);
1869 //------------------------------------------------------------------------------
1870 Any
OBoundControlModel::getPropertyDefaultByHandle( sal_Int32 _nHandle
) const
1872 // RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "forms", "dev@dba.openoffice.org", "OControlModel::convertFastPropertyValue" );
1876 case PROPERTY_ID_INPUT_REQUIRED
:
1877 aDefault
<<= sal_Bool( sal_True
);
1880 case PROPERTY_ID_CONTROLSOURCE
:
1881 aDefault
<<= ::rtl::OUString();
1884 case PROPERTY_ID_CONTROLLABEL
:
1885 aDefault
<<= Reference
< XPropertySet
>();
1891 //------------------------------------------------------------------------------
1892 void OBoundControlModel::setFastPropertyValue_NoBroadcast( sal_Int32 nHandle
, const Any
& rValue
) throw (Exception
)
1896 case PROPERTY_ID_INPUT_REQUIRED
:
1897 OSL_VERIFY( rValue
>>= m_bInputRequired
);
1899 case PROPERTY_ID_CONTROLSOURCE
:
1900 OSL_VERIFY( rValue
>>= m_aControlSource
);
1902 case PROPERTY_ID_BOUNDFIELD
:
1903 DBG_ERROR("OBoundControlModel::setFastPropertyValue_NoBroadcast : BoundField should be a read-only property !");
1904 throw com::sun::star::lang::IllegalArgumentException();
1905 case PROPERTY_ID_CONTROLLABEL
:
1907 DBG_ASSERT(!rValue
.hasValue() || (rValue
.getValueType().getTypeClass() == TypeClass_INTERFACE
),
1908 "OBoundControlModel::setFastPropertyValue_NoBroadcast : invalid argument !");
1909 if (!rValue
.hasValue())
1910 { // set property to "void"
1911 Reference
<com::sun::star::lang::XComponent
> xComp(m_xLabelControl
, UNO_QUERY
);
1913 xComp
->removeEventListener(static_cast<com::sun::star::lang::XEventListener
*>(static_cast<XPropertyChangeListener
*>(this)));
1914 m_xLabelControl
= NULL
;
1918 InterfaceRef xNewValue
;
1919 rValue
>>= xNewValue
;
1921 Reference
<XControlModel
> xAsModel(xNewValue
, UNO_QUERY
);
1922 Reference
<com::sun::star::lang::XServiceInfo
> xAsServiceInfo(xNewValue
, UNO_QUERY
);
1923 Reference
<XPropertySet
> xAsPropSet(xNewValue
, UNO_QUERY
);
1924 Reference
<XChild
> xAsChild(xNewValue
, UNO_QUERY
);
1925 if (!xAsModel
.is() || !xAsServiceInfo
.is() || !xAsPropSet
.is() || !xAsChild
.is())
1927 throw com::sun::star::lang::IllegalArgumentException();
1930 if (!xAsServiceInfo
->supportsService(m_aLabelServiceName
))
1932 throw com::sun::star::lang::IllegalArgumentException();
1935 // check if weself and the given model have a common anchestor (up to the forms collection)
1936 Reference
<XChild
> xCont
;
1937 query_interface(static_cast<XWeak
*>(this), xCont
);
1938 InterfaceRef xMyTopLevel
= xCont
->getParent();
1939 while (xMyTopLevel
.is())
1941 Reference
<XForm
> xAsForm(xMyTopLevel
, UNO_QUERY
);
1946 Reference
<XChild
> xLoopAsChild(xMyTopLevel
, UNO_QUERY
);
1947 xMyTopLevel
= xLoopAsChild
.is() ? xLoopAsChild
->getParent() : InterfaceRef();
1949 InterfaceRef xNewTopLevel
= xAsChild
->getParent();
1950 while (xNewTopLevel
.is())
1952 Reference
<XForm
> xAsForm(xNewTopLevel
, UNO_QUERY
);
1956 Reference
<XChild
> xLoopAsChild(xNewTopLevel
, UNO_QUERY
);
1957 xNewTopLevel
= xLoopAsChild
.is() ? xLoopAsChild
->getParent() : InterfaceRef();
1959 if (xNewTopLevel
!= xMyTopLevel
)
1961 // the both objects don't belong to the same forms collection -> not acceptable
1962 throw com::sun::star::lang::IllegalArgumentException();
1965 m_xLabelControl
= xAsPropSet
;
1966 Reference
<com::sun::star::lang::XComponent
> xComp(m_xLabelControl
, UNO_QUERY
);
1968 xComp
->addEventListener(static_cast<com::sun::star::lang::XEventListener
*>(static_cast<XPropertyChangeListener
*>(this)));
1972 OControlModel::setFastPropertyValue_NoBroadcast(nHandle
, rValue
);
1976 // XPropertyChangeListener
1977 //------------------------------------------------------------------------------
1978 void SAL_CALL
OBoundControlModel::propertyChange( const PropertyChangeEvent
& evt
) throw(RuntimeException
)
1980 // RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "forms", "dev@dba.openoffice.org", "OControlModel::setFastPropertyValue_NoBroadcast" );
1981 // if the DBColumn value changed, transfer it to the control
1982 if ( evt
.PropertyName
.equals( PROPERTY_VALUE
) )
1984 OSL_ENSURE( evt
.Source
== getField(), "OBoundControlModel::propertyChange: value changes from components other than our database colum?" );
1985 osl::MutexGuard
aGuard(m_aMutex
);
1986 if ( m_bForwardValueChanges
&& m_xColumn
.is() )
1987 transferDbValueToControl();
1991 OSL_ENSURE( evt
.Source
== m_xExternalBinding
, "OBoundControlModel::propertyChange: where did this come from?" );
1993 // our binding has properties which can control properties of ourself
1994 ::rtl::OUString sBindingControlledProperty
;
1995 bool bForwardToLabelControl
= false;
1996 if ( evt
.PropertyName
.equals( PROPERTY_READONLY
) )
1998 sBindingControlledProperty
= PROPERTY_READONLY
;
2000 else if ( evt
.PropertyName
.equals( PROPERTY_RELEVANT
) )
2002 sBindingControlledProperty
= PROPERTY_ENABLED
;
2003 bForwardToLabelControl
= true;
2010 setPropertyValue( sBindingControlledProperty
, evt
.NewValue
);
2011 if ( bForwardToLabelControl
&& m_xLabelControl
.is() )
2012 m_xLabelControl
->setPropertyValue( sBindingControlledProperty
, evt
.NewValue
);
2014 catch( const Exception
& )
2016 OSL_ENSURE( sal_False
, "OBoundControlModel::propertyChange: could not adjust my binding-controlled property!" );
2021 //------------------------------------------------------------------------------
2022 void SAL_CALL
OBoundControlModel::onRowSetChanged( const EventObject
& /*i_Event*/ ) throw (RuntimeException
)
2024 ControlModelLock
aLock( *this );
2025 FieldChangeNotifier
aBoundFieldNotifier( aLock
);
2027 // disconnect from database column (which is controlled by parent, directly or indirectly)
2029 impl_disconnectDatabaseColumn_noNotify();
2031 // log off old listeners
2032 if ( isFormListening() )
2033 doFormListening( false );
2035 // determine the new ambient form
2036 impl_determineAmbientForm_nothrow();
2038 // log on new listeners
2039 doFormListening( true );
2041 // re-connect to database column if needed and possible
2042 if ( m_xAmbientForm
.is() && m_xAmbientForm
->isLoaded() )
2043 impl_connectDatabaseColumn_noNotify( false );
2047 //------------------------------------------------------------------------------
2048 void SAL_CALL
OBoundControlModel::addUpdateListener(const Reference
<XUpdateListener
>& _rxListener
) throw(RuntimeException
)
2050 m_aUpdateListeners
.addInterface(_rxListener
);
2053 //------------------------------------------------------------------------------
2054 void SAL_CALL
OBoundControlModel::removeUpdateListener(const Reference
< XUpdateListener
>& _rxListener
) throw(RuntimeException
)
2056 m_aUpdateListeners
.removeInterface(_rxListener
);
2059 //------------------------------------------------------------------------------
2060 sal_Bool SAL_CALL
OBoundControlModel::commit() throw(RuntimeException
)
2062 ControlModelLock
aLock( *this );
2064 OSL_PRECOND( m_bCommitable
, "OBoundControlModel::commit: invalid call (I'm not commitable !) " );
2065 if ( hasExternalValueBinding() )
2067 // in most cases, no action is required: For most derivees, we know the value property of
2068 // our control (see initValueProperty), and when an external binding is active, we
2069 // instantly forward all changes in this property to the external binding.
2070 if ( !m_sValuePropertyName
.getLength() )
2071 // but for those derivees which did not use this feature, we need an
2072 // explicit transfer
2073 transferControlValueToExternal( aLock
);
2077 OSL_ENSURE( !hasExternalValueBinding(), "OBoundControlModel::commit: control flow broken!" );
2078 // we reach this only if we're not working with an external binding
2083 ::cppu::OInterfaceIteratorHelper
aIter( m_aUpdateListeners
);
2085 aEvent
.Source
= static_cast< XWeak
* >( this );
2086 sal_Bool bSuccess
= sal_True
;
2089 // >>>>>>>> ----- UNSAFE ----- >>>>>>>>
2090 while (aIter
.hasMoreElements() && bSuccess
)
2091 bSuccess
= static_cast< XUpdateListener
* >( aIter
.next() )->approveUpdate( aEvent
);
2092 // <<<<<<<< ----- UNSAFE ----- <<<<<<<<
2099 if ( m_xColumnUpdate
.is() )
2100 bSuccess
= commitControlValueToDbColumn( sal_False
);
2104 bSuccess
= sal_False
;
2111 m_aUpdateListeners
.notifyEach( &XUpdateListener::updated
, aEvent
);
2117 //------------------------------------------------------------------------------
2118 void OBoundControlModel::resetField()
2120 m_xColumnUpdate
.clear();
2123 m_nFieldType
= DataType::OTHER
;
2126 //------------------------------------------------------------------------------
2127 sal_Bool
OBoundControlModel::connectToField(const Reference
<XRowSet
>& rForm
)
2129 OSL_PRECOND( !hasExternalValueBinding(), "OBoundControlModel::connectToField: invalid call (have an external binding)!" );
2131 // wenn eine Verbindung zur Datenbank existiert
2132 if (rForm
.is() && getConnection(rForm
).is())
2134 // Feld bestimmen und PropertyChangeListener
2136 Reference
<XPropertySet
> xFieldCandidate
;
2140 Reference
<XColumnsSupplier
> xColumnsSupplier(m_xCursor
, UNO_QUERY
);
2141 DBG_ASSERT(xColumnsSupplier
.is(), "OBoundControlModel::connectToField : the row set should support the com::sun::star::sdb::ResultSet service !");
2142 if (xColumnsSupplier
.is())
2144 Reference
<XNameAccess
> xColumns(xColumnsSupplier
->getColumns(), UNO_QUERY
);
2145 if (xColumns
.is() && xColumns
->hasByName(m_aControlSource
))
2147 OSL_VERIFY( xColumns
->getByName(m_aControlSource
) >>= xFieldCandidate
);
2154 sal_Int32 nFieldType
= DataType::OTHER
;
2155 if ( xFieldCandidate
.is() )
2157 xFieldCandidate
->getPropertyValue( PROPERTY_FIELDTYPE
) >>= nFieldType
;
2158 if ( approveDbColumnType( nFieldType
) )
2159 impl_setField_noNotify( xFieldCandidate
);
2162 impl_setField_noNotify( NULL
);
2164 if ( m_xField
.is() )
2166 if( m_xField
->getPropertySetInfo()->hasPropertyByName( PROPERTY_VALUE
) )
2168 m_nFieldType
= nFieldType
;
2170 // an wertaenderungen horchen
2171 m_xField
->addPropertyChangeListener( PROPERTY_VALUE
, this );
2172 m_xColumnUpdate
= Reference
< XColumnUpdate
>( m_xField
, UNO_QUERY
);
2173 m_xColumn
= Reference
< XColumn
>( m_xField
, UNO_QUERY
);
2175 INT32 nNullableFlag
= ColumnValue::NO_NULLS
;
2176 m_xField
->getPropertyValue(PROPERTY_ISNULLABLE
) >>= nNullableFlag
;
2177 m_bRequired
= (ColumnValue::NO_NULLS
== nNullableFlag
);
2178 // we're optimistic : in case of ColumnValue_NULLABLE_UNKNOWN we assume nullability ....
2182 OSL_ENSURE(sal_False
, "OBoundControlModel::connectToField: property NAME not supported!");
2183 impl_setField_noNotify( NULL
);
2187 catch( const Exception
& )
2189 DBG_UNHANDLED_EXCEPTION();
2196 //------------------------------------------------------------------------------
2197 void OBoundControlModel::initFromField( const Reference
< XRowSet
>& _rxRowSet
)
2199 // but only if the rowset if posisitioned on a valid record
2200 if ( hasField() && _rxRowSet
.is() )
2202 if ( !_rxRowSet
->isBeforeFirst() && !_rxRowSet
->isAfterLast() )
2203 transferDbValueToControl();
2205 // reset the field if the row set is empty
2206 // #i30661# / 2004-12-16 / frank.schoenheit@sun.com
2211 //------------------------------------------------------------------------------
2212 sal_Bool
OBoundControlModel::approveDbColumnType(sal_Int32 _nColumnType
)
2214 OSL_PRECOND( !hasExternalValueBinding(), "OBoundControlModel::approveDbColumnType: invalid call (have an external binding)!" );
2216 if ((_nColumnType
== DataType::BINARY
) || (_nColumnType
== DataType::VARBINARY
)
2217 || (_nColumnType
== DataType::LONGVARBINARY
) || (_nColumnType
== DataType::OTHER
)
2218 || (_nColumnType
== DataType::OBJECT
) || (_nColumnType
== DataType::DISTINCT
)
2219 || (_nColumnType
== DataType::STRUCT
) || (_nColumnType
== DataType::ARRAY
)
2220 || (_nColumnType
== DataType::BLOB
) || (_nColumnType
== DataType::CLOB
)
2221 || (_nColumnType
== DataType::REF
) || (_nColumnType
== DataType::SQLNULL
))
2227 //------------------------------------------------------------------------------
2228 void OBoundControlModel::impl_determineAmbientForm_nothrow()
2230 Reference
< XInterface
> xParent( const_cast< OBoundControlModel
* >( this )->getParent() );
2232 m_xAmbientForm
.set( xParent
, UNO_QUERY
);
2233 if ( !m_xAmbientForm
.is() )
2235 Reference
< XRowSetSupplier
> xSupRowSet( xParent
, UNO_QUERY
);
2236 if ( xSupRowSet
.is() )
2237 m_xAmbientForm
.set( xSupRowSet
->getRowSet(), UNO_QUERY
);
2241 //------------------------------------------------------------------------------
2242 void OBoundControlModel::impl_connectDatabaseColumn_noNotify( bool _bFromReload
)
2244 OSL_PRECOND( !hasExternalValueBinding(), "OBoundControlModel::impl_connectDatabaseColumn_noNotify: not to be called with an external value binding!" );
2246 // consistency checks
2247 DBG_ASSERT( !( hasField() && !_bFromReload
),
2248 "OBoundControlModel::impl_connectDatabaseColumn_noNotify: the form is just *loaded*, but we already have a field!" );
2251 Reference
< XRowSet
> xRowSet( m_xAmbientForm
, UNO_QUERY
);
2252 OSL_ENSURE( xRowSet
.is(), "OBoundControlModel::impl_connectDatabaseColumn_noNotify: no row set!" );
2253 if ( !xRowSet
.is() )
2258 // connect to the column
2259 connectToField( xRowSet
);
2262 // now that we're connected (more or less, even if we did not find a column),
2263 // we definately want to forward any potentially occuring value changes
2264 m_bForwardValueChanges
= sal_True
;
2266 // let derived classes react on this new connection
2267 m_bLoaded
= sal_True
;
2268 onConnectedDbColumn( xRowSet
);
2270 // initially transfer the db column value to the control, if we successfully connected to a database column
2272 initFromField( xRowSet
);
2275 //------------------------------------------------------------------------------
2276 void OBoundControlModel::impl_disconnectDatabaseColumn_noNotify()
2278 OSL_PRECOND( !hasExternalValueBinding(), "OBoundControlModel::impl_disconnectDatabaseColumn_noNotify: not to be called with an external value binding!" );
2280 // let derived classes react on this
2281 onDisconnectedDbColumn();
2285 getField()->removePropertyChangeListener( PROPERTY_VALUE
, this );
2290 m_bLoaded
= sal_False
;
2293 //==============================================================================
2295 //------------------------------------------------------------------------------
2296 void SAL_CALL
OBoundControlModel::loaded( const EventObject
& _rEvent
) throw(RuntimeException
)
2298 ControlModelLock
aLock( *this );
2299 FieldChangeNotifier
aBoundFieldNotifier( aLock
);
2301 OSL_ENSURE( _rEvent
.Source
== m_xAmbientForm
, "OBoundControlModel::loaded: where does this come from?" );
2304 OSL_PRECOND( !hasExternalValueBinding(), "OBoundControlModel::loaded: we should never reach this with an external value binding!" );
2305 if ( hasExternalValueBinding() )
2308 impl_connectDatabaseColumn_noNotify( false );
2312 //------------------------------------------------------------------------------
2313 void SAL_CALL
OBoundControlModel::unloaded( const com::sun::star::lang::EventObject
& /*aEvent*/ ) throw(RuntimeException
)
2315 OSL_PRECOND( !hasExternalValueBinding(), "OBoundControlModel::unloaded: we should never reach this with an external value binding!" );
2318 //------------------------------------------------------------------------------
2319 void SAL_CALL
OBoundControlModel::reloading( const com::sun::star::lang::EventObject
& /*aEvent*/ ) throw(RuntimeException
)
2321 OSL_PRECOND( !hasExternalValueBinding(), "OBoundControlModel::reloading: we should never reach this with an external value binding!" );
2322 if ( hasExternalValueBinding() )
2325 osl::MutexGuard
aGuard(m_aMutex
);
2326 m_bForwardValueChanges
= sal_False
;
2329 //------------------------------------------------------------------------------
2330 void SAL_CALL
OBoundControlModel::unloading(const com::sun::star::lang::EventObject
& /*aEvent*/) throw(RuntimeException
)
2332 ControlModelLock
aLock( *this );
2333 FieldChangeNotifier
aBoundFieldNotifier( aLock
);
2335 OSL_PRECOND( !hasExternalValueBinding(), "OBoundControlModel::unloading: we should never reach this with an external value binding!" );
2336 if ( hasExternalValueBinding() )
2339 impl_disconnectDatabaseColumn_noNotify();
2342 //------------------------------------------------------------------------------
2343 void SAL_CALL
OBoundControlModel::reloaded( const EventObject
& _rEvent
) throw(RuntimeException
)
2345 ControlModelLock
aLock( *this );
2346 FieldChangeNotifier
aBoundFieldNotifier( aLock
);
2348 OSL_ENSURE( _rEvent
.Source
== m_xAmbientForm
, "OBoundControlModel::reloaded: where does this come from?" );
2351 OSL_PRECOND( !hasExternalValueBinding(), "OBoundControlModel::reloaded: we should never reach this with an external value binding!" );
2352 if ( hasExternalValueBinding() )
2355 impl_connectDatabaseColumn_noNotify( true );
2358 //------------------------------------------------------------------------------
2359 void OBoundControlModel::setControlValue( const Any
& _rValue
, ValueChangeInstigator _eInstigator
)
2361 m_eControlValueChangeInstigator
= _eInstigator
;
2362 doSetControlValue( _rValue
);
2363 m_eControlValueChangeInstigator
= eOther
;
2366 //------------------------------------------------------------------------------
2367 void OBoundControlModel::doSetControlValue( const Any
& _rValue
)
2369 OSL_PRECOND( m_xAggregateFastSet
.is() && m_xAggregateSet
.is(),
2370 "OBoundControlModel::doSetControlValue: invalid aggregate !" );
2371 OSL_PRECOND( m_sValuePropertyName
.getLength() || ( m_nValuePropertyAggregateHandle
!= -1 ),
2372 "OBoundControlModel::doSetControlValue: please override if you have own value property handling!" );
2376 // release our mutex once (it's acquired in one of the the calling methods), as setting aggregate properties
2377 // may cause any uno controls belonging to us to lock the solar mutex, which is potentially dangerous with
2378 // our own mutex locked
2379 // #72451# / 2000-01-31 / frank.schoenheit@sun.com
2380 MutexRelease
aRelease( m_aMutex
);
2381 if ( ( m_nValuePropertyAggregateHandle
!= -1 ) && m_xAggregateFastSet
.is() )
2383 m_xAggregateFastSet
->setFastPropertyValue( m_nValuePropertyAggregateHandle
, _rValue
);
2385 else if ( m_sValuePropertyName
.getLength() && m_xAggregateSet
.is() )
2387 m_xAggregateSet
->setPropertyValue( m_sValuePropertyName
, _rValue
);
2390 catch( const Exception
& )
2392 OSL_ENSURE( sal_False
, "OBoundControlModel::doSetControlValue: caught an exception!" );
2396 //------------------------------------------------------------------------------
2397 void OBoundControlModel::onConnectedValidator( )
2401 // if we have an external validator, we do not want the control to force invalid
2402 // inputs to the default value. Instead, invalid inputs should be translated
2403 // to NaN (not a number)
2404 Reference
< XPropertySetInfo
> xAggregatePropertyInfo
;
2405 if ( m_xAggregateSet
.is() )
2406 xAggregatePropertyInfo
= m_xAggregateSet
->getPropertySetInfo();
2407 if ( xAggregatePropertyInfo
.is() && xAggregatePropertyInfo
->hasPropertyByName( PROPERTY_ENFORCE_FORMAT
) )
2408 m_xAggregateSet
->setPropertyValue( PROPERTY_ENFORCE_FORMAT
, makeAny( (sal_Bool
)sal_False
) );
2410 catch( const Exception
& )
2412 OSL_ENSURE( sal_False
, "OBoundControlModel::onConnectedValidator: caught an exception!" );
2414 recheckValidity( false );
2417 //------------------------------------------------------------------------------
2418 void OBoundControlModel::onDisconnectedValidator( )
2422 Reference
< XPropertySetInfo
> xAggregatePropertyInfo
;
2423 if ( m_xAggregateSet
.is() )
2424 xAggregatePropertyInfo
= m_xAggregateSet
->getPropertySetInfo();
2425 if ( xAggregatePropertyInfo
.is() && xAggregatePropertyInfo
->hasPropertyByName( PROPERTY_ENFORCE_FORMAT
) )
2426 m_xAggregateSet
->setPropertyValue( PROPERTY_ENFORCE_FORMAT
, makeAny( (sal_Bool
)sal_True
) );
2428 catch( const Exception
& )
2430 OSL_ENSURE( sal_False
, "OBoundControlModel::onDisconnectedValidator: caught an exception!" );
2432 recheckValidity( false );
2435 //------------------------------------------------------------------------------
2436 void OBoundControlModel::onConnectedExternalValue( )
2438 calculateExternalValueType();
2441 //------------------------------------------------------------------------------
2442 void OBoundControlModel::onDisconnectedExternalValue( )
2446 //------------------------------------------------------------------------------
2447 void OBoundControlModel::onConnectedDbColumn( const Reference
< XInterface
>& /*_rxForm*/ )
2449 OSL_PRECOND( !hasExternalValueBinding(), "OBoundControlModel::onConnectedDbColumn: how this? There's an external value binding!" );
2452 //------------------------------------------------------------------------------
2453 void OBoundControlModel::onDisconnectedDbColumn()
2455 OSL_PRECOND( !hasExternalValueBinding(), "OBoundControlModel::onDisconnectedDbColumn: how this? There's an external value binding!" );
2459 //-----------------------------------------------------------------------------
2460 Any
OBoundControlModel::getDefaultForReset() const
2465 //-----------------------------------------------------------------------------
2466 void OBoundControlModel::resetNoBroadcast()
2468 setControlValue( getDefaultForReset(), eOther
);
2471 //-----------------------------------------------------------------------------
2472 void OBoundControlModel::addResetListener(const Reference
<XResetListener
>& l
) throw (RuntimeException
)
2474 m_aResetHelper
.addResetListener( l
);
2477 //-----------------------------------------------------------------------------
2478 void OBoundControlModel::removeResetListener(const Reference
<XResetListener
>& l
) throw (RuntimeException
)
2480 m_aResetHelper
.removeResetListener( l
);
2483 //-----------------------------------------------------------------------------
2484 void OBoundControlModel::reset() throw (RuntimeException
)
2486 if ( !m_aResetHelper
.approveReset() )
2489 ControlModelLock
aLock( *this );
2492 sal_Bool bIsNewRecord
= sal_False
;
2493 Reference
<XPropertySet
> xSet( m_xCursor
, UNO_QUERY
);
2498 xSet
->getPropertyValue( PROPERTY_ISNEW
) >>= bIsNewRecord
;
2500 catch( const Exception
& )
2502 DBG_UNHANDLED_EXCEPTION();
2506 // cursor on an invalid row?
2507 sal_Bool bInvalidCursorPosition
= sal_True
;
2510 bInvalidCursorPosition
= m_xCursor
.is()
2511 && ( m_xCursor
->isAfterLast()
2512 || m_xCursor
->isBeforeFirst()
2516 catch( const SQLException
& )
2518 OSL_ENSURE( sal_False
, "OBoundControlModel::reset: caught an SQL exception!" );
2520 // don't count the insert row as "invalid"
2523 // @author fs@openoffice.org
2525 sal_Bool bSimpleReset
=
2526 ( !m_xColumn
.is() // no connection to a database column
2527 || ( m_xCursor
.is() // OR we have an improperly positioned cursor
2528 && bInvalidCursorPosition
2530 || hasExternalValueBinding() // OR we have an external value binding
2533 if ( !bSimpleReset
)
2535 // The default values will be set if and only if the current value of the field which we're bound
2537 // Else, the current field value should be refreshed
2538 // This behaviour is not completely ... "matured": What should happen if the field as well as the
2539 // control have a default value?
2541 sal_Bool bIsNull
= sal_True
;
2542 // we have to access the field content at least once to get a reliable result by XColumn::wasNull
2545 // normally, we'd do a getString here. However, this is extremely expensive in the case
2546 // of binary fields. Unfortunately, getString is the only method which is guaranteed
2547 // to *always* succeed, all other getXXX methods may fail if the column is asked for a
2548 // non-convertible type
2549 sal_Int32 nFieldType
= DataType::OBJECT
;
2550 getField()->getPropertyValue( PROPERTY_FIELDTYPE
) >>= nFieldType
;
2551 if ( ( nFieldType
== DataType::BINARY
)
2552 || ( nFieldType
== DataType::VARBINARY
)
2553 || ( nFieldType
== DataType::LONGVARBINARY
)
2554 || ( nFieldType
== DataType::OBJECT
)
2555 || ( nFieldType
== DataType::BLOB
)
2556 || ( nFieldType
== DataType::CLOB
)
2558 m_xColumn
->getBinaryStream();
2560 m_xColumn
->getString();
2562 bIsNull
= m_xColumn
->wasNull();
2566 DBG_ERROR("OBoundControlModel::reset: this should have succeeded in all cases!");
2569 sal_Bool bNeedValueTransfer
= sal_True
;
2575 // reset the control to it's default
2577 // and immediately commit the changes to the DB column, to keep consistency
2578 commitControlValueToDbColumn( sal_True
);
2580 bNeedValueTransfer
= sal_False
;
2584 if ( bNeedValueTransfer
)
2585 transferDbValueToControl();
2591 // transfer to the external binding, if necessary
2592 if ( hasExternalValueBinding() )
2593 transferControlValueToExternal( aLock
);
2596 // revalidate, if necessary
2597 if ( hasValidator() )
2598 recheckValidity( true );
2602 m_aResetHelper
.notifyResetted();
2605 // -----------------------------------------------------------------------------
2606 void OBoundControlModel::impl_setField_noNotify( const Reference
< XPropertySet
>& _rxField
)
2608 DBG_ASSERT( !hasExternalValueBinding(), "OBoundControlModel::impl_setField_noNotify: We have an external value binding!" );
2609 m_xField
= _rxField
;
2612 //--------------------------------------------------------------------
2613 sal_Bool
OBoundControlModel::impl_approveValueBinding_nolock( const Reference
< XValueBinding
>& _rxBinding
)
2615 if ( !_rxBinding
.is() )
2618 Sequence
< Type
> aTypeCandidates
;
2621 ::osl::MutexGuard
aGuard( m_aMutex
);
2622 aTypeCandidates
= getSupportedBindingTypes();
2626 for ( const Type
* pType
= aTypeCandidates
.getConstArray();
2627 pType
!= aTypeCandidates
.getConstArray() + aTypeCandidates
.getLength();
2631 if ( _rxBinding
->supportsType( *pType
) )
2638 //--------------------------------------------------------------------
2639 void OBoundControlModel::connectExternalValueBinding(
2640 const Reference
< XValueBinding
>& _rxBinding
, ControlModelLock
& _rInstanceLock
)
2642 OSL_PRECOND( _rxBinding
.is(), "OBoundControlModel::connectExternalValueBinding: invalid binding instance!" );
2643 OSL_PRECOND( !hasExternalValueBinding( ), "OBoundControlModel::connectExternalValueBinding: precond not met (currently have a binding)!" );
2645 // if we're connected to a database column, suspend this
2647 impl_disconnectDatabaseColumn_noNotify();
2649 // suspend listening for load-related events at out ambient form.
2650 // This is because an external value binding overrules a possible database binding.
2651 if ( isFormListening() )
2652 doFormListening( false );
2654 // remember this new binding
2655 m_xExternalBinding
= _rxBinding
;
2658 onConnectedExternalValue();
2662 // add as value listener so we get notified when the value changes
2663 Reference
< XModifyBroadcaster
> xModifiable( m_xExternalBinding
, UNO_QUERY
);
2664 if ( xModifiable
.is() )
2665 xModifiable
->addModifyListener( this );
2667 // add as property change listener for some (possibly present) properties we're
2669 Reference
< XPropertySet
> xBindingProps( m_xExternalBinding
, UNO_QUERY
);
2670 Reference
< XPropertySetInfo
> xBindingPropsInfo( xBindingProps
.is() ? xBindingProps
->getPropertySetInfo() : Reference
< XPropertySetInfo
>() );
2671 if ( xBindingPropsInfo
.is() )
2673 if ( xBindingPropsInfo
->hasPropertyByName( PROPERTY_READONLY
) )
2675 xBindingProps
->addPropertyChangeListener( PROPERTY_READONLY
, this );
2676 m_bBindingControlsRO
= sal_True
;
2678 if ( xBindingPropsInfo
->hasPropertyByName( PROPERTY_RELEVANT
) )
2680 xBindingProps
->addPropertyChangeListener( PROPERTY_RELEVANT
, this );
2681 m_bBindingControlsEnable
= sal_True
;
2685 catch( const Exception
& )
2687 DBG_UNHANDLED_EXCEPTION();
2690 // propagate our new value
2691 transferExternalValueToControl( _rInstanceLock
);
2693 // if the binding is also a validator, use it, too. This is a constraint of the
2694 // com.sun.star.form.binding.ValidatableBindableFormComponent service
2695 if ( m_bSupportsValidation
)
2699 Reference
< XValidator
> xAsValidator( _rxBinding
, UNO_QUERY
);
2700 if ( xAsValidator
.is() )
2701 setValidator( xAsValidator
);
2703 catch( const Exception
& )
2705 DBG_UNHANDLED_EXCEPTION();
2710 //--------------------------------------------------------------------
2711 void OBoundControlModel::disconnectExternalValueBinding( )
2715 // not listening at the binding anymore
2716 Reference
< XModifyBroadcaster
> xModifiable( m_xExternalBinding
, UNO_QUERY
);
2717 if ( xModifiable
.is() )
2718 xModifiable
->removeModifyListener( this );
2720 // remove as property change listener
2721 Reference
< XPropertySet
> xBindingProps( m_xExternalBinding
, UNO_QUERY
);
2722 if ( m_bBindingControlsRO
)
2723 xBindingProps
->removePropertyChangeListener( PROPERTY_READONLY
, this );
2724 if ( m_bBindingControlsEnable
)
2725 xBindingProps
->removePropertyChangeListener( PROPERTY_RELEVANT
, this );
2727 catch( const Exception
& )
2729 OSL_ENSURE( sal_False
, "OBoundControlModel::disconnectExternalValueBinding: caught an exception!" );
2732 // if the binding also acts as our validator, disconnect the validator, too
2733 if ( ( m_xExternalBinding
== m_xValidator
) && m_xValidator
.is() )
2734 disconnectValidator( );
2736 // no binding anymore
2737 m_xExternalBinding
.clear();
2739 // be a load listener at our form, again. This was suspended while we had
2740 // an external value binding in place.
2741 doFormListening( true );
2743 // re-connect to database column of the new parent
2744 if ( m_xAmbientForm
.is() && m_xAmbientForm
->isLoaded() )
2745 impl_connectDatabaseColumn_noNotify( false );
2748 onDisconnectedExternalValue();
2751 //--------------------------------------------------------------------
2752 void SAL_CALL
OBoundControlModel::setValueBinding( const Reference
< XValueBinding
>& _rxBinding
) throw (IncompatibleTypesException
, RuntimeException
)
2754 OSL_PRECOND( m_bSupportsExternalBinding
, "OBoundControlModel::setValueBinding: How did you reach this method?" );
2755 // the interface for this method should not have been exposed if we do not
2756 // support binding to external data
2758 if ( _rxBinding
.is() && !impl_approveValueBinding_nolock( _rxBinding
) )
2760 throw IncompatibleTypesException(
2761 FRM_RES_STRING( RID_STR_INCOMPATIBLE_TYPES
),
2766 ControlModelLock
aLock( *this );
2768 // since a ValueBinding overrules any potentially active database binding, the change in a ValueBinding
2769 // might trigger a change in our BoundField.
2770 FieldChangeNotifier
aBoundFieldNotifier( aLock
);
2772 // disconnect from the old binding
2773 if ( hasExternalValueBinding() )
2774 disconnectExternalValueBinding( );
2776 // connect to the new binding
2777 if ( _rxBinding
.is() )
2778 connectExternalValueBinding( _rxBinding
, aLock
);
2781 //--------------------------------------------------------------------
2782 Reference
< XValueBinding
> SAL_CALL
OBoundControlModel::getValueBinding( ) throw (RuntimeException
)
2784 ::osl::MutexGuard
aGuard( m_aMutex
);
2785 OSL_PRECOND( m_bSupportsExternalBinding
, "OBoundControlModel::getValueBinding: How did you reach this method?" );
2786 // the interface for this method should not have been exposed if we do not
2787 // support binding to external data
2789 return m_xExternalBinding
;
2792 //--------------------------------------------------------------------
2793 void SAL_CALL
OBoundControlModel::modified( const EventObject
& _rEvent
) throw ( RuntimeException
)
2795 ControlModelLock
aLock( *this );
2797 OSL_PRECOND( hasExternalValueBinding(), "OBoundControlModel::modified: Where did this come from?" );
2798 if ( !m_bTransferingValue
&& ( m_xExternalBinding
== _rEvent
.Source
) && m_xExternalBinding
.is() )
2800 transferExternalValueToControl( aLock
);
2804 //--------------------------------------------------------------------
2805 void OBoundControlModel::transferDbValueToControl( )
2807 setControlValue( translateDbColumnToControlValue(), eDbColumnBinding
);
2810 //------------------------------------------------------------------------------
2811 void OBoundControlModel::transferExternalValueToControl( ControlModelLock
& _rInstanceLock
)
2813 Reference
< XValueBinding
> xExternalBinding( m_xExternalBinding
);
2814 Type
aValueExchangeType( getExternalValueType() );
2816 _rInstanceLock
.release();
2817 // >>>>>>>> ----- UNSAFE ----- >>>>>>>>
2821 aExternalValue
= xExternalBinding
->getValue( aValueExchangeType
);
2823 catch( const Exception
& )
2825 DBG_UNHANDLED_EXCEPTION();
2827 // <<<<<<<< ----- UNSAFE ----- <<<<<<<<
2828 _rInstanceLock
.acquire();
2830 setControlValue( translateExternalValueToControlValue( aExternalValue
), eExternalBinding
);
2833 //------------------------------------------------------------------------------
2834 void OBoundControlModel::transferControlValueToExternal( ControlModelLock
& _rInstanceLock
)
2836 OSL_PRECOND( m_bSupportsExternalBinding
&& hasExternalValueBinding(),
2837 "OBoundControlModel::transferControlValueToExternal: precondition not met!" );
2839 if ( m_xExternalBinding
.is() )
2841 Any
aExternalValue( translateControlValueToExternalValue() );
2842 m_bTransferingValue
= sal_True
;
2844 _rInstanceLock
.release();
2845 // >>>>>>>> ----- UNSAFE ----- >>>>>>>>
2848 m_xExternalBinding
->setValue( aExternalValue
);
2850 catch( const Exception
& )
2852 DBG_UNHANDLED_EXCEPTION();
2854 // <<<<<<<< ----- UNSAFE ----- <<<<<<<<
2855 _rInstanceLock
.acquire();
2857 m_bTransferingValue
= sal_False
;
2861 // -----------------------------------------------------------------------------
2862 Sequence
< Type
> OBoundControlModel::getSupportedBindingTypes()
2864 return Sequence
< Type
>( &m_aValuePropertyType
, 1 );
2867 //-----------------------------------------------------------------------------
2868 void OBoundControlModel::calculateExternalValueType()
2870 m_aExternalValueType
= Type();
2871 if ( !m_xExternalBinding
.is() )
2874 Sequence
< Type
> aTypeCandidates( getSupportedBindingTypes() );
2875 for ( const Type
* pTypeCandidate
= aTypeCandidates
.getConstArray();
2876 pTypeCandidate
!= aTypeCandidates
.getConstArray() + aTypeCandidates
.getLength();
2880 if ( m_xExternalBinding
->supportsType( *pTypeCandidate
) )
2882 m_aExternalValueType
= *pTypeCandidate
;
2888 //-----------------------------------------------------------------------------
2889 Any
OBoundControlModel::translateExternalValueToControlValue( const Any
& _rExternalValue
) const
2891 OSL_PRECOND( m_bSupportsExternalBinding
&& hasExternalValueBinding(),
2892 "OBoundControlModel::translateExternalValueToControlValue: precondition not met!" );
2894 Any
aControlValue( _rExternalValue
);
2896 // if the external value is VOID, and our value property is not allowed to be VOID,
2897 // then default-construct a value
2898 if ( !aControlValue
.hasValue() && !m_bValuePropertyMayBeVoid
)
2899 aControlValue
.setValue( NULL
, m_aValuePropertyType
);
2902 return aControlValue
;
2905 //------------------------------------------------------------------------------
2906 Any
OBoundControlModel::translateControlValueToExternalValue( ) const
2908 return getControlValue( );
2911 //------------------------------------------------------------------------------
2912 Any
OBoundControlModel::translateControlValueToValidatableValue( ) const
2914 OSL_PRECOND( m_xValidator
.is(), "OBoundControlModel::translateControlValueToValidatableValue: no validator, so why should I?" );
2915 if ( ( m_xValidator
== m_xExternalBinding
) && m_xValidator
.is() )
2916 return translateControlValueToExternalValue();
2917 return getControlValue();
2920 //------------------------------------------------------------------------------
2921 Any
OBoundControlModel::getControlValue( ) const
2923 OSL_PRECOND( m_xAggregateFastSet
.is() && m_xAggregateSet
.is(),
2924 "OBoundControlModel::getControlValue: invalid aggregate !" );
2925 OSL_PRECOND( m_sValuePropertyName
.getLength() || ( m_nValuePropertyAggregateHandle
!= -1 ),
2926 "OBoundControlModel::getControlValue: please override if you have own value property handling!" );
2928 // determine the current control value
2930 if ( ( m_nValuePropertyAggregateHandle
!= -1 ) && m_xAggregateFastSet
.is() )
2932 aControlValue
= m_xAggregateFastSet
->getFastPropertyValue( m_nValuePropertyAggregateHandle
);
2934 else if ( m_sValuePropertyName
.getLength() && m_xAggregateSet
.is() )
2936 aControlValue
= m_xAggregateSet
->getPropertyValue( m_sValuePropertyName
);
2939 return aControlValue
;
2942 //--------------------------------------------------------------------
2943 void OBoundControlModel::connectValidator( const Reference
< XValidator
>& _rxValidator
)
2945 OSL_PRECOND( _rxValidator
.is(), "OBoundControlModel::connectValidator: invalid validator instance!" );
2946 OSL_PRECOND( !hasValidator( ), "OBoundControlModel::connectValidator: precond not met (have a validator currently)!" );
2948 m_xValidator
= _rxValidator
;
2950 // add as value listener so we get notified when the value changes
2951 if ( m_xValidator
.is() )
2955 m_xValidator
->addValidityConstraintListener( this );
2957 catch( const RuntimeException
& )
2962 onConnectedValidator( );
2965 //--------------------------------------------------------------------
2966 void OBoundControlModel::disconnectValidator( )
2968 OSL_PRECOND( hasValidator( ), "OBoundControlModel::connectValidator: precond not met (don't have a validator currently)!" );
2970 // add as value listener so we get notified when the value changes
2971 if ( m_xValidator
.is() )
2975 m_xValidator
->removeValidityConstraintListener( this );
2977 catch( const RuntimeException
& )
2982 m_xValidator
.clear();
2984 onDisconnectedValidator( );
2987 //--------------------------------------------------------------------
2988 void SAL_CALL
OBoundControlModel::setValidator( const Reference
< XValidator
>& _rxValidator
) throw (VetoException
,RuntimeException
)
2990 ::osl::ClearableMutexGuard
aGuard( m_aMutex
);
2991 OSL_PRECOND( m_bSupportsValidation
, "OBoundControlModel::setValidator: How did you reach this method?" );
2992 // the interface for this method should not have been exposed if we do not
2993 // support validation
2995 // early out if the validator does not change
2996 if( _rxValidator
== m_xValidator
)
2999 if ( m_xValidator
.is() && ( m_xValidator
== m_xExternalBinding
) )
3000 throw VetoException(
3001 FRM_RES_STRING( RID_STR_INVALID_VALIDATOR
),
3005 // disconnect from the old validator
3006 if ( hasValidator() )
3007 disconnectValidator( );
3009 // connect to the new validator
3010 if ( _rxValidator
.is() )
3011 connectValidator( _rxValidator
);
3014 //--------------------------------------------------------------------
3015 Reference
< XValidator
> SAL_CALL
OBoundControlModel::getValidator( ) throw (RuntimeException
)
3017 ::osl::MutexGuard
aGuard( m_aMutex
);
3018 OSL_PRECOND( m_bSupportsValidation
, "OBoundControlModel::getValidator: How did you reach this method?" );
3019 // the interface for this method should not have been exposed if we do not
3020 // support validation
3022 return m_xValidator
;
3025 //--------------------------------------------------------------------
3026 void SAL_CALL
OBoundControlModel::validityConstraintChanged( const EventObject
& /*Source*/ ) throw (RuntimeException
)
3028 ::osl::ClearableMutexGuard
aGuard( m_aMutex
);
3029 OSL_PRECOND( m_bSupportsValidation
, "OBoundControlModel::validityConstraintChanged: How did you reach this method?" );
3030 // the interface for this method should not have been exposed if we do not
3031 // support validation
3033 recheckValidity( false );
3036 //--------------------------------------------------------------------
3037 sal_Bool SAL_CALL
OBoundControlModel::isValid( ) throw (RuntimeException
)
3039 return m_bIsCurrentValueValid
;
3042 //--------------------------------------------------------------------
3043 ::com::sun::star::uno::Any
OBoundControlModel::getCurrentFormComponentValue() const
3045 if ( hasValidator() )
3046 return translateControlValueToValidatableValue();
3047 return getControlValue();
3050 //--------------------------------------------------------------------
3051 Any SAL_CALL
OBoundControlModel::getCurrentValue( ) throw (RuntimeException
)
3053 ::osl::MutexGuard
aGuard( m_aMutex
);
3054 return getCurrentFormComponentValue();
3057 //--------------------------------------------------------------------
3058 void SAL_CALL
OBoundControlModel::addFormComponentValidityListener( const Reference
< validation::XFormComponentValidityListener
>& Listener
) throw (NullPointerException
, RuntimeException
)
3060 if ( Listener
.is() )
3061 m_aFormComponentListeners
.addInterface( Listener
);
3064 //--------------------------------------------------------------------
3065 void SAL_CALL
OBoundControlModel::removeFormComponentValidityListener( const Reference
< validation::XFormComponentValidityListener
>& Listener
) throw (NullPointerException
, RuntimeException
)
3067 if ( Listener
.is() )
3068 m_aFormComponentListeners
.removeInterface( Listener
);
3071 //--------------------------------------------------------------------
3072 void OBoundControlModel::recheckValidity( bool _bForceNotification
)
3076 sal_Bool bIsCurrentlyValid
= sal_True
;
3077 if ( hasValidator() )
3078 bIsCurrentlyValid
= m_xValidator
->isValid( translateControlValueToValidatableValue() );
3080 if ( ( bIsCurrentlyValid
!= m_bIsCurrentValueValid
) || _bForceNotification
)
3082 m_bIsCurrentValueValid
= bIsCurrentlyValid
;
3084 // release our mutex for the notifications
3085 MutexRelease
aRelease( m_aMutex
);
3086 m_aFormComponentListeners
.notifyEach( &validation::XFormComponentValidityListener::componentValidityChanged
, EventObject( *this ) );
3089 catch( const Exception
& )
3091 OSL_ENSURE( sal_False
, "OBoundControlModel::recheckValidity: caught an exception!" );
3095 //------------------------------------------------------------------------------
3096 void OBoundControlModel::describeFixedProperties( Sequence
< Property
>& _rProps
) const
3098 BEGIN_DESCRIBE_PROPERTIES( 5, OControlModel
)
3099 DECL_PROP1 ( CONTROLSOURCE
, ::rtl::OUString
, BOUND
);
3100 DECL_IFACE_PROP3( BOUNDFIELD
, XPropertySet
, BOUND
, READONLY
, TRANSIENT
);
3101 DECL_IFACE_PROP2( CONTROLLABEL
, XPropertySet
, BOUND
, MAYBEVOID
);
3102 DECL_PROP2 ( CONTROLSOURCEPROPERTY
, ::rtl::OUString
, READONLY
, TRANSIENT
);
3103 DECL_BOOL_PROP1 ( INPUT_REQUIRED
, BOUND
);
3104 END_DESCRIBE_PROPERTIES()
3107 // -----------------------------------------------------------------------------
3109 //.........................................................................
3111 //... namespace frm .......................................................