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 .
20 #include <OPropertySet.hxx>
21 #include <CloneHelper.hxx>
22 #include <cppuhelper/queryinterface.hxx>
23 #include <com/sun/star/uno/Sequence.hxx>
24 #include <com/sun/star/style/XStyle.hpp>
29 using namespace ::com::sun::star
;
31 using ::com::sun::star::uno::Reference
;
32 using ::com::sun::star::uno::Sequence
;
33 using ::com::sun::star::uno::Any
;
34 using ::osl::MutexGuard
;
36 // needed for MS compiler
37 using ::cppu::OBroadcastHelper
;
38 using ::cppu::OPropertySetHelper
;
43 OPropertySet::OPropertySet( ) :
44 OBroadcastHelper( m_aMutex
),
45 // the following causes a warning; there seems to be no way to avoid it
46 OPropertySetHelper( static_cast< OBroadcastHelper
& >( *this )),
47 m_bSetNewValuesExplicitlyEvenIfTheyEqualDefault(false)
51 OPropertySet::OPropertySet( const OPropertySet
& rOther
) :
52 OBroadcastHelper( m_aMutex
),
53 // the following causes a warning; there seems to be no way to avoid it
54 OPropertySetHelper( static_cast< OBroadcastHelper
& >( *this )),
55 css::lang::XTypeProvider(),
56 css::beans::XPropertyState(),
57 css::beans::XMultiPropertyStates(),
58 css::style::XStyleSupplier(),
59 m_bSetNewValuesExplicitlyEvenIfTheyEqualDefault(false)
61 MutexGuard
aGuard( m_aMutex
);
63 m_aProperties
= rOther
.m_aProperties
;
65 // clone interface properties
66 for(auto& rProp
: m_aProperties
)
68 if( rProp
.second
.hasValue() &&
69 rProp
.second
.getValueTypeClass() == uno::TypeClass_INTERFACE
)
71 Reference
< util::XCloneable
> xCloneable
;
72 if( rProp
.second
>>= xCloneable
)
73 rProp
.second
<<= xCloneable
->createClone();
77 m_xStyle
.set( ::chart::CloneHelper::CreateRefClone
< style::XStyle
>()( rOther
.m_xStyle
));
80 void OPropertySet::SetNewValuesExplicitlyEvenIfTheyEqualDefault()
82 m_bSetNewValuesExplicitlyEvenIfTheyEqualDefault
= true;
85 OPropertySet::~OPropertySet()
88 Any SAL_CALL
OPropertySet::queryInterface( const uno::Type
& aType
)
90 return ::cppu::queryInterface(
92 static_cast< lang::XTypeProvider
* >( this ),
93 static_cast< beans::XPropertySet
* >( this ),
94 static_cast< beans::XMultiPropertySet
* >( this ),
95 static_cast< beans::XFastPropertySet
* >( this ),
96 static_cast< beans::XPropertyState
* >( this ),
97 static_cast< beans::XMultiPropertyStates
* >( this ),
98 static_cast< style::XStyleSupplier
* >( this ) );
101 // ____ XTypeProvider ____
102 Sequence
< uno::Type
> SAL_CALL
103 OPropertySet::getTypes()
105 static const Sequence
< uno::Type
> aTypeList
{
106 cppu::UnoType
<lang::XTypeProvider
>::get(),
107 cppu::UnoType
<beans::XPropertySet
>::get(),
108 cppu::UnoType
<beans::XMultiPropertySet
>::get(),
109 cppu::UnoType
<beans::XFastPropertySet
>::get(),
110 cppu::UnoType
<beans::XPropertyState
>::get(),
111 cppu::UnoType
<beans::XMultiPropertyStates
>::get(),
112 cppu::UnoType
<style::XStyleSupplier
>::get() };
117 Sequence
< sal_Int8
> SAL_CALL
118 OPropertySet::getImplementationId()
120 return css::uno::Sequence
<sal_Int8
>();
123 // ____ XPropertyState ____
124 beans::PropertyState SAL_CALL
125 OPropertySet::getPropertyState( const OUString
& PropertyName
)
127 cppu::IPropertyArrayHelper
& rPH
= getInfoHelper();
129 return GetPropertyStateByHandle(
130 rPH
.getHandleByName( PropertyName
));
133 Sequence
< beans::PropertyState
> SAL_CALL
134 OPropertySet::getPropertyStates( const Sequence
< OUString
>& aPropertyName
)
136 cppu::IPropertyArrayHelper
& rPH
= getInfoHelper();
138 std::unique_ptr
<sal_Int32
[]> pHandles(new sal_Int32
[ aPropertyName
.getLength() ]);
139 rPH
.fillHandles( pHandles
.get(), aPropertyName
);
141 std::vector
< sal_Int32
> aHandles( pHandles
.get(), pHandles
.get() + aPropertyName
.getLength());
144 return GetPropertyStatesByHandle( aHandles
);
148 OPropertySet::setPropertyToDefault( const OUString
& PropertyName
)
150 cppu::IPropertyArrayHelper
& rPH
= getInfoHelper();
152 SetPropertyToDefault( rPH
.getHandleByName( PropertyName
));
153 firePropertyChangeEvent();
157 OPropertySet::getPropertyDefault( const OUString
& aPropertyName
)
159 cppu::IPropertyArrayHelper
& rPH
= getInfoHelper();
162 GetDefaultValue( rPH
.getHandleByName( aPropertyName
), any
);
166 // ____ XMultiPropertyStates ____
168 // Note: getPropertyStates() is already implemented in XPropertyState with the
172 OPropertySet::setAllPropertiesToDefault()
174 SetAllPropertiesToDefault();
175 firePropertyChangeEvent();
179 OPropertySet::setPropertiesToDefault( const Sequence
< OUString
>& aPropertyNames
)
181 cppu::IPropertyArrayHelper
& rPH
= getInfoHelper();
183 std::unique_ptr
<sal_Int32
[]> pHandles(new sal_Int32
[ aPropertyNames
.getLength() ]);
184 rPH
.fillHandles( pHandles
.get(), aPropertyNames
);
186 std::vector
< sal_Int32
> aHandles( pHandles
.get(), pHandles
.get() + aPropertyNames
.getLength());
189 SetPropertiesToDefault( aHandles
);
192 Sequence
< Any
> SAL_CALL
193 OPropertySet::getPropertyDefaults( const Sequence
< OUString
>& aPropertyNames
)
195 ::cppu::IPropertyArrayHelper
& rPH
= getInfoHelper();
196 const sal_Int32 nElements
= aPropertyNames
.getLength();
198 Sequence
< Any
> aResult( nElements
);
199 Any
* pResultArray
= aResult
.getArray();
202 for( ; nI
< nElements
; ++nI
)
205 rPH
.getHandleByName( aPropertyNames
[ nI
] ),
212 sal_Bool SAL_CALL
OPropertySet::convertFastPropertyValue
213 ( Any
& rConvertedValue
,
218 getFastPropertyValue( rOldValue
, nHandle
);
219 //accept longs also for short values
222 if( (rOldValue
>>=nValue
) && !(rValue
>>=nValue
) )
224 sal_Int32 n32Value
= 0;
225 if( rValue
>>=n32Value
)
227 rConvertedValue
<<= static_cast<sal_Int16
>(n32Value
);
231 sal_Int64 n64Value
= 0;
232 if( rValue
>>=n64Value
)
234 rConvertedValue
<<= static_cast<sal_Int16
>(n64Value
);
239 rConvertedValue
= rValue
;
240 if( !m_bSetNewValuesExplicitlyEvenIfTheyEqualDefault
&& rOldValue
== rConvertedValue
)
241 return false;//no change necessary
245 void SAL_CALL
OPropertySet::setFastPropertyValue_NoBroadcast
249 #if OSL_DEBUG_LEVEL > 0
250 if( rValue
.hasValue())
252 cppu::IPropertyArrayHelper
& rPH
= getInfoHelper();
254 rPH
.fillPropertyMembersByHandle( &aName
, nullptr, nHandle
);
255 OSL_ENSURE( rValue
.isExtractableTo( rPH
.getPropertyByName( aName
).Type
),
256 "Property type is wrong" );
263 GetDefaultValue( nHandle
, aDefault
);
265 catch( const beans::UnknownPropertyException
& )
269 if( !m_bSetNewValuesExplicitlyEvenIfTheyEqualDefault
&& aDefault
.hasValue() && aDefault
== rValue
) //#i98893# don't export defaults to file
270 SetPropertyToDefault( nHandle
);
272 SetPropertyValueByHandle( nHandle
, rValue
);
275 void SAL_CALL
OPropertySet::getFastPropertyValue
277 sal_Int32 nHandle
) const
279 if( GetPropertyValueByHandle( rValue
, nHandle
))
282 // property was not set -> try style
283 uno::Reference
< beans::XFastPropertySet
> xStylePropSet( m_xStyle
, uno::UNO_QUERY
);
284 if( xStylePropSet
.is() )
288 // check if the handle of the style points to the same property
289 // name as the handle in this property set
290 uno::Reference
< beans::XPropertySet
> xPropSet( xStylePropSet
, uno::UNO_QUERY
);
293 uno::Reference
< beans::XPropertySetInfo
> xInfo
= xPropSet
->getPropertySetInfo();
296 // for some reason the virtual method getInfoHelper() is
298 ::cppu::IPropertyArrayHelper
& rPH
=
299 const_cast< OPropertySet
* >( this )->getInfoHelper();
301 // find the Property with Handle nHandle in Style
302 Sequence
< beans::Property
> aProps( xInfo
->getProperties() );
303 sal_Int32 nI
= aProps
.getLength() - 1;
304 while( ( nI
>= 0 ) && nHandle
!= aProps
[ nI
].Handle
)
307 if( nI
>= 0 ) // => nHandle == aProps[nI].Handle
309 // check whether the handle in this property set is
310 // the same as the one in the style
311 beans::Property
aProp( rPH
.getPropertyByName( aProps
[ nI
].Name
) );
312 OSL_ENSURE( nHandle
== aProp
.Handle
,
313 "HandleCheck: Handles for same property differ!" );
315 if( nHandle
== aProp
.Handle
)
317 OSL_ENSURE( aProp
.Type
== aProps
[nI
].Type
,
318 "HandleCheck: Types differ!" );
319 OSL_ENSURE( aProp
.Attributes
== aProps
[nI
].Attributes
,
320 "HandleCheck: Attributes differ!" );
325 OSL_FAIL( "HandleCheck: Handle not found in Style" );
329 OSL_FAIL( "HandleCheck: Invalid XPropertySetInfo returned" );
332 OSL_FAIL( "HandleCheck: XPropertySet not supported" );
335 rValue
= xStylePropSet
->getFastPropertyValue( nHandle
);
339 // there is no style (or the style does not support XFastPropertySet)
340 // => take the default value
343 GetDefaultValue( nHandle
, rValue
);
345 catch( const beans::UnknownPropertyException
& )
352 void OPropertySet::firePropertyChangeEvent()
354 // nothing in base class
357 // ____ XStyleSupplier ____
358 Reference
< style::XStyle
> SAL_CALL
OPropertySet::getStyle()
363 void SAL_CALL
OPropertySet::setStyle( const Reference
< style::XStyle
>& xStyle
)
365 if( ! SetStyle( xStyle
))
366 throw lang::IllegalArgumentException(
368 static_cast< beans::XPropertySet
* >( this ),
372 // ____ XMultiPropertySet ____
373 void SAL_CALL
OPropertySet::setPropertyValues(
374 const Sequence
< OUString
>& PropertyNames
, const Sequence
< Any
>& Values
)
376 ::cppu::OPropertySetHelper::setPropertyValues( PropertyNames
, Values
);
378 firePropertyChangeEvent();
381 // ____ XFastPropertySet ____
382 void SAL_CALL
OPropertySet::setFastPropertyValue( sal_Int32 nHandle
, const Any
& rValue
)
384 ::cppu::OPropertySetHelper::setFastPropertyValue( nHandle
, rValue
);
386 firePropertyChangeEvent();
389 beans::PropertyState
OPropertySet::GetPropertyStateByHandle( sal_Int32 nHandle
) const
391 if( m_aProperties
.end() == m_aProperties
.find( nHandle
))
392 return beans::PropertyState_DEFAULT_VALUE
;
393 return beans::PropertyState_DIRECT_VALUE
;
396 Sequence
< beans::PropertyState
> OPropertySet::GetPropertyStatesByHandle(
397 const std::vector
< sal_Int32
> & aHandles
) const
399 Sequence
< beans::PropertyState
> aResult( aHandles
.size());
401 std::transform( aHandles
.begin(), aHandles
.end(),
403 [this](sal_Int32 nHandle
) { return GetPropertyStateByHandle(nHandle
); });
408 void OPropertySet::SetPropertyToDefault( sal_Int32 nHandle
)
410 auto aFoundIter( m_aProperties
.find( nHandle
) );
412 if( m_aProperties
.end() != aFoundIter
)
414 m_aProperties
.erase( aFoundIter
);
418 void OPropertySet::SetPropertiesToDefault(
419 const std::vector
< sal_Int32
> & aHandles
)
421 for(auto nHandle
: aHandles
)
422 m_aProperties
.erase(nHandle
);
425 void OPropertySet::SetAllPropertiesToDefault()
427 m_aProperties
.clear();
430 bool OPropertySet::GetPropertyValueByHandle(
432 sal_Int32 nHandle
) const
434 bool bResult
= false;
436 auto aFoundIter( m_aProperties
.find( nHandle
) );
438 if( m_aProperties
.end() != aFoundIter
)
440 rValue
= (*aFoundIter
).second
;
447 void OPropertySet::SetPropertyValueByHandle(
448 sal_Int32 nHandle
, const Any
& rValue
)
450 m_aProperties
[ nHandle
] = rValue
;
453 bool OPropertySet::SetStyle( const Reference
< style::XStyle
> & xStyle
)
463 } // namespace property
465 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */