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