xref: /trunk/main/cppuhelper/source/propshlp.cxx (revision 07a3d7f1)
19d7e27acSAndrew Rist /**************************************************************
2cdf0e10cSrcweir  *
39d7e27acSAndrew Rist  * Licensed to the Apache Software Foundation (ASF) under one
49d7e27acSAndrew Rist  * or more contributor license agreements.  See the NOTICE file
59d7e27acSAndrew Rist  * distributed with this work for additional information
69d7e27acSAndrew Rist  * regarding copyright ownership.  The ASF licenses this file
79d7e27acSAndrew Rist  * to you under the Apache License, Version 2.0 (the
89d7e27acSAndrew Rist  * "License"); you may not use this file except in compliance
99d7e27acSAndrew Rist  * with the License.  You may obtain a copy of the License at
109d7e27acSAndrew Rist  *
119d7e27acSAndrew Rist  *   http://www.apache.org/licenses/LICENSE-2.0
129d7e27acSAndrew Rist  *
139d7e27acSAndrew Rist  * Unless required by applicable law or agreed to in writing,
149d7e27acSAndrew Rist  * software distributed under the License is distributed on an
159d7e27acSAndrew Rist  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
169d7e27acSAndrew Rist  * KIND, either express or implied.  See the License for the
179d7e27acSAndrew Rist  * specific language governing permissions and limitations
189d7e27acSAndrew Rist  * under the License.
199d7e27acSAndrew Rist  *
209d7e27acSAndrew Rist  *************************************************************/
219d7e27acSAndrew Rist 
229d7e27acSAndrew 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 
~IPropertyArrayHelper()45cdf0e10cSrcweir IPropertyArrayHelper::~IPropertyArrayHelper()
46cdf0e10cSrcweir {
47cdf0e10cSrcweir }
48cdf0e10cSrcweir 
getPropertyTypeIdentifier()49cdf0e10cSrcweir inline const ::com::sun::star::uno::Type & getPropertyTypeIdentifier( ) SAL_THROW( () )
50cdf0e10cSrcweir {
51cdf0e10cSrcweir 	return ::getCppuType( (Reference< XPropertyChangeListener > *)0 );
52cdf0e10cSrcweir }
getPropertiesTypeIdentifier()53cdf0e10cSrcweir inline const ::com::sun::star::uno::Type & getPropertiesTypeIdentifier() SAL_THROW( () )
54cdf0e10cSrcweir {
55cdf0e10cSrcweir 	return ::getCppuType( (Reference< XPropertiesChangeListener > *)0 );
56cdf0e10cSrcweir }
getVetoableTypeIdentifier()57cdf0e10cSrcweir inline const ::com::sun::star::uno::Type & getVetoableTypeIdentifier() SAL_THROW( () )
58cdf0e10cSrcweir {
59cdf0e10cSrcweir 	return ::getCppuType( (Reference< XVetoableChangeListener > *)0 );
60cdf0e10cSrcweir }
61cdf0e10cSrcweir 
62cdf0e10cSrcweir extern "C" {
63cdf0e10cSrcweir 
compare_OUString_Property_Impl(const void * arg1,const void * arg2)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  */
OPropertySetHelperInfo_Impl(IPropertyArrayHelper & rHelper_)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  */
getProperties(void)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  */
getPropertyByName(const OUString & PropertyName)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  */
hasPropertyByName(const OUString & PropertyName)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:
Impl(bool i_bIgnoreRuntimeExceptionsWhileFiring,IEventNotificationHook * i_pFireEvents)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 //	----------------------------------------------------
OPropertySetHelper(OBroadcastHelper & rBHelper_)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 
OPropertySetHelper(OBroadcastHelper & rBHelper_,bool bIgnoreRuntimeExceptionsWhileFiring)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 
OPropertySetHelper(OBroadcastHelper & rBHelper_,IEventNotificationHook * i_pFireEvents,bool bIgnoreRuntimeExceptionsWhileFiring)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  */
~OPropertySetHelper()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
queryInterface(const::com::sun::star::uno::Type & rType)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  */
getTypes()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
disposing()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
237*07a3d7f1SPedro Giffuni 	// The listener container are automatically cleared
238cdf0e10cSrcweir 	aBoundLC.disposeAndClear( aEvt );
239cdf0e10cSrcweir 	aVetoableLC.disposeAndClear( aEvt );
240cdf0e10cSrcweir }
241cdf0e10cSrcweir 
createPropertySetInfo(IPropertyArrayHelper & rProperties)242cdf0e10cSrcweir Reference < XPropertySetInfo > OPropertySetHelper::createPropertySetInfo(
243cdf0e10cSrcweir 	IPropertyArrayHelper & rProperties ) SAL_THROW( () )
244cdf0e10cSrcweir {
245cdf0e10cSrcweir 	return static_cast< XPropertySetInfo * >( new OPropertySetHelperInfo_Impl( rProperties ) );
246cdf0e10cSrcweir }
247cdf0e10cSrcweir 
248cdf0e10cSrcweir // XPropertySet
setPropertyValue(const OUString & rPropertyName,const Any & rValue)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
getPropertyValue(const OUString & rPropertyName)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
addPropertyChangeListener(const OUString & rPropertyName,const Reference<XPropertyChangeListener> & rxListener)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
removePropertyChangeListener(const OUString & rPropertyName,const Reference<XPropertyChangeListener> & rxListener)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" );
332*07a3d7f1SPedro Giffuni 	// all listeners are automatically 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
addVetoableChangeListener(const OUString & rPropertyName,const Reference<XVetoableChangeListener> & rxListener)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
removeVetoableChangeListener(const OUString & rPropertyName,const Reference<XVetoableChangeListener> & rxListener)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" );
412*07a3d7f1SPedro Giffuni 	// all listeners are automatically 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 
setDependentFastPropertyValue(sal_Int32 i_handle,const::com::sun::star::uno::Any & i_value)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
setFastPropertyValue(sal_Int32 nHandle,const Any & rValue)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
getFastPropertyValue(sal_Int32 nHandle)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 //--------------------------------------------------------------------------
impl_fireAll(sal_Int32 * i_handles,const Any * i_newValues,const Any * i_oldValues,sal_Int32 i_count)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 //--------------------------------------------------------------------------
fire(sal_Int32 * pnHandles,const Any * pNewValues,const Any * pOldValues,sal_Int32 nHandles,sal_Bool bVetoable)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
setFastPropertyValues(sal_Int32 nSeqLen,sal_Int32 * pHandles,const Any * pValues,sal_Int32 nHitCount)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  */
setPropertyValues(const Sequence<OUString> & rPropertyNames,const Sequence<Any> & rValues)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
getPropertyValues(const Sequence<OUString> & rPropertyNames)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
addPropertiesChangeListener(const Sequence<OUString> &,const Reference<XPropertiesChangeListener> & rListener)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
removePropertiesChangeListener(const Reference<XPropertiesChangeListener> & rListener)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
firePropertiesChangeEvent(const Sequence<OUString> & rPropertyNames,const Reference<XPropertiesChangeListener> & rListener)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
getPropertyState(const OUString & PropertyName)1027cdf0e10cSrcweir PropertyState OPropertySetHelper::getPropertyState( const OUString& PropertyName )
1028cdf0e10cSrcweir {
1029cdf0e10cSrcweir 	PropertyState aState;
1030cdf0e10cSrcweir 	return aState;
1031cdf0e10cSrcweir }
1032cdf0e10cSrcweir 
1033cdf0e10cSrcweir // XPropertyState
getPropertyStates(const Sequence<OUString> & PropertyNames)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 
setPropertyToDefault(const OUString & aPropertyName)1044cdf0e10cSrcweir void OPropertySetHelper::setPropertyToDefault( const OUString& aPropertyName )
1045cdf0e10cSrcweir {
1046cdf0e10cSrcweir 	setPropertyValue( aPropertyName, Any() );
1047cdf0e10cSrcweir }
1048cdf0e10cSrcweir 
getPropertyDefault(const OUString & aPropertyName) const1049cdf0e10cSrcweir Any OPropertySetHelper::getPropertyDefault( const OUString& aPropertyName ) const
1050cdf0e10cSrcweir {
1051cdf0e10cSrcweir 	return Any();
1052cdf0e10cSrcweir }
1053cdf0e10cSrcweir 
addPropertyStateChangeListener(const OUString & aPropertyName,const XPropertyStateChangeListenerRef & Listener)1054cdf0e10cSrcweir void OPropertySetHelper::addPropertyStateChangeListener( const OUString& aPropertyName, const XPropertyStateChangeListenerRef& Listener )
1055cdf0e10cSrcweir {
1056cdf0e10cSrcweir }
1057cdf0e10cSrcweir 
removePropertyStateChangeListener(const OUString & aPropertyName,const XPropertyStateChangeListenerRef & Listener)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 
compare_Property_Impl(const void * arg1,const void * arg2)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 
init(sal_Bool bSorted)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 
OPropertyArrayHelper(Property * pProps,sal_Int32 nEle,sal_Bool bSorted)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 
OPropertyArrayHelper(const Sequence<Property> & aProps,sal_Bool bSorted)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 //========================================================================
getCount() const1146cdf0e10cSrcweir sal_Int32 OPropertyArrayHelper::getCount() const
1147cdf0e10cSrcweir {
1148cdf0e10cSrcweir 	return aInfos.getLength();
1149cdf0e10cSrcweir }
1150cdf0e10cSrcweir 
1151cdf0e10cSrcweir //========================================================================
fillPropertyMembersByHandle(OUString * pPropName,sal_Int16 * pAttributes,sal_Int32 nHandle)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 //========================================================================
getProperties(void)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 //========================================================================
getPropertyByName(const OUString & aPropertyName)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 //========================================================================
hasPropertyByName(const OUString & aPropertyName)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 //========================================================================
getHandleByName(const OUString & rPropName)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 //========================================================================
fillHandles(sal_Int32 * pHandles,const Sequence<OUString> & rPropNames)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