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 <cppuhelper/typeprovider.hxx>
25 #include <com/sun/star/beans/XPropertySet.hpp>
26 #include <com/sun/star/beans/XMultiPropertySet.hpp>
27 #include <com/sun/star/beans/XPropertyState.hpp>
28 #include <com/sun/star/uno/Reference.hxx>
29 #include <tools/solar.h>
33 using com::sun::star::uno::Any
;
34 using com::sun::star::uno::Type
;
35 using com::sun::star::uno::Sequence
;
36 using com::sun::star::uno::Reference
;
37 using com::sun::star::uno::Exception
;
38 using com::sun::star::uno::RuntimeException
;
39 using com::sun::star::lang::IllegalArgumentException
;
40 using com::sun::star::beans::Property
;
41 using com::sun::star::beans::XPropertySetInfo
;
43 PropertyAccessorBase::~PropertyAccessorBase()
47 PropertySetBase::PropertySetBase( )
48 :m_pProperties( NULL
)
52 PropertySetBase::~PropertySetBase( )
54 DELETEZ( m_pProperties
);
57 cppu::IPropertyArrayHelper
& SAL_CALL
PropertySetBase::getInfoHelper()
61 OSL_ENSURE( !m_aProperties
.empty(), "PropertySetBase::getInfoHelper: no registered properties!" );
62 m_pProperties
= new cppu::OPropertyArrayHelper( &m_aProperties
[0], m_aProperties
.size(), sal_False
);
64 return *m_pProperties
;
67 Reference
< XPropertySetInfo
> SAL_CALL
PropertySetBase::getPropertySetInfo( ) throw(RuntimeException
, std::exception
)
69 return cppu::OPropertySetHelper::createPropertySetInfo( getInfoHelper() );
72 void PropertySetBase::registerProperty( const Property
& rProperty
,
73 const ::rtl::Reference
< PropertyAccessorBase
>& rAccessor
)
75 OSL_ENSURE( rAccessor
.get(), "PropertySetBase::registerProperty: invalid property accessor, this will crash!" );
76 m_aAccessors
.insert( PropertyAccessors::value_type( rProperty
.Handle
, rAccessor
) );
78 OSL_ENSURE( rAccessor
->isWriteable()
79 == ( ( rProperty
.Attributes
& com::sun::star::beans::PropertyAttribute::READONLY
) == 0 ),
80 "PropertySetBase::registerProperty: inconsistence!" );
82 m_aProperties
.push_back( rProperty
);
85 void PropertySetBase::notifyAndCachePropertyValue( sal_Int32 nHandle
)
87 ::osl::ClearableMutexGuard
aGuard( GetMutex() );
89 PropertyValueCache::iterator aPos
= m_aCache
.find( nHandle
);
90 if ( aPos
== m_aCache
.end() )
91 { // method has never before been invoked for this property
94 // determine the type of this property
95 ::cppu::IPropertyArrayHelper
& rPropertyMetaData
= getInfoHelper();
97 OSL_VERIFY( rPropertyMetaData
.fillPropertyMembersByHandle( &sPropName
, NULL
, nHandle
) );
98 Property aProperty
= rPropertyMetaData
.getPropertyByName( sPropName
);
99 // default construct a value of this type
100 Any
aEmptyValue( NULL
, aProperty
.Type
);
101 // insert into the cache
102 aPos
= m_aCache
.insert( PropertyValueCache::value_type( nHandle
, aEmptyValue
) ).first
;
104 catch( const Exception
& )
106 OSL_FAIL( "PropertySetBase::notifyAndCachePropertyValue: this is not expected to fail!" );
109 Any aOldValue
= aPos
->second
;
110 // determine the current value
112 getFastPropertyValue( aNewValue
, nHandle
);
113 // remember the old value
114 aPos
->second
= aNewValue
;
117 if ( aNewValue
!= aOldValue
)
118 firePropertyChange( nHandle
, aNewValue
, aOldValue
);
121 void PropertySetBase::initializePropertyValueCache( sal_Int32 nHandle
)
124 getFastPropertyValue( aCurrentValue
, nHandle
);
126 #if OSL_DEBUG_LEVEL > 0
127 ::std::pair
< PropertyValueCache::iterator
, bool > aInsertResult
=
129 m_aCache
.insert( PropertyValueCache::value_type( nHandle
, aCurrentValue
) );
130 OSL_ENSURE( aInsertResult
.second
, "PropertySetBase::initializePropertyValueCache: already cached a value for this property!" );
133 PropertyAccessorBase
& PropertySetBase::locatePropertyHandler( sal_Int32 nHandle
) const
135 PropertyAccessors::const_iterator aPropertyPos
= m_aAccessors
.find( nHandle
);
136 OSL_ENSURE( aPropertyPos
!= m_aAccessors
.end() && aPropertyPos
->second
.get(),
137 "PropertySetBase::locatePropertyHandler: accessor map is corrupted!" );
138 // neither should this be called for handles where there is no accessor, nor should a
139 // NULL accssor be in the map
140 return *aPropertyPos
->second
;
143 sal_Bool SAL_CALL
PropertySetBase::convertFastPropertyValue( Any
& rConvertedValue
, Any
& rOldValue
, sal_Int32 nHandle
,
145 throw (IllegalArgumentException
)
147 PropertyAccessorBase
& rAccessor
= locatePropertyHandler( nHandle
);
148 if ( !rAccessor
.approveValue( rValue
) )
149 throw IllegalArgumentException( OUString(), *this, 0 );
151 rAccessor
.getValue( rOldValue
);
152 if ( rOldValue
!= rValue
)
154 rConvertedValue
= rValue
; // no conversion at all
160 void SAL_CALL
PropertySetBase::setFastPropertyValue_NoBroadcast( sal_Int32 nHandle
, const Any
& rValue
)
161 throw (Exception
, std::exception
)
163 PropertyAccessorBase
& rAccessor
= locatePropertyHandler( nHandle
);
164 rAccessor
.setValue( rValue
);
167 void SAL_CALL
PropertySetBase::getFastPropertyValue( Any
& rValue
, sal_Int32 nHandle
) const
169 PropertyAccessorBase
& rAccessor
= locatePropertyHandler( nHandle
);
170 rAccessor
.getValue( rValue
);
173 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */