/************************************************************************* * * OpenOffice.org - a multi-platform office productivity suite * * $RCSfile: FormComponent.hxx,v $ * * $Revision: 1.10 $ * * last change: $Author: obo $ $Date: 2005-12-21 13:23:20 $ * * The Contents of this file are made available subject to * the terms of GNU Lesser General Public License Version 2.1. * * * GNU Lesser General Public License Version 2.1 * ============================================= * Copyright 2005 by Sun Microsystems, Inc. * 901 San Antonio Road, Palo Alto, CA 94303, USA * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License version 2.1, as published by the Free Software Foundation. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, * MA 02111-1307 USA * ************************************************************************/ #ifndef _FORMS_FORMCOMPONENT_HXX_ #define _FORMS_FORMCOMPONENT_HXX_ #ifndef _OSL_MUTEX_HXX_ #include #endif #ifndef _RTL_USTRING_HXX_ #include #endif #ifndef _CPPUHELPER_COMPONENT_HXX_ #include #endif #ifndef _CPPUHELPER_IMPLBASE1_HXX_ #include #endif #ifndef _CPPUHELPER_IMPLBASE2_HXX_ #include #endif #ifndef _CPPUHELPER_IMPLBASE3_HXX_ #include #endif #ifndef _CPPUHELPER_IMPLBASE4_HXX_ #include #endif #ifndef _CPPUHELPER_IMPLBASE5_HXX_ #include #endif #ifndef _COM_SUN_STAR_AWT_XCONTROL_HPP_ #include #endif #ifndef _COM_SUN_STAR_UNO_XAGGREGATION_HPP_ #include #endif #ifndef _COM_SUN_STAR_LANG_XEVENTLISTENER_HPP_ #include #endif #ifndef _COM_SUN_STAR_LANG_XSERVICEINFO_HPP_ #include #endif #ifndef _COM_SUN_STAR_LANG_XMULTISERVICEFACTORY_HPP_ #include #endif #ifndef _COM_SUN_STAR_FORM_XBOUNDCONTROL_HPP_ #include #endif #ifndef _COM_SUN_STAR_IO_XPERSISTOBJECT_HPP_ #include #endif #ifndef _COM_SUN_STAR_IO_XMARKABLESTREAM_HPP_ #include #endif #ifndef _COM_SUN_STAR_CONTAINER_XNAMED_HPP_ #include #endif #ifndef _COM_SUN_STAR_CONTAINER_XCHILD_HPP_ #include #endif #ifndef _COM_SUN_STAR_FORM_XFORMCOMPONENT_HPP_ #include #endif #ifndef _COM_SUN_STAR_FORM_XBOUNDCOMPONENT_HPP_ #include #endif #ifndef _COM_SUN_STAR_FORM_XLOADLISTENER_HPP_ #include #endif #ifndef _COM_SUN_STAR_FORM_XRESET_HPP_ #include #endif #ifndef _COM_SUN_STAR_SDBC_XROWSET_HPP_ #include #endif #ifndef _COM_SUN_STAR_SDB_XCOLUMN_HPP_ #include #endif #ifndef _COM_SUN_STAR_SDB_XCOLUMNUPDATE_HPP_ #include #endif #ifndef _COM_SUN_STAR_SDBCX_XCOLUMNSSUPPLIER_HPP_ #include #endif #ifndef _COM_SUN_STAR_FORM_FORMCOMPONENTTYPE_HPP_ #include #endif #ifndef _COM_SUN_STAR_UTIL_XCLONEABLE_HPP_ #include #endif #ifndef _COM_SUN_STAR_FORM_BINDING_XBINDABLEVALUE_HPP_ #include #endif #ifndef _COM_SUN_STAR_LANG_DISPOSEDEXCEPTION_HPP_ #include #endif #ifndef _COM_SUN_STAR_UTIL_XMODIFYLISTENER_HPP_ #include #endif #ifndef _COM_SUN_STAR_FORM_VALIDATION_XVALIDITYCONSTRAINTLISTENER_HPP_ #include #endif #ifndef _COM_SUN_STAR_FORM_VALIDATION_XVALIDATABLEFORMCOMPONENT_HPP_ #include #endif #ifndef _COMPHELPER_PROPERTY_AGGREGATION_HXX_ #include #endif #ifndef _COMPHELPER_PROPERTY_ARRAY_HELPER_HXX_ #include #endif #ifndef _COMPHELPER_UNO3_HXX_ #include #endif #ifndef _COMPHELPER_SEQUENCE_HXX_ #include #endif #ifndef _FRM_SERVICES_HXX_ #include "services.hxx" #endif #ifndef _FRM_PROPERTY_HRC_ #include "property.hrc" #endif #ifndef _FRM_PROPERTY_HXX_ #include "property.hxx" #endif #ifndef _FRM_IDS_HXX_ #include "ids.hxx" #endif #ifndef FORMS_COMPONENT_CLONEABLE_HXX #include "cloneable.hxx" #endif #ifndef _COMPHELPER_PROPERTY_MULTIPLEX_HXX_ #include #endif #include //......................................................................... namespace frm { //......................................................................... class OFormComponentListeners; // default tab index for components const sal_Int16 FRM_DEFAULT_TABINDEX = 0; // macros for quickly declaring/implementing XServiceInfo #define DECLARE_XPERSISTOBJECT() \ virtual ::rtl::OUString SAL_CALL getServiceName() throw(::com::sun::star::uno::RuntimeException); \ virtual void SAL_CALL write(const ::com::sun::star::uno::Reference< ::com::sun::star::io::XObjectOutputStream>& _rxOutStream) throw(::com::sun::star::io::IOException, ::com::sun::star::uno::RuntimeException); \ virtual void SAL_CALL read(const ::com::sun::star::uno::Reference< ::com::sun::star::io::XObjectInputStream>& _rxInStream) throw(::com::sun::star::io::IOException, ::com::sun::star::uno::RuntimeException); \ // old macro for quickly implementing XServiceInfo::getImplementationName #define IMPLEMENTATION_NAME(ImplName) \ virtual ::rtl::OUString SAL_CALL getImplementationName( ) throw(::com::sun::star::uno::RuntimeException) \ { return ::rtl::OUString::createFromAscii("com.sun.star.comp.forms.") + ::rtl::OUString::createFromAscii(#ImplName); } // macro for overriding the getInfoServive method of OAggregationArrayUsageHelper #define IMPLEMENT_INFO_SERVICE() \ virtual IPropertyInfoService* getInfoService() const { return &s_aPropInfos; } //========================================================================= //= OControl //= base class for form layer controls //========================================================================= typedef ::cppu::ImplHelper3 < ::com::sun::star::awt::XControl , ::com::sun::star::lang::XEventListener , ::com::sun::star::lang::XServiceInfo > OControl_BASE; class OControl :public ::cppu::OComponentHelper ,public OControl_BASE { protected: osl::Mutex m_aMutex; OImplementationIdsRef m_aHoldIdHelper; ::com::sun::star::uno::Reference< ::com::sun::star::awt::XControl > m_xControl; ::com::sun::star::uno::Reference< ::com::sun::star::uno::XAggregation> m_xAggregate; ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory > m_xServiceFactory; public: /** constructs a control @param _rFactory the service factory for this control @param _rAggregateService the service name of the component to aggregate @param _bSetDelegator set this to if you don't want the constructor to set the delegator at the aggregate. In this case, you have to call doSetDelegator within your own constructor. This is helpfull, if your derived class wants to cache an interface of the aggregate. In this case, the aggregate needs to be queried for this interface before the XAggregation::setDelegator call. In such a case, pass to this parameter. Then, cache the aggregate's interface(s) as needed. Afterwards, call doSetDelegator. In your destructor, you need to call doResetDelegator before resetting the cached interfaces. This will reset the aggregates delegator to , which will ensure that the XInterface::release calls on the cached interfaces are really applied to the aggregate, instead of the OControl itself. */ OControl( const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory >& _rFactory, const ::rtl::OUString& _rAggregateService, const sal_Bool _bSetDelegator = sal_True ); virtual ~OControl(); protected: /** sets the control as delegator at the aggregate This has to be called from within your derived class' constructor, if and only if you passed to the _bSetDelegator parameter of the OControl constructor. */ void doSetDelegator(); void doResetDelegator(); // UNO DECLARE_UNO3_AGG_DEFAULTS(OControl, OComponentHelper); virtual ::com::sun::star::uno::Any SAL_CALL queryAggregation( const ::com::sun::star::uno::Type& _rType ) throw(::com::sun::star::uno::RuntimeException); // XTypeProvider virtual ::com::sun::star::uno::Sequence SAL_CALL getImplementationId() throw(::com::sun::star::uno::RuntimeException); virtual ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Type> SAL_CALL getTypes() throw(::com::sun::star::uno::RuntimeException); // OComponentHelper virtual void SAL_CALL disposing(); // XComponent (as base of XControl) virtual void SAL_CALL dispose( ) throw(::com::sun::star::uno::RuntimeException) { OComponentHelper::dispose(); } virtual void SAL_CALL addEventListener( const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XEventListener>& _rxListener) throw(::com::sun::star::uno::RuntimeException) { OComponentHelper::addEventListener(_rxListener); } virtual void SAL_CALL removeEventListener( const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XEventListener>& _rxListener) throw(::com::sun::star::uno::RuntimeException) { OComponentHelper::removeEventListener(_rxListener); } // XEventListener virtual void SAL_CALL disposing(const ::com::sun::star::lang::EventObject& Source) throw (::com::sun::star::uno::RuntimeException); // XServiceInfo virtual sal_Bool SAL_CALL supportsService(const ::rtl::OUString& ServiceName) throw (::com::sun::star::uno::RuntimeException); virtual StringSequence SAL_CALL getSupportedServiceNames() throw(::com::sun::star::uno::RuntimeException); virtual ::rtl::OUString SAL_CALL getImplementationName() throw(::com::sun::star::uno::RuntimeException) = 0; // XServiceInfo - static version static StringSequence SAL_CALL getSupportedServiceNames_Static() throw(::com::sun::star::uno::RuntimeException); // XControl virtual void SAL_CALL setContext(const InterfaceRef& Context) throw (::com::sun::star::uno::RuntimeException); virtual InterfaceRef SAL_CALL getContext() throw (::com::sun::star::uno::RuntimeException); virtual void SAL_CALL createPeer(const ::com::sun::star::uno::Reference& Toolkit, const ::com::sun::star::uno::Reference& Parent) throw (::com::sun::star::uno::RuntimeException); virtual ::com::sun::star::uno::Reference SAL_CALL getPeer() throw (::com::sun::star::uno::RuntimeException); virtual sal_Bool SAL_CALL setModel(const ::com::sun::star::uno::Reference& Model) throw (::com::sun::star::uno::RuntimeException); virtual ::com::sun::star::uno::Reference SAL_CALL getModel() throw (::com::sun::star::uno::RuntimeException); virtual ::com::sun::star::uno::Reference SAL_CALL getView() throw (::com::sun::star::uno::RuntimeException); virtual void SAL_CALL setDesignMode(sal_Bool bOn) throw (::com::sun::star::uno::RuntimeException); virtual sal_Bool SAL_CALL isDesignMode() throw (::com::sun::star::uno::RuntimeException); virtual sal_Bool SAL_CALL isTransparent() throw (::com::sun::star::uno::RuntimeException); protected: virtual ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Type> _getTypes(); // overwrite this and call the base class if you have additional types ::com::sun::star::uno::Sequence< ::rtl::OUString > getAggregateServiceNames(); }; //================================================================== //= OBoundControl //= a form control implementing the XBoundControl interface //================================================================== typedef ::cppu::ImplHelper1 < ::com::sun::star::form::XBoundControl > OBoundControl_BASE; class OBoundControl :public OControl ,public OBoundControl_BASE { protected: sal_Bool m_bLocked : 1; ::rtl::OUString m_sOriginalHelpText; // as long as the text/value is invalid, we change the help text of our peer ::com::sun::star::awt::FontDescriptor m_aOriginalFont; // as long as the text/value is invalid, we also change the font sal_Int32 m_nOriginalTextLineColor; // (we add red underlining) public: OBoundControl( const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory >& _rxFactory, const ::rtl::OUString& _rAggregateService, const sal_Bool _bSetDelegator = sal_True ); virtual ~OBoundControl(); DECLARE_UNO3_AGG_DEFAULTS(OBoundControl, OControl); virtual ::com::sun::star::uno::Any SAL_CALL queryAggregation( const ::com::sun::star::uno::Type& _rType ) throw(::com::sun::star::uno::RuntimeException); // XBoundControl virtual sal_Bool SAL_CALL getLock() throw(::com::sun::star::uno::RuntimeException); virtual void SAL_CALL setLock(sal_Bool _bLock) throw(::com::sun::star::uno::RuntimeException); // default implementation just disables the controls, overwrite _setLock to change this behaviour // XControl virtual sal_Bool SAL_CALL setModel(const ::com::sun::star::uno::Reference< ::com::sun::star::awt::XControlModel >& Model) throw (::com::sun::star::uno::RuntimeException); // XEventListener virtual void SAL_CALL disposing(const ::com::sun::star::lang::EventObject& Source) throw (::com::sun::star::uno::RuntimeException); // OComponentHelper virtual void SAL_CALL disposing(); protected: virtual ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Type> _getTypes(); // implement the lock setting virtual void _setLock(sal_Bool _bLock); }; //================================================================== //= OControlModel //= model of a form layer control //================================================================== typedef ::cppu::ImplHelper5 < ::com::sun::star::form::XFormComponent , ::com::sun::star::io::XPersistObject , ::com::sun::star::container::XNamed , ::com::sun::star::lang::XServiceInfo , ::com::sun::star::util::XCloneable > OControlModel_BASE; class OControlModel :public ::cppu::OComponentHelper ,public OPropertySetAggregationHelper ,public OControlModel_BASE ,public OCloneableAggregation { protected: ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory> m_xServiceFactory; ::osl::Mutex m_aMutex; InterfaceRef m_xParent; // ParentComponent OImplementationIdsRef m_aHoldIdHelper; static ConcretInfoService s_aPropInfos; const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory >& getORB( ) const { return m_xServiceFactory; } // ::rtl::OUString m_aName; // name of the control ::rtl::OUString m_aTag; // tag for additional data sal_Int16 m_nTabIndex; // index within the taborder sal_Int16 m_nClassId; // type of the control sal_Bool m_bNativeLook; // should the control use the native platform look? // protected: OControlModel( const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory>& _rFactory, // factory to create the aggregate with const ::rtl::OUString& _rUnoControlModelTypeName, // service name of te model to aggregate const ::rtl::OUString& rDefault = ::rtl::OUString(), // service name of the default control const sal_Bool _bSetDelegator = sal_True // set to FALSE if you want to call setDelegator later (after returning from this ctor) ); OControlModel( const OControlModel* _pOriginal, // the original object to clone const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory>& _rFactory, // factory to create the aggregate with const sal_Bool _bCloneAggregate = sal_True, // should the aggregate of the original be cloned, too? const sal_Bool _bSetDelegator = sal_True // set to FALSE if you want to call setDelegator later (after returning from this ctor) ); virtual ~OControlModel(); /** to be called after a OBoundControlModel (a derivee, respectively) has been cloned

