xref: /trunk/main/forms/source/inc/FormComponent.hxx (revision cdf0e10c)
1 /*************************************************************************
2  *
3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4  *
5  * Copyright 2000, 2010 Oracle and/or its affiliates.
6  *
7  * OpenOffice.org - a multi-platform office productivity suite
8  *
9  * This file is part of OpenOffice.org.
10  *
11  * OpenOffice.org is free software: you can redistribute it and/or modify
12  * it under the terms of the GNU Lesser General Public License version 3
13  * only, as published by the Free Software Foundation.
14  *
15  * OpenOffice.org is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18  * GNU Lesser General Public License version 3 for more details
19  * (a copy is included in the LICENSE file that accompanied this code).
20  *
21  * You should have received a copy of the GNU Lesser General Public License
22  * version 3 along with OpenOffice.org.  If not, see
23  * <http://www.openoffice.org/license.html>
24  * for a copy of the LGPLv3 License.
25  *
26  ************************************************************************/
27 
28 #ifndef _FORMS_FORMCOMPONENT_HXX_
29 #define _FORMS_FORMCOMPONENT_HXX_
30 
31 #include "cloneable.hxx"
32 #include "ids.hxx"
33 #include "property.hrc"
34 #include "property.hxx"
35 #include "propertybaghelper.hxx"
36 #include "resettable.hxx"
37 #include "services.hxx"
38 #include "windowstateguard.hxx"
39 
40 /** === begin UNO includes === **/
41 #include <com/sun/star/awt/XControl.hpp>
42 #include <com/sun/star/beans/XPropertyAccess.hpp>
43 #include <com/sun/star/beans/XPropertyContainer.hpp>
44 #include <com/sun/star/container/XChild.hpp>
45 #include <com/sun/star/container/XNamed.hpp>
46 #include <com/sun/star/form/binding/XBindableValue.hpp>
47 #include <com/sun/star/form/FormComponentType.hpp>
48 #include <com/sun/star/form/validation/XValidatableFormComponent.hpp>
49 #include <com/sun/star/form/validation/XValidityConstraintListener.hpp>
50 #include <com/sun/star/form/XBoundComponent.hpp>
51 #include <com/sun/star/form/XBoundControl.hpp>
52 #include <com/sun/star/form/XFormComponent.hpp>
53 #include <com/sun/star/form/XLoadListener.hpp>
54 #include <com/sun/star/form/XReset.hpp>
55 #include <com/sun/star/io/XMarkableStream.hpp>
56 #include <com/sun/star/io/XPersistObject.hpp>
57 #include <com/sun/star/lang/DisposedException.hpp>
58 #include <com/sun/star/lang/XEventListener.hpp>
59 #include <com/sun/star/lang/XMultiServiceFactory.hpp>
60 #include <com/sun/star/lang/XServiceInfo.hpp>
61 #include <com/sun/star/sdb/XColumn.hpp>
62 #include <com/sun/star/sdb/XColumnUpdate.hpp>
63 #include <com/sun/star/sdb/XRowSetChangeListener.hpp>
64 #include <com/sun/star/sdbc/XRowSet.hpp>
65 #include <com/sun/star/sdbcx/XColumnsSupplier.hpp>
66 #include <com/sun/star/uno/XAggregation.hpp>
67 #include <com/sun/star/util/XCloneable.hpp>
68 #include <com/sun/star/util/XModifyListener.hpp>
69 #include <com/sun/star/form/XLoadable.hpp>
70 /** === end UNO includes === **/
71 
72 #include <comphelper/componentcontext.hxx>
73 #include <comphelper/propagg.hxx>
74 #include <comphelper/propertybag.hxx>
75 #include <comphelper/propmultiplex.hxx>
76 #include <comphelper/sequence.hxx>
77 #include <comphelper/uno3.hxx>
78 #include <cppuhelper/component.hxx>
79 #include <cppuhelper/implbase1.hxx>
80 #include <cppuhelper/implbase2.hxx>
81 #include <cppuhelper/implbase3.hxx>
82 #include <cppuhelper/implbase4.hxx>
83 #include <cppuhelper/implbase7.hxx>
84 #include <osl/mutex.hxx>
85 #include <rtl/ustring.hxx>
86 
87 #include <memory>
88 
89 //.........................................................................
90 namespace frm
91 {
92 //.........................................................................
93 
94     // default tab index for components
95     const sal_Int16 FRM_DEFAULT_TABINDEX = 0;
96 
97     // macros for quickly declaring/implementing XServiceInfo
98     #define DECLARE_XPERSISTOBJECT() \
99     virtual ::rtl::OUString SAL_CALL getServiceName() throw(::com::sun::star::uno::RuntimeException);    \
100     virtual void SAL_CALL write(const ::com::sun::star::uno::Reference< ::com::sun::star::io::XObjectOutputStream>& _rxOutStream) throw(::com::sun::star::io::IOException, ::com::sun::star::uno::RuntimeException);    \
101     virtual void SAL_CALL read(const ::com::sun::star::uno::Reference< ::com::sun::star::io::XObjectInputStream>& _rxInStream) throw(::com::sun::star::io::IOException, ::com::sun::star::uno::RuntimeException);   \
102 
103     // old macro for quickly implementing XServiceInfo::getImplementationName
104     #define IMPLEMENTATION_NAME(ImplName)										\
105     virtual ::rtl::OUString SAL_CALL getImplementationName(  ) throw(::com::sun::star::uno::RuntimeException) \
106 		{ return ::rtl::OUString::createFromAscii("com.sun.star.comp.forms.") + ::rtl::OUString::createFromAscii(#ImplName); }
107 
108     class OControlModel;
109 
110     //=========================================================================
111     //= ControlModelLock
112     //=========================================================================
113     /** class whose instances lock a OControlModel
114 
115         Locking here merely means locking the OControlModel's mutex.
116 
117         In addition to the locking facility, the class is also able to fire property
118         change notifications. This happens when the last ControlModelLock instance on a stack
119         dies.
120     */
121     class ControlModelLock
122     {
123     public:
124         ControlModelLock( OControlModel& _rModel )
125             :m_rModel( _rModel )
126             ,m_bLocked( false )
127         {
128             acquire();
129         }
130 
131         ~ControlModelLock()
132         {
133             if ( m_bLocked )
134                 release();
135         }
136         inline void acquire();
137         inline void release();
138 
139         inline OControlModel& getModel() const { return m_rModel; };
140 
141         /** adds a property change notification, which is to be fired when the last lock on the model
142             (in the current thread) is released.
143         */
144         void    addPropertyNotification(
145                     const sal_Int32 _nHandle,
146                     const ::com::sun::star::uno::Any& _rOldValue,
147                     const ::com::sun::star::uno::Any& _rNewValue
148                 );
149 
150     private:
151         void    impl_notifyAll_nothrow();
152 
153     private:
154         OControlModel&                                                  m_rModel;
155         bool                                                            m_bLocked;
156         ::com::sun::star::uno::Sequence< sal_Int32 >                    m_aHandles;
157         ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Any >   m_aOldValues;
158         ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Any >   m_aNewValues;
159 
160     private:
161         ControlModelLock();                                     // never implemented
162         ControlModelLock( const ControlModelLock& );            // never implemented
163         ControlModelLock& operator=( const ControlModelLock& ); // never implemented
164     };
165 
166 //=========================================================================
167 //= OControl
168 //= base class for form layer controls
169 //=========================================================================
170 typedef ::cppu::ImplHelper3	<	::com::sun::star::awt::XControl
171 							,	::com::sun::star::lang::XEventListener
172 							,	::com::sun::star::lang::XServiceInfo
173 							> OControl_BASE;
174 
175 class OControl	:public ::cppu::OComponentHelper
176 				,public OControl_BASE
177 {
178 protected:
179     ::osl::Mutex                                m_aMutex;
180 	OImplementationIdsRef						m_aHoldIdHelper;
181 	::com::sun::star::uno::Reference< ::com::sun::star::awt::XControl >
182 												m_xControl;
183 	::com::sun::star::uno::Reference< ::com::sun::star::uno::XAggregation>
184 												m_xAggregate;
185 
186     ::comphelper::ComponentContext              m_aContext;
187     WindowStateGuard                            m_aWindowStateGuard;
188 
189 public:
190     /** constructs a control
191 
192         @param _rFactory
193             the service factory for this control
194         @param _rAggregateService
195             the service name of the component to aggregate
196         @param _bSetDelegator
197             set this to <FALSE/> if you don't want the constructor to set the delegator at
198             the aggregate. In this case, you <em>have</em> to call doSetDelegator within your
199             own constructor.
200 
201             This is helpfull, if your derived class wants to cache an interface of the aggregate.
202             In this case, the aggregate needs to be queried for this interface <b>before</b> the
203             <member scope="com::sun::star::uno">XAggregation::setDelegator</member> call.
204 
205             In such a case, pass <FALSE/> to this parameter. Then, cache the aggregate's interface(s)
206             as needed. Afterwards, call <member>doSetDelegator</member>.
207 
208             In your destructor, you need to call <member>doResetDelegator</member> before
209             resetting the cached interfaces. This will reset the aggregates delegator to <NULL/>,
210             which will ensure that the <member scope="com::sun::star::uno">XInterface::release</member>
211             calls on the cached interfaces are really applied to the aggregate, instead of
212             the <type>OControl</type> itself.
213     */
214 	OControl(
215         const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory >& _rFactory,
216         const ::rtl::OUString& _rAggregateService,
217         const sal_Bool _bSetDelegator = sal_True
218     );
219 
220     /** initializes the given peer with various settings necessary for form controls
221     */
222     static  void    initFormControlPeer(
223         const ::com::sun::star::uno::Reference< ::com::sun::star::awt::XWindowPeer >& _rxPeer );
224 
225 protected:
226 	virtual ~OControl();
227 
228     /** sets the control as delegator at the aggregate
229 
230         This has to be called from within your derived class' constructor, if and only
231         if you passed <FALSE/> to the <arg>_bSetDelegator</arg> parameter of the
232         <type>OControl</type> constructor.
233     */
234 	void	doSetDelegator();
235 	void	doResetDelegator();
236 
237 // UNO
238 	DECLARE_UNO3_AGG_DEFAULTS(OControl, OComponentHelper);
239 	virtual ::com::sun::star::uno::Any SAL_CALL queryAggregation( const ::com::sun::star::uno::Type& _rType ) throw(::com::sun::star::uno::RuntimeException);
240 
241 // XTypeProvider
242 	virtual ::com::sun::star::uno::Sequence<sal_Int8>			SAL_CALL getImplementationId() throw(::com::sun::star::uno::RuntimeException);
243     virtual ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Type>	SAL_CALL getTypes() throw(::com::sun::star::uno::RuntimeException);
244 
245 // OComponentHelper
246 	virtual void SAL_CALL disposing();
247 
248 // XComponent (as base of XControl)
249     virtual void SAL_CALL dispose(  ) throw(::com::sun::star::uno::RuntimeException)
250 		{ OComponentHelper::dispose(); }
251     virtual void SAL_CALL addEventListener( const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XEventListener>& _rxListener) throw(::com::sun::star::uno::RuntimeException)
252 		{ OComponentHelper::addEventListener(_rxListener); }
253     virtual void SAL_CALL removeEventListener( const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XEventListener>& _rxListener) throw(::com::sun::star::uno::RuntimeException)
254 		{ OComponentHelper::removeEventListener(_rxListener); }
255 
256 // XEventListener
257 	virtual void SAL_CALL disposing(const ::com::sun::star::lang::EventObject& Source) throw (::com::sun::star::uno::RuntimeException);
258 
259 // XServiceInfo
260 	virtual sal_Bool SAL_CALL			supportsService(const ::rtl::OUString& ServiceName) throw (::com::sun::star::uno::RuntimeException);
261 	virtual StringSequence SAL_CALL		getSupportedServiceNames() throw(::com::sun::star::uno::RuntimeException);
262     virtual ::rtl::OUString SAL_CALL	getImplementationName() throw(::com::sun::star::uno::RuntimeException) = 0;
263 
264 // XServiceInfo - static version
265 	static  StringSequence SAL_CALL		getSupportedServiceNames_Static() throw(::com::sun::star::uno::RuntimeException);
266 
267 // XControl
268 	virtual void										SAL_CALL setContext(const InterfaceRef& Context) throw (::com::sun::star::uno::RuntimeException);
269 	virtual InterfaceRef								SAL_CALL getContext() throw (::com::sun::star::uno::RuntimeException);
270 	virtual void										SAL_CALL createPeer(const ::com::sun::star::uno::Reference<starawt::XToolkit>& Toolkit, const ::com::sun::star::uno::Reference<starawt::XWindowPeer>& Parent) throw (::com::sun::star::uno::RuntimeException);
271 	virtual ::com::sun::star::uno::Reference<starawt::XWindowPeer>	SAL_CALL getPeer() throw (::com::sun::star::uno::RuntimeException);
272 	virtual sal_Bool									SAL_CALL setModel(const ::com::sun::star::uno::Reference<starawt::XControlModel>& Model) throw (::com::sun::star::uno::RuntimeException);
273 	virtual ::com::sun::star::uno::Reference<starawt::XControlModel>	SAL_CALL getModel() throw (::com::sun::star::uno::RuntimeException);
274 	virtual ::com::sun::star::uno::Reference<starawt::XView>			SAL_CALL getView() throw (::com::sun::star::uno::RuntimeException);
275 	virtual void										SAL_CALL setDesignMode(sal_Bool bOn) throw (::com::sun::star::uno::RuntimeException);
276 	virtual sal_Bool									SAL_CALL isDesignMode() throw (::com::sun::star::uno::RuntimeException);
277 	virtual sal_Bool									SAL_CALL isTransparent() throw (::com::sun::star::uno::RuntimeException);
278 
279 protected:
280 	virtual ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Type>	_getTypes();
281 		// overwrite this and call the base class if you have additional types
282 
283     ::com::sun::star::uno::Sequence< ::rtl::OUString > getAggregateServiceNames();
284 
285 private:
286     void    impl_resetStateGuard_nothrow();
287 };
288 
289 //==================================================================
290 //= OBoundControl
291 //= a form control implementing the XBoundControl interface
292 //==================================================================
293 typedef ::cppu::ImplHelper1 <   ::com::sun::star::form::XBoundControl
294                             >  OBoundControl_BASE;
295 class OBoundControl	:public OControl
296 					,public OBoundControl_BASE
297 {
298 protected:
299 	sal_Bool	m_bLocked : 1;
300 
301     ::rtl::OUString m_sOriginalHelpText;                // as long as the text/value is invalid, we change the help text of our peer
302     ::com::sun::star::awt::FontDescriptor
303                     m_aOriginalFont;                    // as long as the text/value is invalid, we also change the font
304     sal_Int32       m_nOriginalTextLineColor;           // (we add red underlining)
305 
306 public:
307     OBoundControl(
308         const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory >& _rxFactory,
309         const ::rtl::OUString& _rAggregateService,
310         const sal_Bool _bSetDelegator = sal_True
311     );
312 
313 	virtual ~OBoundControl();
314 
315 	DECLARE_UNO3_AGG_DEFAULTS(OBoundControl, OControl);
316 	virtual ::com::sun::star::uno::Any SAL_CALL queryAggregation( const ::com::sun::star::uno::Type& _rType ) throw(::com::sun::star::uno::RuntimeException);
317 
318     // XBoundControl
319     virtual sal_Bool SAL_CALL	getLock() throw(::com::sun::star::uno::RuntimeException);
320     virtual void SAL_CALL		setLock(sal_Bool _bLock) throw(::com::sun::star::uno::RuntimeException);
321 		// default implementation just disables the controls, overwrite _setLock to change this behaviour
322 
323     // XControl
324 	virtual sal_Bool SAL_CALL setModel(const ::com::sun::star::uno::Reference< ::com::sun::star::awt::XControlModel >& Model) throw (::com::sun::star::uno::RuntimeException);
325 
326     // XEventListener
327 	virtual void SAL_CALL disposing(const ::com::sun::star::lang::EventObject& Source) throw (::com::sun::star::uno::RuntimeException);
328 
329     // OComponentHelper
330 	virtual void SAL_CALL disposing();
331 
332 protected:
333 	virtual ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Type>	_getTypes();
334 	// implement the lock setting
335 	virtual void		 _setLock(sal_Bool _bLock);
336 };
337 
338 //==================================================================
339 //= OControlModel
340 //= model of a form layer control
341 //==================================================================
342 
343 typedef ::cppu::ImplHelper7	<	::com::sun::star::form::XFormComponent
344 							,	::com::sun::star::io::XPersistObject
345 							,	::com::sun::star::container::XNamed
346 							,	::com::sun::star::lang::XServiceInfo
347 							,	::com::sun::star::util::XCloneable
348 							,	::com::sun::star::beans::XPropertyContainer
349 							,	::com::sun::star::beans::XPropertyAccess
350 							>	OControlModel_BASE;
351 
352 class OControlModel	:public ::cppu::OComponentHelper
353 					,public OPropertySetAggregationHelper
354 					,public OControlModel_BASE
355 					,public OCloneableAggregation
356                     ,public IPropertyBagHelperContext
357 {
358 
359 protected:
360     ::comphelper::ComponentContext  m_aContext;
361 
362     ::osl::Mutex                    m_aMutex;
363     oslInterlockedCount             m_lockCount;
364 
365 	InterfaceRef					m_xParent;					// ParentComponent
366 	OImplementationIdsRef			m_aHoldIdHelper;
367     PropertyBagHelper               m_aPropertyBagHelper;
368 
369     const ::comphelper::ComponentContext&
370         getContext() const { return m_aContext; }
371 
372 // <properties>
373 	::rtl::OUString					m_aName;					// name of the control
374 	::rtl::OUString					m_aTag;						// tag for additional data
375 	sal_Int16						m_nTabIndex;				// index within the taborder
376 	sal_Int16						m_nClassId;					// type of the control
377     sal_Bool                        m_bNativeLook;              // should the control use the native platform look?
378 // </properties>
379 
380 
381 protected:
382 	OControlModel(
383 		const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory>& _rFactory,	// factory to create the aggregate with
384 		const ::rtl::OUString& _rUnoControlModelTypeName,						// service name of te model to aggregate
385 		const ::rtl::OUString& rDefault = ::rtl::OUString(),					// service name of the default control
386 		const sal_Bool _bSetDelegator = sal_True								// set to sal_False if you want to call setDelegator later (after returning from this ctor)
387 	);
388 	OControlModel(
389 		const OControlModel* _pOriginal,										// the original object to clone
390 		const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory>& _rFactory,	// factory to create the aggregate with
391         const sal_Bool _bCloneAggregate = sal_True,                             // should the aggregate of the original be cloned, too?
392 		const sal_Bool _bSetDelegator = sal_True								// set to sal_False if you want to call setDelegator later (after returning from this ctor)
393 	);
394 	virtual ~OControlModel();
395 
396     /** to be called after a OBoundControlModel (a derivee, respectively) has been cloned
397 
398         <p>This method contains late initializations which cannot be done in the
399         constructor of this base class, since the virtual method of derived classes do
400         not yet work there.</p>
401     */
402     virtual void clonedFrom( const OControlModel* _pOriginal );
403 
404 	using OComponentHelper::rBHelper;
405 
406 	virtual ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Type>	_getTypes();
407 
408 	void	readHelpTextCompatibly(const ::com::sun::star::uno::Reference< ::com::sun::star::io::XObjectInputStream >& _rxInStream);
409 	void	writeHelpTextCompatibly(const ::com::sun::star::uno::Reference< ::com::sun::star::io::XObjectOutputStream >& _rxOutStream);
410 
411 	void	doSetDelegator();
412 	void	doResetDelegator();
413 
414 	::com::sun::star::uno::Sequence< ::rtl::OUString > getAggregateServiceNames();
415 
416 public:
417 	DECLARE_UNO3_AGG_DEFAULTS(OControl, OComponentHelper);
418 	virtual ::com::sun::star::uno::Any SAL_CALL queryAggregation( const ::com::sun::star::uno::Type& _rType ) throw (::com::sun::star::uno::RuntimeException);
419 
420 // XTypeProvider
421 	virtual ::com::sun::star::uno::Sequence<sal_Int8>			SAL_CALL getImplementationId() throw(::com::sun::star::uno::RuntimeException);
422     virtual ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Type>	SAL_CALL getTypes() throw(::com::sun::star::uno::RuntimeException);
423 
424 // OComponentHelper
425 	virtual void SAL_CALL disposing();
426 
427 // XNamed
428 	virtual ::rtl::OUString SAL_CALL	getName() throw(::com::sun::star::uno::RuntimeException);
429 	virtual void SAL_CALL				setName(const ::rtl::OUString& aName) throw(::com::sun::star::uno::RuntimeException);
430 
431 // XServiceInfo
432 	virtual sal_Bool SAL_CALL			supportsService(const ::rtl::OUString& ServiceName) throw (::com::sun::star::uno::RuntimeException);
433 	virtual StringSequence SAL_CALL		getSupportedServiceNames() throw(::com::sun::star::uno::RuntimeException);
434     virtual ::rtl::OUString SAL_CALL	getImplementationName() throw(::com::sun::star::uno::RuntimeException) = 0;
435 
436 // XSericeInfo - static version(s)
437 	static  StringSequence SAL_CALL		getSupportedServiceNames_Static() throw(::com::sun::star::uno::RuntimeException);
438 
439 // XPersistObject
440     virtual ::rtl::OUString SAL_CALL	getServiceName() throw(::com::sun::star::uno::RuntimeException) = 0;
441     virtual void SAL_CALL
442 		write(const ::com::sun::star::uno::Reference< ::com::sun::star::io::XObjectOutputStream>& _rxOutStream) throw(::com::sun::star::io::IOException, ::com::sun::star::uno::RuntimeException);
443     virtual void SAL_CALL
444 		read(const ::com::sun::star::uno::Reference< ::com::sun::star::io::XObjectInputStream>& _rxInStream) throw(::com::sun::star::io::IOException, ::com::sun::star::uno::RuntimeException);
445 
446 // XChild (base of XFormComponent)
447     virtual InterfaceRef SAL_CALL	getParent() throw(::com::sun::star::uno::RuntimeException);
448     virtual void SAL_CALL			setParent(const InterfaceRef& Parent) throw(::com::sun::star::lang::NoSupportException, ::com::sun::star::uno::RuntimeException);
449 
450 // XEventListener
451 	virtual void SAL_CALL disposing(const ::com::sun::star::lang::EventObject& Source) throw (::com::sun::star::uno::RuntimeException);
452 
453 // XPropertySet
454 	virtual void SAL_CALL getFastPropertyValue(::com::sun::star::uno::Any& rValue, sal_Int32 nHandle) const;
455 	virtual sal_Bool SAL_CALL convertFastPropertyValue(
456 				::com::sun::star::uno::Any& _rConvertedValue, ::com::sun::star::uno::Any& _rOldValue, sal_Int32 _nHandle, const ::com::sun::star::uno::Any& _rValue )
457 				throw (::com::sun::star::lang::IllegalArgumentException);
458 	virtual void SAL_CALL setFastPropertyValue_NoBroadcast( sal_Int32 nHandle, const ::com::sun::star::uno::Any& rValue )
459 				throw (::com::sun::star::uno::Exception);
460     using ::cppu::OPropertySetHelper::getFastPropertyValue;
461 
462 // ::com::sun::star::beans::XPropertyState
463 	virtual	::com::sun::star::beans::PropertyState getPropertyStateByHandle(sal_Int32 nHandle);
464 	virtual	void setPropertyToDefaultByHandle(sal_Int32 nHandle);
465 	virtual ::com::sun::star::uno::Any getPropertyDefaultByHandle( sal_Int32 nHandle ) const;
466 
467 // XCloneable
468 	virtual ::com::sun::star::uno::Reference< ::com::sun::star::util::XCloneable > SAL_CALL createClone(  ) throw (::com::sun::star::uno::RuntimeException) = 0;
469 
470 // XPropertyContainer
471     virtual void SAL_CALL addProperty( const ::rtl::OUString& Name, ::sal_Int16 Attributes, const ::com::sun::star::uno::Any& DefaultValue ) throw (::com::sun::star::beans::PropertyExistException, ::com::sun::star::beans::IllegalTypeException, ::com::sun::star::lang::IllegalArgumentException, ::com::sun::star::uno::RuntimeException);
472     virtual void SAL_CALL removeProperty( const ::rtl::OUString& Name ) throw (::com::sun::star::beans::UnknownPropertyException, ::com::sun::star::beans::NotRemoveableException, ::com::sun::star::uno::RuntimeException);
473 
474 // XPropertyAccess
475     virtual ::com::sun::star::uno::Sequence< ::com::sun::star::beans::PropertyValue > SAL_CALL getPropertyValues(  ) throw (::com::sun::star::uno::RuntimeException);
476     virtual void SAL_CALL setPropertyValues( const ::com::sun::star::uno::Sequence< ::com::sun::star::beans::PropertyValue >& aProps ) throw (::com::sun::star::beans::UnknownPropertyException, ::com::sun::star::beans::PropertyVetoException, ::com::sun::star::lang::IllegalArgumentException, ::com::sun::star::lang::WrappedTargetException, ::com::sun::star::uno::RuntimeException);
477 
478 protected:
479     using OPropertySetAggregationHelper::setPropertyValues;
480     using OPropertySetAggregationHelper::getPropertyValues;
481 
482 protected:
483     virtual void writeAggregate( const ::com::sun::star::uno::Reference< ::com::sun::star::io::XObjectOutputStream >& _rxOutStream ) const;
484     virtual void readAggregate( const ::com::sun::star::uno::Reference< ::com::sun::star::io::XObjectInputStream >& _rxInStream );
485 
486 protected:
487 	// XPropertySet
488 	virtual ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertySetInfo> SAL_CALL getPropertySetInfo() throw( ::com::sun::star::uno::RuntimeException);
489     // OPropertySetHelper
490 	virtual cppu::IPropertyArrayHelper& SAL_CALL getInfoHelper();
491 
492     /** describes the properties provided by this class, or its respective
493         derived class
494 
495         Derived classes usually call the base class first, and then append own properties.
496     */
497 	virtual void describeFixedProperties(
498 		::com::sun::star::uno::Sequence< ::com::sun::star::beans::Property >& /* [out] */ _rProps
499     ) const;
500 
501     // IPropertyBagHelperContext
502     virtual ::osl::Mutex&   getMutex();
503     virtual void            describeFixedAndAggregateProperties(
504         ::com::sun::star::uno::Sequence< ::com::sun::star::beans::Property >& _out_rFixedProperties,
505         ::com::sun::star::uno::Sequence< ::com::sun::star::beans::Property >& _out_rAggregateProperties
506     ) const;
507     virtual ::com::sun::star::uno::Reference< ::com::sun::star::beans::XMultiPropertySet >
508                             getPropertiesInterface();
509 
510     /** describes the properties of our aggregate
511 
512         The default implementation simply asks m_xAggregateSet for its properties.
513 
514         You usually only need to overload this method if you want to filter the aggregate
515         properties.
516     */
517     virtual void describeAggregateProperties(
518 		::com::sun::star::uno::Sequence< ::com::sun::star::beans::Property >& /* [out] */ _rAggregateProps
519     ) const;
520 
521 public:
522     struct LockAccess { friend class ControlModelLock; private: LockAccess() { } };
523 
524     void                lockInstance( LockAccess );
525     oslInterlockedCount unlockInstance( LockAccess );
526 
527     void                firePropertyChanges(
528                             const ::com::sun::star::uno::Sequence< sal_Int32 >& _rHandles,
529                             const ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Any >& _rOldValues,
530                             const ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Any >& _rNewValues,
531                             LockAccess
532                         );
533 
534     inline ::osl::Mutex&
535                         getInstanceMutex() { return m_aMutex; }
536 };
537 
538 //==================================================================
539 // simple destructor
540 #define DECLARE_DEFAULT_DTOR( classname )	\
541 	~classname() \
542 
543 // constructor for cloning a class
544 #define DECLARE_DEFAULT_CLONE_CTOR( classname )  \
545 	classname( \
546 		const classname* _pOriginal, \
547 		const	::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory>& _rxFactory \
548 	); \
549 
550 // all xtors for an inner class of the object hierarchy
551 #define DECLARE_DEFAULT_XTOR( classname )	\
552 	classname( \
553 		const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory>& _rxFactory, \
554 		const ::rtl::OUString& _rUnoControlModelTypeName, \
555 		const ::rtl::OUString& _rDefault \
556 	); \
557     DECLARE_DEFAULT_CLONE_CTOR( classname )  \
558     DECLARE_DEFAULT_DTOR( classname )   \
559 
560 // all xtors for an inner class of the object hierarchy which is *bound*
561 #define DECLARE_DEFAULT_BOUND_XTOR( classname )	\
562 	classname( \
563 		const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory>& _rxFactory, \
564 		const ::rtl::OUString& _rUnoControlModelTypeName, \
565 		const ::rtl::OUString& _rDefault, \
566         const sal_Bool _bSupportExternalBinding, \
567         const sal_Bool _bSupportsValidation \
568 	); \
569     DECLARE_DEFAULT_CLONE_CTOR( classname )  \
570     DECLARE_DEFAULT_DTOR( classname )   \
571 
572 // all xtors for a leas class of the object hierarchy
573 #define DECLARE_DEFAULT_LEAF_XTOR( classname )	\
574 	classname( \
575 		const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory>& _rxFactory \
576 	); \
577 	classname( \
578 		const classname* _pOriginal, \
579 		const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory>& _rxFactory \
580 	); \
581     DECLARE_DEFAULT_DTOR( classname )   \
582 
583 //==================================================================
584 // XCloneable
585 #define DECLARE_XCLONEABLE( ) \
586 	virtual ::com::sun::star::uno::Reference< ::com::sun::star::util::XCloneable > SAL_CALL createClone(  ) throw (::com::sun::star::uno::RuntimeException)
587 
588 #define IMPLEMENT_DEFAULT_CLONING( classname ) \
589 	::com::sun::star::uno::Reference< ::com::sun::star::util::XCloneable > SAL_CALL classname::createClone( ) throw (::com::sun::star::uno::RuntimeException) \
590 	{ \
591         classname* pClone = new classname( this, getContext().getLegacyServiceFactory() ); \
592         pClone->clonedFrom( this ); \
593         return pClone; \
594 	}
595 
596 //==================================================================
597 //= OBoundControlModel
598 //= model of a form layer control which is bound to a data source field
599 //==================================================================
600 typedef ::cppu::ImplHelper4 <	::com::sun::star::form::XLoadListener
601 						    ,   ::com::sun::star::form::XReset
602 							,	::com::sun::star::beans::XPropertyChangeListener
603 							,	::com::sun::star::sdb::XRowSetChangeListener
604                             >	OBoundControlModel_BASE1;
605 
606 // separated into an own base class since derivees can disable the support for this
607 // interface, thus we want to easily exclude it in the queryInterface and getTypes
608 typedef ::cppu::ImplHelper1 <   ::com::sun::star::form::XBoundComponent
609                             >   OBoundControlModel_COMMITTING;
610 
611 // dito
612 typedef ::cppu::ImplHelper2 <   ::com::sun::star::form::binding::XBindableValue
613                             ,   ::com::sun::star::util::XModifyListener
614                             >   OBoundControlModel_BINDING;
615 
616 // dito
617 typedef ::cppu::ImplHelper2 <   ::com::sun::star::form::validation::XValidityConstraintListener
618                             ,   ::com::sun::star::form::validation::XValidatableFormComponent
619                             >   OBoundControlModel_VALIDATION;
620 
621 class OBoundControlModel	:public OControlModel
622 							,public OBoundControlModel_BASE1
623 							,public OBoundControlModel_COMMITTING
624 							,public OBoundControlModel_BINDING
625                             ,public OBoundControlModel_VALIDATION
626                             ,public ::comphelper::OPropertyChangeListener
627 {
628 protected:
629     enum ValueChangeInstigator
630     {
631         eDbColumnBinding,
632         eExternalBinding,
633         eOther
634     };
635 
636 private:
637 	::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertySet >
638                                         m_xField;
639     // the form which controls supplies the field we bind to.
640     ::com::sun::star::uno::Reference< ::com::sun::star::form::XLoadable >
641                                         m_xAmbientForm;
642 
643 	::rtl::OUString					    m_sValuePropertyName;
644     sal_Int32                           m_nValuePropertyAggregateHandle;
645     sal_Int32                           m_nFieldType;
646     ::com::sun::star::uno::Type         m_aValuePropertyType;
647     bool                                m_bValuePropertyMayBeVoid;
648 
649     ResetHelper                         m_aResetHelper;
650     ::cppu::OInterfaceContainerHelper   m_aUpdateListeners;
651     ::cppu::OInterfaceContainerHelper   m_aFormComponentListeners;
652 
653     ::com::sun::star::uno::Reference< ::com::sun::star::form::binding::XValueBinding >
654                                         m_xExternalBinding;
655     ::com::sun::star::uno::Reference< ::com::sun::star::form::validation::XValidator >
656                                         m_xValidator;
657     ::com::sun::star::uno::Type         m_aExternalValueType;
658 
659 // <properties>
660 	::rtl::OUString						m_aControlSource;			// Datenquelle, Name des Feldes
661 	::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertySet >
662                                         m_xLabelControl;			// reference to a sibling control (model) which is our label
663     sal_Bool                            m_bInputRequired;
664 // </properties>
665 
666     ::comphelper::OPropertyChangeMultiplexer*
667                                 m_pAggPropMultiplexer;
668 
669     bool                        m_bFormListening            : 1;    // are we currently a XLoadListener at our ambient form?
670 	sal_Bool					m_bLoaded		            : 1;
671 	sal_Bool					m_bRequired		            : 1;
672 	const sal_Bool              m_bCommitable	            : 1;    // do we support XBoundComponent?
673     const sal_Bool              m_bSupportsExternalBinding  : 1;    // do we support XBindableValue?
674     const sal_Bool			    m_bSupportsValidation       : 1;    // do we support XValidatable?
675 	sal_Bool					m_bForwardValueChanges      : 1;    // do we currently handle changes in the bound database field?
676     sal_Bool			        m_bTransferingValue         : 1;    // true if we're currently transfering our value to an external binding
677     sal_Bool                    m_bIsCurrentValueValid      : 1;    // flag specifying whether our current value is valid, relative to our external validator
678     sal_Bool                    m_bBindingControlsRO        : 1;    // is our ReadOnly property currently controlled by our external binding?
679     sal_Bool                    m_bBindingControlsEnable    : 1;    // is our Enabled property currently controlled by our external binding?
680 
681     ValueChangeInstigator       m_eControlValueChangeInstigator;
682 
683 protected:
684 	::rtl::OUString					    m_aLabelServiceName;
685 		// when setting the label for our control (property FM_PROP_CONTROLLABEL, member m_xLabelControl),
686 		// we accept only objects supporting an XControlModel interface, an XServiceInfo interface and
687 		// support for a service (XServiceInfo::supportsService) determined by this string.
688 		// Any other arguments will throw an IllegalArgumentException.
689 		// The default value is FM_COMPONENT_FIXEDTEXT.
690 
691     ::com::sun::star::uno::Reference< ::com::sun::star::sdbc::XRowSet >
692                                         m_xCursor;
693 	::com::sun::star::uno::Reference< ::com::sun::star::sdb::XColumnUpdate >
694                                         m_xColumnUpdate;
695 	::com::sun::star::uno::Reference< ::com::sun::star::sdb::XColumn >
696                                         m_xColumn;
697 
698 protected:
699     inline const ::rtl::OUString&   getValuePropertyName( ) const       { return m_sValuePropertyName; }
700     inline sal_Int32                getValuePropertyAggHandle( ) const  { return m_nValuePropertyAggregateHandle; }
701     inline const ::rtl::OUString&   getControlSource( ) const           { return m_aControlSource; }
702     inline sal_Bool                 isRequired() const                  { return m_bRequired; }
703     inline sal_Bool                 isLoaded() const                    { return m_bLoaded; }
704 
705 protected:
706 
707 	OBoundControlModel(
708 		const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory>& _rFactory,
709                                                             // factory to create the aggregate with
710 		const ::rtl::OUString& _rUnoControlModelTypeName,	// service name of te model to aggregate
711 		const ::rtl::OUString& _rDefault,					// service name of the default control
712 		const sal_Bool _bCommitable,						// is the control (model) commitable ?
713         const sal_Bool _bSupportExternalBinding,            // set to sal_True if you want to support XBindableValue
714         const sal_Bool _bSupportsValidation                 // set to sal_True if you want to support XValidatable
715 	);
716 	OBoundControlModel(
717 		const OBoundControlModel* _pOriginal,				// the original object to clone
718 		const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory>& _rFactory
719                                                             // factory to create the aggregate with
720 	);
721 	virtual ~OBoundControlModel();
722 
723     /// late ctor after cloning
724     virtual void clonedFrom( const OControlModel* _pOriginal );
725 
726     /** initializes the part of the class which is related to the control value.
727 
728         <p>Kind of late ctor, to be called for derivees which have a dedicated value property.<br/>
729         The value property is the property which's value is synced with either the database
730         column the object is bound to, or with the external value binding, if present.<br/>
731         E.g. for a text control model, this property will most probably be "Text".</p>
732 
733         <p>Derived classes are stronly recommend to call this method - at least the
734         "DataFieldProperty" (exposed in getFastPropertyValue) relies on the information
735         given herein, and needs to be supplied otherwise else.</p>
736 
737         <p>If this method has been called properly, then <member>setControlValue</member>
738         does not need to be overridden - it will simply set the property value at the
739         aggregate then.</p>
740 
741         @precond
742             The method has not be called before during the life time of the object.
743 
744         @param _rValuePropertyName
745             the name of the value property
746         @param _nValuePropertyExternalHandle
747             the handle of the property, as exposed to external components.<br/>
748             Normally, this information can be obtained dynamically (e.g. from describeFixedProperties),
749             but since this method is to be called from within the constructor of derived classes,
750             we prefer to be on the *really* safe side here ....
751 
752         @see setControlValue
753         @see suspendValueListening
754         @see resumeValueListening
755         @see describeFixedProperties
756     */
757     void                    initValueProperty(
758                                 const ::rtl::OUString& _rValuePropertyName,
759                                 sal_Int32 _nValuePropertyExternalHandle
760                             );
761 
762     /** initializes the part of the class which is related to the control value.
763 
764         <p>In opposite to ->initValueProperty, this method is to be used for value properties which are <em>not</em>
765         implemented by our aggregate, but by ourselves.</p>
766 
767         <p>Certain functionality is not available when using own value properties. This includes binding to an external
768         value and external validation. (This is not a conceptual limit, but simply missing implementation.)</p>
769     */
770     void                    initOwnValueProperty(
771                                 const ::rtl::OUString& i_rValuePropertyName
772                             );
773 
774     /** suspends listening at the value property
775 
776         <p>As long as this listening is suspended, changes in the value property will not be
777         recognized and not be handled.</p>
778 
779         @see initValueProperty
780         @see resumeValueListening
781     */
782     void                    suspendValueListening( );
783 
784     /** resumes listening at the value property
785 
786         <p>As long as this listening is suspended, changes in the value property will not be
787         recognized and not be handled.</p>
788 
789         @precond
790             listening at the value property is currently suspended
791 
792         @see initValueProperty
793         @see resumeValueListening
794     */
795     void                    resumeValueListening( );
796 
797     /** (to be) called when the value property changed
798 
799         Normally, this is done automatically, since the value property is a property of our aggregate, and we're
800         a listener at this property.
801         However, in some cases the value property might not be an aggregate property, but a property of the
802         delegator instance. In this case, you'll need to call <code>onValuePropertyChange</code> whenever this
803         property changes.
804     */
805     void                    onValuePropertyChange( ControlModelLock& i_rControLock );
806 
807     /** starts listening at the aggregate, for changes in the given property
808 
809         <p>The OBoundControlModel automatically registers a multiplexer which listens for
810         changes in the aggregate property values. By default, only the control value property
811         is observed. You may add additional properties to be observed with this method.</p>
812 
813         @see initValueProperty
814         @see _propertyChanged
815     */
816     void                    startAggregatePropertyListening( const ::rtl::OUString& _rPropertyName );
817 
818     /** returns the default which should be used when resetting the control
819 
820         <p>The default implementation returns an empty Any.</p>
821 
822         @see resetNoBroadcast
823     */
824     virtual ::com::sun::star::uno::Any
825                             getDefaultForReset() const;
826 
827     /** translates a db column value into a control value.
828 
829         <p>Must transform the very current value of the database column we're bound to
830         (<member>m_xColumn</member>) into a value which can be used as current value
831         for the control.</p>
832 
833         @see setControlValue
834         @pure
835     */
836     virtual ::com::sun::star::uno::Any
837                             translateDbColumnToControlValue( ) = 0;
838 
839     /** returns the data types which the control could use to exchange data with
840         an external value binding
841 
842         The types returned here are completely independent from the concrete value binding,
843         they're just candidates which depend on the control type, and possible the concrete state
844         of the control (i.e. some property value).
845 
846         If a control implementation supports multiple types, the ordering in the returned
847         sequence indicates preference: Preferred types are mentioned first.
848 
849         The default implementation returns the type of our value property.
850     */
851     virtual ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Type >
852                             getSupportedBindingTypes();
853 
854     /** translates the given value, which was obtained from the current external value binding,
855         to a value which can be used in setControlValue
856 
857         <p>The default implementation returns the value itself, exception when it is VOID, and
858         our value property is not allowed to be void - in this case, the returned value is a
859         default-constructed value of the type required by our value property.
860 
861         @see hasExternalValueBinding
862         @see getExternalValueType
863     */
864     virtual ::com::sun::star::uno::Any
865                             translateExternalValueToControlValue( const ::com::sun::star::uno::Any& _rExternalValue ) const;
866 
867     /** commits the current control value to our external value binding
868 
869         <p>The default implementation simply calls getControlValue.</p>
870 
871         @see hasExternalValueBinding
872         @see initValueProperty
873     */
874     virtual ::com::sun::star::uno::Any
875                             translateControlValueToExternalValue( ) const;
876 
877     /** commits the current control value to the database column we're bound to
878         @precond
879             we're properly bound to a database column, especially <member>m_xColumnUpdate</member>
880             is not <NULL/>
881         @param _bPostReset
882             <TRUE/> if and only if the current control value results from a reset (<member>getDefaultForReset</member>)
883         @pure
884     */
885     virtual sal_Bool        commitControlValueToDbColumn(
886                                 bool _bPostReset
887                             ) = 0;
888 
889     /** sets the given value as new current value for the control
890 
891         Besides some administrative work (such as caring for <member>m_eControlValueChangeInstigator</member>),
892         this method simply calls <member>doSetControlValue</member>.
893 
894         @precond
895             Our own mutex is locked.
896         @param _rValue
897             The value to set. This value is guaranteed to be created by
898             <member>translateDbColumnToControlValue</member> or
899             <member>translateExternalValueToControlValue</member>
900         @param _eInstigator
901             the instigator of the value change
902     */
903             void            setControlValue(
904                                 const ::com::sun::star::uno::Any& _rValue,
905                                 ValueChangeInstigator _eInstigator
906                             );
907     /**
908         <p>The default implementation will forward the given value to the aggregate, using
909         m_nValuePropertyAggregateHandle and/or m_sValuePropertyName.</p>
910 
911         @precond
912             Our own mutex is locked.
913         @param _rValue
914             The value to set. This value is guaranteed to be created by
915             <member>translateDbColumnToControlValue</member> or
916             <member>translateExternalValueToControlValue</member>
917     */
918     virtual void            doSetControlValue(
919                                 const ::com::sun::star::uno::Any& _rValue
920                             );
921 
922     /** retrieves the current value of the control
923 
924         <p>The default implementation will ask the aggregate for the property value
925         determined by either m_nValuePropertyAggregateHandle and/or m_sValuePropertyName.</p>
926 
927         @precond
928             Our own mutex is locked.
929     */
930     virtual ::com::sun::star::uno::Any
931                             getControlValue( ) const;
932 
933     /** called whenever a connection to a database column has been established
934     */
935 	virtual void            onConnectedDbColumn( const ::com::sun::star::uno::Reference< ::com::sun::star::uno::XInterface >& _rxForm );
936     /** called whenever a connection to a database column has been suspended
937     */
938 	virtual void            onDisconnectedDbColumn();
939 
940     /** called whenever a connection to an external supplier of values (XValueBinding) has been established
941         @see m_xExternalBinding
942     */
943 	virtual void            onConnectedExternalValue( );
944     /** called whenever a connection to an external supplier of values (XValueBinding) has been suspended
945     */
946 	virtual void            onDisconnectedExternalValue();
947 
948     /** called whenever an external validator has been registered
949     */
950 	virtual void            onConnectedValidator( );
951     /** called whenever an external validator has been revoked
952     */
953 	virtual void            onDisconnectedValidator( );
954 
955 	/**	nFieldType ist der Typ des Feldes, an das das Model gebunden werden soll.
956 		Das Binden erfolgt genau dann, wenn Rueckgabewert sal_True.
957 		Die Standard-Implementation erlaubt alles ausser den drei binary-Typen und
958 		FieldType_OTHER.
959 	*/
960 	virtual sal_Bool		approveDbColumnType(sal_Int32 _nColumnType);
961 
962     /** retrieves the current value of the control, in a shape which can be used with our
963         external validator.
964 
965         The default implementation simply calls <member>>translateControlValueToExternalValue</member>.
966 
967         @precond
968             Our own mutex is locked.
969     */
970     virtual ::com::sun::star::uno::Any
971                             translateControlValueToValidatableValue( ) const;
972 
973     /** retrieves the current value of the form component
974 
975         This is the implementation method for XValidatableFormComponent::getCurrentValue. The default implementation
976         calls translateControlValueToValidatableValue if a validator is present, otherwise getControlValue.
977 
978         @precond
979             our mutex is locked when this method is called
980     */
981     virtual ::com::sun::star::uno::Any
982                             getCurrentFormComponentValue() const;
983 
984 	/** We can't write (new) common properties in this base class, as the file format doesn't allow this
985 	    (unfortunally). So derived classes may use the following to methods. They secure the written
986 	    data with marks, so any new common properties in newer versions will be skipped by older ones.
987     */
988 	void	writeCommonProperties(const ::com::sun::star::uno::Reference< ::com::sun::star::io::XObjectOutputStream>& _rxOutStream);
989 	void	readCommonProperties(const ::com::sun::star::uno::Reference< ::com::sun::star::io::XObjectInputStream>& _rxInStream);
990 	// the next method may be used in derived classes's read when an unknown version is encountered
991 	void	defaultCommonProperties();
992 
993     /** called to reset the control to some kind of default.
994 
995         <p>The semantics of "default" is finally defined by the derived class (in particular,
996         by <member>getDefaultForReset</member>).</p>
997 
998         <p>No listener notification needs to be done in the derived class.</p>
999 
1000         <p>Normally, you won't override this method, but <member>getDefaultForReset</member> instead.</p>
1001 
1002         @see getDefaultForReset
1003     */
1004 	virtual void            resetNoBroadcast();
1005 
1006     virtual ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Type>	_getTypes();
1007 
1008     /// sets m_xField to the given new value, without notifying our listeners
1009 	void    impl_setField_noNotify(
1010                 const ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertySet>& _rxField
1011             );
1012     inline bool hasField() const
1013     {
1014         return m_xField.is();
1015     }
1016     inline sal_Int32 getFieldType() const
1017     {
1018         return m_nFieldType;
1019     }
1020 
1021     // OControlModel's property handling
1022 	virtual void describeFixedProperties(
1023 		::com::sun::star::uno::Sequence< ::com::sun::star::beans::Property >& /* [out] */ _rProps
1024     ) const;
1025 
1026 public:
1027 	inline const ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertySet>& getField() const
1028 	{
1029 		return m_xField;
1030 	}
1031 
1032 public:
1033 	// UNO Anbindung
1034 	DECLARE_UNO3_AGG_DEFAULTS(OBoundControlModel, OControlModel);
1035 	virtual ::com::sun::star::uno::Any SAL_CALL queryAggregation( const ::com::sun::star::uno::Type& _rType ) throw (::com::sun::star::uno::RuntimeException);
1036 
1037     // OComponentHelper
1038 	virtual void SAL_CALL disposing();
1039 
1040     // XReset
1041     virtual void SAL_CALL reset(  ) throw(::com::sun::star::uno::RuntimeException);
1042     virtual void SAL_CALL addResetListener( const ::com::sun::star::uno::Reference< ::com::sun::star::form::XResetListener >& aListener ) throw(::com::sun::star::uno::RuntimeException);
1043     virtual void SAL_CALL removeResetListener( const ::com::sun::star::uno::Reference< ::com::sun::star::form::XResetListener >& aListener ) throw(::com::sun::star::uno::RuntimeException);
1044 
1045     // XServiceInfo
1046     virtual StringSequence SAL_CALL getSupportedServiceNames(  ) throw(::com::sun::star::uno::RuntimeException);
1047 
1048     // XServiceInfo - static version
1049 	static  StringSequence SAL_CALL	getSupportedServiceNames_Static() throw(::com::sun::star::uno::RuntimeException);
1050 
1051     // XChild
1052     virtual void SAL_CALL setParent( const ::com::sun::star::uno::Reference< ::com::sun::star::uno::XInterface >& Parent ) throw(::com::sun::star::lang::NoSupportException, ::com::sun::star::uno::RuntimeException);
1053 
1054     // XPersistObject
1055     virtual void SAL_CALL write( const ::com::sun::star::uno::Reference< ::com::sun::star::io::XObjectOutputStream >& OutStream ) throw(::com::sun::star::io::IOException, ::com::sun::star::uno::RuntimeException);
1056     virtual void SAL_CALL read( const ::com::sun::star::uno::Reference< ::com::sun::star::io::XObjectInputStream >& InStream ) throw(::com::sun::star::io::IOException, ::com::sun::star::uno::RuntimeException);
1057 
1058     // XBoundComponent
1059     virtual sal_Bool SAL_CALL commit() throw(::com::sun::star::uno::RuntimeException);
1060 
1061     // XUpdateBroadcaster (base of XBoundComponent)
1062     virtual void SAL_CALL addUpdateListener( const ::com::sun::star::uno::Reference< ::com::sun::star::form::XUpdateListener >& aListener ) throw(::com::sun::star::uno::RuntimeException);
1063     virtual void SAL_CALL removeUpdateListener( const ::com::sun::star::uno::Reference< ::com::sun::star::form::XUpdateListener >& aListener ) throw(::com::sun::star::uno::RuntimeException);
1064 
1065     // XPropertySet
1066 	virtual void SAL_CALL getFastPropertyValue(::com::sun::star::uno::Any& rValue, sal_Int32 nHandle) const;
1067 	virtual sal_Bool SAL_CALL convertFastPropertyValue(
1068 				::com::sun::star::uno::Any& _rConvertedValue, ::com::sun::star::uno::Any& _rOldValue, sal_Int32 _nHandle, const ::com::sun::star::uno::Any& _rValue )
1069 				throw (::com::sun::star::lang::IllegalArgumentException);
1070 	virtual void SAL_CALL setFastPropertyValue_NoBroadcast( sal_Int32 nHandle, const ::com::sun::star::uno::Any& rValue )
1071 				throw (::com::sun::star::uno::Exception);
1072     using ::cppu::OPropertySetHelper::getFastPropertyValue;
1073 
1074 // ::com::sun::star::beans::XPropertyState
1075 	virtual ::com::sun::star::uno::Any getPropertyDefaultByHandle( sal_Int32 nHandle ) const;
1076 
1077 // XEventListener
1078 	virtual void SAL_CALL disposing(const ::com::sun::star::lang::EventObject& Source) throw (::com::sun::star::uno::RuntimeException);
1079 
1080 // XPropertyChangeListener
1081     virtual void SAL_CALL propertyChange( const ::com::sun::star::beans::PropertyChangeEvent& evt ) throw(::com::sun::star::uno::RuntimeException);
1082 
1083     // XRowSetChangeListener
1084     virtual void SAL_CALL onRowSetChanged( const ::com::sun::star::lang::EventObject& i_Event ) throw (::com::sun::star::uno::RuntimeException);
1085 
1086 // XLoadListener
1087     virtual void SAL_CALL loaded( const ::com::sun::star::lang::EventObject& aEvent ) throw(::com::sun::star::uno::RuntimeException);
1088     virtual void SAL_CALL unloading( const ::com::sun::star::lang::EventObject& aEvent ) throw(::com::sun::star::uno::RuntimeException);
1089     virtual void SAL_CALL unloaded( const ::com::sun::star::lang::EventObject& aEvent ) throw(::com::sun::star::uno::RuntimeException);
1090     virtual void SAL_CALL reloading( const ::com::sun::star::lang::EventObject& aEvent ) throw(::com::sun::star::uno::RuntimeException);
1091     virtual void SAL_CALL reloaded( const ::com::sun::star::lang::EventObject& aEvent ) throw(::com::sun::star::uno::RuntimeException);
1092 
1093 private:
1094     // XBindableValue
1095     virtual void SAL_CALL setValueBinding( const ::com::sun::star::uno::Reference< ::com::sun::star::form::binding::XValueBinding >& _rxBinding ) throw (::com::sun::star::form::binding::IncompatibleTypesException, ::com::sun::star::uno::RuntimeException);
1096     virtual ::com::sun::star::uno::Reference< ::com::sun::star::form::binding::XValueBinding > SAL_CALL getValueBinding(  ) throw (::com::sun::star::uno::RuntimeException);
1097 
1098     // XModifyListener
1099     virtual void SAL_CALL modified( const ::com::sun::star::lang::EventObject& _rEvent ) throw (::com::sun::star::uno::RuntimeException);
1100 
1101     // XValidatable
1102     virtual void SAL_CALL setValidator( const ::com::sun::star::uno::Reference< ::com::sun::star::form::validation::XValidator >& Validator ) throw (::com::sun::star::util::VetoException, ::com::sun::star::uno::RuntimeException);
1103     virtual ::com::sun::star::uno::Reference< ::com::sun::star::form::validation::XValidator > SAL_CALL getValidator(  ) throw (::com::sun::star::uno::RuntimeException);
1104 
1105     // XValidityConstraintListener
1106     virtual void SAL_CALL validityConstraintChanged( const ::com::sun::star::lang::EventObject& Source ) throw (::com::sun::star::uno::RuntimeException);
1107 
1108     // XValidatableFormComponent
1109     virtual sal_Bool SAL_CALL isValid(  ) throw (::com::sun::star::uno::RuntimeException);
1110     virtual ::com::sun::star::uno::Any SAL_CALL getCurrentValue(  ) throw (::com::sun::star::uno::RuntimeException);
1111     virtual void SAL_CALL addFormComponentValidityListener( const ::com::sun::star::uno::Reference< ::com::sun::star::form::validation::XFormComponentValidityListener >& Listener ) throw (::com::sun::star::lang::NullPointerException, ::com::sun::star::uno::RuntimeException);
1112     virtual void SAL_CALL removeFormComponentValidityListener( const ::com::sun::star::uno::Reference< ::com::sun::star::form::validation::XFormComponentValidityListener >& Listener ) throw (::com::sun::star::lang::NullPointerException, ::com::sun::star::uno::RuntimeException);
1113 
1114 protected:
1115     // OPropertyChangeListener
1116 	virtual void
1117                 _propertyChanged( const ::com::sun::star::beans::PropertyChangeEvent& _rEvt ) throw ( ::com::sun::star::uno::RuntimeException );
1118 
1119     /// checks whether we currently have an external value binding in place
1120     inline  bool    hasExternalValueBinding() const { return m_xExternalBinding.is(); }
1121 
1122     // checks whether we currently have an external validator
1123     inline  bool    hasValidator() const { return m_xValidator.is(); }
1124 
1125     /** transfers the very current value of the db column we're bound to the control
1126         @precond
1127             our own mutex is locked
1128         @precond
1129             we don't have an external binding in place
1130     */
1131     void        transferDbValueToControl( );
1132 
1133     /** transfers the current value of the active external binding to the control
1134         @precond
1135             we do have an active external binding in place
1136     */
1137     void        transferExternalValueToControl( ControlModelLock& _rInstanceLock );
1138 
1139     /** transfers the control value to the external binding
1140         @precond
1141             our own mutex is locked, and _rInstanceLock is the guard locking it
1142         @precond
1143             we do have an active external binding in place
1144     */
1145     void        transferControlValueToExternal( ControlModelLock& _rInstanceLock );
1146 
1147     /** calculates the type which is to be used to communicate with the current external binding,
1148         and stores it in m_aExternalValueType
1149 
1150         The method checks the possible type candidates as returned by getSupportedBindingTypes,
1151         and the types supported by the current external binding, if any.
1152     */
1153     void        calculateExternalValueType();
1154 
1155     /** returns the type which should be used to exchange data with our external value binding
1156 
1157         @see initValueProperty
1158     */
1159     const ::com::sun::star::uno::Type&
1160                 getExternalValueType() const { return m_aExternalValueType; }
1161 
1162     /** initializes the control from m_xField
1163 
1164         Basically, this method calls transferDbValueToControl - but only if our cursor is positioned
1165         on a valid row. Otherwise, the control is reset.
1166 
1167         @precond
1168             m_xField is not <NULL/>
1169     */
1170     void        initFromField( const ::com::sun::star::uno::Reference< ::com::sun::star::sdbc::XRowSet>& _rxForm );
1171 
1172 private:
1173 	sal_Bool    connectToField( const ::com::sun::star::uno::Reference< ::com::sun::star::sdbc::XRowSet>& _rxForm );
1174 	void        resetField();
1175 
1176     /** does a new validation of the control value
1177 
1178         If necessary, our <member>m_bIsCurrentValueValid</member> member will be adjusted,
1179         and changes will be notified.
1180 
1181         Note that it's not necessary that we're connected to a validator. If we are not,
1182         it's assumed that our value is valid, and this is handled appropriately.
1183 
1184         Use this method if there is a potential that <b>only</b> the validity flag changed. If
1185         any of the other aspects (our current value, or our current text) changed, then
1186         pass <TRUE/> for <member>_bForceNotification</member>.
1187 
1188         @param _bForceNotification
1189             if <TRUE/>, then the validity listeners will be notified, not matter whether the validity
1190             changed.
1191     */
1192     void        recheckValidity( bool _bForceNotification );
1193 
1194     /// initializes m_pAggPropMultiplexer
1195     void        implInitAggMultiplexer( );
1196 
1197     /// initializes listening at the value property
1198     void        implInitValuePropertyListening( ) const;
1199 
1200     /** adds or removes the component as load listener to/from our form, and (if necessary) as RowSetChange listener at
1201         our parent.
1202 
1203         @precond there must no external value binding be in place
1204     */
1205     void        doFormListening( const bool _bStart );
1206 
1207     inline bool isFormListening() const { return m_bFormListening; }
1208 
1209     /** determines the new value of m_xAmbientForm
1210     */
1211     void        impl_determineAmbientForm_nothrow();
1212 
1213     /** connects to a value supplier which is an database column.
1214 
1215         The column is take from our parent, which must be a database form respectively row set.
1216 
1217         @precond The control does not have an external value supplier
1218 
1219         @param _bFromReload
1220             Determines whether the connection is made after the row set has been loaded (<FALSE/>)
1221             or reloaded (<TRUE/>)
1222 
1223         @see impl_disconnectDatabaseColumn_noNotify
1224     */
1225     void        impl_connectDatabaseColumn_noNotify(
1226                     bool  _bFromReload
1227                 );
1228 
1229     /** disconnects from a value supplier which is an database column
1230 
1231         @precond The control does not have an external value supplier
1232         @see impl_connectDatabaseColumn_noNotify
1233     */
1234     void        impl_disconnectDatabaseColumn_noNotify();
1235 
1236     /** connects to an external value binding
1237 
1238         <p>Note that by definition, external data bindings superseede the SQL data binding which
1239         is defined by our RowSet-column-related properties. This means that in case we're currently
1240         connected to a database column when this is called, this connection is suspended.</p>
1241 
1242         @precond
1243                 the new external binding has already been approved (see <member>impl_approveValueBinding_nolock</member>)
1244         @precond
1245                 there currently is no external binding in place
1246     */
1247     void        connectExternalValueBinding(
1248                     const ::com::sun::star::uno::Reference< ::com::sun::star::form::binding::XValueBinding >& _rxBinding,
1249                     ControlModelLock& _rInstanceLock
1250                 );
1251 
1252     /** disconnects from an external value binding
1253 
1254         @precond
1255                 there currently is an external binding in place
1256     */
1257     void        disconnectExternalValueBinding( );
1258 
1259     /** connects the component to an external validator
1260 
1261         @precond
1262             there currently is no active validator
1263         @precond
1264             our mutex is currently locked exactly once
1265     */
1266     void        connectValidator(
1267                     const ::com::sun::star::uno::Reference< ::com::sun::star::form::validation::XValidator >& _rxValidator
1268                 );
1269 
1270     /** disconnects the component from it's current an external validator
1271 
1272         @precond
1273             there currently is an active validator
1274         @precond
1275             our mutex is currently locked exactly once
1276     */
1277     void        disconnectValidator( );
1278 
1279     /** called from within <member scope="com::sun::star:::form::binding">XBindableValue::setValueBinding</member>
1280         to approve the new binding
1281 
1282         The default implementation approves the binding if and only if it is not <NULL/>, and supports
1283         the type returned by getExternalValueType.
1284 
1285         @param _rxBinding
1286             the binding which applies for being responsible for our value, Must not be
1287             <NULL/>
1288         @return
1289             <TRUE/> if and only if the given binding can supply values in the proper type
1290 
1291         @seealso getExternalValueType
1292     */
1293     sal_Bool    impl_approveValueBinding_nolock(
1294                     const ::com::sun::star::uno::Reference< ::com::sun::star::form::binding::XValueBinding >& _rxBinding
1295                 );
1296 };
1297 
1298     //=========================================================================
1299     //= inlines
1300     //=========================================================================
1301     inline void ControlModelLock::acquire()
1302     {
1303         m_rModel.lockInstance( OControlModel::LockAccess() );
1304         m_bLocked = true;
1305     }
1306     inline void ControlModelLock::release()
1307     {
1308         OSL_ENSURE( m_bLocked, "ControlModelLock::release: not locked!" );
1309         m_bLocked = false;
1310 
1311         if ( 0 == m_rModel.unlockInstance( OControlModel::LockAccess() ) )
1312             impl_notifyAll_nothrow();
1313     }
1314 
1315 //.........................................................................
1316 }
1317 //.........................................................................
1318 
1319 #endif // _FORMS_FORMCOMPONENT_HXX_
1320 
1321