1*9d7e27acSAndrew Rist /************************************************************** 2cdf0e10cSrcweir * 3*9d7e27acSAndrew Rist * Licensed to the Apache Software Foundation (ASF) under one 4*9d7e27acSAndrew Rist * or more contributor license agreements. See the NOTICE file 5*9d7e27acSAndrew Rist * distributed with this work for additional information 6*9d7e27acSAndrew Rist * regarding copyright ownership. The ASF licenses this file 7*9d7e27acSAndrew Rist * to you under the Apache License, Version 2.0 (the 8*9d7e27acSAndrew Rist * "License"); you may not use this file except in compliance 9*9d7e27acSAndrew Rist * with the License. You may obtain a copy of the License at 10*9d7e27acSAndrew Rist * 11*9d7e27acSAndrew Rist * http://www.apache.org/licenses/LICENSE-2.0 12*9d7e27acSAndrew Rist * 13*9d7e27acSAndrew Rist * Unless required by applicable law or agreed to in writing, 14*9d7e27acSAndrew Rist * software distributed under the License is distributed on an 15*9d7e27acSAndrew Rist * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 16*9d7e27acSAndrew Rist * KIND, either express or implied. See the License for the 17*9d7e27acSAndrew Rist * specific language governing permissions and limitations 18*9d7e27acSAndrew Rist * under the License. 19*9d7e27acSAndrew Rist * 20*9d7e27acSAndrew Rist *************************************************************/ 21*9d7e27acSAndrew Rist 22*9d7e27acSAndrew Rist 23cdf0e10cSrcweir 24cdf0e10cSrcweir // MARKER(update_precomp.py): autogen include statement, do not remove 25cdf0e10cSrcweir #include "precompiled_cppuhelper.hxx" 26cdf0e10cSrcweir 27cdf0e10cSrcweir #include "osl/diagnose.h" 28cdf0e10cSrcweir #include "cppuhelper/implbase1.hxx" 29cdf0e10cSrcweir #include "cppuhelper/weak.hxx" 30cdf0e10cSrcweir #include "cppuhelper/propshlp.hxx" 31cdf0e10cSrcweir #include "cppuhelper/exc_hlp.hxx" 32cdf0e10cSrcweir #include "com/sun/star/beans/PropertyAttribute.hpp" 33cdf0e10cSrcweir #include "com/sun/star/lang/DisposedException.hpp" 34cdf0e10cSrcweir 35cdf0e10cSrcweir 36cdf0e10cSrcweir using namespace osl; 37cdf0e10cSrcweir using namespace com::sun::star::uno; 38cdf0e10cSrcweir using namespace com::sun::star::beans; 39cdf0e10cSrcweir using namespace com::sun::star::lang; 40cdf0e10cSrcweir using namespace rtl; 41cdf0e10cSrcweir using namespace cppu; 42cdf0e10cSrcweir 43cdf0e10cSrcweir namespace cppu { 44cdf0e10cSrcweir 45cdf0e10cSrcweir IPropertyArrayHelper::~IPropertyArrayHelper() 46cdf0e10cSrcweir { 47cdf0e10cSrcweir } 48cdf0e10cSrcweir 49cdf0e10cSrcweir inline const ::com::sun::star::uno::Type & getPropertyTypeIdentifier( ) SAL_THROW( () ) 50cdf0e10cSrcweir { 51cdf0e10cSrcweir return ::getCppuType( (Reference< XPropertyChangeListener > *)0 ); 52cdf0e10cSrcweir } 53cdf0e10cSrcweir inline const ::com::sun::star::uno::Type & getPropertiesTypeIdentifier() SAL_THROW( () ) 54cdf0e10cSrcweir { 55cdf0e10cSrcweir return ::getCppuType( (Reference< XPropertiesChangeListener > *)0 ); 56cdf0e10cSrcweir } 57cdf0e10cSrcweir inline const ::com::sun::star::uno::Type & getVetoableTypeIdentifier() SAL_THROW( () ) 58cdf0e10cSrcweir { 59cdf0e10cSrcweir return ::getCppuType( (Reference< XVetoableChangeListener > *)0 ); 60cdf0e10cSrcweir } 61cdf0e10cSrcweir 62cdf0e10cSrcweir extern "C" { 63cdf0e10cSrcweir 64cdf0e10cSrcweir static int compare_OUString_Property_Impl( const void *arg1, const void *arg2 ) 65cdf0e10cSrcweir SAL_THROW_EXTERN_C() 66cdf0e10cSrcweir { 67cdf0e10cSrcweir return ((OUString *)arg1)->compareTo( ((Property *)arg2)->Name ); 68cdf0e10cSrcweir } 69cdf0e10cSrcweir 70cdf0e10cSrcweir } 71cdf0e10cSrcweir 72cdf0e10cSrcweir /** 73cdf0e10cSrcweir * The class which implements the PropertySetInfo interface. 74cdf0e10cSrcweir */ 75cdf0e10cSrcweir 76cdf0e10cSrcweir class OPropertySetHelperInfo_Impl 77cdf0e10cSrcweir : public WeakImplHelper1< ::com::sun::star::beans::XPropertySetInfo > 78cdf0e10cSrcweir { 79cdf0e10cSrcweir Sequence < Property > aInfos; 80cdf0e10cSrcweir 81cdf0e10cSrcweir public: 82cdf0e10cSrcweir OPropertySetHelperInfo_Impl( IPropertyArrayHelper & rHelper_ ) SAL_THROW( () ); 83cdf0e10cSrcweir 84cdf0e10cSrcweir // XPropertySetInfo-Methoden 85cdf0e10cSrcweir virtual Sequence< Property > SAL_CALL getProperties(void) throw(::com::sun::star::uno::RuntimeException); 86cdf0e10cSrcweir virtual Property SAL_CALL getPropertyByName(const OUString& PropertyName) throw(::com::sun::star::beans::UnknownPropertyException, ::com::sun::star::uno::RuntimeException); 87cdf0e10cSrcweir virtual sal_Bool SAL_CALL hasPropertyByName(const OUString& PropertyName) throw(::com::sun::star::uno::RuntimeException); 88cdf0e10cSrcweir }; 89cdf0e10cSrcweir 90cdf0e10cSrcweir 91cdf0e10cSrcweir /** 92cdf0e10cSrcweir * Create an object that implements XPropertySetInfo IPropertyArrayHelper. 93cdf0e10cSrcweir */ 94cdf0e10cSrcweir OPropertySetHelperInfo_Impl::OPropertySetHelperInfo_Impl( 95cdf0e10cSrcweir IPropertyArrayHelper & rHelper_ ) 96cdf0e10cSrcweir SAL_THROW( () ) 97cdf0e10cSrcweir :aInfos( rHelper_.getProperties() ) 98cdf0e10cSrcweir { 99cdf0e10cSrcweir } 100cdf0e10cSrcweir 101cdf0e10cSrcweir /** 102cdf0e10cSrcweir * Return the sequence of properties, which are provided throug the constructor. 103cdf0e10cSrcweir */ 104cdf0e10cSrcweir Sequence< Property > OPropertySetHelperInfo_Impl::getProperties(void) throw(::com::sun::star::uno::RuntimeException) 105cdf0e10cSrcweir 106cdf0e10cSrcweir { 107cdf0e10cSrcweir return aInfos; 108cdf0e10cSrcweir } 109cdf0e10cSrcweir 110cdf0e10cSrcweir /** 111cdf0e10cSrcweir * Return the sequence of properties, which are provided throug the constructor. 112cdf0e10cSrcweir */ 113cdf0e10cSrcweir Property OPropertySetHelperInfo_Impl::getPropertyByName( const OUString & PropertyName ) throw(::com::sun::star::beans::UnknownPropertyException, ::com::sun::star::uno::RuntimeException) 114cdf0e10cSrcweir { 115cdf0e10cSrcweir Property * pR; 116cdf0e10cSrcweir pR = (Property *)bsearch( &PropertyName, aInfos.getConstArray(), aInfos.getLength(), 117cdf0e10cSrcweir sizeof( Property ), 118cdf0e10cSrcweir compare_OUString_Property_Impl ); 119cdf0e10cSrcweir if( !pR ) { 120cdf0e10cSrcweir throw UnknownPropertyException(); 121cdf0e10cSrcweir } 122cdf0e10cSrcweir 123cdf0e10cSrcweir return *pR; 124cdf0e10cSrcweir } 125cdf0e10cSrcweir 126cdf0e10cSrcweir /** 127cdf0e10cSrcweir * Return the sequence of properties, which are provided throug the constructor. 128cdf0e10cSrcweir */ 129cdf0e10cSrcweir sal_Bool OPropertySetHelperInfo_Impl::hasPropertyByName( const OUString & PropertyName ) throw(::com::sun::star::uno::RuntimeException) 130cdf0e10cSrcweir { 131cdf0e10cSrcweir Property * pR; 132cdf0e10cSrcweir pR = (Property *)bsearch( &PropertyName, aInfos.getConstArray(), aInfos.getLength(), 133cdf0e10cSrcweir sizeof( Property ), 134cdf0e10cSrcweir compare_OUString_Property_Impl ); 135cdf0e10cSrcweir return pR != NULL; 136cdf0e10cSrcweir } 137cdf0e10cSrcweir 138cdf0e10cSrcweir // ---------------------------------------------------- 139cdf0e10cSrcweir // class PropertySetHelper_Impl 140cdf0e10cSrcweir // ---------------------------------------------------- 141cdf0e10cSrcweir class OPropertySetHelper::Impl { 142cdf0e10cSrcweir 143cdf0e10cSrcweir public: 144cdf0e10cSrcweir Impl( bool i_bIgnoreRuntimeExceptionsWhileFiring, 145cdf0e10cSrcweir IEventNotificationHook *i_pFireEvents 146cdf0e10cSrcweir ) 147cdf0e10cSrcweir :m_bIgnoreRuntimeExceptionsWhileFiring( i_bIgnoreRuntimeExceptionsWhileFiring ) 148cdf0e10cSrcweir ,m_pFireEvents( i_pFireEvents ) 149cdf0e10cSrcweir { 150cdf0e10cSrcweir } 151cdf0e10cSrcweir 152cdf0e10cSrcweir bool m_bIgnoreRuntimeExceptionsWhileFiring; 153cdf0e10cSrcweir class IEventNotificationHook * const m_pFireEvents; 154cdf0e10cSrcweir 155cdf0e10cSrcweir ::std::vector< sal_Int32 > m_handles; 156cdf0e10cSrcweir ::std::vector< Any > m_newValues; 157cdf0e10cSrcweir ::std::vector< Any > m_oldValues; 158cdf0e10cSrcweir }; 159cdf0e10cSrcweir 160cdf0e10cSrcweir 161cdf0e10cSrcweir // ---------------------------------------------------- 162cdf0e10cSrcweir // class PropertySetHelper 163cdf0e10cSrcweir // ---------------------------------------------------- 164cdf0e10cSrcweir OPropertySetHelper::OPropertySetHelper( 165cdf0e10cSrcweir OBroadcastHelper & rBHelper_ ) SAL_THROW( () ) 166cdf0e10cSrcweir : rBHelper( rBHelper_ ), 167cdf0e10cSrcweir aBoundLC( rBHelper_.rMutex ), 168cdf0e10cSrcweir aVetoableLC( rBHelper_.rMutex ), 169cdf0e10cSrcweir m_pReserved( new Impl(false, 0) ) 170cdf0e10cSrcweir { 171cdf0e10cSrcweir } 172cdf0e10cSrcweir 173cdf0e10cSrcweir OPropertySetHelper::OPropertySetHelper( 174cdf0e10cSrcweir OBroadcastHelper & rBHelper_, bool bIgnoreRuntimeExceptionsWhileFiring ) 175cdf0e10cSrcweir : rBHelper( rBHelper_ ), 176cdf0e10cSrcweir aBoundLC( rBHelper_.rMutex ), 177cdf0e10cSrcweir aVetoableLC( rBHelper_.rMutex ), 178cdf0e10cSrcweir m_pReserved( new Impl( bIgnoreRuntimeExceptionsWhileFiring, 0 ) ) 179cdf0e10cSrcweir { 180cdf0e10cSrcweir } 181cdf0e10cSrcweir 182cdf0e10cSrcweir OPropertySetHelper::OPropertySetHelper( 183cdf0e10cSrcweir OBroadcastHelper & rBHelper_, IEventNotificationHook * i_pFireEvents, 184cdf0e10cSrcweir bool bIgnoreRuntimeExceptionsWhileFiring) 185cdf0e10cSrcweir : rBHelper( rBHelper_ ), 186cdf0e10cSrcweir aBoundLC( rBHelper_.rMutex ), 187cdf0e10cSrcweir aVetoableLC( rBHelper_.rMutex ), 188cdf0e10cSrcweir m_pReserved( 189cdf0e10cSrcweir new Impl( bIgnoreRuntimeExceptionsWhileFiring, i_pFireEvents) ) 190cdf0e10cSrcweir { 191cdf0e10cSrcweir } 192cdf0e10cSrcweir 193cdf0e10cSrcweir /** 194cdf0e10cSrcweir * You must call disposing before. 195cdf0e10cSrcweir */ 196cdf0e10cSrcweir OPropertySetHelper::~OPropertySetHelper() SAL_THROW( () ) 197cdf0e10cSrcweir { 198cdf0e10cSrcweir } 199cdf0e10cSrcweir 200cdf0e10cSrcweir /** 201cdf0e10cSrcweir * These method is called from queryInterface, if no delegator is set. 202cdf0e10cSrcweir * Otherwise this method is called from the delegator. 203cdf0e10cSrcweir */ 204cdf0e10cSrcweir // XAggregation 205cdf0e10cSrcweir Any OPropertySetHelper::queryInterface( const ::com::sun::star::uno::Type & rType ) 206cdf0e10cSrcweir throw (RuntimeException) 207cdf0e10cSrcweir { 208cdf0e10cSrcweir return ::cppu::queryInterface( 209cdf0e10cSrcweir rType, 210cdf0e10cSrcweir static_cast< XPropertySet * >( this ), 211cdf0e10cSrcweir static_cast< XMultiPropertySet * >( this ), 212cdf0e10cSrcweir static_cast< XFastPropertySet * >( this ) ); 213cdf0e10cSrcweir } 214cdf0e10cSrcweir 215cdf0e10cSrcweir /** 216cdf0e10cSrcweir * called from the derivee's XTypeProvider::getTypes implementation 217cdf0e10cSrcweir */ 218cdf0e10cSrcweir ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Type > OPropertySetHelper::getTypes() 219cdf0e10cSrcweir throw (RuntimeException) 220cdf0e10cSrcweir { 221cdf0e10cSrcweir Sequence< ::com::sun::star::uno::Type > aTypes( 3 ); 222cdf0e10cSrcweir aTypes[ 0 ] = XPropertySet::static_type(); 223cdf0e10cSrcweir aTypes[ 1 ] = XMultiPropertySet::static_type(); 224cdf0e10cSrcweir aTypes[ 2 ] = XFastPropertySet::static_type(); 225cdf0e10cSrcweir return aTypes; 226cdf0e10cSrcweir } 227cdf0e10cSrcweir 228cdf0e10cSrcweir // ComponentHelper 229cdf0e10cSrcweir void OPropertySetHelper::disposing() SAL_THROW( () ) 230cdf0e10cSrcweir { 231cdf0e10cSrcweir // Create an event with this as sender 232cdf0e10cSrcweir Reference < XPropertySet > rSource( SAL_STATIC_CAST( XPropertySet * , this ) , UNO_QUERY ); 233cdf0e10cSrcweir EventObject aEvt; 234cdf0e10cSrcweir aEvt.Source = rSource; 235cdf0e10cSrcweir 236cdf0e10cSrcweir // inform all listeners to reelease this object 237cdf0e10cSrcweir // The listener container are automaticly cleared 238cdf0e10cSrcweir aBoundLC.disposeAndClear( aEvt ); 239cdf0e10cSrcweir aVetoableLC.disposeAndClear( aEvt ); 240cdf0e10cSrcweir } 241cdf0e10cSrcweir 242cdf0e10cSrcweir Reference < XPropertySetInfo > OPropertySetHelper::createPropertySetInfo( 243cdf0e10cSrcweir IPropertyArrayHelper & rProperties ) SAL_THROW( () ) 244cdf0e10cSrcweir { 245cdf0e10cSrcweir return static_cast< XPropertySetInfo * >( new OPropertySetHelperInfo_Impl( rProperties ) ); 246cdf0e10cSrcweir } 247cdf0e10cSrcweir 248cdf0e10cSrcweir // XPropertySet 249cdf0e10cSrcweir void OPropertySetHelper::setPropertyValue( 250cdf0e10cSrcweir const OUString& rPropertyName, const Any& rValue ) 251cdf0e10cSrcweir 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) 252cdf0e10cSrcweir { 253cdf0e10cSrcweir // get the map table 254cdf0e10cSrcweir IPropertyArrayHelper & rPH = getInfoHelper(); 255cdf0e10cSrcweir // map the name to the handle 256cdf0e10cSrcweir sal_Int32 nHandle = rPH.getHandleByName( rPropertyName ); 257cdf0e10cSrcweir // call the method of the XFastPropertySet interface 258cdf0e10cSrcweir setFastPropertyValue( nHandle, rValue ); 259cdf0e10cSrcweir } 260cdf0e10cSrcweir 261cdf0e10cSrcweir // XPropertySet 262cdf0e10cSrcweir Any OPropertySetHelper::getPropertyValue( 263cdf0e10cSrcweir const OUString& rPropertyName ) 264cdf0e10cSrcweir throw(::com::sun::star::beans::UnknownPropertyException, ::com::sun::star::lang::WrappedTargetException, ::com::sun::star::uno::RuntimeException) 265cdf0e10cSrcweir { 266cdf0e10cSrcweir // get the map table 267cdf0e10cSrcweir IPropertyArrayHelper & rPH = getInfoHelper(); 268cdf0e10cSrcweir // map the name to the handle 269cdf0e10cSrcweir sal_Int32 nHandle = rPH.getHandleByName( rPropertyName ); 270cdf0e10cSrcweir // call the method of the XFastPropertySet interface 271cdf0e10cSrcweir return getFastPropertyValue( nHandle ); 272cdf0e10cSrcweir } 273cdf0e10cSrcweir 274cdf0e10cSrcweir // XPropertySet 275cdf0e10cSrcweir void OPropertySetHelper::addPropertyChangeListener( 276cdf0e10cSrcweir const OUString& rPropertyName, 277cdf0e10cSrcweir const Reference < XPropertyChangeListener > & rxListener ) 278cdf0e10cSrcweir throw(::com::sun::star::beans::UnknownPropertyException, 279cdf0e10cSrcweir ::com::sun::star::lang::WrappedTargetException, 280cdf0e10cSrcweir ::com::sun::star::uno::RuntimeException) 281cdf0e10cSrcweir { 282cdf0e10cSrcweir MutexGuard aGuard( rBHelper.rMutex ); 283cdf0e10cSrcweir OSL_ENSURE( !rBHelper.bInDispose, "do not addPropertyChangeListener in the dispose call" ); 284cdf0e10cSrcweir OSL_ENSURE( !rBHelper.bDisposed, "object is disposed" ); 285cdf0e10cSrcweir if( !rBHelper.bInDispose && !rBHelper.bDisposed ) 286cdf0e10cSrcweir { 287cdf0e10cSrcweir // only add listeners if you are not disposed 288cdf0e10cSrcweir // a listener with no name means all properties 289cdf0e10cSrcweir if( rPropertyName.getLength() ) 290cdf0e10cSrcweir { 291cdf0e10cSrcweir // get the map table 292cdf0e10cSrcweir IPropertyArrayHelper & rPH = getInfoHelper(); 293cdf0e10cSrcweir // map the name to the handle 294cdf0e10cSrcweir sal_Int32 nHandle = rPH.getHandleByName( rPropertyName ); 295cdf0e10cSrcweir if( nHandle == -1 ) { 296cdf0e10cSrcweir // property not known throw exception 297cdf0e10cSrcweir throw UnknownPropertyException() ; 298cdf0e10cSrcweir } 299cdf0e10cSrcweir 300cdf0e10cSrcweir sal_Int16 nAttributes; 301cdf0e10cSrcweir rPH.fillPropertyMembersByHandle( NULL, &nAttributes, nHandle ); 302cdf0e10cSrcweir if( !(nAttributes & ::com::sun::star::beans::PropertyAttribute::BOUND) ) 303cdf0e10cSrcweir { 304cdf0e10cSrcweir OSL_ENSURE( sal_False, "add listener to an unbound property" ); 305cdf0e10cSrcweir // silent ignore this 306cdf0e10cSrcweir return; 307cdf0e10cSrcweir } 308cdf0e10cSrcweir // add the change listener to the helper container 309cdf0e10cSrcweir 310cdf0e10cSrcweir aBoundLC.addInterface( (sal_Int32)nHandle, rxListener ); 311cdf0e10cSrcweir } 312cdf0e10cSrcweir else 313cdf0e10cSrcweir // add the change listener to the helper container 314cdf0e10cSrcweir rBHelper.aLC.addInterface( 315cdf0e10cSrcweir getPropertyTypeIdentifier( ), 316cdf0e10cSrcweir rxListener 317cdf0e10cSrcweir ); 318cdf0e10cSrcweir } 319cdf0e10cSrcweir } 320cdf0e10cSrcweir 321cdf0e10cSrcweir 322cdf0e10cSrcweir // XPropertySet 323cdf0e10cSrcweir void OPropertySetHelper::removePropertyChangeListener( 324cdf0e10cSrcweir const OUString& rPropertyName, 325cdf0e10cSrcweir const Reference < XPropertyChangeListener >& rxListener ) 326cdf0e10cSrcweir throw(::com::sun::star::beans::UnknownPropertyException, 327cdf0e10cSrcweir ::com::sun::star::lang::WrappedTargetException, 328cdf0e10cSrcweir ::com::sun::star::uno::RuntimeException) 329cdf0e10cSrcweir { 330cdf0e10cSrcweir MutexGuard aGuard( rBHelper.rMutex ); 331cdf0e10cSrcweir OSL_ENSURE( !rBHelper.bDisposed, "object is disposed" ); 332cdf0e10cSrcweir // all listeners are automaticly released in a dispose call 333cdf0e10cSrcweir if( !rBHelper.bInDispose && !rBHelper.bDisposed ) 334cdf0e10cSrcweir { 335cdf0e10cSrcweir if( rPropertyName.getLength() ) 336cdf0e10cSrcweir { 337cdf0e10cSrcweir // get the map table 338cdf0e10cSrcweir IPropertyArrayHelper & rPH = getInfoHelper(); 339cdf0e10cSrcweir // map the name to the handle 340cdf0e10cSrcweir sal_Int32 nHandle = rPH.getHandleByName( rPropertyName ); 341cdf0e10cSrcweir if( nHandle == -1 ) 342cdf0e10cSrcweir // property not known throw exception 343cdf0e10cSrcweir throw UnknownPropertyException(); 344cdf0e10cSrcweir aBoundLC.removeInterface( (sal_Int32)nHandle, rxListener ); 345cdf0e10cSrcweir } 346cdf0e10cSrcweir else { 347cdf0e10cSrcweir // remove the change listener to the helper container 348cdf0e10cSrcweir rBHelper.aLC.removeInterface( 349cdf0e10cSrcweir getPropertyTypeIdentifier( ), 350cdf0e10cSrcweir rxListener 351cdf0e10cSrcweir ); 352cdf0e10cSrcweir } 353cdf0e10cSrcweir } 354cdf0e10cSrcweir } 355cdf0e10cSrcweir 356cdf0e10cSrcweir // XPropertySet 357cdf0e10cSrcweir void OPropertySetHelper::addVetoableChangeListener( 358cdf0e10cSrcweir const OUString& rPropertyName, 359cdf0e10cSrcweir const Reference< XVetoableChangeListener > & rxListener ) 360cdf0e10cSrcweir throw(::com::sun::star::beans::UnknownPropertyException, 361cdf0e10cSrcweir ::com::sun::star::lang::WrappedTargetException, 362cdf0e10cSrcweir ::com::sun::star::uno::RuntimeException) 363cdf0e10cSrcweir { 364cdf0e10cSrcweir MutexGuard aGuard( rBHelper.rMutex ); 365cdf0e10cSrcweir OSL_ENSURE( !rBHelper.bInDispose, "do not addVetoableChangeListener in the dispose call" ); 366cdf0e10cSrcweir OSL_ENSURE( !rBHelper.bDisposed, "object is disposed" ); 367cdf0e10cSrcweir if( !rBHelper.bInDispose && !rBHelper.bDisposed ) 368cdf0e10cSrcweir { 369cdf0e10cSrcweir // only add listeners if you are not disposed 370cdf0e10cSrcweir // a listener with no name means all properties 371cdf0e10cSrcweir if( rPropertyName.getLength() ) 372cdf0e10cSrcweir { 373cdf0e10cSrcweir // get the map table 374cdf0e10cSrcweir IPropertyArrayHelper & rPH = getInfoHelper(); 375cdf0e10cSrcweir // map the name to the handle 376cdf0e10cSrcweir sal_Int32 nHandle = rPH.getHandleByName( rPropertyName ); 377cdf0e10cSrcweir if( nHandle == -1 ) { 378cdf0e10cSrcweir // property not known throw exception 379cdf0e10cSrcweir throw UnknownPropertyException(); 380cdf0e10cSrcweir } 381cdf0e10cSrcweir 382cdf0e10cSrcweir sal_Int16 nAttributes; 383cdf0e10cSrcweir rPH.fillPropertyMembersByHandle( NULL, &nAttributes, nHandle ); 384cdf0e10cSrcweir if( !(nAttributes & PropertyAttribute::CONSTRAINED) ) 385cdf0e10cSrcweir { 386cdf0e10cSrcweir OSL_ENSURE( sal_False, "addVetoableChangeListener, and property is not constrained" ); 387cdf0e10cSrcweir // silent ignore this 388cdf0e10cSrcweir return; 389cdf0e10cSrcweir } 390cdf0e10cSrcweir // add the vetoable listener to the helper container 391cdf0e10cSrcweir aVetoableLC.addInterface( (sal_Int32)nHandle, rxListener ); 392cdf0e10cSrcweir } 393cdf0e10cSrcweir else 394cdf0e10cSrcweir // add the vetoable listener to the helper container 395cdf0e10cSrcweir rBHelper.aLC.addInterface( 396cdf0e10cSrcweir getVetoableTypeIdentifier( ), 397cdf0e10cSrcweir rxListener 398cdf0e10cSrcweir ); 399cdf0e10cSrcweir } 400cdf0e10cSrcweir } 401cdf0e10cSrcweir 402cdf0e10cSrcweir // XPropertySet 403cdf0e10cSrcweir void OPropertySetHelper::removeVetoableChangeListener( 404cdf0e10cSrcweir const OUString& rPropertyName, 405cdf0e10cSrcweir const Reference < XVetoableChangeListener > & rxListener ) 406cdf0e10cSrcweir throw(::com::sun::star::beans::UnknownPropertyException, 407cdf0e10cSrcweir ::com::sun::star::lang::WrappedTargetException, 408cdf0e10cSrcweir ::com::sun::star::uno::RuntimeException) 409cdf0e10cSrcweir { 410cdf0e10cSrcweir MutexGuard aGuard( rBHelper.rMutex ); 411cdf0e10cSrcweir OSL_ENSURE( !rBHelper.bDisposed, "object is disposed" ); 412cdf0e10cSrcweir // all listeners are automaticly released in a dispose call 413cdf0e10cSrcweir if( !rBHelper.bInDispose && !rBHelper.bDisposed ) 414cdf0e10cSrcweir { 415cdf0e10cSrcweir if( rPropertyName.getLength() ) 416cdf0e10cSrcweir { 417cdf0e10cSrcweir // get the map table 418cdf0e10cSrcweir IPropertyArrayHelper & rPH = getInfoHelper(); 419cdf0e10cSrcweir // map the name to the handle 420cdf0e10cSrcweir sal_Int32 nHandle = rPH.getHandleByName( rPropertyName ); 421cdf0e10cSrcweir if( nHandle == -1 ) { 422cdf0e10cSrcweir // property not known throw exception 423cdf0e10cSrcweir throw UnknownPropertyException(); 424cdf0e10cSrcweir } 425cdf0e10cSrcweir // remove the vetoable listener to the helper container 426cdf0e10cSrcweir aVetoableLC.removeInterface( (sal_Int32)nHandle, rxListener ); 427cdf0e10cSrcweir } 428cdf0e10cSrcweir else 429cdf0e10cSrcweir // add the vetoable listener to the helper container 430cdf0e10cSrcweir rBHelper.aLC.removeInterface( 431cdf0e10cSrcweir getVetoableTypeIdentifier( ), 432cdf0e10cSrcweir rxListener 433cdf0e10cSrcweir ); 434cdf0e10cSrcweir } 435cdf0e10cSrcweir } 436cdf0e10cSrcweir 437cdf0e10cSrcweir void OPropertySetHelper::setDependentFastPropertyValue( sal_Int32 i_handle, const ::com::sun::star::uno::Any& i_value ) 438cdf0e10cSrcweir { 439cdf0e10cSrcweir //OSL_PRECOND( rBHelper.rMutex.isAcquired(), "OPropertySetHelper::setDependentFastPropertyValue: to be called with a locked mutex only!" ); 440cdf0e10cSrcweir // there is no such thing as Mutex.isAcquired, sadly ... 441cdf0e10cSrcweir 442cdf0e10cSrcweir sal_Int16 nAttributes(0); 443cdf0e10cSrcweir IPropertyArrayHelper& rInfo = getInfoHelper(); 444cdf0e10cSrcweir if ( !rInfo.fillPropertyMembersByHandle( NULL, &nAttributes, i_handle ) ) 445cdf0e10cSrcweir // unknown property 446cdf0e10cSrcweir throw UnknownPropertyException(); 447cdf0e10cSrcweir 448cdf0e10cSrcweir // no need to check for READONLY-ness of the property. The method is intended to be called internally, which 449cdf0e10cSrcweir // implies it might be invoked for properties which are read-only to the instance's clients, but well allowed 450cdf0e10cSrcweir // to change their value. 451cdf0e10cSrcweir 452cdf0e10cSrcweir Any aConverted, aOld; 453cdf0e10cSrcweir sal_Bool bChanged = convertFastPropertyValue( aConverted, aOld, i_handle, i_value ); 454cdf0e10cSrcweir if ( !bChanged ) 455cdf0e10cSrcweir return; 456cdf0e10cSrcweir 457cdf0e10cSrcweir // don't fire vetoable events. This method is called with our mutex locked, so calling into listeners would not be 458cdf0e10cSrcweir // a good idea. The caler is responsible for not invoking this for constrained properties. 459cdf0e10cSrcweir OSL_ENSURE( ( nAttributes & PropertyAttribute::CONSTRAINED ) == 0, 460cdf0e10cSrcweir "OPropertySetHelper::setDependentFastPropertyValue: not to be used for constrained properties!" ); 461cdf0e10cSrcweir (void)nAttributes; 462cdf0e10cSrcweir 463cdf0e10cSrcweir // actually set the new value 464cdf0e10cSrcweir try 465cdf0e10cSrcweir { 466cdf0e10cSrcweir setFastPropertyValue_NoBroadcast( i_handle, aConverted ); 467cdf0e10cSrcweir } 468cdf0e10cSrcweir catch (const UnknownPropertyException& ) { throw; /* allowed to leave */ } 469cdf0e10cSrcweir catch (const PropertyVetoException& ) { throw; /* allowed to leave */ } 470cdf0e10cSrcweir catch (const IllegalArgumentException& ) { throw; /* allowed to leave */ } 471cdf0e10cSrcweir catch (const WrappedTargetException& ) { throw; /* allowed to leave */ } 472cdf0e10cSrcweir catch (const RuntimeException& ) { throw; /* allowed to leave */ } 473cdf0e10cSrcweir catch (const Exception& ) 474cdf0e10cSrcweir { 475cdf0e10cSrcweir // not allowed to leave this meathod 476cdf0e10cSrcweir WrappedTargetException aWrapped; 477cdf0e10cSrcweir aWrapped.TargetException <<= ::cppu::getCaughtException(); 478cdf0e10cSrcweir aWrapped.Context = static_cast< XPropertySet* >( this ); 479cdf0e10cSrcweir throw aWrapped; 480cdf0e10cSrcweir } 481cdf0e10cSrcweir 482cdf0e10cSrcweir // remember the handle/values, for the events to be fired later 483cdf0e10cSrcweir m_pReserved->m_handles.push_back( i_handle ); 484cdf0e10cSrcweir m_pReserved->m_newValues.push_back( aConverted ); // TODO: setFastPropertyValue notifies the unconverted value here ...? 485cdf0e10cSrcweir m_pReserved->m_oldValues.push_back( aOld ); 486cdf0e10cSrcweir } 487cdf0e10cSrcweir 488cdf0e10cSrcweir // XFastPropertySet 489cdf0e10cSrcweir void OPropertySetHelper::setFastPropertyValue( sal_Int32 nHandle, const Any& rValue ) 490cdf0e10cSrcweir throw(::com::sun::star::beans::UnknownPropertyException, 491cdf0e10cSrcweir ::com::sun::star::beans::PropertyVetoException, 492cdf0e10cSrcweir ::com::sun::star::lang::IllegalArgumentException, 493cdf0e10cSrcweir ::com::sun::star::lang::WrappedTargetException, 494cdf0e10cSrcweir ::com::sun::star::uno::RuntimeException) 495cdf0e10cSrcweir { 496cdf0e10cSrcweir OSL_ENSURE( !rBHelper.bInDispose, "do not setFastPropertyValue in the dispose call" ); 497cdf0e10cSrcweir OSL_ENSURE( !rBHelper.bDisposed, "object is disposed" ); 498cdf0e10cSrcweir 499cdf0e10cSrcweir IPropertyArrayHelper & rInfo = getInfoHelper(); 500cdf0e10cSrcweir sal_Int16 nAttributes; 501cdf0e10cSrcweir if( !rInfo.fillPropertyMembersByHandle( NULL, &nAttributes, nHandle ) ) { 502cdf0e10cSrcweir // unknown property 503cdf0e10cSrcweir throw UnknownPropertyException(); 504cdf0e10cSrcweir } 505cdf0e10cSrcweir if( nAttributes & PropertyAttribute::READONLY ) 506cdf0e10cSrcweir throw PropertyVetoException(); 507cdf0e10cSrcweir 508cdf0e10cSrcweir Any aConvertedVal; 509cdf0e10cSrcweir Any aOldVal; 510cdf0e10cSrcweir 511cdf0e10cSrcweir // Will the property change? 512cdf0e10cSrcweir sal_Bool bChanged; 513cdf0e10cSrcweir { 514cdf0e10cSrcweir MutexGuard aGuard( rBHelper.rMutex ); 515cdf0e10cSrcweir bChanged = convertFastPropertyValue( aConvertedVal, aOldVal, nHandle, rValue ); 516cdf0e10cSrcweir // release guard to fire events 517cdf0e10cSrcweir } 518cdf0e10cSrcweir if( bChanged ) 519cdf0e10cSrcweir { 520cdf0e10cSrcweir // Is it a constrained property? 521cdf0e10cSrcweir if( nAttributes & PropertyAttribute::CONSTRAINED ) 522cdf0e10cSrcweir { 523cdf0e10cSrcweir // In aValue is the converted rValue 524cdf0e10cSrcweir // fire a constarined event 525cdf0e10cSrcweir // second parameter NULL means constrained 526cdf0e10cSrcweir fire( &nHandle, &rValue, &aOldVal, 1, sal_True ); 527cdf0e10cSrcweir } 528cdf0e10cSrcweir 529cdf0e10cSrcweir { 530cdf0e10cSrcweir MutexGuard aGuard( rBHelper.rMutex ); 531cdf0e10cSrcweir try 532cdf0e10cSrcweir { 533cdf0e10cSrcweir // set the property to the new value 534cdf0e10cSrcweir setFastPropertyValue_NoBroadcast( nHandle, aConvertedVal ); 535cdf0e10cSrcweir } 536cdf0e10cSrcweir catch (const ::com::sun::star::beans::UnknownPropertyException& ) { throw; /* allowed to leave */ } 537cdf0e10cSrcweir catch (const ::com::sun::star::beans::PropertyVetoException& ) { throw; /* allowed to leave */ } 538cdf0e10cSrcweir catch (const ::com::sun::star::lang::IllegalArgumentException& ) { throw; /* allowed to leave */ } 539cdf0e10cSrcweir catch (const ::com::sun::star::lang::WrappedTargetException& ) { throw; /* allowed to leave */ } 540cdf0e10cSrcweir catch (const ::com::sun::star::uno::RuntimeException& ) { throw; /* allowed to leave */ } 541cdf0e10cSrcweir catch (const ::com::sun::star::uno::Exception& e ) 542cdf0e10cSrcweir { 543cdf0e10cSrcweir // not allowed to leave this meathod 544cdf0e10cSrcweir ::com::sun::star::lang::WrappedTargetException aWrap; 545cdf0e10cSrcweir aWrap.Context = static_cast< ::com::sun::star::beans::XPropertySet* >( this ); 546cdf0e10cSrcweir aWrap.TargetException <<= e; 547cdf0e10cSrcweir 548cdf0e10cSrcweir throw ::com::sun::star::lang::WrappedTargetException( aWrap ); 549cdf0e10cSrcweir } 550cdf0e10cSrcweir 551cdf0e10cSrcweir // release guard to fire events 552cdf0e10cSrcweir } 553cdf0e10cSrcweir // file a change event, if the value changed 554cdf0e10cSrcweir impl_fireAll( &nHandle, &rValue, &aOldVal, 1 ); 555cdf0e10cSrcweir } 556cdf0e10cSrcweir } 557cdf0e10cSrcweir 558cdf0e10cSrcweir // XFastPropertySet 559cdf0e10cSrcweir Any OPropertySetHelper::getFastPropertyValue( sal_Int32 nHandle ) 560cdf0e10cSrcweir throw(::com::sun::star::beans::UnknownPropertyException, 561cdf0e10cSrcweir ::com::sun::star::lang::WrappedTargetException, 562cdf0e10cSrcweir ::com::sun::star::uno::RuntimeException) 563cdf0e10cSrcweir 564cdf0e10cSrcweir { 565cdf0e10cSrcweir IPropertyArrayHelper & rInfo = getInfoHelper(); 566cdf0e10cSrcweir if( !rInfo.fillPropertyMembersByHandle( NULL, NULL, nHandle ) ) 567cdf0e10cSrcweir // unknown property 568cdf0e10cSrcweir throw UnknownPropertyException(); 569cdf0e10cSrcweir 570cdf0e10cSrcweir Any aRet; 571cdf0e10cSrcweir MutexGuard aGuard( rBHelper.rMutex ); 572cdf0e10cSrcweir getFastPropertyValue( aRet, nHandle ); 573cdf0e10cSrcweir return aRet; 574cdf0e10cSrcweir } 575cdf0e10cSrcweir 576cdf0e10cSrcweir //-------------------------------------------------------------------------- 577cdf0e10cSrcweir void OPropertySetHelper::impl_fireAll( sal_Int32* i_handles, const Any* i_newValues, const Any* i_oldValues, sal_Int32 i_count ) 578cdf0e10cSrcweir { 579cdf0e10cSrcweir ClearableMutexGuard aGuard( rBHelper.rMutex ); 580cdf0e10cSrcweir if ( m_pReserved->m_handles.empty() ) 581cdf0e10cSrcweir { 582cdf0e10cSrcweir aGuard.clear(); 583cdf0e10cSrcweir fire( i_handles, i_newValues, i_oldValues, i_count, sal_False ); 584cdf0e10cSrcweir return; 585cdf0e10cSrcweir } 586cdf0e10cSrcweir 587cdf0e10cSrcweir const size_t additionalEvents = m_pReserved->m_handles.size(); 588cdf0e10cSrcweir OSL_ENSURE( additionalEvents == m_pReserved->m_newValues.size() 589cdf0e10cSrcweir && additionalEvents == m_pReserved->m_oldValues.size(), 590cdf0e10cSrcweir "OPropertySetHelper::impl_fireAll: inconsistency!" ); 591cdf0e10cSrcweir 592cdf0e10cSrcweir ::std::vector< sal_Int32 > allHandles( additionalEvents + i_count ); 593cdf0e10cSrcweir ::std::copy( m_pReserved->m_handles.begin(), m_pReserved->m_handles.end(), allHandles.begin() ); 594cdf0e10cSrcweir ::std::copy( i_handles, i_handles + i_count, allHandles.begin() + additionalEvents ); 595cdf0e10cSrcweir 596cdf0e10cSrcweir ::std::vector< Any > allNewValues( additionalEvents + i_count ); 597cdf0e10cSrcweir ::std::copy( m_pReserved->m_newValues.begin(), m_pReserved->m_newValues.end(), allNewValues.begin() ); 598cdf0e10cSrcweir ::std::copy( i_newValues, i_newValues + i_count, allNewValues.begin() + additionalEvents ); 599cdf0e10cSrcweir 600cdf0e10cSrcweir ::std::vector< Any > allOldValues( additionalEvents + i_count ); 601cdf0e10cSrcweir ::std::copy( m_pReserved->m_oldValues.begin(), m_pReserved->m_oldValues.end(), allOldValues.begin() ); 602cdf0e10cSrcweir ::std::copy( i_oldValues, i_oldValues + i_count, allOldValues.begin() + additionalEvents ); 603cdf0e10cSrcweir 604cdf0e10cSrcweir m_pReserved->m_handles.clear(); 605cdf0e10cSrcweir m_pReserved->m_newValues.clear(); 606cdf0e10cSrcweir m_pReserved->m_oldValues.clear(); 607cdf0e10cSrcweir 608cdf0e10cSrcweir aGuard.clear(); 609cdf0e10cSrcweir fire( &allHandles[0], &allNewValues[0], &allOldValues[0], additionalEvents + i_count, sal_False ); 610cdf0e10cSrcweir } 611cdf0e10cSrcweir 612cdf0e10cSrcweir //-------------------------------------------------------------------------- 613cdf0e10cSrcweir void OPropertySetHelper::fire 614cdf0e10cSrcweir ( 615cdf0e10cSrcweir sal_Int32 * pnHandles, 616cdf0e10cSrcweir const Any * pNewValues, 617cdf0e10cSrcweir const Any * pOldValues, 618cdf0e10cSrcweir sal_Int32 nHandles, // These is the Count of the array 619cdf0e10cSrcweir sal_Bool bVetoable 620cdf0e10cSrcweir ) 621cdf0e10cSrcweir { 622cdf0e10cSrcweir OSL_ENSURE( m_pReserved.get(), "No OPropertySetHelper::Impl" ); 623cdf0e10cSrcweir if (m_pReserved->m_pFireEvents) { 624cdf0e10cSrcweir m_pReserved->m_pFireEvents->fireEvents( 625cdf0e10cSrcweir pnHandles, nHandles, bVetoable, 626cdf0e10cSrcweir m_pReserved->m_bIgnoreRuntimeExceptionsWhileFiring); 627cdf0e10cSrcweir } 628cdf0e10cSrcweir 629cdf0e10cSrcweir // Only fire, if one or more properties changed 630cdf0e10cSrcweir if( nHandles ) 631cdf0e10cSrcweir { 632cdf0e10cSrcweir // create the event sequence of all changed properties 633cdf0e10cSrcweir Sequence< PropertyChangeEvent > aEvts( nHandles ); 634cdf0e10cSrcweir PropertyChangeEvent * pEvts = aEvts.getArray(); 635cdf0e10cSrcweir Reference < XInterface > xSource( (XPropertySet *)this, UNO_QUERY ); 636cdf0e10cSrcweir sal_Int32 i; 637cdf0e10cSrcweir sal_Int32 nChangesLen = 0; 638cdf0e10cSrcweir // Loop over all changed properties to fill the event struct 639cdf0e10cSrcweir for( i = 0; i < nHandles; i++ ) 640cdf0e10cSrcweir { 641cdf0e10cSrcweir // Vetoable fire and constrained attribute set or 642cdf0e10cSrcweir // Change fire and Changed and bound attribute set 643cdf0e10cSrcweir IPropertyArrayHelper & rInfo = getInfoHelper(); 644cdf0e10cSrcweir sal_Int16 nAttributes; 645cdf0e10cSrcweir OUString aPropName; 646cdf0e10cSrcweir rInfo.fillPropertyMembersByHandle( &aPropName, &nAttributes, pnHandles[i] ); 647cdf0e10cSrcweir 648cdf0e10cSrcweir if( 649cdf0e10cSrcweir (bVetoable && (nAttributes & PropertyAttribute::CONSTRAINED)) || 650cdf0e10cSrcweir (!bVetoable && (nAttributes & PropertyAttribute::BOUND)) 651cdf0e10cSrcweir ) 652cdf0e10cSrcweir { 653cdf0e10cSrcweir pEvts[nChangesLen].Source = xSource; 654cdf0e10cSrcweir pEvts[nChangesLen].PropertyName = aPropName; 655cdf0e10cSrcweir pEvts[nChangesLen].PropertyHandle = pnHandles[i]; 656cdf0e10cSrcweir pEvts[nChangesLen].OldValue = pOldValues[i]; 657cdf0e10cSrcweir pEvts[nChangesLen].NewValue = pNewValues[i]; 658cdf0e10cSrcweir nChangesLen++; 659cdf0e10cSrcweir } 660cdf0e10cSrcweir } 661cdf0e10cSrcweir 662cdf0e10cSrcweir bool bIgnoreRuntimeExceptionsWhileFiring = 663cdf0e10cSrcweir m_pReserved->m_bIgnoreRuntimeExceptionsWhileFiring; 664cdf0e10cSrcweir 665cdf0e10cSrcweir // fire the events for all changed properties 666cdf0e10cSrcweir for( i = 0; i < nChangesLen; i++ ) 667cdf0e10cSrcweir { 668cdf0e10cSrcweir // get the listener container for the property name 669cdf0e10cSrcweir OInterfaceContainerHelper * pLC; 670cdf0e10cSrcweir if( bVetoable ) // fire change Events? 671cdf0e10cSrcweir pLC = aVetoableLC.getContainer( pEvts[i].PropertyHandle ); 672cdf0e10cSrcweir else 673cdf0e10cSrcweir pLC = aBoundLC.getContainer( pEvts[i].PropertyHandle ); 674cdf0e10cSrcweir if( pLC ) 675cdf0e10cSrcweir { 676cdf0e10cSrcweir // Ueber alle Listener iterieren und Events senden 677cdf0e10cSrcweir OInterfaceIteratorHelper aIt( *pLC); 678cdf0e10cSrcweir while( aIt.hasMoreElements() ) 679cdf0e10cSrcweir { 680cdf0e10cSrcweir XInterface * pL = aIt.next(); 681cdf0e10cSrcweir try 682cdf0e10cSrcweir { 683cdf0e10cSrcweir try 684cdf0e10cSrcweir { 685cdf0e10cSrcweir if( bVetoable ) // fire change Events? 686cdf0e10cSrcweir { 687cdf0e10cSrcweir ((XVetoableChangeListener *)pL)->vetoableChange( 688cdf0e10cSrcweir pEvts[i] ); 689cdf0e10cSrcweir } 690cdf0e10cSrcweir else 691cdf0e10cSrcweir { 692cdf0e10cSrcweir ((XPropertyChangeListener *)pL)->propertyChange( 693cdf0e10cSrcweir pEvts[i] ); 694cdf0e10cSrcweir } 695cdf0e10cSrcweir } 696cdf0e10cSrcweir catch (DisposedException & exc) 697cdf0e10cSrcweir { 698cdf0e10cSrcweir OSL_ENSURE( exc.Context.is(), 699cdf0e10cSrcweir "DisposedException without Context!" ); 700cdf0e10cSrcweir if (exc.Context == pL) 701cdf0e10cSrcweir aIt.remove(); 702cdf0e10cSrcweir else 703cdf0e10cSrcweir throw; 704cdf0e10cSrcweir } 705cdf0e10cSrcweir } 706cdf0e10cSrcweir catch (RuntimeException & exc) 707cdf0e10cSrcweir { 708cdf0e10cSrcweir OSL_TRACE( 709cdf0e10cSrcweir OUStringToOString( 710cdf0e10cSrcweir OUString( RTL_CONSTASCII_USTRINGPARAM( 711cdf0e10cSrcweir "caught RuntimeException while " 712cdf0e10cSrcweir "firing listeners: ") ) + 713cdf0e10cSrcweir exc.Message, RTL_TEXTENCODING_UTF8 ).getStr() ); 714cdf0e10cSrcweir if (! bIgnoreRuntimeExceptionsWhileFiring) 715cdf0e10cSrcweir throw; 716cdf0e10cSrcweir } 717cdf0e10cSrcweir } 718cdf0e10cSrcweir } 719cdf0e10cSrcweir // broadcast to all listeners with "" property name 720cdf0e10cSrcweir if( bVetoable ){ 721cdf0e10cSrcweir // fire change Events? 722cdf0e10cSrcweir pLC = rBHelper.aLC.getContainer( 723cdf0e10cSrcweir getVetoableTypeIdentifier() 724cdf0e10cSrcweir ); 725cdf0e10cSrcweir } 726cdf0e10cSrcweir else { 727cdf0e10cSrcweir pLC = rBHelper.aLC.getContainer( 728cdf0e10cSrcweir getPropertyTypeIdentifier( ) 729cdf0e10cSrcweir ); 730cdf0e10cSrcweir } 731cdf0e10cSrcweir if( pLC ) 732cdf0e10cSrcweir { 733cdf0e10cSrcweir // Ueber alle Listener iterieren und Events senden 734cdf0e10cSrcweir OInterfaceIteratorHelper aIt( *pLC); 735cdf0e10cSrcweir while( aIt.hasMoreElements() ) 736cdf0e10cSrcweir { 737cdf0e10cSrcweir XInterface * pL = aIt.next(); 738cdf0e10cSrcweir try 739cdf0e10cSrcweir { 740cdf0e10cSrcweir try 741cdf0e10cSrcweir { 742cdf0e10cSrcweir if( bVetoable ) // fire change Events? 743cdf0e10cSrcweir { 744cdf0e10cSrcweir ((XVetoableChangeListener *)pL)->vetoableChange( 745cdf0e10cSrcweir pEvts[i] ); 746cdf0e10cSrcweir } 747cdf0e10cSrcweir else 748cdf0e10cSrcweir { 749cdf0e10cSrcweir ((XPropertyChangeListener *)pL)->propertyChange( 750cdf0e10cSrcweir pEvts[i] ); 751cdf0e10cSrcweir } 752cdf0e10cSrcweir } 753cdf0e10cSrcweir catch (DisposedException & exc) 754cdf0e10cSrcweir { 755cdf0e10cSrcweir OSL_ENSURE( exc.Context.is(), 756cdf0e10cSrcweir "DisposedException without Context!" ); 757cdf0e10cSrcweir if (exc.Context == pL) 758cdf0e10cSrcweir aIt.remove(); 759cdf0e10cSrcweir else 760cdf0e10cSrcweir throw; 761cdf0e10cSrcweir } 762cdf0e10cSrcweir } 763cdf0e10cSrcweir catch (RuntimeException & exc) 764cdf0e10cSrcweir { 765cdf0e10cSrcweir OSL_TRACE( 766cdf0e10cSrcweir OUStringToOString( 767cdf0e10cSrcweir OUString( RTL_CONSTASCII_USTRINGPARAM( 768cdf0e10cSrcweir "caught RuntimeException while " 769cdf0e10cSrcweir "firing listeners: ") ) + 770cdf0e10cSrcweir exc.Message, RTL_TEXTENCODING_UTF8 ).getStr() ); 771cdf0e10cSrcweir if (! bIgnoreRuntimeExceptionsWhileFiring) 772cdf0e10cSrcweir throw; 773cdf0e10cSrcweir } 774cdf0e10cSrcweir } 775cdf0e10cSrcweir } 776cdf0e10cSrcweir } 777cdf0e10cSrcweir 778cdf0e10cSrcweir // reduce array to changed properties 779cdf0e10cSrcweir aEvts.realloc( nChangesLen ); 780cdf0e10cSrcweir 781cdf0e10cSrcweir if( !bVetoable ) 782cdf0e10cSrcweir { 783cdf0e10cSrcweir OInterfaceContainerHelper * pCont = 0; 784cdf0e10cSrcweir pCont = rBHelper.aLC.getContainer( 785cdf0e10cSrcweir getPropertiesTypeIdentifier( ) 786cdf0e10cSrcweir ); 787cdf0e10cSrcweir if( pCont ) 788cdf0e10cSrcweir { 789cdf0e10cSrcweir // Here is a Bug, unbound properties are also fired 790cdf0e10cSrcweir OInterfaceIteratorHelper aIt( *pCont ); 791cdf0e10cSrcweir while( aIt.hasMoreElements() ) 792cdf0e10cSrcweir { 793cdf0e10cSrcweir XPropertiesChangeListener * pL = 794cdf0e10cSrcweir (XPropertiesChangeListener *)aIt.next(); 795cdf0e10cSrcweir try 796cdf0e10cSrcweir { 797cdf0e10cSrcweir try 798cdf0e10cSrcweir { 799cdf0e10cSrcweir // fire the hole event sequence to the 800cdf0e10cSrcweir // XPropertiesChangeListener's 801cdf0e10cSrcweir pL->propertiesChange( aEvts ); 802cdf0e10cSrcweir } 803cdf0e10cSrcweir catch (DisposedException & exc) 804cdf0e10cSrcweir { 805cdf0e10cSrcweir OSL_ENSURE( exc.Context.is(), 806cdf0e10cSrcweir "DisposedException without Context!" ); 807cdf0e10cSrcweir if (exc.Context == pL) 808cdf0e10cSrcweir aIt.remove(); 809cdf0e10cSrcweir else 810cdf0e10cSrcweir throw; 811cdf0e10cSrcweir } 812cdf0e10cSrcweir } 813cdf0e10cSrcweir catch (RuntimeException & exc) 814cdf0e10cSrcweir { 815cdf0e10cSrcweir OSL_TRACE( 816cdf0e10cSrcweir OUStringToOString( 817cdf0e10cSrcweir OUString( RTL_CONSTASCII_USTRINGPARAM( 818cdf0e10cSrcweir "caught RuntimeException while " 819cdf0e10cSrcweir "firing listeners: ") ) + 820cdf0e10cSrcweir exc.Message, RTL_TEXTENCODING_UTF8 ).getStr() ); 821cdf0e10cSrcweir if (! bIgnoreRuntimeExceptionsWhileFiring) 822cdf0e10cSrcweir throw; 823cdf0e10cSrcweir } 824cdf0e10cSrcweir } 825cdf0e10cSrcweir } 826cdf0e10cSrcweir } 827cdf0e10cSrcweir } 828cdf0e10cSrcweir } 829cdf0e10cSrcweir 830cdf0e10cSrcweir // OPropertySetHelper 831cdf0e10cSrcweir void OPropertySetHelper::setFastPropertyValues( 832cdf0e10cSrcweir sal_Int32 nSeqLen, 833cdf0e10cSrcweir sal_Int32 * pHandles, 834cdf0e10cSrcweir const Any * pValues, 835cdf0e10cSrcweir sal_Int32 nHitCount ) 836cdf0e10cSrcweir SAL_THROW( (::com::sun::star::uno::Exception) ) 837cdf0e10cSrcweir { 838cdf0e10cSrcweir OSL_ENSURE( !rBHelper.bInDispose, "do not getFastPropertyValue in the dispose call" ); 839cdf0e10cSrcweir OSL_ENSURE( !rBHelper.bDisposed, "object is disposed" ); 840cdf0e10cSrcweir 841cdf0e10cSrcweir Any * pConvertedValues = NULL; 842cdf0e10cSrcweir Any * pOldValues = NULL; 843cdf0e10cSrcweir 844cdf0e10cSrcweir try 845cdf0e10cSrcweir { 846cdf0e10cSrcweir // get the map table 847cdf0e10cSrcweir IPropertyArrayHelper & rPH = getInfoHelper(); 848cdf0e10cSrcweir 849cdf0e10cSrcweir pConvertedValues = new Any[ nHitCount ]; 850cdf0e10cSrcweir pOldValues = new Any[ nHitCount ]; 851cdf0e10cSrcweir sal_Int32 n = 0; 852cdf0e10cSrcweir sal_Int32 i; 853cdf0e10cSrcweir 854cdf0e10cSrcweir { 855cdf0e10cSrcweir // must lock the mutex outside the loop. So all values are consistent. 856cdf0e10cSrcweir MutexGuard aGuard( rBHelper.rMutex ); 857cdf0e10cSrcweir for( i = 0; i < nSeqLen; i++ ) 858cdf0e10cSrcweir { 859cdf0e10cSrcweir if( pHandles[i] != -1 ) 860cdf0e10cSrcweir { 861cdf0e10cSrcweir sal_Int16 nAttributes; 862cdf0e10cSrcweir rPH.fillPropertyMembersByHandle( NULL, &nAttributes, pHandles[i] ); 863cdf0e10cSrcweir if( nAttributes & PropertyAttribute::READONLY ) { 864cdf0e10cSrcweir throw PropertyVetoException(); 865cdf0e10cSrcweir } 866cdf0e10cSrcweir // Will the property change? 867cdf0e10cSrcweir if( convertFastPropertyValue( pConvertedValues[ n ], pOldValues[n], 868cdf0e10cSrcweir pHandles[i], pValues[i] ) ) 869cdf0e10cSrcweir { 870cdf0e10cSrcweir // only increment if the property really change 871cdf0e10cSrcweir pHandles[n] = pHandles[i]; 872cdf0e10cSrcweir n++; 873cdf0e10cSrcweir } 874cdf0e10cSrcweir } 875cdf0e10cSrcweir } 876cdf0e10cSrcweir // release guard to fire events 877cdf0e10cSrcweir } 878cdf0e10cSrcweir 879cdf0e10cSrcweir // fire vetoable events 880cdf0e10cSrcweir fire( pHandles, pConvertedValues, pOldValues, n, sal_True ); 881cdf0e10cSrcweir 882cdf0e10cSrcweir { 883cdf0e10cSrcweir // must lock the mutex outside the loop. 884cdf0e10cSrcweir MutexGuard aGuard( rBHelper.rMutex ); 885cdf0e10cSrcweir // Loop over all changed properties 886cdf0e10cSrcweir for( i = 0; i < n; i++ ) 887cdf0e10cSrcweir { 888cdf0e10cSrcweir // Will the property change? 889cdf0e10cSrcweir setFastPropertyValue_NoBroadcast( pHandles[i], pConvertedValues[i] ); 890cdf0e10cSrcweir } 891cdf0e10cSrcweir // release guard to fire events 892cdf0e10cSrcweir } 893cdf0e10cSrcweir 894cdf0e10cSrcweir // fire change events 895cdf0e10cSrcweir impl_fireAll( pHandles, pConvertedValues, pOldValues, n ); 896cdf0e10cSrcweir } 897cdf0e10cSrcweir catch( ... ) 898cdf0e10cSrcweir { 899cdf0e10cSrcweir delete [] pOldValues; 900cdf0e10cSrcweir delete [] pConvertedValues; 901cdf0e10cSrcweir throw; 902cdf0e10cSrcweir } 903cdf0e10cSrcweir delete [] pOldValues; 904cdf0e10cSrcweir delete [] pConvertedValues; 905cdf0e10cSrcweir } 906cdf0e10cSrcweir 907cdf0e10cSrcweir // XMultiPropertySet 908cdf0e10cSrcweir /** 909cdf0e10cSrcweir * The sequence may be conatain not known properties. The implementation 910cdf0e10cSrcweir * must ignore these properties. 911cdf0e10cSrcweir */ 912cdf0e10cSrcweir void OPropertySetHelper::setPropertyValues( 913cdf0e10cSrcweir const Sequence<OUString>& rPropertyNames, 914cdf0e10cSrcweir const Sequence<Any>& rValues ) 915cdf0e10cSrcweir throw(::com::sun::star::beans::PropertyVetoException, ::com::sun::star::lang::IllegalArgumentException, ::com::sun::star::lang::WrappedTargetException, ::com::sun::star::uno::RuntimeException) 916cdf0e10cSrcweir { 917cdf0e10cSrcweir sal_Int32 * pHandles = NULL; 918cdf0e10cSrcweir try 919cdf0e10cSrcweir { 920cdf0e10cSrcweir sal_Int32 nSeqLen = rPropertyNames.getLength(); 921cdf0e10cSrcweir pHandles = new sal_Int32[ nSeqLen ]; 922cdf0e10cSrcweir // get the map table 923cdf0e10cSrcweir IPropertyArrayHelper & rPH = getInfoHelper(); 924cdf0e10cSrcweir // fill the handle array 925cdf0e10cSrcweir sal_Int32 nHitCount = rPH.fillHandles( pHandles, rPropertyNames ); 926cdf0e10cSrcweir if( nHitCount != 0 ) 927cdf0e10cSrcweir setFastPropertyValues( nSeqLen, pHandles, rValues.getConstArray(), nHitCount ); 928cdf0e10cSrcweir } 929cdf0e10cSrcweir catch( ... ) 930cdf0e10cSrcweir { 931cdf0e10cSrcweir delete [] pHandles; 932cdf0e10cSrcweir throw; 933cdf0e10cSrcweir } 934cdf0e10cSrcweir delete [] pHandles; 935cdf0e10cSrcweir } 936cdf0e10cSrcweir 937cdf0e10cSrcweir // XMultiPropertySet 938cdf0e10cSrcweir Sequence<Any> OPropertySetHelper::getPropertyValues( const Sequence<OUString>& rPropertyNames ) 939cdf0e10cSrcweir throw(::com::sun::star::uno::RuntimeException) 940cdf0e10cSrcweir { 941cdf0e10cSrcweir sal_Int32 nSeqLen = rPropertyNames.getLength(); 942cdf0e10cSrcweir sal_Int32 * pHandles = new sal_Int32[ nSeqLen ]; 943cdf0e10cSrcweir Sequence< Any > aValues( nSeqLen ); 944cdf0e10cSrcweir 945cdf0e10cSrcweir // get the map table 946cdf0e10cSrcweir IPropertyArrayHelper & rPH = getInfoHelper(); 947cdf0e10cSrcweir // fill the handle array 948cdf0e10cSrcweir rPH.fillHandles( pHandles, rPropertyNames ); 949cdf0e10cSrcweir 950cdf0e10cSrcweir Any * pValues = aValues.getArray(); 951cdf0e10cSrcweir 952cdf0e10cSrcweir MutexGuard aGuard( rBHelper.rMutex ); 953cdf0e10cSrcweir // fill the sequence with the values 954cdf0e10cSrcweir for( sal_Int32 i = 0; i < nSeqLen; i++ ) 955cdf0e10cSrcweir getFastPropertyValue( pValues[i], pHandles[i] ); 956cdf0e10cSrcweir 957cdf0e10cSrcweir delete [] pHandles; 958cdf0e10cSrcweir return aValues; 959cdf0e10cSrcweir } 960cdf0e10cSrcweir 961cdf0e10cSrcweir // XMultiPropertySet 962cdf0e10cSrcweir void OPropertySetHelper::addPropertiesChangeListener( 963cdf0e10cSrcweir const Sequence<OUString> & , 964cdf0e10cSrcweir const Reference < XPropertiesChangeListener > & rListener ) 965cdf0e10cSrcweir throw(::com::sun::star::uno::RuntimeException) 966cdf0e10cSrcweir { 967cdf0e10cSrcweir rBHelper.addListener( getCppuType(&rListener) , rListener ); 968cdf0e10cSrcweir } 969cdf0e10cSrcweir 970cdf0e10cSrcweir // XMultiPropertySet 971cdf0e10cSrcweir void OPropertySetHelper::removePropertiesChangeListener( 972cdf0e10cSrcweir const Reference < XPropertiesChangeListener > & rListener ) 973cdf0e10cSrcweir throw(::com::sun::star::uno::RuntimeException) 974cdf0e10cSrcweir { 975cdf0e10cSrcweir rBHelper.removeListener( getCppuType(&rListener) , rListener ); 976cdf0e10cSrcweir } 977cdf0e10cSrcweir 978cdf0e10cSrcweir // XMultiPropertySet 979cdf0e10cSrcweir void OPropertySetHelper::firePropertiesChangeEvent( 980cdf0e10cSrcweir const Sequence<OUString>& rPropertyNames, 981cdf0e10cSrcweir const Reference < XPropertiesChangeListener >& rListener ) 982cdf0e10cSrcweir throw(::com::sun::star::uno::RuntimeException) 983cdf0e10cSrcweir { 984cdf0e10cSrcweir sal_Int32 nLen = rPropertyNames.getLength(); 985cdf0e10cSrcweir sal_Int32 * pHandles = new sal_Int32[nLen]; 986cdf0e10cSrcweir IPropertyArrayHelper & rPH = getInfoHelper(); 987cdf0e10cSrcweir rPH.fillHandles( pHandles, rPropertyNames ); 988cdf0e10cSrcweir const OUString* pNames = rPropertyNames.getConstArray(); 989cdf0e10cSrcweir 990cdf0e10cSrcweir // get the count of matching properties 991cdf0e10cSrcweir sal_Int32 nFireLen = 0; 992cdf0e10cSrcweir sal_Int32 i; 993cdf0e10cSrcweir for( i = 0; i < nLen; i++ ) 994cdf0e10cSrcweir if( pHandles[i] != -1 ) 995cdf0e10cSrcweir nFireLen++; 996cdf0e10cSrcweir 997cdf0e10cSrcweir Sequence<PropertyChangeEvent> aChanges( nFireLen ); 998cdf0e10cSrcweir PropertyChangeEvent* pChanges = aChanges.getArray(); 999cdf0e10cSrcweir 1000cdf0e10cSrcweir sal_Int32 nFirePos = 0; 1001cdf0e10cSrcweir { 1002cdf0e10cSrcweir // must lock the mutex outside the loop. So all values are consistent. 1003cdf0e10cSrcweir MutexGuard aGuard( rBHelper.rMutex ); 1004cdf0e10cSrcweir Reference < XInterface > xSource( (XPropertySet *)this, UNO_QUERY ); 1005cdf0e10cSrcweir for( i = 0; i < nLen; i++ ) 1006cdf0e10cSrcweir { 1007cdf0e10cSrcweir if( pHandles[i] != -1 ) 1008cdf0e10cSrcweir { 1009cdf0e10cSrcweir pChanges[nFirePos].Source = xSource; 1010cdf0e10cSrcweir pChanges[nFirePos].PropertyName = pNames[i]; 1011cdf0e10cSrcweir pChanges[nFirePos].PropertyHandle = pHandles[i]; 1012cdf0e10cSrcweir getFastPropertyValue( pChanges[nFirePos].OldValue, pHandles[i] ); 1013cdf0e10cSrcweir pChanges[nFirePos].NewValue = pChanges[nFirePos].OldValue; 1014cdf0e10cSrcweir nFirePos++; 1015cdf0e10cSrcweir } 1016cdf0e10cSrcweir } 1017cdf0e10cSrcweir // release guard to fire events 1018cdf0e10cSrcweir } 1019cdf0e10cSrcweir if( nFireLen ) 1020cdf0e10cSrcweir rListener->propertiesChange( aChanges ); 1021cdf0e10cSrcweir 1022cdf0e10cSrcweir delete [] pHandles; 1023cdf0e10cSrcweir } 1024cdf0e10cSrcweir 1025cdf0e10cSrcweir #ifdef xdvnsdfln 1026cdf0e10cSrcweir // XPropertyState 1027cdf0e10cSrcweir PropertyState OPropertySetHelper::getPropertyState( const OUString& PropertyName ) 1028cdf0e10cSrcweir { 1029cdf0e10cSrcweir PropertyState aState; 1030cdf0e10cSrcweir return aState; 1031cdf0e10cSrcweir } 1032cdf0e10cSrcweir 1033cdf0e10cSrcweir // XPropertyState 1034cdf0e10cSrcweir Sequence< PropertyState > OPropertySetHelper::getPropertyStates( const Sequence< OUString >& PropertyNames ) 1035cdf0e10cSrcweir { 1036cdf0e10cSrcweir ULONG nNames = PropertyNames.getLength(); 1037cdf0e10cSrcweir const OUString* pNames = PropertyNames.getConstArray(); 1038cdf0e10cSrcweir 1039cdf0e10cSrcweir Sequence< PropertyState > aStates( nNames ); 1040cdf0e10cSrcweir return aStates; 1041cdf0e10cSrcweir 1042cdf0e10cSrcweir } 1043cdf0e10cSrcweir 1044cdf0e10cSrcweir void OPropertySetHelper::setPropertyToDefault( const OUString& aPropertyName ) 1045cdf0e10cSrcweir { 1046cdf0e10cSrcweir setPropertyValue( aPropertyName, Any() ); 1047cdf0e10cSrcweir } 1048cdf0e10cSrcweir 1049cdf0e10cSrcweir Any OPropertySetHelper::getPropertyDefault( const OUString& aPropertyName ) const 1050cdf0e10cSrcweir { 1051cdf0e10cSrcweir return Any(); 1052cdf0e10cSrcweir } 1053cdf0e10cSrcweir 1054cdf0e10cSrcweir void OPropertySetHelper::addPropertyStateChangeListener( const OUString& aPropertyName, const XPropertyStateChangeListenerRef& Listener ) 1055cdf0e10cSrcweir { 1056cdf0e10cSrcweir } 1057cdf0e10cSrcweir 1058cdf0e10cSrcweir void OPropertySetHelper::removePropertyStateChangeListener( const OUString& aPropertyName, const XPropertyStateChangeListenerRef& Listener ) 1059cdf0e10cSrcweir { 1060cdf0e10cSrcweir } 1061cdf0e10cSrcweir #endif 1062cdf0e10cSrcweir 1063cdf0e10cSrcweir //======================================================================== 1064cdf0e10cSrcweir //== OPropertyArrayHelper ================================================ 1065cdf0e10cSrcweir //======================================================================== 1066cdf0e10cSrcweir 1067cdf0e10cSrcweir //======================================================================== 1068cdf0e10cSrcweir 1069cdf0e10cSrcweir // static OUString makeOUString( sal_Char *p ) 1070cdf0e10cSrcweir // { 1071cdf0e10cSrcweir // sal_Int32 nLen = strlen(p); 1072cdf0e10cSrcweir // sal_Unicode *pw = new sal_Unicode[nLen]; 1073cdf0e10cSrcweir 1074cdf0e10cSrcweir // for( int i = 0 ; i < nLen ; i ++ ) { 1075cdf0e10cSrcweir 1076cdf0e10cSrcweir // // Only ascii strings allowed with this helper ! 1077cdf0e10cSrcweir // OSL_ASSERT( p[i] < 127 ); 1078cdf0e10cSrcweir // pw[i] = p[i]; 1079cdf0e10cSrcweir // } 1080cdf0e10cSrcweir // OUString ow( pw , nLen ); 1081cdf0e10cSrcweir // delete pw; 1082cdf0e10cSrcweir // return ow; 1083cdf0e10cSrcweir // } 1084cdf0e10cSrcweir 1085cdf0e10cSrcweir extern "C" { 1086cdf0e10cSrcweir 1087cdf0e10cSrcweir static int compare_Property_Impl( const void *arg1, const void *arg2 ) 1088cdf0e10cSrcweir SAL_THROW_EXTERN_C() 1089cdf0e10cSrcweir { 1090cdf0e10cSrcweir return ((Property *)arg1)->Name.compareTo( ((Property *)arg2)->Name ); 1091cdf0e10cSrcweir } 1092cdf0e10cSrcweir 1093cdf0e10cSrcweir } 1094cdf0e10cSrcweir 1095cdf0e10cSrcweir void OPropertyArrayHelper::init( sal_Bool bSorted ) SAL_THROW( () ) 1096cdf0e10cSrcweir { 1097cdf0e10cSrcweir sal_Int32 i, nElements = aInfos.getLength(); 1098cdf0e10cSrcweir const Property* pProperties = aInfos.getConstArray(); 1099cdf0e10cSrcweir 1100cdf0e10cSrcweir for( i = 1; i < nElements; i++ ) 1101cdf0e10cSrcweir { 1102cdf0e10cSrcweir if( pProperties[i-1].Name >= pProperties[i].Name ) 1103cdf0e10cSrcweir { 1104cdf0e10cSrcweir #ifndef OS2 // YD disabled, too many troubles with debug builds! 1105cdf0e10cSrcweir if (bSorted) { 1106cdf0e10cSrcweir OSL_ENSURE( false, "Property array is not sorted" ); 1107cdf0e10cSrcweir } 1108cdf0e10cSrcweir #endif 1109cdf0e10cSrcweir // not sorted 1110cdf0e10cSrcweir qsort( aInfos.getArray(), nElements, sizeof( Property ), 1111cdf0e10cSrcweir compare_Property_Impl ); 1112cdf0e10cSrcweir break; 1113cdf0e10cSrcweir } 1114cdf0e10cSrcweir } 1115cdf0e10cSrcweir // may be that the array is resorted 1116cdf0e10cSrcweir pProperties = aInfos.getConstArray(); 1117cdf0e10cSrcweir for( i = 0; i < nElements; i++ ) 1118cdf0e10cSrcweir if( pProperties[i].Handle != i ) 1119cdf0e10cSrcweir return; 1120cdf0e10cSrcweir // The handle is the index 1121cdf0e10cSrcweir bRightOrdered = sal_True; 1122cdf0e10cSrcweir } 1123cdf0e10cSrcweir 1124cdf0e10cSrcweir OPropertyArrayHelper::OPropertyArrayHelper( 1125cdf0e10cSrcweir Property * pProps, 1126cdf0e10cSrcweir sal_Int32 nEle, 1127cdf0e10cSrcweir sal_Bool bSorted ) 1128cdf0e10cSrcweir SAL_THROW( () ) 1129cdf0e10cSrcweir : aInfos(pProps, nEle) 1130cdf0e10cSrcweir , bRightOrdered( sal_False ) 1131cdf0e10cSrcweir { 1132cdf0e10cSrcweir init( bSorted ); 1133cdf0e10cSrcweir } 1134cdf0e10cSrcweir 1135cdf0e10cSrcweir OPropertyArrayHelper::OPropertyArrayHelper( 1136cdf0e10cSrcweir const Sequence< Property > & aProps, 1137cdf0e10cSrcweir sal_Bool bSorted ) 1138cdf0e10cSrcweir SAL_THROW( () ) 1139cdf0e10cSrcweir : aInfos(aProps) 1140cdf0e10cSrcweir , bRightOrdered( sal_False ) 1141cdf0e10cSrcweir { 1142cdf0e10cSrcweir init( bSorted ); 1143cdf0e10cSrcweir } 1144cdf0e10cSrcweir 1145cdf0e10cSrcweir //======================================================================== 1146cdf0e10cSrcweir sal_Int32 OPropertyArrayHelper::getCount() const 1147cdf0e10cSrcweir { 1148cdf0e10cSrcweir return aInfos.getLength(); 1149cdf0e10cSrcweir } 1150cdf0e10cSrcweir 1151cdf0e10cSrcweir //======================================================================== 1152cdf0e10cSrcweir sal_Bool OPropertyArrayHelper::fillPropertyMembersByHandle 1153cdf0e10cSrcweir ( 1154cdf0e10cSrcweir OUString * pPropName, 1155cdf0e10cSrcweir sal_Int16 * pAttributes, 1156cdf0e10cSrcweir sal_Int32 nHandle 1157cdf0e10cSrcweir ) 1158cdf0e10cSrcweir { 1159cdf0e10cSrcweir const Property* pProperties = aInfos.getConstArray(); 1160cdf0e10cSrcweir sal_Int32 nElements = aInfos.getLength(); 1161cdf0e10cSrcweir 1162cdf0e10cSrcweir if( bRightOrdered ) 1163cdf0e10cSrcweir { 1164cdf0e10cSrcweir if( nHandle < 0 || nHandle >= nElements ) 1165cdf0e10cSrcweir return sal_False; 1166cdf0e10cSrcweir if( pPropName ) 1167cdf0e10cSrcweir *pPropName = pProperties[ nHandle ].Name; 1168cdf0e10cSrcweir if( pAttributes ) 1169cdf0e10cSrcweir *pAttributes = pProperties[ nHandle ].Attributes; 1170cdf0e10cSrcweir return sal_True; 1171cdf0e10cSrcweir } 1172cdf0e10cSrcweir else 1173cdf0e10cSrcweir { 1174cdf0e10cSrcweir // normally the array is sorted 1175cdf0e10cSrcweir for( sal_Int32 i = 0; i < nElements; i++ ) 1176cdf0e10cSrcweir { 1177cdf0e10cSrcweir if( pProperties[i].Handle == nHandle ) 1178cdf0e10cSrcweir { 1179cdf0e10cSrcweir if( pPropName ) 1180cdf0e10cSrcweir *pPropName = pProperties[ i ].Name; 1181cdf0e10cSrcweir if( pAttributes ) 1182cdf0e10cSrcweir *pAttributes = pProperties[ i ].Attributes; 1183cdf0e10cSrcweir return sal_True; 1184cdf0e10cSrcweir } 1185cdf0e10cSrcweir } 1186cdf0e10cSrcweir } 1187cdf0e10cSrcweir return sal_False; 1188cdf0e10cSrcweir } 1189cdf0e10cSrcweir 1190cdf0e10cSrcweir //======================================================================== 1191cdf0e10cSrcweir Sequence< Property > OPropertyArrayHelper::getProperties(void) 1192cdf0e10cSrcweir { 1193cdf0e10cSrcweir /*if( aInfos.getLength() != nElements ) 1194cdf0e10cSrcweir { 1195cdf0e10cSrcweir ((OPropertyArrayHelper *)this)->aInfos.realloc( nElements ); 1196cdf0e10cSrcweir Property * pProps = ((OPropertyArrayHelper *)this)->aInfos.getArray(); 1197cdf0e10cSrcweir for( sal_Int32 i = 0; i < nElements; i++ ) 1198cdf0e10cSrcweir { 1199cdf0e10cSrcweir pProps[i].Name = pProperties[i].Name; 1200cdf0e10cSrcweir pProps[i].Handle = pProperties[i].Handle; 1201cdf0e10cSrcweir pProps[i].Type = pProperties[i].Type; 1202cdf0e10cSrcweir pProps[i].Attributes = pProperties[i].Attributes; 1203cdf0e10cSrcweir } 1204cdf0e10cSrcweir }*/ 1205cdf0e10cSrcweir return aInfos; 1206cdf0e10cSrcweir } 1207cdf0e10cSrcweir 1208cdf0e10cSrcweir //======================================================================== 1209cdf0e10cSrcweir Property OPropertyArrayHelper::getPropertyByName(const OUString& aPropertyName) 1210cdf0e10cSrcweir throw (UnknownPropertyException) 1211cdf0e10cSrcweir { 1212cdf0e10cSrcweir Property * pR; 1213cdf0e10cSrcweir pR = (Property *)bsearch( &aPropertyName, aInfos.getConstArray(), aInfos.getLength(), 1214cdf0e10cSrcweir sizeof( Property ), 1215cdf0e10cSrcweir compare_OUString_Property_Impl ); 1216cdf0e10cSrcweir if( !pR ) { 1217cdf0e10cSrcweir throw UnknownPropertyException(); 1218cdf0e10cSrcweir } 1219cdf0e10cSrcweir 1220cdf0e10cSrcweir /*Property aProp; 1221cdf0e10cSrcweir aProp.Name = pR->Name; 1222cdf0e10cSrcweir aProp.Handle = pR->Handle; 1223cdf0e10cSrcweir aProp.Type = pR->Type; 1224cdf0e10cSrcweir aProp.Attributes = pR->Attributes; 1225cdf0e10cSrcweir return aProp;*/ 1226cdf0e10cSrcweir return *pR; 1227cdf0e10cSrcweir } 1228cdf0e10cSrcweir 1229cdf0e10cSrcweir //======================================================================== 1230cdf0e10cSrcweir sal_Bool OPropertyArrayHelper::hasPropertyByName(const OUString& aPropertyName) 1231cdf0e10cSrcweir { 1232cdf0e10cSrcweir Property * pR; 1233cdf0e10cSrcweir pR = (Property *)bsearch( &aPropertyName, aInfos.getConstArray(), aInfos.getLength(), 1234cdf0e10cSrcweir sizeof( Property ), 1235cdf0e10cSrcweir compare_OUString_Property_Impl ); 1236cdf0e10cSrcweir return pR != NULL; 1237cdf0e10cSrcweir } 1238cdf0e10cSrcweir 1239cdf0e10cSrcweir //======================================================================== 1240cdf0e10cSrcweir sal_Int32 OPropertyArrayHelper::getHandleByName( const OUString & rPropName ) 1241cdf0e10cSrcweir { 1242cdf0e10cSrcweir Property * pR; 1243cdf0e10cSrcweir pR = (Property *)bsearch( &rPropName, aInfos.getConstArray(), aInfos.getLength(), 1244cdf0e10cSrcweir sizeof( Property ), 1245cdf0e10cSrcweir compare_OUString_Property_Impl ); 1246cdf0e10cSrcweir return pR ? pR->Handle : -1; 1247cdf0e10cSrcweir } 1248cdf0e10cSrcweir 1249cdf0e10cSrcweir //======================================================================== 1250cdf0e10cSrcweir sal_Int32 OPropertyArrayHelper::fillHandles( sal_Int32 * pHandles, const Sequence< OUString > & rPropNames ) 1251cdf0e10cSrcweir { 1252cdf0e10cSrcweir sal_Int32 nHitCount = 0; 1253cdf0e10cSrcweir const OUString * pReqProps = rPropNames.getConstArray(); 1254cdf0e10cSrcweir sal_Int32 nReqLen = rPropNames.getLength(); 1255cdf0e10cSrcweir const Property * pCur = aInfos.getConstArray(); 1256cdf0e10cSrcweir const Property * pEnd = pCur + aInfos.getLength(); 1257cdf0e10cSrcweir 1258cdf0e10cSrcweir for( sal_Int32 i = 0; i < nReqLen; i++ ) 1259cdf0e10cSrcweir { 1260cdf0e10cSrcweir // Logarithmus ermitteln 1261cdf0e10cSrcweir sal_Int32 n = (sal_Int32)(pEnd - pCur); 1262cdf0e10cSrcweir sal_Int32 nLog = 0; 1263cdf0e10cSrcweir while( n ) 1264cdf0e10cSrcweir { 1265cdf0e10cSrcweir nLog += 1; 1266cdf0e10cSrcweir n = n >> 1; 1267cdf0e10cSrcweir } 1268cdf0e10cSrcweir 1269cdf0e10cSrcweir // Anzahl der noch zu suchenden Properties * dem Log2 der verbleibenden 1270cdf0e10cSrcweir // zu dursuchenden Properties. 1271cdf0e10cSrcweir if( (nReqLen - i) * nLog >= pEnd - pCur ) 1272cdf0e10cSrcweir { 1273cdf0e10cSrcweir // linear search is better 1274cdf0e10cSrcweir while( pCur < pEnd && pReqProps[i] > pCur->Name ) 1275cdf0e10cSrcweir { 1276cdf0e10cSrcweir pCur++; 1277cdf0e10cSrcweir } 1278cdf0e10cSrcweir if( pCur < pEnd && pReqProps[i] == pCur->Name ) 1279cdf0e10cSrcweir { 1280cdf0e10cSrcweir pHandles[i] = pCur->Handle; 1281cdf0e10cSrcweir nHitCount++; 1282cdf0e10cSrcweir } 1283cdf0e10cSrcweir else 1284cdf0e10cSrcweir pHandles[i] = -1; 1285cdf0e10cSrcweir } 1286cdf0e10cSrcweir else 1287cdf0e10cSrcweir { 1288cdf0e10cSrcweir // binary search is better 1289cdf0e10cSrcweir sal_Int32 nCompVal = 1; 1290cdf0e10cSrcweir const Property * pOldEnd = pEnd--; 1291cdf0e10cSrcweir const Property * pMid = pCur; 1292cdf0e10cSrcweir 1293cdf0e10cSrcweir while( nCompVal != 0 && pCur <= pEnd ) 1294cdf0e10cSrcweir { 1295cdf0e10cSrcweir pMid = (pEnd - pCur) / 2 + pCur; 1296cdf0e10cSrcweir 1297cdf0e10cSrcweir nCompVal = pReqProps[i].compareTo( pMid->Name ); 1298cdf0e10cSrcweir 1299cdf0e10cSrcweir if( nCompVal > 0 ) 1300cdf0e10cSrcweir pCur = pMid + 1; 1301cdf0e10cSrcweir else 1302cdf0e10cSrcweir pEnd = pMid - 1; 1303cdf0e10cSrcweir } 1304cdf0e10cSrcweir 1305cdf0e10cSrcweir if( nCompVal == 0 ) 1306cdf0e10cSrcweir { 1307cdf0e10cSrcweir pHandles[i] = pMid->Handle; 1308cdf0e10cSrcweir nHitCount++; 1309cdf0e10cSrcweir pCur = pMid +1; 1310cdf0e10cSrcweir } 1311cdf0e10cSrcweir else if( nCompVal > 0 ) 1312cdf0e10cSrcweir { 1313cdf0e10cSrcweir pHandles[i] = -1; 1314cdf0e10cSrcweir pCur = pMid +1; 1315cdf0e10cSrcweir } 1316cdf0e10cSrcweir else 1317cdf0e10cSrcweir { 1318cdf0e10cSrcweir pHandles[i] = -1; 1319cdf0e10cSrcweir pCur = pMid; 1320cdf0e10cSrcweir } 1321cdf0e10cSrcweir pEnd = pOldEnd; 1322cdf0e10cSrcweir } 1323cdf0e10cSrcweir } 1324cdf0e10cSrcweir return nHitCount; 1325cdf0e10cSrcweir } 1326cdf0e10cSrcweir 1327cdf0e10cSrcweir } // end namespace cppu 1328cdf0e10cSrcweir 1329cdf0e10cSrcweir 1330cdf0e10cSrcweir 1331