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 { 47 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 53 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 { 73 lcl_StringMatches( const OUString & rCmpStr ) : 74 m_aCmpStr( rCmpStr ) 75 {} 76 77 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 { 88 lcl_OUStringRestToInt32( sal_Int32 nPrefixLength ) : 89 m_nPrefixLength( nPrefixLength ) 90 {} 91 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 */ 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.getLength()) 139 { 140 aIt = ::std::find( aNames.begin(), aNames.end(), rPreferredName ); 141 if( aIt == aNames.end()) 142 aUniqueName = rPreferredName; 143 } 144 145 if( ! aUniqueName.getLength()) 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.getLength()); 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 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 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 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 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 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 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<> 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 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<> 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 303 void setEmptyPropertyValueDefault( tPropertyValueMap & rOutMap, tPropertyValueMapKey key ) 304 { 305 setPropertyValueDefault( rOutMap, key, uno::Any()); 306 } 307 308 } // namespace PropertyHelper 309 310 } // namespace chart 311