1*b1cdbd2cSJim Jagielski /************************************************************** 2*b1cdbd2cSJim Jagielski * 3*b1cdbd2cSJim Jagielski * Licensed to the Apache Software Foundation (ASF) under one 4*b1cdbd2cSJim Jagielski * or more contributor license agreements. See the NOTICE file 5*b1cdbd2cSJim Jagielski * distributed with this work for additional information 6*b1cdbd2cSJim Jagielski * regarding copyright ownership. The ASF licenses this file 7*b1cdbd2cSJim Jagielski * to you under the Apache License, Version 2.0 (the 8*b1cdbd2cSJim Jagielski * "License"); you may not use this file except in compliance 9*b1cdbd2cSJim Jagielski * with the License. You may obtain a copy of the License at 10*b1cdbd2cSJim Jagielski * 11*b1cdbd2cSJim Jagielski * http://www.apache.org/licenses/LICENSE-2.0 12*b1cdbd2cSJim Jagielski * 13*b1cdbd2cSJim Jagielski * Unless required by applicable law or agreed to in writing, 14*b1cdbd2cSJim Jagielski * software distributed under the License is distributed on an 15*b1cdbd2cSJim Jagielski * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 16*b1cdbd2cSJim Jagielski * KIND, either express or implied. See the License for the 17*b1cdbd2cSJim Jagielski * specific language governing permissions and limitations 18*b1cdbd2cSJim Jagielski * under the License. 19*b1cdbd2cSJim Jagielski * 20*b1cdbd2cSJim Jagielski *************************************************************/ 21*b1cdbd2cSJim Jagielski 22*b1cdbd2cSJim Jagielski 23*b1cdbd2cSJim Jagielski #ifndef _PROPERTYSETBASE_HXX 24*b1cdbd2cSJim Jagielski #define _PROPERTYSETBASE_HXX 25*b1cdbd2cSJim Jagielski 26*b1cdbd2cSJim Jagielski 27*b1cdbd2cSJim Jagielski // include for parent class 28*b1cdbd2cSJim Jagielski #include <cppuhelper/weak.hxx> 29*b1cdbd2cSJim Jagielski #include <com/sun/star/lang/XTypeProvider.hpp> 30*b1cdbd2cSJim Jagielski #include <comphelper/propstate.hxx> 31*b1cdbd2cSJim Jagielski #include <comphelper/propertysetinfo.hxx> 32*b1cdbd2cSJim Jagielski #include <comphelper/proparrhlp.hxx> 33*b1cdbd2cSJim Jagielski #include <rtl/ref.hxx> 34*b1cdbd2cSJim Jagielski 35*b1cdbd2cSJim Jagielski // include for inlined helper function below 36*b1cdbd2cSJim Jagielski #include <com/sun/star/lang/IllegalArgumentException.hpp> 37*b1cdbd2cSJim Jagielski #include <com/sun/star/beans/PropertyAttribute.hpp> 38*b1cdbd2cSJim Jagielski 39*b1cdbd2cSJim Jagielski #include <map> 40*b1cdbd2cSJim Jagielski 41*b1cdbd2cSJim Jagielski // forward declarations for method arguments 42*b1cdbd2cSJim Jagielski namespace com { namespace sun { namespace star { namespace uno { 43*b1cdbd2cSJim Jagielski class Any; 44*b1cdbd2cSJim Jagielski class Type; 45*b1cdbd2cSJim Jagielski class RuntimeException; 46*b1cdbd2cSJim Jagielski template<class T> class Sequence; 47*b1cdbd2cSJim Jagielski } } } } 48*b1cdbd2cSJim Jagielski 49*b1cdbd2cSJim Jagielski /** base class which encapsulates accessing (reading/writing) concrete property values 50*b1cdbd2cSJim Jagielski */ 51*b1cdbd2cSJim Jagielski class PropertyAccessorBase : public ::rtl::IReference 52*b1cdbd2cSJim Jagielski { 53*b1cdbd2cSJim Jagielski private: 54*b1cdbd2cSJim Jagielski oslInterlockedCount m_refCount; 55*b1cdbd2cSJim Jagielski 56*b1cdbd2cSJim Jagielski protected: PropertyAccessorBase()57*b1cdbd2cSJim Jagielski PropertyAccessorBase() : m_refCount( 0 ) { } 58*b1cdbd2cSJim Jagielski 59*b1cdbd2cSJim Jagielski public: 60*b1cdbd2cSJim Jagielski virtual oslInterlockedCount SAL_CALL acquire(); 61*b1cdbd2cSJim Jagielski virtual oslInterlockedCount SAL_CALL release(); 62*b1cdbd2cSJim Jagielski 63*b1cdbd2cSJim Jagielski virtual bool approveValue( const com::sun::star::uno::Any& rValue ) const = 0; 64*b1cdbd2cSJim Jagielski virtual void setValue( const com::sun::star::uno::Any& rValue ) = 0; 65*b1cdbd2cSJim Jagielski virtual void getValue( com::sun::star::uno::Any& rValue ) const = 0; 66*b1cdbd2cSJim Jagielski virtual bool isWriteable() const = 0; 67*b1cdbd2cSJim Jagielski }; 68*b1cdbd2cSJim Jagielski 69*b1cdbd2cSJim Jagielski 70*b1cdbd2cSJim Jagielski /** helper class for implementing property accessors through public member functions 71*b1cdbd2cSJim Jagielski */ 72*b1cdbd2cSJim Jagielski template< typename CLASS, typename VALUE, class WRITER, class READER > 73*b1cdbd2cSJim Jagielski class GenericPropertyAccessor : public PropertyAccessorBase 74*b1cdbd2cSJim Jagielski { 75*b1cdbd2cSJim Jagielski public: 76*b1cdbd2cSJim Jagielski typedef WRITER Writer; 77*b1cdbd2cSJim Jagielski typedef READER Reader; 78*b1cdbd2cSJim Jagielski 79*b1cdbd2cSJim Jagielski private: 80*b1cdbd2cSJim Jagielski CLASS* m_pInstance; 81*b1cdbd2cSJim Jagielski Writer m_pWriter; 82*b1cdbd2cSJim Jagielski Reader m_pReader; 83*b1cdbd2cSJim Jagielski 84*b1cdbd2cSJim Jagielski public: GenericPropertyAccessor(CLASS * pInstance,Writer pWriter,Reader pReader)85*b1cdbd2cSJim Jagielski GenericPropertyAccessor( CLASS* pInstance, Writer pWriter, Reader pReader ) 86*b1cdbd2cSJim Jagielski :m_pInstance( pInstance ) 87*b1cdbd2cSJim Jagielski ,m_pWriter( pWriter ) 88*b1cdbd2cSJim Jagielski ,m_pReader( pReader ) 89*b1cdbd2cSJim Jagielski { 90*b1cdbd2cSJim Jagielski } 91*b1cdbd2cSJim Jagielski approveValue(const com::sun::star::uno::Any & rValue) const92*b1cdbd2cSJim Jagielski virtual bool approveValue( const com::sun::star::uno::Any& rValue ) const 93*b1cdbd2cSJim Jagielski { 94*b1cdbd2cSJim Jagielski VALUE aVal; 95*b1cdbd2cSJim Jagielski return ( rValue >>= aVal ); 96*b1cdbd2cSJim Jagielski } 97*b1cdbd2cSJim Jagielski setValue(const com::sun::star::uno::Any & rValue)98*b1cdbd2cSJim Jagielski virtual void setValue( const com::sun::star::uno::Any& rValue ) 99*b1cdbd2cSJim Jagielski { 100*b1cdbd2cSJim Jagielski VALUE aTypedVal = VALUE(); 101*b1cdbd2cSJim Jagielski OSL_VERIFY( rValue >>= aTypedVal ); 102*b1cdbd2cSJim Jagielski (m_pInstance->*m_pWriter)( aTypedVal ); 103*b1cdbd2cSJim Jagielski } 104*b1cdbd2cSJim Jagielski getValue(com::sun::star::uno::Any & rValue) const105*b1cdbd2cSJim Jagielski virtual void getValue( com::sun::star::uno::Any& rValue ) const 106*b1cdbd2cSJim Jagielski { 107*b1cdbd2cSJim Jagielski rValue = com::sun::star::uno::makeAny( (m_pInstance->*m_pReader)() ); 108*b1cdbd2cSJim Jagielski } 109*b1cdbd2cSJim Jagielski isWriteable() const110*b1cdbd2cSJim Jagielski virtual bool isWriteable() const 111*b1cdbd2cSJim Jagielski { 112*b1cdbd2cSJim Jagielski return m_pWriter != NULL; 113*b1cdbd2cSJim Jagielski } 114*b1cdbd2cSJim Jagielski }; 115*b1cdbd2cSJim Jagielski 116*b1cdbd2cSJim Jagielski /** helper class for implementing property accessors via non-UNO methods 117*b1cdbd2cSJim Jagielski */ 118*b1cdbd2cSJim Jagielski template< typename CLASS, typename VALUE > 119*b1cdbd2cSJim Jagielski class DirectPropertyAccessor 120*b1cdbd2cSJim Jagielski :public GenericPropertyAccessor < CLASS 121*b1cdbd2cSJim Jagielski , VALUE 122*b1cdbd2cSJim Jagielski , void (CLASS::*)( const VALUE& ) 123*b1cdbd2cSJim Jagielski , VALUE (CLASS::*)() const 124*b1cdbd2cSJim Jagielski > 125*b1cdbd2cSJim Jagielski { 126*b1cdbd2cSJim Jagielski protected: 127*b1cdbd2cSJim Jagielski typedef void (CLASS::*Writer)( const VALUE& ); 128*b1cdbd2cSJim Jagielski typedef VALUE (CLASS::*Reader)() const; 129*b1cdbd2cSJim Jagielski public: DirectPropertyAccessor(CLASS * pInstance,Writer pWriter,Reader pReader)130*b1cdbd2cSJim Jagielski DirectPropertyAccessor( CLASS* pInstance, Writer pWriter, Reader pReader ) 131*b1cdbd2cSJim Jagielski :GenericPropertyAccessor< CLASS, VALUE, Writer, Reader >( pInstance, pWriter, pReader ) 132*b1cdbd2cSJim Jagielski { 133*b1cdbd2cSJim Jagielski } 134*b1cdbd2cSJim Jagielski }; 135*b1cdbd2cSJim Jagielski 136*b1cdbd2cSJim Jagielski /** helper class for implementing non-UNO accessors to a boolean property 137*b1cdbd2cSJim Jagielski */ 138*b1cdbd2cSJim Jagielski template< typename CLASS, typename DUMMY > 139*b1cdbd2cSJim Jagielski class BooleanPropertyAccessor 140*b1cdbd2cSJim Jagielski :public GenericPropertyAccessor < CLASS 141*b1cdbd2cSJim Jagielski , bool 142*b1cdbd2cSJim Jagielski , void (CLASS::*)( bool ) 143*b1cdbd2cSJim Jagielski , bool (CLASS::*)() const 144*b1cdbd2cSJim Jagielski > 145*b1cdbd2cSJim Jagielski { 146*b1cdbd2cSJim Jagielski protected: 147*b1cdbd2cSJim Jagielski typedef void (CLASS::*Writer)( bool ); 148*b1cdbd2cSJim Jagielski typedef bool (CLASS::*Reader)() const; 149*b1cdbd2cSJim Jagielski public: BooleanPropertyAccessor(CLASS * pInstance,Writer pWriter,Reader pReader)150*b1cdbd2cSJim Jagielski BooleanPropertyAccessor( CLASS* pInstance, Writer pWriter, Reader pReader ) 151*b1cdbd2cSJim Jagielski :GenericPropertyAccessor< CLASS, bool, Writer, Reader >( pInstance, pWriter, pReader ) 152*b1cdbd2cSJim Jagielski { 153*b1cdbd2cSJim Jagielski } 154*b1cdbd2cSJim Jagielski }; 155*b1cdbd2cSJim Jagielski 156*b1cdbd2cSJim Jagielski /** helper class for implementing property accessors via UNO methods 157*b1cdbd2cSJim Jagielski */ 158*b1cdbd2cSJim Jagielski template< typename CLASS, typename VALUE > 159*b1cdbd2cSJim Jagielski class APIPropertyAccessor 160*b1cdbd2cSJim Jagielski :public GenericPropertyAccessor < CLASS 161*b1cdbd2cSJim Jagielski , VALUE 162*b1cdbd2cSJim Jagielski , void (SAL_CALL CLASS::*)( const VALUE& ) 163*b1cdbd2cSJim Jagielski , VALUE (SAL_CALL CLASS::*)() 164*b1cdbd2cSJim Jagielski > 165*b1cdbd2cSJim Jagielski { 166*b1cdbd2cSJim Jagielski protected: 167*b1cdbd2cSJim Jagielski typedef void (SAL_CALL CLASS::*Writer)( const VALUE& ); 168*b1cdbd2cSJim Jagielski typedef VALUE (SAL_CALL CLASS::*Reader)(); 169*b1cdbd2cSJim Jagielski public: APIPropertyAccessor(CLASS * pInstance,Writer pWriter,Reader pReader)170*b1cdbd2cSJim Jagielski APIPropertyAccessor( CLASS* pInstance, Writer pWriter, Reader pReader ) 171*b1cdbd2cSJim Jagielski :GenericPropertyAccessor< CLASS, VALUE, Writer, Reader >( pInstance, pWriter, pReader ) 172*b1cdbd2cSJim Jagielski { 173*b1cdbd2cSJim Jagielski } 174*b1cdbd2cSJim Jagielski }; 175*b1cdbd2cSJim Jagielski 176*b1cdbd2cSJim Jagielski /** bridges two XPropertySet helper implementations 177*b1cdbd2cSJim Jagielski 178*b1cdbd2cSJim Jagielski The <type scope="comphelper">OStatefulPropertySet</type> (basically, the 179*b1cdbd2cSJim Jagielski <type scope="cppu">OPropertySetHelper</type>) implements a comprehensive framework 180*b1cdbd2cSJim Jagielski for property sets, including property change notifications. 181*b1cdbd2cSJim Jagielski However, it lacks some easy possibilities to declare the supported properties. 182*b1cdbd2cSJim Jagielski Other helper structs and classes allow for this, but are lacking needed features 183*b1cdbd2cSJim Jagielski such as property change notifications. 184*b1cdbd2cSJim Jagielski 185*b1cdbd2cSJim Jagielski The <type>PropertySetBase</type> bridges various implementations, 186*b1cdbd2cSJim Jagielski so you have the best of both worlds. 187*b1cdbd2cSJim Jagielski */ 188*b1cdbd2cSJim Jagielski class PropertySetBase : public ::comphelper::OStatefulPropertySet 189*b1cdbd2cSJim Jagielski { 190*b1cdbd2cSJim Jagielski private: 191*b1cdbd2cSJim Jagielski typedef com::sun::star::uno::Any Any_t; 192*b1cdbd2cSJim Jagielski 193*b1cdbd2cSJim Jagielski typedef ::std::map< const sal_Int32, ::rtl::Reference< PropertyAccessorBase > > PropertyAccessors; 194*b1cdbd2cSJim Jagielski typedef ::std::vector< ::com::sun::star::beans::Property > PropertyArray; 195*b1cdbd2cSJim Jagielski typedef ::std::map< const sal_Int32, Any_t > PropertyValueCache; 196*b1cdbd2cSJim Jagielski 197*b1cdbd2cSJim Jagielski PropertyArray m_aProperties; 198*b1cdbd2cSJim Jagielski cppu::IPropertyArrayHelper* m_pProperties; 199*b1cdbd2cSJim Jagielski PropertyAccessors m_aAccessors; 200*b1cdbd2cSJim Jagielski PropertyValueCache m_aCache; 201*b1cdbd2cSJim Jagielski 202*b1cdbd2cSJim Jagielski protected: 203*b1cdbd2cSJim Jagielski PropertySetBase(); 204*b1cdbd2cSJim Jagielski virtual ~PropertySetBase(); 205*b1cdbd2cSJim Jagielski 206*b1cdbd2cSJim Jagielski /** registers a new property to be supported by this instance 207*b1cdbd2cSJim Jagielski @param rProperty 208*b1cdbd2cSJim Jagielski the descriptor for the to-be-supported property 209*b1cdbd2cSJim Jagielski @param rAccessor 210*b1cdbd2cSJim Jagielski an instance which is able to provide read and possibly write access to 211*b1cdbd2cSJim Jagielski the property. 212*b1cdbd2cSJim Jagielski @precond 213*b1cdbd2cSJim Jagielski Must not be called after any of the property set related UNO interfaces 214*b1cdbd2cSJim Jagielski has been used. Usually, you will do a number of <member>registerProperty</member> 215*b1cdbd2cSJim Jagielski calls in the constructor of your class. 216*b1cdbd2cSJim Jagielski */ 217*b1cdbd2cSJim Jagielski void registerProperty( 218*b1cdbd2cSJim Jagielski const com::sun::star::beans::Property& rProperty, 219*b1cdbd2cSJim Jagielski const ::rtl::Reference< PropertyAccessorBase >& rAccessor 220*b1cdbd2cSJim Jagielski ); 221*b1cdbd2cSJim Jagielski 222*b1cdbd2cSJim Jagielski /** notifies a change in a given property value, if necessary 223*b1cdbd2cSJim Jagielski 224*b1cdbd2cSJim Jagielski The necessity of the notification is determined by a cached value for the given 225*b1cdbd2cSJim Jagielski property. Caching happens after notification. 226*b1cdbd2cSJim Jagielski 227*b1cdbd2cSJim Jagielski That is, when you call <member>notifyAndCachePropertyValue</member> for the first time, 228*b1cdbd2cSJim Jagielski a value for the given property is default constructed, and considered to be the "old value". 229*b1cdbd2cSJim Jagielski If this value differs from the current value, then this change is notified to all interested 230*b1cdbd2cSJim Jagielski listeners. Finally, the current value is remembered. 231*b1cdbd2cSJim Jagielski 232*b1cdbd2cSJim Jagielski Subsequent calls to <member>notifyAndCachePropertyValue</member> use the remembered value as 233*b1cdbd2cSJim Jagielski "old value", and from then on behave as the first call. 234*b1cdbd2cSJim Jagielski 235*b1cdbd2cSJim Jagielski @param nHandle 236*b1cdbd2cSJim Jagielski the handle of the property. Must denote a property supported by this instance, i.e. 237*b1cdbd2cSJim Jagielski one previously registered via <member>registerProperty</member>. 238*b1cdbd2cSJim Jagielski 239*b1cdbd2cSJim Jagielski @precond 240*b1cdbd2cSJim Jagielski our ref count must not be 0. The reason is that during this method's execution, 241*b1cdbd2cSJim Jagielski the instance might be acquired and released, which would immediately destroy 242*b1cdbd2cSJim Jagielski the instance if it has a ref count of 0. 243*b1cdbd2cSJim Jagielski 244*b1cdbd2cSJim Jagielski @seealso initializePropertyValueCache 245*b1cdbd2cSJim Jagielski */ 246*b1cdbd2cSJim Jagielski void notifyAndCachePropertyValue( sal_Int32 nHandle ); 247*b1cdbd2cSJim Jagielski 248*b1cdbd2cSJim Jagielski /** initializes the property value cache for the given property, with its current value 249*b1cdbd2cSJim Jagielski 250*b1cdbd2cSJim Jagielski Usually used to initialize the cache with values which are different from default 251*b1cdbd2cSJim Jagielski constructed values. Say you have a boolean property whose initial state 252*b1cdbd2cSJim Jagielski is <TRUE/>. Say you call <member>notifyAndCachePropertyValue</member> the first time: it will 253*b1cdbd2cSJim Jagielski default construct the "old value" for this property as <FALSE/>, and thus <b>not</b> do 254*b1cdbd2cSJim Jagielski any notifications if the "current value" is also <FALSE/> - which might be wrong, since 255*b1cdbd2cSJim Jagielski the guessing of the "old value" differed from the real initial value which was <TRUE/>. 256*b1cdbd2cSJim Jagielski 257*b1cdbd2cSJim Jagielski Too confusing? Okay, than just call this method for every property you have. 258*b1cdbd2cSJim Jagielski 259*b1cdbd2cSJim Jagielski @param nHandle 260*b1cdbd2cSJim Jagielski the handle of the property. Must denote a property supported by this instance, i.e. 261*b1cdbd2cSJim Jagielski one previously registered via <member>registerProperty</member>. 262*b1cdbd2cSJim Jagielski @param rValue 263*b1cdbd2cSJim Jagielski the value to cache 264*b1cdbd2cSJim Jagielski @seealso notifyAndCachePropertyValue 265*b1cdbd2cSJim Jagielski */ 266*b1cdbd2cSJim Jagielski void initializePropertyValueCache( sal_Int32 nHandle ); 267*b1cdbd2cSJim Jagielski 268*b1cdbd2cSJim Jagielski /// OPropertysetHelper methods 269*b1cdbd2cSJim Jagielski virtual sal_Bool SAL_CALL convertFastPropertyValue( Any_t& rConvertedValue, Any_t& rOldValue, sal_Int32 nHandle, const Any_t& rValue ) 270*b1cdbd2cSJim Jagielski throw (::com::sun::star::lang::IllegalArgumentException); 271*b1cdbd2cSJim Jagielski virtual void SAL_CALL setFastPropertyValue_NoBroadcast( sal_Int32 nHandle, const Any_t& rValue ) 272*b1cdbd2cSJim Jagielski throw (::com::sun::star::uno::Exception); 273*b1cdbd2cSJim Jagielski virtual void SAL_CALL getFastPropertyValue( Any_t& rValue, sal_Int32 nHandle ) const; 274*b1cdbd2cSJim Jagielski 275*b1cdbd2cSJim Jagielski virtual cppu::IPropertyArrayHelper& SAL_CALL getInfoHelper(); 276*b1cdbd2cSJim Jagielski virtual ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertySetInfo > SAL_CALL getPropertySetInfo( ) throw(::com::sun::star::uno::RuntimeException); 277*b1cdbd2cSJim Jagielski 278*b1cdbd2cSJim Jagielski public: 279*b1cdbd2cSJim Jagielski /// helper struct for granting selective access to some notification-related methods NotifierAccessPropertySetBase::NotifierAccess280*b1cdbd2cSJim Jagielski struct NotifierAccess { friend struct PropertyChangeNotifier; private: NotifierAccess() { } }; 281*b1cdbd2cSJim Jagielski /** retrieves the current property value for the given handle 282*b1cdbd2cSJim Jagielski @param nHandle 283*b1cdbd2cSJim Jagielski the handle of the property. Must denote a property supported by this instance, i.e. 284*b1cdbd2cSJim Jagielski one previously registered via <member>registerProperty</member>. 285*b1cdbd2cSJim Jagielski @see registerProperty 286*b1cdbd2cSJim Jagielski */ getCurrentPropertyValueByHandle(sal_Int32 nHandle,Any_t & rValue,const NotifierAccess &) const287*b1cdbd2cSJim Jagielski inline void getCurrentPropertyValueByHandle( sal_Int32 nHandle, Any_t& /* [out] */ rValue, const NotifierAccess& ) const 288*b1cdbd2cSJim Jagielski { 289*b1cdbd2cSJim Jagielski getFastPropertyValue( rValue, nHandle ); 290*b1cdbd2cSJim Jagielski } 291*b1cdbd2cSJim Jagielski 292*b1cdbd2cSJim Jagielski /** notifies a change in a given property to all interested listeners 293*b1cdbd2cSJim Jagielski */ notifyPropertyChange(sal_Int32 nHandle,const Any_t & rOldValue,const Any_t & rNewValue,const NotifierAccess &) const294*b1cdbd2cSJim Jagielski inline void notifyPropertyChange( sal_Int32 nHandle, const Any_t& rOldValue, const Any_t& rNewValue, const NotifierAccess& ) const 295*b1cdbd2cSJim Jagielski { 296*b1cdbd2cSJim Jagielski const_cast< PropertySetBase* >( this )->firePropertyChange( nHandle, rNewValue, rOldValue ); 297*b1cdbd2cSJim Jagielski } 298*b1cdbd2cSJim Jagielski 299*b1cdbd2cSJim Jagielski using ::comphelper::OStatefulPropertySet::getFastPropertyValue; 300*b1cdbd2cSJim Jagielski 301*b1cdbd2cSJim Jagielski private: 302*b1cdbd2cSJim Jagielski /** locates a property given by handle 303*b1cdbd2cSJim Jagielski @param nHandle 304*b1cdbd2cSJim Jagielski the handle of the property. Must denote a property supported by this instance, i.e. 305*b1cdbd2cSJim Jagielski one previously registered via <member>registerProperty</member>. 306*b1cdbd2cSJim Jagielski @see registerProperty 307*b1cdbd2cSJim Jagielski */ 308*b1cdbd2cSJim Jagielski PropertyAccessorBase& locatePropertyHandler( sal_Int32 nHandle ) const; 309*b1cdbd2cSJim Jagielski }; 310*b1cdbd2cSJim Jagielski 311*b1cdbd2cSJim Jagielski /** a helper class for notifying property changes in a <type>PropertySetBase</type> instance. 312*b1cdbd2cSJim Jagielski 313*b1cdbd2cSJim Jagielski You can create an instance of this class on the stack of a method which is to programmatically 314*b1cdbd2cSJim Jagielski change the value of a property. In its constructor, the instance will acquire the current property 315*b1cdbd2cSJim Jagielski value, and in its destructor, it will notify the change of this property's value (if necessary). 316*b1cdbd2cSJim Jagielski 317*b1cdbd2cSJim Jagielski You do not need this class if you are modifying property values by using the X(Fast|Multi)PropertSet 318*b1cdbd2cSJim Jagielski methods, since those already care for property notifications. You only need it if you're changing 319*b1cdbd2cSJim Jagielski the internal representation of your property directly. 320*b1cdbd2cSJim Jagielski 321*b1cdbd2cSJim Jagielski Also note that usually, notifications in the UNO world should be done without a locked mutex. So 322*b1cdbd2cSJim Jagielski if you use this class in conjunction with a <type>MutexGuard</type>, ensure that you <b>first</b> 323*b1cdbd2cSJim Jagielski instantiate the <type>PropertyChangeNotifier</type>, and <b>then</b> the <type>MutexGuard</type>, 324*b1cdbd2cSJim Jagielski so your mutex is released before the notification happens. 325*b1cdbd2cSJim Jagielski */ 326*b1cdbd2cSJim Jagielski struct PropertyChangeNotifier 327*b1cdbd2cSJim Jagielski { 328*b1cdbd2cSJim Jagielski private: 329*b1cdbd2cSJim Jagielski const PropertySetBase& m_rPropertySet; 330*b1cdbd2cSJim Jagielski sal_Int32 m_nHandle; 331*b1cdbd2cSJim Jagielski com::sun::star::uno::Any m_aOldValue; 332*b1cdbd2cSJim Jagielski 333*b1cdbd2cSJim Jagielski public: 334*b1cdbd2cSJim Jagielski /** constructs a PropertyChangeNotifier 335*b1cdbd2cSJim Jagielski @param rPropertySet 336*b1cdbd2cSJim Jagielski the property set implementation whose property is going to be changed. Note 337*b1cdbd2cSJim Jagielski that this property set implementation must live at least as long as the 338*b1cdbd2cSJim Jagielski PropertyChangeNotifier instance does. 339*b1cdbd2cSJim Jagielski @param nHandle 340*b1cdbd2cSJim Jagielski the handle of the property which is going to be changed. Must be a valid property 341*b1cdbd2cSJim Jagielski handle for the given <arg>rPropertySet</arg> 342*b1cdbd2cSJim Jagielski */ PropertyChangeNotifierPropertyChangeNotifier343*b1cdbd2cSJim Jagielski inline PropertyChangeNotifier( const PropertySetBase& rPropertySet, sal_Int32 nHandle ) 344*b1cdbd2cSJim Jagielski :m_rPropertySet( rPropertySet ) 345*b1cdbd2cSJim Jagielski ,m_nHandle( nHandle ) 346*b1cdbd2cSJim Jagielski { 347*b1cdbd2cSJim Jagielski m_rPropertySet.getCurrentPropertyValueByHandle( m_nHandle, m_aOldValue, PropertySetBase::NotifierAccess() ); 348*b1cdbd2cSJim Jagielski } ~PropertyChangeNotifierPropertyChangeNotifier349*b1cdbd2cSJim Jagielski inline ~PropertyChangeNotifier() 350*b1cdbd2cSJim Jagielski { 351*b1cdbd2cSJim Jagielski com::sun::star::uno::Any aNewValue; 352*b1cdbd2cSJim Jagielski m_rPropertySet.getCurrentPropertyValueByHandle( m_nHandle, aNewValue, PropertySetBase::NotifierAccess() ); 353*b1cdbd2cSJim Jagielski if ( aNewValue != m_aOldValue ) 354*b1cdbd2cSJim Jagielski { 355*b1cdbd2cSJim Jagielski m_rPropertySet.notifyPropertyChange( m_nHandle, m_aOldValue, aNewValue, PropertySetBase::NotifierAccess() ); 356*b1cdbd2cSJim Jagielski } 357*b1cdbd2cSJim Jagielski } 358*b1cdbd2cSJim Jagielski }; 359*b1cdbd2cSJim Jagielski 360*b1cdbd2cSJim Jagielski 361*b1cdbd2cSJim Jagielski #define PROPERTY_FLAGS( NAME, TYPE, FLAG ) com::sun::star::beans::Property( \ 362*b1cdbd2cSJim Jagielski ::rtl::OUString( #NAME, sizeof( #NAME ) - 1, RTL_TEXTENCODING_ASCII_US ), \ 363*b1cdbd2cSJim Jagielski HANDLE_##NAME, getCppuType( static_cast< TYPE* >( NULL ) ), FLAG ) 364*b1cdbd2cSJim Jagielski #define PROPERTY( NAME, TYPE ) PROPERTY_FLAGS( NAME, TYPE, com::sun::star::beans::PropertyAttribute::BOUND ) 365*b1cdbd2cSJim Jagielski #define PROPERTY_RO( NAME, TYPE ) PROPERTY_FLAGS( NAME, TYPE, com::sun::star::beans::PropertyAttribute::BOUND | com::sun::star::beans::PropertyAttribute::READONLY ) 366*b1cdbd2cSJim Jagielski 367*b1cdbd2cSJim Jagielski #endif 368