Branch data Line data Source code
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 "ContainerHelper.hxx"
22 : : #include "macros.hxx"
23 : : #include <com/sun/star/beans/PropertyAttribute.hpp>
24 : : #include <com/sun/star/container/XNameContainer.hpp>
25 : :
26 : : #include <vector>
27 : : #include <algorithm>
28 : : #include <functional>
29 : :
30 : : using namespace ::com::sun::star;
31 : : using namespace ::com::sun::star::beans;
32 : : using ::rtl::OUString;
33 : : using ::com::sun::star::uno::Any;
34 : : using ::com::sun::star::uno::Reference;
35 : : using ::com::sun::star::uno::Sequence;
36 : :
37 : : namespace
38 : : {
39 : 0 : struct lcl_EqualsElement : public ::std::unary_function< OUString, bool >
40 : : {
41 : 0 : explicit lcl_EqualsElement( const Any & rValue, const Reference< container::XNameAccess > & xAccess )
42 : 0 : : m_aValue( rValue ), m_xAccess( xAccess )
43 : : {
44 : : OSL_ASSERT( m_xAccess.is());
45 : 0 : }
46 : :
47 : 0 : bool operator() ( const OUString & rName )
48 : : {
49 : : try
50 : : {
51 [ # # ][ # # ]: 0 : return (m_xAccess->getByName( rName ) == m_aValue);
[ # # ]
52 : : }
53 : 0 : catch( const uno::Exception & ex )
54 : : {
55 : : ASSERT_EXCEPTION( ex );
56 : : }
57 : 0 : return false;
58 : : }
59 : :
60 : : private:
61 : : Any m_aValue;
62 : : Reference< container::XNameAccess > m_xAccess;
63 : : };
64 : :
65 : 0 : struct lcl_StringMatches : public ::std::unary_function< OUString ,bool >
66 : : {
67 : 0 : lcl_StringMatches( const OUString & rCmpStr ) :
68 : 0 : m_aCmpStr( rCmpStr )
69 : 0 : {}
70 : :
71 : 0 : bool operator() ( const OUString & rStr )
72 : : {
73 : 0 : return rStr.match( m_aCmpStr );
74 : : }
75 : :
76 : : private:
77 : : OUString m_aCmpStr;
78 : : };
79 : :
80 : : struct lcl_OUStringRestToInt32 : public ::std::unary_function< OUString, sal_Int32 >
81 : : {
82 : 0 : lcl_OUStringRestToInt32( sal_Int32 nPrefixLength ) :
83 : 0 : m_nPrefixLength( nPrefixLength )
84 : 0 : {}
85 : 0 : sal_Int32 operator() ( const OUString & rStr )
86 : : {
87 [ # # ]: 0 : if( m_nPrefixLength > rStr.getLength() )
88 : 0 : return 0;
89 : 0 : return rStr.copy( m_nPrefixLength ).toInt32( 10 /* radix */ );
90 : : }
91 : : private:
92 : : sal_Int32 m_nPrefixLength;
93 : : };
94 : :
95 : : /** adds a fill gradient, fill hatch, fill bitmap, fill transparency gradient,
96 : : line dash or line marker to the corresponding name container with a unique
97 : : name.
98 : :
99 : : @param rPrefix
100 : : The prefix used for automated name generation.
101 : :
102 : : @param rPreferredName
103 : : If this string is not empty it is used as name if it is unique in the
104 : : table. Otherwise a new name is generated using pPrefix.
105 : :
106 : : @return the new name under which the property was stored in the table
107 : : */
108 : 0 : OUString lcl_addNamedPropertyUniqueNameToTable(
109 : : const Any & rValue,
110 : : const Reference< container::XNameContainer > & xNameContainer,
111 : : const OUString & rPrefix,
112 : : const OUString & rPreferredName )
113 : : {
114 [ # # # # : 0 : if( ! xNameContainer.is() ||
# # ][ # # ]
115 : 0 : ! rValue.hasValue() ||
116 [ # # ][ # # ]: 0 : ( rValue.getValueType() != xNameContainer->getElementType()))
[ # # ][ # # ]
117 : 0 : return rPreferredName;
118 : :
119 : : try
120 : : {
121 [ # # ]: 0 : Reference< container::XNameAccess > xNameAccess( xNameContainer, uno::UNO_QUERY_THROW );
122 [ # # ][ # # ]: 0 : ::std::vector< OUString > aNames( ::chart::ContainerHelper::SequenceToVector( xNameAccess->getElementNames()));
[ # # ][ # # ]
123 : : ::std::vector< OUString >::const_iterator aIt(
124 [ # # ][ # # ]: 0 : ::std::find_if( aNames.begin(), aNames.end(), lcl_EqualsElement( rValue, xNameAccess )));
[ # # ][ # # ]
125 : :
126 : : // element not found in container
127 [ # # ][ # # ]: 0 : if( aIt == aNames.end())
128 : : {
129 : 0 : OUString aUniqueName;
130 : :
131 : : // check if preferred name is already used
132 [ # # ]: 0 : if( !rPreferredName.isEmpty())
133 : : {
134 [ # # ][ # # ]: 0 : aIt = ::std::find( aNames.begin(), aNames.end(), rPreferredName );
135 [ # # ][ # # ]: 0 : if( aIt == aNames.end())
136 : 0 : aUniqueName = rPreferredName;
137 : : }
138 : :
139 [ # # ]: 0 : if( aUniqueName.isEmpty())
140 : : {
141 : : // create a unique id using the prefix plus a number
142 [ # # ]: 0 : ::std::vector< sal_Int32 > aNumbers;
143 : : ::std::vector< OUString >::iterator aNonConstIt(
144 [ # # ]: 0 : ::std::partition( aNames.begin(), aNames.end(), lcl_StringMatches( rPrefix )));
145 : : ::std::transform( aNames.begin(), aNonConstIt,
146 : : back_inserter( aNumbers ),
147 [ # # ][ # # ]: 0 : lcl_OUStringRestToInt32( rPrefix.getLength() ));
148 : : ::std::vector< sal_Int32 >::const_iterator aMaxIt(
149 [ # # ][ # # ]: 0 : ::std::max_element( aNumbers.begin(), aNumbers.end()));
150 : :
151 : 0 : sal_Int32 nIndex = 1;
152 [ # # ][ # # ]: 0 : if( aMaxIt != aNumbers.end())
153 [ # # ]: 0 : nIndex = (*aMaxIt) + 1;
154 : :
155 : 0 : aUniqueName = rPrefix + OUString::valueOf( nIndex );
156 : : }
157 : :
158 : : OSL_ASSERT( !aUniqueName.isEmpty());
159 [ # # ][ # # ]: 0 : xNameContainer->insertByName( aUniqueName, rValue );
160 : 0 : return aUniqueName;
161 : : }
162 : : else
163 : : // element found => return name
164 [ # # ]: 0 : return *aIt;
165 : : }
166 : 0 : catch( const uno::Exception & ex )
167 : : {
168 : : ASSERT_EXCEPTION( ex );
169 : : }
170 : :
171 : 0 : return rPreferredName;
172 : : }
173 : :
174 : : } // anonymous namespace
175 : :
176 : : namespace chart
177 : : {
178 : : namespace PropertyHelper
179 : : {
180 : :
181 : 0 : OUString addLineDashUniqueNameToTable(
182 : : const Any & rValue,
183 : : const Reference< lang::XMultiServiceFactory > & xFact,
184 : : const OUString & rPreferredName )
185 : : {
186 [ # # ]: 0 : if( xFact.is())
187 : : {
188 : : Reference< container::XNameContainer > xNameCnt(
189 [ # # ]: 0 : xFact->createInstance( C2U( "com.sun.star.drawing.DashTable" )),
190 [ # # ][ # # ]: 0 : uno::UNO_QUERY );
[ # # ]
191 [ # # ]: 0 : if( xNameCnt.is())
192 : : return lcl_addNamedPropertyUniqueNameToTable(
193 [ # # ][ # # ]: 0 : rValue, xNameCnt, C2U( "ChartDash " ), rPreferredName );
[ # # ]
194 : : }
195 : 0 : return OUString();
196 : : }
197 : :
198 : 0 : OUString addGradientUniqueNameToTable(
199 : : const Any & rValue,
200 : : const Reference< lang::XMultiServiceFactory > & xFact,
201 : : const OUString & rPreferredName )
202 : : {
203 [ # # ]: 0 : if( xFact.is())
204 : : {
205 : : Reference< container::XNameContainer > xNameCnt(
206 [ # # ]: 0 : xFact->createInstance( C2U( "com.sun.star.drawing.GradientTable" )),
207 [ # # ][ # # ]: 0 : uno::UNO_QUERY );
[ # # ]
208 [ # # ]: 0 : if( xNameCnt.is())
209 : : return lcl_addNamedPropertyUniqueNameToTable(
210 [ # # ][ # # ]: 0 : rValue, xNameCnt, C2U( "ChartGradient " ), rPreferredName );
[ # # ]
211 : : }
212 : 0 : return OUString();
213 : : }
214 : :
215 : :
216 : 0 : OUString addTransparencyGradientUniqueNameToTable(
217 : : const Any & rValue,
218 : : const Reference< lang::XMultiServiceFactory > & xFact,
219 : : const OUString & rPreferredName )
220 : : {
221 [ # # ]: 0 : if( xFact.is())
222 : : {
223 : : Reference< container::XNameContainer > xNameCnt(
224 [ # # ]: 0 : xFact->createInstance( C2U( "com.sun.star.drawing.TransparencyGradientTable" )),
225 [ # # ][ # # ]: 0 : uno::UNO_QUERY );
[ # # ]
226 [ # # ]: 0 : if( xNameCnt.is())
227 : : return lcl_addNamedPropertyUniqueNameToTable(
228 [ # # ][ # # ]: 0 : rValue, xNameCnt, C2U( "ChartTransparencyGradient " ), rPreferredName );
[ # # ]
229 : : }
230 : 0 : return OUString();
231 : : }
232 : :
233 : 0 : OUString addHatchUniqueNameToTable(
234 : : const Any & rValue,
235 : : const Reference< lang::XMultiServiceFactory > & xFact,
236 : : const OUString & rPreferredName )
237 : : {
238 [ # # ]: 0 : if( xFact.is())
239 : : {
240 : : Reference< container::XNameContainer > xNameCnt(
241 [ # # ]: 0 : xFact->createInstance( C2U( "com.sun.star.drawing.HatchTable" )),
242 [ # # ][ # # ]: 0 : uno::UNO_QUERY );
[ # # ]
243 [ # # ]: 0 : if( xNameCnt.is())
244 : : return lcl_addNamedPropertyUniqueNameToTable(
245 [ # # ][ # # ]: 0 : rValue, xNameCnt, C2U( "ChartHatch " ), rPreferredName );
[ # # ]
246 : : }
247 : 0 : return OUString();
248 : : }
249 : :
250 : 0 : OUString addBitmapUniqueNameToTable(
251 : : const Any & rValue,
252 : : const Reference< lang::XMultiServiceFactory > & xFact,
253 : : const OUString & rPreferredName )
254 : : {
255 [ # # ]: 0 : if( xFact.is())
256 : : {
257 : : Reference< container::XNameContainer > xNameCnt(
258 [ # # ]: 0 : xFact->createInstance( C2U( "com.sun.star.drawing.BitmapTable" )),
259 [ # # ][ # # ]: 0 : uno::UNO_QUERY );
[ # # ]
260 [ # # ]: 0 : if( xNameCnt.is())
261 : : return lcl_addNamedPropertyUniqueNameToTable(
262 [ # # ][ # # ]: 0 : rValue, xNameCnt, C2U( "ChartBitmap " ), rPreferredName );
[ # # ]
263 : : }
264 : 0 : return OUString();
265 : : }
266 : :
267 : : // ----------------------------------------
268 : :
269 : 5161 : void setPropertyValueAny( tPropertyValueMap & rOutMap, tPropertyValueMapKey key, const uno::Any & rAny )
270 : : {
271 [ + - ]: 5161 : tPropertyValueMap::iterator aIt( rOutMap.find( key ));
272 [ + + ]: 5161 : if( aIt == rOutMap.end())
273 [ + - ][ + - ]: 4961 : rOutMap.insert( tPropertyValueMap::value_type( key, rAny ));
274 : : else
275 : 200 : (*aIt).second = rAny;
276 : 5161 : }
277 : :
278 : : template<>
279 : 4961 : void setPropertyValue< ::com::sun::star::uno::Any >( tPropertyValueMap & rOutMap, tPropertyValueMapKey key, const ::com::sun::star::uno::Any & rAny )
280 : : {
281 : 4961 : setPropertyValueAny( rOutMap, key, rAny );
282 : 4961 : }
283 : :
284 : 4961 : void setPropertyValueDefaultAny( tPropertyValueMap & rOutMap, tPropertyValueMapKey key, const uno::Any & rAny )
285 : : {
286 : : OSL_ENSURE( rOutMap.end() == rOutMap.find( key ), "Default already exists for property" );
287 : 4961 : setPropertyValue( rOutMap, key, rAny );
288 : 4961 : }
289 : :
290 : : template<>
291 : 294 : void setPropertyValueDefault< ::com::sun::star::uno::Any >( tPropertyValueMap & rOutMap, tPropertyValueMapKey key, const ::com::sun::star::uno::Any & rAny )
292 : : {
293 : 294 : setPropertyValueDefaultAny( rOutMap, key, rAny );
294 : 294 : }
295 : :
296 : :
297 : 84 : void setEmptyPropertyValueDefault( tPropertyValueMap & rOutMap, tPropertyValueMapKey key )
298 : : {
299 [ + - ]: 84 : setPropertyValueDefault( rOutMap, key, uno::Any());
300 : 84 : }
301 : :
302 : : } // namespace PropertyHelper
303 : :
304 : : } // namespace chart
305 : :
306 : : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|