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