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:
ControlModelLock(OControlModel & _rModel)120         ControlModelLock( OControlModel& _rModel )
121             :m_rModel( _rModel )
122             ,m_bLocked( false )
123         {
124             acquire();
125         }
126 
~ControlModelLock()127         ~ControlModelLock()
128         {
129             if ( m_bLocked )
130                 release();
131         }
132         inline void acquire();
133         inline void release();
134 
getModel() const135         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)
dispose()245     virtual void SAL_CALL dispose(  ) throw(::com::sun::star::uno::RuntimeException)
246 		{ OComponentHelper::dispose(); }
addEventListener(const::com::sun::star::uno::Reference<::com::sun::star::lang::XEventListener> & _rxListener)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); }
removeEventListener(const::com::sun::star::uno::Reference<::com::sun::star::lang::XEventListener> & _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 //added for exporting OCX control
339 #define INVALID_OBJ_ID_IN_MSO     0xFFFF
340 
341 typedef ::cppu::ImplHelper7	<	::com::sun::star::form::XFormComponent
342 							,	::com::sun::star::io::XPersistObject
343 							,	::com::sun::star::container::XNamed
344 							,	::com::sun::star::lang::XServiceInfo
345 							,	::com::sun::star::util::XCloneable
346 							,	::com::sun::star::beans::XPropertyContainer
347 							,	::com::sun::star::beans::XPropertyAccess
348 							>	OControlModel_BASE;
349 
350 class OControlModel	:public ::cppu::OComponentHelper
351 					,public OPropertySetAggregationHelper
352 					,public OControlModel_BASE
353 					,public OCloneableAggregation
354                     ,public IPropertyBagHelperContext
355 {
356 
357 protected:
358     ::comphelper::ComponentContext  m_aContext;
359 
360     ::osl::Mutex                    m_aMutex;
361     oslInterlockedCount             m_lockCount;
362 
363 	InterfaceRef					m_xParent;					// ParentComponent
364 	OImplementationIdsRef			m_aHoldIdHelper;
365     PropertyBagHelper               m_aPropertyBagHelper;
366 
367     const ::comphelper::ComponentContext&
getContext() const368         getContext() const { return m_aContext; }
369 
370 // <properties>
371 	::rtl::OUString					m_aName;					// name of the control
372 	::rtl::OUString					m_aTag;						// tag for additional data
373 	sal_Int16						m_nTabIndex;				// index within the taborder
374 	sal_Int16						m_nClassId;					// type of the control
375     sal_Bool                        m_bNativeLook;              // should the control use the native platform look?
376     //added for exporting OCX control
377     sal_Int16						m_nControlTypeinMSO;		//keep the MS office control type for exporting to MS binarary file
378     sal_uInt16						m_nObjIDinMSO;				//keep the OCX control obj id for exporting to MS binarary file
379 // </properties>
380 
381 
382 protected:
383 	OControlModel(
384 		const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory>& _rFactory,	// factory to create the aggregate with
385 		const ::rtl::OUString& _rUnoControlModelTypeName,						// service name of te model to aggregate
386 		const ::rtl::OUString& rDefault = ::rtl::OUString(),					// service name of the default control
387 		const sal_Bool _bSetDelegator = sal_True								// set to sal_False if you want to call setDelegator later (after returning from this ctor)
388 	);
389 	OControlModel(
390 		const OControlModel* _pOriginal,										// the original object to clone
391 		const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory>& _rFactory,	// factory to create the aggregate with
392         const sal_Bool _bCloneAggregate = sal_True,                             // should the aggregate of the original be cloned, too?
393 		const sal_Bool _bSetDelegator = sal_True								// set to sal_False if you want to call setDelegator later (after returning from this ctor)
394 	);
395 	virtual ~OControlModel();
396 
397     /** to be called after a OBoundControlModel (a derivee, respectively) has been cloned
398 
399         <p>This method contains late initializations which cannot be done in the
400         constructor of this base class, since the virtual method of derived classes do
401         not yet work there.</p>
402     */
403     virtual void clonedFrom( const OControlModel* _pOriginal );
404 
405 	using OComponentHelper::rBHelper;
406 
407 	virtual ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Type>	_getTypes();
408 
409 	void	readHelpTextCompatibly(const ::com::sun::star::uno::Reference< ::com::sun::star::io::XObjectInputStream >& _rxInStream);
410 	void	writeHelpTextCompatibly(const ::com::sun::star::uno::Reference< ::com::sun::star::io::XObjectOutputStream >& _rxOutStream);
411 
412 	void	doSetDelegator();
413 	void	doResetDelegator();
414 
415 	::com::sun::star::uno::Sequence< ::rtl::OUString > getAggregateServiceNames();
416 
417 public:
418 	DECLARE_UNO3_AGG_DEFAULTS(OControl, OComponentHelper);
419 	virtual ::com::sun::star::uno::Any SAL_CALL queryAggregation( const ::com::sun::star::uno::Type& _rType ) throw (::com::sun::star::uno::RuntimeException);
420 
421 // XTypeProvider
422 	virtual ::com::sun::star::uno::Sequence<sal_Int8>			SAL_CALL getImplementationId() throw(::com::sun::star::uno::RuntimeException);
423     virtual ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Type>	SAL_CALL getTypes() throw(::com::sun::star::uno::RuntimeException);
424 
425 // OComponentHelper
426 	virtual void SAL_CALL disposing();
427 
428 // XNamed
429 	virtual ::rtl::OUString SAL_CALL	getName() throw(::com::sun::star::uno::RuntimeException);
430 	virtual void SAL_CALL				setName(const ::rtl::OUString& aName) throw(::com::sun::star::uno::RuntimeException);
431 
432 // XServiceInfo
433 	virtual sal_Bool SAL_CALL			supportsService(const ::rtl::OUString& ServiceName) throw (::com::sun::star::uno::RuntimeException);
434 	virtual StringSequence SAL_CALL		getSupportedServiceNames() throw(::com::sun::star::uno::RuntimeException);
435     virtual ::rtl::OUString SAL_CALL	getImplementationName() throw(::com::sun::star::uno::RuntimeException) = 0;
436 
437 // XSericeInfo - static version(s)
438 	static  StringSequence SAL_CALL		getSupportedServiceNames_Static() throw(::com::sun::star::uno::RuntimeException);
439 
440 // XPersistObject
441     virtual ::rtl::OUString SAL_CALL	getServiceName() throw(::com::sun::star::uno::RuntimeException) = 0;
442     virtual void SAL_CALL
443 		write(const ::com::sun::star::uno::Reference< ::com::sun::star::io::XObjectOutputStream>& _rxOutStream) throw(::com::sun::star::io::IOException, ::com::sun::star::uno::RuntimeException);
444     virtual void SAL_CALL
445 		read(const ::com::sun::star::uno::Reference< ::com::sun::star::io::XObjectInputStream>& _rxInStream) throw(::com::sun::star::io::IOException, ::com::sun::star::uno::RuntimeException);
446 
447 // XChild (base of XFormComponent)
448     virtual InterfaceRef SAL_CALL	getParent() throw(::com::sun::star::uno::RuntimeException);
449     virtual void SAL_CALL			setParent(const InterfaceRef& Parent) throw(::com::sun::star::lang::NoSupportException, ::com::sun::star::uno::RuntimeException);
450 
451 // XEventListener
452 	virtual void SAL_CALL disposing(const ::com::sun::star::lang::EventObject& Source) throw (::com::sun::star::uno::RuntimeException);
453 
454 // XPropertySet
455 	virtual void SAL_CALL getFastPropertyValue(::com::sun::star::uno::Any& rValue, sal_Int32 nHandle) const;
456 	virtual sal_Bool SAL_CALL convertFastPropertyValue(
457 				::com::sun::star::uno::Any& _rConvertedValue, ::com::sun::star::uno::Any& _rOldValue, sal_Int32 _nHandle, const ::com::sun::star::uno::Any& _rValue )
458 				throw (::com::sun::star::lang::IllegalArgumentException);
459 	virtual void SAL_CALL setFastPropertyValue_NoBroadcast( sal_Int32 nHandle, const ::com::sun::star::uno::Any& rValue )
460 				throw (::com::sun::star::uno::Exception);
461     using ::cppu::OPropertySetHelper::getFastPropertyValue;
462 
463 // ::com::sun::star::beans::XPropertyState
464 	virtual	::com::sun::star::beans::PropertyState getPropertyStateByHandle(sal_Int32 nHandle);
465 	virtual	void setPropertyToDefaultByHandle(sal_Int32 nHandle);
466 	virtual ::com::sun::star::uno::Any getPropertyDefaultByHandle( sal_Int32 nHandle ) const;
467 
468 // XCloneable
469 	virtual ::com::sun::star::uno::Reference< ::com::sun::star::util::XCloneable > SAL_CALL createClone(  ) throw (::com::sun::star::uno::RuntimeException) = 0;
470 
471 // XPropertyContainer
472     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);
473     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);
474 
475 // XPropertyAccess
476     virtual ::com::sun::star::uno::Sequence< ::com::sun::star::beans::PropertyValue > SAL_CALL getPropertyValues(  ) throw (::com::sun::star::uno::RuntimeException);
477     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);
478 
479 protected:
480     using OPropertySetAggregationHelper::setPropertyValues;
481     using OPropertySetAggregationHelper::getPropertyValues;
482 
483 protected:
484     virtual void writeAggregate( const ::com::sun::star::uno::Reference< ::com::sun::star::io::XObjectOutputStream >& _rxOutStream ) const;
485     virtual void readAggregate( const ::com::sun::star::uno::Reference< ::com::sun::star::io::XObjectInputStream >& _rxInStream );
486 
487 protected:
488 	// XPropertySet
489 	virtual ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertySetInfo> SAL_CALL getPropertySetInfo() throw( ::com::sun::star::uno::RuntimeException);
490     // OPropertySetHelper
491 	virtual cppu::IPropertyArrayHelper& SAL_CALL getInfoHelper();
492 
493     /** describes the properties provided by this class, or its respective
494         derived class
495 
496         Derived classes usually call the base class first, and then append own properties.
497     */
498 	virtual void describeFixedProperties(
499 		::com::sun::star::uno::Sequence< ::com::sun::star::beans::Property >& /* [out] */ _rProps
500     ) const;
501 
502     // IPropertyBagHelperContext
503     virtual ::osl::Mutex&   getMutex();
504     virtual void            describeFixedAndAggregateProperties(
505         ::com::sun::star::uno::Sequence< ::com::sun::star::beans::Property >& _out_rFixedProperties,
506         ::com::sun::star::uno::Sequence< ::com::sun::star::beans::Property >& _out_rAggregateProperties
507     ) const;
508     virtual ::com::sun::star::uno::Reference< ::com::sun::star::beans::XMultiPropertySet >
509                             getPropertiesInterface();
510 
511     /** describes the properties of our aggregate
512 
513         The default implementation simply asks m_xAggregateSet for its properties.
514 
515         You usually only need to overload this method if you want to filter the aggregate
516         properties.
517     */
518     virtual void describeAggregateProperties(
519 		::com::sun::star::uno::Sequence< ::com::sun::star::beans::Property >& /* [out] */ _rAggregateProps
520     ) const;
521 
522 public:
LockAccessfrm::OControlModel::LockAccess523     struct LockAccess { friend class ControlModelLock; private: LockAccess() { } };
524 
525     void                lockInstance( LockAccess );
526     oslInterlockedCount unlockInstance( LockAccess );
527 
528     void                firePropertyChanges(
529                             const ::com::sun::star::uno::Sequence< sal_Int32 >& _rHandles,
530                             const ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Any >& _rOldValues,
531                             const ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Any >& _rNewValues,
532                             LockAccess
533                         );
534 
535     inline ::osl::Mutex&
getInstanceMutex()536                         getInstanceMutex() { return m_aMutex; }
537 };
538 
539 //==================================================================
540 // simple destructor
541 #define DECLARE_DEFAULT_DTOR( classname )	\
542 	~classname() \
543 
544 // constructor for cloning a class
545 #define DECLARE_DEFAULT_CLONE_CTOR( classname )  \
546 	classname( \
547 		const classname* _pOriginal, \
548 		const	::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory>& _rxFactory \
549 	); \
550 
551 // all xtors for an inner class of the object hierarchy
552 #define DECLARE_DEFAULT_XTOR( classname )	\
553 	classname( \
554 		const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory>& _rxFactory, \
555 		const ::rtl::OUString& _rUnoControlModelTypeName, \
556 		const ::rtl::OUString& _rDefault \
557 	); \
558     DECLARE_DEFAULT_CLONE_CTOR( classname )  \
559     DECLARE_DEFAULT_DTOR( classname )   \
560 
561 // all xtors for an inner class of the object hierarchy which is *bound*
562 #define DECLARE_DEFAULT_BOUND_XTOR( classname )	\
563 	classname( \
564 		const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory>& _rxFactory, \
565 		const ::rtl::OUString& _rUnoControlModelTypeName, \
566 		const ::rtl::OUString& _rDefault, \
567         const sal_Bool _bSupportExternalBinding, \
568         const sal_Bool _bSupportsValidation \
569 	); \
570     DECLARE_DEFAULT_CLONE_CTOR( classname )  \
571     DECLARE_DEFAULT_DTOR( classname )   \
572 
573 // all xtors for a leas class of the object hierarchy
574 #define DECLARE_DEFAULT_LEAF_XTOR( classname )	\
575 	classname( \
576 		const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory>& _rxFactory \
577 	); \
578 	classname( \
579 		const classname* _pOriginal, \
580 		const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory>& _rxFactory \
581 	); \
582     DECLARE_DEFAULT_DTOR( classname )   \
583 
584 //==================================================================
585 // XCloneable
586 #define DECLARE_XCLONEABLE( ) \
587 	virtual ::com::sun::star::uno::Reference< ::com::sun::star::util::XCloneable > SAL_CALL createClone(  ) throw (::com::sun::star::uno::RuntimeException)
588 
589 #define IMPLEMENT_DEFAULT_CLONING( classname ) \
590 	::com::sun::star::uno::Reference< ::com::sun::star::util::XCloneable > SAL_CALL classname::createClone( ) throw (::com::sun::star::uno::RuntimeException) \
591 	{ \
592         classname* pClone = new classname( this, getContext().getLegacyServiceFactory() ); \
593         pClone->clonedFrom( this ); \
594         return pClone; \
595 	}
596 
597 //==================================================================
598 //= OBoundControlModel
599 //= model of a form layer control which is bound to a data source field
600 //==================================================================
601 typedef ::cppu::ImplHelper4 <	::com::sun::star::form::XLoadListener
602 						    ,   ::com::sun::star::form::XReset
603 							,	::com::sun::star::beans::XPropertyChangeListener
604 							,	::com::sun::star::sdb::XRowSetChangeListener
605                             >	OBoundControlModel_BASE1;
606 
607 // separated into an own base class since derivees can disable the support for this
608 // interface, thus we want to easily exclude it in the queryInterface and getTypes
609 typedef ::cppu::ImplHelper1 <   ::com::sun::star::form::XBoundComponent
610                             >   OBoundControlModel_COMMITTING;
611 
612 // dito
613 typedef ::cppu::ImplHelper2 <   ::com::sun::star::form::binding::XBindableValue
614                             ,   ::com::sun::star::util::XModifyListener
615                             >   OBoundControlModel_BINDING;
616 
617 // dito
618 typedef ::cppu::ImplHelper2 <   ::com::sun::star::form::validation::XValidityConstraintListener
619                             ,   ::com::sun::star::form::validation::XValidatableFormComponent
620                             >   OBoundControlModel_VALIDATION;
621 
622 class OBoundControlModel	:public OControlModel
623 							,public OBoundControlModel_BASE1
624 							,public OBoundControlModel_COMMITTING
625 							,public OBoundControlModel_BINDING
626                             ,public OBoundControlModel_VALIDATION
627                             ,public ::comphelper::OPropertyChangeListener
628 {
629 protected:
630     enum ValueChangeInstigator
631     {
632         eDbColumnBinding,
633         eExternalBinding,
634         eOther
635     };
636 
637 private:
638 	::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertySet >
639                                         m_xField;
640     // the form which controls supplies the field we bind to.
641     ::com::sun::star::uno::Reference< ::com::sun::star::form::XLoadable >
642                                         m_xAmbientForm;
643 
644 	::rtl::OUString					    m_sValuePropertyName;
645     sal_Int32                           m_nValuePropertyAggregateHandle;
646     sal_Int32                           m_nFieldType;
647     ::com::sun::star::uno::Type         m_aValuePropertyType;
648     bool                                m_bValuePropertyMayBeVoid;
649 
650     ResetHelper                         m_aResetHelper;
651     ::cppu::OInterfaceContainerHelper   m_aUpdateListeners;
652     ::cppu::OInterfaceContainerHelper   m_aFormComponentListeners;
653 
654     ::com::sun::star::uno::Reference< ::com::sun::star::form::binding::XValueBinding >
655                                         m_xExternalBinding;
656     ::com::sun::star::uno::Reference< ::com::sun::star::form::validation::XValidator >
657                                         m_xValidator;
658     ::com::sun::star::uno::Type         m_aExternalValueType;
659 
660 // <properties>
661 	::rtl::OUString						m_aControlSource;			// Datenquelle, Name des Feldes
662 	::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertySet >
663                                         m_xLabelControl;			// reference to a sibling control (model) which is our label
664     sal_Bool                            m_bInputRequired;
665 // </properties>
666 
667     ::comphelper::OPropertyChangeMultiplexer*
668                                 m_pAggPropMultiplexer;
669 
670     bool                        m_bFormListening            : 1;    // are we currently a XLoadListener at our ambient form?
671 	sal_Bool					m_bLoaded		            : 1;
672 	sal_Bool					m_bRequired		            : 1;
673 	const sal_Bool              m_bCommitable	            : 1;    // do we support XBoundComponent?
674     const sal_Bool              m_bSupportsExternalBinding  : 1;    // do we support XBindableValue?
675     const sal_Bool			    m_bSupportsValidation       : 1;    // do we support XValidatable?
676 	sal_Bool					m_bForwardValueChanges      : 1;    // do we currently handle changes in the bound database field?
677     sal_Bool			        m_bTransferingValue         : 1;    // true if we're currently transfering our value to an external binding
678     sal_Bool                    m_bIsCurrentValueValid      : 1;    // flag specifying whether our current value is valid, relative to our external validator
679     sal_Bool                    m_bBindingControlsRO        : 1;    // is our ReadOnly property currently controlled by our external binding?
680     sal_Bool                    m_bBindingControlsEnable    : 1;    // is our Enabled property currently controlled by our external binding?
681 
682     ValueChangeInstigator       m_eControlValueChangeInstigator;
683 
684 protected:
685 	::rtl::OUString					    m_aLabelServiceName;
686 		// when setting the label for our control (property FM_PROP_CONTROLLABEL, member m_xLabelControl),
687 		// we accept only objects supporting an XControlModel interface, an XServiceInfo interface and
688 		// support for a service (XServiceInfo::supportsService) determined by this string.
689 		// Any other arguments will throw an IllegalArgumentException.
690 		// The default value is FM_COMPONENT_FIXEDTEXT.
691 
692     ::com::sun::star::uno::Reference< ::com::sun::star::sdbc::XRowSet >
693                                         m_xCursor;
694 	::com::sun::star::uno::Reference< ::com::sun::star::sdb::XColumnUpdate >
695                                         m_xColumnUpdate;
696 	::com::sun::star::uno::Reference< ::com::sun::star::sdb::XColumn >
697                                         m_xColumn;
698 
699 protected:
getValuePropertyName() const700     inline const ::rtl::OUString&   getValuePropertyName( ) const       { return m_sValuePropertyName; }
getValuePropertyAggHandle() const701     inline sal_Int32                getValuePropertyAggHandle( ) const  { return m_nValuePropertyAggregateHandle; }
getControlSource() const702     inline const ::rtl::OUString&   getControlSource( ) const           { return m_aControlSource; }
isRequired() const703     inline sal_Bool                 isRequired() const                  { return m_bRequired; }
isLoaded() const704     inline sal_Bool                 isLoaded() const                    { return m_bLoaded; }
705 
706 protected:
707 
708 	OBoundControlModel(
709 		const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory>& _rFactory,
710                                                             // factory to create the aggregate with
711 		const ::rtl::OUString& _rUnoControlModelTypeName,	// service name of te model to aggregate
712 		const ::rtl::OUString& _rDefault,					// service name of the default control
713 		const sal_Bool _bCommitable,						// is the control (model) commitable ?
714         const sal_Bool _bSupportExternalBinding,            // set to sal_True if you want to support XBindableValue
715         const sal_Bool _bSupportsValidation                 // set to sal_True if you want to support XValidatable
716 	);
717 	OBoundControlModel(
718 		const OBoundControlModel* _pOriginal,				// the original object to clone
719 		const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory>& _rFactory
720                                                             // factory to create the aggregate with
721 	);
722 	virtual ~OBoundControlModel();
723 
724     /// late ctor after cloning
725     virtual void clonedFrom( const OControlModel* _pOriginal );
726 
727     /** initializes the part of the class which is related to the control value.
728 
729         <p>Kind of late ctor, to be called for derivees which have a dedicated value property.<br/>
730         The value property is the property which's value is synced with either the database
731         column the object is bound to, or with the external value binding, if present.<br/>
732         E.g. for a text control model, this property will most probably be "Text".</p>
733 
734         <p>Derived classes are stronly recommend to call this method - at least the
735         "DataFieldProperty" (exposed in getFastPropertyValue) relies on the information
736         given herein, and needs to be supplied otherwise else.</p>
737 
738         <p>If this method has been called properly, then <member>setControlValue</member>
739         does not need to be overridden - it will simply set the property value at the
740         aggregate then.</p>
741 
742         @precond
743             The method has not be called before during the life time of the object.
744 
745         @param _rValuePropertyName
746             the name of the value property
747         @param _nValuePropertyExternalHandle
748             the handle of the property, as exposed to external components.<br/>
749             Normally, this information can be obtained dynamically (e.g. from describeFixedProperties),
750             but since this method is to be called from within the constructor of derived classes,
751             we prefer to be on the *really* safe side here ....
752 
753         @see setControlValue
754         @see suspendValueListening
755         @see resumeValueListening
756         @see describeFixedProperties
757     */
758     void                    initValueProperty(
759                                 const ::rtl::OUString& _rValuePropertyName,
760                                 sal_Int32 _nValuePropertyExternalHandle
761                             );
762 
763     /** initializes the part of the class which is related to the control value.
764 
765         <p>In opposite to ->initValueProperty, this method is to be used for value properties which are <em>not</em>
766         implemented by our aggregate, but by ourselves.</p>
767 
768         <p>Certain functionality is not available when using own value properties. This includes binding to an external
769         value and external validation. (This is not a conceptual limit, but simply missing implementation.)</p>
770     */
771     void                    initOwnValueProperty(
772                                 const ::rtl::OUString& i_rValuePropertyName
773                             );
774 
775     /** suspends listening at the value property
776 
777         <p>As long as this listening is suspended, changes in the value property will not be
778         recognized and not be handled.</p>
779 
780         @see initValueProperty
781         @see resumeValueListening
782     */
783     void                    suspendValueListening( );
784 
785     /** resumes listening at the value property
786 
787         <p>As long as this listening is suspended, changes in the value property will not be
788         recognized and not be handled.</p>
789 
790         @precond
791             listening at the value property is currently suspended
792 
793         @see initValueProperty
794         @see resumeValueListening
795     */
796     void                    resumeValueListening( );
797 
798     /** (to be) called when the value property changed
799 
800         Normally, this is done automatically, since the value property is a property of our aggregate, and we're
801         a listener at this property.
802         However, in some cases the value property might not be an aggregate property, but a property of the
803         delegator instance. In this case, you'll need to call <code>onValuePropertyChange</code> whenever this
804         property changes.
805     */
806     void                    onValuePropertyChange( ControlModelLock& i_rControLock );
807 
808     /** starts listening at the aggregate, for changes in the given property
809 
810         <p>The OBoundControlModel automatically registers a multiplexer which listens for
811         changes in the aggregate property values. By default, only the control value property
812         is observed. You may add additional properties to be observed with this method.</p>
813 
814         @see initValueProperty
815         @see _propertyChanged
816     */
817     void                    startAggregatePropertyListening( const ::rtl::OUString& _rPropertyName );
818 
819     /** returns the default which should be used when resetting the control
820 
821         <p>The default implementation returns an empty Any.</p>
822 
823         @see resetNoBroadcast
824     */
825     virtual ::com::sun::star::uno::Any
826                             getDefaultForReset() const;
827 
828     /** translates a db column value into a control value.
829 
830         <p>Must transform the very current value of the database column we're bound to
831         (<member>m_xColumn</member>) into a value which can be used as current value
832         for the control.</p>
833 
834         @see setControlValue
835         @pure
836     */
837     virtual ::com::sun::star::uno::Any
838                             translateDbColumnToControlValue( ) = 0;
839 
840     /** returns the data types which the control could use to exchange data with
841         an external value binding
842 
843         The types returned here are completely independent from the concrete value binding,
844         they're just candidates which depend on the control type, and possible the concrete state
845         of the control (i.e. some property value).
846 
847         If a control implementation supports multiple types, the ordering in the returned
848         sequence indicates preference: Preferred types are mentioned first.
849 
850         The default implementation returns the type of our value property.
851     */
852     virtual ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Type >
853                             getSupportedBindingTypes();
854 
855     /** translates the given value, which was obtained from the current external value binding,
856         to a value which can be used in setControlValue
857 
858         <p>The default implementation returns the value itself, exception when it is VOID, and
859         our value property is not allowed to be void - in this case, the returned value is a
860         default-constructed value of the type required by our value property.
861 
862         @see hasExternalValueBinding
863         @see getExternalValueType
864     */
865     virtual ::com::sun::star::uno::Any
866                             translateExternalValueToControlValue( const ::com::sun::star::uno::Any& _rExternalValue ) const;
867 
868     /** commits the current control value to our external value binding
869 
870         <p>The default implementation simply calls getControlValue.</p>
871 
872         @see hasExternalValueBinding
873         @see initValueProperty
874     */
875     virtual ::com::sun::star::uno::Any
876                             translateControlValueToExternalValue( ) const;
877 
878     /** commits the current control value to the database column we're bound to
879         @precond
880             we're properly bound to a database column, especially <member>m_xColumnUpdate</member>
881             is not <NULL/>
882         @param _bPostReset
883             <TRUE/> if and only if the current control value results from a reset (<member>getDefaultForReset</member>)
884         @pure
885     */
886     virtual sal_Bool        commitControlValueToDbColumn(
887                                 bool _bPostReset
888                             ) = 0;
889 
890     /** sets the given value as new current value for the control
891 
892         Besides some administrative work (such as caring for <member>m_eControlValueChangeInstigator</member>),
893         this method simply calls <member>doSetControlValue</member>.
894 
895         @precond
896             Our own mutex is locked.
897         @param _rValue
898             The value to set. This value is guaranteed to be created by
899             <member>translateDbColumnToControlValue</member> or
900             <member>translateExternalValueToControlValue</member>
901         @param _eInstigator
902             the instigator of the value change
903     */
904             void            setControlValue(
905                                 const ::com::sun::star::uno::Any& _rValue,
906                                 ValueChangeInstigator _eInstigator
907                             );
908     /**
909         <p>The default implementation will forward the given value to the aggregate, using
910         m_nValuePropertyAggregateHandle and/or m_sValuePropertyName.</p>
911 
912         @precond
913             Our own mutex is locked.
914         @param _rValue
915             The value to set. This value is guaranteed to be created by
916             <member>translateDbColumnToControlValue</member> or
917             <member>translateExternalValueToControlValue</member>
918     */
919     virtual void            doSetControlValue(
920                                 const ::com::sun::star::uno::Any& _rValue
921                             );
922 
923     /** retrieves the current value of the control
924 
925         <p>The default implementation will ask the aggregate for the property value
926         determined by either m_nValuePropertyAggregateHandle and/or m_sValuePropertyName.</p>
927 
928         @precond
929             Our own mutex is locked.
930     */
931     virtual ::com::sun::star::uno::Any
932                             getControlValue( ) const;
933 
934     /** called whenever a connection to a database column has been established
935     */
936 	virtual void            onConnectedDbColumn( const ::com::sun::star::uno::Reference< ::com::sun::star::uno::XInterface >& _rxForm );
937     /** called whenever a connection to a database column has been suspended
938     */
939 	virtual void            onDisconnectedDbColumn();
940 
941     /** called whenever a connection to an external supplier of values (XValueBinding) has been established
942         @see m_xExternalBinding
943     */
944 	virtual void            onConnectedExternalValue( );
945     /** called whenever a connection to an external supplier of values (XValueBinding) has been suspended
946     */
947 	virtual void            onDisconnectedExternalValue();
948 
949     /** called whenever an external validator has been registered
950     */
951 	virtual void            onConnectedValidator( );
952     /** called whenever an external validator has been revoked
953     */
954 	virtual void            onDisconnectedValidator( );
955 
956 	/**	nFieldType ist der Typ des Feldes, an das das Model gebunden werden soll.
957 		Das Binden erfolgt genau dann, wenn Rueckgabewert sal_True.
958 		Die Standard-Implementation erlaubt alles ausser den drei binary-Typen und
959 		FieldType_OTHER.
960 	*/
961 	virtual sal_Bool		approveDbColumnType(sal_Int32 _nColumnType);
962 
963     /** retrieves the current value of the control, in a shape which can be used with our
964         external validator.
965 
966         The default implementation simply calls <member>>translateControlValueToExternalValue</member>.
967 
968         @precond
969             Our own mutex is locked.
970     */
971     virtual ::com::sun::star::uno::Any
972                             translateControlValueToValidatableValue( ) const;
973 
974     /** retrieves the current value of the form component
975 
976         This is the implementation method for XValidatableFormComponent::getCurrentValue. The default implementation
977         calls translateControlValueToValidatableValue if a validator is present, otherwise getControlValue.
978 
979         @precond
980             our mutex is locked when this method is called
981     */
982     virtual ::com::sun::star::uno::Any
983                             getCurrentFormComponentValue() const;
984 
985 	/** We can't write (new) common properties in this base class, as the file format doesn't allow this
986 	    (unfortunally). So derived classes may use the following to methods. They secure the written
987 	    data with marks, so any new common properties in newer versions will be skipped by older ones.
988     */
989 	void	writeCommonProperties(const ::com::sun::star::uno::Reference< ::com::sun::star::io::XObjectOutputStream>& _rxOutStream);
990 	void	readCommonProperties(const ::com::sun::star::uno::Reference< ::com::sun::star::io::XObjectInputStream>& _rxInStream);
991 	// the next method may be used in derived classes's read when an unknown version is encountered
992 	void	defaultCommonProperties();
993 
994     /** called to reset the control to some kind of default.
995 
996         <p>The semantics of "default" is finally defined by the derived class (in particular,
997         by <member>getDefaultForReset</member>).</p>
998 
999         <p>No listener notification needs to be done in the derived class.</p>
1000 
1001         <p>Normally, you won't override this method, but <member>getDefaultForReset</member> instead.</p>
1002 
1003         @see getDefaultForReset
1004     */
1005 	virtual void            resetNoBroadcast();
1006 
1007     virtual ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Type>	_getTypes();
1008 
1009     /// sets m_xField to the given new value, without notifying our listeners
1010 	void    impl_setField_noNotify(
1011                 const ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertySet>& _rxField
1012             );
hasField() const1013     inline bool hasField() const
1014     {
1015         return m_xField.is();
1016     }
getFieldType() const1017     inline sal_Int32 getFieldType() const
1018     {
1019         return m_nFieldType;
1020     }
1021 
1022     // OControlModel's property handling
1023 	virtual void describeFixedProperties(
1024 		::com::sun::star::uno::Sequence< ::com::sun::star::beans::Property >& /* [out] */ _rProps
1025     ) const;
1026 
1027 public:
getField() const1028 	inline const ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertySet>& getField() const
1029 	{
1030 		return m_xField;
1031 	}
1032 
1033 public:
1034 	// UNO Anbindung
1035 	DECLARE_UNO3_AGG_DEFAULTS(OBoundControlModel, OControlModel);
1036 	virtual ::com::sun::star::uno::Any SAL_CALL queryAggregation( const ::com::sun::star::uno::Type& _rType ) throw (::com::sun::star::uno::RuntimeException);
1037 
1038     // OComponentHelper
1039 	virtual void SAL_CALL disposing();
1040 
1041     // XReset
1042     virtual void SAL_CALL reset(  ) throw(::com::sun::star::uno::RuntimeException);
1043     virtual void SAL_CALL addResetListener( const ::com::sun::star::uno::Reference< ::com::sun::star::form::XResetListener >& aListener ) throw(::com::sun::star::uno::RuntimeException);
1044     virtual void SAL_CALL removeResetListener( const ::com::sun::star::uno::Reference< ::com::sun::star::form::XResetListener >& aListener ) throw(::com::sun::star::uno::RuntimeException);
1045 
1046     // XServiceInfo
1047     virtual StringSequence SAL_CALL getSupportedServiceNames(  ) throw(::com::sun::star::uno::RuntimeException);
1048 
1049     // XServiceInfo - static version
1050 	static  StringSequence SAL_CALL	getSupportedServiceNames_Static() throw(::com::sun::star::uno::RuntimeException);
1051 
1052     // XChild
1053     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);
1054 
1055     // XPersistObject
1056     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);
1057     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);
1058 
1059     // XBoundComponent
1060     virtual sal_Bool SAL_CALL commit() throw(::com::sun::star::uno::RuntimeException);
1061 
1062     // XUpdateBroadcaster (base of XBoundComponent)
1063     virtual void SAL_CALL addUpdateListener( const ::com::sun::star::uno::Reference< ::com::sun::star::form::XUpdateListener >& aListener ) throw(::com::sun::star::uno::RuntimeException);
1064     virtual void SAL_CALL removeUpdateListener( const ::com::sun::star::uno::Reference< ::com::sun::star::form::XUpdateListener >& aListener ) throw(::com::sun::star::uno::RuntimeException);
1065 
1066     // XPropertySet
1067 	virtual void SAL_CALL getFastPropertyValue(::com::sun::star::uno::Any& rValue, sal_Int32 nHandle) const;
1068 	virtual sal_Bool SAL_CALL convertFastPropertyValue(
1069 				::com::sun::star::uno::Any& _rConvertedValue, ::com::sun::star::uno::Any& _rOldValue, sal_Int32 _nHandle, const ::com::sun::star::uno::Any& _rValue )
1070 				throw (::com::sun::star::lang::IllegalArgumentException);
1071 	virtual void SAL_CALL setFastPropertyValue_NoBroadcast( sal_Int32 nHandle, const ::com::sun::star::uno::Any& rValue )
1072 				throw (::com::sun::star::uno::Exception);
1073     using ::cppu::OPropertySetHelper::getFastPropertyValue;
1074 
1075 // ::com::sun::star::beans::XPropertyState
1076 	virtual ::com::sun::star::uno::Any getPropertyDefaultByHandle( sal_Int32 nHandle ) const;
1077 
1078 // XEventListener
1079 	virtual void SAL_CALL disposing(const ::com::sun::star::lang::EventObject& Source) throw (::com::sun::star::uno::RuntimeException);
1080 
1081 // XPropertyChangeListener
1082     virtual void SAL_CALL propertyChange( const ::com::sun::star::beans::PropertyChangeEvent& evt ) throw(::com::sun::star::uno::RuntimeException);
1083 
1084     // XRowSetChangeListener
1085     virtual void SAL_CALL onRowSetChanged( const ::com::sun::star::lang::EventObject& i_Event ) throw (::com::sun::star::uno::RuntimeException);
1086 
1087 // XLoadListener
1088     virtual void SAL_CALL loaded( const ::com::sun::star::lang::EventObject& aEvent ) throw(::com::sun::star::uno::RuntimeException);
1089     virtual void SAL_CALL unloading( const ::com::sun::star::lang::EventObject& aEvent ) throw(::com::sun::star::uno::RuntimeException);
1090     virtual void SAL_CALL unloaded( const ::com::sun::star::lang::EventObject& aEvent ) throw(::com::sun::star::uno::RuntimeException);
1091     virtual void SAL_CALL reloading( const ::com::sun::star::lang::EventObject& aEvent ) throw(::com::sun::star::uno::RuntimeException);
1092     virtual void SAL_CALL reloaded( const ::com::sun::star::lang::EventObject& aEvent ) throw(::com::sun::star::uno::RuntimeException);
1093 
1094 private:
1095     // XBindableValue
1096     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);
1097     virtual ::com::sun::star::uno::Reference< ::com::sun::star::form::binding::XValueBinding > SAL_CALL getValueBinding(  ) throw (::com::sun::star::uno::RuntimeException);
1098 
1099     // XModifyListener
1100     virtual void SAL_CALL modified( const ::com::sun::star::lang::EventObject& _rEvent ) throw (::com::sun::star::uno::RuntimeException);
1101 
1102     // XValidatable
1103     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);
1104     virtual ::com::sun::star::uno::Reference< ::com::sun::star::form::validation::XValidator > SAL_CALL getValidator(  ) throw (::com::sun::star::uno::RuntimeException);
1105 
1106     // XValidityConstraintListener
1107     virtual void SAL_CALL validityConstraintChanged( const ::com::sun::star::lang::EventObject& Source ) throw (::com::sun::star::uno::RuntimeException);
1108 
1109     // XValidatableFormComponent
1110     virtual sal_Bool SAL_CALL isValid(  ) throw (::com::sun::star::uno::RuntimeException);
1111     virtual ::com::sun::star::uno::Any SAL_CALL getCurrentValue(  ) throw (::com::sun::star::uno::RuntimeException);
1112     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);
1113     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);
1114 
1115 protected:
1116     // OPropertyChangeListener
1117 	virtual void
1118                 _propertyChanged( const ::com::sun::star::beans::PropertyChangeEvent& _rEvt ) throw ( ::com::sun::star::uno::RuntimeException );
1119 
1120     /// checks whether we currently have an external value binding in place
hasExternalValueBinding() const1121     inline  bool    hasExternalValueBinding() const { return m_xExternalBinding.is(); }
1122 
1123     // checks whether we currently have an external validator
hasValidator() const1124     inline  bool    hasValidator() const { return m_xValidator.is(); }
1125 
1126     /** transfers the very current value of the db column we're bound to the control
1127         @precond
1128             our own mutex is locked
1129         @precond
1130             we don't have an external binding in place
1131     */
1132     void        transferDbValueToControl( );
1133 
1134     /** transfers the current value of the active external binding to the control
1135         @precond
1136             we do have an active external binding in place
1137     */
1138     void        transferExternalValueToControl( ControlModelLock& _rInstanceLock );
1139 
1140     /** transfers the control value to the external binding
1141         @precond
1142             our own mutex is locked, and _rInstanceLock is the guard locking it
1143         @precond
1144             we do have an active external binding in place
1145     */
1146     void        transferControlValueToExternal( ControlModelLock& _rInstanceLock );
1147 
1148     /** calculates the type which is to be used to communicate with the current external binding,
1149         and stores it in m_aExternalValueType
1150 
1151         The method checks the possible type candidates as returned by getSupportedBindingTypes,
1152         and the types supported by the current external binding, if any.
1153     */
1154     void        calculateExternalValueType();
1155 
1156     /** returns the type which should be used to exchange data with our external value binding
1157 
1158         @see initValueProperty
1159     */
1160     const ::com::sun::star::uno::Type&
getExternalValueType() const1161                 getExternalValueType() const { return m_aExternalValueType; }
1162 
1163     /** initializes the control from m_xField
1164 
1165         Basically, this method calls transferDbValueToControl - but only if our cursor is positioned
1166         on a valid row. Otherwise, the control is reset.
1167 
1168         @precond
1169             m_xField is not <NULL/>
1170     */
1171     void        initFromField( const ::com::sun::star::uno::Reference< ::com::sun::star::sdbc::XRowSet>& _rxForm );
1172 
1173 private:
1174 	sal_Bool    connectToField( const ::com::sun::star::uno::Reference< ::com::sun::star::sdbc::XRowSet>& _rxForm );
1175 	void        resetField();
1176 
1177     /** does a new validation of the control value
1178 
1179         If necessary, our <member>m_bIsCurrentValueValid</member> member will be adjusted,
1180         and changes will be notified.
1181 
1182         Note that it's not necessary that we're connected to a validator. If we are not,
1183         it's assumed that our value is valid, and this is handled appropriately.
1184 
1185         Use this method if there is a potential that <b>only</b> the validity flag changed. If
1186         any of the other aspects (our current value, or our current text) changed, then
1187         pass <TRUE/> for <member>_bForceNotification</member>.
1188 
1189         @param _bForceNotification
1190             if <TRUE/>, then the validity listeners will be notified, not matter whether the validity
1191             changed.
1192     */
1193     void        recheckValidity( bool _bForceNotification );
1194 
1195     /// initializes m_pAggPropMultiplexer
1196     void        implInitAggMultiplexer( );
1197 
1198     /// initializes listening at the value property
1199     void        implInitValuePropertyListening( ) const;
1200 
1201     /** adds or removes the component as load listener to/from our form, and (if necessary) as RowSetChange listener at
1202         our parent.
1203 
1204         @precond there must no external value binding be in place
1205     */
1206     void        doFormListening( const bool _bStart );
1207 
isFormListening() const1208     inline bool isFormListening() const { return m_bFormListening; }
1209 
1210     /** determines the new value of m_xAmbientForm
1211     */
1212     void        impl_determineAmbientForm_nothrow();
1213 
1214     /** connects to a value supplier which is an database column.
1215 
1216         The column is take from our parent, which must be a database form respectively row set.
1217 
1218         @precond The control does not have an external value supplier
1219 
1220         @param _bFromReload
1221             Determines whether the connection is made after the row set has been loaded (<FALSE/>)
1222             or reloaded (<TRUE/>)
1223 
1224         @see impl_disconnectDatabaseColumn_noNotify
1225     */
1226     void        impl_connectDatabaseColumn_noNotify(
1227                     bool  _bFromReload
1228                 );
1229 
1230     /** disconnects from a value supplier which is an database column
1231 
1232         @precond The control does not have an external value supplier
1233         @see impl_connectDatabaseColumn_noNotify
1234     */
1235     void        impl_disconnectDatabaseColumn_noNotify();
1236 
1237     /** connects to an external value binding
1238 
1239         <p>Note that by definition, external data bindings superseede the SQL data binding which
1240         is defined by our RowSet-column-related properties. This means that in case we're currently
1241         connected to a database column when this is called, this connection is suspended.</p>
1242 
1243         @precond
1244                 the new external binding has already been approved (see <member>impl_approveValueBinding_nolock</member>)
1245         @precond
1246                 there currently is no external binding in place
1247     */
1248     void        connectExternalValueBinding(
1249                     const ::com::sun::star::uno::Reference< ::com::sun::star::form::binding::XValueBinding >& _rxBinding,
1250                     ControlModelLock& _rInstanceLock
1251                 );
1252 
1253     /** disconnects from an external value binding
1254 
1255         @precond
1256                 there currently is an external binding in place
1257     */
1258     void        disconnectExternalValueBinding( );
1259 
1260     /** connects the component to an external validator
1261 
1262         @precond
1263             there currently is no active validator
1264         @precond
1265             our mutex is currently locked exactly once
1266     */
1267     void        connectValidator(
1268                     const ::com::sun::star::uno::Reference< ::com::sun::star::form::validation::XValidator >& _rxValidator
1269                 );
1270 
1271     /** disconnects the component from it's current an external validator
1272 
1273         @precond
1274             there currently is an active validator
1275         @precond
1276             our mutex is currently locked exactly once
1277     */
1278     void        disconnectValidator( );
1279 
1280     /** called from within <member scope="com::sun::star:::form::binding">XBindableValue::setValueBinding</member>
1281         to approve the new binding
1282 
1283         The default implementation approves the binding if and only if it is not <NULL/>, and supports
1284         the type returned by getExternalValueType.
1285 
1286         @param _rxBinding
1287             the binding which applies for being responsible for our value, Must not be
1288             <NULL/>
1289         @return
1290             <TRUE/> if and only if the given binding can supply values in the proper type
1291 
1292         @seealso getExternalValueType
1293     */
1294     sal_Bool    impl_approveValueBinding_nolock(
1295                     const ::com::sun::star::uno::Reference< ::com::sun::star::form::binding::XValueBinding >& _rxBinding
1296                 );
1297 };
1298 
1299     //=========================================================================
1300     //= inlines
1301     //=========================================================================
acquire()1302     inline void ControlModelLock::acquire()
1303     {
1304         m_rModel.lockInstance( OControlModel::LockAccess() );
1305         m_bLocked = true;
1306     }
release()1307     inline void ControlModelLock::release()
1308     {
1309         OSL_ENSURE( m_bLocked, "ControlModelLock::release: not locked!" );
1310         m_bLocked = false;
1311 
1312         if ( 0 == m_rModel.unlockInstance( OControlModel::LockAccess() ) )
1313             impl_notifyAll_nothrow();
1314     }
1315 
1316 //.........................................................................
1317 }
1318 //.........................................................................
1319 
1320 #endif // _FORMS_FORMCOMPONENT_HXX_
1321 
1322