This method contains late initializations which cannot be done in the constructor of this base class, since the virtual method of derived classes do not yet work there.

*/ virtual void clonedFrom( const OControlModel* _pOriginal ); using OComponentHelper::rBHelper; virtual ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Type> _getTypes(); void readHelpTextCompatibly(const ::com::sun::star::uno::Reference< ::com::sun::star::io::XObjectInputStream >& _rxInStream); void writeHelpTextCompatibly(const ::com::sun::star::uno::Reference< ::com::sun::star::io::XObjectOutputStream >& _rxOutStream); void doSetDelegator(); void doResetDelegator(); /** checks if the object is still alive @throws ::com::sun::star::lang::DisposedException if the object is already disposed */ void ensureAlive() SAL_THROW( ( ::com::sun::star::lang::DisposedException ) ); ::com::sun::star::uno::Sequence< ::rtl::OUString > getAggregateServiceNames(); // OPropertySetAggregationHelper virtual void fillProperties( ::com::sun::star::uno::Sequence< ::com::sun::star::beans::Property >& /* [out] */ _rProps, ::com::sun::star::uno::Sequence< ::com::sun::star::beans::Property >& /* [out] */ _rAggregateProps ) const; public: DECLARE_UNO3_AGG_DEFAULTS(OControl, OComponentHelper); virtual ::com::sun::star::uno::Any SAL_CALL queryAggregation( const ::com::sun::star::uno::Type& _rType ) throw (::com::sun::star::uno::RuntimeException); // XTypeProvider virtual ::com::sun::star::uno::Sequence SAL_CALL getImplementationId() throw(::com::sun::star::uno::RuntimeException); virtual ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Type> SAL_CALL getTypes() throw(::com::sun::star::uno::RuntimeException); // OComponentHelper virtual void SAL_CALL disposing(); // XNamed virtual ::rtl::OUString SAL_CALL getName() throw(::com::sun::star::uno::RuntimeException); virtual void SAL_CALL setName(const ::rtl::OUString& aName) throw(::com::sun::star::uno::RuntimeException); // XServiceInfo virtual sal_Bool SAL_CALL supportsService(const ::rtl::OUString& ServiceName) throw (::com::sun::star::uno::RuntimeException); virtual StringSequence SAL_CALL getSupportedServiceNames() throw(::com::sun::star::uno::RuntimeException); virtual ::rtl::OUString SAL_CALL getImplementationName() throw(::com::sun::star::uno::RuntimeException) = 0; // XSericeInfo - static version(s) static StringSequence SAL_CALL getSupportedServiceNames_Static() throw(::com::sun::star::uno::RuntimeException); // XPersistObject virtual ::rtl::OUString SAL_CALL getServiceName() throw(::com::sun::star::uno::RuntimeException) = 0; virtual void SAL_CALL write(const ::com::sun::star::uno::Reference< ::com::sun::star::io::XObjectOutputStream>& _rxOutStream) throw(::com::sun::star::io::IOException, ::com::sun::star::uno::RuntimeException); virtual void SAL_CALL read(const ::com::sun::star::uno::Reference< ::com::sun::star::io::XObjectInputStream>& _rxInStream) throw(::com::sun::star::io::IOException, ::com::sun::star::uno::RuntimeException); // XChild (base of XFormComponent) virtual InterfaceRef SAL_CALL getParent() throw(::com::sun::star::uno::RuntimeException); virtual void SAL_CALL setParent(const InterfaceRef& Parent) throw(::com::sun::star::lang::NoSupportException, ::com::sun::star::uno::RuntimeException); // XEventListener virtual void SAL_CALL disposing(const ::com::sun::star::lang::EventObject& Source) throw (::com::sun::star::uno::RuntimeException); // XPropertySet virtual void SAL_CALL getFastPropertyValue(::com::sun::star::uno::Any& rValue, sal_Int32 nHandle) const; virtual sal_Bool SAL_CALL convertFastPropertyValue( ::com::sun::star::uno::Any& _rConvertedValue, ::com::sun::star::uno::Any& _rOldValue, sal_Int32 _nHandle, const ::com::sun::star::uno::Any& _rValue ) throw (::com::sun::star::lang::IllegalArgumentException); virtual void SAL_CALL setFastPropertyValue_NoBroadcast( sal_Int32 nHandle, const ::com::sun::star::uno::Any& rValue ) throw (::com::sun::star::uno::Exception); // ::com::sun::star::beans::XPropertyState virtual ::com::sun::star::beans::PropertyState getPropertyStateByHandle(sal_Int32 nHandle); virtual void setPropertyToDefaultByHandle(sal_Int32 nHandle); virtual ::com::sun::star::uno::Any getPropertyDefaultByHandle( sal_Int32 nHandle ) const; // XCloneable virtual ::com::sun::star::uno::Reference< ::com::sun::star::util::XCloneable > SAL_CALL createClone( ) throw (::com::sun::star::uno::RuntimeException) = 0; protected: virtual void writeAggregate( const ::com::sun::star::uno::Reference< ::com::sun::star::io::XObjectOutputStream >& _rxOutStream ) const; virtual void readAggregate( const ::com::sun::star::uno::Reference< ::com::sun::star::io::XObjectInputStream >& _rxInStream ); }; //================================================================== // simple destructor #define DECLARE_DEFAULT_DTOR( classname ) \ ~classname() \ // constructor for cloning a class #define DECLARE_DEFAULT_CLONE_CTOR( classname ) \ classname( \ const classname* _pOriginal, \ const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory>& _rxFactory \ ); \ // all xtors for an inner class of the object hierarchy #define DECLARE_DEFAULT_XTOR( classname ) \ classname( \ const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory>& _rxFactory, \ const ::rtl::OUString& _rUnoControlModelTypeName, \ const ::rtl::OUString& _rDefault \ ); \ DECLARE_DEFAULT_CLONE_CTOR( classname ) \ DECLARE_DEFAULT_DTOR( classname ) \ // all xtors for an inner class of the object hierarchy which is *bound* #define DECLARE_DEFAULT_BOUND_XTOR( classname ) \ classname( \ const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory>& _rxFactory, \ const ::rtl::OUString& _rUnoControlModelTypeName, \ const ::rtl::OUString& _rDefault, \ const sal_Bool _bSupportExternalBinding, \ const sal_Bool _bSupportsValidation \ ); \ DECLARE_DEFAULT_CLONE_CTOR( classname ) \ DECLARE_DEFAULT_DTOR( classname ) \ // all xtors for a leas class of the object hierarchy #define DECLARE_DEFAULT_LEAF_XTOR( classname ) \ classname( \ const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory>& _rxFactory \ ); \ classname( \ const classname* _pOriginal, \ const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory>& _rxFactory \ ); \ DECLARE_DEFAULT_DTOR( classname ) \ //================================================================== // XCloneable #define DECLARE_XCLONEABLE( ) \ virtual ::com::sun::star::uno::Reference< ::com::sun::star::util::XCloneable > SAL_CALL createClone( ) throw (::com::sun::star::uno::RuntimeException) #define IMPLEMENT_DEFAULT_CLONING( classname ) \ ::com::sun::star::uno::Reference< ::com::sun::star::util::XCloneable > SAL_CALL classname::createClone( ) throw (::com::sun::star::uno::RuntimeException) \ { \ classname* pClone = new classname( this, getORB() ); \ pClone->clonedFrom( this ); \ return pClone; \ } //================================================================== //= OBoundControlModel //= model of a form layer control which is bound to a data source field //================================================================== typedef ::cppu::ImplHelper3 < ::com::sun::star::form::XLoadListener , ::com::sun::star::form::XReset , ::com::sun::star::beans::XPropertyChangeListener > OBoundControlModel_BASE1; // separated into an own base class since derivees can disable the support for this // interface, thus we want to easily exclude it in the queryInterface and getTypes typedef ::cppu::ImplHelper1 < ::com::sun::star::form::XBoundComponent > OBoundControlModel_COMMITTING; // dito typedef ::cppu::ImplHelper2 < ::com::sun::star::form::binding::XBindableValue , ::com::sun::star::util::XModifyListener > OBoundControlModel_BINDING; // dito typedef ::cppu::ImplHelper2 < ::com::sun::star::form::validation::XValidityConstraintListener , ::com::sun::star::form::validation::XValidatableFormComponent > OBoundControlModel_VALIDATION; class OBoundControlModel :public OControlModel ,public OBoundControlModel_BASE1 ,public OBoundControlModel_COMMITTING ,public OBoundControlModel_BINDING ,public OBoundControlModel_VALIDATION ,public ::comphelper::OPropertyChangeListener { protected: enum ValueChangeInstigator { eDbColumnBinding, eExternalBinding, eOther }; private: ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertySet > m_xField; ::rtl::OUString m_sValuePropertyName; sal_Int32 m_nValuePropertyAggregateHandle; cppu::OInterfaceContainerHelper m_aUpdateListeners; cppu::OInterfaceContainerHelper m_aResetListeners; ::std::auto_ptr< OFormComponentListeners > m_pFormComponentListeners; ::com::sun::star::uno::Reference< ::com::sun::star::form::binding::XValueBinding > m_xExternalBinding; ::com::sun::star::uno::Reference< ::com::sun::star::form::validation::XValidator > m_xValidator; // ::rtl::OUString m_aControlSource; // Datenquelle, Name des Feldes ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertySet > m_xLabelControl; // reference to a sibling control (model) which is our label // ::comphelper::OPropertyChangeMultiplexer* m_pAggPropMultiplexer; sal_Bool m_bLoadListening : 1; // are we currently a load listener at our parent form? sal_Bool m_bLoaded : 1; sal_Bool m_bRequired : 1; sal_Bool m_bCommitable : 1; // do we support XBoundComponent? sal_Bool m_bSupportsExternalBinding : 1; // do we support XBindableValue? sal_Bool m_bSupportsValidation : 1; // do we support XValidatable? sal_Bool m_bForwardValueChanges : 1; // do we currently handle changes in the bound database field? sal_Bool m_bTransferingValue : 1; // true if we're currently transfering our value to an external binding sal_Bool m_bIsCurrentValueValid : 1; // flag specifying whether our current value is valid, relative to our external validator sal_Bool m_bBindingControlsRO : 1; // is our ReadOnly property currently controlled by our external binding? sal_Bool m_bBindingControlsEnable : 1; // is our Enabled property currently controlled by our external binding? ValueChangeInstigator m_eControlValueChangeInstigator; protected: ::rtl::OUString m_aLabelServiceName; // when setting the label for our control (property FM_PROP_CONTROLLABEL, member m_xLabelControl), // we accept only objects supporting an XControlModel interface, an XServiceInfo interface and // support for a service (XServiceInfo::supportsService) determined by this string. // Any other arguments will throw an IllegalArgumentException. // The default value is FM_COMPONENT_FIXEDTEXT. ::com::sun::star::uno::Reference< ::com::sun::star::sdbc::XRowSet > m_xCursor; ::com::sun::star::uno::Reference< ::com::sun::star::sdb::XColumnUpdate > m_xColumnUpdate; ::com::sun::star::uno::Reference< ::com::sun::star::sdb::XColumn > m_xColumn; protected: inline const ::rtl::OUString& getValuePropertyName( ) const { return m_sValuePropertyName; } inline sal_Int32 getValuePropertyAggHandle( ) const { return m_nValuePropertyAggregateHandle; } inline const ::rtl::OUString& getControlSource( ) const { return m_aControlSource; } inline sal_Bool isRequired() const { return m_bRequired; } inline sal_Bool isLoaded() const { return m_bLoaded; } inline const ::com::sun::star::uno::Reference< ::com::sun::star::form::binding::XValueBinding >& getExternalValueBinding() const { return m_xExternalBinding; } protected: OBoundControlModel( const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory>& _rFactory, // factory to create the aggregate with const ::rtl::OUString& _rUnoControlModelTypeName, // service name of te model to aggregate const ::rtl::OUString& _rDefault, // service name of the default control const sal_Bool _bCommitable, // is the control (model) commitable ? const sal_Bool _bSupportExternalBinding, // set to TRUE if you want to support XBindableValue const sal_Bool _bSupportsValidation // set to TRUE if you want to support XValidatable ); OBoundControlModel( const OBoundControlModel* _pOriginal, // the original object to clone const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory>& _rFactory // factory to create the aggregate with ); virtual ~OBoundControlModel(); /// late ctor after cloning virtual void clonedFrom( const OControlModel* _pOriginal ); /** initializes the part of the class which is related to the control value.

