1 /**************************************************************
2 *
3 * Licensed to the Apache Software Foundation (ASF) under one
4 * or more contributor license agreements. See the NOTICE file
5 * distributed with this work for additional information
6 * regarding copyright ownership. The ASF licenses this file
7 * to you under the Apache License, Version 2.0 (the
8 * "License"); you may not use this file except in compliance
9 * with the License. You may obtain a copy of the License at
10 *
11 * http://www.apache.org/licenses/LICENSE-2.0
12 *
13 * Unless required by applicable law or agreed to in writing,
14 * software distributed under the License is distributed on an
15 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16 * KIND, either express or implied. See the License for the
17 * specific language governing permissions and limitations
18 * under the License.
19 *
20 *************************************************************/
21
22
23
24 // MARKER(update_precomp.py): autogen include statement, do not remove
25 #include "precompiled_comphelper.hxx"
26 #include "comphelper/propagg.hxx"
27 #include "comphelper/property.hxx"
28 #include <cppuhelper/queryinterface.hxx>
29 #include <osl/diagnose.h>
30 #include <com/sun/star/beans/PropertyAttribute.hpp>
31
32 #if OSL_DEBUG_LEVEL > 0
33 #include <typeinfo>
34 #include <rtl/strbuf.hxx>
35 #endif
36
37 #include <algorithm>
38 #include <set>
39
40 //.........................................................................
41 namespace comphelper
42 {
43 //.........................................................................
44
45 using namespace ::com::sun::star::uno;
46 using namespace ::com::sun::star::lang;
47 using namespace ::com::sun::star::beans;
48
49 using namespace internal;
50
51 //------------------------------------------------------------------------------
52 namespace
53 {
lcl_findPropertyByName(const Sequence<Property> & _rProps,const::rtl::OUString & _rName)54 const Property* lcl_findPropertyByName( const Sequence< Property >& _rProps, const ::rtl::OUString& _rName )
55 {
56 sal_Int32 nLen = _rProps.getLength();
57 const Property* pProperties = _rProps.getConstArray();
58 const Property* pResult = ::std::lower_bound(pProperties, pProperties + nLen,_rName, ::comphelper::PropertyStringLessFunctor());
59 if ( pResult && ( pResult == pProperties + nLen || pResult->Name != _rName) )
60 pResult = NULL;
61
62 return pResult;
63 }
64 }
65 //==================================================================
66 //= OPropertyArrayAggregationHelper
67 //==================================================================
68
69 //------------------------------------------------------------------------------
OPropertyArrayAggregationHelper(const Sequence<Property> & _rProperties,const Sequence<Property> & _rAggProperties,IPropertyInfoService * _pInfoService,sal_Int32 _nFirstAggregateId)70 OPropertyArrayAggregationHelper::OPropertyArrayAggregationHelper(
71 const Sequence< Property >& _rProperties, const Sequence< Property >& _rAggProperties,
72 IPropertyInfoService* _pInfoService, sal_Int32 _nFirstAggregateId )
73 :m_aProperties( _rProperties )
74 {
75 sal_Int32 nDelegatorProps = _rProperties.getLength();
76 sal_Int32 nAggregateProps = _rAggProperties.getLength();
77
78 // make room for all properties
79 sal_Int32 nMergedProps = nDelegatorProps + nAggregateProps;
80 m_aProperties.realloc( nMergedProps );
81
82 const Property* pAggregateProps = _rAggProperties.getConstArray();
83 const Property* pDelegateProps = _rProperties.getConstArray();
84 Property* pMergedProps = m_aProperties.getArray();
85
86 // if properties are present both at the delegatee and the aggregate, then the former are supposed to win.
87 // So, we'll need an existence check.
88 ::std::set< ::rtl::OUString > aDelegatorProps;
89
90 // create the map for the delegator properties
91 sal_Int32 nMPLoop = 0;
92 for ( ; nMPLoop < nDelegatorProps; ++nMPLoop, ++pDelegateProps )
93 {
94 m_aPropertyAccessors[ pDelegateProps->Handle ] = OPropertyAccessor( -1, nMPLoop, sal_False );
95 OSL_ENSURE( aDelegatorProps.find( pDelegateProps->Name ) == aDelegatorProps.end(),
96 "OPropertyArrayAggregationHelper::OPropertyArrayAggregationHelper: duplicate delegatee property!" );
97 aDelegatorProps.insert( pDelegateProps->Name );
98 }
99
100 // create the map for the aggregate properties
101 sal_Int32 nAggregateHandle = _nFirstAggregateId;
102 pMergedProps += nDelegatorProps;
103 for ( ; nMPLoop < nMergedProps; ++pAggregateProps )
104 {
105 // if the aggregate property is present at the delegatee already, ignore it
106 if ( aDelegatorProps.find( pAggregateProps->Name ) != aDelegatorProps.end() )
107 {
108 --nMergedProps;
109 continue;
110 }
111
112 // next aggregate property - remember it
113 *pMergedProps = *pAggregateProps;
114
115 // determine the handle for the property which we will expose to the outside world
116 sal_Int32 nHandle = -1;
117 // ask the infor service first
118 if ( _pInfoService )
119 nHandle = _pInfoService->getPreferedPropertyId( pMergedProps->Name );
120
121 if ( -1 == nHandle )
122 // no handle from the info service -> default
123 nHandle = nAggregateHandle++;
124 else
125 { // check if we alread have a property with the given handle
126 const Property* pPropsTilNow = m_aProperties.getConstArray();
127 for ( sal_Int32 nCheck = 0; nCheck < nMPLoop; ++nCheck, ++pPropsTilNow )
128 if ( pPropsTilNow->Handle == nHandle )
129 { // conflicts -> use another one (which we don't check anymore, assuming _nFirstAggregateId was large enough)
130 nHandle = nAggregateHandle++;
131 break;
132 }
133 }
134
135 // remember the accessor for this property
136 m_aPropertyAccessors[ nHandle ] = OPropertyAccessor( pMergedProps->Handle, nMPLoop, sal_True );
137 pMergedProps->Handle = nHandle;
138
139 ++nMPLoop;
140 ++pMergedProps;
141 }
142 m_aProperties.realloc( nMergedProps );
143 pMergedProps = m_aProperties.getArray(); // reset, needed again below
144
145 // sortieren der Properties nach Namen
146 ::std::sort( pMergedProps, pMergedProps+nMergedProps, PropertyCompareByName());
147
148 pMergedProps = m_aProperties.getArray();
149
150 // Positionen in der Map abgleichen
151 for ( nMPLoop = 0; nMPLoop < nMergedProps; ++nMPLoop, ++pMergedProps )
152 m_aPropertyAccessors[ pMergedProps->Handle ].nPos = nMPLoop;
153 }
154
155 //------------------------------------------------------------------
classifyProperty(const::rtl::OUString & _rName)156 OPropertyArrayAggregationHelper::PropertyOrigin OPropertyArrayAggregationHelper::classifyProperty( const ::rtl::OUString& _rName )
157 {
158 PropertyOrigin eOrigin = UNKNOWN_PROPERTY;
159 // look up the name
160 const Property* pPropertyDescriptor = lcl_findPropertyByName( m_aProperties, _rName );
161 if ( pPropertyDescriptor )
162 {
163 // look up the handle for this name
164 ConstPropertyAccessorMapIterator aPos = m_aPropertyAccessors.find( pPropertyDescriptor->Handle );
165 OSL_ENSURE( m_aPropertyAccessors.end() != aPos, "OPropertyArrayAggregationHelper::classifyProperty: should have this handle in my map!" );
166 if ( m_aPropertyAccessors.end() != aPos )
167 {
168 eOrigin = aPos->second.bAggregate ? AGGREGATE_PROPERTY : DELEGATOR_PROPERTY;
169 }
170 }
171 return eOrigin;
172 }
173
174 //------------------------------------------------------------------
getPropertyByName(const::rtl::OUString & _rPropertyName)175 Property OPropertyArrayAggregationHelper::getPropertyByName( const ::rtl::OUString& _rPropertyName ) throw( UnknownPropertyException )
176 {
177 const Property* pProperty = findPropertyByName( _rPropertyName );
178
179 if ( !pProperty )
180 throw UnknownPropertyException();
181
182 return *pProperty;
183 }
184
185 //------------------------------------------------------------------------------
hasPropertyByName(const::rtl::OUString & _rPropertyName)186 sal_Bool OPropertyArrayAggregationHelper::hasPropertyByName(const ::rtl::OUString& _rPropertyName)
187 {
188 return NULL != findPropertyByName( _rPropertyName );
189 }
190
191 //------------------------------------------------------------------------------
findPropertyByName(const::rtl::OUString & _rName) const192 const Property* OPropertyArrayAggregationHelper::findPropertyByName(const :: rtl::OUString& _rName ) const
193 {
194 return lcl_findPropertyByName( m_aProperties, _rName );
195 }
196
197 //------------------------------------------------------------------------------
getHandleByName(const::rtl::OUString & _rPropertyName)198 sal_Int32 OPropertyArrayAggregationHelper::getHandleByName(const ::rtl::OUString& _rPropertyName)
199 {
200 const Property* pProperty = findPropertyByName( _rPropertyName );
201 return pProperty ? pProperty->Handle : -1;
202 }
203
204 //------------------------------------------------------------------------------
fillPropertyMembersByHandle(::rtl::OUString * _pPropName,sal_Int16 * _pAttributes,sal_Int32 _nHandle)205 sal_Bool OPropertyArrayAggregationHelper::fillPropertyMembersByHandle(
206 ::rtl::OUString* _pPropName, sal_Int16* _pAttributes, sal_Int32 _nHandle)
207 {
208 ConstPropertyAccessorMapIterator i = m_aPropertyAccessors.find(_nHandle);
209 sal_Bool bRet = i != m_aPropertyAccessors.end();
210 if (bRet)
211 {
212 const ::com::sun::star::beans::Property& rProperty = m_aProperties.getConstArray()[(*i).second.nPos];
213 if (_pPropName)
214 *_pPropName = rProperty.Name;
215 if (_pAttributes)
216 *_pAttributes = rProperty.Attributes;
217 }
218 return bRet;
219 }
220
221 //------------------------------------------------------------------------------
getPropertyByHandle(sal_Int32 _nHandle,Property & _rProperty) const222 sal_Bool OPropertyArrayAggregationHelper::getPropertyByHandle( sal_Int32 _nHandle, Property& _rProperty ) const
223 {
224 ConstPropertyAccessorMapIterator pos = m_aPropertyAccessors.find(_nHandle);
225 if ( pos != m_aPropertyAccessors.end() )
226 {
227 _rProperty = m_aProperties[ pos->second.nPos ];
228 return sal_True;
229 }
230 return sal_False;
231 }
232
233 //------------------------------------------------------------------------------
fillAggregatePropertyInfoByHandle(::rtl::OUString * _pPropName,sal_Int32 * _pOriginalHandle,sal_Int32 _nHandle) const234 sal_Bool OPropertyArrayAggregationHelper::fillAggregatePropertyInfoByHandle(
235 ::rtl::OUString* _pPropName, sal_Int32* _pOriginalHandle, sal_Int32 _nHandle) const
236 {
237 ConstPropertyAccessorMapIterator i = m_aPropertyAccessors.find(_nHandle);
238 sal_Bool bRet = i != m_aPropertyAccessors.end() && (*i).second.bAggregate;
239 if (bRet)
240 {
241 if (_pOriginalHandle)
242 *_pOriginalHandle = (*i).second.nOriginalHandle;
243 if (_pPropName)
244 {
245 OSL_ENSURE((*i).second.nPos < m_aProperties.getLength(),"Invalid index for sequence!");
246 const ::com::sun::star::beans::Property& rProperty = m_aProperties.getConstArray()[(*i).second.nPos];
247 *_pPropName = rProperty.Name;
248 }
249 }
250 return bRet;
251 }
252
253
254 //------------------------------------------------------------------------------
getProperties()255 ::com::sun::star::uno::Sequence< ::com::sun::star::beans::Property> OPropertyArrayAggregationHelper::getProperties()
256 {
257 return m_aProperties;
258 }
259
260
261 //------------------------------------------------------------------------------
fillHandles(sal_Int32 * _pHandles,const::com::sun::star::uno::Sequence<::rtl::OUString> & _rPropNames)262 sal_Int32 OPropertyArrayAggregationHelper::fillHandles(
263 sal_Int32* _pHandles, const ::com::sun::star::uno::Sequence< ::rtl::OUString >& _rPropNames )
264 {
265 sal_Int32 nHitCount = 0;
266 const ::rtl::OUString* pReqProps = _rPropNames.getConstArray();
267 sal_Int32 nReqLen = _rPropNames.getLength();
268
269 #if OSL_DEBUG_LEVEL > 0
270 // assure that the sequence is sorted
271 {
272 const ::rtl::OUString* pLookup = _rPropNames.getConstArray();
273 const ::rtl::OUString* pEnd = _rPropNames.getConstArray() + _rPropNames.getLength() - 1;
274 for (; pLookup < pEnd; ++pLookup)
275 {
276 const ::rtl::OUString* pCompare = pLookup + 1;
277 const ::rtl::OUString* pCompareEnd = pEnd + 1;
278 for (; pCompare < pCompareEnd; ++pCompare)
279 {
280 OSL_ENSURE(pLookup->compareTo(*pCompare) < 0, "OPropertyArrayAggregationHelper::fillHandles : property names are not sorted!");
281 }
282 }
283 }
284 #endif
285
286 const ::com::sun::star::beans::Property* pCur = m_aProperties.getConstArray();
287 const ::com::sun::star::beans::Property* pEnd = m_aProperties.getConstArray() + m_aProperties.getLength();
288
289 for( sal_Int32 i = 0; i < nReqLen; ++i )
290 {
291 // Logarithmus ermitteln
292 sal_uInt32 n = (sal_uInt32)(pEnd - pCur);
293 sal_Int32 nLog = 0;
294 while( n )
295 {
296 nLog += 1;
297 n = n >> 1;
298 }
299
300 // Anzahl der noch zu suchenden Properties * dem Log2 der verbleibenden
301 // zu dursuchenden Properties.
302 if( (nReqLen - i) * nLog >= pEnd - pCur )
303 {
304 // linear search is better
305 while( pCur < pEnd && pReqProps[i] > pCur->Name )
306 {
307 pCur++;
308 }
309 if( pCur < pEnd && pReqProps[i] == pCur->Name )
310 {
311 _pHandles[i] = pCur->Handle;
312 nHitCount++;
313 }
314 else
315 _pHandles[i] = -1;
316 }
317 else
318 {
319 // binary search is better
320 sal_Int32 nCompVal = 1;
321 const ::com::sun::star::beans::Property* pOldEnd = pEnd--;
322 const ::com::sun::star::beans::Property* pMid = pCur;
323
324 while( nCompVal != 0 && pCur <= pEnd )
325 {
326 pMid = (pEnd - pCur) / 2 + pCur;
327
328 nCompVal = pReqProps[i].compareTo( pMid->Name );
329
330 if( nCompVal > 0 )
331 pCur = pMid + 1;
332 else
333 pEnd = pMid - 1;
334 }
335
336 if( nCompVal == 0 )
337 {
338 _pHandles[i] = pMid->Handle;
339 nHitCount++;
340 pCur = pMid +1;
341 }
342 else if( nCompVal > 0 )
343 {
344 _pHandles[i] = -1;
345 pCur = pMid + 1;
346 }
347 else
348 {
349 _pHandles[i] = -1;
350 pCur = pMid;
351 }
352 pEnd = pOldEnd;
353 }
354 }
355 return nHitCount;
356 }
357
358 //==================================================================
359 //= PropertyForwarder
360 //==================================================================
361 namespace internal
362 {
363 class PropertyForwarder
364 {
365 private:
366 OPropertySetAggregationHelper& m_rAggregationHelper;
367 ::std::set< sal_Int32 > m_aProperties;
368 sal_Int32 m_nCurrentlyForwarding;
369
370 public:
371 PropertyForwarder( OPropertySetAggregationHelper& _rAggregationHelper );
372 ~PropertyForwarder();
373
374 /** declares that the forwarder should be responsible for the given property
375
376 @param _nHandle
377 the public handle (<em>not</em> the original handle!) of the property
378 */
379 void takeResponsibilityFor( sal_Int32 _nHandle );
380
381 /** checks whether the forwarder is responsible for the given property
382 */
383 bool isResponsibleFor( sal_Int32 _nHandle );
384
385 /// actually forwards a property value to the aggregate
386 void doForward( sal_Int32 _nHandle, const Any& _rValue ) throw ( Exception );
387
getCurrentlyForwardedProperty() const388 sal_Int32 getCurrentlyForwardedProperty( ) const { return m_nCurrentlyForwarding; }
389 };
390
391 //--------------------------------------------------------------------------
PropertyForwarder(OPropertySetAggregationHelper & _rAggregationHelper)392 PropertyForwarder::PropertyForwarder( OPropertySetAggregationHelper& _rAggregationHelper )
393 :m_rAggregationHelper( _rAggregationHelper )
394 ,m_nCurrentlyForwarding( -1 )
395 {
396 }
397
398 //--------------------------------------------------------------------------
~PropertyForwarder()399 PropertyForwarder::~PropertyForwarder()
400 {
401 }
402
403 //--------------------------------------------------------------------------
takeResponsibilityFor(sal_Int32 _nHandle)404 void PropertyForwarder::takeResponsibilityFor( sal_Int32 _nHandle )
405 {
406 m_aProperties.insert( _nHandle );
407 }
408
409 //--------------------------------------------------------------------------
isResponsibleFor(sal_Int32 _nHandle)410 bool PropertyForwarder::isResponsibleFor( sal_Int32 _nHandle )
411 {
412 return m_aProperties.find( _nHandle ) != m_aProperties.end();
413 }
414
415 //--------------------------------------------------------------------------
doForward(sal_Int32 _nHandle,const Any & _rValue)416 void PropertyForwarder::doForward( sal_Int32 _nHandle, const Any& _rValue ) throw ( Exception )
417 {
418 OSL_ENSURE( m_rAggregationHelper.m_xAggregateSet.is(), "PropertyForwarder::doForward: no property set!" );
419 if ( m_rAggregationHelper.m_xAggregateSet.is() )
420 {
421 m_rAggregationHelper.forwardingPropertyValue( _nHandle );
422
423 OSL_ENSURE( m_nCurrentlyForwarding == -1, "PropertyForwarder::doForward: reentrance?" );
424 m_nCurrentlyForwarding = _nHandle;
425
426 try
427 {
428 m_rAggregationHelper.m_xAggregateSet->setPropertyValue( m_rAggregationHelper.getPropertyName( _nHandle ), _rValue );
429 // TODO: cache the property name? (it's a O(log n) search)
430 }
431 catch( const Exception& )
432 {
433 m_rAggregationHelper.forwardedPropertyValue( _nHandle, false );
434 throw;
435 }
436
437 m_nCurrentlyForwarding = -1;
438
439 m_rAggregationHelper.forwardedPropertyValue( _nHandle, true );
440 }
441 }
442 }
443
444 //==================================================================
445 //= OPropertySetAggregationHelper
446 //==================================================================
447
448 //------------------------------------------------------------------------------
OPropertySetAggregationHelper(::cppu::OBroadcastHelper & rBHlp)449 OPropertySetAggregationHelper::OPropertySetAggregationHelper( ::cppu::OBroadcastHelper& rBHlp )
450 :OPropertyStateHelper( rBHlp )
451 ,m_bListening( sal_False )
452 {
453 m_pForwarder = new PropertyForwarder( *this );
454 }
455
456 //------------------------------------------------------------------------------
~OPropertySetAggregationHelper()457 OPropertySetAggregationHelper::~OPropertySetAggregationHelper()
458 {
459 delete m_pForwarder;
460 }
461
462 //------------------------------------------------------------------------------
queryInterface(const::com::sun::star::uno::Type & _rType)463 ::com::sun::star::uno::Any SAL_CALL OPropertySetAggregationHelper::queryInterface(const ::com::sun::star::uno::Type& _rType) throw( ::com::sun::star::uno::RuntimeException)
464 {
465 ::com::sun::star::uno::Any aReturn = OPropertyStateHelper::queryInterface(_rType);
466
467 if ( !aReturn.hasValue() )
468 aReturn = cppu::queryInterface(_rType
469 ,static_cast< ::com::sun::star::beans::XPropertiesChangeListener*>(this)
470 ,static_cast< ::com::sun::star::beans::XVetoableChangeListener*>(this)
471 ,static_cast< ::com::sun::star::lang::XEventListener*>(static_cast< ::com::sun::star::beans::XPropertiesChangeListener*>(this))
472 );
473
474 return aReturn;
475 }
476
477 //------------------------------------------------------------------------------
disposing()478 void OPropertySetAggregationHelper::disposing()
479 {
480 osl::MutexGuard aGuard(rBHelper.rMutex);
481
482 if ( m_xAggregateSet.is() && m_bListening )
483 {
484 // als einziger Listener anmelden
485 m_xAggregateMultiSet->removePropertiesChangeListener(this);
486 m_xAggregateSet->removeVetoableChangeListener(::rtl::OUString(), this);
487 m_bListening = sal_False;
488 }
489
490 OPropertyStateHelper::disposing();
491 }
492
493 //------------------------------------------------------------------------------
disposing(const::com::sun::star::lang::EventObject & _rSource)494 void SAL_CALL OPropertySetAggregationHelper::disposing(const ::com::sun::star::lang::EventObject& _rSource) throw ( ::com::sun::star::uno::RuntimeException)
495 {
496 OSL_ENSURE(m_xAggregateSet.is(), "OPropertySetAggregationHelper::disposing : don't have an aggregate anymore !");
497 if (_rSource.Source == m_xAggregateSet)
498 m_bListening = sal_False;
499 }
500
501 //------------------------------------------------------------------------------
propertiesChange(const::com::sun::star::uno::Sequence<::com::sun::star::beans::PropertyChangeEvent> & _rEvents)502 void SAL_CALL OPropertySetAggregationHelper::propertiesChange(const ::com::sun::star::uno::Sequence< ::com::sun::star::beans::PropertyChangeEvent>& _rEvents) throw( ::com::sun::star::uno::RuntimeException)
503 {
504 OSL_ENSURE(m_xAggregateSet.is(), "OPropertySetAggregationHelper::propertiesChange : have no aggregate !");
505
506 sal_Int32 nLen = _rEvents.getLength();
507 cppu::IPropertyArrayHelper& rPH = getInfoHelper();
508
509 if (1 == nLen)
510 {
511 const ::com::sun::star::beans::PropertyChangeEvent& evt = _rEvents.getConstArray()[0];
512 OSL_ENSURE( !evt.PropertyName.isEmpty(), "OPropertySetAggregationHelper::propertiesChange : invalid event !");
513 // we had a bug where this assertion would have us saved a whole day :) (72514)
514 sal_Int32 nHandle = rPH.getHandleByName( evt.PropertyName );
515
516 // If nHandle is -1 the event marks a (aggregate) property which we hide to callers
517 // If isCurrentlyForwardingProperty( nHandle ) is <TRUE/>, then we ourself triggered
518 // setting this property. In this case, it will be notified later (by the OPropertySetHelper
519 // implementation)
520
521 if ( ( nHandle != -1 ) && !isCurrentlyForwardingProperty( nHandle ) )
522 fire(&nHandle, &evt.NewValue, &evt.OldValue, 1, sal_False);
523 }
524 else
525 {
526 sal_Int32* pHandles = new sal_Int32[nLen];
527 ::com::sun::star::uno::Any* pNewValues = new ::com::sun::star::uno::Any[nLen];
528 ::com::sun::star::uno::Any* pOldValues = new ::com::sun::star::uno::Any[nLen];
529
530 const ::com::sun::star::beans::PropertyChangeEvent* pEvents = _rEvents.getConstArray();
531 sal_Int32 nDest = 0;
532 for (sal_Int32 nSource=0; nSource<nLen; ++nSource, ++pEvents)
533 {
534 sal_Int32 nHandle = rPH.getHandleByName(pEvents->PropertyName);
535 if ( ( nHandle != -1 ) && !isCurrentlyForwardingProperty( nHandle ) )
536 { // same as above : -1 is valid (73247) ...
537 pHandles[nDest] = nHandle;
538 pNewValues[nDest] = pEvents->NewValue;
539 pOldValues[nDest] = pEvents->OldValue;
540 ++nDest;
541 }
542 }
543
544 if (nDest)
545 fire(pHandles, pNewValues, pOldValues, nDest, sal_False);
546
547 delete[] pHandles;
548 delete[] pNewValues;
549 delete[] pOldValues;
550 }
551 }
552
553 //------------------------------------------------------------------------------
vetoableChange(const::com::sun::star::beans::PropertyChangeEvent & _rEvent)554 void SAL_CALL OPropertySetAggregationHelper::vetoableChange(const ::com::sun::star::beans::PropertyChangeEvent& _rEvent) throw( ::com::sun::star::beans::PropertyVetoException, ::com::sun::star::uno::RuntimeException)
555 {
556 OSL_ENSURE(m_xAggregateSet.is(), "OPropertySetAggregationHelper::vetoableChange : have no aggregate !");
557
558 cppu::IPropertyArrayHelper& rPH = getInfoHelper();
559
560 sal_Int32 nHandle = rPH.getHandleByName(_rEvent.PropertyName);
561 fire(&nHandle, &_rEvent.NewValue, &_rEvent.OldValue, 1, sal_True);
562 }
563
564 //------------------------------------------------------------------------------
setAggregation(const::com::sun::star::uno::Reference<::com::sun::star::uno::XInterface> & _rxDelegate)565 void OPropertySetAggregationHelper::setAggregation(const ::com::sun::star::uno::Reference< ::com::sun::star::uno::XInterface >& _rxDelegate)
566 throw( ::com::sun::star::lang::IllegalArgumentException )
567 {
568 osl::MutexGuard aGuard(rBHelper.rMutex);
569
570 if (m_bListening && m_xAggregateSet.is())
571 {
572 m_xAggregateMultiSet->removePropertiesChangeListener(this);
573 m_xAggregateSet->removeVetoableChangeListener(::rtl::OUString(), this);
574 m_bListening = sal_False;
575 }
576
577 m_xAggregateState = m_xAggregateState.query( _rxDelegate );
578 m_xAggregateSet = m_xAggregateSet.query( _rxDelegate );
579 m_xAggregateMultiSet = m_xAggregateMultiSet.query( _rxDelegate );
580 m_xAggregateFastSet = m_xAggregateFastSet.query( _rxDelegate );
581
582 // must support XPropertySet and XMultiPropertySet
583 if ( m_xAggregateSet.is() && !m_xAggregateMultiSet.is() )
584 throw ::com::sun::star::lang::IllegalArgumentException();
585 }
586
587 //------------------------------------------------------------------------------
startListening()588 void OPropertySetAggregationHelper::startListening()
589 {
590 osl::MutexGuard aGuard(rBHelper.rMutex);
591
592 if (!m_bListening && m_xAggregateSet.is())
593 {
594 // als einziger Listener anmelden
595 ::com::sun::star::uno::Sequence< ::rtl::OUString > aPropertyNames;
596 m_xAggregateMultiSet->addPropertiesChangeListener(aPropertyNames, this);
597 m_xAggregateSet->addVetoableChangeListener(::rtl::OUString(), this);
598
599 m_bListening = sal_True;
600 }
601 }
602
603 //------------------------------------------------------------------------------
addVetoableChangeListener(const::rtl::OUString & _rPropertyName,const::com::sun::star::uno::Reference<::com::sun::star::beans::XVetoableChangeListener> & _rxListener)604 void SAL_CALL OPropertySetAggregationHelper::addVetoableChangeListener(const ::rtl::OUString& _rPropertyName,
605 const ::com::sun::star::uno::Reference< ::com::sun::star::beans::XVetoableChangeListener>& _rxListener)
606 throw( ::com::sun::star::beans::UnknownPropertyException, ::com::sun::star::lang::WrappedTargetException, ::com::sun::star::uno::RuntimeException)
607 {
608 OPropertySetHelper::addVetoableChangeListener(_rPropertyName, _rxListener);
609 if (!m_bListening)
610 startListening();
611 }
612
613 //------------------------------------------------------------------------------
addPropertyChangeListener(const::rtl::OUString & _rPropertyName,const::com::sun::star::uno::Reference<::com::sun::star::beans::XPropertyChangeListener> & _rxListener)614 void SAL_CALL OPropertySetAggregationHelper::addPropertyChangeListener(const ::rtl::OUString& _rPropertyName,
615 const ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertyChangeListener>& _rxListener)
616 throw( ::com::sun::star::beans::UnknownPropertyException, ::com::sun::star::lang::WrappedTargetException, ::com::sun::star::uno::RuntimeException)
617 {
618 OPropertySetHelper::addPropertyChangeListener(_rPropertyName, _rxListener);
619 if (!m_bListening)
620 startListening();
621 }
622
623 //------------------------------------------------------------------------------
addPropertiesChangeListener(const::com::sun::star::uno::Sequence<::rtl::OUString> & _rPropertyNames,const::com::sun::star::uno::Reference<::com::sun::star::beans::XPropertiesChangeListener> & _rxListener)624 void SAL_CALL OPropertySetAggregationHelper::addPropertiesChangeListener(const ::com::sun::star::uno::Sequence< ::rtl::OUString >& _rPropertyNames,
625 const ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertiesChangeListener>& _rxListener)
626 throw( ::com::sun::star::uno::RuntimeException)
627 {
628 OPropertySetHelper::addPropertiesChangeListener(_rPropertyNames, _rxListener);
629 if (!m_bListening)
630 startListening();
631 }
632
633 //------------------------------------------------------------------------------
getOriginalHandle(sal_Int32 nHandle) const634 sal_Int32 OPropertySetAggregationHelper::getOriginalHandle(sal_Int32 nHandle) const
635 {
636 OPropertyArrayAggregationHelper& rPH = (OPropertyArrayAggregationHelper&)const_cast<OPropertySetAggregationHelper*>(this)->getInfoHelper();
637 sal_Int32 nOriginalHandle = -1;
638 rPH.fillAggregatePropertyInfoByHandle(NULL, &nOriginalHandle, nHandle);
639 return nOriginalHandle;
640 }
641
642 //--------------------------------------------------------------------------
getPropertyName(sal_Int32 _nHandle) const643 ::rtl::OUString OPropertySetAggregationHelper::getPropertyName( sal_Int32 _nHandle ) const
644 {
645 OPropertyArrayAggregationHelper& rPH = static_cast< OPropertyArrayAggregationHelper& >( const_cast<OPropertySetAggregationHelper*>(this)->getInfoHelper() );
646 Property aProperty;
647 OSL_VERIFY( rPH.getPropertyByHandle( _nHandle, aProperty ) );
648 return aProperty.Name;
649 }
650
651 //------------------------------------------------------------------------------
setFastPropertyValue(sal_Int32 _nHandle,const::com::sun::star::uno::Any & _rValue)652 void SAL_CALL OPropertySetAggregationHelper::setFastPropertyValue(sal_Int32 _nHandle, const ::com::sun::star::uno::Any& _rValue)
653 throw( ::com::sun::star::beans::UnknownPropertyException, ::com::sun::star::beans::PropertyVetoException,
654 ::com::sun::star::lang::IllegalArgumentException, ::com::sun::star::lang::WrappedTargetException,
655 ::com::sun::star::uno::RuntimeException)
656 {
657 OPropertyArrayAggregationHelper& rPH = static_cast< OPropertyArrayAggregationHelper& >( getInfoHelper() );
658 ::rtl::OUString aPropName;
659 sal_Int32 nOriginalHandle = -1;
660
661 // does the handle belong to the aggregation ?
662 if (rPH.fillAggregatePropertyInfoByHandle(&aPropName, &nOriginalHandle, _nHandle))
663 if (m_xAggregateFastSet.is())
664 m_xAggregateFastSet->setFastPropertyValue(nOriginalHandle, _rValue);
665 else
666 m_xAggregateSet->setPropertyValue(aPropName, _rValue);
667 else
668 OPropertySetHelper::setFastPropertyValue(_nHandle, _rValue);
669 }
670
671 //------------------------------------------------------------------------------
getFastPropertyValue(::com::sun::star::uno::Any & rValue,sal_Int32 nHandle) const672 void OPropertySetAggregationHelper::getFastPropertyValue( ::com::sun::star::uno::Any& rValue, sal_Int32 nHandle) const
673 {
674 OPropertyArrayAggregationHelper& rPH = (OPropertyArrayAggregationHelper&)const_cast<OPropertySetAggregationHelper*>(this)->getInfoHelper();
675 ::rtl::OUString aPropName;
676 sal_Int32 nOriginalHandle = -1;
677
678 if (rPH.fillAggregatePropertyInfoByHandle(&aPropName, &nOriginalHandle, nHandle))
679 {
680 if (m_xAggregateFastSet.is())
681 rValue = m_xAggregateFastSet->getFastPropertyValue(nOriginalHandle);
682 else
683 rValue = m_xAggregateSet->getPropertyValue(aPropName);
684 }
685 else if ( m_pForwarder->isResponsibleFor( nHandle ) )
686 {
687 // this is a property which has been "overwritten" in our instance (thus
688 // fillAggregatePropertyInfoByHandle didn't find it)
689 rValue = m_xAggregateSet->getPropertyValue( getPropertyName( nHandle ) );
690 }
691 }
692
693 //------------------------------------------------------------------------------
getFastPropertyValue(sal_Int32 nHandle)694 ::com::sun::star::uno::Any SAL_CALL OPropertySetAggregationHelper::getFastPropertyValue(sal_Int32 nHandle)
695 throw( ::com::sun::star::beans::UnknownPropertyException,
696 ::com::sun::star::lang::WrappedTargetException,
697 ::com::sun::star::uno::RuntimeException)
698 {
699 OPropertyArrayAggregationHelper& rPH = static_cast< OPropertyArrayAggregationHelper& >( getInfoHelper() );
700 ::rtl::OUString aPropName;
701 sal_Int32 nOriginalHandle = -1;
702 ::com::sun::star::uno::Any aValue;
703
704 if (rPH.fillAggregatePropertyInfoByHandle(&aPropName, &nOriginalHandle, nHandle))
705 {
706 if (m_xAggregateFastSet.is())
707 aValue = m_xAggregateFastSet->getFastPropertyValue(nOriginalHandle);
708 else
709 aValue = m_xAggregateSet->getPropertyValue(aPropName);
710 }
711 else
712 aValue = OPropertySetHelper::getFastPropertyValue(nHandle);
713
714 return aValue;
715 }
716
717 //------------------------------------------------------------------------------
setPropertyValues(const Sequence<::rtl::OUString> & _rPropertyNames,const Sequence<Any> & _rValues)718 void SAL_CALL OPropertySetAggregationHelper::setPropertyValues(
719 const Sequence< ::rtl::OUString >& _rPropertyNames, const Sequence< Any >& _rValues )
720 throw ( PropertyVetoException, IllegalArgumentException, WrappedTargetException, RuntimeException )
721 {
722 OSL_ENSURE( !rBHelper.bInDispose, "OPropertySetAggregationHelper::setPropertyValues : do not use within the dispose call !");
723 OSL_ENSURE( !rBHelper.bDisposed, "OPropertySetAggregationHelper::setPropertyValues : object is disposed" );
724
725 // check where the properties come from
726 if (!m_xAggregateSet.is())
727 OPropertySetHelper::setPropertyValues(_rPropertyNames, _rValues);
728 else if (_rPropertyNames.getLength() == 1) // use the more efficient way
729 {
730 try
731 {
732 setPropertyValue( _rPropertyNames[0], _rValues[0] );
733 }
734 catch( const UnknownPropertyException& )
735 {
736 // by definition of XMultiPropertySet::setPropertyValues, unknown properties are to be ignored
737 #if OSL_DEBUG_LEVEL > 0
738 ::rtl::OStringBuffer aMessage;
739 aMessage.append( "OPropertySetAggregationHelper::setPropertyValues: unknown property '" );
740 aMessage.append( ::rtl::OUStringToOString( _rPropertyNames[0], RTL_TEXTENCODING_ASCII_US ) );
741 aMessage.append( "'" );
742 aMessage.append( "\n(implementation " );
743 aMessage.append( typeid( *this ).name() );
744 aMessage.append( ")" );
745 OSL_ENSURE( false, aMessage.getStr() );
746 #endif
747 }
748 }
749 else
750 {
751 OPropertyArrayAggregationHelper& rPH = static_cast< OPropertyArrayAggregationHelper& >( getInfoHelper() );
752
753 // determine which properties belong to the aggregate, and which ones to the delegator
754 const ::rtl::OUString* pNames = _rPropertyNames.getConstArray();
755 sal_Int32 nAggCount(0);
756 sal_Int32 nLen(_rPropertyNames.getLength());
757
758 for ( sal_Int32 i = 0; i < nLen; ++i, ++pNames )
759 {
760 OPropertyArrayAggregationHelper::PropertyOrigin ePropOrg = rPH.classifyProperty( *pNames );
761 if ( OPropertyArrayAggregationHelper::UNKNOWN_PROPERTY == ePropOrg )
762 throw WrappedTargetException( ::rtl::OUString(), static_cast< XMultiPropertySet* >( this ), makeAny( UnknownPropertyException( ) ) );
763 // due to a flaw in the API design, this method is not allowed to throw an UnknownPropertyException
764 // so we wrap it into a WrappedTargetException
765 // #107545# - 2002-02-20 - fs@openoffice.org
766
767 if ( OPropertyArrayAggregationHelper::AGGREGATE_PROPERTY == ePropOrg )
768 ++nAggCount;
769 }
770
771 pNames = _rPropertyNames.getConstArray(); // reset, we'll need it again below ...
772
773 // all properties belong to the aggregate
774 if (nAggCount == nLen)
775 m_xAggregateMultiSet->setPropertyValues(_rPropertyNames, _rValues);
776
777 // all properties belong to the aggregating object
778 else if (nAggCount == 0)
779 OPropertySetHelper::setPropertyValues(_rPropertyNames, _rValues);
780
781 // mixed
782 else
783 {
784 const ::com::sun::star::uno::Any* pValues = _rValues.getConstArray();
785 ::com::sun::star::uno::Any* pConvertedValues = NULL;
786 ::com::sun::star::uno::Any* pOldValues = NULL;
787 sal_Int32* pHandles = NULL;
788
789 try
790 {
791 // dividing the Names and _rValues
792
793 // aggregate's names
794 Sequence< ::rtl::OUString > AggPropertyNames( nAggCount );
795 ::rtl::OUString* pAggNames = AggPropertyNames.getArray();
796 // aggregate's values
797 Sequence< Any > AggValues( nAggCount );
798 Any* pAggValues = AggValues.getArray();
799
800 // delegator names
801 Sequence< ::rtl::OUString > DelPropertyNames( nLen - nAggCount );
802 ::rtl::OUString* pDelNames = DelPropertyNames.getArray();
803
804 // delegator values
805 Sequence< Any > DelValues( nLen - nAggCount );
806 Any* pDelValues = DelValues.getArray();
807
808 for ( sal_Int32 i = 0; i < nLen; ++i, ++pNames, ++pValues )
809 {
810 if ( OPropertyArrayAggregationHelper::AGGREGATE_PROPERTY == rPH.classifyProperty( *pNames ) )
811 {
812 *pAggNames++ = *pNames;
813 *pAggValues++ = *pValues;
814 }
815 else
816 {
817 *pDelNames++ = *pNames;
818 *pDelValues++ = *pValues;
819 }
820 }
821
822 // reset, needed below
823 pDelValues = DelValues.getArray();
824
825 pHandles = new sal_Int32[ nLen - nAggCount ];
826
827 // get the map table
828 cppu::IPropertyArrayHelper& rPH2 = getInfoHelper();
829
830 // fill the handle array
831 sal_Int32 nHitCount = rPH2.fillHandles( pHandles, DelPropertyNames );
832 if (nHitCount != 0)
833 {
834
835 pConvertedValues = new ::com::sun::star::uno::Any[ nHitCount ];
836 pOldValues = new ::com::sun::star::uno::Any[ nHitCount ];
837 nHitCount = 0;
838 sal_Int32 i;
839
840 {
841 // must lock the mutex outside the loop. So all values are consistent.
842 osl::MutexGuard aGuard( rBHelper.rMutex );
843 for( i = 0; i < (nLen - nAggCount); ++i )
844 {
845 if( pHandles[i] != -1 )
846 {
847 sal_Int16 nAttributes;
848 rPH2.fillPropertyMembersByHandle( NULL, &nAttributes, pHandles[i] );
849 if( nAttributes & ::com::sun::star::beans::PropertyAttribute::READONLY )
850 throw ::com::sun::star::beans::PropertyVetoException();
851 // Will the property change?
852 if( convertFastPropertyValue( pConvertedValues[ nHitCount ], pOldValues[nHitCount],
853 pHandles[i], pDelValues[i] ) )
854 {
855 // only increment if the property really change
856 pHandles[nHitCount] = pHandles[i];
857 nHitCount++;
858 }
859 }
860 }
861 // release guard to fire events
862 }
863
864 // fire vetoable events
865 fire( pHandles, pConvertedValues, pOldValues, nHitCount, sal_True );
866
867 // setting the agg Properties
868 m_xAggregateMultiSet->setPropertyValues(AggPropertyNames, AggValues);
869
870 {
871 // must lock the mutex outside the loop.
872 osl::MutexGuard aGuard( rBHelper.rMutex );
873 // Loop over all changed properties
874 for( i = 0; i < nHitCount; i++ )
875 {
876 // Will the property change?
877 setFastPropertyValue_NoBroadcast( pHandles[i], pConvertedValues[i] );
878 }
879 // release guard to fire events
880 }
881
882 // fire change events
883 fire( pHandles, pConvertedValues, pOldValues, nHitCount, sal_False );
884 }
885 else
886 m_xAggregateMultiSet->setPropertyValues(AggPropertyNames, AggValues);
887
888 }
889 catch(::com::sun::star::uno::Exception&)
890 {
891 delete [] pHandles;
892 delete [] pOldValues;
893 delete [] pConvertedValues;
894 throw;
895 }
896
897 delete [] pHandles;
898 delete [] pOldValues;
899 delete [] pConvertedValues;
900 }
901 }
902 }
903
904 // XPropertyState
905 //------------------------------------------------------------------------------
getPropertyState(const::rtl::OUString & _rPropertyName)906 ::com::sun::star::beans::PropertyState SAL_CALL OPropertySetAggregationHelper::getPropertyState(const ::rtl::OUString& _rPropertyName)
907 throw( ::com::sun::star::beans::UnknownPropertyException, ::com::sun::star::uno::RuntimeException)
908 {
909 OPropertyArrayAggregationHelper& rPH = static_cast< OPropertyArrayAggregationHelper& >( getInfoHelper() );
910 sal_Int32 nHandle = rPH.getHandleByName( _rPropertyName );
911
912 if (nHandle == -1)
913 {
914 throw ::com::sun::star::beans::UnknownPropertyException();
915 }
916
917 ::rtl::OUString aPropName;
918 sal_Int32 nOriginalHandle = -1;
919 if (rPH.fillAggregatePropertyInfoByHandle(&aPropName, &nOriginalHandle, nHandle))
920 {
921 if (m_xAggregateState.is())
922 return m_xAggregateState->getPropertyState(_rPropertyName);
923 else
924 return ::com::sun::star::beans::PropertyState_DIRECT_VALUE;
925 }
926 else
927 return getPropertyStateByHandle(nHandle);
928 }
929
930 //------------------------------------------------------------------------------
setPropertyToDefault(const::rtl::OUString & _rPropertyName)931 void SAL_CALL OPropertySetAggregationHelper::setPropertyToDefault(const ::rtl::OUString& _rPropertyName)
932 throw( ::com::sun::star::beans::UnknownPropertyException, ::com::sun::star::uno::RuntimeException)
933 {
934 OPropertyArrayAggregationHelper& rPH = static_cast< OPropertyArrayAggregationHelper& >( getInfoHelper() );
935 sal_Int32 nHandle = rPH.getHandleByName(_rPropertyName);
936 if (nHandle == -1)
937 {
938 throw ::com::sun::star::beans::UnknownPropertyException();
939 }
940
941 ::rtl::OUString aPropName;
942 sal_Int32 nOriginalHandle = -1;
943 if (rPH.fillAggregatePropertyInfoByHandle(&aPropName, &nOriginalHandle, nHandle))
944 {
945 if (m_xAggregateState.is())
946 m_xAggregateState->setPropertyToDefault(_rPropertyName);
947 }
948 else
949 {
950 try
951 {
952 setPropertyToDefaultByHandle( nHandle );
953 }
954 catch( const UnknownPropertyException& ) { throw; }
955 catch( const RuntimeException& ) { throw; }
956 catch( const Exception& )
957 {
958 OSL_ENSURE( sal_False, "OPropertySetAggregationHelper::setPropertyToDefault: caught an exception which is not allowed to leave here!" );
959 }
960 }
961 }
962
963 //------------------------------------------------------------------------------
getPropertyDefault(const::rtl::OUString & aPropertyName)964 ::com::sun::star::uno::Any SAL_CALL OPropertySetAggregationHelper::getPropertyDefault(const ::rtl::OUString& aPropertyName)
965 throw( ::com::sun::star::beans::UnknownPropertyException, ::com::sun::star::lang::WrappedTargetException, ::com::sun::star::uno::RuntimeException)
966 {
967 OPropertyArrayAggregationHelper& rPH = static_cast< OPropertyArrayAggregationHelper& >( getInfoHelper() );
968 sal_Int32 nHandle = rPH.getHandleByName( aPropertyName );
969
970 if ( nHandle == -1 )
971 throw ::com::sun::star::beans::UnknownPropertyException();
972
973 ::rtl::OUString aPropName;
974 sal_Int32 nOriginalHandle = -1;
975 if (rPH.fillAggregatePropertyInfoByHandle(&aPropName, &nOriginalHandle, nHandle))
976 {
977 if (m_xAggregateState.is())
978 return m_xAggregateState->getPropertyDefault(aPropertyName);
979 else
980 return ::com::sun::star::uno::Any();
981 }
982 else
983 return getPropertyDefaultByHandle(nHandle);
984 }
985
986 //------------------------------------------------------------------------------
convertFastPropertyValue(Any & _rConvertedValue,Any & _rOldValue,sal_Int32 _nHandle,const Any & _rValue)987 sal_Bool SAL_CALL OPropertySetAggregationHelper::convertFastPropertyValue( Any& _rConvertedValue, Any& _rOldValue, sal_Int32 _nHandle, const Any& _rValue ) throw(IllegalArgumentException)
988 {
989 sal_Bool bModified = sal_False;
990
991 OSL_ENSURE( m_pForwarder->isResponsibleFor( _nHandle ), "OPropertySetAggregationHelper::convertFastPropertyValue: this is no forwarded property - did you use declareForwardedProperty for it?" );
992 if ( m_pForwarder->isResponsibleFor( _nHandle ) )
993 {
994 // need to determine the type of the property for conversion
995 OPropertyArrayAggregationHelper& rPH = static_cast< OPropertyArrayAggregationHelper& >( getInfoHelper() );
996 Property aProperty;
997 OSL_VERIFY( rPH.getPropertyByHandle( _nHandle, aProperty ) );
998
999 Any aCurrentValue;
1000 getFastPropertyValue( aCurrentValue, _nHandle );
1001 bModified = tryPropertyValue( _rConvertedValue, _rOldValue, _rValue, aCurrentValue, aProperty.Type );
1002 }
1003
1004 return bModified;
1005 }
1006
1007 //------------------------------------------------------------------------------
setFastPropertyValue_NoBroadcast(sal_Int32 _nHandle,const Any & _rValue)1008 void SAL_CALL OPropertySetAggregationHelper::setFastPropertyValue_NoBroadcast( sal_Int32 _nHandle, const Any& _rValue ) throw ( Exception )
1009 {
1010 OSL_ENSURE( m_pForwarder->isResponsibleFor( _nHandle ), "OPropertySetAggregationHelper::setFastPropertyValue_NoBroadcast: this is no forwarded property - did you use declareForwardedProperty for it?" );
1011 if ( m_pForwarder->isResponsibleFor( _nHandle ) )
1012 m_pForwarder->doForward( _nHandle, _rValue );
1013 }
1014
1015 //------------------------------------------------------------------------------
declareForwardedProperty(sal_Int32 _nHandle)1016 void OPropertySetAggregationHelper::declareForwardedProperty( sal_Int32 _nHandle )
1017 {
1018 OSL_ENSURE( !m_pForwarder->isResponsibleFor( _nHandle ), "OPropertySetAggregationHelper::declareForwardedProperty: already declared!" );
1019 m_pForwarder->takeResponsibilityFor( _nHandle );
1020 }
1021
1022 //------------------------------------------------------------------------------
forwardingPropertyValue(sal_Int32)1023 void SAL_CALL OPropertySetAggregationHelper::forwardingPropertyValue( sal_Int32 )
1024 {
1025 // not interested in
1026 }
1027
1028 //------------------------------------------------------------------------------
forwardedPropertyValue(sal_Int32,bool)1029 void SAL_CALL OPropertySetAggregationHelper::forwardedPropertyValue( sal_Int32, bool )
1030 {
1031 // not interested in
1032 }
1033
1034 //------------------------------------------------------------------------------
isCurrentlyForwardingProperty(sal_Int32 _nHandle) const1035 bool OPropertySetAggregationHelper::isCurrentlyForwardingProperty( sal_Int32 _nHandle ) const
1036 {
1037 return m_pForwarder->getCurrentlyForwardedProperty() == _nHandle;
1038 }
1039
1040 //.........................................................................
1041 } // namespace comphelper
1042 //.........................................................................
1043
1044