bump product version to 6.4.3.1
[LibreOffice.git] / forms / source / inc / FormComponent.hxx
blob66ec3aed8aff463911925241fc6fea91879a76e7
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 "property.hxx"
25 #include "propertybaghelper.hxx"
26 #include "resettable.hxx"
27 #include "services.hxx"
28 #include "windowstateguard.hxx"
30 #include <com/sun/star/awt/XControl.hpp>
31 #include <com/sun/star/beans/XPropertyAccess.hpp>
32 #include <com/sun/star/beans/XPropertyContainer.hpp>
33 #include <com/sun/star/container/XChild.hpp>
34 #include <com/sun/star/container/XNamed.hpp>
35 #include <com/sun/star/form/binding/XBindableValue.hpp>
36 #include <com/sun/star/form/FormComponentType.hpp>
37 #include <com/sun/star/form/validation/XValidatableFormComponent.hpp>
38 #include <com/sun/star/form/validation/XValidityConstraintListener.hpp>
39 #include <com/sun/star/form/XBoundComponent.hpp>
40 #include <com/sun/star/form/XBoundControl.hpp>
41 #include <com/sun/star/form/XFormComponent.hpp>
42 #include <com/sun/star/form/XLoadListener.hpp>
43 #include <com/sun/star/form/XReset.hpp>
44 #include <com/sun/star/io/XMarkableStream.hpp>
45 #include <com/sun/star/io/XPersistObject.hpp>
46 #include <com/sun/star/lang/DisposedException.hpp>
47 #include <com/sun/star/lang/XEventListener.hpp>
48 #include <com/sun/star/lang/XMultiServiceFactory.hpp>
49 #include <com/sun/star/lang/XServiceInfo.hpp>
50 #include <com/sun/star/sdb/XColumn.hpp>
51 #include <com/sun/star/sdb/XColumnUpdate.hpp>
52 #include <com/sun/star/sdb/XRowSetChangeListener.hpp>
53 #include <com/sun/star/sdbc/XRowSet.hpp>
54 #include <com/sun/star/sdbcx/XColumnsSupplier.hpp>
55 #include <com/sun/star/uno/XAggregation.hpp>
56 #include <com/sun/star/uno/XComponentContext.hpp>
57 #include <com/sun/star/util/XCloneable.hpp>
58 #include <com/sun/star/util/XModifyListener.hpp>
59 #include <com/sun/star/form/XLoadable.hpp>
61 #include <comphelper/propagg.hxx>
62 #include <comphelper/propertybag.hxx>
63 #include <comphelper/propmultiplex.hxx>
64 #include <comphelper/uno3.hxx>
65 #include <cppuhelper/component.hxx>
66 #include <cppuhelper/implbase1.hxx>
67 #include <cppuhelper/implbase2.hxx>
68 #include <cppuhelper/implbase3.hxx>
69 #include <cppuhelper/implbase4.hxx>
70 #include <cppuhelper/implbase7.hxx>
71 #include <osl/mutex.hxx>
72 #include <rtl/ustring.hxx>
75 namespace frm
79 // default tab index for components
80 const sal_Int16 FRM_DEFAULT_TABINDEX = 0;
82 // macros for quickly declaring/implementing XServiceInfo
83 #define DECLARE_XPERSISTOBJECT() \
84 virtual OUString SAL_CALL getServiceName() override; \
85 virtual void SAL_CALL write(const css::uno::Reference< css::io::XObjectOutputStream>& _rxOutStream) override; \
86 virtual void SAL_CALL read(const css::uno::Reference< css::io::XObjectInputStream>& _rxInStream) override;
88 class OControlModel;
91 //= ControlModelLock
93 /** class whose instances lock an OControlModel
95 Locking here merely means locking the OControlModel's mutex.
97 In addition to the locking facility, the class is also able to fire property
98 change notifications. This happens when the last ControlModelLock instance on a stack
99 dies.
101 class ControlModelLock
103 public:
104 ControlModelLock( OControlModel& _rModel )
105 :m_rModel( _rModel )
106 ,m_bLocked( false )
108 acquire();
111 ~ControlModelLock()
113 if ( m_bLocked )
114 release();
116 inline void acquire();
117 inline void release();
119 OControlModel& getModel() const { return m_rModel; };
121 /** adds a property change notification, which is to be fired when the last lock on the model
122 (in the current thread) is released.
124 void addPropertyNotification(
125 const sal_Int32 _nHandle,
126 const css::uno::Any& _rOldValue,
127 const css::uno::Any& _rNewValue
130 private:
131 void impl_notifyAll_nothrow();
133 OControlModel& m_rModel;
134 bool m_bLocked;
135 std::vector< sal_Int32 > m_aHandles;
136 std::vector< css::uno::Any > m_aOldValues;
137 std::vector< css::uno::Any > m_aNewValues;
139 ControlModelLock( const ControlModelLock& ) = delete;
140 ControlModelLock& operator=( const ControlModelLock& ) = delete;
144 //= OControl
145 //= base class for form layer controls
147 typedef ::cppu::ImplHelper3 < css::awt::XControl
148 , css::lang::XEventListener
149 , css::lang::XServiceInfo
150 > OControl_BASE;
152 class OControl :public ::cppu::OComponentHelper
153 ,public OControl_BASE
155 protected:
156 ::osl::Mutex m_aMutex;
157 css::uno::Reference< css::awt::XControl > m_xControl;
158 css::uno::Reference< css::uno::XAggregation>
159 m_xAggregate;
161 css::uno::Reference< css::uno::XComponentContext >
162 m_xContext;
163 WindowStateGuard m_aWindowStateGuard;
165 public:
166 /** constructs a control
168 @param _rFactory
169 the service factory for this control
170 @param _rAggregateService
171 the service name of the component to aggregate
172 @param _bSetDelegator
173 set this to <FALSE/> if you don't want the constructor to set the delegator at
174 the aggregate. In this case, you <em>have</em> to call doSetDelegator within your
175 own constructor.
177 This is helpful, if your derived class wants to cache an interface of the aggregate.
178 In this case, the aggregate needs to be queried for this interface <b>before</b> the
179 <member scope="css::uno">XAggregation::setDelegator</member> call.
181 In such a case, pass <FALSE/> to this parameter. Then, cache the aggregate's interface(s)
182 as needed. Afterwards, call <member>doSetDelegator</member>.
184 In your destructor, you need to call <member>doResetDelegator</member> before
185 resetting the cached interfaces. This will reset the aggregates delegator to <NULL/>,
186 which will ensure that the <member scope="css::uno">XInterface::release</member>
187 calls on the cached interfaces are really applied to the aggregate, instead of
188 the <type>OControl</type> itself.
190 OControl(
191 const css::uno::Reference< css::uno::XComponentContext >& _rFactory,
192 const OUString& _rAggregateService,
193 const bool _bSetDelegator = true
196 protected:
197 virtual ~OControl() override;
199 /** sets the control as delegator at the aggregate
201 This has to be called from within your derived class' constructor, if and only
202 if you passed <FALSE/> to the <arg>_bSetDelegator</arg> parameter of the
203 <type>OControl</type> constructor.
205 void doSetDelegator();
206 void doResetDelegator();
208 // UNO
209 DECLARE_UNO3_AGG_DEFAULTS(OControl, OComponentHelper)
210 virtual css::uno::Any SAL_CALL queryAggregation( const css::uno::Type& _rType ) override;
212 // XTypeProvider
213 virtual css::uno::Sequence<sal_Int8> SAL_CALL getImplementationId() override;
214 virtual css::uno::Sequence< css::uno::Type> SAL_CALL getTypes() override;
216 // OComponentHelper
217 virtual void SAL_CALL disposing() override;
219 // XComponent (as base of XControl)
220 virtual void SAL_CALL dispose( ) override
221 { OComponentHelper::dispose(); }
222 virtual void SAL_CALL addEventListener( const css::uno::Reference< css::lang::XEventListener>& _rxListener) override
223 { OComponentHelper::addEventListener(_rxListener); }
224 virtual void SAL_CALL removeEventListener( const css::uno::Reference< css::lang::XEventListener>& _rxListener) override
225 { OComponentHelper::removeEventListener(_rxListener); }
227 // XEventListener
228 virtual void SAL_CALL disposing(const css::lang::EventObject& Source) override;
230 // XServiceInfo
231 virtual sal_Bool SAL_CALL supportsService(const OUString& ServiceName) override;
232 virtual css::uno::Sequence<OUString> SAL_CALL getSupportedServiceNames() override;
233 virtual OUString SAL_CALL getImplementationName() override = 0;
235 // XControl
236 virtual void SAL_CALL setContext(const css::uno::Reference<css::uno::XInterface>& Context) override;
237 virtual css::uno::Reference<css::uno::XInterface> SAL_CALL getContext() override;
238 virtual void SAL_CALL createPeer(const css::uno::Reference<css::awt::XToolkit>& Toolkit, const css::uno::Reference<css::awt::XWindowPeer>& Parent) override;
239 virtual css::uno::Reference<css::awt::XWindowPeer> SAL_CALL getPeer() override;
240 virtual sal_Bool SAL_CALL setModel(const css::uno::Reference<css::awt::XControlModel>& Model) override;
241 virtual css::uno::Reference<css::awt::XControlModel> SAL_CALL getModel() override;
242 virtual css::uno::Reference<css::awt::XView> SAL_CALL getView() override;
243 virtual void SAL_CALL setDesignMode(sal_Bool bOn) override;
244 virtual sal_Bool SAL_CALL isDesignMode() override;
245 virtual sal_Bool SAL_CALL isTransparent() override;
247 protected:
248 virtual css::uno::Sequence< css::uno::Type> _getTypes();
249 // overwrite this and call the base class if you have additional types
251 css::uno::Sequence< OUString > getAggregateServiceNames() const;
253 private:
254 void impl_resetStateGuard_nothrow();
257 // a form control implementing the XBoundControl interface
258 typedef ::cppu::ImplHelper1 < css::form::XBoundControl
259 > OBoundControl_BASE;
260 class OBoundControl :public OControl
261 ,public OBoundControl_BASE
263 bool m_bLocked : 1;
265 public:
266 OBoundControl(
267 const css::uno::Reference< css::uno::XComponentContext >& _rxContext,
268 const OUString& _rAggregateService,
269 const bool _bSetDelegator = true
272 virtual ~OBoundControl() override;
274 DECLARE_UNO3_AGG_DEFAULTS(OBoundControl, OControl)
275 virtual css::uno::Any SAL_CALL queryAggregation( const css::uno::Type& _rType ) override;
277 // XBoundControl
278 virtual sal_Bool SAL_CALL getLock() override;
279 virtual void SAL_CALL setLock(sal_Bool _bLock) override;
280 // default implementation just disables the controls, overwrite _setLock to change this behaviour
282 // XControl
283 virtual sal_Bool SAL_CALL setModel(const css::uno::Reference< css::awt::XControlModel >& Model) override;
285 // XEventListener
286 virtual void SAL_CALL disposing(const css::lang::EventObject& Source) override;
288 // OComponentHelper
289 virtual void SAL_CALL disposing() override;
291 protected:
292 virtual css::uno::Sequence< css::uno::Type> _getTypes() override;
293 // implement the lock setting
294 void _setLock(bool _bLock);
298 //= OControlModel
299 //= model of a form layer control
301 //added for exporting OCX control
302 #define INVALID_OBJ_ID_IN_MSO 0xFFFF
304 typedef ::cppu::ImplHelper7 < css::form::XFormComponent
305 , css::io::XPersistObject
306 , css::container::XNamed
307 , css::lang::XServiceInfo
308 , css::util::XCloneable
309 , css::beans::XPropertyContainer
310 , css::beans::XPropertyAccess
311 > OControlModel_BASE;
313 class OControlModel :public ::cppu::OComponentHelper
314 ,public OPropertySetAggregationHelper
315 ,public OControlModel_BASE
316 ,public OCloneableAggregation
317 ,public IPropertyBagHelperContext
320 protected:
321 css::uno::Reference<css::uno::XComponentContext> m_xContext;
323 ::osl::Mutex m_aMutex;
324 oslInterlockedCount m_lockCount;
326 css::uno::Reference<css::uno::XInterface> m_xParent; // ParentComponent
327 PropertyBagHelper m_aPropertyBagHelper;
329 const css::uno::Reference<css::uno::XComponentContext>&
330 getContext() const { return m_xContext; }
332 // <properties>
333 OUString m_aName; // name of the control
334 OUString m_aTag; // tag for additional data
335 sal_Int16 m_nTabIndex; // index within the taborder
336 sal_Int16 m_nClassId; // type of the control
337 bool m_bNativeLook; // should the control use the native platform look?
338 bool m_bGenerateVbEvents; // should the control generate fake vba events
339 //added for exporting OCX control
340 sal_Int16 m_nControlTypeinMSO; //keep the MS office control type for exporting to MS binarary file
341 sal_uInt16 m_nObjIDinMSO; //keep the OCX control obj id for exporting to MS binarary file
342 // </properties>
345 protected:
346 OControlModel(
347 const css::uno::Reference< css::uno::XComponentContext>& _rFactory, // factory to create the aggregate with
348 const OUString& _rUnoControlModelTypeName, // service name of te model to aggregate
349 const OUString& rDefault = OUString(), // service name of the default control
350 const bool _bSetDelegator = true // set to sal_False if you want to call setDelegator later (after returning from this ctor)
352 OControlModel(
353 const OControlModel* _pOriginal, // the original object to clone
354 const css::uno::Reference< css::uno::XComponentContext>& _rFactory, // factory to create the aggregate with
355 const bool _bCloneAggregate = true, // should the aggregate of the original be cloned, too?
356 const bool _bSetDelegator = true // set to sal_False if you want to call setDelegator later (after returning from this ctor)
358 virtual ~OControlModel() override;
360 /** to be called after an OBoundControlModel (a derivee, respectively) has been cloned
362 <p>This method contains late initializations which cannot be done in the
363 constructor of this base class, since the virtual method of derived classes do
364 not yet work there.</p>
366 virtual void clonedFrom( const OControlModel* _pOriginal );
368 using OComponentHelper::rBHelper;
370 virtual css::uno::Sequence< css::uno::Type> _getTypes();
372 void readHelpTextCompatibly(const css::uno::Reference< css::io::XObjectInputStream >& _rxInStream);
373 void writeHelpTextCompatibly(const css::uno::Reference< css::io::XObjectOutputStream >& _rxOutStream);
375 void doSetDelegator();
376 void doResetDelegator();
378 css::uno::Sequence< OUString > getAggregateServiceNames() const;
380 public:
381 DECLARE_UNO3_AGG_DEFAULTS(OControl, OComponentHelper)
382 virtual css::uno::Any SAL_CALL queryAggregation( const css::uno::Type& _rType ) override;
384 // XTypeProvider
385 virtual css::uno::Sequence<sal_Int8> SAL_CALL getImplementationId() override;
386 virtual css::uno::Sequence< css::uno::Type> SAL_CALL getTypes() override;
388 // OComponentHelper
389 virtual void SAL_CALL disposing() override;
391 // XNamed
392 virtual OUString SAL_CALL getName() override;
393 virtual void SAL_CALL setName(const OUString& aName) override;
395 // XServiceInfo
396 virtual sal_Bool SAL_CALL supportsService(const OUString& ServiceName) override;
397 virtual css::uno::Sequence<OUString> SAL_CALL getSupportedServiceNames() override;
398 virtual OUString SAL_CALL getImplementationName() override = 0;
400 // XServiceInfo - static version(s)
401 /// @throws css::uno::RuntimeException
402 static css::uno::Sequence<OUString> getSupportedServiceNames_Static();
404 // XPersistObject
405 virtual OUString SAL_CALL getServiceName() override = 0;
406 virtual void SAL_CALL
407 write(const css::uno::Reference< css::io::XObjectOutputStream>& _rxOutStream) override;
408 virtual void SAL_CALL
409 read(const css::uno::Reference< css::io::XObjectInputStream>& _rxInStream) override;
411 // XChild (base of XFormComponent)
412 virtual css::uno::Reference<css::uno::XInterface> SAL_CALL getParent() override;
413 virtual void SAL_CALL setParent(const css::uno::Reference<css::uno::XInterface>& Parent) override;
415 // XEventListener
416 virtual void SAL_CALL disposing(const css::lang::EventObject& Source) override;
418 // XPropertySet
419 virtual void SAL_CALL getFastPropertyValue(css::uno::Any& rValue, sal_Int32 nHandle) const override;
420 virtual sal_Bool SAL_CALL convertFastPropertyValue(
421 css::uno::Any& _rConvertedValue, css::uno::Any& _rOldValue, sal_Int32 _nHandle, const css::uno::Any& _rValue ) override;
422 virtual void SAL_CALL setFastPropertyValue_NoBroadcast( sal_Int32 nHandle, const css::uno::Any& rValue ) override;
423 using ::cppu::OPropertySetHelper::getFastPropertyValue;
425 // css::beans::XPropertyState
426 virtual css::beans::PropertyState getPropertyStateByHandle(sal_Int32 nHandle) override;
427 virtual void setPropertyToDefaultByHandle(sal_Int32 nHandle) override;
428 virtual css::uno::Any getPropertyDefaultByHandle( sal_Int32 nHandle ) const override;
430 // XCloneable
431 virtual css::uno::Reference< css::util::XCloneable > SAL_CALL createClone( ) override = 0;
433 // XPropertyContainer
434 virtual void SAL_CALL addProperty( const OUString& Name, ::sal_Int16 Attributes, const css::uno::Any& DefaultValue ) override;
435 virtual void SAL_CALL removeProperty( const OUString& Name ) override;
437 // XPropertyAccess
438 virtual css::uno::Sequence< css::beans::PropertyValue > SAL_CALL getPropertyValues( ) override;
439 virtual void SAL_CALL setPropertyValues( const css::uno::Sequence< css::beans::PropertyValue >& aProps ) override;
441 protected:
442 using OPropertySetAggregationHelper::setPropertyValues;
443 using OPropertySetAggregationHelper::getPropertyValues;
445 protected:
446 virtual void writeAggregate( const css::uno::Reference< css::io::XObjectOutputStream >& _rxOutStream ) const;
447 virtual void readAggregate( const css::uno::Reference< css::io::XObjectInputStream >& _rxInStream );
449 protected:
450 // XPropertySet
451 virtual css::uno::Reference< css::beans::XPropertySetInfo> SAL_CALL getPropertySetInfo() override;
452 // OPropertySetHelper
453 virtual cppu::IPropertyArrayHelper& SAL_CALL getInfoHelper() override;
455 /** describes the properties provided by this class, or its respective
456 derived class
458 Derived classes usually call the base class first, and then append own properties.
460 virtual void describeFixedProperties(
461 css::uno::Sequence< css::beans::Property >& /* [out] */ _rProps
462 ) const;
464 // IPropertyBagHelperContext
465 virtual ::osl::Mutex& getMutex() override;
466 virtual void describeFixedAndAggregateProperties(
467 css::uno::Sequence< css::beans::Property >& _out_rFixedProperties,
468 css::uno::Sequence< css::beans::Property >& _out_rAggregateProperties
469 ) const override;
470 virtual css::uno::Reference< css::beans::XMultiPropertySet >
471 getPropertiesInterface() override;
473 /** describes the properties of our aggregate
475 The default implementation simply asks m_xAggregateSet for its properties.
477 You usually only need to override this method if you want to filter the
478 aggregate properties.
480 virtual void describeAggregateProperties(
481 css::uno::Sequence< css::beans::Property >& /* [out] */ _rAggregateProps
482 ) const;
484 public:
485 struct LockAccess { friend class ControlModelLock; private: LockAccess() { } };
487 void lockInstance( LockAccess );
488 oslInterlockedCount unlockInstance( LockAccess );
490 void firePropertyChanges(
491 const std::vector< sal_Int32 >& _rHandles,
492 const std::vector< css::uno::Any >& _rOldValues,
493 const std::vector< css::uno::Any >& _rNewValues,
494 LockAccess
497 ::osl::Mutex&
498 getInstanceMutex() { return m_aMutex; }
501 // constructor for cloning a class
502 #define DECLARE_DEFAULT_CLONE_CTOR( classname ) \
503 classname( \
504 const classname* _pOriginal, \
505 const css::uno::Reference< css::uno::XComponentContext>& _rxFactory \
506 ); \
508 // all xtors for a leaf class of the object hierarchy
509 #define DECLARE_DEFAULT_LEAF_XTOR( classname ) \
510 classname( \
511 const css::uno::Reference< css::uno::XComponentContext>& _rxFactory \
512 ); \
513 classname( \
514 const classname* _pOriginal, \
515 const css::uno::Reference< css::uno::XComponentContext>& _rxFactory \
516 ); \
517 virtual ~classname() override \
520 #define IMPLEMENT_DEFAULT_CLONING( classname ) \
521 css::uno::Reference< css::util::XCloneable > SAL_CALL classname::createClone( ) \
523 classname* pClone = new classname( this, getContext() ); \
524 pClone->clonedFrom( this ); \
525 return pClone; \
529 //= OBoundControlModel
530 //= model of a form layer control which is bound to a data source field
532 typedef ::cppu::ImplHelper4 < css::form::XLoadListener
533 , css::form::XReset
534 , css::beans::XPropertyChangeListener
535 , css::sdb::XRowSetChangeListener
536 > OBoundControlModel_BASE1;
538 // separated into an own base class since derivees can disable the support for this
539 // interface, thus we want to easily exclude it in the queryInterface and getTypes
540 typedef ::cppu::ImplHelper1 < css::form::XBoundComponent
541 > OBoundControlModel_COMMITTING;
543 // dito
544 typedef ::cppu::ImplHelper2 < css::form::binding::XBindableValue
545 , css::util::XModifyListener
546 > OBoundControlModel_BINDING;
548 // dito
549 typedef ::cppu::ImplHelper2 < css::form::validation::XValidityConstraintListener
550 , css::form::validation::XValidatableFormComponent
551 > OBoundControlModel_VALIDATION;
553 class OBoundControlModel :public OControlModel
554 ,public OBoundControlModel_BASE1
555 ,public OBoundControlModel_COMMITTING
556 ,public OBoundControlModel_BINDING
557 ,public OBoundControlModel_VALIDATION
558 ,public ::comphelper::OPropertyChangeListener
560 protected:
561 enum ValueChangeInstigator
563 eDbColumnBinding,
564 eExternalBinding,
565 eOther
568 private:
569 css::uno::Reference< css::beans::XPropertySet >
570 m_xField;
571 // the form which controls supplies the field we bind to.
572 css::uno::Reference< css::form::XLoadable >
573 m_xAmbientForm;
575 OUString m_sValuePropertyName;
576 sal_Int32 m_nValuePropertyAggregateHandle;
577 sal_Int32 m_nFieldType;
578 css::uno::Type m_aValuePropertyType;
579 bool m_bValuePropertyMayBeVoid;
581 ResetHelper m_aResetHelper;
582 ::comphelper::OInterfaceContainerHelper2 m_aUpdateListeners;
583 ::comphelper::OInterfaceContainerHelper2 m_aFormComponentListeners;
585 css::uno::Reference< css::form::binding::XValueBinding >
586 m_xExternalBinding;
587 css::uno::Reference< css::form::validation::XValidator >
588 m_xValidator;
589 css::uno::Type m_aExternalValueType;
591 // <properties>
592 OUString m_aControlSource; // data source, name of the field
593 css::uno::Reference< css::beans::XPropertySet >
594 m_xLabelControl; // reference to a sibling control (model) which is our label
595 bool m_bInputRequired;
596 // </properties>
598 ::comphelper::OPropertyChangeMultiplexer*
599 m_pAggPropMultiplexer;
601 bool m_bFormListening : 1; // are we currently a XLoadListener at our ambient form?
602 bool m_bLoaded : 1;
603 bool m_bRequired : 1;
604 const bool m_bCommitable : 1; // do we support XBoundComponent?
605 const bool m_bSupportsExternalBinding : 1; // do we support XBindableValue?
606 const bool m_bSupportsValidation : 1; // do we support XValidatable?
607 bool m_bForwardValueChanges : 1; // do we currently handle changes in the bound database field?
608 bool m_bTransferingValue : 1; // true if we're currently transferring our value to an external binding
609 bool m_bIsCurrentValueValid : 1; // flag specifying whether our current value is valid, relative to our external validator
610 bool m_bBindingControlsRO : 1; // is our ReadOnly property currently controlled by our external binding?
611 bool m_bBindingControlsEnable : 1; // is our Enabled property currently controlled by our external binding?
613 ValueChangeInstigator m_eControlValueChangeInstigator;
615 protected:
616 OUString m_aLabelServiceName;
617 // when setting the label for our control (property FM_PROP_CONTROLLABEL, member m_xLabelControl),
618 // we accept only objects supporting an XControlModel interface, an XServiceInfo interface and
619 // support for a service (XServiceInfo::supportsService) determined by this string.
620 // Any other arguments will throw an IllegalArgumentException.
621 // The default value is FM_COMPONENT_FIXEDTEXT.
623 css::uno::Reference< css::sdbc::XRowSet >
624 m_xCursor;
625 css::uno::Reference< css::sdb::XColumnUpdate >
626 m_xColumnUpdate;
627 css::uno::Reference< css::sdb::XColumn >
628 m_xColumn;
630 protected:
631 sal_Int32 getValuePropertyAggHandle( ) const { return m_nValuePropertyAggregateHandle; }
632 const OUString& getControlSource( ) const { return m_aControlSource; }
633 bool isRequired() const { return m_bRequired; }
634 bool isLoaded() const { return m_bLoaded; }
636 protected:
638 OBoundControlModel(
639 const css::uno::Reference< css::uno::XComponentContext>& _rxContext,
640 // factory to create the aggregate with
641 const OUString& _rUnoControlModelTypeName, // service name of te model to aggregate
642 const OUString& _rDefault, // service name of the default control
643 const bool _bCommitable, // is the control (model) committable?
644 const bool _bSupportExternalBinding, // set to sal_True if you want to support XBindableValue
645 const bool _bSupportsValidation // set to sal_True if you want to support XValidatable
647 OBoundControlModel(
648 const OBoundControlModel* _pOriginal, // the original object to clone
649 const css::uno::Reference< css::uno::XComponentContext>& _rxContext
650 // factory to create the aggregate with
652 virtual ~OBoundControlModel() override;
654 /// late ctor after cloning
655 virtual void clonedFrom( const OControlModel* _pOriginal ) override;
657 /** initializes the part of the class which is related to the control value.
659 <p>Kind of late ctor, to be called for derivees which have a dedicated value property.<br/>
660 The value property is the property which's value is synced with either the database
661 column the object is bound to, or with the external value binding, if present.<br/>
662 E.g. for a text control model, this property will most probably be "Text".</p>
664 <p>Derived classes are strongly recommended to call this method - at least the
665 "DataFieldProperty" (exposed in getFastPropertyValue) relies on the information
666 given herein, and needs to be supplied otherwise else.</p>
668 <p>If this method has been called properly, then <member>setControlValue</member>
669 does not need to be overridden - it will simply set the property value at the
670 aggregate then.</p>
672 @precond
673 The method has not be called before during the life time of the object.
675 @param _rValuePropertyName
676 the name of the value property
677 @param _nValuePropertyExternalHandle
678 the handle of the property, as exposed to external components.<br/>
679 Normally, this information can be obtained dynamically (e.g. from describeFixedProperties),
680 but since this method is to be called from within the constructor of derived classes,
681 we prefer to be on the *really* safe side here...
683 @see setControlValue
684 @see suspendValueListening
685 @see resumeValueListening
686 @see describeFixedProperties
688 void initValueProperty(
689 const OUString& _rValuePropertyName,
690 sal_Int32 _nValuePropertyExternalHandle
693 /** initializes the part of the class which is related to the control value.
695 <p>In opposite to ->initValueProperty, this method is to be used for value properties which are <em>not</em>
696 implemented by our aggregate, but by ourselves.</p>
698 <p>Certain functionality is not available when using own value properties. This includes binding to an external
699 value and external validation. (This is not a conceptual limit, but simply missing implementation.)</p>
701 void initOwnValueProperty(
702 const OUString& i_rValuePropertyName
705 /** suspends listening at the value property
707 <p>As long as this listening is suspended, changes in the value property will not be
708 recognized and not be handled.</p>
710 @see initValueProperty
711 @see resumeValueListening
713 void suspendValueListening( );
715 /** resumes listening at the value property
717 <p>As long as this listening is suspended, changes in the value property will not be
718 recognized and not be handled.</p>
720 @precond
721 listening at the value property is currently suspended
723 @see initValueProperty
724 @see resumeValueListening
726 void resumeValueListening( );
728 /** (to be) called when the value property changed
730 Normally, this is done automatically, since the value property is a property of our aggregate, and we're
731 a listener at this property.
732 However, in some cases the value property might not be an aggregate property, but a property of the
733 delegator instance. In this case, you'll need to call <code>onValuePropertyChange</code> whenever this
734 property changes.
736 void onValuePropertyChange( ControlModelLock& i_rControLock );
738 /** starts listening at the aggregate, for changes in the given property
740 <p>The OBoundControlModel automatically registers a multiplexer which listens for
741 changes in the aggregate property values. By default, only the control value property
742 is observed. You may add additional properties to be observed with this method.</p>
744 @see initValueProperty
745 @see _propertyChanged
747 void startAggregatePropertyListening( const OUString& _rPropertyName );
749 /** returns the default which should be used when resetting the control
751 <p>The default implementation returns an empty Any.</p>
753 @see resetNoBroadcast
755 virtual css::uno::Any
756 getDefaultForReset() const;
758 /** translates a db column value into a control value.
760 <p>Must transform the very current value of the database column we're bound to
761 (<member>m_xColumn</member>) into a value which can be used as current value
762 for the control.</p>
764 @see setControlValue
765 @pure
767 virtual css::uno::Any
768 translateDbColumnToControlValue( ) = 0;
770 /** returns the data types which the control could use to exchange data with
771 an external value binding
773 The types returned here are completely independent from the concrete value binding,
774 they're just candidates which depend on the control type, and possible the concrete state
775 of the control (i.e. some property value).
777 If a control implementation supports multiple types, the ordering in the returned
778 sequence indicates preference: Preferred types are mentioned first.
780 The default implementation returns the type of our value property.
782 virtual css::uno::Sequence< css::uno::Type >
783 getSupportedBindingTypes();
785 /** translates the given value, which was obtained from the current external value binding,
786 to a value which can be used in setControlValue
788 <p>The default implementation returns the value itself, exception when it is VOID, and
789 our value property is not allowed to be void - in this case, the returned value is a
790 default-constructed value of the type required by our value property.
792 @see hasExternalValueBinding
793 @see getExternalValueType
795 virtual css::uno::Any
796 translateExternalValueToControlValue( const css::uno::Any& _rExternalValue ) const;
798 /** commits the current control value to our external value binding
800 <p>The default implementation simply calls getControlValue.</p>
802 @see hasExternalValueBinding
803 @see initValueProperty
805 virtual css::uno::Any
806 translateControlValueToExternalValue( ) const;
808 /** commits the current control value to the database column we're bound to
809 @precond
810 we're properly bound to a database column, especially <member>m_xColumnUpdate</member>
811 is not <NULL/>
812 @param _bPostReset
813 <TRUE/> if and only if the current control value results from a reset (<member>getDefaultForReset</member>)
814 @pure
816 virtual bool commitControlValueToDbColumn(
817 bool _bPostReset
818 ) = 0;
820 /** sets the given value as new current value for the control
822 Besides some administrative work (such as caring for <member>m_eControlValueChangeInstigator</member>),
823 this method simply calls <member>doSetControlValue</member>.
825 @precond
826 Our own mutex is locked.
827 @param _rValue
828 The value to set. This value is guaranteed to be created by
829 <member>translateDbColumnToControlValue</member> or
830 <member>translateExternalValueToControlValue</member>
831 @param _eInstigator
832 the instigator of the value change
834 void setControlValue(
835 const css::uno::Any& _rValue,
836 ValueChangeInstigator _eInstigator
839 <p>The default implementation will forward the given value to the aggregate, using
840 m_nValuePropertyAggregateHandle and/or m_sValuePropertyName.</p>
842 @precond
843 Our own mutex is locked.
844 @param _rValue
845 The value to set. This value is guaranteed to be created by
846 <member>translateDbColumnToControlValue</member> or
847 <member>translateExternalValueToControlValue</member>
849 virtual void doSetControlValue(
850 const css::uno::Any& _rValue
853 /** retrieves the current value of the control
855 <p>The default implementation will ask the aggregate for the property value
856 determined by either m_nValuePropertyAggregateHandle and/or m_sValuePropertyName.</p>
858 @precond
859 Our own mutex is locked.
861 virtual css::uno::Any
862 getControlValue( ) const;
864 /** called whenever a connection to a database column has been established
866 virtual void onConnectedDbColumn( const css::uno::Reference< css::uno::XInterface >& _rxForm );
867 /** called whenever a connection to a database column has been suspended
869 virtual void onDisconnectedDbColumn();
871 /** called whenever a connection to an external supplier of values (XValueBinding) has been established
872 @see m_xExternalBinding
874 virtual void onConnectedExternalValue( );
876 /** called whenever an external validator has been registered
878 void onConnectedValidator( );
879 /** called whenever an external validator has been revoked
881 void onDisconnectedValidator( );
883 /** nFieldType is the type of the field, on which the model will be linked.
884 The linking happens when sal_True is returned.
885 The default-implementation allows everything but the three binary types
886 and FieldType_OTHER.
888 virtual bool approveDbColumnType(sal_Int32 _nColumnType);
890 /** retrieves the current value of the control, in a shape which can be used with our
891 external validator.
893 The default implementation simply calls <member>>translateControlValueToExternalValue</member>.
895 @precond
896 Our own mutex is locked.
898 virtual css::uno::Any
899 translateControlValueToValidatableValue( ) const;
901 /** retrieves the current value of the form component
903 This is the implementation method for XValidatableFormComponent::getCurrentValue. The default implementation
904 calls translateControlValueToValidatableValue if a validator is present, otherwise getControlValue.
906 @precond
907 our mutex is locked when this method is called
909 virtual css::uno::Any
910 getCurrentFormComponentValue() const;
912 /** We can't write (new) common properties in this base class, as the file format doesn't allow this
913 (unfortunately). So derived classes may use the following two methods. They secure the written
914 data with marks, so any new common properties in newer versions will be skipped by older ones.
916 void writeCommonProperties(const css::uno::Reference< css::io::XObjectOutputStream>& _rxOutStream);
917 void readCommonProperties(const css::uno::Reference< css::io::XObjectInputStream>& _rxInStream);
918 // the next method may be used in derived classes's read when an unknown version is encountered
919 void defaultCommonProperties();
921 /** called to reset the control to some kind of default.
923 <p>The semantics of "default" is finally defined by the derived class (in particular,
924 by <member>getDefaultForReset</member>).</p>
926 <p>No listener notification needs to be done in the derived class.</p>
928 <p>Normally, you won't override this method, but <member>getDefaultForReset</member> instead.</p>
930 @see getDefaultForReset
932 virtual void resetNoBroadcast();
934 virtual css::uno::Sequence< css::uno::Type> _getTypes() override;
936 /// sets m_xField to the given new value, without notifying our listeners
937 void impl_setField_noNotify(
938 const css::uno::Reference< css::beans::XPropertySet>& _rxField
940 bool hasField() const
942 return m_xField.is();
944 sal_Int32 getFieldType() const
946 return m_nFieldType;
949 // OControlModel's property handling
950 virtual void describeFixedProperties(
951 css::uno::Sequence< css::beans::Property >& /* [out] */ _rProps
952 ) const override;
954 public:
955 const css::uno::Reference< css::beans::XPropertySet>& getField() const
957 return m_xField;
960 public:
961 // UNO link
962 DECLARE_UNO3_AGG_DEFAULTS(OBoundControlModel, OControlModel)
963 virtual css::uno::Any SAL_CALL queryAggregation( const css::uno::Type& _rType ) override;
965 // OComponentHelper
966 virtual void SAL_CALL disposing() override;
968 // XReset
969 virtual void SAL_CALL reset( ) override;
970 virtual void SAL_CALL addResetListener( const css::uno::Reference< css::form::XResetListener >& aListener ) override;
971 virtual void SAL_CALL removeResetListener( const css::uno::Reference< css::form::XResetListener >& aListener ) override;
973 // XServiceInfo
974 virtual css::uno::Sequence<OUString> SAL_CALL getSupportedServiceNames( ) override;
976 // XServiceInfo - static version
977 /// @throws css::uno::RuntimeException
978 static css::uno::Sequence<OUString> getSupportedServiceNames_Static();
980 // XChild
981 virtual void SAL_CALL setParent( const css::uno::Reference< css::uno::XInterface >& Parent ) override;
983 // XPersistObject
984 virtual void SAL_CALL write( const css::uno::Reference< css::io::XObjectOutputStream >& OutStream ) override;
985 virtual void SAL_CALL read( const css::uno::Reference< css::io::XObjectInputStream >& InStream ) override;
987 // XBoundComponent
988 virtual sal_Bool SAL_CALL commit() override;
990 // XUpdateBroadcaster (base of XBoundComponent)
991 virtual void SAL_CALL addUpdateListener( const css::uno::Reference< css::form::XUpdateListener >& aListener ) override;
992 virtual void SAL_CALL removeUpdateListener( const css::uno::Reference< css::form::XUpdateListener >& aListener ) override;
994 // XPropertySet
995 virtual void SAL_CALL getFastPropertyValue(css::uno::Any& rValue, sal_Int32 nHandle) const override;
996 virtual sal_Bool SAL_CALL convertFastPropertyValue(
997 css::uno::Any& _rConvertedValue, css::uno::Any& _rOldValue, sal_Int32 _nHandle, const css::uno::Any& _rValue ) override;
998 virtual void SAL_CALL setFastPropertyValue_NoBroadcast( sal_Int32 nHandle, const css::uno::Any& rValue ) override;
999 using ::cppu::OPropertySetHelper::getFastPropertyValue;
1001 // css::beans::XPropertyState
1002 virtual css::uno::Any getPropertyDefaultByHandle( sal_Int32 nHandle ) const override;
1004 // XEventListener
1005 virtual void SAL_CALL disposing(const css::lang::EventObject& Source) override;
1007 // XPropertyChangeListener
1008 virtual void SAL_CALL propertyChange( const css::beans::PropertyChangeEvent& evt ) override;
1010 // XRowSetChangeListener
1011 virtual void SAL_CALL onRowSetChanged( const css::lang::EventObject& i_Event ) override;
1013 // XLoadListener
1014 virtual void SAL_CALL loaded( const css::lang::EventObject& aEvent ) override;
1015 virtual void SAL_CALL unloading( const css::lang::EventObject& aEvent ) override;
1016 virtual void SAL_CALL unloaded( const css::lang::EventObject& aEvent ) override;
1017 virtual void SAL_CALL reloading( const css::lang::EventObject& aEvent ) override;
1018 virtual void SAL_CALL reloaded( const css::lang::EventObject& aEvent ) override;
1020 protected:
1021 // XBindableValue
1022 virtual void SAL_CALL setValueBinding( const css::uno::Reference< css::form::binding::XValueBinding >& _rxBinding ) override;
1023 virtual css::uno::Reference< css::form::binding::XValueBinding > SAL_CALL getValueBinding( ) override;
1025 // XModifyListener
1026 virtual void SAL_CALL modified( const css::lang::EventObject& _rEvent ) override;
1028 // XValidatable
1029 virtual void SAL_CALL setValidator( const css::uno::Reference< css::form::validation::XValidator >& Validator ) override;
1030 virtual css::uno::Reference< css::form::validation::XValidator > SAL_CALL getValidator( ) override;
1032 // XValidityConstraintListener
1033 virtual void SAL_CALL validityConstraintChanged( const css::lang::EventObject& Source ) override;
1035 // XValidatableFormComponent
1036 virtual sal_Bool SAL_CALL isValid( ) override;
1037 virtual css::uno::Any SAL_CALL getCurrentValue( ) override;
1038 virtual void SAL_CALL addFormComponentValidityListener( const css::uno::Reference< css::form::validation::XFormComponentValidityListener >& Listener ) override;
1039 virtual void SAL_CALL removeFormComponentValidityListener( const css::uno::Reference< css::form::validation::XFormComponentValidityListener >& Listener ) override;
1041 protected:
1042 // OPropertyChangeListener
1043 virtual void
1044 _propertyChanged( const css::beans::PropertyChangeEvent& _rEvt ) override;
1046 /// checks whether we currently have an external value binding in place
1047 bool hasExternalValueBinding() const { return m_xExternalBinding.is(); }
1049 // checks whether we currently have an external validator
1050 bool hasValidator() const { return m_xValidator.is(); }
1052 /** transfers the very current value of the db column we're bound to the control
1053 @precond
1054 our own mutex is locked
1055 @precond
1056 we don't have an external binding in place
1058 void transferDbValueToControl( );
1060 /** transfers the current value of the active external binding to the control
1061 @precond
1062 we do have an active external binding in place
1064 void transferExternalValueToControl( ControlModelLock& _rInstanceLock );
1066 /** transfers the control value to the external binding
1067 @precond
1068 our own mutex is locked, and _rInstanceLock is the guard locking it
1069 @precond
1070 we do have an active external binding in place
1072 void transferControlValueToExternal( ControlModelLock& _rInstanceLock );
1074 /** calculates the type which is to be used to communicate with the current external binding,
1075 and stores it in m_aExternalValueType
1077 The method checks the possible type candidates as returned by getSupportedBindingTypes,
1078 and the types supported by the current external binding, if any.
1080 void calculateExternalValueType();
1082 /** returns the type which should be used to exchange data with our external value binding
1084 @see initValueProperty
1086 const css::uno::Type&
1087 getExternalValueType() const { return m_aExternalValueType; }
1089 /** initializes the control from m_xField
1091 Basically, this method calls transferDbValueToControl - but only if our cursor is positioned
1092 on a valid row. Otherwise, the control is reset.
1094 @precond
1095 m_xField is not <NULL/>
1097 void initFromField( const css::uno::Reference< css::sdbc::XRowSet>& _rxForm );
1099 private:
1100 void connectToField( const css::uno::Reference< css::sdbc::XRowSet>& _rxForm );
1101 void resetField();
1103 /** does a new validation of the control value
1105 If necessary, our <member>m_bIsCurrentValueValid</member> member will be adjusted,
1106 and changes will be notified.
1108 Note that it's not necessary that we're connected to a validator. If we are not,
1109 it's assumed that our value is valid, and this is handled appropriately.
1111 Use this method if there is a potential that <b>only</b> the validity flag changed. If
1112 any of the other aspects (our current value, or our current text) changed, then
1113 pass <TRUE/> for <member>_bForceNotification</member>.
1115 @param _bForceNotification
1116 if <TRUE/>, then the validity listeners will be notified, not matter whether the validity
1117 changed.
1119 void recheckValidity( bool _bForceNotification );
1121 /// initializes m_pAggPropMultiplexer
1122 void implInitAggMultiplexer( );
1124 /// initializes listening at the value property
1125 void implInitValuePropertyListening( ) const;
1127 /** adds or removes the component as load listener to/from our form, and (if necessary) as RowSetChange listener at
1128 our parent.
1130 @precond there must no external value binding be in place
1132 void doFormListening( const bool _bStart );
1134 bool isFormListening() const { return m_bFormListening; }
1136 /** determines the new value of m_xAmbientForm
1138 void impl_determineAmbientForm_nothrow();
1140 /** connects to a value supplier which is a database column.
1142 The column is taken from our parent, which must be a database form respectively row set.
1144 @precond The control does not have an external value supplier
1146 @param _bFromReload
1147 Determines whether the connection is made after the row set has been loaded (<FALSE/>)
1148 or reloaded (<TRUE/>)
1150 @see impl_disconnectDatabaseColumn_noNotify
1152 void impl_connectDatabaseColumn_noNotify(
1153 bool _bFromReload
1156 /** disconnects from a value supplier which is a database column
1158 @precond The control does not have an external value supplier
1159 @see impl_connectDatabaseColumn_noNotify
1161 void impl_disconnectDatabaseColumn_noNotify();
1163 /** connects to an external value binding
1165 <p>Note that by definition, external data bindings supersede the SQL data binding which
1166 is defined by our RowSet-column-related properties. This means that in case we're currently
1167 connected to a database column when this is called, this connection is suspended.</p>
1169 @precond
1170 the new external binding has already been approved (see <member>impl_approveValueBinding_nolock</member>)
1171 @precond
1172 there currently is no external binding in place
1174 void connectExternalValueBinding(
1175 const css::uno::Reference< css::form::binding::XValueBinding >& _rxBinding,
1176 ControlModelLock& _rInstanceLock
1179 /** disconnects from an external value binding
1181 @precond
1182 there currently is an external binding in place
1184 void disconnectExternalValueBinding( );
1186 /** connects the component to an external validator
1188 @precond
1189 there currently is no active validator
1190 @precond
1191 our mutex is currently locked exactly once
1193 void connectValidator(
1194 const css::uno::Reference< css::form::validation::XValidator >& _rxValidator
1197 /** disconnects the component from its current an external validator
1199 @precond
1200 there currently is an active validator
1201 @precond
1202 our mutex is currently locked exactly once
1204 void disconnectValidator( );
1206 /** called from within <member scope="css:::form::binding">XBindableValue::setValueBinding</member>
1207 to approve the new binding
1209 The default implementation approves the binding if and only if it is not <NULL/>, and supports
1210 the type returned by getExternalValueType.
1212 @param _rxBinding
1213 the binding which applies for being responsible for our value, Must not be
1214 <NULL/>
1215 @return
1216 <TRUE/> if and only if the given binding can supply values in the proper type
1218 @seealso getExternalValueType
1220 bool impl_approveValueBinding_nolock(
1221 const css::uno::Reference< css::form::binding::XValueBinding >& _rxBinding
1226 //= inlines
1228 inline void ControlModelLock::acquire()
1230 m_rModel.lockInstance( OControlModel::LockAccess() );
1231 m_bLocked = true;
1233 inline void ControlModelLock::release()
1235 OSL_ENSURE( m_bLocked, "ControlModelLock::release: not locked!" );
1236 m_bLocked = false;
1238 if ( 0 == m_rModel.unlockInstance( OControlModel::LockAccess() ) )
1239 impl_notifyAll_nothrow();
1246 #endif // INCLUDED_FORMS_SOURCE_INC_FORMCOMPONENT_HXX
1248 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */