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