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 <PropertyHelper.hxx>
21 #include <com/sun/star/container/XNameContainer.hpp>
22 #include <com/sun/star/lang/XMultiServiceFactory.hpp>
23 #include <docmodel/uno/UnoGradientTools.hxx>
24 #include <comphelper/sequence.hxx>
25 #include <osl/diagnose.h>
26 #include <comphelper/diagnose_ex.hxx>
27 #include <o3tl/string_view.hxx>
34 using namespace ::com::sun::star
;
35 using namespace ::com::sun::star::beans
;
36 using ::com::sun::star::uno::Any
;
37 using ::com::sun::star::uno::Reference
;
41 struct lcl_EqualsElement
43 explicit lcl_EqualsElement( Any rValue
, const Reference
< container::XNameAccess
> & xAccess
)
44 : m_aValue(std::move( rValue
)), m_xAccess( xAccess
)
46 OSL_ASSERT( m_xAccess
.is());
49 bool operator() ( const OUString
& rName
)
53 return (m_xAccess
->getByName( rName
) == m_aValue
);
55 catch( const uno::Exception
& )
57 DBG_UNHANDLED_EXCEPTION("chart2");
64 Reference
< container::XNameAccess
> m_xAccess
;
67 struct lcl_StringMatches
69 explicit lcl_StringMatches( OUString aCmpStr
) :
70 m_aCmpStr(std::move( aCmpStr
))
73 bool operator() ( std::u16string_view rStr
)
75 return o3tl::starts_with( rStr
, m_aCmpStr
);
82 struct lcl_OUStringRestToInt32
84 explicit lcl_OUStringRestToInt32( sal_Int32 nPrefixLength
) :
85 m_nPrefixLength( nPrefixLength
)
87 sal_Int32
operator() ( std::u16string_view rStr
)
89 if( m_nPrefixLength
> static_cast<sal_Int32
>(rStr
.size()) )
91 return o3tl::toInt32(rStr
.substr( m_nPrefixLength
));
94 sal_Int32 m_nPrefixLength
;
97 /** adds a fill gradient, fill hatch, fill bitmap, fill transparency gradient,
98 line dash or line marker to the corresponding name container with a unique
102 The prefix used for automated name generation.
104 @param rPreferredName
105 If this string is not empty it is used as name if it is unique in the
106 table. Otherwise a new name is generated using pPrefix.
108 @return the new name under which the property was stored in the table
110 OUString
lcl_addNamedPropertyUniqueNameToTable(
112 const Reference
< container::XNameContainer
> & xNameContainer
,
113 const OUString
& rPrefix
,
114 const OUString
& rPreferredName
)
116 if( ! xNameContainer
.is() ||
117 ! rValue
.hasValue() )
118 return rPreferredName
;
122 if ( rValue
.has
<css::awt::Gradient
>())
124 // tdf#158421 the lists for Gradients needs awt::Gradient2
125 // as type, convert input data if needed (and warn about it,
126 // the caller should be changed to offer the needed type)
127 SAL_WARN("chart2","input value needs to be awt::Gradient2");
128 const basegfx::BGradient
aTemp(model::gradient::getFromAny(rValue
));
129 aValue
<<= model::gradient::createUnoGradient2(aTemp
);
132 if ( aValue
.getValueType() != xNameContainer
->getElementType())
133 return rPreferredName
;
137 Reference
< container::XNameAccess
> xNameAccess( xNameContainer
, uno::UNO_QUERY_THROW
);
138 const uno::Sequence
<OUString
> aElementNames
= xNameAccess
->getElementNames();
139 auto it
= std::find_if( aElementNames
.begin(), aElementNames
.end(), lcl_EqualsElement( aValue
, xNameAccess
));
141 // element found => return name
142 if( it
!= aElementNames
.end())
145 // element not found in container
146 OUString aUniqueName
;
148 // check if preferred name is already used
149 if( !rPreferredName
.isEmpty())
151 auto aIt
= std::find( aElementNames
.begin(), aElementNames
.end(), rPreferredName
);
152 if( aIt
== aElementNames
.end())
153 aUniqueName
= rPreferredName
;
156 if( aUniqueName
.isEmpty())
158 auto aNames( comphelper::sequenceToContainer
<std::vector
< OUString
>>( aElementNames
));
159 // create a unique id using the prefix plus a number
160 std::vector
< sal_Int32
> aNumbers
;
161 std::vector
< OUString
>::iterator
aNonConstIt(
162 std::partition( aNames
.begin(), aNames
.end(), lcl_StringMatches( rPrefix
)));
163 std::transform( aNames
.begin(), aNonConstIt
,
164 back_inserter( aNumbers
),
165 lcl_OUStringRestToInt32( rPrefix
.getLength() ));
166 std::vector
< sal_Int32
>::const_iterator
aMaxIt(
167 std::max_element( aNumbers
.begin(), aNumbers
.end()));
169 sal_Int32 nIndex
= 1;
170 if( aMaxIt
!= aNumbers
.end())
171 nIndex
= (*aMaxIt
) + 1;
173 aUniqueName
= rPrefix
+ OUString::number( nIndex
);
176 OSL_ASSERT( !aUniqueName
.isEmpty());
177 xNameContainer
->insertByName( aUniqueName
, aValue
);
180 catch( const uno::Exception
& )
182 DBG_UNHANDLED_EXCEPTION("chart2");
185 return rPreferredName
;
188 } // anonymous namespace
190 namespace chart::PropertyHelper
193 OUString
addLineDashUniqueNameToTable(
195 const Reference
< lang::XMultiServiceFactory
> & xFact
,
196 const OUString
& rPreferredName
)
200 Reference
< container::XNameContainer
> xNameCnt(
201 xFact
->createInstance( "com.sun.star.drawing.DashTable"),
204 return lcl_addNamedPropertyUniqueNameToTable(
205 rValue
, xNameCnt
, "ChartDash ", rPreferredName
);
210 OUString
addGradientUniqueNameToTable(
212 const Reference
< lang::XMultiServiceFactory
> & xFact
,
213 const OUString
& rPreferredName
)
217 Reference
< container::XNameContainer
> xNameCnt(
218 xFact
->createInstance( "com.sun.star.drawing.GradientTable"),
221 return lcl_addNamedPropertyUniqueNameToTable(
222 rValue
, xNameCnt
, "ChartGradient ", rPreferredName
);
227 OUString
addTransparencyGradientUniqueNameToTable(
229 const Reference
< lang::XMultiServiceFactory
> & xFact
,
230 const OUString
& rPreferredName
)
234 Reference
< container::XNameContainer
> xNameCnt(
235 xFact
->createInstance( "com.sun.star.drawing.TransparencyGradientTable"),
238 return lcl_addNamedPropertyUniqueNameToTable(
239 rValue
, xNameCnt
, "ChartTransparencyGradient ", rPreferredName
);
244 OUString
addHatchUniqueNameToTable(
246 const Reference
< lang::XMultiServiceFactory
> & xFact
,
247 const OUString
& rPreferredName
)
251 Reference
< container::XNameContainer
> xNameCnt(
252 xFact
->createInstance( "com.sun.star.drawing.HatchTable"),
255 return lcl_addNamedPropertyUniqueNameToTable(
256 rValue
, xNameCnt
, "ChartHatch ", rPreferredName
);
261 OUString
addBitmapUniqueNameToTable(
263 const Reference
< lang::XMultiServiceFactory
> & xFact
,
264 const OUString
& rPreferredName
)
268 Reference
< container::XNameContainer
> xNameCnt(
269 xFact
->createInstance( "com.sun.star.drawing.BitmapTable"),
272 return lcl_addNamedPropertyUniqueNameToTable(
273 rValue
, xNameCnt
, "ChartBitmap ", rPreferredName
);
278 void setPropertyValueAny( tPropertyValueMap
& rOutMap
, tPropertyValueMapKey key
, const uno::Any
& rAny
)
280 tPropertyValueMap::iterator
aIt( rOutMap
.find( key
));
281 if( aIt
== rOutMap
.end())
282 rOutMap
.emplace( key
, rAny
);
284 (*aIt
).second
= rAny
;
288 void setPropertyValue
< css::uno::Any
>( tPropertyValueMap
& rOutMap
, tPropertyValueMapKey key
, const css::uno::Any
& rAny
)
290 setPropertyValueAny( rOutMap
, key
, rAny
);
293 void setPropertyValueDefaultAny( tPropertyValueMap
& rOutMap
, tPropertyValueMapKey key
, const uno::Any
& rAny
)
295 OSL_ENSURE( rOutMap
.end() == rOutMap
.find( key
), "Default already exists for property" );
296 setPropertyValue( rOutMap
, key
, rAny
);
300 void setPropertyValueDefault
< css::uno::Any
>( tPropertyValueMap
& rOutMap
, tPropertyValueMapKey key
, const css::uno::Any
& rAny
)
302 setPropertyValueDefaultAny( rOutMap
, key
, rAny
);
305 void setEmptyPropertyValueDefault( tPropertyValueMap
& rOutMap
, tPropertyValueMapKey key
)
307 setPropertyValueDefault( rOutMap
, key
, uno::Any());
310 } // namespace chart::PropertyHelper
312 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */