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 <sal/config.h>
22 #include <o3tl/any.hxx>
23 #include <svx/sdasitm.hxx>
25 #include <com/sun/star/beans/PropertyValue.hpp>
27 using namespace ::std
;
28 using namespace com::sun::star
;
31 SdrCustomShapeGeometryItem::SdrCustomShapeGeometryItem()
32 : SfxPoolItem( SDRATTR_CUSTOMSHAPE_GEOMETRY
)
35 SdrCustomShapeGeometryItem::SdrCustomShapeGeometryItem( const uno::Sequence
< beans::PropertyValue
>& rVal
)
36 : SfxPoolItem( SDRATTR_CUSTOMSHAPE_GEOMETRY
)
41 for ( i
= 0; i
< aPropSeq
.getLength(); i
++ )
43 beans::PropertyValue
& rPropVal
= aPropSeq
[ i
];
44 std::pair
<PropertyHashMap::iterator
, bool> const ret(
45 aPropHashMap
.insert(std::make_pair(rPropVal
.Name
, i
)));
46 assert(ret
.second
); // serious bug: duplicate xml attribute exported
49 throw uno::RuntimeException(
50 "CustomShapeGeometry has duplicate property " + rPropVal
.Name
);
52 if (auto rPropSeq
= o3tl::tryAccess
<uno::Sequence
<beans::PropertyValue
>>(
55 for ( j
= 0; j
< rPropSeq
->getLength(); j
++ )
57 beans::PropertyValue
const & rPropVal2
= (*rPropSeq
)[ j
];
58 aPropPairHashMap
[ PropertyPair( rPropVal
.Name
, rPropVal2
.Name
) ] = j
;
64 css::uno::Any
* SdrCustomShapeGeometryItem::GetPropertyValueByName( const OUString
& rPropName
)
66 css::uno::Any
* pRet
= nullptr;
67 PropertyHashMap::iterator
aHashIter( aPropHashMap
.find( rPropName
) );
68 if ( aHashIter
!= aPropHashMap
.end() )
69 pRet
= &aPropSeq
[ (*aHashIter
).second
].Value
;
73 const css::uno::Any
* SdrCustomShapeGeometryItem::GetPropertyValueByName( const OUString
& rPropName
) const
75 const css::uno::Any
* pRet
= nullptr;
76 PropertyHashMap::const_iterator
aHashIter( aPropHashMap
.find( rPropName
) );
77 if ( aHashIter
!= aPropHashMap
.end() )
78 pRet
= &aPropSeq
[ (*aHashIter
).second
].Value
;
82 css::uno::Any
* SdrCustomShapeGeometryItem::GetPropertyValueByName( const OUString
& rSequenceName
, const OUString
& rPropName
)
84 css::uno::Any
* pRet
= nullptr;
85 css::uno::Any
* pSeqAny
= GetPropertyValueByName( rSequenceName
);
88 if ( auto rSecSequence
= o3tl::tryAccess
<css::uno::Sequence
<beans::PropertyValue
>>(*pSeqAny
) )
90 PropertyPairHashMap::iterator
aHashIter( aPropPairHashMap
.find( PropertyPair( rSequenceName
, rPropName
) ) );
91 if ( aHashIter
!= aPropPairHashMap
.end() )
93 pRet
= &const_cast<css::uno::Sequence
<css::beans::PropertyValue
> &>(*rSecSequence
)[ (*aHashIter
).second
].Value
;
100 const css::uno::Any
* SdrCustomShapeGeometryItem::GetPropertyValueByName( const OUString
& rSequenceName
, const OUString
& rPropName
) const
102 const css::uno::Any
* pRet
= nullptr;
103 const css::uno::Any
* pSeqAny
= GetPropertyValueByName( rSequenceName
);
106 if ( auto rSecSequence
= o3tl::tryAccess
<css::uno::Sequence
<beans::PropertyValue
>>(*pSeqAny
) )
108 PropertyPairHashMap::const_iterator
aHashIter( aPropPairHashMap
.find( PropertyPair( rSequenceName
, rPropName
) ) );
109 if ( aHashIter
!= aPropPairHashMap
.end() )
111 pRet
= &(*rSecSequence
)[ (*aHashIter
).second
].Value
;
118 void SdrCustomShapeGeometryItem::SetPropertyValue( const css::beans::PropertyValue
& rPropVal
)
120 css::uno::Any
* pAny
= GetPropertyValueByName( rPropVal
.Name
);
122 { // property is already available
123 if ( auto rSecSequence
= o3tl::tryAccess
<css::uno::Sequence
<beans::PropertyValue
>>(*pAny
) )
124 { // old property is a sequence->each entry has to be removed from the HashPairMap
125 for ( auto const & i
: *rSecSequence
)
127 PropertyPairHashMap::iterator
aHashIter( aPropPairHashMap
.find( PropertyPair( rPropVal
.Name
, i
.Name
) ) );
128 if ( aHashIter
!= aPropPairHashMap
.end() )
129 aPropPairHashMap
.erase( aHashIter
);
132 *pAny
= rPropVal
.Value
;
133 if ( auto rSecSequence
= o3tl::tryAccess
<css::uno::Sequence
<beans::PropertyValue
>>(*pAny
) )
134 { // the new property is a sequence->each entry has to be inserted into the HashPairMap
135 for ( sal_Int32 i
= 0; i
< rSecSequence
->getLength(); i
++ )
137 beans::PropertyValue
const & rPropVal2
= (*rSecSequence
)[ i
];
138 aPropPairHashMap
[ PropertyPair( rPropVal
.Name
, rPropVal2
.Name
) ] = i
;
143 { // it's a new property
144 assert(std::none_of(aPropSeq
.begin(), aPropSeq
.end(),
145 [&rPropVal
](beans::PropertyValue
const& rVal
)
146 { return rVal
.Name
== rPropVal
.Name
; } ));
147 sal_uInt32 nIndex
= aPropSeq
.getLength();
148 aPropSeq
.realloc( nIndex
+ 1 );
149 aPropSeq
[ nIndex
] = rPropVal
;
151 aPropHashMap
[ rPropVal
.Name
] = nIndex
;
155 void SdrCustomShapeGeometryItem::SetPropertyValue( const OUString
& rSequenceName
, const css::beans::PropertyValue
& rPropVal
)
157 css::uno::Any
* pAny
= GetPropertyValueByName( rSequenceName
, rPropVal
.Name
);
158 if ( pAny
) // just replacing
159 *pAny
= rPropVal
.Value
;
162 css::uno::Any
* pSeqAny
= GetPropertyValueByName( rSequenceName
);
163 if( pSeqAny
== nullptr )
165 css::uno::Sequence
< beans::PropertyValue
> aSeq
;
166 beans::PropertyValue aValue
;
167 aValue
.Name
= rSequenceName
;
168 aValue
.Value
<<= aSeq
;
170 assert(std::none_of(aPropSeq
.begin(), aPropSeq
.end(),
171 [&rSequenceName
](beans::PropertyValue
const& rV
)
172 { return rV
.Name
== rSequenceName
; } ));
173 sal_uInt32 nIndex
= aPropSeq
.getLength();
174 aPropSeq
.realloc( nIndex
+ 1 );
175 aPropSeq
[ nIndex
] = aValue
;
176 aPropHashMap
[ rSequenceName
] = nIndex
;
178 pSeqAny
= &aPropSeq
[ nIndex
].Value
;
181 if (auto pSecSequence
= o3tl::tryAccess
<css::uno::Sequence
<beans::PropertyValue
>>(*pSeqAny
))
183 PropertyPairHashMap::iterator
aHashIter(
184 aPropPairHashMap
.find(PropertyPair(rSequenceName
, rPropVal
.Name
)));
185 auto& rSeq
= const_cast<css::uno::Sequence
<css::beans::PropertyValue
>&>(*pSecSequence
);
186 if (aHashIter
!= aPropPairHashMap
.end())
188 rSeq
[(*aHashIter
).second
].Value
= rPropVal
.Value
;
192 const sal_Int32 nCount
= pSecSequence
->getLength();
193 rSeq
.realloc(nCount
+ 1);
194 rSeq
[nCount
] = rPropVal
;
196 aPropPairHashMap
[PropertyPair(rSequenceName
, rPropVal
.Name
)] = nCount
;
202 void SdrCustomShapeGeometryItem::ClearPropertyValue( const OUString
& rPropName
)
204 if ( !aPropSeq
.hasElements() )
207 PropertyHashMap::iterator
aHashIter( aPropHashMap
.find( rPropName
) );
208 if ( aHashIter
== aPropHashMap
.end() )
211 css::uno::Any
& rSeqAny
= aPropSeq
[(*aHashIter
).second
].Value
;
212 if (auto pSecSequence
213 = o3tl::tryAccess
<css::uno::Sequence
<beans::PropertyValue
>>(rSeqAny
))
215 for (const auto& rPropVal
: *pSecSequence
)
217 auto _aHashIter(aPropPairHashMap
.find(PropertyPair(rPropName
, rPropVal
.Name
)));
218 if (_aHashIter
!= aPropPairHashMap
.end())
219 aPropPairHashMap
.erase(_aHashIter
); // removing property from pair hashmap
222 sal_Int32 nLength
= aPropSeq
.getLength();
225 sal_Int32 nIndex
= (*aHashIter
).second
;
226 if ( nIndex
!= ( nLength
- 1 ) ) // resizing sequence
228 PropertyHashMap::iterator
aHashIter2( aPropHashMap
.find( aPropSeq
[ nLength
- 1 ].Name
) );
229 (*aHashIter2
).second
= nIndex
;
230 aPropSeq
[ nIndex
] = aPropSeq
[ nLength
- 1 ];
232 aPropSeq
.realloc( nLength
- 1 );
234 aPropHashMap
.erase( aHashIter
); // removing property from hashmap
237 SdrCustomShapeGeometryItem::~SdrCustomShapeGeometryItem()
240 bool SdrCustomShapeGeometryItem::operator==( const SfxPoolItem
& rCmp
) const
242 bool bRet
= SfxPoolItem::operator==( rCmp
);
244 bRet
= static_cast<const SdrCustomShapeGeometryItem
&>(rCmp
).aPropSeq
== aPropSeq
;
248 bool SdrCustomShapeGeometryItem::GetPresentation(
249 SfxItemPresentation ePresentation
, MapUnit
/*eCoreMetric*/,
250 MapUnit
/*ePresentationMetric*/, OUString
&rText
, const IntlWrapper
&) const
253 if ( ePresentation
== SfxItemPresentation::Complete
)
258 else if ( ePresentation
== SfxItemPresentation::Nameless
)
263 SdrCustomShapeGeometryItem
* SdrCustomShapeGeometryItem::Clone( SfxItemPool
* /*pPool*/ ) const
265 return new SdrCustomShapeGeometryItem( aPropSeq
);
268 bool SdrCustomShapeGeometryItem::QueryValue( uno::Any
& rVal
, sal_uInt8
/*nMemberId*/ ) const
274 bool SdrCustomShapeGeometryItem::PutValue( const uno::Any
& rVal
, sal_uInt8
/*nMemberId*/ )
276 if ( ! ( rVal
>>= aPropSeq
) )
279 for (sal_Int32 i
= 0; i
< aPropSeq
.getLength(); ++i
)
281 const auto& rName
= aPropSeq
[i
].Name
;
282 bool isDuplicated
= std::any_of(std::next(aPropSeq
.begin(), i
+ 1), aPropSeq
.end(),
283 [&rName
](const css::beans::PropertyValue
& rProp
) { return rProp
.Name
== rName
; });
286 assert(false); // serious bug: duplicate xml attribute exported
287 OUString
const name(aPropSeq
[i
].Name
);
289 throw uno::RuntimeException(
290 "CustomShapeGeometry has duplicate property " + name
);
296 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */