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 #include "DataSeries.hxx" 31 #include "DataSeriesProperties.hxx" 32 #include "DataPointProperties.hxx" 33 #include "CharacterProperties.hxx" 34 #include "UserDefinedProperties.hxx" 35 #include "DataPoint.hxx" 36 #include "macros.hxx" 37 #include "DataSeriesHelper.hxx" 38 #include "ContainerHelper.hxx" 39 #include "CloneHelper.hxx" 40 #include "ModifyListenerHelper.hxx" 41 #include "EventListenerHelper.hxx" 42 43 #include <algorithm> 44 45 using namespace ::com::sun::star; 46 47 using ::com::sun::star::beans::Property; 48 using ::com::sun::star::uno::Sequence; 49 using ::com::sun::star::uno::Reference; 50 using ::com::sun::star::uno::Any; 51 using ::rtl::OUString; 52 using ::osl::MutexGuard; 53 54 // ---------------------------------------- 55 56 namespace 57 { 58 59 struct StaticDataSeriesDefaults_Initializer 60 { 61 ::chart::tPropertyValueMap* operator()() 62 { 63 static ::chart::tPropertyValueMap aStaticDefaults; 64 lcl_AddDefaultsToMap( aStaticDefaults ); 65 return &aStaticDefaults; 66 } 67 private: 68 void lcl_AddDefaultsToMap( ::chart::tPropertyValueMap & rOutMap ) 69 { 70 ::chart::DataSeriesProperties::AddDefaultsToMap( rOutMap ); 71 ::chart::CharacterProperties::AddDefaultsToMap( rOutMap ); 72 73 float fDefaultCharHeight = 10.0; 74 ::chart::PropertyHelper::setPropertyValue( rOutMap, ::chart::CharacterProperties::PROP_CHAR_CHAR_HEIGHT, fDefaultCharHeight ); 75 ::chart::PropertyHelper::setPropertyValue( rOutMap, ::chart::CharacterProperties::PROP_CHAR_ASIAN_CHAR_HEIGHT, fDefaultCharHeight ); 76 ::chart::PropertyHelper::setPropertyValue( rOutMap, ::chart::CharacterProperties::PROP_CHAR_COMPLEX_CHAR_HEIGHT, fDefaultCharHeight ); 77 } 78 }; 79 80 struct StaticDataSeriesDefaults : public rtl::StaticAggregate< ::chart::tPropertyValueMap, StaticDataSeriesDefaults_Initializer > 81 { 82 }; 83 84 struct StaticDataSeriesInfoHelper_Initializer 85 { 86 ::cppu::OPropertyArrayHelper* operator()() 87 { 88 static ::cppu::OPropertyArrayHelper aPropHelper( lcl_GetPropertySequence() ); 89 return &aPropHelper; 90 } 91 92 private: 93 uno::Sequence< Property > lcl_GetPropertySequence() 94 { 95 ::std::vector< ::com::sun::star::beans::Property > aProperties; 96 ::chart::DataSeriesProperties::AddPropertiesToVector( aProperties ); 97 ::chart::CharacterProperties::AddPropertiesToVector( aProperties ); 98 ::chart::UserDefinedProperties::AddPropertiesToVector( aProperties ); 99 100 ::std::sort( aProperties.begin(), aProperties.end(), 101 ::chart::PropertyNameLess() ); 102 103 return ::chart::ContainerHelper::ContainerToSequence( aProperties ); 104 } 105 106 }; 107 108 struct StaticDataSeriesInfoHelper : public rtl::StaticAggregate< ::cppu::OPropertyArrayHelper, StaticDataSeriesInfoHelper_Initializer > 109 { 110 }; 111 112 struct StaticDataSeriesInfo_Initializer 113 { 114 uno::Reference< beans::XPropertySetInfo >* operator()() 115 { 116 static uno::Reference< beans::XPropertySetInfo > xPropertySetInfo( 117 ::cppu::OPropertySetHelper::createPropertySetInfo(*StaticDataSeriesInfoHelper::get() ) ); 118 return &xPropertySetInfo; 119 } 120 }; 121 122 struct StaticDataSeriesInfo : public rtl::StaticAggregate< uno::Reference< beans::XPropertySetInfo >, StaticDataSeriesInfo_Initializer > 123 { 124 }; 125 126 void lcl_SetParent( 127 const uno::Reference< uno::XInterface > & xChildInterface, 128 const uno::Reference< uno::XInterface > & xParentInterface ) 129 { 130 uno::Reference< container::XChild > xChild( xChildInterface, uno::UNO_QUERY ); 131 if( xChild.is()) 132 xChild->setParent( xParentInterface ); 133 } 134 135 typedef ::std::map< sal_Int32, ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertySet > > 136 lcl_tDataPointMap; 137 138 void lcl_CloneAttributedDataPoints( 139 const lcl_tDataPointMap & rSource, lcl_tDataPointMap & rDestination, 140 const uno::Reference< uno::XInterface > & xSeries ) 141 { 142 for( lcl_tDataPointMap::const_iterator aIt( rSource.begin()); 143 aIt != rSource.end(); ++aIt ) 144 { 145 Reference< beans::XPropertySet > xPoint( (*aIt).second ); 146 if( xPoint.is()) 147 { 148 Reference< util::XCloneable > xCloneable( xPoint, uno::UNO_QUERY ); 149 if( xCloneable.is()) 150 { 151 xPoint.set( xCloneable->createClone(), uno::UNO_QUERY ); 152 if( xPoint.is()) 153 { 154 lcl_SetParent( xPoint, xSeries ); 155 rDestination.insert( lcl_tDataPointMap::value_type( (*aIt).first, xPoint )); 156 } 157 } 158 } 159 } 160 } 161 162 } // anonymous namespace 163 164 // ---------------------------------------- 165 166 namespace chart 167 { 168 169 DataSeries::DataSeries( const uno::Reference< uno::XComponentContext > & xContext ) : 170 ::property::OPropertySet( m_aMutex ), 171 m_xContext( xContext ), 172 m_xModifyEventForwarder( ModifyListenerHelper::createModifyEventForwarder()) 173 { 174 } 175 176 DataSeries::DataSeries( const DataSeries & rOther ) : 177 MutexContainer(), 178 impl::DataSeries_Base(), 179 ::property::OPropertySet( rOther, m_aMutex ), 180 m_xContext( rOther.m_xContext ), 181 m_xModifyEventForwarder( ModifyListenerHelper::createModifyEventForwarder()) 182 { 183 if( ! rOther.m_aDataSequences.empty()) 184 { 185 CloneHelper::CloneRefVector< tDataSequenceContainer::value_type >( 186 rOther.m_aDataSequences, m_aDataSequences ); 187 ModifyListenerHelper::addListenerToAllElements( m_aDataSequences, m_xModifyEventForwarder ); 188 } 189 190 CloneHelper::CloneRefVector< Reference< chart2::XRegressionCurve > >( rOther.m_aRegressionCurves, m_aRegressionCurves ); 191 ModifyListenerHelper::addListenerToAllElements( m_aRegressionCurves, m_xModifyEventForwarder ); 192 193 // add as listener to XPropertySet properties 194 Reference< beans::XPropertySet > xPropertySet; 195 uno::Any aValue; 196 197 getFastPropertyValue( aValue, DataPointProperties::PROP_DATAPOINT_ERROR_BAR_X ); 198 if( ( aValue >>= xPropertySet ) 199 && xPropertySet.is()) 200 ModifyListenerHelper::addListener( xPropertySet, m_xModifyEventForwarder ); 201 202 getFastPropertyValue( aValue, DataPointProperties::PROP_DATAPOINT_ERROR_BAR_Y ); 203 if( ( aValue >>= xPropertySet ) 204 && xPropertySet.is()) 205 ModifyListenerHelper::addListener( xPropertySet, m_xModifyEventForwarder ); 206 } 207 208 // late initialization to call after copy-constructing 209 void DataSeries::Init( const DataSeries & rOther ) 210 { 211 if( ! rOther.m_aDataSequences.empty()) 212 EventListenerHelper::addListenerToAllElements( m_aDataSequences, this ); 213 214 Reference< uno::XInterface > xThisInterface( static_cast< ::cppu::OWeakObject * >( this )); 215 if( ! rOther.m_aAttributedDataPoints.empty()) 216 { 217 lcl_CloneAttributedDataPoints( 218 rOther.m_aAttributedDataPoints, m_aAttributedDataPoints, xThisInterface ); 219 ModifyListenerHelper::addListenerToAllMapElements( m_aAttributedDataPoints, m_xModifyEventForwarder ); 220 } 221 222 // add as parent to error bars 223 Reference< beans::XPropertySet > xPropertySet; 224 uno::Any aValue; 225 226 getFastPropertyValue( aValue, DataPointProperties::PROP_DATAPOINT_ERROR_BAR_X ); 227 if( ( aValue >>= xPropertySet ) 228 && xPropertySet.is()) 229 lcl_SetParent( xPropertySet, xThisInterface ); 230 231 getFastPropertyValue( aValue, DataPointProperties::PROP_DATAPOINT_ERROR_BAR_Y ); 232 if( ( aValue >>= xPropertySet ) 233 && xPropertySet.is()) 234 lcl_SetParent( xPropertySet, xThisInterface ); 235 } 236 237 DataSeries::~DataSeries() 238 { 239 try 240 { 241 ModifyListenerHelper::removeListenerFromAllMapElements( m_aAttributedDataPoints, m_xModifyEventForwarder ); 242 ModifyListenerHelper::removeListenerFromAllElements( m_aRegressionCurves, m_xModifyEventForwarder ); 243 ModifyListenerHelper::removeListenerFromAllElements( m_aDataSequences, m_xModifyEventForwarder ); 244 245 // remove listener from XPropertySet properties 246 Reference< beans::XPropertySet > xPropertySet; 247 uno::Any aValue; 248 249 getFastPropertyValue( aValue, DataPointProperties::PROP_DATAPOINT_ERROR_BAR_X ); 250 if( ( aValue >>= xPropertySet ) 251 && xPropertySet.is()) 252 ModifyListenerHelper::removeListener( xPropertySet, m_xModifyEventForwarder ); 253 254 getFastPropertyValue( aValue, DataPointProperties::PROP_DATAPOINT_ERROR_BAR_Y ); 255 if( ( aValue >>= xPropertySet ) 256 && xPropertySet.is()) 257 ModifyListenerHelper::removeListener( xPropertySet, m_xModifyEventForwarder ); 258 } 259 catch( const uno::Exception & ex ) 260 { 261 ASSERT_EXCEPTION( ex ); 262 } 263 } 264 265 // ____ XCloneable ____ 266 uno::Reference< util::XCloneable > SAL_CALL DataSeries::createClone() 267 throw (uno::RuntimeException) 268 { 269 DataSeries * pNewSeries( new DataSeries( *this )); 270 // hold a reference to the clone 271 uno::Reference< util::XCloneable > xResult( pNewSeries ); 272 // do initialization that uses uno references to the clone 273 pNewSeries->Init( *this ); 274 275 return xResult; 276 } 277 278 Sequence< OUString > DataSeries::getSupportedServiceNames_Static() 279 { 280 Sequence< OUString > aServices( 3 ); 281 aServices[ 0 ] = C2U( "com.sun.star.chart2.DataSeries" ); 282 aServices[ 1 ] = C2U( "com.sun.star.chart2.DataPointProperties" ); 283 aServices[ 2 ] = C2U( "com.sun.star.beans.PropertySet" ); 284 return aServices; 285 } 286 287 // ____ OPropertySet ____ 288 uno::Any DataSeries::GetDefaultValue( sal_Int32 nHandle ) const 289 throw(beans::UnknownPropertyException) 290 { 291 const tPropertyValueMap& rStaticDefaults = *StaticDataSeriesDefaults::get(); 292 tPropertyValueMap::const_iterator aFound( rStaticDefaults.find( nHandle ) ); 293 if( aFound == rStaticDefaults.end() ) 294 return uno::Any(); 295 return (*aFound).second; 296 } 297 298 // ____ OPropertySet ____ 299 ::cppu::IPropertyArrayHelper & SAL_CALL DataSeries::getInfoHelper() 300 { 301 return *StaticDataSeriesInfoHelper::get(); 302 } 303 304 // ____ XPropertySet ____ 305 uno::Reference< beans::XPropertySetInfo > SAL_CALL DataSeries::getPropertySetInfo() 306 throw (uno::RuntimeException) 307 { 308 return *StaticDataSeriesInfo::get(); 309 } 310 311 void SAL_CALL DataSeries::getFastPropertyValue 312 ( uno::Any& rValue, 313 sal_Int32 nHandle ) const 314 { 315 // special handling for get. set is not possible for this property 316 if( nHandle == DataSeriesProperties::PROP_DATASERIES_ATTRIBUTED_DATA_POINTS ) 317 { 318 // ToDo: only add those property sets that are really modified 319 uno::Sequence< sal_Int32 > aSeq( m_aAttributedDataPoints.size()); 320 sal_Int32 * pIndexArray = aSeq.getArray(); 321 sal_Int32 i = 0; 322 323 for( tDataPointAttributeContainer::const_iterator aIt( m_aAttributedDataPoints.begin()); 324 aIt != m_aAttributedDataPoints.end(); ++aIt ) 325 { 326 pIndexArray[ i ] = (*aIt).first; 327 ++i; 328 } 329 330 rValue <<= aSeq; 331 } 332 else 333 OPropertySet::getFastPropertyValue( rValue, nHandle ); 334 } 335 336 void SAL_CALL DataSeries::setFastPropertyValue_NoBroadcast( 337 sal_Int32 nHandle, const uno::Any& rValue ) 338 throw (uno::Exception) 339 { 340 if( nHandle == DataPointProperties::PROP_DATAPOINT_ERROR_BAR_Y 341 || nHandle == DataPointProperties::PROP_DATAPOINT_ERROR_BAR_X ) 342 { 343 uno::Any aOldValue; 344 Reference< util::XModifyBroadcaster > xBroadcaster; 345 this->getFastPropertyValue( aOldValue, nHandle ); 346 if( aOldValue.hasValue() && 347 (aOldValue >>= xBroadcaster) && 348 xBroadcaster.is()) 349 { 350 ModifyListenerHelper::removeListener( xBroadcaster, m_xModifyEventForwarder ); 351 } 352 353 OSL_ASSERT( rValue.getValueType().getTypeClass() == uno::TypeClass_INTERFACE ); 354 if( rValue.hasValue() && 355 (rValue >>= xBroadcaster) && 356 xBroadcaster.is()) 357 { 358 ModifyListenerHelper::addListener( xBroadcaster, m_xModifyEventForwarder ); 359 } 360 } 361 362 ::property::OPropertySet::setFastPropertyValue_NoBroadcast( nHandle, rValue ); 363 } 364 365 Reference< beans::XPropertySet > 366 SAL_CALL DataSeries::getDataPointByIndex( sal_Int32 nIndex ) 367 throw (lang::IndexOutOfBoundsException, 368 uno::RuntimeException) 369 { 370 Reference< beans::XPropertySet > xResult; 371 372 Sequence< Reference< chart2::data::XLabeledDataSequence > > aSequences; 373 { 374 MutexGuard aGuard( GetMutex() ); 375 aSequences = ContainerHelper::ContainerToSequence( m_aDataSequences ); 376 } 377 378 ::std::vector< Reference< chart2::data::XLabeledDataSequence > > aValuesSeries( 379 DataSeriesHelper::getAllDataSequencesByRole( aSequences , C2U("values"), true ) ); 380 if( !aValuesSeries.empty() ) 381 { 382 Reference< chart2::data::XDataSequence > xSeq( aValuesSeries.front()->getValues() ); 383 if( 0 <= nIndex && nIndex < xSeq->getData().getLength() ) 384 { 385 { 386 MutexGuard aGuard( GetMutex() ); 387 tDataPointAttributeContainer::iterator aIt( m_aAttributedDataPoints.find( nIndex ) ); 388 if( aIt != m_aAttributedDataPoints.end() ) 389 xResult = (*aIt).second; 390 } 391 if( !xResult.is() ) 392 { 393 Reference< beans::XPropertySet > xParentProperties; 394 Reference< util::XModifyListener > xModifyEventForwarder; 395 { 396 MutexGuard aGuard( GetMutex() ); 397 xParentProperties = this; 398 xModifyEventForwarder = m_xModifyEventForwarder; 399 } 400 401 // create a new XPropertySet for this data point 402 xResult.set( new DataPoint( xParentProperties ) ); 403 { 404 MutexGuard aGuard( GetMutex() ); 405 m_aAttributedDataPoints[ nIndex ] = xResult; 406 } 407 ModifyListenerHelper::addListener( xResult, xModifyEventForwarder ); 408 } 409 } 410 } 411 else 412 { 413 throw lang::IndexOutOfBoundsException(); 414 } 415 416 return xResult; 417 } 418 419 void SAL_CALL DataSeries::resetDataPoint( sal_Int32 nIndex ) 420 throw (uno::RuntimeException) 421 { 422 Reference< beans::XPropertySet > xDataPointProp; 423 Reference< util::XModifyListener > xModifyEventForwarder; 424 { 425 MutexGuard aGuard( GetMutex() ); 426 xModifyEventForwarder = m_xModifyEventForwarder; 427 tDataPointAttributeContainer::iterator aIt( m_aAttributedDataPoints.find( nIndex )); 428 if( aIt != m_aAttributedDataPoints.end()) 429 { 430 xDataPointProp = (*aIt).second; 431 m_aAttributedDataPoints.erase(aIt); 432 } 433 434 } 435 if( xDataPointProp.is() ) 436 { 437 Reference< util::XModifyBroadcaster > xBroadcaster( xDataPointProp, uno::UNO_QUERY ); 438 if( xBroadcaster.is() && xModifyEventForwarder.is()) 439 xBroadcaster->removeModifyListener( xModifyEventForwarder ); 440 fireModifyEvent(); 441 } 442 } 443 444 void SAL_CALL DataSeries::resetAllDataPoints() 445 throw (uno::RuntimeException) 446 { 447 tDataPointAttributeContainer aOldAttributedDataPoints; 448 Reference< util::XModifyListener > xModifyEventForwarder; 449 { 450 MutexGuard aGuard( GetMutex() ); 451 xModifyEventForwarder = m_xModifyEventForwarder; 452 std::swap( aOldAttributedDataPoints, m_aAttributedDataPoints ); 453 } 454 ModifyListenerHelper::removeListenerFromAllMapElements( aOldAttributedDataPoints, xModifyEventForwarder ); 455 aOldAttributedDataPoints.clear(); 456 fireModifyEvent(); 457 } 458 459 // ____ XDataSink ____ 460 void SAL_CALL DataSeries::setData( const uno::Sequence< Reference< chart2::data::XLabeledDataSequence > >& aData ) 461 throw (uno::RuntimeException) 462 { 463 tDataSequenceContainer aOldDataSequences; 464 tDataSequenceContainer aNewDataSequences; 465 Reference< util::XModifyListener > xModifyEventForwarder; 466 Reference< lang::XEventListener > xListener; 467 { 468 MutexGuard aGuard( GetMutex() ); 469 xModifyEventForwarder = m_xModifyEventForwarder; 470 xListener = this; 471 std::swap( aOldDataSequences, m_aDataSequences ); 472 aNewDataSequences = ContainerHelper::SequenceToVector( aData ); 473 m_aDataSequences = aNewDataSequences; 474 } 475 ModifyListenerHelper::removeListenerFromAllElements( aOldDataSequences, xModifyEventForwarder ); 476 EventListenerHelper::removeListenerFromAllElements( aOldDataSequences, xListener ); 477 EventListenerHelper::addListenerToAllElements( aNewDataSequences, xListener ); 478 ModifyListenerHelper::addListenerToAllElements( aNewDataSequences, xModifyEventForwarder ); 479 fireModifyEvent(); 480 } 481 482 // ____ XDataSource ____ 483 Sequence< Reference< chart2::data::XLabeledDataSequence > > SAL_CALL DataSeries::getDataSequences() 484 throw (uno::RuntimeException) 485 { 486 MutexGuard aGuard( GetMutex() ); 487 return ContainerHelper::ContainerToSequence( m_aDataSequences ); 488 } 489 490 491 // ____ XRegressionCurveContainer ____ 492 void SAL_CALL DataSeries::addRegressionCurve( 493 const uno::Reference< chart2::XRegressionCurve >& xRegressionCurve ) 494 throw (lang::IllegalArgumentException, 495 uno::RuntimeException) 496 { 497 Reference< util::XModifyListener > xModifyEventForwarder; 498 { 499 MutexGuard aGuard( GetMutex() ); 500 xModifyEventForwarder = m_xModifyEventForwarder; 501 if( ::std::find( m_aRegressionCurves.begin(), m_aRegressionCurves.end(), xRegressionCurve ) 502 != m_aRegressionCurves.end()) 503 throw lang::IllegalArgumentException(); 504 m_aRegressionCurves.push_back( xRegressionCurve ); 505 } 506 ModifyListenerHelper::addListener( xRegressionCurve, xModifyEventForwarder ); 507 fireModifyEvent(); 508 } 509 510 void SAL_CALL DataSeries::removeRegressionCurve( 511 const uno::Reference< chart2::XRegressionCurve >& xRegressionCurve ) 512 throw (container::NoSuchElementException, 513 uno::RuntimeException) 514 { 515 if( !xRegressionCurve.is() ) 516 throw container::NoSuchElementException(); 517 518 Reference< util::XModifyListener > xModifyEventForwarder; 519 { 520 MutexGuard aGuard( GetMutex() ); 521 xModifyEventForwarder = m_xModifyEventForwarder; 522 tRegressionCurveContainerType::iterator aIt( 523 ::std::find( m_aRegressionCurves.begin(), m_aRegressionCurves.end(), xRegressionCurve ) ); 524 if( aIt == m_aRegressionCurves.end()) 525 throw container::NoSuchElementException( 526 C2U( "The given regression curve is no element of this series" ), 527 static_cast< uno::XWeak * >( this )); 528 m_aRegressionCurves.erase( aIt ); 529 } 530 531 ModifyListenerHelper::removeListener( xRegressionCurve, xModifyEventForwarder ); 532 fireModifyEvent(); 533 } 534 535 uno::Sequence< uno::Reference< chart2::XRegressionCurve > > SAL_CALL DataSeries::getRegressionCurves() 536 throw (uno::RuntimeException) 537 { 538 MutexGuard aGuard( GetMutex() ); 539 return ContainerHelper::ContainerToSequence( m_aRegressionCurves ); 540 } 541 542 void SAL_CALL DataSeries::setRegressionCurves( 543 const Sequence< Reference< chart2::XRegressionCurve > >& aRegressionCurves ) 544 throw (uno::RuntimeException) 545 { 546 tRegressionCurveContainerType aOldCurves; 547 tRegressionCurveContainerType aNewCurves( ContainerHelper::SequenceToVector( aRegressionCurves ) ); 548 Reference< util::XModifyListener > xModifyEventForwarder; 549 { 550 MutexGuard aGuard( GetMutex() ); 551 xModifyEventForwarder = m_xModifyEventForwarder; 552 std::swap( aOldCurves, m_aRegressionCurves ); 553 m_aRegressionCurves = aNewCurves; 554 } 555 ModifyListenerHelper::removeListenerFromAllElements( aOldCurves, xModifyEventForwarder ); 556 ModifyListenerHelper::addListenerToAllElements( aNewCurves, xModifyEventForwarder ); 557 fireModifyEvent(); 558 } 559 560 // ____ XModifyBroadcaster ____ 561 void SAL_CALL DataSeries::addModifyListener( const Reference< util::XModifyListener >& aListener ) 562 throw (uno::RuntimeException) 563 { 564 try 565 { 566 Reference< util::XModifyBroadcaster > xBroadcaster( m_xModifyEventForwarder, uno::UNO_QUERY_THROW ); 567 xBroadcaster->addModifyListener( aListener ); 568 } 569 catch( const uno::Exception & ex ) 570 { 571 ASSERT_EXCEPTION( ex ); 572 } 573 } 574 575 void SAL_CALL DataSeries::removeModifyListener( const Reference< util::XModifyListener >& aListener ) 576 throw (uno::RuntimeException) 577 { 578 try 579 { 580 Reference< util::XModifyBroadcaster > xBroadcaster( m_xModifyEventForwarder, uno::UNO_QUERY_THROW ); 581 xBroadcaster->removeModifyListener( aListener ); 582 } 583 catch( const uno::Exception & ex ) 584 { 585 ASSERT_EXCEPTION( ex ); 586 } 587 } 588 589 // ____ XModifyListener ____ 590 void SAL_CALL DataSeries::modified( const lang::EventObject& aEvent ) 591 throw (uno::RuntimeException) 592 { 593 m_xModifyEventForwarder->modified( aEvent ); 594 } 595 596 // ____ XEventListener (base of XModifyListener) ____ 597 void SAL_CALL DataSeries::disposing( const lang::EventObject& rEventObject ) 598 throw (uno::RuntimeException) 599 { 600 // forget disposed data sequences 601 tDataSequenceContainer::iterator aIt( 602 ::std::find( m_aDataSequences.begin(), m_aDataSequences.end(), rEventObject.Source )); 603 if( aIt != m_aDataSequences.end()) 604 m_aDataSequences.erase( aIt ); 605 } 606 607 // ____ OPropertySet ____ 608 void DataSeries::firePropertyChangeEvent() 609 { 610 fireModifyEvent(); 611 } 612 613 void DataSeries::fireModifyEvent() 614 { 615 m_xModifyEventForwarder->modified( lang::EventObject( static_cast< uno::XWeak* >( this ))); 616 } 617 618 619 // ================================================================================ 620 621 using impl::DataSeries_Base; 622 using ::property::OPropertySet; 623 624 IMPLEMENT_FORWARD_XINTERFACE2( DataSeries, DataSeries_Base, OPropertySet ) 625 IMPLEMENT_FORWARD_XTYPEPROVIDER2( DataSeries, DataSeries_Base, OPropertySet ) 626 627 // implement XServiceInfo methods basing upon getSupportedServiceNames_Static 628 APPHELPER_XSERVICEINFO_IMPL( DataSeries, 629 C2U( "com.sun.star.comp.chart.DataSeries" )); 630 631 } // namespace chart 632