nss: upgrade to release 3.73
[LibreOffice.git] / forms / source / inc / FormComponent.hxx
blob4a2fc4bf95caf9a9d05d6b8bfad1f6b8b8789166
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
20 #ifndef INCLUDED_FORMS_SOURCE_INC_FORMCOMPONENT_HXX
21 #define INCLUDED_FORMS_SOURCE_INC_FORMCOMPONENT_HXX
23 #include "cloneable.hxx"
24 #include "propertybaghelper.hxx"
25 #include "resettable.hxx"
26 #include "windowstateguard.hxx"
28 #include <com/sun/star/awt/XControl.hpp>
29 #include <com/sun/star/beans/XPropertyAccess.hpp>
30 #include <com/sun/star/beans/XPropertyContainer.hpp>
31 #include <com/sun/star/container/XNamed.hpp>
32 #include <com/sun/star/form/binding/XBindableValue.hpp>
33 #include <com/sun/star/form/validation/XValidatableFormComponent.hpp>
34 #include <com/sun/star/form/validation/XValidityConstraintListener.hpp>
35 #include <com/sun/star/form/XBoundComponent.hpp>
36 #include <com/sun/star/form/XBoundControl.hpp>
37 #include <com/sun/star/form/XFormComponent.hpp>
38 #include <com/sun/star/form/XLoadListener.hpp>
39 #include <com/sun/star/form/XReset.hpp>
40 #include <com/sun/star/io/XPersistObject.hpp>
41 #include <com/sun/star/lang/XEventListener.hpp>
42 #include <com/sun/star/lang/XServiceInfo.hpp>
43 #include <com/sun/star/sdb/XColumn.hpp>
44 #include <com/sun/star/sdb/XColumnUpdate.hpp>
45 #include <com/sun/star/sdb/XRowSetChangeListener.hpp>
46 #include <com/sun/star/sdbc/XRowSet.hpp>
47 #include <com/sun/star/uno/XAggregation.hpp>
48 #include <com/sun/star/uno/XComponentContext.hpp>
49 #include <com/sun/star/util/XCloneable.hpp>
50 #include <com/sun/star/util/XModifyListener.hpp>
51 #include <com/sun/star/form/XLoadable.hpp>
53 #include <comphelper/propagg.hxx>
54 #include <comphelper/propmultiplex.hxx>
55 #include <comphelper/uno3.hxx>
56 #include <cppuhelper/component.hxx>
57 #include <cppuhelper/implbase1.hxx>
58 #include <cppuhelper/implbase2.hxx>
59 #include <cppuhelper/implbase3.hxx>
60 #include <cppuhelper/implbase4.hxx>
61 #include <cppuhelper/implbase7.hxx>
62 #include <cppuhelper/propshlp.hxx>
63 #include <osl/mutex.hxx>
64 #include <rtl/ustring.hxx>
67 namespace frm
71 // default tab index for components
72 const sal_Int16 FRM_DEFAULT_TABINDEX = 0;
74 // macros for quickly declaring/implementing XServiceInfo
75 #define DECLARE_XPERSISTOBJECT() \
76 virtual OUString SAL_CALL getServiceName() override; \
77 virtual void SAL_CALL write(const css::uno::Reference< css::io::XObjectOutputStream>& _rxOutStream) override; \
78 virtual void SAL_CALL read(const css::uno::Reference< css::io::XObjectInputStream>& _rxInStream) override;
80 class OControlModel;
83 //= ControlModelLock
85 /** class whose instances lock an OControlModel
87 Locking here merely means locking the OControlModel's mutex.
89 In addition to the locking facility, the class is also able to fire property
90 change notifications. This happens when the last ControlModelLock instance on a stack
91 dies.
93 class ControlModelLock
95 public:
96 ControlModelLock( OControlModel& _rModel )
97 :m_rModel( _rModel )
98 ,m_bLocked( false )
100 acquire();
103 ~ControlModelLock()
105 if ( m_bLocked )
106 release();
108 inline void acquire();
109 inline void release();
111 OControlModel& getModel() const { return m_rModel; };
113 /** adds a property change notification, which is to be fired when the last lock on the model
114 (in the current thread) is released.
116 void addPropertyNotification(
117 const sal_Int32 _nHandle,
118 const css::uno::Any& _rOldValue,
119 const css::uno::Any& _rNewValue
122 private:
123 void impl_notifyAll_nothrow();
125 OControlModel& m_rModel;
126 bool m_bLocked;
127 std::vector< sal_Int32 > m_aHandles;
128 std::vector< css::uno::Any > m_aOldValues;
129 std::vector< css::uno::Any > m_aNewValues;
131 ControlModelLock( const ControlModelLock& ) = delete;
132 ControlModelLock& operator=( const ControlModelLock& ) = delete;
136 //= OControl
137 //= base class for form layer controls
139 typedef ::cppu::ImplHelper3 < css::awt::XControl
140 , css::lang::XEventListener
141 , css::lang::XServiceInfo
142 > OControl_BASE;
144 class OControl :public ::cppu::OComponentHelper
145 ,public OControl_BASE
147 protected:
148 ::osl::Mutex m_aMutex;
149 css::uno::Reference< css::awt::XControl > m_xControl;
150 css::uno::Reference< css::uno::XAggregation>
151 m_xAggregate;
153 css::uno::Reference< css::uno::XComponentContext >
154 m_xContext;
155 WindowStateGuard m_aWindowStateGuard;
157 public:
158 /** constructs a control
160 @param _rFactory
161 the service factory for this control
162 @param _rAggregateService
163 the service name of the component to aggregate
164 @param _bSetDelegator
165 set this to <FALSE/> if you don't want the constructor to set the delegator at
166 the aggregate. In this case, you <em>have</em> to call doSetDelegator within your
167 own constructor.
169 This is helpful, if your derived class wants to cache an interface of the aggregate.
170 In this case, the aggregate needs to be queried for this interface <b>before</b> the
171 <member scope="css::uno">XAggregation::setDelegator</member> call.
173 In such a case, pass <FALSE/> to this parameter. Then, cache the aggregate's interface(s)
174 as needed. Afterwards, call <member>doSetDelegator</member>.
176 In your destructor, you need to call <member>doResetDelegator</member> before
177 resetting the cached interfaces. This will reset the aggregates delegator to <NULL/>,
178 which will ensure that the <member scope="css::uno">XInterface::release</member>
179 calls on the cached interfaces are really applied to the aggregate, instead of
180 the <type>OControl</type> itself.
182 OControl(
183 const css::uno::Reference< css::uno::XComponentContext >& _rFactory,
184 const OUString& _rAggregateService,
185 const bool _bSetDelegator = true
188 protected:
189 virtual ~OControl() override;
191 /** sets the control as delegator at the aggregate
193 This has to be called from within your derived class' constructor, if and only
194 if you passed <FALSE/> to the <arg>_bSetDelegator</arg> parameter of the
195 <type>OControl</type> constructor.
197 void doSetDelegator();
198 void doResetDelegator();
200 // UNO
201 DECLARE_UNO3_AGG_DEFAULTS(OControl, OComponentHelper)
202 virtual css::uno::Any SAL_CALL queryAggregation( const css::uno::Type& _rType ) override;
204 // XTypeProvider
205 virtual css::uno::Sequence<sal_Int8> SAL_CALL getImplementationId() override;
206 virtual css::uno::Sequence< css::uno::Type> SAL_CALL getTypes() override;
208 // OComponentHelper
209 virtual void SAL_CALL disposing() override;
211 // XComponent (as base of XControl)
212 virtual void SAL_CALL dispose( ) override
213 { OComponentHelper::dispose(); }
214 virtual void SAL_CALL addEventListener( const css::uno::Reference< css::lang::XEventListener>& _rxListener) override
215 { OComponentHelper::addEventListener(_rxListener); }
216 virtual void SAL_CALL removeEventListener( const css::uno::Reference< css::lang::XEventListener>& _rxListener) override
217 { OComponentHelper::removeEventListener(_rxListener); }
219 // XEventListener
220 virtual void SAL_CALL disposing(const css::lang::EventObject& Source) override;
222 // XServiceInfo
223 virtual sal_Bool SAL_CALL supportsService(const OUString& ServiceName) override;
224 virtual css::uno::Sequence<OUString> SAL_CALL getSupportedServiceNames() override;
225 virtual OUString SAL_CALL getImplementationName() override = 0;
227 // XControl
228 virtual void SAL_CALL setContext(const css::uno::Reference<css::uno::XInterface>& Context) override;
229 virtual css::uno::Reference<css::uno::XInterface> SAL_CALL getContext() override;
230 virtual void SAL_CALL createPeer(const css::uno::Reference<css::awt::XToolkit>& Toolkit, const css::uno::Reference<css::awt::XWindowPeer>& Parent) override;
231 virtual css::uno::Reference<css::awt::XWindowPeer> SAL_CALL getPeer() override;
232 virtual sal_Bool SAL_CALL setModel(const css::uno::Reference<css::awt::XControlModel>& Model) override;
233 virtual css::uno::Reference<css::awt::XControlModel> SAL_CALL getModel() override;
234 virtual css::uno::Reference<css::awt::XView> SAL_CALL getView() override;
235 virtual void SAL_CALL setDesignMode(sal_Bool bOn) override;
236 virtual sal_Bool SAL_CALL isDesignMode() override;
237 virtual sal_Bool SAL_CALL isTransparent() override;
239 protected:
240 virtual css::uno::Sequence< css::uno::Type> _getTypes();
241 // overwrite this and call the base class if you have additional types
243 css::uno::Sequence< OUString > getAggregateServiceNames() const;
245 private:
246 void impl_resetStateGuard_nothrow();
249 // a form control implementing the XBoundControl interface
250 typedef ::cppu::ImplHelper1 < css::form::XBoundControl
251 > OBoundControl_BASE;
252 class OBoundControl :public OControl
253 ,public OBoundControl_BASE
255 bool m_bLocked : 1;
257 public:
258 OBoundControl(
259 const css::uno::Reference< css::uno::XComponentContext >& _rxContext,
260 const OUString& _rAggregateService,
261 const bool _bSetDelegator = true
264 virtual ~OBoundControl() override;
266 DECLARE_UNO3_AGG_DEFAULTS(OBoundControl, OControl)
267 virtual css::uno::Any SAL_CALL queryAggregation( const css::uno::Type& _rType ) override;
269 // XBoundControl
270 virtual sal_Bool SAL_CALL getLock() override;
271 virtual void SAL_CALL setLock(sal_Bool _bLock) override;
272 // default implementation just disables the controls, overwrite _setLock to change this behaviour
274 // XControl
275 virtual sal_Bool SAL_CALL setModel(const css::uno::Reference< css::awt::XControlModel >& Model) override;
277 // XEventListener
278 virtual void SAL_CALL disposing(const css::lang::EventObject& Source) override;
280 // OComponentHelper
281 virtual void SAL_CALL disposing() override;
283 protected:
284 virtual css::uno::Sequence< css::uno::Type> _getTypes() override;
285 // implement the lock setting
286 void _setLock(bool _bLock);
290 //= OControlModel
291 //= model of a form layer control
293 //added for exporting OCX control
294 #define INVALID_OBJ_ID_IN_MSO 0xFFFF
296 typedef ::cppu::ImplHelper7 < css::form::XFormComponent
297 , css::io::XPersistObject
298 , css::container::XNamed
299 , css::lang::XServiceInfo
300 , css::util::XCloneable
301 , css::beans::XPropertyContainer
302 , css::beans::XPropertyAccess
303 > OControlModel_BASE;
305 class OControlModel :public ::cppu::OComponentHelper
306 ,public comphelper::OPropertySetAggregationHelper
307 ,public OControlModel_BASE
308 ,public OCloneableAggregation
309 ,public IPropertyBagHelperContext
312 protected:
313 css::uno::Reference<css::uno::XComponentContext> m_xContext;
315 ::osl::Mutex m_aMutex;
316 oslInterlockedCount m_lockCount;
318 css::uno::Reference<css::uno::XInterface> m_xParent; // ParentComponent
319 PropertyBagHelper m_aPropertyBagHelper;
321 const css::uno::Reference<css::uno::XComponentContext>&
322 getContext() const { return m_xContext; }
324 // <properties>
325 OUString m_aName; // name of the control
326 OUString m_aTag; // tag for additional data
327 sal_Int16 m_nTabIndex; // index within the taborder
328 sal_Int16 m_nClassId; // type of the control
329 bool m_bNativeLook; // should the control use the native platform look?
330 bool m_bGenerateVbEvents; // should the control generate fake vba events
331 //added for exporting OCX control
332 sal_Int16 m_nControlTypeinMSO; //keep the MS office control type for exporting to MS binary file
333 sal_uInt16 m_nObjIDinMSO; //keep the OCX control obj id for exporting to MS binary file
334 // </properties>
337 protected:
338 OControlModel(
339 const css::uno::Reference< css::uno::XComponentContext>& _rFactory, // factory to create the aggregate with
340 const OUString& _rUnoControlModelTypeName, // service name of te model to aggregate
341 const OUString& rDefault = OUString(), // service name of the default control
342 const bool _bSetDelegator = true // set to sal_False if you want to call setDelegator later (after returning from this ctor)
344 OControlModel(
345 const OControlModel* _pOriginal, // the original object to clone
346 const css::uno::Reference< css::uno::XComponentContext>& _rFactory, // factory to create the aggregate with
347 const bool _bCloneAggregate = true, // should the aggregate of the original be cloned, too?
348 const bool _bSetDelegator = true // set to sal_False if you want to call setDelegator later (after returning from this ctor)
350 virtual ~OControlModel() override;
352 /** to be called after an OBoundControlModel (a derivee, respectively) has been cloned
354 <p>This method contains late initializations which cannot be done in the
355 constructor of this base class, since the virtual method of derived classes do
356 not yet work there.</p>
358 virtual void clonedFrom( const OControlModel* _pOriginal );
360 using OComponentHelper::rBHelper;
362 virtual css::uno::Sequence< css::uno::Type> _getTypes();
364 void readHelpTextCompatibly(const css::uno::Reference< css::io::XObjectInputStream >& _rxInStream);
365 void writeHelpTextCompatibly(const css::uno::Reference< css::io::XObjectOutputStream >& _rxOutStream);
367 void doSetDelegator();
368 void doResetDelegator();
370 css::uno::Sequence< OUString > getAggregateServiceNames() const;
372 public:
373 DECLARE_UNO3_AGG_DEFAULTS(OControl, OComponentHelper)
374 virtual css::uno::Any SAL_CALL queryAggregation( const css::uno::Type& _rType ) override;
376 // XTypeProvider
377 virtual css::uno::Sequence<sal_Int8> SAL_CALL getImplementationId() override;
378 virtual css::uno::Sequence< css::uno::Type> SAL_CALL getTypes() override;
380 // OComponentHelper
381 virtual void SAL_CALL disposing() override;
383 // XNamed
384 virtual OUString SAL_CALL getName() override;
385 virtual void SAL_CALL setName(const OUString& aName) override;
387 // XServiceInfo
388 virtual sal_Bool SAL_CALL supportsService(const OUString& ServiceName) override;
389 virtual css::uno::Sequence<OUString> SAL_CALL getSupportedServiceNames() override;
390 virtual OUString SAL_CALL getImplementationName() override = 0;
392 // XServiceInfo - static version(s)
393 /// @throws css::uno::RuntimeException
394 static css::uno::Sequence<OUString> getSupportedServiceNames_Static();
396 // XPersistObject
397 virtual OUString SAL_CALL getServiceName() override = 0;
398 virtual void SAL_CALL
399 write(const css::uno::Reference< css::io::XObjectOutputStream>& _rxOutStream) override;
400 virtual void SAL_CALL
401 read(const css::uno::Reference< css::io::XObjectInputStream>& _rxInStream) override;
403 // XChild (base of XFormComponent)
404 virtual css::uno::Reference<css::uno::XInterface> SAL_CALL getParent() override;
405 virtual void SAL_CALL setParent(const css::uno::Reference<css::uno::XInterface>& Parent) override;
407 // XEventListener
408 virtual void SAL_CALL disposing(const css::lang::EventObject& Source) override;
410 // XPropertySet
411 virtual void SAL_CALL getFastPropertyValue(css::uno::Any& rValue, sal_Int32 nHandle) const override;
412 virtual sal_Bool SAL_CALL convertFastPropertyValue(
413 css::uno::Any& _rConvertedValue, css::uno::Any& _rOldValue, sal_Int32 _nHandle, const css::uno::Any& _rValue ) override;
414 virtual void SAL_CALL setFastPropertyValue_NoBroadcast( sal_Int32 nHandle, const css::uno::Any& rValue ) override;
415 using ::cppu::OPropertySetHelper::getFastPropertyValue;
417 // css::beans::XPropertyState
418 virtual css::beans::PropertyState getPropertyStateByHandle(sal_Int32 nHandle) override;
419 virtual void setPropertyToDefaultByHandle(sal_Int32 nHandle) override;
420 virtual css::uno::Any getPropertyDefaultByHandle( sal_Int32 nHandle ) const override;
422 // XCloneable
423 virtual css::uno::Reference< css::util::XCloneable > SAL_CALL createClone( ) override = 0;
425 // XPropertyContainer
426 virtual void SAL_CALL addProperty( const OUString& Name, ::sal_Int16 Attributes, const css::uno::Any& DefaultValue ) override;
427 virtual void SAL_CALL removeProperty( const OUString& Name ) override;
429 // XPropertyAccess
430 virtual css::uno::Sequence< css::beans::PropertyValue > SAL_CALL getPropertyValues( ) override;
431 virtual void SAL_CALL setPropertyValues( const css::uno::Sequence< css::beans::PropertyValue >& aProps ) override;
433 protected:
434 using OPropertySetAggregationHelper::setPropertyValues;
435 using OPropertySetAggregationHelper::getPropertyValues;
437 protected:
438 virtual void writeAggregate( const css::uno::Reference< css::io::XObjectOutputStream >& _rxOutStream ) const;
439 virtual void readAggregate( const css::uno::Reference< css::io::XObjectInputStream >& _rxInStream );
441 protected:
442 // XPropertySet
443 virtual css::uno::Reference< css::beans::XPropertySetInfo> SAL_CALL getPropertySetInfo() override;
444 // OPropertySetHelper
445 virtual cppu::IPropertyArrayHelper& SAL_CALL getInfoHelper() override;
447 /** describes the properties provided by this class, or its respective
448 derived class
450 Derived classes usually call the base class first, and then append own properties.
452 virtual void describeFixedProperties(
453 css::uno::Sequence< css::beans::Property >& /* [out] */ _rProps
454 ) const;
456 // IPropertyBagHelperContext
457 virtual ::osl::Mutex& getMutex() override;
458 virtual void describeFixedAndAggregateProperties(
459 css::uno::Sequence< css::beans::Property >& _out_rFixedProperties,
460 css::uno::Sequence< css::beans::Property >& _out_rAggregateProperties
461 ) const override;
462 virtual css::uno::Reference< css::beans::XMultiPropertySet >
463 getPropertiesInterface() override;
465 /** describes the properties of our aggregate
467 The default implementation simply asks m_xAggregateSet for its properties.
469 You usually only need to override this method if you want to filter the
470 aggregate properties.
472 virtual void describeAggregateProperties(
473 css::uno::Sequence< css::beans::Property >& /* [out] */ _rAggregateProps
474 ) const;
476 public:
477 struct LockAccess { friend class ControlModelLock; private: LockAccess() { } };
479 void lockInstance( LockAccess );
480 oslInterlockedCount unlockInstance( LockAccess );
482 void firePropertyChanges(
483 const std::vector< sal_Int32 >& _rHandles,
484 const std::vector< css::uno::Any >& _rOldValues,
485 const std::vector< css::uno::Any >& _rNewValues,
486 LockAccess
489 ::osl::Mutex&
490 getInstanceMutex() { return m_aMutex; }
493 // constructor for cloning a class
494 #define DECLARE_DEFAULT_CLONE_CTOR( classname ) \
495 classname( \
496 const classname* _pOriginal, \
497 const css::uno::Reference< css::uno::XComponentContext>& _rxFactory \
498 ); \
500 // all xtors for a leaf class of the object hierarchy
501 #define DECLARE_DEFAULT_LEAF_XTOR( classname ) \
502 classname( \
503 const css::uno::Reference< css::uno::XComponentContext>& _rxFactory \
504 ); \
505 classname( \
506 const classname* _pOriginal, \
507 const css::uno::Reference< css::uno::XComponentContext>& _rxFactory \
508 ); \
509 virtual ~classname() override \
512 #define IMPLEMENT_DEFAULT_CLONING( classname ) \
513 css::uno::Reference< css::util::XCloneable > SAL_CALL classname::createClone( ) \
515 classname* pClone = new classname( this, getContext() ); \
516 pClone->clonedFrom( this ); \
517 return pClone; \
521 //= OBoundControlModel
522 //= model of a form layer control which is bound to a data source field
524 typedef ::cppu::ImplHelper4 < css::form::XLoadListener
525 , css::form::XReset
526 , css::beans::XPropertyChangeListener
527 , css::sdb::XRowSetChangeListener
528 > OBoundControlModel_BASE1;
530 // separated into an own base class since derivees can disable the support for this
531 // interface, thus we want to easily exclude it in the queryInterface and getTypes
532 typedef ::cppu::ImplHelper1 < css::form::XBoundComponent
533 > OBoundControlModel_COMMITTING;
535 // ditto
536 typedef ::cppu::ImplHelper2 < css::form::binding::XBindableValue
537 , css::util::XModifyListener
538 > OBoundControlModel_BINDING;
540 // ditto
541 typedef ::cppu::ImplHelper2 < css::form::validation::XValidityConstraintListener
542 , css::form::validation::XValidatableFormComponent
543 > OBoundControlModel_VALIDATION;
545 class OBoundControlModel :public OControlModel
546 ,public OBoundControlModel_BASE1
547 ,public OBoundControlModel_COMMITTING
548 ,public OBoundControlModel_BINDING
549 ,public OBoundControlModel_VALIDATION
550 ,public ::comphelper::OPropertyChangeListener
552 protected:
553 enum ValueChangeInstigator
555 eDbColumnBinding,
556 eExternalBinding,
557 eOther
560 private:
561 css::uno::Reference< css::beans::XPropertySet >
562 m_xField;
563 // the form which controls supplies the field we bind to.
564 css::uno::Reference< css::form::XLoadable >
565 m_xAmbientForm;
567 OUString m_sValuePropertyName;
568 sal_Int32 m_nValuePropertyAggregateHandle;
569 sal_Int32 m_nFieldType;
570 css::uno::Type m_aValuePropertyType;
571 bool m_bValuePropertyMayBeVoid;
573 ResetHelper m_aResetHelper;
574 ::comphelper::OInterfaceContainerHelper2 m_aUpdateListeners;
575 ::comphelper::OInterfaceContainerHelper2 m_aFormComponentListeners;
577 css::uno::Reference< css::form::binding::XValueBinding >
578 m_xExternalBinding;
579 css::uno::Reference< css::form::validation::XValidator >
580 m_xValidator;
581 css::uno::Type m_aExternalValueType;
583 // <properties>
584 OUString m_aControlSource; // data source, name of the field
585 css::uno::Reference< css::beans::XPropertySet >
586 m_xLabelControl; // reference to a sibling control (model) which is our label
587 bool m_bInputRequired;
588 // </properties>
590 ::comphelper::OPropertyChangeMultiplexer*
591 m_pAggPropMultiplexer;
593 bool m_bFormListening : 1; // are we currently a XLoadListener at our ambient form?
594 bool m_bLoaded : 1;
595 bool m_bRequired : 1;
596 const bool m_bCommitable : 1; // do we support XBoundComponent?
597 const bool m_bSupportsExternalBinding : 1; // do we support XBindableValue?
598 const bool m_bSupportsValidation : 1; // do we support XValidatable?
599 bool m_bForwardValueChanges : 1; // do we currently handle changes in the bound database field?
600 bool m_bTransferringValue : 1; // true if we're currently transferring our value to an external binding
601 bool m_bIsCurrentValueValid : 1; // flag specifying whether our current value is valid, relative to our external validator
602 bool m_bBindingControlsRO : 1; // is our ReadOnly property currently controlled by our external binding?
603 bool m_bBindingControlsEnable : 1; // is our Enabled property currently controlled by our external binding?
605 ValueChangeInstigator m_eControlValueChangeInstigator;
607 protected:
608 OUString m_aLabelServiceName;
609 // when setting the label for our control (property FM_PROP_CONTROLLABEL, member m_xLabelControl),
610 // we accept only objects supporting an XControlModel interface, an XServiceInfo interface and
611 // support for a service (XServiceInfo::supportsService) determined by this string.
612 // Any other arguments will throw an IllegalArgumentException.
613 // The default value is FM_COMPONENT_FIXEDTEXT.
615 css::uno::Reference< css::sdbc::XRowSet >
616 m_xCursor;
617 css::uno::Reference< css::sdb::XColumnUpdate >
618 m_xColumnUpdate;
619 css::uno::Reference< css::sdb::XColumn >
620 m_xColumn;
622 protected:
623 sal_Int32 getValuePropertyAggHandle( ) const { return m_nValuePropertyAggregateHandle; }
624 const OUString& getControlSource( ) const { return m_aControlSource; }
625 bool isRequired() const { return m_bRequired; }
626 bool isLoaded() const { return m_bLoaded; }
628 protected:
630 OBoundControlModel(
631 const css::uno::Reference< css::uno::XComponentContext>& _rxContext,
632 // factory to create the aggregate with
633 const OUString& _rUnoControlModelTypeName, // service name of te model to aggregate
634 const OUString& _rDefault, // service name of the default control
635 const bool _bCommitable, // is the control (model) committable?
636 const bool _bSupportExternalBinding, // set to sal_True if you want to support XBindableValue
637 const bool _bSupportsValidation // set to sal_True if you want to support XValidatable
639 OBoundControlModel(
640 const OBoundControlModel* _pOriginal, // the original object to clone
641 const css::uno::Reference< css::uno::XComponentContext>& _rxContext
642 // factory to create the aggregate with
644 virtual ~OBoundControlModel() override;
646 /// late ctor after cloning
647 virtual void clonedFrom( const OControlModel* _pOriginal ) override;
649 /** initializes the part of the class which is related to the control value.
651 <p>Kind of late ctor, to be called for derivees which have a dedicated value property.<br/>
652 The value property is the property which's value is synced with either the database
653 column the object is bound to, or with the external value binding, if present.<br/>
654 E.g. for a text control model, this property will most probably be "Text".</p>
656 <p>Derived classes are strongly recommended to call this method - at least the
657 "DataFieldProperty" (exposed in getFastPropertyValue) relies on the information
658 given herein, and needs to be supplied otherwise else.</p>
660 <p>If this method has been called properly, then <member>setControlValue</member>
661 does not need to be overridden - it will simply set the property value at the
662 aggregate then.</p>
664 @precond
665 The method has not be called before during the life time of the object.
667 @param _rValuePropertyName
668 the name of the value property
669 @param _nValuePropertyExternalHandle
670 the handle of the property, as exposed to external components.<br/>
671 Normally, this information can be obtained dynamically (e.g. from describeFixedProperties),
672 but since this method is to be called from within the constructor of derived classes,
673 we prefer to be on the *really* safe side here...
675 @see setControlValue
676 @see suspendValueListening
677 @see resumeValueListening
678 @see describeFixedProperties
680 void initValueProperty(
681 const OUString& _rValuePropertyName,
682 sal_Int32 _nValuePropertyExternalHandle
685 /** initializes the part of the class which is related to the control value.
687 <p>In opposite to ->initValueProperty, this method is to be used for value properties which are <em>not</em>
688 implemented by our aggregate, but by ourselves.</p>
690 <p>Certain functionality is not available when using own value properties. This includes binding to an external
691 value and external validation. (This is not a conceptual limit, but simply missing implementation.)</p>
693 void initOwnValueProperty(
694 const OUString& i_rValuePropertyName
697 /** suspends listening at the value property
699 <p>As long as this listening is suspended, changes in the value property will not be
700 recognized and not be handled.</p>
702 @see initValueProperty
703 @see resumeValueListening
705 void suspendValueListening( );
707 /** resumes listening at the value property
709 <p>As long as this listening is suspended, changes in the value property will not be
710 recognized and not be handled.</p>
712 @precond
713 listening at the value property is currently suspended
715 @see initValueProperty
716 @see resumeValueListening
718 void resumeValueListening( );
720 /** (to be) called when the value property changed
722 Normally, this is done automatically, since the value property is a property of our aggregate, and we're
723 a listener at this property.
724 However, in some cases the value property might not be an aggregate property, but a property of the
725 delegator instance. In this case, you'll need to call <code>onValuePropertyChange</code> whenever this
726 property changes.
728 void onValuePropertyChange( ControlModelLock& i_rControLock );
730 /** starts listening at the aggregate, for changes in the given property
732 <p>The OBoundControlModel automatically registers a multiplexer which listens for
733 changes in the aggregate property values. By default, only the control value property
734 is observed. You may add additional properties to be observed with this method.</p>
736 @see initValueProperty
737 @see _propertyChanged
739 void startAggregatePropertyListening( const OUString& _rPropertyName );
741 /** returns the default which should be used when resetting the control
743 <p>The default implementation returns an empty Any.</p>
745 @see resetNoBroadcast
747 virtual css::uno::Any
748 getDefaultForReset() const;
750 /** translates a db column value into a control value.
752 <p>Must transform the very current value of the database column we're bound to
753 (<member>m_xColumn</member>) into a value which can be used as current value
754 for the control.</p>
756 @see setControlValue
757 @pure
759 virtual css::uno::Any
760 translateDbColumnToControlValue( ) = 0;
762 /** returns the data types which the control could use to exchange data with
763 an external value binding
765 The types returned here are completely independent from the concrete value binding,
766 they're just candidates which depend on the control type, and possible the concrete state
767 of the control (i.e. some property value).
769 If a control implementation supports multiple types, the ordering in the returned
770 sequence indicates preference: Preferred types are mentioned first.
772 The default implementation returns the type of our value property.
774 virtual css::uno::Sequence< css::uno::Type >
775 getSupportedBindingTypes();
777 /** translates the given value, which was obtained from the current external value binding,
778 to a value which can be used in setControlValue
780 <p>The default implementation returns the value itself, exception when it is VOID, and
781 our value property is not allowed to be void - in this case, the returned value is a
782 default-constructed value of the type required by our value property.
784 @see hasExternalValueBinding
785 @see getExternalValueType
787 virtual css::uno::Any
788 translateExternalValueToControlValue( const css::uno::Any& _rExternalValue ) const;
790 /** commits the current control value to our external value binding
792 <p>The default implementation simply calls getControlValue.</p>
794 @see hasExternalValueBinding
795 @see initValueProperty
797 virtual css::uno::Any
798 translateControlValueToExternalValue( ) const;
800 /** commits the current control value to the database column we're bound to
801 @precond
802 we're properly bound to a database column, especially <member>m_xColumnUpdate</member>
803 is not <NULL/>
804 @param _bPostReset
805 <TRUE/> if and only if the current control value results from a reset (<member>getDefaultForReset</member>)
806 @pure
808 virtual bool commitControlValueToDbColumn(
809 bool _bPostReset
810 ) = 0;
812 /** sets the given value as new current value for the control
814 Besides some administrative work (such as caring for <member>m_eControlValueChangeInstigator</member>),
815 this method simply calls <member>doSetControlValue</member>.
817 @precond
818 Our own mutex is locked.
819 @param _rValue
820 The value to set. This value is guaranteed to be created by
821 <member>translateDbColumnToControlValue</member> or
822 <member>translateExternalValueToControlValue</member>
823 @param _eInstigator
824 the instigator of the value change
826 void setControlValue(
827 const css::uno::Any& _rValue,
828 ValueChangeInstigator _eInstigator
831 <p>The default implementation will forward the given value to the aggregate, using
832 m_nValuePropertyAggregateHandle and/or m_sValuePropertyName.</p>
834 @precond
835 Our own mutex is locked.
836 @param _rValue
837 The value to set. This value is guaranteed to be created by
838 <member>translateDbColumnToControlValue</member> or
839 <member>translateExternalValueToControlValue</member>
841 virtual void doSetControlValue(
842 const css::uno::Any& _rValue
845 /** retrieves the current value of the control
847 <p>The default implementation will ask the aggregate for the property value
848 determined by either m_nValuePropertyAggregateHandle and/or m_sValuePropertyName.</p>
850 @precond
851 Our own mutex is locked.
853 virtual css::uno::Any
854 getControlValue( ) const;
856 /** called whenever a connection to a database column has been established
858 virtual void onConnectedDbColumn( const css::uno::Reference< css::uno::XInterface >& _rxForm );
859 /** called whenever a connection to a database column has been suspended
861 virtual void onDisconnectedDbColumn();
863 /** called whenever a connection to an external supplier of values (XValueBinding) has been established
864 @see m_xExternalBinding
866 virtual void onConnectedExternalValue( );
868 /** called whenever an external validator has been registered
870 void onConnectedValidator( );
871 /** called whenever an external validator has been revoked
873 void onDisconnectedValidator( );
875 /** nFieldType is the type of the field, on which the model will be linked.
876 The linking happens when sal_True is returned.
877 The default-implementation allows everything but the three binary types
878 and FieldType_OTHER.
880 virtual bool approveDbColumnType(sal_Int32 _nColumnType);
882 /** retrieves the current value of the control, in a shape which can be used with our
883 external validator.
885 The default implementation simply calls <member>>translateControlValueToExternalValue</member>.
887 @precond
888 Our own mutex is locked.
890 virtual css::uno::Any
891 translateControlValueToValidatableValue( ) const;
893 /** retrieves the current value of the form component
895 This is the implementation method for XValidatableFormComponent::getCurrentValue. The default implementation
896 calls translateControlValueToValidatableValue if a validator is present, otherwise getControlValue.
898 @precond
899 our mutex is locked when this method is called
901 virtual css::uno::Any
902 getCurrentFormComponentValue() const;
904 /** We can't write (new) common properties in this base class, as the file format doesn't allow this
905 (unfortunately). So derived classes may use the following two methods. They secure the written
906 data with marks, so any new common properties in newer versions will be skipped by older ones.
908 void writeCommonProperties(const css::uno::Reference< css::io::XObjectOutputStream>& _rxOutStream);
909 void readCommonProperties(const css::uno::Reference< css::io::XObjectInputStream>& _rxInStream);
910 // the next method may be used in derived classes's read when an unknown version is encountered
911 void defaultCommonProperties();
913 /** called to reset the control to some kind of default.
915 <p>The semantics of "default" is finally defined by the derived class (in particular,
916 by <member>getDefaultForReset</member>).</p>
918 <p>No listener notification needs to be done in the derived class.</p>
920 <p>Normally, you won't override this method, but <member>getDefaultForReset</member> instead.</p>
922 @see getDefaultForReset
924 virtual void resetNoBroadcast();
926 virtual css::uno::Sequence< css::uno::Type> _getTypes() override;
928 /// sets m_xField to the given new value, without notifying our listeners
929 void impl_setField_noNotify(
930 const css::uno::Reference< css::beans::XPropertySet>& _rxField
932 bool hasField() const
934 return m_xField.is();
936 sal_Int32 getFieldType() const
938 return m_nFieldType;
941 // OControlModel's property handling
942 virtual void describeFixedProperties(
943 css::uno::Sequence< css::beans::Property >& /* [out] */ _rProps
944 ) const override;
946 public:
947 const css::uno::Reference< css::beans::XPropertySet>& getField() const
949 return m_xField;
952 public:
953 // UNO link
954 DECLARE_UNO3_AGG_DEFAULTS(OBoundControlModel, OControlModel)
955 virtual css::uno::Any SAL_CALL queryAggregation( const css::uno::Type& _rType ) override;
957 // OComponentHelper
958 virtual void SAL_CALL disposing() override;
960 // XReset
961 virtual void SAL_CALL reset( ) override;
962 virtual void SAL_CALL addResetListener( const css::uno::Reference< css::form::XResetListener >& aListener ) override;
963 virtual void SAL_CALL removeResetListener( const css::uno::Reference< css::form::XResetListener >& aListener ) override;
965 // XServiceInfo
966 virtual css::uno::Sequence<OUString> SAL_CALL getSupportedServiceNames( ) override;
968 // XServiceInfo - static version
969 /// @throws css::uno::RuntimeException
970 static css::uno::Sequence<OUString> getSupportedServiceNames_Static();
972 // XChild
973 virtual void SAL_CALL setParent( const css::uno::Reference< css::uno::XInterface >& Parent ) override;
975 // XPersistObject
976 virtual void SAL_CALL write( const css::uno::Reference< css::io::XObjectOutputStream >& OutStream ) override;
977 virtual void SAL_CALL read( const css::uno::Reference< css::io::XObjectInputStream >& InStream ) override;
979 // XBoundComponent
980 virtual sal_Bool SAL_CALL commit() override;
982 // XUpdateBroadcaster (base of XBoundComponent)
983 virtual void SAL_CALL addUpdateListener( const css::uno::Reference< css::form::XUpdateListener >& aListener ) override;
984 virtual void SAL_CALL removeUpdateListener( const css::uno::Reference< css::form::XUpdateListener >& aListener ) override;
986 // XPropertySet
987 virtual void SAL_CALL getFastPropertyValue(css::uno::Any& rValue, sal_Int32 nHandle) const override;
988 virtual sal_Bool SAL_CALL convertFastPropertyValue(
989 css::uno::Any& _rConvertedValue, css::uno::Any& _rOldValue, sal_Int32 _nHandle, const css::uno::Any& _rValue ) override;
990 virtual void SAL_CALL setFastPropertyValue_NoBroadcast( sal_Int32 nHandle, const css::uno::Any& rValue ) override;
991 using ::cppu::OPropertySetHelper::getFastPropertyValue;
993 // css::beans::XPropertyState
994 virtual css::uno::Any getPropertyDefaultByHandle( sal_Int32 nHandle ) const override;
996 // XEventListener
997 virtual void SAL_CALL disposing(const css::lang::EventObject& Source) override;
999 // XPropertyChangeListener
1000 virtual void SAL_CALL propertyChange( const css::beans::PropertyChangeEvent& evt ) override;
1002 // XRowSetChangeListener
1003 virtual void SAL_CALL onRowSetChanged( const css::lang::EventObject& i_Event ) override;
1005 // XLoadListener
1006 virtual void SAL_CALL loaded( const css::lang::EventObject& aEvent ) override;
1007 virtual void SAL_CALL unloading( const css::lang::EventObject& aEvent ) override;
1008 virtual void SAL_CALL unloaded( const css::lang::EventObject& aEvent ) override;
1009 virtual void SAL_CALL reloading( const css::lang::EventObject& aEvent ) override;
1010 virtual void SAL_CALL reloaded( const css::lang::EventObject& aEvent ) override;
1012 protected:
1013 // XBindableValue
1014 virtual void SAL_CALL setValueBinding( const css::uno::Reference< css::form::binding::XValueBinding >& _rxBinding ) override;
1015 virtual css::uno::Reference< css::form::binding::XValueBinding > SAL_CALL getValueBinding( ) override;
1017 // XModifyListener
1018 virtual void SAL_CALL modified( const css::lang::EventObject& _rEvent ) override;
1020 // XValidatable
1021 virtual void SAL_CALL setValidator( const css::uno::Reference< css::form::validation::XValidator >& Validator ) override;
1022 virtual css::uno::Reference< css::form::validation::XValidator > SAL_CALL getValidator( ) override;
1024 // XValidityConstraintListener
1025 virtual void SAL_CALL validityConstraintChanged( const css::lang::EventObject& Source ) override;
1027 // XValidatableFormComponent
1028 virtual sal_Bool SAL_CALL isValid( ) override;
1029 virtual css::uno::Any SAL_CALL getCurrentValue( ) override;
1030 virtual void SAL_CALL addFormComponentValidityListener( const css::uno::Reference< css::form::validation::XFormComponentValidityListener >& Listener ) override;
1031 virtual void SAL_CALL removeFormComponentValidityListener( const css::uno::Reference< css::form::validation::XFormComponentValidityListener >& Listener ) override;
1033 protected:
1034 // OPropertyChangeListener
1035 virtual void
1036 _propertyChanged( const css::beans::PropertyChangeEvent& _rEvt ) override;
1038 /// checks whether we currently have an external value binding in place
1039 bool hasExternalValueBinding() const { return m_xExternalBinding.is(); }
1041 // checks whether we currently have an external validator
1042 bool hasValidator() const { return m_xValidator.is(); }
1044 /** transfers the very current value of the db column we're bound to the control
1045 @precond
1046 our own mutex is locked
1047 @precond
1048 we don't have an external binding in place
1050 void transferDbValueToControl( );
1052 /** transfers the current value of the active external binding to the control
1053 @precond
1054 we do have an active external binding in place
1056 void transferExternalValueToControl( ControlModelLock& _rInstanceLock );
1058 /** transfers the control value to the external binding
1059 @precond
1060 our own mutex is locked, and _rInstanceLock is the guard locking it
1061 @precond
1062 we do have an active external binding in place
1064 void transferControlValueToExternal( ControlModelLock& _rInstanceLock );
1066 /** calculates the type which is to be used to communicate with the current external binding,
1067 and stores it in m_aExternalValueType
1069 The method checks the possible type candidates as returned by getSupportedBindingTypes,
1070 and the types supported by the current external binding, if any.
1072 void calculateExternalValueType();
1074 /** returns the type which should be used to exchange data with our external value binding
1076 @see initValueProperty
1078 const css::uno::Type&
1079 getExternalValueType() const { return m_aExternalValueType; }
1081 /** initializes the control from m_xField
1083 Basically, this method calls transferDbValueToControl - but only if our cursor is positioned
1084 on a valid row. Otherwise, the control is reset.
1086 @precond
1087 m_xField is not <NULL/>
1089 void initFromField( const css::uno::Reference< css::sdbc::XRowSet>& _rxForm );
1091 private:
1092 void connectToField( const css::uno::Reference< css::sdbc::XRowSet>& _rxForm );
1093 void resetField();
1095 /** does a new validation of the control value
1097 If necessary, our <member>m_bIsCurrentValueValid</member> member will be adjusted,
1098 and changes will be notified.
1100 Note that it's not necessary that we're connected to a validator. If we are not,
1101 it's assumed that our value is valid, and this is handled appropriately.
1103 Use this method if there is a potential that <b>only</b> the validity flag changed. If
1104 any of the other aspects (our current value, or our current text) changed, then
1105 pass <TRUE/> for <member>_bForceNotification</member>.
1107 @param _bForceNotification
1108 if <TRUE/>, then the validity listeners will be notified, not matter whether the validity
1109 changed.
1111 void recheckValidity( bool _bForceNotification );
1113 /// initializes m_pAggPropMultiplexer
1114 void implInitAggMultiplexer( );
1116 /// initializes listening at the value property
1117 void implInitValuePropertyListening( ) const;
1119 /** adds or removes the component as load listener to/from our form, and (if necessary) as RowSetChange listener at
1120 our parent.
1122 @precond there must no external value binding be in place
1124 void doFormListening( const bool _bStart );
1126 bool isFormListening() const { return m_bFormListening; }
1128 /** determines the new value of m_xAmbientForm
1130 void impl_determineAmbientForm_nothrow();
1132 /** connects to a value supplier which is a database column.
1134 The column is taken from our parent, which must be a database form respectively row set.
1136 @precond The control does not have an external value supplier
1138 @param _bFromReload
1139 Determines whether the connection is made after the row set has been loaded (<FALSE/>)
1140 or reloaded (<TRUE/>)
1142 @see impl_disconnectDatabaseColumn_noNotify
1144 void impl_connectDatabaseColumn_noNotify(
1145 bool _bFromReload
1148 /** disconnects from a value supplier which is a database column
1150 @precond The control does not have an external value supplier
1151 @see impl_connectDatabaseColumn_noNotify
1153 void impl_disconnectDatabaseColumn_noNotify();
1155 /** connects to an external value binding
1157 <p>Note that by definition, external data bindings supersede the SQL data binding which
1158 is defined by our RowSet-column-related properties. This means that in case we're currently
1159 connected to a database column when this is called, this connection is suspended.</p>
1161 @precond
1162 the new external binding has already been approved (see <member>impl_approveValueBinding_nolock</member>)
1163 @precond
1164 there currently is no external binding in place
1166 void connectExternalValueBinding(
1167 const css::uno::Reference< css::form::binding::XValueBinding >& _rxBinding,
1168 ControlModelLock& _rInstanceLock
1171 /** disconnects from an external value binding
1173 @precond
1174 there currently is an external binding in place
1176 void disconnectExternalValueBinding( );
1178 /** connects the component to an external validator
1180 @precond
1181 there currently is no active validator
1182 @precond
1183 our mutex is currently locked exactly once
1185 void connectValidator(
1186 const css::uno::Reference< css::form::validation::XValidator >& _rxValidator
1189 /** disconnects the component from its current an external validator
1191 @precond
1192 there currently is an active validator
1193 @precond
1194 our mutex is currently locked exactly once
1196 void disconnectValidator( );
1198 /** called from within <member scope="css:::form::binding">XBindableValue::setValueBinding</member>
1199 to approve the new binding
1201 The default implementation approves the binding if and only if it is not <NULL/>, and supports
1202 the type returned by getExternalValueType.
1204 @param _rxBinding
1205 the binding which applies for being responsible for our value, Must not be
1206 <NULL/>
1207 @return
1208 <TRUE/> if and only if the given binding can supply values in the proper type
1210 @seealso getExternalValueType
1212 bool impl_approveValueBinding_nolock(
1213 const css::uno::Reference< css::form::binding::XValueBinding >& _rxBinding
1218 //= inlines
1220 inline void ControlModelLock::acquire()
1222 m_rModel.lockInstance( OControlModel::LockAccess() );
1223 m_bLocked = true;
1225 inline void ControlModelLock::release()
1227 OSL_ENSURE( m_bLocked, "ControlModelLock::release: not locked!" );
1228 m_bLocked = false;
1230 if ( 0 == m_rModel.unlockInstance( OControlModel::LockAccess() ) )
1231 impl_notifyAll_nothrow();
1238 #endif // INCLUDED_FORMS_SOURCE_INC_FORMCOMPONENT_HXX
1240 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */