LibreOffice Module chart2 (master) 1
PropertyHelper.cxx
Go to the documentation of this file.
1/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2/*
3 * This file is part of the LibreOffice project.
4 *
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/.
8 *
9 * This file incorporates work covered by the following license notice:
10 *
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 .
18 */
19
20#include <PropertyHelper.hxx>
21#include <com/sun/star/container/XNameContainer.hpp>
22#include <com/sun/star/lang/XMultiServiceFactory.hpp>
24#include <osl/diagnose.h>
26#include <o3tl/string_view.hxx>
27
28#include <utility>
29#include <vector>
30#include <algorithm>
31#include <iterator>
32
33using namespace ::com::sun::star;
34using namespace ::com::sun::star::beans;
35using ::com::sun::star::uno::Any;
36using ::com::sun::star::uno::Reference;
37
38namespace
39{
40struct lcl_EqualsElement
41{
42 explicit lcl_EqualsElement( Any rValue, const Reference< container::XNameAccess > & xAccess )
43 : m_aValue(std::move( rValue )), m_xAccess( xAccess )
44 {
45 OSL_ASSERT( m_xAccess.is());
46 }
47
48 bool operator() ( const OUString & rName )
49 {
50 try
51 {
52 return (m_xAccess->getByName( rName ) == m_aValue);
53 }
54 catch( const uno::Exception & )
55 {
57 }
58 return false;
59 }
60
61private:
62 Any m_aValue;
63 Reference< container::XNameAccess > m_xAccess;
64};
65
66struct lcl_StringMatches
67{
68 explicit lcl_StringMatches( OUString aCmpStr ) :
69 m_aCmpStr(std::move( aCmpStr ))
70 {}
71
72 bool operator() ( std::u16string_view rStr )
73 {
74 return o3tl::starts_with( rStr, m_aCmpStr );
75 }
76
77private:
78 OUString m_aCmpStr;
79};
80
81struct lcl_OUStringRestToInt32
82{
83 explicit lcl_OUStringRestToInt32( sal_Int32 nPrefixLength ) :
84 m_nPrefixLength( nPrefixLength )
85 {}
86 sal_Int32 operator() ( std::u16string_view rStr )
87 {
88 if( m_nPrefixLength > static_cast<sal_Int32>(rStr.size()) )
89 return 0;
90 return o3tl::toInt32(rStr.substr( m_nPrefixLength ));
91 }
92private:
93 sal_Int32 m_nPrefixLength;
94};
95
109OUString lcl_addNamedPropertyUniqueNameToTable(
110 const Any & rValue,
111 const Reference< container::XNameContainer > & xNameContainer,
112 const OUString & rPrefix,
113 const OUString & rPreferredName )
114{
115 if( ! xNameContainer.is() ||
116 ! rValue.hasValue() ||
117 ( rValue.getValueType() != xNameContainer->getElementType()))
118 return rPreferredName;
119
120 try
121 {
122 Reference< container::XNameAccess > xNameAccess( xNameContainer, uno::UNO_QUERY_THROW );
123 const uno::Sequence<OUString> aElementNames = xNameAccess->getElementNames();
124 auto it = std::find_if( aElementNames.begin(), aElementNames.end(), lcl_EqualsElement( rValue, xNameAccess ));
125
126 // element found => return name
127 if( it != aElementNames.end())
128 return *it;
129
130 // element not found in container
131 OUString aUniqueName;
132
133 // check if preferred name is already used
134 if( !rPreferredName.isEmpty())
135 {
136 auto aIt = std::find( aElementNames.begin(), aElementNames.end(), rPreferredName );
137 if( aIt == aElementNames.end())
138 aUniqueName = rPreferredName;
139 }
140
141 if( aUniqueName.isEmpty())
142 {
143 auto aNames( comphelper::sequenceToContainer<std::vector< OUString >>( aElementNames ));
144 // create a unique id using the prefix plus a number
145 std::vector< sal_Int32 > aNumbers;
146 std::vector< OUString >::iterator aNonConstIt(
147 std::partition( aNames.begin(), aNames.end(), lcl_StringMatches( rPrefix )));
148 std::transform( aNames.begin(), aNonConstIt,
149 back_inserter( aNumbers ),
150 lcl_OUStringRestToInt32( rPrefix.getLength() ));
151 std::vector< sal_Int32 >::const_iterator aMaxIt(
152 std::max_element( aNumbers.begin(), aNumbers.end()));
153
154 sal_Int32 nIndex = 1;
155 if( aMaxIt != aNumbers.end())
156 nIndex = (*aMaxIt) + 1;
157
158 aUniqueName = rPrefix + OUString::number( nIndex );
159 }
160
161 OSL_ASSERT( !aUniqueName.isEmpty());
162 xNameContainer->insertByName( aUniqueName, rValue );
163 return aUniqueName;
164 }
165 catch( const uno::Exception & )
166 {
167 DBG_UNHANDLED_EXCEPTION("chart2");
168 }
169
170 return rPreferredName;
171}
172
173} // anonymous namespace
174
175namespace chart::PropertyHelper
176{
177
179 const Any & rValue,
181 const OUString & rPreferredName )
182{
183 if( xFact.is())
184 {
186 xFact->createInstance( "com.sun.star.drawing.DashTable"),
187 uno::UNO_QUERY );
188 if( xNameCnt.is())
189 return lcl_addNamedPropertyUniqueNameToTable(
190 rValue, xNameCnt, "ChartDash ", rPreferredName );
191 }
192 return OUString();
193}
194
196 const Any & rValue,
198 const OUString & rPreferredName )
199{
200 if( xFact.is())
201 {
203 xFact->createInstance( "com.sun.star.drawing.GradientTable"),
204 uno::UNO_QUERY );
205 if( xNameCnt.is())
206 return lcl_addNamedPropertyUniqueNameToTable(
207 rValue, xNameCnt, "ChartGradient ", rPreferredName );
208 }
209 return OUString();
210}
211
213 const Any & rValue,
215 const OUString & rPreferredName )
216{
217 if( xFact.is())
218 {
220 xFact->createInstance( "com.sun.star.drawing.TransparencyGradientTable"),
221 uno::UNO_QUERY );
222 if( xNameCnt.is())
223 return lcl_addNamedPropertyUniqueNameToTable(
224 rValue, xNameCnt, "ChartTransparencyGradient ", rPreferredName );
225 }
226 return OUString();
227}
228
230 const Any & rValue,
232 const OUString & rPreferredName )
233{
234 if( xFact.is())
235 {
237 xFact->createInstance( "com.sun.star.drawing.HatchTable"),
238 uno::UNO_QUERY );
239 if( xNameCnt.is())
240 return lcl_addNamedPropertyUniqueNameToTable(
241 rValue, xNameCnt, "ChartHatch ", rPreferredName );
242 }
243 return OUString();
244}
245
247 const Any & rValue,
249 const OUString & rPreferredName )
250{
251 if( xFact.is())
252 {
254 xFact->createInstance( "com.sun.star.drawing.BitmapTable"),
255 uno::UNO_QUERY );
256 if( xNameCnt.is())
257 return lcl_addNamedPropertyUniqueNameToTable(
258 rValue, xNameCnt, "ChartBitmap ", rPreferredName );
259 }
260 return OUString();
261}
262
264{
265 tPropertyValueMap::iterator aIt( rOutMap.find( key ));
266 if( aIt == rOutMap.end())
267 rOutMap.emplace( key, rAny );
268 else
269 (*aIt).second = rAny;
270}
271
272template<>
273 void setPropertyValue< css::uno::Any >( tPropertyValueMap & rOutMap, tPropertyValueMapKey key, const css::uno::Any & rAny )
274{
275 setPropertyValueAny( rOutMap, key, rAny );
276}
277
279{
280 OSL_ENSURE( rOutMap.end() == rOutMap.find( key ), "Default already exists for property" );
281 setPropertyValue( rOutMap, key, rAny );
282}
283
284template<>
285 void setPropertyValueDefault< css::uno::Any >( tPropertyValueMap & rOutMap, tPropertyValueMapKey key, const css::uno::Any & rAny )
286{
287 setPropertyValueDefaultAny( rOutMap, key, rAny );
288}
289
291{
292 setPropertyValueDefault( rOutMap, key, uno::Any());
293}
294
295} // namespace chart::PropertyHelper
296
297/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
#define DBG_UNHANDLED_EXCEPTION(...)
sal_Int32 nIndex
OOO_DLLPUBLIC_CHARTTOOLS OUString addGradientUniqueNameToTable(const css::uno::Any &rValue, const css::uno::Reference< css::lang::XMultiServiceFactory > &xFact, const OUString &rPreferredName)
adds a gradient with a unique name to the gradient obtained by the given factory.
void setPropertyValue< css::uno::Any >(tPropertyValueMap &rOutMap, tPropertyValueMapKey key, const css::uno::Any &rAny)
OOO_DLLPUBLIC_CHARTTOOLS OUString addLineDashUniqueNameToTable(const css::uno::Any &rValue, const css::uno::Reference< css::lang::XMultiServiceFactory > &xFact, const OUString &rPreferredName)
adds a line dash with a unique name to the gradient obtained by the given factory.
OOO_DLLPUBLIC_CHARTTOOLS void setPropertyValueDefaultAny(tPropertyValueMap &rOutMap, tPropertyValueMapKey key, const css::uno::Any &rAny)
OOO_DLLPUBLIC_CHARTTOOLS void setPropertyValueAny(tPropertyValueMap &rOutMap, tPropertyValueMapKey key, const css::uno::Any &rAny)
Set a property to a certain value in the given map.
OOO_DLLPUBLIC_CHARTTOOLS OUString addBitmapUniqueNameToTable(const css::uno::Any &rValue, const css::uno::Reference< css::lang::XMultiServiceFactory > &xFact, const OUString &rPreferredName)
adds a bitmap with a unique name to the gradient obtained by the given factory.
OOO_DLLPUBLIC_CHARTTOOLS OUString addTransparencyGradientUniqueNameToTable(const css::uno::Any &rValue, const css::uno::Reference< css::lang::XMultiServiceFactory > &xFact, const OUString &rPreferredName)
adds a transparency gradient with a unique name to the gradient obtained by the given factory.
void setPropertyValueDefault< css::uno::Any >(tPropertyValueMap &rOutMap, tPropertyValueMapKey key, const css::uno::Any &rAny)
Calls setPropertyValue() but asserts that the given property hasn't been set before.
void setPropertyValueDefault(tPropertyValueMap &rOutMap, tPropertyValueMapKey key, const Value &value)
Calls setPropertyValue() but asserts that the given property hasn't been set before.
OOO_DLLPUBLIC_CHARTTOOLS void setEmptyPropertyValueDefault(tPropertyValueMap &rOutMap, tPropertyValueMapKey key)
Calls setPropertyValueDefault() with an empty Any as value.
void setPropertyValue(tPropertyValueMap &rOutMap, tPropertyValueMapKey key, const Value &value)
Set a property to a certain value in the given map.
OOO_DLLPUBLIC_CHARTTOOLS OUString addHatchUniqueNameToTable(const css::uno::Any &rValue, const css::uno::Reference< css::lang::XMultiServiceFactory > &xFact, const OUString &rPreferredName)
adds a hatch with a unique name to the gradient obtained by the given factory.
std::unordered_map< tPropertyValueMapKey, css::uno::Any > tPropertyValueMap
int tPropertyValueMapKey
DstType sequenceToContainer(const css::uno::Sequence< SrcType > &i_Sequence)
sal_Int32 toInt32(std::u16string_view str, sal_Int16 radix=10)
constexpr bool starts_with(std::basic_string_view< charT, traits > sv, std::basic_string_view< charT, traits > x) noexcept