1 /**************************************************************
2 *
3 * Licensed to the Apache Software Foundation (ASF) under one
4 * or more contributor license agreements. See the NOTICE file
5 * distributed with this work for additional information
6 * regarding copyright ownership. The ASF licenses this file
7 * to you under the Apache License, Version 2.0 (the
8 * "License"); you may not use this file except in compliance
9 * with the License. You may obtain a copy of the License at
10 *
11 * http://www.apache.org/licenses/LICENSE-2.0
12 *
13 * Unless required by applicable law or agreed to in writing,
14 * software distributed under the License is distributed on an
15 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16 * KIND, either express or implied. See the License for the
17 * specific language governing permissions and limitations
18 * under the License.
19 *
20 *************************************************************/
21
22
23
24 // MARKER(update_precomp.py): autogen include statement, do not remove
25 #include "precompiled_chart2.hxx"
26 #include "PropertyHelper.hxx"
27 #include "ContainerHelper.hxx"
28 #include "macros.hxx"
29 #include <com/sun/star/beans/PropertyAttribute.hpp>
30 #include <com/sun/star/container/XNameContainer.hpp>
31
32 #include <vector>
33 #include <algorithm>
34 #include <functional>
35
36 using namespace ::com::sun::star;
37 using namespace ::com::sun::star::beans;
38 using ::rtl::OUString;
39 using ::com::sun::star::uno::Any;
40 using ::com::sun::star::uno::Reference;
41 using ::com::sun::star::uno::Sequence;
42
43 namespace
44 {
45 struct lcl_EqualsElement : public ::std::unary_function< OUString, bool >
46 {
lcl_EqualsElement__anon8f3fdcb80111::lcl_EqualsElement47 explicit lcl_EqualsElement( const Any & rValue, const Reference< container::XNameAccess > & xAccess )
48 : m_aValue( rValue ), m_xAccess( xAccess )
49 {
50 OSL_ASSERT( m_xAccess.is());
51 }
52
operator ()__anon8f3fdcb80111::lcl_EqualsElement53 bool operator() ( const OUString & rName )
54 {
55 try
56 {
57 return (m_xAccess->getByName( rName ) == m_aValue);
58 }
59 catch( const uno::Exception & ex )
60 {
61 ASSERT_EXCEPTION( ex );
62 }
63 return false;
64 }
65
66 private:
67 Any m_aValue;
68 Reference< container::XNameAccess > m_xAccess;
69 };
70
71 struct lcl_StringMatches : public ::std::unary_function< OUString ,bool >
72 {
lcl_StringMatches__anon8f3fdcb80111::lcl_StringMatches73 lcl_StringMatches( const OUString & rCmpStr ) :
74 m_aCmpStr( rCmpStr )
75 {}
76
operator ()__anon8f3fdcb80111::lcl_StringMatches77 bool operator() ( const OUString & rStr )
78 {
79 return rStr.match( m_aCmpStr );
80 }
81
82 private:
83 OUString m_aCmpStr;
84 };
85
86 struct lcl_OUStringRestToInt32 : public ::std::unary_function< OUString, sal_Int32 >
87 {
lcl_OUStringRestToInt32__anon8f3fdcb80111::lcl_OUStringRestToInt3288 lcl_OUStringRestToInt32( sal_Int32 nPrefixLength ) :
89 m_nPrefixLength( nPrefixLength )
90 {}
operator ()__anon8f3fdcb80111::lcl_OUStringRestToInt3291 sal_Int32 operator() ( const OUString & rStr )
92 {
93 if( m_nPrefixLength > rStr.getLength() )
94 return 0;
95 return rStr.copy( m_nPrefixLength ).toInt32( 10 /* radix */ );
96 }
97 private:
98 sal_Int32 m_nPrefixLength;
99 };
100
101 /** adds a fill gradient, fill hatch, fill bitmap, fill transparency gradient,
102 line dash or line marker to the corresponding name container with a unique
103 name.
104
105 @param rPrefix
106 The prefix used for automated name generation.
107
108 @param rPreferredName
109 If this string is not empty it is used as name if it is unique in the
110 table. Otherwise a new name is generated using pPrefix.
111
112 @return the new name under which the property was stored in the table
113 */
lcl_addNamedPropertyUniqueNameToTable(const Any & rValue,const Reference<container::XNameContainer> & xNameContainer,const OUString & rPrefix,const OUString & rPreferredName)114 OUString lcl_addNamedPropertyUniqueNameToTable(
115 const Any & rValue,
116 const Reference< container::XNameContainer > & xNameContainer,
117 const OUString & rPrefix,
118 const OUString & rPreferredName )
119 {
120 if( ! xNameContainer.is() ||
121 ! rValue.hasValue() ||
122 ( rValue.getValueType() != xNameContainer->getElementType()))
123 return rPreferredName;
124
125 try
126 {
127 Reference< container::XNameAccess > xNameAccess( xNameContainer, uno::UNO_QUERY_THROW );
128 ::std::vector< OUString > aNames( ::chart::ContainerHelper::SequenceToVector( xNameAccess->getElementNames()));
129 ::std::vector< OUString >::const_iterator aIt(
130 ::std::find_if( aNames.begin(), aNames.end(), lcl_EqualsElement( rValue, xNameAccess )));
131
132 // element not found in container
133 if( aIt == aNames.end())
134 {
135 OUString aUniqueName;
136
137 // check if preferred name is already used
138 if( !rPreferredName.isEmpty() )
139 {
140 aIt = ::std::find( aNames.begin(), aNames.end(), rPreferredName );
141 if( aIt == aNames.end())
142 aUniqueName = rPreferredName;
143 }
144
145 if( aUniqueName.isEmpty() )
146 {
147 // create a unique id using the prefix plus a number
148 ::std::vector< sal_Int32 > aNumbers;
149 ::std::vector< OUString >::iterator aNonConstIt(
150 ::std::partition( aNames.begin(), aNames.end(), lcl_StringMatches( rPrefix )));
151 ::std::transform( aNames.begin(), aNonConstIt,
152 back_inserter( aNumbers ),
153 lcl_OUStringRestToInt32( rPrefix.getLength() ));
154 ::std::vector< sal_Int32 >::const_iterator aMaxIt(
155 ::std::max_element( aNumbers.begin(), aNumbers.end()));
156
157 sal_Int32 nIndex = 1;
158 if( aMaxIt != aNumbers.end())
159 nIndex = (*aMaxIt) + 1;
160
161 aUniqueName = rPrefix + OUString::valueOf( nIndex );
162 }
163
164 OSL_ASSERT( !aUniqueName.isEmpty() );
165 xNameContainer->insertByName( aUniqueName, rValue );
166 return aUniqueName;
167 }
168 else
169 // element found => return name
170 return *aIt;
171 }
172 catch( const uno::Exception & ex )
173 {
174 ASSERT_EXCEPTION( ex );
175 }
176
177 return rPreferredName;
178 }
179
180 } // anonymous namespace
181
182 namespace chart
183 {
184 namespace PropertyHelper
185 {
186
addLineDashUniqueNameToTable(const Any & rValue,const Reference<lang::XMultiServiceFactory> & xFact,const OUString & rPreferredName)187 OUString addLineDashUniqueNameToTable(
188 const Any & rValue,
189 const Reference< lang::XMultiServiceFactory > & xFact,
190 const OUString & rPreferredName )
191 {
192 if( xFact.is())
193 {
194 Reference< container::XNameContainer > xNameCnt(
195 xFact->createInstance( C2U( "com.sun.star.drawing.DashTable" )),
196 uno::UNO_QUERY );
197 if( xNameCnt.is())
198 return lcl_addNamedPropertyUniqueNameToTable(
199 rValue, xNameCnt, C2U( "ChartDash " ), rPreferredName );
200 }
201 return OUString();
202 }
203
addGradientUniqueNameToTable(const Any & rValue,const Reference<lang::XMultiServiceFactory> & xFact,const OUString & rPreferredName)204 OUString addGradientUniqueNameToTable(
205 const Any & rValue,
206 const Reference< lang::XMultiServiceFactory > & xFact,
207 const OUString & rPreferredName )
208 {
209 if( xFact.is())
210 {
211 Reference< container::XNameContainer > xNameCnt(
212 xFact->createInstance( C2U( "com.sun.star.drawing.GradientTable" )),
213 uno::UNO_QUERY );
214 if( xNameCnt.is())
215 return lcl_addNamedPropertyUniqueNameToTable(
216 rValue, xNameCnt, C2U( "ChartGradient " ), rPreferredName );
217 }
218 return OUString();
219 }
220
221
addTransparencyGradientUniqueNameToTable(const Any & rValue,const Reference<lang::XMultiServiceFactory> & xFact,const OUString & rPreferredName)222 OUString addTransparencyGradientUniqueNameToTable(
223 const Any & rValue,
224 const Reference< lang::XMultiServiceFactory > & xFact,
225 const OUString & rPreferredName )
226 {
227 if( xFact.is())
228 {
229 Reference< container::XNameContainer > xNameCnt(
230 xFact->createInstance( C2U( "com.sun.star.drawing.TransparencyGradientTable" )),
231 uno::UNO_QUERY );
232 if( xNameCnt.is())
233 return lcl_addNamedPropertyUniqueNameToTable(
234 rValue, xNameCnt, C2U( "ChartTransparencyGradient " ), rPreferredName );
235 }
236 return OUString();
237 }
238
addHatchUniqueNameToTable(const Any & rValue,const Reference<lang::XMultiServiceFactory> & xFact,const OUString & rPreferredName)239 OUString addHatchUniqueNameToTable(
240 const Any & rValue,
241 const Reference< lang::XMultiServiceFactory > & xFact,
242 const OUString & rPreferredName )
243 {
244 if( xFact.is())
245 {
246 Reference< container::XNameContainer > xNameCnt(
247 xFact->createInstance( C2U( "com.sun.star.drawing.HatchTable" )),
248 uno::UNO_QUERY );
249 if( xNameCnt.is())
250 return lcl_addNamedPropertyUniqueNameToTable(
251 rValue, xNameCnt, C2U( "ChartHatch " ), rPreferredName );
252 }
253 return OUString();
254 }
255
addBitmapUniqueNameToTable(const Any & rValue,const Reference<lang::XMultiServiceFactory> & xFact,const OUString & rPreferredName)256 OUString addBitmapUniqueNameToTable(
257 const Any & rValue,
258 const Reference< lang::XMultiServiceFactory > & xFact,
259 const OUString & rPreferredName )
260 {
261 if( xFact.is())
262 {
263 Reference< container::XNameContainer > xNameCnt(
264 xFact->createInstance( C2U( "com.sun.star.drawing.BitmapTable" )),
265 uno::UNO_QUERY );
266 if( xNameCnt.is())
267 return lcl_addNamedPropertyUniqueNameToTable(
268 rValue, xNameCnt, C2U( "ChartBitmap " ), rPreferredName );
269 }
270 return OUString();
271 }
272
273 // ----------------------------------------
274
setPropertyValueAny(tPropertyValueMap & rOutMap,tPropertyValueMapKey key,const uno::Any & rAny)275 void setPropertyValueAny( tPropertyValueMap & rOutMap, tPropertyValueMapKey key, const uno::Any & rAny )
276 {
277 tPropertyValueMap::iterator aIt( rOutMap.find( key ));
278 if( aIt == rOutMap.end())
279 rOutMap.insert( tPropertyValueMap::value_type( key, rAny ));
280 else
281 (*aIt).second = rAny;
282 }
283
284 template<>
setPropertyValue(tPropertyValueMap & rOutMap,tPropertyValueMapKey key,const::com::sun::star::uno::Any & rAny)285 void setPropertyValue< ::com::sun::star::uno::Any >( tPropertyValueMap & rOutMap, tPropertyValueMapKey key, const ::com::sun::star::uno::Any & rAny )
286 {
287 setPropertyValueAny( rOutMap, key, rAny );
288 }
289
setPropertyValueDefaultAny(tPropertyValueMap & rOutMap,tPropertyValueMapKey key,const uno::Any & rAny)290 void setPropertyValueDefaultAny( tPropertyValueMap & rOutMap, tPropertyValueMapKey key, const uno::Any & rAny )
291 {
292 OSL_ENSURE( rOutMap.end() == rOutMap.find( key ), "Default already exists for property" );
293 setPropertyValue( rOutMap, key, rAny );
294 }
295
296 template<>
setPropertyValueDefault(tPropertyValueMap & rOutMap,tPropertyValueMapKey key,const::com::sun::star::uno::Any & rAny)297 void setPropertyValueDefault< ::com::sun::star::uno::Any >( tPropertyValueMap & rOutMap, tPropertyValueMapKey key, const ::com::sun::star::uno::Any & rAny )
298 {
299 setPropertyValueDefaultAny( rOutMap, key, rAny );
300 }
301
302
setEmptyPropertyValueDefault(tPropertyValueMap & rOutMap,tPropertyValueMapKey key)303 void setEmptyPropertyValueDefault( tPropertyValueMap & rOutMap, tPropertyValueMapKey key )
304 {
305 setPropertyValueDefault( rOutMap, key, uno::Any());
306 }
307
308 } // namespace PropertyHelper
309
310 } // namespace chart
311