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