Kind of late ctor, to be called for derivees which have a dedicated value property.
The value property is the property which's value is synced with either the database column the object is bound to, or with the external value binding, if present.
E.g. for a text control model, this property will most probably be "Text".

Derived classes are stronly recommend to call this method - at least the "DataFieldProperty" (exposed in getFastPropertyValue) relies on the information given herein, and needs to be supplied otherwise else.

If this method has been called properly, then setControlValue does not need to be overridden - it will simply set the property value at the aggregate then.

@precond The method has not be called before during the life time of the object. @param _rValuePropertyName the name of the value property @param _nValuePropertyExternalHandle the handle of the property, as exposed to external components.
Normally, this information can be obtained dynamically (e.g. from fillProperties), but since this method is to be called from within the constructor of derived classes, we prefer to be on the *really* safe side here .... @see setControlValue @see suspendValueListening @see resumeValueListening @see fillProperties */ void initValueProperty( const ::rtl::OUString& _rValuePropertyName, sal_Int32 _nValuePropertyExternalHandle ); /** suspends listening at the value property

As long as this listening is suspended, changes in the value property will not be recognized and not be handled.

@see initValueProperty @see resumeValueListening */ void suspendValueListening( ); /** resumes listening at the value property

As long as this listening is suspended, changes in the value property will not be recognized and not be handled.

@precond listening at the value property is currently suspended @see initValueProperty @see resumeValueListening */ void resumeValueListening( ); /** starts listening at the aggregate, for changes in the given property

The OBoundControlModel automatically registers a multiplexer which listens for changes in the aggregate property values. By default, only the control value property is observed. You may add additional properties to be observed with this method.

@see initValueProperty @see _propertyChanged */ void startAggregatePropertyListening( const ::rtl::OUString& _rPropertyName ); /** returns the default which should be used when resetting the control

The default implementation returns an empty Any.

@see resetNoBroadcast */ virtual ::com::sun::star::uno::Any getDefaultForReset() const; /** translates a db column value into a control value.

Must transform the very current value of the database column we're bound to (m_xColumn) into a value which can be used as current value for the control.

@see setControlValue @pure */ virtual ::com::sun::star::uno::Any translateDbColumnToControlValue( ) = 0; /** translates the current value of the external value binding (if any) to a value which can be used in setControlValue

The default implementation checks for the type of the value property (see initValueProperty), and if the external binding supports this type, a value of this type is requested from the binding and returned.

@see hasExternalValueBinding @see initValueProperty */ virtual ::com::sun::star::uno::Any translateExternalValueToControlValue( ) const; /** commits the current control value to our external value binding

The default implementation simply calls getControlValue.

@see hasExternalValueBinding @see initValueProperty */ virtual ::com::sun::star::uno::Any translateControlValueToExternalValue( ) const; /** commits the current control value to the database column we're bound to @precond we're properly bound to a database column, especially m_xColumnUpdate is not @param _bPostReset if and only if the current control value results from a reset (getDefaultForReset) @pure */ virtual sal_Bool commitControlValueToDbColumn( bool _bPostReset ) = 0; /** sets the given value as new current value for the control Besides some administrative work (such as caring for m_eControlValueChangeInstigator), this method simply calls doSetControlValue. @precond Our own mutex is locked. @param _rValue The value to set. This value is guaranteed to be created by translateDbColumnToControlValue or translateExternalValueToControlValue @param _eInstigator the instigator of the value change */ void setControlValue( const ::com::sun::star::uno::Any& _rValue, ValueChangeInstigator _eInstigator ); /**

The default implementation will forward the given value to the aggregate, using m_nValuePropertyAggregateHandle and/or m_sValuePropertyName.

@precond Our own mutex is locked. @param _rValue The value to set. This value is guaranteed to be created by translateDbColumnToControlValue or translateExternalValueToControlValue */ virtual void doSetControlValue( const ::com::sun::star::uno::Any& _rValue ); /** retrieves the current value of the control

The default implementation will ask the aggregate for the property value determined by either m_nValuePropertyAggregateHandle and/or m_sValuePropertyName.

@precond Our own mutex is locked. */ virtual ::com::sun::star::uno::Any getControlValue( ) const; /** called whenever a connection to a database column has been established */ virtual void onConnectedDbColumn( const ::com::sun::star::uno::Reference< ::com::sun::star::uno::XInterface >& _rxForm ); /** called whenever a connection to a database column has been suspended */ virtual void onDisconnectedDbColumn(); /** called whenever a connection to an external supplier of values (XValueBinding) has been established @see m_xExternalBinding */ virtual void onConnectedExternalValue( ); /** called whenever a connection to an external supplier of values (XValueBinding) has been suspended */ virtual void onDisconnectedExternalValue(); /** called whenever an external validator has been registered */ virtual void onConnectedValidator( ); /** called whenever an external validator has been revoked */ virtual void onDisconnectedValidator( ); /** nFieldType ist der Typ des Feldes, an das das Model gebunden werden soll. Das Binden erfolgt genau dann, wenn Rueckgabewert sal_True. Die Standard-Implementation erlaubt alles ausser den drei binary-Typen und FieldType_OTHER. */ virtual sal_Bool approveDbColumnType(sal_Int32 _nColumnType); /** called from within XBindableValue::setValueBinding to approve the new binding @param _rxBinding the binding which applies for being responsible for our value, Must not be @return if and only if the given binding can supply values in the proper type */ virtual sal_Bool approveValueBinding( const ::com::sun::star::uno::Reference< ::com::sun::star::form::binding::XValueBinding >& _rxBinding ); /** retrieves the current value of the control, in a shape which can be used with our external validator. The default implementation simply calls >translateControlValueToExternalValue. @precond Our own mutex is locked. */ virtual ::com::sun::star::uno::Any translateControlValueToValidatableValue( ) const; /** We can't write (new) common properties in this base class, as the file format doesn't allow this (unfortunally). So derived classes may use the following to methods. They secure the written data with marks, so any new common properties in newer versions will be skipped by older ones. */ void writeCommonProperties(const ::com::sun::star::uno::Reference< ::com::sun::star::io::XObjectOutputStream>& _rxOutStream); void readCommonProperties(const ::com::sun::star::uno::Reference< ::com::sun::star::io::XObjectInputStream>& _rxInStream); // the next method may be used in derived classes's read when an unknown version is encountered void defaultCommonProperties(); /** called to reset the control to some kind of default.

