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