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