The semantics of "default" is finally defined by the derived class (in particular, by getDefaultForReset).

No listener notification needs to be done in the derived class.

Normally, you won't override this method, but getDefaultForReset instead.

@see getDefaultForReset */ virtual void resetNoBroadcast(); virtual ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Type> _getTypes(); void setField( const ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertySet>& _rxField,sal_Bool _bFire=sal_True); inline const ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertySet>& getField() const { return m_xField; } // OPropertySetAggregationHelper virtual void fillProperties( ::com::sun::star::uno::Sequence< ::com::sun::star::beans::Property >& /* [out] */ _rProps, ::com::sun::star::uno::Sequence< ::com::sun::star::beans::Property >& /* [out] */ _rAggregateProps ) const; public: // UNO Anbindung DECLARE_UNO3_AGG_DEFAULTS(OBoundControlModel, OControlModel); virtual ::com::sun::star::uno::Any SAL_CALL queryAggregation( const ::com::sun::star::uno::Type& _rType ) throw (::com::sun::star::uno::RuntimeException); // OComponentHelper virtual void SAL_CALL disposing(); // XReset virtual void SAL_CALL reset( ) throw(::com::sun::star::uno::RuntimeException); virtual void SAL_CALL addResetListener( const ::com::sun::star::uno::Reference< ::com::sun::star::form::XResetListener >& aListener ) throw(::com::sun::star::uno::RuntimeException); virtual void SAL_CALL removeResetListener( const ::com::sun::star::uno::Reference< ::com::sun::star::form::XResetListener >& aListener ) throw(::com::sun::star::uno::RuntimeException); // XServiceInfo virtual StringSequence SAL_CALL getSupportedServiceNames( ) throw(::com::sun::star::uno::RuntimeException); // XServiceInfo - static version static StringSequence SAL_CALL getSupportedServiceNames_Static() throw(::com::sun::star::uno::RuntimeException); // XChild virtual void SAL_CALL setParent( const ::com::sun::star::uno::Reference< ::com::sun::star::uno::XInterface >& Parent ) throw(::com::sun::star::lang::NoSupportException, ::com::sun::star::uno::RuntimeException); // XPersistObject virtual void SAL_CALL write( const ::com::sun::star::uno::Reference< ::com::sun::star::io::XObjectOutputStream >& OutStream ) throw(::com::sun::star::io::IOException, ::com::sun::star::uno::RuntimeException); virtual void SAL_CALL read( const ::com::sun::star::uno::Reference< ::com::sun::star::io::XObjectInputStream >& InStream ) throw(::com::sun::star::io::IOException, ::com::sun::star::uno::RuntimeException); // XBoundComponent virtual sal_Bool SAL_CALL commit() throw(::com::sun::star::uno::RuntimeException); // XUpdateBroadcaster (base of XBoundComponent) virtual void SAL_CALL addUpdateListener( const ::com::sun::star::uno::Reference< ::com::sun::star::form::XUpdateListener >& aListener ) throw(::com::sun::star::uno::RuntimeException); virtual void SAL_CALL removeUpdateListener( const ::com::sun::star::uno::Reference< ::com::sun::star::form::XUpdateListener >& aListener ) throw(::com::sun::star::uno::RuntimeException); // XPropertySet virtual void SAL_CALL getFastPropertyValue(::com::sun::star::uno::Any& rValue, sal_Int32 nHandle) const; virtual sal_Bool SAL_CALL convertFastPropertyValue( ::com::sun::star::uno::Any& _rConvertedValue, ::com::sun::star::uno::Any& _rOldValue, sal_Int32 _nHandle, const ::com::sun::star::uno::Any& _rValue ) throw (::com::sun::star::lang::IllegalArgumentException); virtual void SAL_CALL setFastPropertyValue_NoBroadcast( sal_Int32 nHandle, const ::com::sun::star::uno::Any& rValue ) throw (::com::sun::star::uno::Exception); // ::com::sun::star::beans::XPropertyState virtual ::com::sun::star::uno::Any getPropertyDefaultByHandle( sal_Int32 nHandle ) const; // XEventListener virtual void SAL_CALL disposing(const ::com::sun::star::lang::EventObject& Source) throw (::com::sun::star::uno::RuntimeException); // XPropertyChangeListener virtual void SAL_CALL propertyChange( const ::com::sun::star::beans::PropertyChangeEvent& evt ) throw(::com::sun::star::uno::RuntimeException); // XLoadListener virtual void SAL_CALL loaded( const ::com::sun::star::lang::EventObject& aEvent ) throw(::com::sun::star::uno::RuntimeException); virtual void SAL_CALL unloading( const ::com::sun::star::lang::EventObject& aEvent ) throw(::com::sun::star::uno::RuntimeException); virtual void SAL_CALL unloaded( const ::com::sun::star::lang::EventObject& aEvent ) throw(::com::sun::star::uno::RuntimeException); virtual void SAL_CALL reloading( const ::com::sun::star::lang::EventObject& aEvent ) throw(::com::sun::star::uno::RuntimeException); virtual void SAL_CALL reloaded( const ::com::sun::star::lang::EventObject& aEvent ) throw(::com::sun::star::uno::RuntimeException); private: // XBindableValue virtual void SAL_CALL setValueBinding( const ::com::sun::star::uno::Reference< ::com::sun::star::form::binding::XValueBinding >& _rxBinding ) throw (::com::sun::star::form::binding::IncompatibleTypesException, ::com::sun::star::uno::RuntimeException); virtual ::com::sun::star::uno::Reference< ::com::sun::star::form::binding::XValueBinding > SAL_CALL getValueBinding( ) throw (::com::sun::star::uno::RuntimeException); // XModifyListener virtual void SAL_CALL modified( const ::com::sun::star::lang::EventObject& _rEvent ) throw (::com::sun::star::uno::RuntimeException); // XValidatable virtual void SAL_CALL setValidator( const ::com::sun::star::uno::Reference< ::com::sun::star::form::validation::XValidator >& Validator ) throw (::com::sun::star::util::VetoException, ::com::sun::star::uno::RuntimeException); virtual ::com::sun::star::uno::Reference< ::com::sun::star::form::validation::XValidator > SAL_CALL getValidator( ) throw (::com::sun::star::uno::RuntimeException); // XValidityConstraintListener virtual void SAL_CALL validityConstraintChanged( const ::com::sun::star::lang::EventObject& Source ) throw (::com::sun::star::uno::RuntimeException); // XValidatableFormComponent virtual sal_Bool SAL_CALL isValid( ) throw (::com::sun::star::uno::RuntimeException); virtual ::com::sun::star::uno::Any SAL_CALL getCurrentValue( ) throw (::com::sun::star::uno::RuntimeException); virtual void SAL_CALL addFormComponentValidityListener( const ::com::sun::star::uno::Reference< ::com::sun::star::form::validation::XFormComponentValidityListener >& Listener ) throw (::com::sun::star::lang::NullPointerException, ::com::sun::star::uno::RuntimeException); virtual void SAL_CALL removeFormComponentValidityListener( const ::com::sun::star::uno::Reference< ::com::sun::star::form::validation::XFormComponentValidityListener >& Listener ) throw (::com::sun::star::lang::NullPointerException, ::com::sun::star::uno::RuntimeException); protected: // OPropertyChangeListener virtual void _propertyChanged( const ::com::sun::star::beans::PropertyChangeEvent& _rEvt ) throw ( ::com::sun::star::uno::RuntimeException ); /// checks whether we currently have an external value binding in place inline bool hasExternalValueBinding() const { return m_xExternalBinding.is(); } // checks whether we currently have an external validator inline bool hasValidator() const { return m_xValidator.is(); } /** transfers the very current value of the db column we're bound to the control @precond our own mutex is locked @precond we don't have an external binding in place */ void transferDbValueToControl( ); /** transfers the current value of the active external binding to the control @precond our own mutex is locked @precond we do have an active external binding in place */ void transferExternalValueToControl( ); /** transfers the control value to the external binding @precond our own mutex is locked @precond we do have an active external binding in place */ void transferControlValueToExternal( ); private: sal_Bool connectToField(const ::com::sun::star::uno::Reference< ::com::sun::star::sdbc::XRowSet>& _rxForm); void resetField(); /** does a new validation of the control value If necessary, our m_bIsCurrentValueValid member will be adjusted, and changes will be notified. Note that it's not necessary that we're connected to a validator. If we are not, it's assumed that our value is valid, and this is handled appropriately. Use this method if there is a potential that only the validity flag changed. If any of the other aspects (our current value, or our current text) changed, then pass for _bForceNotification. @param _bForceNotification if , then the validity listeners will be notified, not matter whether the validity changed. */ void recheckValidity( bool _bForceNotification ); /// initializes m_pAggPropMultiplexer void implInitAggMultiplexer( ); /// initializes listening at the value property void implInitValuePropertyListening( ) const; /** adds the component as load listener to the parent form @precond there is a valid (non-NULL) parent form @precond there must no external value binding be in place @precond We are currently *not* listening at the parent form. */ void startLoadListening( ); /** removes the component as load listener from the parent form @precond We currently *are* listening at the parent form. */ void stopLoadListening( ); inline sal_Bool isLoadListening() const { return m_bLoadListening; } /** connects to a value supplier which is an database column @precond The control does not have an external value supplier @precond Our mutex is not locked @param _rxRowSet The row set which contains the column which we should connect to @param _bFromReload Determines whether the connection is made after the row set has been loaded () or reloaded () @see disconnectDatabaseColumn */ void connectDatabaseColumn( const ::com::sun::star::uno::Reference< ::com::sun::star::sdbc::XRowSet >& _rxRowSet, bool _bFromReload ); /** disconnects from a value supplier which is an database column @precond The control does not have an external value supplier @precond Our mutex is not locked @see connectDatabaseColumn */ void disconnectDatabaseColumn( ); /** connects to an external value binding

Note that by definition, external data bindings superseede the SQL data binding which is defined by our RowSet-column-related properties. This means that in case we're currently connected to a database column when this is called, this connection is suspended.

@precond the new external binding has already been approved (see approveValueBinding) @precond there currently is no external binding in place */ void connectExternalValueBinding( const ::com::sun::star::uno::Reference< ::com::sun::star::form::binding::XValueBinding >& _rxBinding ); /** disconnects from an external value binding @precond there currently is an external binding in place */ void disconnectExternalValueBinding( ); /** connects the component to an external validator @precond there currently is no active validator @precond our mutex is currently locked exactly once */ void connectValidator( const ::com::sun::star::uno::Reference< ::com::sun::star::form::validation::XValidator >& _rxValidator ); /** disconnects the component from it's current an external validator @precond there currently is an active validator @precond our mutex is currently locked exactly once */ void disconnectValidator( ); }; //......................................................................... } //......................................................................... #endif // _FORMS_FORMCOMPONENT_HXX_