Line data Source code
1 : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 : /*
3 : * This file is part of the LibreOffice project.
4 : *
5 : * This Source Code Form is subject to the terms of the Mozilla Public
6 : * License, v. 2.0. If a copy of the MPL was not distributed with this
7 : * file, You can obtain one at http://mozilla.org/MPL/2.0/.
8 : *
9 : * This file incorporates work covered by the following license notice:
10 : *
11 : * Licensed to the Apache Software Foundation (ASF) under one or more
12 : * contributor license agreements. See the NOTICE file distributed
13 : * with this work for additional information regarding copyright
14 : * ownership. The ASF licenses this file to you under the Apache
15 : * License, Version 2.0 (the "License"); you may not use this file
16 : * except in compliance with the License. You may obtain a copy of
17 : * the License at http://www.apache.org/licenses/LICENSE-2.0 .
18 : */
19 :
20 :
21 : #include "opropertybag.hxx"
22 : #include "comphelper_module.hxx"
23 :
24 : #include <com/sun/star/beans/PropertyAttribute.hpp>
25 : #include <com/sun/star/beans/NamedValue.hpp>
26 : #include <com/sun/star/beans/Property.hpp>
27 :
28 : #include <comphelper/namedvaluecollection.hxx>
29 :
30 : #include <cppuhelper/exc_hlp.hxx>
31 : #include <osl/thread.h>
32 :
33 : #include <algorithm>
34 : #include <functional>
35 : #include <iterator>
36 :
37 :
38 : //--------------------------------------------------------------------------
39 : using namespace ::com::sun::star;
40 :
41 119 : void createRegistryInfo_OPropertyBag()
42 : {
43 119 : static ::comphelper::module::OAutoRegistration< ::comphelper::OPropertyBag > aAutoRegistration;
44 119 : }
45 :
46 : //........................................................................
47 : namespace comphelper
48 : {
49 : //........................................................................
50 :
51 : using namespace ::com::sun::star::uno;
52 : using namespace ::com::sun::star::lang;
53 : using namespace ::com::sun::star::beans;
54 : using namespace ::com::sun::star::util;
55 : using namespace ::com::sun::star::container;
56 :
57 : //====================================================================
58 : //= OPropertyBag
59 : //====================================================================
60 : //--------------------------------------------------------------------
61 462 : OPropertyBag::OPropertyBag()
62 462 : :OPropertyBag_PBase( GetBroadcastHelper(), this )
63 : ,::cppu::IEventNotificationHook()
64 : ,m_bAutoAddProperties( false )
65 : ,m_NotifyListeners(m_aMutex)
66 924 : ,m_isModified(false)
67 :
68 : {
69 462 : }
70 :
71 : //--------------------------------------------------------------------
72 914 : OPropertyBag::~OPropertyBag()
73 : {
74 914 : }
75 :
76 : //--------------------------------------------------------------------
77 40856 : IMPLEMENT_FORWARD_XINTERFACE2( OPropertyBag, OPropertyBag_Base, OPropertyBag_PBase )
78 0 : IMPLEMENT_FORWARD_XTYPEPROVIDER2( OPropertyBag, OPropertyBag_Base, OPropertyBag_PBase )
79 :
80 : //--------------------------------------------------------------------
81 119 : Sequence< OUString > OPropertyBag::getSupportedServiceNames_static() throw( RuntimeException )
82 : {
83 119 : Sequence< OUString > aServices(1);
84 119 : aServices[0] = "com.sun.star.beans.PropertyBag";
85 119 : return aServices;
86 : }
87 :
88 : //--------------------------------------------------------------------
89 461 : void SAL_CALL OPropertyBag::initialize( const Sequence< Any >& _rArguments ) throw (Exception, RuntimeException)
90 : {
91 461 : Sequence< Type > aTypes;
92 461 : bool AllowEmptyPropertyName(false);
93 461 : bool AutomaticAddition(false);
94 :
95 922 : if (_rArguments.getLength() == 3
96 431 : && (_rArguments[0] >>= aTypes)
97 431 : && (_rArguments[1] >>= AllowEmptyPropertyName)
98 892 : && (_rArguments[2] >>= AutomaticAddition))
99 : {
100 : ::std::copy(
101 : aTypes.getConstArray(),
102 431 : aTypes.getConstArray() + aTypes.getLength(),
103 : ::std::insert_iterator< TypeBag >( m_aAllowedTypes, m_aAllowedTypes.begin() )
104 862 : );
105 431 : m_bAutoAddProperties = AutomaticAddition;
106 :
107 : } else {
108 30 : ::comphelper::NamedValueCollection aArguments( _rArguments );
109 :
110 30 : if ( aArguments.get_ensureType( "AllowedTypes", aTypes ) )
111 : ::std::copy(
112 : aTypes.getConstArray(),
113 0 : aTypes.getConstArray() + aTypes.getLength(),
114 : ::std::insert_iterator< TypeBag >( m_aAllowedTypes, m_aAllowedTypes.begin() )
115 0 : );
116 :
117 30 : aArguments.get_ensureType( "AutomaticAddition", m_bAutoAddProperties );
118 : aArguments.get_ensureType( "AllowEmptyPropertyName",
119 30 : AllowEmptyPropertyName );
120 : }
121 461 : if (AllowEmptyPropertyName) {
122 : m_aDynamicProperties.setAllowEmptyPropertyName(
123 334 : AllowEmptyPropertyName);
124 461 : }
125 461 : }
126 :
127 : //--------------------------------------------------------------------
128 119 : OUString OPropertyBag::getImplementationName_static() throw( RuntimeException )
129 : {
130 119 : return OUString( "com.sun.star.comp.comphelper.OPropertyBag" );
131 : }
132 :
133 : //--------------------------------------------------------------------
134 462 : Reference< XInterface > SAL_CALL OPropertyBag::Create( SAL_UNUSED_PARAMETER const Reference< XComponentContext >& )
135 : {
136 462 : return *new OPropertyBag;
137 : }
138 :
139 : //--------------------------------------------------------------------
140 0 : OUString SAL_CALL OPropertyBag::getImplementationName() throw (RuntimeException)
141 : {
142 0 : return getImplementationName_static();
143 : }
144 :
145 : //--------------------------------------------------------------------
146 0 : ::sal_Bool SAL_CALL OPropertyBag::supportsService( const OUString& rServiceName ) throw (RuntimeException)
147 : {
148 0 : Sequence< OUString > aServices( getSupportedServiceNames_static() );
149 0 : const OUString* pStart = aServices.getConstArray();
150 0 : const OUString* pEnd = aServices.getConstArray() + aServices.getLength();
151 0 : return ::std::find( pStart, pEnd, rServiceName ) != pEnd;
152 : }
153 :
154 : //--------------------------------------------------------------------
155 0 : Sequence< OUString > SAL_CALL OPropertyBag::getSupportedServiceNames( ) throw (RuntimeException)
156 : {
157 0 : return getSupportedServiceNames_static();
158 : }
159 :
160 : //--------------------------------------------------------------------
161 24 : void OPropertyBag::fireEvents(
162 : sal_Int32 * /*pnHandles*/,
163 : sal_Int32 nCount,
164 : sal_Bool bVetoable,
165 : bool bIgnoreRuntimeExceptionsWhileFiring)
166 : {
167 24 : if (nCount && !bVetoable) {
168 13 : setModifiedImpl(sal_True, bIgnoreRuntimeExceptionsWhileFiring);
169 : }
170 24 : }
171 :
172 6122 : void OPropertyBag::setModifiedImpl(::sal_Bool bModified,
173 : bool bIgnoreRuntimeExceptionsWhileFiring)
174 : {
175 : { // do not lock mutex while notifying (#i93514#) to prevent deadlock
176 6122 : ::osl::MutexGuard aGuard( m_aMutex );
177 6122 : m_isModified = bModified;
178 : }
179 6122 : if (bModified) {
180 : try {
181 6122 : Reference<XInterface> xThis(*this);
182 12244 : EventObject event(xThis);
183 : m_NotifyListeners.notifyEach(
184 12244 : &XModifyListener::modified, event);
185 0 : } catch (RuntimeException &) {
186 0 : if (!bIgnoreRuntimeExceptionsWhileFiring) {
187 0 : throw;
188 : }
189 0 : } catch (Exception &) {
190 : // ignore
191 : }
192 : }
193 6122 : }
194 :
195 : //--------------------------------------------------------------------
196 0 : ::sal_Bool SAL_CALL OPropertyBag::isModified()
197 : throw (RuntimeException)
198 : {
199 0 : ::osl::MutexGuard aGuard( m_aMutex );
200 0 : return m_isModified;
201 : }
202 :
203 6109 : void SAL_CALL OPropertyBag::setModified( ::sal_Bool bModified )
204 : throw (PropertyVetoException, RuntimeException)
205 : {
206 6109 : setModifiedImpl(bModified, false);
207 6109 : }
208 :
209 284 : void SAL_CALL OPropertyBag::addModifyListener(
210 : const Reference< XModifyListener > & xListener)
211 : throw (RuntimeException)
212 : {
213 284 : m_NotifyListeners.addInterface(xListener);
214 284 : }
215 :
216 1 : void SAL_CALL OPropertyBag::removeModifyListener(
217 : const Reference< XModifyListener > & xListener)
218 : throw (RuntimeException)
219 : {
220 1 : m_NotifyListeners.removeInterface(xListener);
221 1 : }
222 :
223 : //--------------------------------------------------------------------
224 437 : Reference< XPropertySetInfo > SAL_CALL OPropertyBag::getPropertySetInfo( ) throw(RuntimeException)
225 : {
226 437 : return createPropertySetInfo( getInfoHelper() );
227 : }
228 :
229 : //--------------------------------------------------------------------
230 0 : ::sal_Bool SAL_CALL OPropertyBag::has( const Any& /*aElement*/ ) throw (RuntimeException)
231 : {
232 : // XSet is only a workaround for addProperty not being able to add default-void properties.
233 : // So, everything of XSet except insert is implemented empty
234 0 : return sal_False;
235 : }
236 :
237 : //--------------------------------------------------------------------
238 291 : void SAL_CALL OPropertyBag::insert( const Any& _element ) throw (IllegalArgumentException, ElementExistException, RuntimeException)
239 : {
240 : // This is a workaround for addProperty not being able to add default-void properties.
241 : // If we ever have a smarter XPropertyContainer::addProperty interface, we can remove this, ehm, well, hack.
242 291 : Property aProperty;
243 291 : if ( !( _element >>= aProperty ) )
244 0 : throw IllegalArgumentException( OUString(), *this, 1 );
245 :
246 582 : ::osl::ClearableMutexGuard g( m_aMutex );
247 :
248 : // check whether the type is allowed, everything else will be checked
249 : // by m_aDynamicProperties
250 873 : if ( !m_aAllowedTypes.empty()
251 1164 : && m_aAllowedTypes.find( aProperty.Type ) == m_aAllowedTypes.end()
252 : )
253 0 : throw IllegalTypeException( OUString(), *this );
254 :
255 291 : m_aDynamicProperties.addVoidProperty( aProperty.Name, aProperty.Type, findFreeHandle(), aProperty.Attributes );
256 :
257 : // our property info is dirty
258 291 : m_pArrayHelper.reset();
259 :
260 291 : g.clear();
261 582 : setModified(sal_True);
262 291 : }
263 :
264 : //--------------------------------------------------------------------
265 0 : void SAL_CALL OPropertyBag::remove( const Any& /*aElement*/ ) throw (IllegalArgumentException, NoSuchElementException, RuntimeException)
266 : {
267 : // XSet is only a workaround for addProperty not being able to add default-void properties.
268 : // So, everything of XSet except insert is implemented empty
269 0 : throw NoSuchElementException( OUString(), *this );
270 : }
271 :
272 :
273 : //--------------------------------------------------------------------
274 0 : Reference< XEnumeration > SAL_CALL OPropertyBag::createEnumeration( ) throw (RuntimeException)
275 : {
276 : // XSet is only a workaround for addProperty not being able to add default-void properties.
277 : // So, everything of XSet except insert is implemented empty
278 0 : return NULL;
279 : }
280 :
281 : //--------------------------------------------------------------------
282 0 : Type SAL_CALL OPropertyBag::getElementType( ) throw (RuntimeException)
283 : {
284 : // XSet is only a workaround for addProperty not being able to add default-void properties.
285 : // So, everything of XSet except insert is implemented empty
286 0 : return Type();
287 : }
288 :
289 : //--------------------------------------------------------------------
290 0 : ::sal_Bool SAL_CALL OPropertyBag::hasElements( ) throw (RuntimeException)
291 : {
292 : // XSet is only a workaround for addProperty not being able to add default-void properties.
293 : // So, everything of XSet except insert is implemented empty
294 0 : return sal_False;
295 : }
296 :
297 : //--------------------------------------------------------------------
298 24663 : void SAL_CALL OPropertyBag::getFastPropertyValue( Any& _rValue, sal_Int32 _nHandle ) const
299 : {
300 24663 : m_aDynamicProperties.getFastPropertyValue( _nHandle, _rValue );
301 24663 : }
302 :
303 : //--------------------------------------------------------------------
304 486 : sal_Bool SAL_CALL OPropertyBag::convertFastPropertyValue( Any& _rConvertedValue, Any& _rOldValue, sal_Int32 _nHandle, const Any& _rValue ) throw (IllegalArgumentException)
305 : {
306 486 : return m_aDynamicProperties.convertFastPropertyValue( _nHandle, _rValue, _rConvertedValue, _rOldValue );
307 : }
308 :
309 : //--------------------------------------------------------------------
310 23 : void SAL_CALL OPropertyBag::setFastPropertyValue_NoBroadcast( sal_Int32 nHandle, const Any& rValue ) throw (Exception)
311 : {
312 23 : m_aDynamicProperties.setFastPropertyValue( nHandle, rValue );
313 23 : }
314 :
315 : //--------------------------------------------------------------------
316 28644 : ::cppu::IPropertyArrayHelper& SAL_CALL OPropertyBag::getInfoHelper()
317 : {
318 28644 : if ( !m_pArrayHelper.get() )
319 : {
320 288 : Sequence< Property > aProperties;
321 288 : m_aDynamicProperties.describeProperties( aProperties );
322 288 : m_pArrayHelper.reset( new ::cppu::OPropertyArrayHelper( aProperties ) );
323 : }
324 28644 : return *m_pArrayHelper;
325 :
326 : }
327 :
328 : //--------------------------------------------------------------------
329 6108 : sal_Int32 OPropertyBag::findFreeHandle() const
330 : {
331 6108 : const sal_Int32 nPrime = 1009;
332 6108 : const sal_Int32 nSeed = 11;
333 :
334 6108 : sal_Int32 nCheck = nSeed;
335 148308 : while ( m_aDynamicProperties.hasPropertyByHandle( nCheck ) && ( nCheck != 1 ) )
336 : {
337 136092 : nCheck = ( nCheck * nSeed ) % nPrime;
338 : }
339 :
340 6108 : if ( nCheck == 1 )
341 : { // uh ... we already have 1008 handles used up
342 : // -> simply count upwards
343 0 : while ( m_aDynamicProperties.hasPropertyByHandle( nCheck ) )
344 0 : ++nCheck;
345 : }
346 :
347 6108 : return nCheck;
348 : }
349 :
350 : //--------------------------------------------------------------------
351 5818 : void SAL_CALL OPropertyBag::addProperty( const OUString& _rName, ::sal_Int16 _nAttributes, const Any& _rInitialValue ) throw (PropertyExistException, IllegalTypeException, IllegalArgumentException, RuntimeException)
352 : {
353 5818 : ::osl::ClearableMutexGuard g( m_aMutex );
354 :
355 : // check whether the type is allowed, everything else will be checked
356 : // by m_aDynamicProperties
357 11636 : Type aPropertyType = _rInitialValue.getValueType();
358 17497 : if ( _rInitialValue.hasValue()
359 5818 : && !m_aAllowedTypes.empty()
360 29004 : && m_aAllowedTypes.find( aPropertyType ) == m_aAllowedTypes.end()
361 : )
362 1 : throw IllegalTypeException( OUString(), *this );
363 :
364 5817 : m_aDynamicProperties.addProperty( _rName, findFreeHandle(), _nAttributes, _rInitialValue );
365 :
366 : // our property info is dirty
367 5815 : m_pArrayHelper.reset();
368 :
369 5815 : g.clear();
370 11633 : setModified(sal_True);
371 5815 : }
372 :
373 : //--------------------------------------------------------------------
374 5 : void SAL_CALL OPropertyBag::removeProperty( const OUString& _rName ) throw (UnknownPropertyException, NotRemoveableException, RuntimeException)
375 : {
376 5 : ::osl::ClearableMutexGuard g( m_aMutex );
377 :
378 5 : m_aDynamicProperties.removeProperty( _rName );
379 :
380 : // our property info is dirty
381 3 : m_pArrayHelper.reset();
382 :
383 3 : g.clear();
384 5 : setModified(sal_True);
385 3 : }
386 :
387 : //--------------------------------------------------------------------
388 : namespace
389 : {
390 : struct ComparePropertyValueByName : public ::std::binary_function< PropertyValue, PropertyValue, bool >
391 : {
392 279 : bool operator()( const PropertyValue& _rLHS, const PropertyValue& _rRHS )
393 : {
394 279 : return _rLHS.Name < _rRHS.Name;
395 : }
396 : };
397 :
398 : template< typename CLASS >
399 : struct TransformPropertyToName : public ::std::unary_function< CLASS, OUString >
400 : {
401 7683 : const OUString& operator()( const CLASS& _rProp )
402 : {
403 7683 : return _rProp.Name;
404 : }
405 : };
406 :
407 : struct ExtractPropertyValue : public ::std::unary_function< PropertyValue, Any >
408 : {
409 97 : const Any& operator()( const PropertyValue& _rProp )
410 : {
411 97 : return _rProp.Value;
412 : }
413 : };
414 : }
415 :
416 : //--------------------------------------------------------------------
417 144 : Sequence< PropertyValue > SAL_CALL OPropertyBag::getPropertyValues( ) throw (RuntimeException)
418 : {
419 144 : ::osl::MutexGuard aGuard( m_aMutex );
420 :
421 : // all registered properties
422 288 : Sequence< Property > aProperties;
423 144 : m_aDynamicProperties.describeProperties( aProperties );
424 :
425 : // their names
426 288 : Sequence< OUString > aNames( aProperties.getLength() );
427 : ::std::transform(
428 : aProperties.getConstArray(),
429 144 : aProperties.getConstArray() + aProperties.getLength(),
430 : aNames.getArray(),
431 : TransformPropertyToName< Property >()
432 288 : );
433 :
434 : // their values
435 288 : Sequence< Any > aValues;
436 : try
437 : {
438 144 : aValues = OPropertyBag_PBase::getPropertyValues( aNames );
439 144 : if ( aValues.getLength() != aNames.getLength() )
440 0 : throw RuntimeException();
441 : }
442 0 : catch( const RuntimeException& )
443 : {
444 0 : throw;
445 : }
446 0 : catch( const Exception& )
447 : {
448 : // ignore
449 : }
450 :
451 : // merge names and values, and retrieve the state/handle
452 144 : ::cppu::IPropertyArrayHelper& rPropInfo = getInfoHelper();
453 :
454 144 : Sequence< PropertyValue > aPropertyValues( aNames.getLength() );
455 144 : const OUString* pName = aNames.getConstArray();
456 144 : const OUString* pNamesEnd = aNames.getConstArray() + aNames.getLength();
457 144 : const Any* pValue = aValues.getArray();
458 144 : PropertyValue* pPropertyValue = aPropertyValues.getArray();
459 :
460 7727 : for ( ; pName != pNamesEnd; ++pName, ++pValue, ++pPropertyValue )
461 : {
462 7583 : pPropertyValue->Name = *pName;
463 7583 : pPropertyValue->Handle = rPropInfo.getHandleByName( *pName );
464 7583 : pPropertyValue->Value = *pValue;
465 7583 : pPropertyValue->State = getPropertyStateByHandle( pPropertyValue->Handle );
466 : }
467 :
468 288 : return aPropertyValues;
469 : }
470 :
471 : //--------------------------------------------------------------------
472 12 : void OPropertyBag::impl_setPropertyValues_throw( const Sequence< PropertyValue >& _rProps )
473 : {
474 : // sort (the XMultiPropertySet interface requires this)
475 12 : Sequence< PropertyValue > aProperties( _rProps );
476 : ::std::sort(
477 : aProperties.getArray(),
478 12 : aProperties.getArray() + aProperties.getLength(),
479 : ComparePropertyValueByName()
480 12 : );
481 :
482 : // a sequence of names
483 24 : Sequence< OUString > aNames( aProperties.getLength() );
484 : ::std::transform(
485 : aProperties.getConstArray(),
486 12 : aProperties.getConstArray() + aProperties.getLength(),
487 : aNames.getArray(),
488 : TransformPropertyToName< PropertyValue >()
489 24 : );
490 :
491 : try
492 : {
493 : // check for unknown properties
494 : // we cannot simply rely on the XMultiPropertySet::setPropertyValues
495 : // implementation of our base class, since it does not throw
496 : // an UnknownPropertyException. More precise, XMultiPropertySet::setPropertyValues
497 : // does not allow to throw this exception, while XPropertyAccess::setPropertyValues
498 : // requires it
499 12 : sal_Int32 nCount = aNames.getLength();
500 :
501 12 : Sequence< sal_Int32 > aHandles( nCount );
502 12 : sal_Int32* pHandle = aHandles.getArray();
503 12 : const PropertyValue* pProperty = aProperties.getConstArray();
504 220 : for ( const OUString* pName = aNames.getConstArray();
505 110 : pName != aNames.getConstArray() + aNames.getLength();
506 : ++pName, ++pHandle, ++pProperty
507 : )
508 : {
509 99 : ::cppu::IPropertyArrayHelper& rPropInfo = getInfoHelper();
510 99 : *pHandle = rPropInfo.getHandleByName( *pName );
511 99 : if ( *pHandle != -1 )
512 97 : continue;
513 :
514 : // there's a property requested which we do not know
515 2 : if ( m_bAutoAddProperties )
516 : {
517 : // add the property
518 1 : sal_Int16 nAttributes = PropertyAttribute::BOUND | PropertyAttribute::REMOVABLE | PropertyAttribute::MAYBEDEFAULT;
519 1 : addProperty( *pName, nAttributes, pProperty->Value );
520 1 : continue;
521 : }
522 :
523 : // no way out
524 1 : throw UnknownPropertyException( *pName, *this );
525 : }
526 :
527 : // a sequence of values
528 22 : Sequence< Any > aValues( aProperties.getLength() );
529 : ::std::transform(
530 : aProperties.getConstArray(),
531 11 : aProperties.getConstArray() + aProperties.getLength(),
532 : aValues.getArray(),
533 : ExtractPropertyValue()
534 22 : );
535 :
536 23 : setFastPropertyValues( nCount, aHandles.getArray(), aValues.getConstArray(), nCount );
537 : }
538 0 : catch( const PropertyVetoException& ) { throw; }
539 0 : catch( const IllegalArgumentException& ) { throw; }
540 0 : catch( const WrappedTargetException& ) { throw; }
541 0 : catch( const RuntimeException& ) { throw; }
542 2 : catch( const UnknownPropertyException& ) { throw; }
543 0 : catch( const Exception& )
544 : {
545 0 : throw WrappedTargetException( OUString(), *this, ::cppu::getCaughtException() );
546 12 : }
547 11 : }
548 :
549 : //--------------------------------------------------------------------
550 12 : void SAL_CALL OPropertyBag::setPropertyValues( const Sequence< PropertyValue >& _rProps ) throw (UnknownPropertyException, PropertyVetoException, IllegalArgumentException, WrappedTargetException, RuntimeException)
551 : {
552 12 : ::osl::MutexGuard aGuard( m_aMutex );
553 13 : impl_setPropertyValues_throw( _rProps );
554 11 : }
555 :
556 : //--------------------------------------------------------------------
557 11237 : PropertyState OPropertyBag::getPropertyStateByHandle( sal_Int32 _nHandle )
558 : {
559 : // for properties which do not support the MAYBEDEFAULT attribute, don't rely on the base class, but
560 : // assume they're always in DIRECT state.
561 : // (Note that this probably would belong into the base class. However, this would mean we would need
562 : // to check all existent usages of the base class, where MAYBEDEFAULT is *not* set, but
563 : // a default is nonetheless supplied/used. This is hard to accomplish reliably, in the
564 : // current phase.
565 : // #i78593# / 2007-07-07 / frank.schoenheit@sun.com
566 :
567 11237 : ::cppu::IPropertyArrayHelper& rPropInfo = getInfoHelper();
568 11237 : sal_Int16 nAttributes(0);
569 11237 : OSL_VERIFY( rPropInfo.fillPropertyMembersByHandle( NULL, &nAttributes, _nHandle ) );
570 11237 : if ( ( nAttributes & PropertyAttribute::MAYBEDEFAULT ) == 0 )
571 4 : return PropertyState_DIRECT_VALUE;
572 :
573 11233 : return OPropertyBag_PBase::getPropertyStateByHandle( _nHandle );
574 : }
575 :
576 : //--------------------------------------------------------------------
577 11968 : Any OPropertyBag::getPropertyDefaultByHandle( sal_Int32 _nHandle ) const
578 : {
579 11968 : Any aDefault;
580 11968 : m_aDynamicProperties.getPropertyDefaultByHandle( _nHandle, aDefault );
581 11968 : return aDefault;
582 : }
583 :
584 : //........................................................................
585 : } // namespace comphelper
586 : //........................................................................
587 :
588 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|