Version 7.6.3.2-android, tag libreoffice-7.6.3.2-android
[LibreOffice.git] / forms / source / inc / FormComponent.hxx
blob0a0ec19be553387e26a2a35bb6667f00217fb4cc
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 #pragma once
22 #include "cloneable.hxx"
23 #include "propertybaghelper.hxx"
24 #include "resettable.hxx"
25 #include "windowstateguard.hxx"
27 #include <com/sun/star/awt/XControl.hpp>
28 #include <com/sun/star/beans/XPropertyAccess.hpp>
29 #include <com/sun/star/beans/XPropertyContainer.hpp>
30 #include <com/sun/star/container/XNamed.hpp>
31 #include <com/sun/star/form/binding/XBindableValue.hpp>
32 #include <com/sun/star/form/validation/XValidatableFormComponent.hpp>
33 #include <com/sun/star/form/validation/XValidityConstraintListener.hpp>
34 #include <com/sun/star/form/XBoundComponent.hpp>
35 #include <com/sun/star/form/XBoundControl.hpp>
36 #include <com/sun/star/form/XFormComponent.hpp>
37 #include <com/sun/star/form/XLoadListener.hpp>
38 #include <com/sun/star/form/XReset.hpp>
39 #include <com/sun/star/io/XPersistObject.hpp>
40 #include <com/sun/star/lang/XEventListener.hpp>
41 #include <com/sun/star/lang/XServiceInfo.hpp>
42 #include <com/sun/star/sdb/XColumn.hpp>
43 #include <com/sun/star/sdb/XColumnUpdate.hpp>
44 #include <com/sun/star/sdb/XRowSetChangeListener.hpp>
45 #include <com/sun/star/sdbc/XRowSet.hpp>
46 #include <com/sun/star/uno/XAggregation.hpp>
47 #include <com/sun/star/uno/XComponentContext.hpp>
48 #include <com/sun/star/util/XCloneable.hpp>
49 #include <com/sun/star/util/XModifyListener.hpp>
50 #include <com/sun/star/form/XLoadable.hpp>
52 #include <comphelper/interfacecontainer3.hxx>
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 class OControlModel;
77 //= ControlModelLock
79 /** class whose instances lock an OControlModel
81 Locking here merely means locking the OControlModel's mutex.
83 In addition to the locking facility, the class is also able to fire property
84 change notifications. This happens when the last ControlModelLock instance on a stack
85 dies.
87 class ControlModelLock
89 public:
90 ControlModelLock( OControlModel& _rModel )
91 :m_rModel( _rModel )
92 ,m_bLocked( false )
94 acquire();
97 ~ControlModelLock()
99 if ( m_bLocked )
100 release();
102 inline void acquire();
103 inline void release();
105 OControlModel& getModel() const { return m_rModel; };
107 /** adds a property change notification, which is to be fired when the last lock on the model
108 (in the current thread) is released.
110 void addPropertyNotification(
111 const sal_Int32 _nHandle,
112 const css::uno::Any& _rOldValue,
113 const css::uno::Any& _rNewValue
116 private:
117 void impl_notifyAll_nothrow();
119 OControlModel& m_rModel;
120 bool m_bLocked;
121 std::vector< sal_Int32 > m_aHandles;
122 std::vector< css::uno::Any > m_aOldValues;
123 std::vector< css::uno::Any > m_aNewValues;
125 ControlModelLock( const ControlModelLock& ) = delete;
126 ControlModelLock& operator=( const ControlModelLock& ) = delete;
130 //= OControl
131 //= base class for form layer controls
133 typedef ::cppu::ImplHelper3 < css::awt::XControl
134 , css::lang::XEventListener
135 , css::lang::XServiceInfo
136 > OControl_BASE;
138 class OControl :public ::cppu::OComponentHelper
139 ,public OControl_BASE
141 protected:
142 ::osl::Mutex m_aMutex;
143 css::uno::Reference< css::awt::XControl > m_xControl;
144 css::uno::Reference< css::uno::XAggregation>
145 m_xAggregate;
147 css::uno::Reference< css::uno::XComponentContext >
148 m_xContext;
149 WindowStateGuard m_aWindowStateGuard;
151 public:
152 /** constructs a control
154 @param _rFactory
155 the service factory for this control
156 @param _rAggregateService
157 the service name of the component to aggregate
158 @param _bSetDelegator
159 set this to <FALSE/> if you don't want the constructor to set the delegator at
160 the aggregate. In this case, you <em>have</em> to call doSetDelegator within your
161 own constructor.
163 This is helpful, if your derived class wants to cache an interface of the aggregate.
164 In this case, the aggregate needs to be queried for this interface <b>before</b> the
165 <member scope="css::uno">XAggregation::setDelegator</member> call.
167 In such a case, pass <FALSE/> to this parameter. Then, cache the aggregate's interface(s)
168 as needed. Afterwards, call <member>doSetDelegator</member>.
170 In your destructor, you need to call <member>doResetDelegator</member> before
171 resetting the cached interfaces. This will reset the aggregates delegator to <NULL/>,
172 which will ensure that the <member scope="css::uno">XInterface::release</member>
173 calls on the cached interfaces are really applied to the aggregate, instead of
174 the <type>OControl</type> itself.
176 OControl(
177 const css::uno::Reference< css::uno::XComponentContext >& _rFactory,
178 const OUString& _rAggregateService,
179 const bool _bSetDelegator = true
182 protected:
183 virtual ~OControl() override;
185 /** sets the control as delegator at the aggregate
187 This has to be called from within your derived class' constructor, if and only
188 if you passed <FALSE/> to the <arg>_bSetDelegator</arg> parameter of the
189 <type>OControl</type> constructor.
191 void doSetDelegator();
192 void doResetDelegator();
194 // UNO
195 DECLARE_UNO3_AGG_DEFAULTS(OControl, OComponentHelper)
196 virtual css::uno::Any SAL_CALL queryAggregation( const css::uno::Type& _rType ) override;
198 // XTypeProvider
199 virtual css::uno::Sequence<sal_Int8> SAL_CALL getImplementationId() override;
200 virtual css::uno::Sequence< css::uno::Type> SAL_CALL getTypes() override;
202 // OComponentHelper
203 virtual void SAL_CALL disposing() override;
205 // XComponent (as base of XControl)
206 virtual void SAL_CALL dispose( ) override
207 { OComponentHelper::dispose(); }
208 virtual void SAL_CALL addEventListener( const css::uno::Reference< css::lang::XEventListener>& _rxListener) override
209 { OComponentHelper::addEventListener(_rxListener); }
210 virtual void SAL_CALL removeEventListener( const css::uno::Reference< css::lang::XEventListener>& _rxListener) override
211 { OComponentHelper::removeEventListener(_rxListener); }
213 // XEventListener
214 virtual void SAL_CALL disposing(const css::lang::EventObject& Source) override;
216 // XServiceInfo
217 virtual sal_Bool SAL_CALL supportsService(const OUString& ServiceName) override;
218 virtual css::uno::Sequence<OUString> SAL_CALL getSupportedServiceNames() override;
219 virtual OUString SAL_CALL getImplementationName() override = 0;
221 // XControl
222 virtual void SAL_CALL setContext(const css::uno::Reference<css::uno::XInterface>& Context) override;
223 virtual css::uno::Reference<css::uno::XInterface> SAL_CALL getContext() override;
224 virtual void SAL_CALL createPeer(const css::uno::Reference<css::awt::XToolkit>& Toolkit, const css::uno::Reference<css::awt::XWindowPeer>& Parent) override;
225 virtual css::uno::Reference<css::awt::XWindowPeer> SAL_CALL getPeer() override;
226 virtual sal_Bool SAL_CALL setModel(const css::uno::Reference<css::awt::XControlModel>& Model) override;
227 virtual css::uno::Reference<css::awt::XControlModel> SAL_CALL getModel() override;
228 virtual css::uno::Reference<css::awt::XView> SAL_CALL getView() override;
229 virtual void SAL_CALL setDesignMode(sal_Bool bOn) override;
230 virtual sal_Bool SAL_CALL isDesignMode() override;
231 virtual sal_Bool SAL_CALL isTransparent() override;
233 protected:
234 virtual css::uno::Sequence< css::uno::Type> _getTypes();
235 // overwrite this and call the base class if you have additional types
237 css::uno::Sequence< OUString > getAggregateServiceNames() const;
239 private:
240 void impl_resetStateGuard_nothrow();
243 // a form control implementing the XBoundControl interface
244 typedef ::cppu::ImplHelper1 < css::form::XBoundControl
245 > OBoundControl_BASE;
246 class OBoundControl :public OControl
247 ,public OBoundControl_BASE
249 bool m_bLocked : 1;
251 public:
252 OBoundControl(
253 const css::uno::Reference< css::uno::XComponentContext >& _rxContext,
254 const OUString& _rAggregateService,
255 const bool _bSetDelegator = true
258 virtual ~OBoundControl() override;
260 DECLARE_UNO3_AGG_DEFAULTS(OBoundControl, OControl)
261 virtual css::uno::Any SAL_CALL queryAggregation( const css::uno::Type& _rType ) override;
263 // XBoundControl
264 virtual sal_Bool SAL_CALL getLock() override;
265 virtual void SAL_CALL setLock(sal_Bool _bLock) override;
266 // default implementation just disables the controls, overwrite _setLock to change this behaviour
268 // XControl
269 virtual sal_Bool SAL_CALL setModel(const css::uno::Reference< css::awt::XControlModel >& Model) override;
271 // XEventListener
272 virtual void SAL_CALL disposing(const css::lang::EventObject& Source) override;
274 // OComponentHelper
275 virtual void SAL_CALL disposing() override;
277 protected:
278 virtual css::uno::Sequence< css::uno::Type> _getTypes() override;
279 // implement the lock setting
280 void _setLock(bool _bLock);
284 //= OControlModel
285 //= model of a form layer control
287 //added for exporting OCX control
288 #define INVALID_OBJ_ID_IN_MSO 0xFFFF
290 typedef ::cppu::ImplHelper7 < css::form::XFormComponent
291 , css::io::XPersistObject
292 , css::container::XNamed
293 , css::lang::XServiceInfo
294 , css::util::XCloneable
295 , css::beans::XPropertyContainer
296 , css::beans::XPropertyAccess
297 > OControlModel_BASE;
299 class OControlModel :public ::cppu::OComponentHelper
300 ,public comphelper::OPropertySetAggregationHelper
301 ,public OControlModel_BASE
302 ,public OCloneableAggregation
303 ,public IPropertyBagHelperContext
306 protected:
307 css::uno::Reference<css::uno::XComponentContext> m_xContext;
309 ::osl::Mutex m_aMutex;
310 oslInterlockedCount m_lockCount;
312 css::uno::Reference<css::uno::XInterface> m_xParent; // ParentComponent
313 PropertyBagHelper m_aPropertyBagHelper;
315 const css::uno::Reference<css::uno::XComponentContext>&
316 getContext() const { return m_xContext; }
318 // <properties>
319 OUString m_aName; // name of the control
320 OUString m_aTag; // tag for additional data
321 sal_Int16 m_nTabIndex; // index within the taborder
322 sal_Int16 m_nClassId; // type of the control
323 bool m_bNativeLook; // should the control use the native platform look?
324 bool m_bStandardTheme; // should the default control colors be 'standard' or use the native platform theme?
325 bool m_bGenerateVbEvents; // should the control generate fake vba events
326 //added for exporting OCX control
327 sal_Int16 m_nControlTypeinMSO; //keep the MS office control type for exporting to MS binary file
328 sal_uInt16 m_nObjIDinMSO; //keep the OCX control obj id for exporting to MS binary file
329 // </properties>
332 protected:
333 OControlModel(
334 const css::uno::Reference< css::uno::XComponentContext>& _rFactory, // factory to create the aggregate with
335 const OUString& _rUnoControlModelTypeName, // service name of te model to aggregate
336 const OUString& rDefault = OUString(), // service name of the default control
337 const bool _bSetDelegator = true // set to sal_False if you want to call setDelegator later (after returning from this ctor)
339 OControlModel(
340 const OControlModel* _pOriginal, // the original object to clone
341 const css::uno::Reference< css::uno::XComponentContext>& _rFactory, // factory to create the aggregate with
342 const bool _bCloneAggregate = true, // should the aggregate of the original be cloned, too?
343 const bool _bSetDelegator = true // set to sal_False if you want to call setDelegator later (after returning from this ctor)
345 virtual ~OControlModel() override;
347 /** to be called after an OBoundControlModel (a derivee, respectively) has been cloned
349 <p>This method contains late initializations which cannot be done in the
350 constructor of this base class, since the virtual method of derived classes do
351 not yet work there.</p>
353 virtual void clonedFrom( const OControlModel* _pOriginal );
355 using OComponentHelper::rBHelper;
357 virtual css::uno::Sequence< css::uno::Type> _getTypes();
359 void readHelpTextCompatibly(const css::uno::Reference< css::io::XObjectInputStream >& _rxInStream);
360 void writeHelpTextCompatibly(const css::uno::Reference< css::io::XObjectOutputStream >& _rxOutStream);
362 void doSetDelegator();
363 void doResetDelegator();
365 css::uno::Sequence< OUString > getAggregateServiceNames() const;
367 public:
368 DECLARE_UNO3_AGG_DEFAULTS(OControl, OComponentHelper)
369 virtual css::uno::Any SAL_CALL queryAggregation( const css::uno::Type& _rType ) override;
371 // XTypeProvider
372 virtual css::uno::Sequence<sal_Int8> SAL_CALL getImplementationId() override;
373 virtual css::uno::Sequence< css::uno::Type> SAL_CALL getTypes() override;
375 // OComponentHelper
376 virtual void SAL_CALL disposing() override;
378 // XNamed
379 virtual OUString SAL_CALL getName() override;
380 virtual void SAL_CALL setName(const OUString& aName) override;
382 // XServiceInfo
383 virtual sal_Bool SAL_CALL supportsService(const OUString& ServiceName) override;
384 virtual css::uno::Sequence<OUString> SAL_CALL getSupportedServiceNames() override;
385 virtual OUString SAL_CALL getImplementationName() override = 0;
387 // XServiceInfo - static version(s)
388 /// @throws css::uno::RuntimeException
389 static css::uno::Sequence<OUString> getSupportedServiceNames_Static();
391 // XPersistObject
392 virtual OUString SAL_CALL getServiceName() override = 0;
393 virtual void SAL_CALL
394 write(const css::uno::Reference< css::io::XObjectOutputStream>& _rxOutStream) override;
395 virtual void SAL_CALL
396 read(const css::uno::Reference< css::io::XObjectInputStream>& _rxInStream) override;
398 // XChild (base of XFormComponent)
399 virtual css::uno::Reference<css::uno::XInterface> SAL_CALL getParent() override;
400 virtual void SAL_CALL setParent(const css::uno::Reference<css::uno::XInterface>& Parent) override;
402 // XEventListener
403 virtual void SAL_CALL disposing(const css::lang::EventObject& Source) override;
405 // XPropertySet
406 virtual void SAL_CALL getFastPropertyValue(css::uno::Any& rValue, sal_Int32 nHandle) const override;
407 virtual sal_Bool SAL_CALL convertFastPropertyValue(
408 css::uno::Any& _rConvertedValue, css::uno::Any& _rOldValue, sal_Int32 _nHandle, const css::uno::Any& _rValue ) override;
409 virtual void SAL_CALL setFastPropertyValue_NoBroadcast( sal_Int32 nHandle, const css::uno::Any& rValue ) override;
410 using ::cppu::OPropertySetHelper::getFastPropertyValue;
412 // css::beans::XPropertyState
413 virtual css::beans::PropertyState getPropertyStateByHandle(sal_Int32 nHandle) override;
414 virtual void setPropertyToDefaultByHandle(sal_Int32 nHandle) override;
415 virtual css::uno::Any getPropertyDefaultByHandle( sal_Int32 nHandle ) const override;
417 // XCloneable
418 virtual css::uno::Reference< css::util::XCloneable > SAL_CALL createClone( ) override = 0;
420 // XPropertyContainer
421 virtual void SAL_CALL addProperty( const OUString& Name, ::sal_Int16 Attributes, const css::uno::Any& DefaultValue ) override;
422 virtual void SAL_CALL removeProperty( const OUString& Name ) override;
424 // XPropertyAccess
425 virtual css::uno::Sequence< css::beans::PropertyValue > SAL_CALL getPropertyValues( ) override;
426 virtual void SAL_CALL setPropertyValues( const css::uno::Sequence< css::beans::PropertyValue >& aProps ) override;
428 protected:
429 using OPropertySetAggregationHelper::setPropertyValues;
430 using OPropertySetAggregationHelper::getPropertyValues;
432 protected:
433 virtual void writeAggregate( const css::uno::Reference< css::io::XObjectOutputStream >& _rxOutStream ) const;
434 virtual void readAggregate( const css::uno::Reference< css::io::XObjectInputStream >& _rxInStream );
436 protected:
437 // XPropertySet
438 virtual css::uno::Reference< css::beans::XPropertySetInfo> SAL_CALL getPropertySetInfo() override;
439 // OPropertySetHelper
440 virtual cppu::IPropertyArrayHelper& SAL_CALL getInfoHelper() override;
442 /** describes the properties provided by this class, or its respective
443 derived class
445 Derived classes usually call the base class first, and then append own properties.
447 virtual void describeFixedProperties(
448 css::uno::Sequence< css::beans::Property >& /* [out] */ _rProps
449 ) const;
451 // IPropertyBagHelperContext
452 virtual ::osl::Mutex& getMutex() override;
453 virtual void describeFixedAndAggregateProperties(
454 css::uno::Sequence< css::beans::Property >& _out_rFixedProperties,
455 css::uno::Sequence< css::beans::Property >& _out_rAggregateProperties
456 ) const override;
457 virtual css::uno::Reference< css::beans::XMultiPropertySet >
458 getPropertiesInterface() override;
460 /** describes the properties of our aggregate
462 The default implementation simply asks m_xAggregateSet for its properties.
464 You usually only need to override this method if you want to filter the
465 aggregate properties.
467 virtual void describeAggregateProperties(
468 css::uno::Sequence< css::beans::Property >& /* [out] */ _rAggregateProps
469 ) const;
471 public:
472 struct LockAccess { friend class ControlModelLock; private: LockAccess() { } };
474 void lockInstance( LockAccess );
475 oslInterlockedCount unlockInstance( LockAccess );
477 void firePropertyChanges(
478 const std::vector< sal_Int32 >& _rHandles,
479 const std::vector< css::uno::Any >& _rOldValues,
480 const std::vector< css::uno::Any >& _rNewValues,
481 LockAccess
484 ::osl::Mutex&
485 getInstanceMutex() { return m_aMutex; }
488 //= OBoundControlModel
489 //= model of a form layer control which is bound to a data source field
491 typedef ::cppu::ImplHelper4 < css::form::XLoadListener
492 , css::form::XReset
493 , css::beans::XPropertyChangeListener
494 , css::sdb::XRowSetChangeListener
495 > OBoundControlModel_BASE1;
497 // separated into an own base class since derivees can disable the support for this
498 // interface, thus we want to easily exclude it in the queryInterface and getTypes
499 typedef ::cppu::ImplHelper1 < css::form::XBoundComponent
500 > OBoundControlModel_COMMITTING;
502 // ditto
503 typedef ::cppu::ImplHelper2 < css::form::binding::XBindableValue
504 , css::util::XModifyListener
505 > OBoundControlModel_BINDING;
507 // ditto
508 typedef ::cppu::ImplHelper2 < css::form::validation::XValidityConstraintListener
509 , css::form::validation::XValidatableFormComponent
510 > OBoundControlModel_VALIDATION;
512 class OBoundControlModel :public OControlModel
513 ,public OBoundControlModel_BASE1
514 ,public OBoundControlModel_COMMITTING
515 ,public OBoundControlModel_BINDING
516 ,public OBoundControlModel_VALIDATION
517 ,public ::comphelper::OPropertyChangeListener
519 protected:
520 enum ValueChangeInstigator
522 eDbColumnBinding,
523 eExternalBinding,
524 eOther
527 private:
528 css::uno::Reference< css::beans::XPropertySet >
529 m_xField;
530 // the form which controls supplies the field we bind to.
531 css::uno::Reference< css::form::XLoadable >
532 m_xAmbientForm;
534 OUString m_sValuePropertyName;
535 sal_Int32 m_nValuePropertyAggregateHandle;
536 sal_Int32 m_nFieldType;
537 css::uno::Type m_aValuePropertyType;
538 bool m_bValuePropertyMayBeVoid;
540 ResetHelper m_aResetHelper;
541 ::comphelper::OInterfaceContainerHelper3<css::form::XUpdateListener>
542 m_aUpdateListeners;
543 ::comphelper::OInterfaceContainerHelper3<css::form::validation::XFormComponentValidityListener>
544 m_aFormComponentListeners;
546 css::uno::Reference< css::form::binding::XValueBinding >
547 m_xExternalBinding;
548 css::uno::Reference< css::form::validation::XValidator >
549 m_xValidator;
550 css::uno::Type m_aExternalValueType;
552 // <properties>
553 OUString m_aControlSource; // data source, name of the field
554 css::uno::Reference< css::beans::XPropertySet >
555 m_xLabelControl; // reference to a sibling control (model) which is our label
556 bool m_bInputRequired;
557 // </properties>
559 rtl::Reference<::comphelper::OPropertyChangeMultiplexer>
560 m_pAggPropMultiplexer;
562 bool m_bFormListening : 1; // are we currently a XLoadListener at our ambient form?
563 bool m_bLoaded : 1;
564 bool m_bRequired : 1;
565 const bool m_bCommitable : 1; // do we support XBoundComponent?
566 const bool m_bSupportsExternalBinding : 1; // do we support XBindableValue?
567 const bool m_bSupportsValidation : 1; // do we support XValidatable?
568 bool m_bForwardValueChanges : 1; // do we currently handle changes in the bound database field?
569 bool m_bTransferringValue : 1; // true if we're currently transferring our value to an external binding
570 bool m_bIsCurrentValueValid : 1; // flag specifying whether our current value is valid, relative to our external validator
571 bool m_bBindingControlsRO : 1; // is our ReadOnly property currently controlled by our external binding?
572 bool m_bBindingControlsEnable : 1; // is our Enabled property currently controlled by our external binding?
574 ValueChangeInstigator m_eControlValueChangeInstigator;
576 protected:
577 OUString m_aLabelServiceName;
578 // when setting the label for our control (property FM_PROP_CONTROLLABEL, member m_xLabelControl),
579 // we accept only objects supporting an XControlModel interface, an XServiceInfo interface and
580 // support for a service (XServiceInfo::supportsService) determined by this string.
581 // Any other arguments will throw an IllegalArgumentException.
582 // The default value is FM_COMPONENT_FIXEDTEXT.
584 css::uno::Reference< css::sdbc::XRowSet >
585 m_xCursor;
586 css::uno::Reference< css::sdb::XColumnUpdate >
587 m_xColumnUpdate;
588 css::uno::Reference< css::sdb::XColumn >
589 m_xColumn;
591 protected:
592 sal_Int32 getValuePropertyAggHandle( ) const { return m_nValuePropertyAggregateHandle; }
593 const OUString& getControlSource( ) const { return m_aControlSource; }
594 bool isRequired() const { return m_bRequired; }
595 bool isLoaded() const { return m_bLoaded; }
597 protected:
599 OBoundControlModel(
600 const css::uno::Reference< css::uno::XComponentContext>& _rxContext,
601 // factory to create the aggregate with
602 const OUString& _rUnoControlModelTypeName, // service name of te model to aggregate
603 const OUString& _rDefault, // service name of the default control
604 const bool _bCommitable, // is the control (model) committable?
605 const bool _bSupportExternalBinding, // set to sal_True if you want to support XBindableValue
606 const bool _bSupportsValidation // set to sal_True if you want to support XValidatable
608 OBoundControlModel(
609 const OBoundControlModel* _pOriginal, // the original object to clone
610 const css::uno::Reference< css::uno::XComponentContext>& _rxContext
611 // factory to create the aggregate with
613 virtual ~OBoundControlModel() override;
615 /// late ctor after cloning
616 virtual void clonedFrom( const OControlModel* _pOriginal ) override;
618 /** initializes the part of the class which is related to the control value.
620 <p>Kind of late ctor, to be called for derivees which have a dedicated value property.<br/>
621 The value property is the property which's value is synced with either the database
622 column the object is bound to, or with the external value binding, if present.<br/>
623 E.g. for a text control model, this property will most probably be "Text".</p>
625 <p>Derived classes are strongly recommended to call this method - at least the
626 "DataFieldProperty" (exposed in getFastPropertyValue) relies on the information
627 given herein, and needs to be supplied otherwise else.</p>
629 <p>If this method has been called properly, then <member>setControlValue</member>
630 does not need to be overridden - it will simply set the property value at the
631 aggregate then.</p>
633 @precond
634 The method has not be called before during the life time of the object.
636 @param _rValuePropertyName
637 the name of the value property
638 @param _nValuePropertyExternalHandle
639 the handle of the property, as exposed to external components.<br/>
640 Normally, this information can be obtained dynamically (e.g. from describeFixedProperties),
641 but since this method is to be called from within the constructor of derived classes,
642 we prefer to be on the *really* safe side here...
644 @see setControlValue
645 @see suspendValueListening
646 @see resumeValueListening
647 @see describeFixedProperties
649 void initValueProperty(
650 const OUString& _rValuePropertyName,
651 sal_Int32 _nValuePropertyExternalHandle
654 /** initializes the part of the class which is related to the control value.
656 <p>In opposite to ->initValueProperty, this method is to be used for value properties which are <em>not</em>
657 implemented by our aggregate, but by ourselves.</p>
659 <p>Certain functionality is not available when using own value properties. This includes binding to an external
660 value and external validation. (This is not a conceptual limit, but simply missing implementation.)</p>
662 void initOwnValueProperty(
663 const OUString& i_rValuePropertyName
666 /** suspends listening at the value property
668 <p>As long as this listening is suspended, changes in the value property will not be
669 recognized and not be handled.</p>
671 @see initValueProperty
672 @see resumeValueListening
674 void suspendValueListening( );
676 /** resumes listening at the value property
678 <p>As long as this listening is suspended, changes in the value property will not be
679 recognized and not be handled.</p>
681 @precond
682 listening at the value property is currently suspended
684 @see initValueProperty
685 @see resumeValueListening
687 void resumeValueListening( );
689 /** (to be) called when the value property changed
691 Normally, this is done automatically, since the value property is a property of our aggregate, and we're
692 a listener at this property.
693 However, in some cases the value property might not be an aggregate property, but a property of the
694 delegator instance. In this case, you'll need to call <code>onValuePropertyChange</code> whenever this
695 property changes.
697 void onValuePropertyChange( ControlModelLock& i_rControLock );
699 /** starts listening at the aggregate, for changes in the given property
701 <p>The OBoundControlModel automatically registers a multiplexer which listens for
702 changes in the aggregate property values. By default, only the control value property
703 is observed. You may add additional properties to be observed with this method.</p>
705 @see initValueProperty
706 @see _propertyChanged
708 void startAggregatePropertyListening( const OUString& _rPropertyName );
710 /** returns the default which should be used when resetting the control
712 <p>The default implementation returns an empty Any.</p>
714 @see resetNoBroadcast
716 virtual css::uno::Any
717 getDefaultForReset() const;
719 /** translates a db column value into a control value.
721 <p>Must transform the very current value of the database column we're bound to
722 (<member>m_xColumn</member>) into a value which can be used as current value
723 for the control.</p>
725 @see setControlValue
726 @pure
728 virtual css::uno::Any
729 translateDbColumnToControlValue( ) = 0;
731 /** returns the data types which the control could use to exchange data with
732 an external value binding
734 The types returned here are completely independent from the concrete value binding,
735 they're just candidates which depend on the control type, and possible the concrete state
736 of the control (i.e. some property value).
738 If a control implementation supports multiple types, the ordering in the returned
739 sequence indicates preference: Preferred types are mentioned first.
741 The default implementation returns the type of our value property.
743 virtual css::uno::Sequence< css::uno::Type >
744 getSupportedBindingTypes();
746 /** translates the given value, which was obtained from the current external value binding,
747 to a value which can be used in setControlValue
749 <p>The default implementation returns the value itself, exception when it is VOID, and
750 our value property is not allowed to be void - in this case, the returned value is a
751 default-constructed value of the type required by our value property.
753 @see hasExternalValueBinding
754 @see getExternalValueType
756 virtual css::uno::Any
757 translateExternalValueToControlValue( const css::uno::Any& _rExternalValue ) const;
759 /** commits the current control value to our external value binding
761 <p>The default implementation simply calls getControlValue.</p>
763 @see hasExternalValueBinding
764 @see initValueProperty
766 virtual css::uno::Any
767 translateControlValueToExternalValue( ) const;
769 /** commits the current control value to the database column we're bound to
770 @precond
771 we're properly bound to a database column, especially <member>m_xColumnUpdate</member>
772 is not <NULL/>
773 @param _bPostReset
774 <TRUE/> if and only if the current control value results from a reset (<member>getDefaultForReset</member>)
775 @pure
777 virtual bool commitControlValueToDbColumn(
778 bool _bPostReset
779 ) = 0;
781 /** sets the given value as new current value for the control
783 Besides some administrative work (such as caring for <member>m_eControlValueChangeInstigator</member>),
784 this method simply calls <member>doSetControlValue</member>.
786 @precond
787 Our own mutex is locked.
788 @param _rValue
789 The value to set. This value is guaranteed to be created by
790 <member>translateDbColumnToControlValue</member> or
791 <member>translateExternalValueToControlValue</member>
792 @param _eInstigator
793 the instigator of the value change
795 void setControlValue(
796 const css::uno::Any& _rValue,
797 ValueChangeInstigator _eInstigator
800 <p>The default implementation will forward the given value to the aggregate, using
801 m_nValuePropertyAggregateHandle and/or m_sValuePropertyName.</p>
803 @precond
804 Our own mutex is locked.
805 @param _rValue
806 The value to set. This value is guaranteed to be created by
807 <member>translateDbColumnToControlValue</member> or
808 <member>translateExternalValueToControlValue</member>
810 virtual void doSetControlValue(
811 const css::uno::Any& _rValue
814 /** retrieves the current value of the control
816 <p>The default implementation will ask the aggregate for the property value
817 determined by either m_nValuePropertyAggregateHandle and/or m_sValuePropertyName.</p>
819 @precond
820 Our own mutex is locked.
822 virtual css::uno::Any
823 getControlValue( ) const;
825 /** called whenever a connection to a database column has been established
827 virtual void onConnectedDbColumn( const css::uno::Reference< css::uno::XInterface >& _rxForm );
828 /** called whenever a connection to a database column has been suspended
830 virtual void onDisconnectedDbColumn();
832 /** called whenever a connection to an external supplier of values (XValueBinding) has been established
833 @see m_xExternalBinding
835 virtual void onConnectedExternalValue( );
837 /** called whenever an external validator has been registered
839 void onConnectedValidator( );
840 /** called whenever an external validator has been revoked
842 void onDisconnectedValidator( );
844 /** nFieldType is the type of the field, on which the model will be linked.
845 The linking happens when sal_True is returned.
846 The default-implementation allows everything but the three binary types
847 and FieldType_OTHER.
849 virtual bool approveDbColumnType(sal_Int32 _nColumnType);
851 /** retrieves the current value of the control, in a shape which can be used with our
852 external validator.
854 The default implementation simply calls <member>>translateControlValueToExternalValue</member>.
856 @precond
857 Our own mutex is locked.
859 virtual css::uno::Any
860 translateControlValueToValidatableValue( ) const;
862 /** retrieves the current value of the form component
864 This is the implementation method for XValidatableFormComponent::getCurrentValue. The default implementation
865 calls translateControlValueToValidatableValue if a validator is present, otherwise getControlValue.
867 @precond
868 our mutex is locked when this method is called
870 virtual css::uno::Any
871 getCurrentFormComponentValue() const;
873 /** We can't write (new) common properties in this base class, as the file format doesn't allow this
874 (unfortunately). So derived classes may use the following two methods. They secure the written
875 data with marks, so any new common properties in newer versions will be skipped by older ones.
877 void writeCommonProperties(const css::uno::Reference< css::io::XObjectOutputStream>& _rxOutStream);
878 void readCommonProperties(const css::uno::Reference< css::io::XObjectInputStream>& _rxInStream);
879 // the next method may be used in derived classes's read when an unknown version is encountered
880 void defaultCommonProperties();
882 /** called to reset the control to some kind of default.
884 <p>The semantics of "default" is finally defined by the derived class (in particular,
885 by <member>getDefaultForReset</member>).</p>
887 <p>No listener notification needs to be done in the derived class.</p>
889 <p>Normally, you won't override this method, but <member>getDefaultForReset</member> instead.</p>
891 @see getDefaultForReset
893 virtual void resetNoBroadcast();
895 virtual css::uno::Sequence< css::uno::Type> _getTypes() override;
897 /// sets m_xField to the given new value, without notifying our listeners
898 void impl_setField_noNotify(
899 const css::uno::Reference< css::beans::XPropertySet>& _rxField
901 bool hasField() const
903 return m_xField.is();
905 sal_Int32 getFieldType() const
907 return m_nFieldType;
910 // OControlModel's property handling
911 virtual void describeFixedProperties(
912 css::uno::Sequence< css::beans::Property >& /* [out] */ _rProps
913 ) const override;
915 public:
916 const css::uno::Reference< css::beans::XPropertySet>& getField() const
918 return m_xField;
921 public:
922 // UNO link
923 DECLARE_UNO3_AGG_DEFAULTS(OBoundControlModel, OControlModel)
924 virtual css::uno::Any SAL_CALL queryAggregation( const css::uno::Type& _rType ) override;
926 // OComponentHelper
927 virtual void SAL_CALL disposing() override;
929 // XReset
930 virtual void SAL_CALL reset( ) override;
931 virtual void SAL_CALL addResetListener( const css::uno::Reference< css::form::XResetListener >& aListener ) override;
932 virtual void SAL_CALL removeResetListener( const css::uno::Reference< css::form::XResetListener >& aListener ) override;
934 // XServiceInfo
935 virtual css::uno::Sequence<OUString> SAL_CALL getSupportedServiceNames( ) override;
937 // XServiceInfo - static version
938 /// @throws css::uno::RuntimeException
939 static css::uno::Sequence<OUString> getSupportedServiceNames_Static();
941 // XChild
942 virtual void SAL_CALL setParent( const css::uno::Reference< css::uno::XInterface >& Parent ) override;
944 // XPersistObject
945 virtual void SAL_CALL write( const css::uno::Reference< css::io::XObjectOutputStream >& OutStream ) override;
946 virtual void SAL_CALL read( const css::uno::Reference< css::io::XObjectInputStream >& InStream ) override;
948 // XBoundComponent
949 virtual sal_Bool SAL_CALL commit() override;
951 // XUpdateBroadcaster (base of XBoundComponent)
952 virtual void SAL_CALL addUpdateListener( const css::uno::Reference< css::form::XUpdateListener >& aListener ) override;
953 virtual void SAL_CALL removeUpdateListener( const css::uno::Reference< css::form::XUpdateListener >& aListener ) override;
955 // XPropertySet
956 virtual void SAL_CALL getFastPropertyValue(css::uno::Any& rValue, sal_Int32 nHandle) const override;
957 virtual sal_Bool SAL_CALL convertFastPropertyValue(
958 css::uno::Any& _rConvertedValue, css::uno::Any& _rOldValue, sal_Int32 _nHandle, const css::uno::Any& _rValue ) override;
959 virtual void SAL_CALL setFastPropertyValue_NoBroadcast( sal_Int32 nHandle, const css::uno::Any& rValue ) override;
960 using ::cppu::OPropertySetHelper::getFastPropertyValue;
962 // css::beans::XPropertyState
963 virtual css::uno::Any getPropertyDefaultByHandle( sal_Int32 nHandle ) const override;
965 // XEventListener
966 virtual void SAL_CALL disposing(const css::lang::EventObject& Source) override;
968 // XPropertyChangeListener
969 virtual void SAL_CALL propertyChange( const css::beans::PropertyChangeEvent& evt ) override;
971 // XRowSetChangeListener
972 virtual void SAL_CALL onRowSetChanged( const css::lang::EventObject& i_Event ) override;
974 // XLoadListener
975 virtual void SAL_CALL loaded( const css::lang::EventObject& aEvent ) override;
976 virtual void SAL_CALL unloading( const css::lang::EventObject& aEvent ) override;
977 virtual void SAL_CALL unloaded( const css::lang::EventObject& aEvent ) override;
978 virtual void SAL_CALL reloading( const css::lang::EventObject& aEvent ) override;
979 virtual void SAL_CALL reloaded( const css::lang::EventObject& aEvent ) override;
981 protected:
982 // XBindableValue
983 virtual void SAL_CALL setValueBinding( const css::uno::Reference< css::form::binding::XValueBinding >& _rxBinding ) override;
984 virtual css::uno::Reference< css::form::binding::XValueBinding > SAL_CALL getValueBinding( ) override;
986 // XModifyListener
987 virtual void SAL_CALL modified( const css::lang::EventObject& _rEvent ) override;
989 // XValidatable
990 virtual void SAL_CALL setValidator( const css::uno::Reference< css::form::validation::XValidator >& Validator ) override;
991 virtual css::uno::Reference< css::form::validation::XValidator > SAL_CALL getValidator( ) override;
993 // XValidityConstraintListener
994 virtual void SAL_CALL validityConstraintChanged( const css::lang::EventObject& Source ) override;
996 // XValidatableFormComponent
997 virtual sal_Bool SAL_CALL isValid( ) override;
998 virtual css::uno::Any SAL_CALL getCurrentValue( ) override;
999 virtual void SAL_CALL addFormComponentValidityListener( const css::uno::Reference< css::form::validation::XFormComponentValidityListener >& Listener ) override;
1000 virtual void SAL_CALL removeFormComponentValidityListener( const css::uno::Reference< css::form::validation::XFormComponentValidityListener >& Listener ) override;
1002 protected:
1003 // OPropertyChangeListener
1004 virtual void
1005 _propertyChanged( const css::beans::PropertyChangeEvent& _rEvt ) override;
1007 /// checks whether we currently have an external value binding in place
1008 bool hasExternalValueBinding() const { return m_xExternalBinding.is(); }
1010 // checks whether we currently have an external validator
1011 bool hasValidator() const { return m_xValidator.is(); }
1013 /** transfers the very current value of the db column we're bound to the control
1014 @precond
1015 our own mutex is locked
1016 @precond
1017 we don't have an external binding in place
1019 void transferDbValueToControl( );
1021 /** transfers the current value of the active external binding to the control
1022 @precond
1023 we do have an active external binding in place
1025 void transferExternalValueToControl( ControlModelLock& _rInstanceLock );
1027 /** transfers the control value to the external binding
1028 @precond
1029 our own mutex is locked, and _rInstanceLock is the guard locking it
1030 @precond
1031 we do have an active external binding in place
1033 void transferControlValueToExternal( ControlModelLock& _rInstanceLock );
1035 /** calculates the type which is to be used to communicate with the current external binding,
1036 and stores it in m_aExternalValueType
1038 The method checks the possible type candidates as returned by getSupportedBindingTypes,
1039 and the types supported by the current external binding, if any.
1041 void calculateExternalValueType();
1043 /** returns the type which should be used to exchange data with our external value binding
1045 @see initValueProperty
1047 const css::uno::Type&
1048 getExternalValueType() const { return m_aExternalValueType; }
1050 /** initializes the control from m_xField
1052 Basically, this method calls transferDbValueToControl - but only if our cursor is positioned
1053 on a valid row. Otherwise, the control is reset.
1055 @precond
1056 m_xField is not <NULL/>
1058 void initFromField( const css::uno::Reference< css::sdbc::XRowSet>& _rxForm );
1060 private:
1061 void connectToField( const css::uno::Reference< css::sdbc::XRowSet>& _rxForm );
1062 void resetField();
1064 /** does a new validation of the control value
1066 If necessary, our <member>m_bIsCurrentValueValid</member> member will be adjusted,
1067 and changes will be notified.
1069 Note that it's not necessary that we're connected to a validator. If we are not,
1070 it's assumed that our value is valid, and this is handled appropriately.
1072 Use this method if there is a potential that <b>only</b> the validity flag changed. If
1073 any of the other aspects (our current value, or our current text) changed, then
1074 pass <TRUE/> for <member>_bForceNotification</member>.
1076 @param _bForceNotification
1077 if <TRUE/>, then the validity listeners will be notified, not matter whether the validity
1078 changed.
1080 void recheckValidity( bool _bForceNotification );
1082 /// initializes m_pAggPropMultiplexer
1083 void implInitAggMultiplexer( );
1085 /// initializes listening at the value property
1086 void implInitValuePropertyListening( ) const;
1088 /** adds or removes the component as load listener to/from our form, and (if necessary) as RowSetChange listener at
1089 our parent.
1091 @precond there must no external value binding be in place
1093 void doFormListening( const bool _bStart );
1095 bool isFormListening() const { return m_bFormListening; }
1097 /** determines the new value of m_xAmbientForm
1099 void impl_determineAmbientForm_nothrow();
1101 /** connects to a value supplier which is a database column.
1103 The column is taken from our parent, which must be a database form respectively row set.
1105 @precond The control does not have an external value supplier
1107 @param _bFromReload
1108 Determines whether the connection is made after the row set has been loaded (<FALSE/>)
1109 or reloaded (<TRUE/>)
1111 @see impl_disconnectDatabaseColumn_noNotify
1113 void impl_connectDatabaseColumn_noNotify(
1114 bool _bFromReload
1117 /** disconnects from a value supplier which is a database column
1119 @precond The control does not have an external value supplier
1120 @see impl_connectDatabaseColumn_noNotify
1122 void impl_disconnectDatabaseColumn_noNotify();
1124 /** connects to an external value binding
1126 <p>Note that by definition, external data bindings supersede the SQL data binding which
1127 is defined by our RowSet-column-related properties. This means that in case we're currently
1128 connected to a database column when this is called, this connection is suspended.</p>
1130 @precond
1131 the new external binding has already been approved (see <member>impl_approveValueBinding_nolock</member>)
1132 @precond
1133 there currently is no external binding in place
1135 void connectExternalValueBinding(
1136 const css::uno::Reference< css::form::binding::XValueBinding >& _rxBinding,
1137 ControlModelLock& _rInstanceLock
1140 /** disconnects from an external value binding
1142 @precond
1143 there currently is an external binding in place
1145 void disconnectExternalValueBinding( );
1147 /** connects the component to an external validator
1149 @precond
1150 there currently is no active validator
1151 @precond
1152 our mutex is currently locked exactly once
1154 void connectValidator(
1155 const css::uno::Reference< css::form::validation::XValidator >& _rxValidator
1158 /** disconnects the component from its current an external validator
1160 @precond
1161 there currently is an active validator
1162 @precond
1163 our mutex is currently locked exactly once
1165 void disconnectValidator( );
1167 /** called from within <member scope="css:::form::binding">XBindableValue::setValueBinding</member>
1168 to approve the new binding
1170 The default implementation approves the binding if and only if it is not <NULL/>, and supports
1171 the type returned by getExternalValueType.
1173 @param _rxBinding
1174 the binding which applies for being responsible for our value, Must not be
1175 <NULL/>
1176 @return
1177 <TRUE/> if and only if the given binding can supply values in the proper type
1179 @seealso getExternalValueType
1181 bool impl_approveValueBinding_nolock(
1182 const css::uno::Reference< css::form::binding::XValueBinding >& _rxBinding
1187 //= inlines
1189 inline void ControlModelLock::acquire()
1191 m_rModel.lockInstance( OControlModel::LockAccess() );
1192 m_bLocked = true;
1194 inline void ControlModelLock::release()
1196 OSL_ENSURE( m_bLocked, "ControlModelLock::release: not locked!" );
1197 m_bLocked = false;
1199 if ( 0 == m_rModel.unlockInstance( OControlModel::LockAccess() ) )
1200 impl_notifyAll_nothrow();
1207 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */