Version 7.1.7.1, tag libreoffice-7.1.7.1
[LibreOffice.git] / svx / source / items / customshapeitem.cxx
blob9a86a3bdb4aa1903d5345f7d79867230dfca65ba
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
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 )
38 sal_Int32 i, j;
39 aPropSeq = rVal;
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
47 if (!ret.second)
49 throw uno::RuntimeException(
50 "CustomShapeGeometry has duplicate property " + rPropVal.Name);
52 if (auto rPropSeq = o3tl::tryAccess<uno::Sequence<beans::PropertyValue>>(
53 rPropVal.Value))
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;
70 return pRet;
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;
79 return pRet;
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 );
86 if ( pSeqAny )
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;
97 return pRet;
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 );
104 if ( pSeqAny )
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;
115 return pRet;
118 void SdrCustomShapeGeometryItem::SetPropertyValue( const css::beans::PropertyValue& rPropVal )
120 css::uno::Any* pAny = GetPropertyValueByName( rPropVal.Name );
121 if ( pAny )
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;
142 else
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;
160 else
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;
190 else
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() )
205 return;
207 PropertyHashMap::iterator aHashIter( aPropHashMap.find( rPropName ) );
208 if ( aHashIter == aPropHashMap.end() )
209 return;
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();
223 if ( nLength )
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 );
243 if ( bRet )
244 bRet = static_cast<const SdrCustomShapeGeometryItem&>(rCmp).aPropSeq == aPropSeq;
245 return bRet;
248 bool SdrCustomShapeGeometryItem::GetPresentation(
249 SfxItemPresentation ePresentation, MapUnit /*eCoreMetric*/,
250 MapUnit /*ePresentationMetric*/, OUString &rText, const IntlWrapper&) const
252 rText += " ";
253 if ( ePresentation == SfxItemPresentation::Complete )
255 rText = " " + rText;
256 return true;
258 else if ( ePresentation == SfxItemPresentation::Nameless )
259 return true;
260 return false;
263 SdrCustomShapeGeometryItem* SdrCustomShapeGeometryItem::Clone( SfxItemPool * /*pPool*/ ) const
265 return new SdrCustomShapeGeometryItem( aPropSeq );
268 bool SdrCustomShapeGeometryItem::QueryValue( uno::Any& rVal, sal_uInt8 /*nMemberId*/ ) const
270 rVal <<= aPropSeq;
271 return true;
274 bool SdrCustomShapeGeometryItem::PutValue( const uno::Any& rVal, sal_uInt8 /*nMemberId*/ )
276 if ( ! ( rVal >>= aPropSeq ) )
277 return false;
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; });
284 if (isDuplicated)
286 assert(false); // serious bug: duplicate xml attribute exported
287 OUString const name(aPropSeq[i].Name);
288 aPropSeq.realloc(0);
289 throw uno::RuntimeException(
290 "CustomShapeGeometry has duplicate property " + name);
293 return true;
296 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */