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
.getValueType().getTypeClass() == 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 SetPropertyValueByHandle( nHandle
, rValue
);
270 if( !m_bSetNewValuesExplicitlyEvenIfTheyEqualDefault
&& aDefault
.hasValue() && aDefault
== rValue
) //#i98893# don't export defaults to file
271 SetPropertyToDefault( nHandle
);
273 SetPropertyValueByHandle( nHandle
, rValue
);
276 void SAL_CALL
OPropertySet::getFastPropertyValue
278 sal_Int32 nHandle
) const
280 if( GetPropertyValueByHandle( rValue
, nHandle
))
283 // property was not set -> try style
284 uno::Reference
< beans::XFastPropertySet
> xStylePropSet( m_xStyle
, uno::UNO_QUERY
);
285 if( xStylePropSet
.is() )
289 // check if the handle of the style points to the same property
290 // name as the handle in this property set
291 uno::Reference
< beans::XPropertySet
> xPropSet( xStylePropSet
, uno::UNO_QUERY
);
294 uno::Reference
< beans::XPropertySetInfo
> xInfo
= xPropSet
->getPropertySetInfo();
297 // for some reason the virtual method getInfoHelper() is
299 ::cppu::IPropertyArrayHelper
& rPH
=
300 const_cast< OPropertySet
* >( this )->getInfoHelper();
302 // find the Property with Handle nHandle in Style
303 Sequence
< beans::Property
> aProps( xInfo
->getProperties() );
304 sal_Int32 nI
= aProps
.getLength() - 1;
305 while( ( nI
>= 0 ) && nHandle
!= aProps
[ nI
].Handle
)
308 if( nI
>= 0 ) // => nHandle == aProps[nI].Handle
310 // check whether the handle in this property set is
311 // the same as the one in the style
312 beans::Property
aProp( rPH
.getPropertyByName( aProps
[ nI
].Name
) );
313 OSL_ENSURE( nHandle
== aProp
.Handle
,
314 "HandleCheck: Handles for same property differ!" );
316 if( nHandle
== aProp
.Handle
)
318 OSL_ENSURE( aProp
.Type
== aProps
[nI
].Type
,
319 "HandleCheck: Types differ!" );
320 OSL_ENSURE( aProp
.Attributes
== aProps
[nI
].Attributes
,
321 "HandleCheck: Attributes differ!" );
326 OSL_FAIL( "HandleCheck: Handle not found in Style" );
330 OSL_FAIL( "HandleCheck: Invalid XPropertySetInfo returned" );
333 OSL_FAIL( "HandleCheck: XPropertySet not supported" );
336 rValue
= xStylePropSet
->getFastPropertyValue( nHandle
);
340 // there is no style (or the style does not support XFastPropertySet)
341 // => take the default value
344 GetDefaultValue( nHandle
, rValue
);
346 catch( const beans::UnknownPropertyException
& )
353 void OPropertySet::firePropertyChangeEvent()
355 // nothing in base class
358 // ____ XStyleSupplier ____
359 Reference
< style::XStyle
> SAL_CALL
OPropertySet::getStyle()
364 void SAL_CALL
OPropertySet::setStyle( const Reference
< style::XStyle
>& xStyle
)
366 if( ! SetStyle( xStyle
))
367 throw lang::IllegalArgumentException(
369 static_cast< beans::XPropertySet
* >( this ),
373 // ____ XMultiPropertySet ____
374 void SAL_CALL
OPropertySet::setPropertyValues(
375 const Sequence
< OUString
>& PropertyNames
, const Sequence
< Any
>& Values
)
377 ::cppu::OPropertySetHelper::setPropertyValues( PropertyNames
, Values
);
379 firePropertyChangeEvent();
382 // ____ XFastPropertySet ____
383 void SAL_CALL
OPropertySet::setFastPropertyValue( sal_Int32 nHandle
, const Any
& rValue
)
385 ::cppu::OPropertySetHelper::setFastPropertyValue( nHandle
, rValue
);
387 firePropertyChangeEvent();
390 beans::PropertyState
OPropertySet::GetPropertyStateByHandle( sal_Int32 nHandle
) const
392 if( m_aProperties
.end() == m_aProperties
.find( nHandle
))
393 return beans::PropertyState_DEFAULT_VALUE
;
394 return beans::PropertyState_DIRECT_VALUE
;
397 Sequence
< beans::PropertyState
> OPropertySet::GetPropertyStatesByHandle(
398 const std::vector
< sal_Int32
> & aHandles
) const
400 Sequence
< beans::PropertyState
> aResult( aHandles
.size());
402 std::transform( aHandles
.begin(), aHandles
.end(),
404 [this](sal_Int32 nHandle
) { return GetPropertyStateByHandle(nHandle
); });
409 void OPropertySet::SetPropertyToDefault( sal_Int32 nHandle
)
411 auto aFoundIter( m_aProperties
.find( nHandle
) );
413 if( m_aProperties
.end() != aFoundIter
)
415 m_aProperties
.erase( aFoundIter
);
419 void OPropertySet::SetPropertiesToDefault(
420 const std::vector
< sal_Int32
> & aHandles
)
422 for(auto nHandle
: aHandles
)
423 m_aProperties
.erase(nHandle
);
426 void OPropertySet::SetAllPropertiesToDefault()
428 m_aProperties
.clear();
431 bool OPropertySet::GetPropertyValueByHandle(
433 sal_Int32 nHandle
) const
435 bool bResult
= false;
437 auto aFoundIter( m_aProperties
.find( nHandle
) );
439 if( m_aProperties
.end() != aFoundIter
)
441 rValue
= (*aFoundIter
).second
;
448 void OPropertySet::SetPropertyValueByHandle(
449 sal_Int32 nHandle
, const Any
& rValue
)
451 m_aProperties
[ nHandle
] = rValue
;
454 bool OPropertySet::SetStyle( const Reference
< style::XStyle
> & xStyle
)
464 } // namespace property
466 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */