1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
3 * This file is part of the LibreOffice project.
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/.
9 * This file incorporates work covered by the following license notice:
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 .
21 #include "propertysetbase.hxx"
23 #include <com/sun/star/beans/XMultiPropertySet.hpp>
24 #include <com/sun/star/uno/Reference.hxx>
26 using com::sun::star::uno::Any
;
27 using com::sun::star::uno::Reference
;
28 using com::sun::star::uno::Exception
;
29 using com::sun::star::lang::IllegalArgumentException
;
30 using com::sun::star::beans::Property
;
31 using com::sun::star::beans::XPropertySetInfo
;
33 PropertyAccessorBase::~PropertyAccessorBase()
37 PropertySetBase::PropertySetBase( )
41 PropertySetBase::~PropertySetBase( )
45 cppu::IPropertyArrayHelper
& SAL_CALL
PropertySetBase::getInfoHelper()
49 OSL_ENSURE( !m_aProperties
.empty(), "PropertySetBase::getInfoHelper: no registered properties!" );
50 m_pProperties
.reset(new cppu::OPropertyArrayHelper( m_aProperties
.data(), m_aProperties
.size(), false ));
52 return *m_pProperties
;
55 Reference
< XPropertySetInfo
> SAL_CALL
PropertySetBase::getPropertySetInfo( )
57 return cppu::OPropertySetHelper::createPropertySetInfo( getInfoHelper() );
60 void PropertySetBase::registerProperty( const Property
& rProperty
,
61 const ::rtl::Reference
< PropertyAccessorBase
>& rAccessor
)
64 "PropertySetBase::registerProperty: invalid property accessor, this will crash!");
65 m_aAccessors
.emplace( rProperty
.Handle
, rAccessor
);
67 OSL_ENSURE( rAccessor
->isWriteable()
68 == ( ( rProperty
.Attributes
& css::beans::PropertyAttribute::READONLY
) == 0 ),
69 "PropertySetBase::registerProperty: inconsistence!" );
71 m_aProperties
.push_back( rProperty
);
74 void PropertySetBase::notifyAndCachePropertyValue( sal_Int32 nHandle
)
76 ::osl::ClearableMutexGuard
aGuard( GetMutex() );
78 PropertyValueCache::iterator aPos
= m_aCache
.find( nHandle
);
79 if ( aPos
== m_aCache
.end() )
80 { // method has never before been invoked for this property
83 // determine the type of this property
84 ::cppu::IPropertyArrayHelper
& rPropertyMetaData
= getInfoHelper();
86 OSL_VERIFY( rPropertyMetaData
.fillPropertyMembersByHandle( &sPropName
, nullptr, nHandle
) );
87 Property aProperty
= rPropertyMetaData
.getPropertyByName( sPropName
);
88 // default construct a value of this type
89 Any
aEmptyValue( nullptr, aProperty
.Type
);
90 // insert into the cache
91 aPos
= m_aCache
.emplace( nHandle
, aEmptyValue
).first
;
93 catch( const Exception
& )
95 OSL_FAIL( "PropertySetBase::notifyAndCachePropertyValue: this is not expected to fail!" );
98 Any aOldValue
= aPos
->second
;
99 // determine the current value
101 getFastPropertyValue( aNewValue
, nHandle
);
102 // remember the old value
103 aPos
->second
= aNewValue
;
106 if ( aNewValue
!= aOldValue
)
107 firePropertyChange( nHandle
, aNewValue
, aOldValue
);
110 void PropertySetBase::initializePropertyValueCache( sal_Int32 nHandle
)
113 getFastPropertyValue( aCurrentValue
, nHandle
);
115 ::std::pair
< PropertyValueCache::iterator
, bool > aInsertResult
=
116 m_aCache
.emplace( nHandle
, aCurrentValue
);
117 OSL_ENSURE( aInsertResult
.second
, "PropertySetBase::initializePropertyValueCache: already cached a value for this property!" );
120 PropertyAccessorBase
& PropertySetBase::locatePropertyHandler( sal_Int32 nHandle
) const
122 PropertyAccessors::const_iterator aPropertyPos
= m_aAccessors
.find( nHandle
);
123 assert( aPropertyPos
!= m_aAccessors
.end() && aPropertyPos
->second
&&
124 "PropertySetBase::locatePropertyHandler: accessor map is corrupted!" );
125 // neither should this be called for handles where there is no accessor, nor should a
126 // NULL accessor be in the map
127 return *aPropertyPos
->second
;
130 sal_Bool SAL_CALL
PropertySetBase::convertFastPropertyValue( Any
& rConvertedValue
, Any
& rOldValue
, sal_Int32 nHandle
,
133 PropertyAccessorBase
& rAccessor
= locatePropertyHandler( nHandle
);
134 if ( !rAccessor
.approveValue( rValue
) )
135 throw IllegalArgumentException( OUString(), *this, 0 );
137 rAccessor
.getValue( rOldValue
);
138 if ( rOldValue
!= rValue
)
140 rConvertedValue
= rValue
; // no conversion at all
146 void SAL_CALL
PropertySetBase::setFastPropertyValue_NoBroadcast( sal_Int32 nHandle
, const Any
& rValue
)
148 PropertyAccessorBase
& rAccessor
= locatePropertyHandler( nHandle
);
149 rAccessor
.setValue( rValue
);
152 void SAL_CALL
PropertySetBase::getFastPropertyValue( Any
& rValue
, sal_Int32 nHandle
) const
154 PropertyAccessorBase
& rAccessor
= locatePropertyHandler( nHandle
);
155 rAccessor
.getValue( rValue
);
158 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */