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