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