1 /************************************************************************* 2 * 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * Copyright 2000, 2010 Oracle and/or its affiliates. 6 * 7 * OpenOffice.org - a multi-platform office productivity suite 8 * 9 * This file is part of OpenOffice.org. 10 * 11 * OpenOffice.org is free software: you can redistribute it and/or modify 12 * it under the terms of the GNU Lesser General Public License version 3 13 * only, as published by the Free Software Foundation. 14 * 15 * OpenOffice.org is distributed in the hope that it will be useful, 16 * but WITHOUT ANY WARRANTY; without even the implied warranty of 17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18 * GNU Lesser General Public License version 3 for more details 19 * (a copy is included in the LICENSE file that accompanied this code). 20 * 21 * You should have received a copy of the GNU Lesser General Public License 22 * version 3 along with OpenOffice.org. If not, see 23 * <http://www.openoffice.org/license.html> 24 * for a copy of the LGPLv3 License. 25 * 26 ************************************************************************/ 27 28 // MARKER(update_precomp.py): autogen include statement, do not remove 29 #include "precompiled_chart2.hxx" 30 31 #include "BaseCoordinateSystem.hxx" 32 #include "macros.hxx" 33 #include "PropertyHelper.hxx" 34 #include "UserDefinedProperties.hxx" 35 #include "ContainerHelper.hxx" 36 #include "CloneHelper.hxx" 37 #include "Axis.hxx" 38 #include "AxisHelper.hxx" 39 #include <com/sun/star/chart2/AxisType.hpp> 40 41 #include <algorithm> 42 43 #if OSL_DEBUG_LEVEL > 1 44 #include <rtl/math.hxx> 45 #endif 46 #include <com/sun/star/beans/PropertyAttribute.hpp> 47 48 using namespace ::com::sun::star; 49 using ::com::sun::star::uno::Reference; 50 using ::com::sun::star::uno::Sequence; 51 using ::rtl::OUString; 52 using ::com::sun::star::beans::Property; 53 54 namespace 55 { 56 enum 57 { 58 PROP_COORDINATESYSTEM_SWAPXANDYAXIS 59 }; 60 61 void lcl_AddPropertiesToVector( 62 ::std::vector< Property > & rOutProperties ) 63 { 64 rOutProperties.push_back( 65 Property( C2U( "SwapXAndYAxis" ), 66 PROP_COORDINATESYSTEM_SWAPXANDYAXIS, 67 ::getBooleanCppuType(), 68 beans::PropertyAttribute::BOUND 69 | beans::PropertyAttribute::MAYBEVOID )); 70 } 71 72 struct StaticCooSysDefaults_Initializer 73 { 74 ::chart::tPropertyValueMap* operator()() 75 { 76 static ::chart::tPropertyValueMap aStaticDefaults; 77 lcl_AddDefaultsToMap( aStaticDefaults ); 78 return &aStaticDefaults; 79 } 80 private: 81 void lcl_AddDefaultsToMap( ::chart::tPropertyValueMap & rOutMap ) 82 { 83 ::chart::PropertyHelper::setPropertyValueDefault( rOutMap, PROP_COORDINATESYSTEM_SWAPXANDYAXIS, false ); 84 } 85 }; 86 87 struct StaticCooSysDefaults : public rtl::StaticAggregate< ::chart::tPropertyValueMap, StaticCooSysDefaults_Initializer > 88 { 89 }; 90 91 struct StaticCooSysInfoHelper_Initializer 92 { 93 ::cppu::OPropertyArrayHelper* operator()() 94 { 95 static ::cppu::OPropertyArrayHelper aPropHelper( lcl_GetPropertySequence() ); 96 return &aPropHelper; 97 } 98 99 private: 100 Sequence< Property > lcl_GetPropertySequence() 101 { 102 ::std::vector< ::com::sun::star::beans::Property > aProperties; 103 lcl_AddPropertiesToVector( aProperties ); 104 ::chart::UserDefinedProperties::AddPropertiesToVector( aProperties ); 105 106 ::std::sort( aProperties.begin(), aProperties.end(), 107 ::chart::PropertyNameLess() ); 108 109 return ::chart::ContainerHelper::ContainerToSequence( aProperties ); 110 } 111 }; 112 113 struct StaticCooSysInfoHelper : public rtl::StaticAggregate< ::cppu::OPropertyArrayHelper, StaticCooSysInfoHelper_Initializer > 114 { 115 }; 116 117 struct StaticCooSysInfo_Initializer 118 { 119 uno::Reference< beans::XPropertySetInfo >* operator()() 120 { 121 static uno::Reference< beans::XPropertySetInfo > xPropertySetInfo( 122 ::cppu::OPropertySetHelper::createPropertySetInfo(*StaticCooSysInfoHelper::get() ) ); 123 return &xPropertySetInfo; 124 } 125 }; 126 127 struct StaticCooSysInfo : public rtl::StaticAggregate< uno::Reference< beans::XPropertySetInfo >, StaticCooSysInfo_Initializer > 128 { 129 }; 130 131 } // anonymous namespace 132 133 namespace chart 134 { 135 136 BaseCoordinateSystem::BaseCoordinateSystem( 137 const Reference< uno::XComponentContext > & xContext, 138 sal_Int32 nDimensionCount /* = 2 */, 139 sal_Bool bSwapXAndYAxis /* = sal_False */ ) : 140 ::property::OPropertySet( m_aMutex ), 141 m_xContext( xContext ), 142 m_xModifyEventForwarder( ModifyListenerHelper::createModifyEventForwarder()), 143 m_nDimensionCount( nDimensionCount ) 144 { 145 m_aAllAxis.resize( m_nDimensionCount ); 146 for( sal_Int32 nN=0; nN<m_nDimensionCount; nN++ ) 147 { 148 m_aAllAxis[nN].resize( 1 ); 149 Reference< chart2::XAxis > xAxis( new Axis(m_xContext) ); 150 m_aAllAxis[nN][0] = xAxis; 151 152 ModifyListenerHelper::addListenerToAllElements( m_aAllAxis[nN], m_xModifyEventForwarder ); 153 chart2::ScaleData aScaleData( xAxis->getScaleData() ); 154 if(nN==0) 155 { 156 aScaleData.AxisType = chart2::AxisType::CATEGORY; 157 } 158 else if( nN==1) 159 { 160 aScaleData.AxisType = chart2::AxisType::REALNUMBER; 161 } 162 else if( nN==2) 163 { 164 aScaleData.AxisType = chart2::AxisType::SERIES; 165 } 166 xAxis->setScaleData( aScaleData ); 167 } 168 169 m_aOrigin.realloc( m_nDimensionCount ); 170 for( sal_Int32 i = 0; i < m_nDimensionCount; ++i ) 171 m_aOrigin[ i ] = uno::makeAny( double( 0.0 ) ); 172 173 setFastPropertyValue_NoBroadcast( PROP_COORDINATESYSTEM_SWAPXANDYAXIS, uno::makeAny( sal_Bool( bSwapXAndYAxis ))); 174 } 175 176 // explicit 177 BaseCoordinateSystem::BaseCoordinateSystem( 178 const BaseCoordinateSystem & rSource ) : 179 impl::BaseCoordinateSystem_Base(), 180 MutexContainer(), 181 ::property::OPropertySet( rSource, m_aMutex ), 182 m_xContext( rSource.m_xContext ), 183 m_xModifyEventForwarder( ModifyListenerHelper::createModifyEventForwarder()), 184 m_nDimensionCount( rSource.m_nDimensionCount ), 185 m_aOrigin( rSource.m_aOrigin ) 186 { 187 m_aAllAxis.resize(rSource.m_aAllAxis.size()); 188 tAxisVecVecType::size_type nN=0; 189 for( nN=0; nN<m_aAllAxis.size(); nN++ ) 190 CloneHelper::CloneRefVector< Reference< chart2::XAxis > >( rSource.m_aAllAxis[nN], m_aAllAxis[nN] ); 191 CloneHelper::CloneRefVector< Reference< chart2::XChartType > >( rSource.m_aChartTypes, m_aChartTypes ); 192 193 for( nN=0; nN<m_aAllAxis.size(); nN++ ) 194 ModifyListenerHelper::addListenerToAllElements( m_aAllAxis[nN], m_xModifyEventForwarder ); 195 ModifyListenerHelper::addListenerToAllElements( m_aChartTypes, m_xModifyEventForwarder ); 196 } 197 198 BaseCoordinateSystem::~BaseCoordinateSystem() 199 { 200 try 201 { 202 for( tAxisVecVecType::size_type nN=0; nN<m_aAllAxis.size(); nN++ ) 203 ModifyListenerHelper::removeListenerFromAllElements( m_aAllAxis[nN], m_xModifyEventForwarder ); 204 ModifyListenerHelper::removeListenerFromAllElements( m_aChartTypes, m_xModifyEventForwarder ); 205 } 206 catch( const uno::Exception & ex ) 207 { 208 ASSERT_EXCEPTION( ex ); 209 } 210 } 211 212 // ____ XCoordinateSystem ____ 213 sal_Int32 SAL_CALL BaseCoordinateSystem::getDimension() 214 throw (uno::RuntimeException) 215 { 216 return m_nDimensionCount; 217 } 218 219 void SAL_CALL BaseCoordinateSystem::setAxisByDimension( 220 sal_Int32 nDimensionIndex, 221 const Reference< chart2::XAxis >& xAxis, 222 sal_Int32 nIndex ) 223 throw (lang::IndexOutOfBoundsException, 224 uno::RuntimeException) 225 { 226 if( nDimensionIndex < 0 || nDimensionIndex >= getDimension() ) 227 throw lang::IndexOutOfBoundsException(); 228 229 if( nIndex < 0 ) 230 throw lang::IndexOutOfBoundsException(); 231 232 if( m_aAllAxis[ nDimensionIndex ].size() < static_cast< tAxisVecVecType::size_type >( nIndex+1 )) 233 { 234 m_aAllAxis[ nDimensionIndex ].resize( nIndex+1 ); 235 m_aAllAxis[ nDimensionIndex ][nIndex] = 0; 236 } 237 238 Reference< chart2::XAxis > xOldAxis( m_aAllAxis[ nDimensionIndex ][nIndex] ); 239 if( xOldAxis.is()) 240 ModifyListenerHelper::removeListener( xOldAxis, m_xModifyEventForwarder ); 241 m_aAllAxis[ nDimensionIndex ][nIndex] = xAxis; 242 if( xAxis.is()) 243 ModifyListenerHelper::addListener( xAxis, m_xModifyEventForwarder ); 244 fireModifyEvent(); 245 } 246 247 Reference< chart2::XAxis > SAL_CALL BaseCoordinateSystem::getAxisByDimension( 248 sal_Int32 nDimensionIndex, sal_Int32 nAxisIndex ) 249 throw (lang::IndexOutOfBoundsException, 250 uno::RuntimeException) 251 { 252 if( nDimensionIndex < 0 || nDimensionIndex >= getDimension() ) 253 throw lang::IndexOutOfBoundsException(); 254 255 OSL_ASSERT( m_aAllAxis.size() == static_cast< size_t >( getDimension())); 256 257 if( nAxisIndex < 0 || nAxisIndex > this->getMaximumAxisIndexByDimension(nDimensionIndex) ) 258 throw lang::IndexOutOfBoundsException(); 259 260 return m_aAllAxis[ nDimensionIndex ][nAxisIndex]; 261 } 262 263 sal_Int32 SAL_CALL BaseCoordinateSystem::getMaximumAxisIndexByDimension( sal_Int32 nDimensionIndex ) 264 throw (lang::IndexOutOfBoundsException, 265 uno::RuntimeException) 266 { 267 if( nDimensionIndex < 0 || nDimensionIndex >= getDimension() ) 268 throw lang::IndexOutOfBoundsException(); 269 270 OSL_ASSERT( m_aAllAxis.size() == static_cast< size_t >( getDimension())); 271 272 sal_Int32 nRet = m_aAllAxis[ nDimensionIndex ].size(); 273 if(nRet) 274 nRet-=1; 275 276 return nRet; 277 } 278 279 // ____ XChartTypeContainer ____ 280 void SAL_CALL BaseCoordinateSystem::addChartType( const Reference< chart2::XChartType >& aChartType ) 281 throw (lang::IllegalArgumentException, 282 uno::RuntimeException) 283 { 284 if( ::std::find( m_aChartTypes.begin(), m_aChartTypes.end(), aChartType ) 285 != m_aChartTypes.end()) 286 throw lang::IllegalArgumentException(); 287 288 m_aChartTypes.push_back( aChartType ); 289 ModifyListenerHelper::addListener( aChartType, m_xModifyEventForwarder ); 290 fireModifyEvent(); 291 } 292 293 void SAL_CALL BaseCoordinateSystem::removeChartType( const Reference< chart2::XChartType >& aChartType ) 294 throw (container::NoSuchElementException, 295 uno::RuntimeException) 296 { 297 ::std::vector< uno::Reference< chart2::XChartType > >::iterator 298 aIt( ::std::find( m_aChartTypes.begin(), m_aChartTypes.end(), aChartType )); 299 if( aIt == m_aChartTypes.end()) 300 throw container::NoSuchElementException( 301 C2U( "The given chart type is no element of the container" ), 302 static_cast< uno::XWeak * >( this )); 303 304 m_aChartTypes.erase( aIt ); 305 ModifyListenerHelper::removeListener( aChartType, m_xModifyEventForwarder ); 306 fireModifyEvent(); 307 } 308 309 Sequence< Reference< chart2::XChartType > > SAL_CALL BaseCoordinateSystem::getChartTypes() 310 throw (uno::RuntimeException) 311 { 312 return ContainerHelper::ContainerToSequence( m_aChartTypes ); 313 } 314 315 void SAL_CALL BaseCoordinateSystem::setChartTypes( const Sequence< Reference< chart2::XChartType > >& aChartTypes ) 316 throw (lang::IllegalArgumentException, 317 uno::RuntimeException) 318 { 319 ModifyListenerHelper::removeListenerFromAllElements( m_aChartTypes, m_xModifyEventForwarder ); 320 m_aChartTypes = ContainerHelper::SequenceToVector( aChartTypes ); 321 ModifyListenerHelper::addListenerToAllElements( m_aChartTypes, m_xModifyEventForwarder ); 322 fireModifyEvent(); 323 } 324 325 // ____ XModifyBroadcaster ____ 326 void SAL_CALL BaseCoordinateSystem::addModifyListener( const Reference< util::XModifyListener >& aListener ) 327 throw (uno::RuntimeException) 328 { 329 try 330 { 331 Reference< util::XModifyBroadcaster > xBroadcaster( m_xModifyEventForwarder, uno::UNO_QUERY_THROW ); 332 xBroadcaster->addModifyListener( aListener ); 333 } 334 catch( const uno::Exception & ex ) 335 { 336 ASSERT_EXCEPTION( ex ); 337 } 338 } 339 340 void SAL_CALL BaseCoordinateSystem::removeModifyListener( const Reference< util::XModifyListener >& aListener ) 341 throw (uno::RuntimeException) 342 { 343 try 344 { 345 Reference< util::XModifyBroadcaster > xBroadcaster( m_xModifyEventForwarder, uno::UNO_QUERY_THROW ); 346 xBroadcaster->removeModifyListener( aListener ); 347 } 348 catch( const uno::Exception & ex ) 349 { 350 ASSERT_EXCEPTION( ex ); 351 } 352 } 353 354 // ____ XModifyListener ____ 355 void SAL_CALL BaseCoordinateSystem::modified( const lang::EventObject& aEvent ) 356 throw (uno::RuntimeException) 357 { 358 m_xModifyEventForwarder->modified( aEvent ); 359 } 360 361 // ____ XEventListener (base of XModifyListener) ____ 362 void SAL_CALL BaseCoordinateSystem::disposing( const lang::EventObject& /* Source */ ) 363 throw (uno::RuntimeException) 364 { 365 // nothing 366 } 367 368 // ____ OPropertySet ____ 369 void BaseCoordinateSystem::firePropertyChangeEvent() 370 { 371 fireModifyEvent(); 372 } 373 374 void BaseCoordinateSystem::fireModifyEvent() 375 { 376 m_xModifyEventForwarder->modified( lang::EventObject( static_cast< uno::XWeak* >( this ))); 377 } 378 379 380 // ____ OPropertySet ____ 381 uno::Any BaseCoordinateSystem::GetDefaultValue( sal_Int32 nHandle ) const 382 throw(beans::UnknownPropertyException) 383 { 384 const tPropertyValueMap& rStaticDefaults = *StaticCooSysDefaults::get(); 385 tPropertyValueMap::const_iterator aFound( rStaticDefaults.find( nHandle ) ); 386 if( aFound == rStaticDefaults.end() ) 387 return uno::Any(); 388 return (*aFound).second; 389 } 390 391 // ____ OPropertySet ____ 392 ::cppu::IPropertyArrayHelper & SAL_CALL BaseCoordinateSystem::getInfoHelper() 393 { 394 return *StaticCooSysInfoHelper::get(); 395 } 396 397 398 // ____ XPropertySet ____ 399 Reference< beans::XPropertySetInfo > SAL_CALL BaseCoordinateSystem::getPropertySetInfo() 400 throw (uno::RuntimeException) 401 { 402 return *StaticCooSysInfo::get(); 403 } 404 405 using impl::BaseCoordinateSystem_Base; 406 407 IMPLEMENT_FORWARD_XINTERFACE2( BaseCoordinateSystem, BaseCoordinateSystem_Base, ::property::OPropertySet ) 408 IMPLEMENT_FORWARD_XTYPEPROVIDER2( BaseCoordinateSystem, BaseCoordinateSystem_Base, ::property::OPropertySet ) 409 410 } // namespace chart 411