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 <comphelper/property.hxx>
21 #include <comphelper/sequence.hxx>
22 #include <osl/diagnose.h>
23 #include <sal/log.hxx>
24 #include <comphelper/diagnose_ex.hxx>
26 #if OSL_DEBUG_LEVEL > 0
27 #include <cppuhelper/exc_hlp.hxx>
28 #include <com/sun/star/lang/XServiceInfo.hpp>
31 #include <com/sun/star/beans/PropertyAttribute.hpp>
32 #include <com/sun/star/beans/XPropertySet.hpp>
33 #include <com/sun/star/lang/IllegalArgumentException.hpp>
34 #include <rtl/ustrbuf.hxx>
41 using ::com::sun::star::uno::Reference
;
42 using ::com::sun::star::beans::XPropertySet
;
43 using ::com::sun::star::beans::XPropertySetInfo
;
44 using ::com::sun::star::beans::Property
;
45 using ::com::sun::star::uno::Sequence
;
46 using ::com::sun::star::uno::Exception
;
47 using ::com::sun::star::uno::Any
;
48 using ::com::sun::star::uno::Type
;
49 using ::com::sun::star::uno::cpp_queryInterface
;
50 using ::com::sun::star::uno::cpp_acquire
;
51 using ::com::sun::star::uno::cpp_release
;
52 #if OSL_DEBUG_LEVEL > 0
53 using ::com::sun::star::lang::XServiceInfo
;
55 using ::com::sun::star::uno::UNO_QUERY
;
57 namespace PropertyAttribute
= ::com::sun::star::beans::PropertyAttribute
;
60 void copyProperties(const Reference
<XPropertySet
>& _rxSource
,
61 const Reference
<XPropertySet
>& _rxDest
)
63 if (!_rxSource
.is() || !_rxDest
.is())
65 OSL_FAIL("copyProperties: invalid arguments !");
69 Reference
< XPropertySetInfo
> xSourceProps
= _rxSource
->getPropertySetInfo();
70 Reference
< XPropertySetInfo
> xDestProps
= _rxDest
->getPropertySetInfo();
72 const Sequence
< Property
> aSourceProps
= xSourceProps
->getProperties();
74 for (const Property
& rSourceProp
: aSourceProps
)
76 if ( xDestProps
->hasPropertyByName(rSourceProp
.Name
) )
80 aDestProp
= xDestProps
->getPropertyByName(rSourceProp
.Name
);
81 if (0 == (aDestProp
.Attributes
& PropertyAttribute::READONLY
) )
83 const Any aSourceValue
= _rxSource
->getPropertyValue(rSourceProp
.Name
);
84 if ( 0 != (aDestProp
.Attributes
& PropertyAttribute::MAYBEVOID
) || aSourceValue
.hasValue() )
85 _rxDest
->setPropertyValue(rSourceProp
.Name
, aSourceValue
);
90 #if OSL_DEBUG_LEVEL > 0
91 TOOLS_WARN_EXCEPTION("comphelper", "Caught exception copying properties");
93 OUStringBuffer
aBuffer(
94 "::comphelper::copyProperties: could not copy property '"
96 + "' to the destination set (a '" );
98 Reference
< XServiceInfo
> xSI( _rxDest
, UNO_QUERY
);
101 aBuffer
.append( xSI
->getImplementationName() );
105 aBuffer
.appendAscii( typeid( *_rxDest
).name() );
107 aBuffer
.append( "' implementation).\n" );
109 Any
aException( ::cppu::getCaughtException() );
110 aBuffer
.append( "Caught an exception of type '"
111 + aException
.getValueTypeName()
114 Exception aBaseException
;
115 if ( ( aException
>>= aBaseException
) && !aBaseException
.Message
.isEmpty() )
117 aBuffer
.append( ", saying '"
118 + aBaseException
.Message
121 aBuffer
.append( "." );
123 SAL_WARN( "comphelper", aBuffer
.makeStringAndClear() );
131 bool hasProperty(const OUString
& _rName
, const Reference
<XPropertySet
>& _rxSet
)
135 // XPropertySetInfoRef xInfo(rxSet->getPropertySetInfo());
136 return _rxSet
->getPropertySetInfo()->hasPropertyByName(_rName
);
142 void RemoveProperty(Sequence
<Property
>& _rProps
, const OUString
& _rPropName
)
145 Property
aNameProp(_rPropName
, 0, Type(), 0);
146 const Property
* pResult
= std::lower_bound(std::cbegin(_rProps
), std::cend(_rProps
), aNameProp
, PropertyCompareByName());
148 if ( pResult
!= std::cend(_rProps
) && pResult
->Name
== _rPropName
)
150 removeElementAt(_rProps
, pResult
- std::cbegin(_rProps
));
155 void ModifyPropertyAttributes(Sequence
<Property
>& seqProps
, const OUString
& sPropName
, sal_Int16 nAddAttrib
, sal_Int16 nRemoveAttrib
)
158 auto [begin
, end
] = asNonConstRange(seqProps
);
159 Property
aNameProp(sPropName
, 0, Type(), 0);
160 Property
* pResult
= std::lower_bound(begin
, end
, aNameProp
, PropertyCompareByName());
162 if ( (pResult
!= end
) && (pResult
->Name
== sPropName
) )
164 pResult
->Attributes
|= nAddAttrib
;
165 pResult
->Attributes
&= ~nRemoveAttrib
;
170 bool tryPropertyValue(Any
& _rConvertedValue
, Any
& _rOldValue
, const Any
& _rValueToSet
, const Any
& _rCurrentValue
, const Type
& _rExpectedType
)
172 bool bModified(false);
173 if (_rCurrentValue
.getValue() != _rValueToSet
.getValue())
175 if ( _rValueToSet
.hasValue() && ( !_rExpectedType
.equals( _rValueToSet
.getValueType() ) ) )
177 _rConvertedValue
= Any( nullptr, _rExpectedType
.getTypeLibType() );
179 if ( !uno_type_assignData(
180 const_cast< void* >( _rConvertedValue
.getValue() ), _rConvertedValue
.getValueType().getTypeLibType(),
181 const_cast< void* >( _rValueToSet
.getValue() ), _rValueToSet
.getValueType().getTypeLibType(),
182 reinterpret_cast< uno_QueryInterfaceFunc
>(
184 reinterpret_cast< uno_AcquireFunc
>(cpp_acquire
),
185 reinterpret_cast< uno_ReleaseFunc
>(cpp_release
)
188 throw css::lang::IllegalArgumentException();
191 _rConvertedValue
= _rValueToSet
;
193 if ( _rCurrentValue
!= _rConvertedValue
)
195 _rOldValue
= _rCurrentValue
;
206 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */