1 /************************************************************************* 2 * 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * Copyright 2000, 2010 Oracle and/or its affiliates. 6 * 7 * OpenOffice.org - a multi-platform office productivity suite 8 * 9 * This file is part of OpenOffice.org. 10 * 11 * OpenOffice.org is free software: you can redistribute it and/or modify 12 * it under the terms of the GNU Lesser General Public License version 3 13 * only, as published by the Free Software Foundation. 14 * 15 * OpenOffice.org is distributed in the hope that it will be useful, 16 * but WITHOUT ANY WARRANTY; without even the implied warranty of 17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18 * GNU Lesser General Public License version 3 for more details 19 * (a copy is included in the LICENSE file that accompanied this code). 20 * 21 * You should have received a copy of the GNU Lesser General Public License 22 * version 3 along with OpenOffice.org. If not, see 23 * <http://www.openoffice.org/license.html> 24 * for a copy of the LGPLv3 License. 25 * 26 ************************************************************************/ 27 28 #ifndef _FORMS_FORMCOMPONENT_HXX_ 29 #define _FORMS_FORMCOMPONENT_HXX_ 30 31 #include "cloneable.hxx" 32 #include "ids.hxx" 33 #include "property.hrc" 34 #include "property.hxx" 35 #include "propertybaghelper.hxx" 36 #include "resettable.hxx" 37 #include "services.hxx" 38 #include "windowstateguard.hxx" 39 40 /** === begin UNO includes === **/ 41 #include <com/sun/star/awt/XControl.hpp> 42 #include <com/sun/star/beans/XPropertyAccess.hpp> 43 #include <com/sun/star/beans/XPropertyContainer.hpp> 44 #include <com/sun/star/container/XChild.hpp> 45 #include <com/sun/star/container/XNamed.hpp> 46 #include <com/sun/star/form/binding/XBindableValue.hpp> 47 #include <com/sun/star/form/FormComponentType.hpp> 48 #include <com/sun/star/form/validation/XValidatableFormComponent.hpp> 49 #include <com/sun/star/form/validation/XValidityConstraintListener.hpp> 50 #include <com/sun/star/form/XBoundComponent.hpp> 51 #include <com/sun/star/form/XBoundControl.hpp> 52 #include <com/sun/star/form/XFormComponent.hpp> 53 #include <com/sun/star/form/XLoadListener.hpp> 54 #include <com/sun/star/form/XReset.hpp> 55 #include <com/sun/star/io/XMarkableStream.hpp> 56 #include <com/sun/star/io/XPersistObject.hpp> 57 #include <com/sun/star/lang/DisposedException.hpp> 58 #include <com/sun/star/lang/XEventListener.hpp> 59 #include <com/sun/star/lang/XMultiServiceFactory.hpp> 60 #include <com/sun/star/lang/XServiceInfo.hpp> 61 #include <com/sun/star/sdb/XColumn.hpp> 62 #include <com/sun/star/sdb/XColumnUpdate.hpp> 63 #include <com/sun/star/sdb/XRowSetChangeListener.hpp> 64 #include <com/sun/star/sdbc/XRowSet.hpp> 65 #include <com/sun/star/sdbcx/XColumnsSupplier.hpp> 66 #include <com/sun/star/uno/XAggregation.hpp> 67 #include <com/sun/star/util/XCloneable.hpp> 68 #include <com/sun/star/util/XModifyListener.hpp> 69 #include <com/sun/star/form/XLoadable.hpp> 70 /** === end UNO includes === **/ 71 72 #include <comphelper/componentcontext.hxx> 73 #include <comphelper/propagg.hxx> 74 #include <comphelper/propertybag.hxx> 75 #include <comphelper/propmultiplex.hxx> 76 #include <comphelper/sequence.hxx> 77 #include <comphelper/uno3.hxx> 78 #include <cppuhelper/component.hxx> 79 #include <cppuhelper/implbase1.hxx> 80 #include <cppuhelper/implbase2.hxx> 81 #include <cppuhelper/implbase3.hxx> 82 #include <cppuhelper/implbase4.hxx> 83 #include <cppuhelper/implbase7.hxx> 84 #include <osl/mutex.hxx> 85 #include <rtl/ustring.hxx> 86 87 #include <memory> 88 89 //......................................................................... 90 namespace frm 91 { 92 //......................................................................... 93 94 // default tab index for components 95 const sal_Int16 FRM_DEFAULT_TABINDEX = 0; 96 97 // macros for quickly declaring/implementing XServiceInfo 98 #define DECLARE_XPERSISTOBJECT() \ 99 virtual ::rtl::OUString SAL_CALL getServiceName() throw(::com::sun::star::uno::RuntimeException); \ 100 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); \ 101 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); \ 102 103 // old macro for quickly implementing XServiceInfo::getImplementationName 104 #define IMPLEMENTATION_NAME(ImplName) \ 105 virtual ::rtl::OUString SAL_CALL getImplementationName( ) throw(::com::sun::star::uno::RuntimeException) \ 106 { return ::rtl::OUString::createFromAscii("com.sun.star.comp.forms.") + ::rtl::OUString::createFromAscii(#ImplName); } 107 108 class OControlModel; 109 110 //========================================================================= 111 //= ControlModelLock 112 //========================================================================= 113 /** class whose instances lock a OControlModel 114 115 Locking here merely means locking the OControlModel's mutex. 116 117 In addition to the locking facility, the class is also able to fire property 118 change notifications. This happens when the last ControlModelLock instance on a stack 119 dies. 120 */ 121 class ControlModelLock 122 { 123 public: 124 ControlModelLock( OControlModel& _rModel ) 125 :m_rModel( _rModel ) 126 ,m_bLocked( false ) 127 { 128 acquire(); 129 } 130 131 ~ControlModelLock() 132 { 133 if ( m_bLocked ) 134 release(); 135 } 136 inline void acquire(); 137 inline void release(); 138 139 inline OControlModel& getModel() const { return m_rModel; }; 140 141 /** adds a property change notification, which is to be fired when the last lock on the model 142 (in the current thread) is released. 143 */ 144 void addPropertyNotification( 145 const sal_Int32 _nHandle, 146 const ::com::sun::star::uno::Any& _rOldValue, 147 const ::com::sun::star::uno::Any& _rNewValue 148 ); 149 150 private: 151 void impl_notifyAll_nothrow(); 152 153 private: 154 OControlModel& m_rModel; 155 bool m_bLocked; 156 ::com::sun::star::uno::Sequence< sal_Int32 > m_aHandles; 157 ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Any > m_aOldValues; 158 ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Any > m_aNewValues; 159 160 private: 161 ControlModelLock(); // never implemented 162 ControlModelLock( const ControlModelLock& ); // never implemented 163 ControlModelLock& operator=( const ControlModelLock& ); // never implemented 164 }; 165 166 //========================================================================= 167 //= OControl 168 //= base class for form layer controls 169 //========================================================================= 170 typedef ::cppu::ImplHelper3 < ::com::sun::star::awt::XControl 171 , ::com::sun::star::lang::XEventListener 172 , ::com::sun::star::lang::XServiceInfo 173 > OControl_BASE; 174 175 class OControl :public ::cppu::OComponentHelper 176 ,public OControl_BASE 177 { 178 protected: 179 ::osl::Mutex m_aMutex; 180 OImplementationIdsRef m_aHoldIdHelper; 181 ::com::sun::star::uno::Reference< ::com::sun::star::awt::XControl > 182 m_xControl; 183 ::com::sun::star::uno::Reference< ::com::sun::star::uno::XAggregation> 184 m_xAggregate; 185 186 ::comphelper::ComponentContext m_aContext; 187 WindowStateGuard m_aWindowStateGuard; 188 189 public: 190 /** constructs a control 191 192 @param _rFactory 193 the service factory for this control 194 @param _rAggregateService 195 the service name of the component to aggregate 196 @param _bSetDelegator 197 set this to <FALSE/> if you don't want the constructor to set the delegator at 198 the aggregate. In this case, you <em>have</em> to call doSetDelegator within your 199 own constructor. 200 201 This is helpfull, if your derived class wants to cache an interface of the aggregate. 202 In this case, the aggregate needs to be queried for this interface <b>before</b> the 203 <member scope="com::sun::star::uno">XAggregation::setDelegator</member> call. 204 205 In such a case, pass <FALSE/> to this parameter. Then, cache the aggregate's interface(s) 206 as needed. Afterwards, call <member>doSetDelegator</member>. 207 208 In your destructor, you need to call <member>doResetDelegator</member> before 209 resetting the cached interfaces. This will reset the aggregates delegator to <NULL/>, 210 which will ensure that the <member scope="com::sun::star::uno">XInterface::release</member> 211 calls on the cached interfaces are really applied to the aggregate, instead of 212 the <type>OControl</type> itself. 213 */ 214 OControl( 215 const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory >& _rFactory, 216 const ::rtl::OUString& _rAggregateService, 217 const sal_Bool _bSetDelegator = sal_True 218 ); 219 220 /** initializes the given peer with various settings necessary for form controls 221 */ 222 static void initFormControlPeer( 223 const ::com::sun::star::uno::Reference< ::com::sun::star::awt::XWindowPeer >& _rxPeer ); 224 225 protected: 226 virtual ~OControl(); 227 228 /** sets the control as delegator at the aggregate 229 230 This has to be called from within your derived class' constructor, if and only 231 if you passed <FALSE/> to the <arg>_bSetDelegator</arg> parameter of the 232 <type>OControl</type> constructor. 233 */ 234 void doSetDelegator(); 235 void doResetDelegator(); 236 237 // UNO 238 DECLARE_UNO3_AGG_DEFAULTS(OControl, OComponentHelper); 239 virtual ::com::sun::star::uno::Any SAL_CALL queryAggregation( const ::com::sun::star::uno::Type& _rType ) throw(::com::sun::star::uno::RuntimeException); 240 241 // XTypeProvider 242 virtual ::com::sun::star::uno::Sequence<sal_Int8> SAL_CALL getImplementationId() throw(::com::sun::star::uno::RuntimeException); 243 virtual ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Type> SAL_CALL getTypes() throw(::com::sun::star::uno::RuntimeException); 244 245 // OComponentHelper 246 virtual void SAL_CALL disposing(); 247 248 // XComponent (as base of XControl) 249 virtual void SAL_CALL dispose( ) throw(::com::sun::star::uno::RuntimeException) 250 { OComponentHelper::dispose(); } 251 virtual void SAL_CALL addEventListener( const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XEventListener>& _rxListener) throw(::com::sun::star::uno::RuntimeException) 252 { OComponentHelper::addEventListener(_rxListener); } 253 virtual void SAL_CALL removeEventListener( const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XEventListener>& _rxListener) throw(::com::sun::star::uno::RuntimeException) 254 { OComponentHelper::removeEventListener(_rxListener); } 255 256 // XEventListener 257 virtual void SAL_CALL disposing(const ::com::sun::star::lang::EventObject& Source) throw (::com::sun::star::uno::RuntimeException); 258 259 // XServiceInfo 260 virtual sal_Bool SAL_CALL supportsService(const ::rtl::OUString& ServiceName) throw (::com::sun::star::uno::RuntimeException); 261 virtual StringSequence SAL_CALL getSupportedServiceNames() throw(::com::sun::star::uno::RuntimeException); 262 virtual ::rtl::OUString SAL_CALL getImplementationName() throw(::com::sun::star::uno::RuntimeException) = 0; 263 264 // XServiceInfo - static version 265 static StringSequence SAL_CALL getSupportedServiceNames_Static() throw(::com::sun::star::uno::RuntimeException); 266 267 // XControl 268 virtual void SAL_CALL setContext(const InterfaceRef& Context) throw (::com::sun::star::uno::RuntimeException); 269 virtual InterfaceRef SAL_CALL getContext() throw (::com::sun::star::uno::RuntimeException); 270 virtual void SAL_CALL createPeer(const ::com::sun::star::uno::Reference<starawt::XToolkit>& Toolkit, const ::com::sun::star::uno::Reference<starawt::XWindowPeer>& Parent) throw (::com::sun::star::uno::RuntimeException); 271 virtual ::com::sun::star::uno::Reference<starawt::XWindowPeer> SAL_CALL getPeer() throw (::com::sun::star::uno::RuntimeException); 272 virtual sal_Bool SAL_CALL setModel(const ::com::sun::star::uno::Reference<starawt::XControlModel>& Model) throw (::com::sun::star::uno::RuntimeException); 273 virtual ::com::sun::star::uno::Reference<starawt::XControlModel> SAL_CALL getModel() throw (::com::sun::star::uno::RuntimeException); 274 virtual ::com::sun::star::uno::Reference<starawt::XView> SAL_CALL getView() throw (::com::sun::star::uno::RuntimeException); 275 virtual void SAL_CALL setDesignMode(sal_Bool bOn) throw (::com::sun::star::uno::RuntimeException); 276 virtual sal_Bool SAL_CALL isDesignMode() throw (::com::sun::star::uno::RuntimeException); 277 virtual sal_Bool SAL_CALL isTransparent() throw (::com::sun::star::uno::RuntimeException); 278 279 protected: 280 virtual ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Type> _getTypes(); 281 // overwrite this and call the base class if you have additional types 282 283 ::com::sun::star::uno::Sequence< ::rtl::OUString > getAggregateServiceNames(); 284 285 private: 286 void impl_resetStateGuard_nothrow(); 287 }; 288 289 //================================================================== 290 //= OBoundControl 291 //= a form control implementing the XBoundControl interface 292 //================================================================== 293 typedef ::cppu::ImplHelper1 < ::com::sun::star::form::XBoundControl 294 > OBoundControl_BASE; 295 class OBoundControl :public OControl 296 ,public OBoundControl_BASE 297 { 298 protected: 299 sal_Bool m_bLocked : 1; 300 301 ::rtl::OUString m_sOriginalHelpText; // as long as the text/value is invalid, we change the help text of our peer 302 ::com::sun::star::awt::FontDescriptor 303 m_aOriginalFont; // as long as the text/value is invalid, we also change the font 304 sal_Int32 m_nOriginalTextLineColor; // (we add red underlining) 305 306 public: 307 OBoundControl( 308 const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory >& _rxFactory, 309 const ::rtl::OUString& _rAggregateService, 310 const sal_Bool _bSetDelegator = sal_True 311 ); 312 313 virtual ~OBoundControl(); 314 315 DECLARE_UNO3_AGG_DEFAULTS(OBoundControl, OControl); 316 virtual ::com::sun::star::uno::Any SAL_CALL queryAggregation( const ::com::sun::star::uno::Type& _rType ) throw(::com::sun::star::uno::RuntimeException); 317 318 // XBoundControl 319 virtual sal_Bool SAL_CALL getLock() throw(::com::sun::star::uno::RuntimeException); 320 virtual void SAL_CALL setLock(sal_Bool _bLock) throw(::com::sun::star::uno::RuntimeException); 321 // default implementation just disables the controls, overwrite _setLock to change this behaviour 322 323 // XControl 324 virtual sal_Bool SAL_CALL setModel(const ::com::sun::star::uno::Reference< ::com::sun::star::awt::XControlModel >& Model) throw (::com::sun::star::uno::RuntimeException); 325 326 // XEventListener 327 virtual void SAL_CALL disposing(const ::com::sun::star::lang::EventObject& Source) throw (::com::sun::star::uno::RuntimeException); 328 329 // OComponentHelper 330 virtual void SAL_CALL disposing(); 331 332 protected: 333 virtual ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Type> _getTypes(); 334 // implement the lock setting 335 virtual void _setLock(sal_Bool _bLock); 336 }; 337 338 //================================================================== 339 //= OControlModel 340 //= model of a form layer control 341 //================================================================== 342 343 typedef ::cppu::ImplHelper7 < ::com::sun::star::form::XFormComponent 344 , ::com::sun::star::io::XPersistObject 345 , ::com::sun::star::container::XNamed 346 , ::com::sun::star::lang::XServiceInfo 347 , ::com::sun::star::util::XCloneable 348 , ::com::sun::star::beans::XPropertyContainer 349 , ::com::sun::star::beans::XPropertyAccess 350 > OControlModel_BASE; 351 352 class OControlModel :public ::cppu::OComponentHelper 353 ,public OPropertySetAggregationHelper 354 ,public OControlModel_BASE 355 ,public OCloneableAggregation 356 ,public IPropertyBagHelperContext 357 { 358 359 protected: 360 ::comphelper::ComponentContext m_aContext; 361 362 ::osl::Mutex m_aMutex; 363 oslInterlockedCount m_lockCount; 364 365 InterfaceRef m_xParent; // ParentComponent 366 OImplementationIdsRef m_aHoldIdHelper; 367 PropertyBagHelper m_aPropertyBagHelper; 368 369 const ::comphelper::ComponentContext& 370 getContext() const { return m_aContext; } 371 372 // <properties> 373 ::rtl::OUString m_aName; // name of the control 374 ::rtl::OUString m_aTag; // tag for additional data 375 sal_Int16 m_nTabIndex; // index within the taborder 376 sal_Int16 m_nClassId; // type of the control 377 sal_Bool m_bNativeLook; // should the control use the native platform look? 378 // </properties> 379 380 381 protected: 382 OControlModel( 383 const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory>& _rFactory, // factory to create the aggregate with 384 const ::rtl::OUString& _rUnoControlModelTypeName, // service name of te model to aggregate 385 const ::rtl::OUString& rDefault = ::rtl::OUString(), // service name of the default control 386 const sal_Bool _bSetDelegator = sal_True // set to sal_False if you want to call setDelegator later (after returning from this ctor) 387 ); 388 OControlModel( 389 const OControlModel* _pOriginal, // the original object to clone 390 const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory>& _rFactory, // factory to create the aggregate with 391 const sal_Bool _bCloneAggregate = sal_True, // should the aggregate of the original be cloned, too? 392 const sal_Bool _bSetDelegator = sal_True // set to sal_False if you want to call setDelegator later (after returning from this ctor) 393 ); 394 virtual ~OControlModel(); 395 396 /** to be called after a OBoundControlModel (a derivee, respectively) has been cloned 397 398 <p>This method contains late initializations which cannot be done in the 399 constructor of this base class, since the virtual method of derived classes do 400 not yet work there.</p> 401 */ 402 virtual void clonedFrom( const OControlModel* _pOriginal ); 403 404 using OComponentHelper::rBHelper; 405 406 virtual ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Type> _getTypes(); 407 408 void readHelpTextCompatibly(const ::com::sun::star::uno::Reference< ::com::sun::star::io::XObjectInputStream >& _rxInStream); 409 void writeHelpTextCompatibly(const ::com::sun::star::uno::Reference< ::com::sun::star::io::XObjectOutputStream >& _rxOutStream); 410 411 void doSetDelegator(); 412 void doResetDelegator(); 413 414 ::com::sun::star::uno::Sequence< ::rtl::OUString > getAggregateServiceNames(); 415 416 public: 417 DECLARE_UNO3_AGG_DEFAULTS(OControl, OComponentHelper); 418 virtual ::com::sun::star::uno::Any SAL_CALL queryAggregation( const ::com::sun::star::uno::Type& _rType ) throw (::com::sun::star::uno::RuntimeException); 419 420 // XTypeProvider 421 virtual ::com::sun::star::uno::Sequence<sal_Int8> SAL_CALL getImplementationId() throw(::com::sun::star::uno::RuntimeException); 422 virtual ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Type> SAL_CALL getTypes() throw(::com::sun::star::uno::RuntimeException); 423 424 // OComponentHelper 425 virtual void SAL_CALL disposing(); 426 427 // XNamed 428 virtual ::rtl::OUString SAL_CALL getName() throw(::com::sun::star::uno::RuntimeException); 429 virtual void SAL_CALL setName(const ::rtl::OUString& aName) throw(::com::sun::star::uno::RuntimeException); 430 431 // XServiceInfo 432 virtual sal_Bool SAL_CALL supportsService(const ::rtl::OUString& ServiceName) throw (::com::sun::star::uno::RuntimeException); 433 virtual StringSequence SAL_CALL getSupportedServiceNames() throw(::com::sun::star::uno::RuntimeException); 434 virtual ::rtl::OUString SAL_CALL getImplementationName() throw(::com::sun::star::uno::RuntimeException) = 0; 435 436 // XSericeInfo - static version(s) 437 static StringSequence SAL_CALL getSupportedServiceNames_Static() throw(::com::sun::star::uno::RuntimeException); 438 439 // XPersistObject 440 virtual ::rtl::OUString SAL_CALL getServiceName() throw(::com::sun::star::uno::RuntimeException) = 0; 441 virtual void SAL_CALL 442 write(const ::com::sun::star::uno::Reference< ::com::sun::star::io::XObjectOutputStream>& _rxOutStream) throw(::com::sun::star::io::IOException, ::com::sun::star::uno::RuntimeException); 443 virtual void SAL_CALL 444 read(const ::com::sun::star::uno::Reference< ::com::sun::star::io::XObjectInputStream>& _rxInStream) throw(::com::sun::star::io::IOException, ::com::sun::star::uno::RuntimeException); 445 446 // XChild (base of XFormComponent) 447 virtual InterfaceRef SAL_CALL getParent() throw(::com::sun::star::uno::RuntimeException); 448 virtual void SAL_CALL setParent(const InterfaceRef& Parent) throw(::com::sun::star::lang::NoSupportException, ::com::sun::star::uno::RuntimeException); 449 450 // XEventListener 451 virtual void SAL_CALL disposing(const ::com::sun::star::lang::EventObject& Source) throw (::com::sun::star::uno::RuntimeException); 452 453 // XPropertySet 454 virtual void SAL_CALL getFastPropertyValue(::com::sun::star::uno::Any& rValue, sal_Int32 nHandle) const; 455 virtual sal_Bool SAL_CALL convertFastPropertyValue( 456 ::com::sun::star::uno::Any& _rConvertedValue, ::com::sun::star::uno::Any& _rOldValue, sal_Int32 _nHandle, const ::com::sun::star::uno::Any& _rValue ) 457 throw (::com::sun::star::lang::IllegalArgumentException); 458 virtual void SAL_CALL setFastPropertyValue_NoBroadcast( sal_Int32 nHandle, const ::com::sun::star::uno::Any& rValue ) 459 throw (::com::sun::star::uno::Exception); 460 using ::cppu::OPropertySetHelper::getFastPropertyValue; 461 462 // ::com::sun::star::beans::XPropertyState 463 virtual ::com::sun::star::beans::PropertyState getPropertyStateByHandle(sal_Int32 nHandle); 464 virtual void setPropertyToDefaultByHandle(sal_Int32 nHandle); 465 virtual ::com::sun::star::uno::Any getPropertyDefaultByHandle( sal_Int32 nHandle ) const; 466 467 // XCloneable 468 virtual ::com::sun::star::uno::Reference< ::com::sun::star::util::XCloneable > SAL_CALL createClone( ) throw (::com::sun::star::uno::RuntimeException) = 0; 469 470 // XPropertyContainer 471 virtual void SAL_CALL addProperty( const ::rtl::OUString& Name, ::sal_Int16 Attributes, const ::com::sun::star::uno::Any& DefaultValue ) throw (::com::sun::star::beans::PropertyExistException, ::com::sun::star::beans::IllegalTypeException, ::com::sun::star::lang::IllegalArgumentException, ::com::sun::star::uno::RuntimeException); 472 virtual void SAL_CALL removeProperty( const ::rtl::OUString& Name ) throw (::com::sun::star::beans::UnknownPropertyException, ::com::sun::star::beans::NotRemoveableException, ::com::sun::star::uno::RuntimeException); 473 474 // XPropertyAccess 475 virtual ::com::sun::star::uno::Sequence< ::com::sun::star::beans::PropertyValue > SAL_CALL getPropertyValues( ) throw (::com::sun::star::uno::RuntimeException); 476 virtual void SAL_CALL setPropertyValues( const ::com::sun::star::uno::Sequence< ::com::sun::star::beans::PropertyValue >& aProps ) throw (::com::sun::star::beans::UnknownPropertyException, ::com::sun::star::beans::PropertyVetoException, ::com::sun::star::lang::IllegalArgumentException, ::com::sun::star::lang::WrappedTargetException, ::com::sun::star::uno::RuntimeException); 477 478 protected: 479 using OPropertySetAggregationHelper::setPropertyValues; 480 using OPropertySetAggregationHelper::getPropertyValues; 481 482 protected: 483 virtual void writeAggregate( const ::com::sun::star::uno::Reference< ::com::sun::star::io::XObjectOutputStream >& _rxOutStream ) const; 484 virtual void readAggregate( const ::com::sun::star::uno::Reference< ::com::sun::star::io::XObjectInputStream >& _rxInStream ); 485 486 protected: 487 // XPropertySet 488 virtual ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertySetInfo> SAL_CALL getPropertySetInfo() throw( ::com::sun::star::uno::RuntimeException); 489 // OPropertySetHelper 490 virtual cppu::IPropertyArrayHelper& SAL_CALL getInfoHelper(); 491 492 /** describes the properties provided by this class, or its respective 493 derived class 494 495 Derived classes usually call the base class first, and then append own properties. 496 */ 497 virtual void describeFixedProperties( 498 ::com::sun::star::uno::Sequence< ::com::sun::star::beans::Property >& /* [out] */ _rProps 499 ) const; 500 501 // IPropertyBagHelperContext 502 virtual ::osl::Mutex& getMutex(); 503 virtual void describeFixedAndAggregateProperties( 504 ::com::sun::star::uno::Sequence< ::com::sun::star::beans::Property >& _out_rFixedProperties, 505 ::com::sun::star::uno::Sequence< ::com::sun::star::beans::Property >& _out_rAggregateProperties 506 ) const; 507 virtual ::com::sun::star::uno::Reference< ::com::sun::star::beans::XMultiPropertySet > 508 getPropertiesInterface(); 509 510 /** describes the properties of our aggregate 511 512 The default implementation simply asks m_xAggregateSet for its properties. 513 514 You usually only need to overload this method if you want to filter the aggregate 515 properties. 516 */ 517 virtual void describeAggregateProperties( 518 ::com::sun::star::uno::Sequence< ::com::sun::star::beans::Property >& /* [out] */ _rAggregateProps 519 ) const; 520 521 public: 522 struct LockAccess { friend class ControlModelLock; private: LockAccess() { } }; 523 524 void lockInstance( LockAccess ); 525 oslInterlockedCount unlockInstance( LockAccess ); 526 527 void firePropertyChanges( 528 const ::com::sun::star::uno::Sequence< sal_Int32 >& _rHandles, 529 const ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Any >& _rOldValues, 530 const ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Any >& _rNewValues, 531 LockAccess 532 ); 533 534 inline ::osl::Mutex& 535 getInstanceMutex() { return m_aMutex; } 536 }; 537 538 //================================================================== 539 // simple destructor 540 #define DECLARE_DEFAULT_DTOR( classname ) \ 541 ~classname() \ 542 543 // constructor for cloning a class 544 #define DECLARE_DEFAULT_CLONE_CTOR( classname ) \ 545 classname( \ 546 const classname* _pOriginal, \ 547 const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory>& _rxFactory \ 548 ); \ 549 550 // all xtors for an inner class of the object hierarchy 551 #define DECLARE_DEFAULT_XTOR( classname ) \ 552 classname( \ 553 const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory>& _rxFactory, \ 554 const ::rtl::OUString& _rUnoControlModelTypeName, \ 555 const ::rtl::OUString& _rDefault \ 556 ); \ 557 DECLARE_DEFAULT_CLONE_CTOR( classname ) \ 558 DECLARE_DEFAULT_DTOR( classname ) \ 559 560 // all xtors for an inner class of the object hierarchy which is *bound* 561 #define DECLARE_DEFAULT_BOUND_XTOR( classname ) \ 562 classname( \ 563 const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory>& _rxFactory, \ 564 const ::rtl::OUString& _rUnoControlModelTypeName, \ 565 const ::rtl::OUString& _rDefault, \ 566 const sal_Bool _bSupportExternalBinding, \ 567 const sal_Bool _bSupportsValidation \ 568 ); \ 569 DECLARE_DEFAULT_CLONE_CTOR( classname ) \ 570 DECLARE_DEFAULT_DTOR( classname ) \ 571 572 // all xtors for a leas class of the object hierarchy 573 #define DECLARE_DEFAULT_LEAF_XTOR( classname ) \ 574 classname( \ 575 const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory>& _rxFactory \ 576 ); \ 577 classname( \ 578 const classname* _pOriginal, \ 579 const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory>& _rxFactory \ 580 ); \ 581 DECLARE_DEFAULT_DTOR( classname ) \ 582 583 //================================================================== 584 // XCloneable 585 #define DECLARE_XCLONEABLE( ) \ 586 virtual ::com::sun::star::uno::Reference< ::com::sun::star::util::XCloneable > SAL_CALL createClone( ) throw (::com::sun::star::uno::RuntimeException) 587 588 #define IMPLEMENT_DEFAULT_CLONING( classname ) \ 589 ::com::sun::star::uno::Reference< ::com::sun::star::util::XCloneable > SAL_CALL classname::createClone( ) throw (::com::sun::star::uno::RuntimeException) \ 590 { \ 591 classname* pClone = new classname( this, getContext().getLegacyServiceFactory() ); \ 592 pClone->clonedFrom( this ); \ 593 return pClone; \ 594 } 595 596 //================================================================== 597 //= OBoundControlModel 598 //= model of a form layer control which is bound to a data source field 599 //================================================================== 600 typedef ::cppu::ImplHelper4 < ::com::sun::star::form::XLoadListener 601 , ::com::sun::star::form::XReset 602 , ::com::sun::star::beans::XPropertyChangeListener 603 , ::com::sun::star::sdb::XRowSetChangeListener 604 > OBoundControlModel_BASE1; 605 606 // separated into an own base class since derivees can disable the support for this 607 // interface, thus we want to easily exclude it in the queryInterface and getTypes 608 typedef ::cppu::ImplHelper1 < ::com::sun::star::form::XBoundComponent 609 > OBoundControlModel_COMMITTING; 610 611 // dito 612 typedef ::cppu::ImplHelper2 < ::com::sun::star::form::binding::XBindableValue 613 , ::com::sun::star::util::XModifyListener 614 > OBoundControlModel_BINDING; 615 616 // dito 617 typedef ::cppu::ImplHelper2 < ::com::sun::star::form::validation::XValidityConstraintListener 618 , ::com::sun::star::form::validation::XValidatableFormComponent 619 > OBoundControlModel_VALIDATION; 620 621 class OBoundControlModel :public OControlModel 622 ,public OBoundControlModel_BASE1 623 ,public OBoundControlModel_COMMITTING 624 ,public OBoundControlModel_BINDING 625 ,public OBoundControlModel_VALIDATION 626 ,public ::comphelper::OPropertyChangeListener 627 { 628 protected: 629 enum ValueChangeInstigator 630 { 631 eDbColumnBinding, 632 eExternalBinding, 633 eOther 634 }; 635 636 private: 637 ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertySet > 638 m_xField; 639 // the form which controls supplies the field we bind to. 640 ::com::sun::star::uno::Reference< ::com::sun::star::form::XLoadable > 641 m_xAmbientForm; 642 643 ::rtl::OUString m_sValuePropertyName; 644 sal_Int32 m_nValuePropertyAggregateHandle; 645 sal_Int32 m_nFieldType; 646 ::com::sun::star::uno::Type m_aValuePropertyType; 647 bool m_bValuePropertyMayBeVoid; 648 649 ResetHelper m_aResetHelper; 650 ::cppu::OInterfaceContainerHelper m_aUpdateListeners; 651 ::cppu::OInterfaceContainerHelper m_aFormComponentListeners; 652 653 ::com::sun::star::uno::Reference< ::com::sun::star::form::binding::XValueBinding > 654 m_xExternalBinding; 655 ::com::sun::star::uno::Reference< ::com::sun::star::form::validation::XValidator > 656 m_xValidator; 657 ::com::sun::star::uno::Type m_aExternalValueType; 658 659 // <properties> 660 ::rtl::OUString m_aControlSource; // Datenquelle, Name des Feldes 661 ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertySet > 662 m_xLabelControl; // reference to a sibling control (model) which is our label 663 sal_Bool m_bInputRequired; 664 // </properties> 665 666 ::comphelper::OPropertyChangeMultiplexer* 667 m_pAggPropMultiplexer; 668 669 bool m_bFormListening : 1; // are we currently a XLoadListener at our ambient form? 670 sal_Bool m_bLoaded : 1; 671 sal_Bool m_bRequired : 1; 672 const sal_Bool m_bCommitable : 1; // do we support XBoundComponent? 673 const sal_Bool m_bSupportsExternalBinding : 1; // do we support XBindableValue? 674 const sal_Bool m_bSupportsValidation : 1; // do we support XValidatable? 675 sal_Bool m_bForwardValueChanges : 1; // do we currently handle changes in the bound database field? 676 sal_Bool m_bTransferingValue : 1; // true if we're currently transfering our value to an external binding 677 sal_Bool m_bIsCurrentValueValid : 1; // flag specifying whether our current value is valid, relative to our external validator 678 sal_Bool m_bBindingControlsRO : 1; // is our ReadOnly property currently controlled by our external binding? 679 sal_Bool m_bBindingControlsEnable : 1; // is our Enabled property currently controlled by our external binding? 680 681 ValueChangeInstigator m_eControlValueChangeInstigator; 682 683 protected: 684 ::rtl::OUString m_aLabelServiceName; 685 // when setting the label for our control (property FM_PROP_CONTROLLABEL, member m_xLabelControl), 686 // we accept only objects supporting an XControlModel interface, an XServiceInfo interface and 687 // support for a service (XServiceInfo::supportsService) determined by this string. 688 // Any other arguments will throw an IllegalArgumentException. 689 // The default value is FM_COMPONENT_FIXEDTEXT. 690 691 ::com::sun::star::uno::Reference< ::com::sun::star::sdbc::XRowSet > 692 m_xCursor; 693 ::com::sun::star::uno::Reference< ::com::sun::star::sdb::XColumnUpdate > 694 m_xColumnUpdate; 695 ::com::sun::star::uno::Reference< ::com::sun::star::sdb::XColumn > 696 m_xColumn; 697 698 protected: 699 inline const ::rtl::OUString& getValuePropertyName( ) const { return m_sValuePropertyName; } 700 inline sal_Int32 getValuePropertyAggHandle( ) const { return m_nValuePropertyAggregateHandle; } 701 inline const ::rtl::OUString& getControlSource( ) const { return m_aControlSource; } 702 inline sal_Bool isRequired() const { return m_bRequired; } 703 inline sal_Bool isLoaded() const { return m_bLoaded; } 704 705 protected: 706 707 OBoundControlModel( 708 const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory>& _rFactory, 709 // factory to create the aggregate with 710 const ::rtl::OUString& _rUnoControlModelTypeName, // service name of te model to aggregate 711 const ::rtl::OUString& _rDefault, // service name of the default control 712 const sal_Bool _bCommitable, // is the control (model) commitable ? 713 const sal_Bool _bSupportExternalBinding, // set to sal_True if you want to support XBindableValue 714 const sal_Bool _bSupportsValidation // set to sal_True if you want to support XValidatable 715 ); 716 OBoundControlModel( 717 const OBoundControlModel* _pOriginal, // the original object to clone 718 const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory>& _rFactory 719 // factory to create the aggregate with 720 ); 721 virtual ~OBoundControlModel(); 722 723 /// late ctor after cloning 724 virtual void clonedFrom( const OControlModel* _pOriginal ); 725 726 /** initializes the part of the class which is related to the control value. 727 728 <p>Kind of late ctor, to be called for derivees which have a dedicated value property.<br/> 729 The value property is the property which's value is synced with either the database 730 column the object is bound to, or with the external value binding, if present.<br/> 731 E.g. for a text control model, this property will most probably be "Text".</p> 732 733 <p>Derived classes are stronly recommend to call this method - at least the 734 "DataFieldProperty" (exposed in getFastPropertyValue) relies on the information 735 given herein, and needs to be supplied otherwise else.</p> 736 737 <p>If this method has been called properly, then <member>setControlValue</member> 738 does not need to be overridden - it will simply set the property value at the 739 aggregate then.</p> 740 741 @precond 742 The method has not be called before during the life time of the object. 743 744 @param _rValuePropertyName 745 the name of the value property 746 @param _nValuePropertyExternalHandle 747 the handle of the property, as exposed to external components.<br/> 748 Normally, this information can be obtained dynamically (e.g. from describeFixedProperties), 749 but since this method is to be called from within the constructor of derived classes, 750 we prefer to be on the *really* safe side here .... 751 752 @see setControlValue 753 @see suspendValueListening 754 @see resumeValueListening 755 @see describeFixedProperties 756 */ 757 void initValueProperty( 758 const ::rtl::OUString& _rValuePropertyName, 759 sal_Int32 _nValuePropertyExternalHandle 760 ); 761 762 /** initializes the part of the class which is related to the control value. 763 764 <p>In opposite to ->initValueProperty, this method is to be used for value properties which are <em>not</em> 765 implemented by our aggregate, but by ourselves.</p> 766 767 <p>Certain functionality is not available when using own value properties. This includes binding to an external 768 value and external validation. (This is not a conceptual limit, but simply missing implementation.)</p> 769 */ 770 void initOwnValueProperty( 771 const ::rtl::OUString& i_rValuePropertyName 772 ); 773 774 /** suspends listening at the value property 775 776 <p>As long as this listening is suspended, changes in the value property will not be 777 recognized and not be handled.</p> 778 779 @see initValueProperty 780 @see resumeValueListening 781 */ 782 void suspendValueListening( ); 783 784 /** resumes listening at the value property 785 786 <p>As long as this listening is suspended, changes in the value property will not be 787 recognized and not be handled.</p> 788 789 @precond 790 listening at the value property is currently suspended 791 792 @see initValueProperty 793 @see resumeValueListening 794 */ 795 void resumeValueListening( ); 796 797 /** (to be) called when the value property changed 798 799 Normally, this is done automatically, since the value property is a property of our aggregate, and we're 800 a listener at this property. 801 However, in some cases the value property might not be an aggregate property, but a property of the 802 delegator instance. In this case, you'll need to call <code>onValuePropertyChange</code> whenever this 803 property changes. 804 */ 805 void onValuePropertyChange( ControlModelLock& i_rControLock ); 806 807 /** starts listening at the aggregate, for changes in the given property 808 809 <p>The OBoundControlModel automatically registers a multiplexer which listens for 810 changes in the aggregate property values. By default, only the control value property 811 is observed. You may add additional properties to be observed with this method.</p> 812 813 @see initValueProperty 814 @see _propertyChanged 815 */ 816 void startAggregatePropertyListening( const ::rtl::OUString& _rPropertyName ); 817 818 /** returns the default which should be used when resetting the control 819 820 <p>The default implementation returns an empty Any.</p> 821 822 @see resetNoBroadcast 823 */ 824 virtual ::com::sun::star::uno::Any 825 getDefaultForReset() const; 826 827 /** translates a db column value into a control value. 828 829 <p>Must transform the very current value of the database column we're bound to 830 (<member>m_xColumn</member>) into a value which can be used as current value 831 for the control.</p> 832 833 @see setControlValue 834 @pure 835 */ 836 virtual ::com::sun::star::uno::Any 837 translateDbColumnToControlValue( ) = 0; 838 839 /** returns the data types which the control could use to exchange data with 840 an external value binding 841 842 The types returned here are completely independent from the concrete value binding, 843 they're just candidates which depend on the control type, and possible the concrete state 844 of the control (i.e. some property value). 845 846 If a control implementation supports multiple types, the ordering in the returned 847 sequence indicates preference: Preferred types are mentioned first. 848 849 The default implementation returns the type of our value property. 850 */ 851 virtual ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Type > 852 getSupportedBindingTypes(); 853 854 /** translates the given value, which was obtained from the current external value binding, 855 to a value which can be used in setControlValue 856 857 <p>The default implementation returns the value itself, exception when it is VOID, and 858 our value property is not allowed to be void - in this case, the returned value is a 859 default-constructed value of the type required by our value property. 860 861 @see hasExternalValueBinding 862 @see getExternalValueType 863 */ 864 virtual ::com::sun::star::uno::Any 865 translateExternalValueToControlValue( const ::com::sun::star::uno::Any& _rExternalValue ) const; 866 867 /** commits the current control value to our external value binding 868 869 <p>The default implementation simply calls getControlValue.</p> 870 871 @see hasExternalValueBinding 872 @see initValueProperty 873 */ 874 virtual ::com::sun::star::uno::Any 875 translateControlValueToExternalValue( ) const; 876 877 /** commits the current control value to the database column we're bound to 878 @precond 879 we're properly bound to a database column, especially <member>m_xColumnUpdate</member> 880 is not <NULL/> 881 @param _bPostReset 882 <TRUE/> if and only if the current control value results from a reset (<member>getDefaultForReset</member>) 883 @pure 884 */ 885 virtual sal_Bool commitControlValueToDbColumn( 886 bool _bPostReset 887 ) = 0; 888 889 /** sets the given value as new current value for the control 890 891 Besides some administrative work (such as caring for <member>m_eControlValueChangeInstigator</member>), 892 this method simply calls <member>doSetControlValue</member>. 893 894 @precond 895 Our own mutex is locked. 896 @param _rValue 897 The value to set. This value is guaranteed to be created by 898 <member>translateDbColumnToControlValue</member> or 899 <member>translateExternalValueToControlValue</member> 900 @param _eInstigator 901 the instigator of the value change 902 */ 903 void setControlValue( 904 const ::com::sun::star::uno::Any& _rValue, 905 ValueChangeInstigator _eInstigator 906 ); 907 /** 908 <p>The default implementation will forward the given value to the aggregate, using 909 m_nValuePropertyAggregateHandle and/or m_sValuePropertyName.</p> 910 911 @precond 912 Our own mutex is locked. 913 @param _rValue 914 The value to set. This value is guaranteed to be created by 915 <member>translateDbColumnToControlValue</member> or 916 <member>translateExternalValueToControlValue</member> 917 */ 918 virtual void doSetControlValue( 919 const ::com::sun::star::uno::Any& _rValue 920 ); 921 922 /** retrieves the current value of the control 923 924 <p>The default implementation will ask the aggregate for the property value 925 determined by either m_nValuePropertyAggregateHandle and/or m_sValuePropertyName.</p> 926 927 @precond 928 Our own mutex is locked. 929 */ 930 virtual ::com::sun::star::uno::Any 931 getControlValue( ) const; 932 933 /** called whenever a connection to a database column has been established 934 */ 935 virtual void onConnectedDbColumn( const ::com::sun::star::uno::Reference< ::com::sun::star::uno::XInterface >& _rxForm ); 936 /** called whenever a connection to a database column has been suspended 937 */ 938 virtual void onDisconnectedDbColumn(); 939 940 /** called whenever a connection to an external supplier of values (XValueBinding) has been established 941 @see m_xExternalBinding 942 */ 943 virtual void onConnectedExternalValue( ); 944 /** called whenever a connection to an external supplier of values (XValueBinding) has been suspended 945 */ 946 virtual void onDisconnectedExternalValue(); 947 948 /** called whenever an external validator has been registered 949 */ 950 virtual void onConnectedValidator( ); 951 /** called whenever an external validator has been revoked 952 */ 953 virtual void onDisconnectedValidator( ); 954 955 /** nFieldType ist der Typ des Feldes, an das das Model gebunden werden soll. 956 Das Binden erfolgt genau dann, wenn Rueckgabewert sal_True. 957 Die Standard-Implementation erlaubt alles ausser den drei binary-Typen und 958 FieldType_OTHER. 959 */ 960 virtual sal_Bool approveDbColumnType(sal_Int32 _nColumnType); 961 962 /** retrieves the current value of the control, in a shape which can be used with our 963 external validator. 964 965 The default implementation simply calls <member>>translateControlValueToExternalValue</member>. 966 967 @precond 968 Our own mutex is locked. 969 */ 970 virtual ::com::sun::star::uno::Any 971 translateControlValueToValidatableValue( ) const; 972 973 /** retrieves the current value of the form component 974 975 This is the implementation method for XValidatableFormComponent::getCurrentValue. The default implementation 976 calls translateControlValueToValidatableValue if a validator is present, otherwise getControlValue. 977 978 @precond 979 our mutex is locked when this method is called 980 */ 981 virtual ::com::sun::star::uno::Any 982 getCurrentFormComponentValue() const; 983 984 /** We can't write (new) common properties in this base class, as the file format doesn't allow this 985 (unfortunally). So derived classes may use the following to methods. They secure the written 986 data with marks, so any new common properties in newer versions will be skipped by older ones. 987 */ 988 void writeCommonProperties(const ::com::sun::star::uno::Reference< ::com::sun::star::io::XObjectOutputStream>& _rxOutStream); 989 void readCommonProperties(const ::com::sun::star::uno::Reference< ::com::sun::star::io::XObjectInputStream>& _rxInStream); 990 // the next method may be used in derived classes's read when an unknown version is encountered 991 void defaultCommonProperties(); 992 993 /** called to reset the control to some kind of default. 994 995 <p>The semantics of "default" is finally defined by the derived class (in particular, 996 by <member>getDefaultForReset</member>).</p> 997 998 <p>No listener notification needs to be done in the derived class.</p> 999 1000 <p>Normally, you won't override this method, but <member>getDefaultForReset</member> instead.</p> 1001 1002 @see getDefaultForReset 1003 */ 1004 virtual void resetNoBroadcast(); 1005 1006 virtual ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Type> _getTypes(); 1007 1008 /// sets m_xField to the given new value, without notifying our listeners 1009 void impl_setField_noNotify( 1010 const ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertySet>& _rxField 1011 ); 1012 inline bool hasField() const 1013 { 1014 return m_xField.is(); 1015 } 1016 inline sal_Int32 getFieldType() const 1017 { 1018 return m_nFieldType; 1019 } 1020 1021 // OControlModel's property handling 1022 virtual void describeFixedProperties( 1023 ::com::sun::star::uno::Sequence< ::com::sun::star::beans::Property >& /* [out] */ _rProps 1024 ) const; 1025 1026 public: 1027 inline const ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertySet>& getField() const 1028 { 1029 return m_xField; 1030 } 1031 1032 public: 1033 // UNO Anbindung 1034 DECLARE_UNO3_AGG_DEFAULTS(OBoundControlModel, OControlModel); 1035 virtual ::com::sun::star::uno::Any SAL_CALL queryAggregation( const ::com::sun::star::uno::Type& _rType ) throw (::com::sun::star::uno::RuntimeException); 1036 1037 // OComponentHelper 1038 virtual void SAL_CALL disposing(); 1039 1040 // XReset 1041 virtual void SAL_CALL reset( ) throw(::com::sun::star::uno::RuntimeException); 1042 virtual void SAL_CALL addResetListener( const ::com::sun::star::uno::Reference< ::com::sun::star::form::XResetListener >& aListener ) throw(::com::sun::star::uno::RuntimeException); 1043 virtual void SAL_CALL removeResetListener( const ::com::sun::star::uno::Reference< ::com::sun::star::form::XResetListener >& aListener ) throw(::com::sun::star::uno::RuntimeException); 1044 1045 // XServiceInfo 1046 virtual StringSequence SAL_CALL getSupportedServiceNames( ) throw(::com::sun::star::uno::RuntimeException); 1047 1048 // XServiceInfo - static version 1049 static StringSequence SAL_CALL getSupportedServiceNames_Static() throw(::com::sun::star::uno::RuntimeException); 1050 1051 // XChild 1052 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); 1053 1054 // XPersistObject 1055 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); 1056 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); 1057 1058 // XBoundComponent 1059 virtual sal_Bool SAL_CALL commit() throw(::com::sun::star::uno::RuntimeException); 1060 1061 // XUpdateBroadcaster (base of XBoundComponent) 1062 virtual void SAL_CALL addUpdateListener( const ::com::sun::star::uno::Reference< ::com::sun::star::form::XUpdateListener >& aListener ) throw(::com::sun::star::uno::RuntimeException); 1063 virtual void SAL_CALL removeUpdateListener( const ::com::sun::star::uno::Reference< ::com::sun::star::form::XUpdateListener >& aListener ) throw(::com::sun::star::uno::RuntimeException); 1064 1065 // XPropertySet 1066 virtual void SAL_CALL getFastPropertyValue(::com::sun::star::uno::Any& rValue, sal_Int32 nHandle) const; 1067 virtual sal_Bool SAL_CALL convertFastPropertyValue( 1068 ::com::sun::star::uno::Any& _rConvertedValue, ::com::sun::star::uno::Any& _rOldValue, sal_Int32 _nHandle, const ::com::sun::star::uno::Any& _rValue ) 1069 throw (::com::sun::star::lang::IllegalArgumentException); 1070 virtual void SAL_CALL setFastPropertyValue_NoBroadcast( sal_Int32 nHandle, const ::com::sun::star::uno::Any& rValue ) 1071 throw (::com::sun::star::uno::Exception); 1072 using ::cppu::OPropertySetHelper::getFastPropertyValue; 1073 1074 // ::com::sun::star::beans::XPropertyState 1075 virtual ::com::sun::star::uno::Any getPropertyDefaultByHandle( sal_Int32 nHandle ) const; 1076 1077 // XEventListener 1078 virtual void SAL_CALL disposing(const ::com::sun::star::lang::EventObject& Source) throw (::com::sun::star::uno::RuntimeException); 1079 1080 // XPropertyChangeListener 1081 virtual void SAL_CALL propertyChange( const ::com::sun::star::beans::PropertyChangeEvent& evt ) throw(::com::sun::star::uno::RuntimeException); 1082 1083 // XRowSetChangeListener 1084 virtual void SAL_CALL onRowSetChanged( const ::com::sun::star::lang::EventObject& i_Event ) throw (::com::sun::star::uno::RuntimeException); 1085 1086 // XLoadListener 1087 virtual void SAL_CALL loaded( const ::com::sun::star::lang::EventObject& aEvent ) throw(::com::sun::star::uno::RuntimeException); 1088 virtual void SAL_CALL unloading( const ::com::sun::star::lang::EventObject& aEvent ) throw(::com::sun::star::uno::RuntimeException); 1089 virtual void SAL_CALL unloaded( const ::com::sun::star::lang::EventObject& aEvent ) throw(::com::sun::star::uno::RuntimeException); 1090 virtual void SAL_CALL reloading( const ::com::sun::star::lang::EventObject& aEvent ) throw(::com::sun::star::uno::RuntimeException); 1091 virtual void SAL_CALL reloaded( const ::com::sun::star::lang::EventObject& aEvent ) throw(::com::sun::star::uno::RuntimeException); 1092 1093 private: 1094 // XBindableValue 1095 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); 1096 virtual ::com::sun::star::uno::Reference< ::com::sun::star::form::binding::XValueBinding > SAL_CALL getValueBinding( ) throw (::com::sun::star::uno::RuntimeException); 1097 1098 // XModifyListener 1099 virtual void SAL_CALL modified( const ::com::sun::star::lang::EventObject& _rEvent ) throw (::com::sun::star::uno::RuntimeException); 1100 1101 // XValidatable 1102 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); 1103 virtual ::com::sun::star::uno::Reference< ::com::sun::star::form::validation::XValidator > SAL_CALL getValidator( ) throw (::com::sun::star::uno::RuntimeException); 1104 1105 // XValidityConstraintListener 1106 virtual void SAL_CALL validityConstraintChanged( const ::com::sun::star::lang::EventObject& Source ) throw (::com::sun::star::uno::RuntimeException); 1107 1108 // XValidatableFormComponent 1109 virtual sal_Bool SAL_CALL isValid( ) throw (::com::sun::star::uno::RuntimeException); 1110 virtual ::com::sun::star::uno::Any SAL_CALL getCurrentValue( ) throw (::com::sun::star::uno::RuntimeException); 1111 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); 1112 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); 1113 1114 protected: 1115 // OPropertyChangeListener 1116 virtual void 1117 _propertyChanged( const ::com::sun::star::beans::PropertyChangeEvent& _rEvt ) throw ( ::com::sun::star::uno::RuntimeException ); 1118 1119 /// checks whether we currently have an external value binding in place 1120 inline bool hasExternalValueBinding() const { return m_xExternalBinding.is(); } 1121 1122 // checks whether we currently have an external validator 1123 inline bool hasValidator() const { return m_xValidator.is(); } 1124 1125 /** transfers the very current value of the db column we're bound to the control 1126 @precond 1127 our own mutex is locked 1128 @precond 1129 we don't have an external binding in place 1130 */ 1131 void transferDbValueToControl( ); 1132 1133 /** transfers the current value of the active external binding to the control 1134 @precond 1135 we do have an active external binding in place 1136 */ 1137 void transferExternalValueToControl( ControlModelLock& _rInstanceLock ); 1138 1139 /** transfers the control value to the external binding 1140 @precond 1141 our own mutex is locked, and _rInstanceLock is the guard locking it 1142 @precond 1143 we do have an active external binding in place 1144 */ 1145 void transferControlValueToExternal( ControlModelLock& _rInstanceLock ); 1146 1147 /** calculates the type which is to be used to communicate with the current external binding, 1148 and stores it in m_aExternalValueType 1149 1150 The method checks the possible type candidates as returned by getSupportedBindingTypes, 1151 and the types supported by the current external binding, if any. 1152 */ 1153 void calculateExternalValueType(); 1154 1155 /** returns the type which should be used to exchange data with our external value binding 1156 1157 @see initValueProperty 1158 */ 1159 const ::com::sun::star::uno::Type& 1160 getExternalValueType() const { return m_aExternalValueType; } 1161 1162 /** initializes the control from m_xField 1163 1164 Basically, this method calls transferDbValueToControl - but only if our cursor is positioned 1165 on a valid row. Otherwise, the control is reset. 1166 1167 @precond 1168 m_xField is not <NULL/> 1169 */ 1170 void initFromField( const ::com::sun::star::uno::Reference< ::com::sun::star::sdbc::XRowSet>& _rxForm ); 1171 1172 private: 1173 sal_Bool connectToField( const ::com::sun::star::uno::Reference< ::com::sun::star::sdbc::XRowSet>& _rxForm ); 1174 void resetField(); 1175 1176 /** does a new validation of the control value 1177 1178 If necessary, our <member>m_bIsCurrentValueValid</member> member will be adjusted, 1179 and changes will be notified. 1180 1181 Note that it's not necessary that we're connected to a validator. If we are not, 1182 it's assumed that our value is valid, and this is handled appropriately. 1183 1184 Use this method if there is a potential that <b>only</b> the validity flag changed. If 1185 any of the other aspects (our current value, or our current text) changed, then 1186 pass <TRUE/> for <member>_bForceNotification</member>. 1187 1188 @param _bForceNotification 1189 if <TRUE/>, then the validity listeners will be notified, not matter whether the validity 1190 changed. 1191 */ 1192 void recheckValidity( bool _bForceNotification ); 1193 1194 /// initializes m_pAggPropMultiplexer 1195 void implInitAggMultiplexer( ); 1196 1197 /// initializes listening at the value property 1198 void implInitValuePropertyListening( ) const; 1199 1200 /** adds or removes the component as load listener to/from our form, and (if necessary) as RowSetChange listener at 1201 our parent. 1202 1203 @precond there must no external value binding be in place 1204 */ 1205 void doFormListening( const bool _bStart ); 1206 1207 inline bool isFormListening() const { return m_bFormListening; } 1208 1209 /** determines the new value of m_xAmbientForm 1210 */ 1211 void impl_determineAmbientForm_nothrow(); 1212 1213 /** connects to a value supplier which is an database column. 1214 1215 The column is take from our parent, which must be a database form respectively row set. 1216 1217 @precond The control does not have an external value supplier 1218 1219 @param _bFromReload 1220 Determines whether the connection is made after the row set has been loaded (<FALSE/>) 1221 or reloaded (<TRUE/>) 1222 1223 @see impl_disconnectDatabaseColumn_noNotify 1224 */ 1225 void impl_connectDatabaseColumn_noNotify( 1226 bool _bFromReload 1227 ); 1228 1229 /** disconnects from a value supplier which is an database column 1230 1231 @precond The control does not have an external value supplier 1232 @see impl_connectDatabaseColumn_noNotify 1233 */ 1234 void impl_disconnectDatabaseColumn_noNotify(); 1235 1236 /** connects to an external value binding 1237 1238 <p>Note that by definition, external data bindings superseede the SQL data binding which 1239 is defined by our RowSet-column-related properties. This means that in case we're currently 1240 connected to a database column when this is called, this connection is suspended.</p> 1241 1242 @precond 1243 the new external binding has already been approved (see <member>impl_approveValueBinding_nolock</member>) 1244 @precond 1245 there currently is no external binding in place 1246 */ 1247 void connectExternalValueBinding( 1248 const ::com::sun::star::uno::Reference< ::com::sun::star::form::binding::XValueBinding >& _rxBinding, 1249 ControlModelLock& _rInstanceLock 1250 ); 1251 1252 /** disconnects from an external value binding 1253 1254 @precond 1255 there currently is an external binding in place 1256 */ 1257 void disconnectExternalValueBinding( ); 1258 1259 /** connects the component to an external validator 1260 1261 @precond 1262 there currently is no active validator 1263 @precond 1264 our mutex is currently locked exactly once 1265 */ 1266 void connectValidator( 1267 const ::com::sun::star::uno::Reference< ::com::sun::star::form::validation::XValidator >& _rxValidator 1268 ); 1269 1270 /** disconnects the component from it's current an external validator 1271 1272 @precond 1273 there currently is an active validator 1274 @precond 1275 our mutex is currently locked exactly once 1276 */ 1277 void disconnectValidator( ); 1278 1279 /** called from within <member scope="com::sun::star:::form::binding">XBindableValue::setValueBinding</member> 1280 to approve the new binding 1281 1282 The default implementation approves the binding if and only if it is not <NULL/>, and supports 1283 the type returned by getExternalValueType. 1284 1285 @param _rxBinding 1286 the binding which applies for being responsible for our value, Must not be 1287 <NULL/> 1288 @return 1289 <TRUE/> if and only if the given binding can supply values in the proper type 1290 1291 @seealso getExternalValueType 1292 */ 1293 sal_Bool impl_approveValueBinding_nolock( 1294 const ::com::sun::star::uno::Reference< ::com::sun::star::form::binding::XValueBinding >& _rxBinding 1295 ); 1296 }; 1297 1298 //========================================================================= 1299 //= inlines 1300 //========================================================================= 1301 inline void ControlModelLock::acquire() 1302 { 1303 m_rModel.lockInstance( OControlModel::LockAccess() ); 1304 m_bLocked = true; 1305 } 1306 inline void ControlModelLock::release() 1307 { 1308 OSL_ENSURE( m_bLocked, "ControlModelLock::release: not locked!" ); 1309 m_bLocked = false; 1310 1311 if ( 0 == m_rModel.unlockInstance( OControlModel::LockAccess() ) ) 1312 impl_notifyAll_nothrow(); 1313 } 1314 1315 //......................................................................... 1316 } 1317 //......................................................................... 1318 1319 #endif // _FORMS_FORMCOMPONENT_HXX_ 1320 1321