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 "ChartDataWrapper.hxx" 31 #include "macros.hxx" 32 #include "DiagramHelper.hxx" 33 #include "DataSourceHelper.hxx" 34 #include "servicenames_charttypes.hxx" 35 #include "ContainerHelper.hxx" 36 #include "CommonFunctors.hxx" 37 #include "ChartModelHelper.hxx" 38 #include "DataSeriesHelper.hxx" 39 #include "ControllerLockGuard.hxx" 40 #include "Chart2ModelContact.hxx" 41 #include <com/sun/star/beans/PropertyAttribute.hpp> 42 #include <com/sun/star/chart2/XTitled.hpp> 43 #include <com/sun/star/chart2/data/XNumericalDataSequence.hpp> 44 #include <com/sun/star/chart2/data/XTextualDataSequence.hpp> 45 #include <com/sun/star/chart2/data/XDataSource.hpp> 46 #include <com/sun/star/chart2/XDataSeries.hpp> 47 #include <com/sun/star/chart2/XDataSeriesContainer.hpp> 48 #include <com/sun/star/chart2/XCoordinateSystemContainer.hpp> 49 #include <com/sun/star/chart2/XChartTypeContainer.hpp> 50 #include <com/sun/star/chart2/data/XDataReceiver.hpp> 51 #include <com/sun/star/chart/ChartDataRowSource.hpp> 52 #include <com/sun/star/chart/XChartDocument.hpp> 53 54 #include "CharacterProperties.hxx" 55 #include "LineProperties.hxx" 56 #include "FillProperties.hxx" 57 58 #include <map> 59 #include <algorithm> 60 #include <rtl/math.hxx> 61 62 using namespace ::com::sun::star; 63 using ::com::sun::star::uno::Reference; 64 using ::com::sun::star::uno::Sequence; 65 using ::rtl::OUString; 66 using ::osl::MutexGuard; 67 using ::com::sun::star::chart2::XAnyDescriptionAccess; 68 using ::com::sun::star::chart::XComplexDescriptionAccess; 69 using ::com::sun::star::chart::XChartData; 70 using ::com::sun::star::chart::XChartDataArray; 71 using ::com::sun::star::chart::XDateCategories; 72 73 namespace 74 { 75 static const ::rtl::OUString lcl_aServiceName( 76 RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.comp.chart.ChartData" )); 77 78 uno::Sequence< uno::Sequence< double > > lcl_getNANInsteadDBL_MIN( const uno::Sequence< uno::Sequence< double > >& rData ) 79 { 80 uno::Sequence< uno::Sequence< double > > aRet; 81 const sal_Int32 nOuterSize = rData.getLength(); 82 aRet.realloc( nOuterSize ); 83 for( sal_Int32 nOuter=0; nOuter<nOuterSize; ++nOuter ) 84 { 85 sal_Int32 nInnerSize = rData[nOuter].getLength(); 86 aRet[nOuter].realloc( nInnerSize ); 87 for( sal_Int32 nInner=0; nInner<nInnerSize; ++nInner ) 88 { 89 aRet[nOuter][nInner] = rData[nOuter][nInner]; 90 double& rValue = aRet[nOuter][nInner]; 91 if( rValue == DBL_MIN ) 92 ::rtl::math::setNan( &rValue ); 93 } 94 } 95 return aRet; 96 } 97 98 uno::Sequence< uno::Sequence< double > > lcl_getDBL_MINInsteadNAN( const uno::Sequence< uno::Sequence< double > >& rData ) 99 { 100 uno::Sequence< uno::Sequence< double > > aRet; 101 const sal_Int32 nOuterSize = rData.getLength(); 102 aRet.realloc( nOuterSize ); 103 for( sal_Int32 nOuter=0; nOuter<nOuterSize; ++nOuter ) 104 { 105 sal_Int32 nInnerSize = rData[nOuter].getLength(); 106 aRet[nOuter].realloc( nInnerSize ); 107 for( sal_Int32 nInner=0; nInner<nInnerSize; ++nInner ) 108 { 109 aRet[nOuter][nInner] = rData[nOuter][nInner]; 110 double& rValue = aRet[nOuter][nInner]; 111 if( ::rtl::math::isNan( rValue ) ) 112 rValue = DBL_MIN; 113 } 114 } 115 return aRet; 116 } 117 118 } // anonymous namespace 119 120 // -------------------------------------------------------------------------------- 121 122 namespace chart 123 { 124 namespace wrapper 125 { 126 127 //-------------------------------------------------------------------------------------- 128 129 struct lcl_Operator 130 { 131 lcl_Operator() 132 { 133 } 134 virtual ~lcl_Operator() 135 { 136 } 137 virtual void apply( const Reference< XAnyDescriptionAccess >& xDataAccess ) = 0; 138 139 virtual bool setsCategories( bool /*bDataInColumns*/ ) 140 { 141 return false; 142 } 143 }; 144 145 //-------------------------------------------------------------------------- 146 147 struct lcl_AllOperator : public lcl_Operator 148 { 149 lcl_AllOperator( const Reference< XChartData >& xDataToApply ) 150 : lcl_Operator() 151 , m_xDataToApply( xDataToApply ) 152 { 153 } 154 155 virtual bool setsCategories( bool /*bDataInColumns*/ ) 156 { 157 return true; 158 } 159 160 virtual void apply( const Reference< XAnyDescriptionAccess >& xDataAccess ) 161 { 162 if( !xDataAccess.is() ) 163 return; 164 165 Reference< XAnyDescriptionAccess > xNewAny( m_xDataToApply, uno::UNO_QUERY ); 166 Reference< XComplexDescriptionAccess > xNewComplex( m_xDataToApply, uno::UNO_QUERY ); 167 if( xNewAny.is() ) 168 { 169 xDataAccess->setData( xNewAny->getData() ); 170 xDataAccess->setComplexRowDescriptions( xNewAny->getComplexRowDescriptions() ); 171 xDataAccess->setComplexColumnDescriptions( xNewAny->getComplexColumnDescriptions() ); 172 } 173 else if( xNewComplex.is() ) 174 { 175 xDataAccess->setData( xNewComplex->getData() ); 176 xDataAccess->setComplexRowDescriptions( xNewComplex->getComplexRowDescriptions() ); 177 xDataAccess->setComplexColumnDescriptions( xNewComplex->getComplexColumnDescriptions() ); 178 } 179 else 180 { 181 Reference< XChartDataArray > xNew( m_xDataToApply, uno::UNO_QUERY ); 182 if( xNew.is() ) 183 { 184 xDataAccess->setData( xNew->getData() ); 185 xDataAccess->setRowDescriptions( xNew->getRowDescriptions() ); 186 xDataAccess->setColumnDescriptions( xNew->getColumnDescriptions() ); 187 } 188 } 189 } 190 191 Reference< XChartData > m_xDataToApply; 192 }; 193 194 //-------------------------------------------------------------------------- 195 196 struct lcl_DataOperator : public lcl_Operator 197 { 198 lcl_DataOperator( const Sequence< Sequence< double > >& rData ) 199 : lcl_Operator() 200 , m_rData( rData ) 201 { 202 } 203 204 virtual void apply( const Reference< XAnyDescriptionAccess >& xDataAccess ) 205 { 206 if( xDataAccess.is() ) 207 xDataAccess->setData( lcl_getNANInsteadDBL_MIN( m_rData ) ); 208 } 209 210 const Sequence< Sequence< double > >& m_rData; 211 }; 212 213 //-------------------------------------------------------------------------- 214 215 struct lcl_RowDescriptionsOperator : public lcl_Operator 216 { 217 lcl_RowDescriptionsOperator( const Sequence< OUString >& rRowDescriptions 218 , const Reference< chart2::XChartDocument >& xChartDoc ) 219 : lcl_Operator() 220 , m_rRowDescriptions( rRowDescriptions ) 221 , m_xChartDoc(xChartDoc) 222 , m_bDataInColumns(true) 223 { 224 } 225 226 virtual bool setsCategories( bool bDataInColumns ) 227 { 228 m_bDataInColumns = bDataInColumns; 229 return bDataInColumns; 230 } 231 232 virtual void apply( const Reference< XAnyDescriptionAccess >& xDataAccess ) 233 { 234 if( xDataAccess.is() ) 235 { 236 xDataAccess->setRowDescriptions( m_rRowDescriptions ); 237 if( m_bDataInColumns ) 238 DiagramHelper::switchToTextCategories( m_xChartDoc ); 239 } 240 } 241 242 const Sequence< OUString >& m_rRowDescriptions; 243 Reference< chart2::XChartDocument > m_xChartDoc; 244 bool m_bDataInColumns; 245 }; 246 247 //-------------------------------------------------------------------------- 248 249 struct lcl_ComplexRowDescriptionsOperator : public lcl_Operator 250 { 251 lcl_ComplexRowDescriptionsOperator( const Sequence< Sequence< OUString > >& rComplexRowDescriptions 252 , const Reference< chart2::XChartDocument >& xChartDoc ) 253 : lcl_Operator() 254 , m_rComplexRowDescriptions( rComplexRowDescriptions ) 255 , m_xChartDoc(xChartDoc) 256 , m_bDataInColumns(true) 257 { 258 } 259 260 virtual bool setsCategories( bool bDataInColumns ) 261 { 262 m_bDataInColumns = bDataInColumns; 263 return bDataInColumns; 264 } 265 266 virtual void apply( const Reference< XAnyDescriptionAccess >& xDataAccess ) 267 { 268 if( xDataAccess.is() ) 269 { 270 xDataAccess->setComplexRowDescriptions( m_rComplexRowDescriptions ); 271 if( m_bDataInColumns ) 272 DiagramHelper::switchToTextCategories( m_xChartDoc ); 273 } 274 } 275 276 const Sequence< Sequence< OUString > >& m_rComplexRowDescriptions; 277 Reference< chart2::XChartDocument > m_xChartDoc; 278 bool m_bDataInColumns; 279 }; 280 //-------------------------------------------------------------------------- 281 282 struct lcl_AnyRowDescriptionsOperator : public lcl_Operator 283 { 284 lcl_AnyRowDescriptionsOperator( const Sequence< Sequence< uno::Any > >& rAnyRowDescriptions ) 285 : lcl_Operator() 286 , m_rAnyRowDescriptions( rAnyRowDescriptions ) 287 { 288 } 289 290 virtual bool setsCategories( bool bDataInColumns ) 291 { 292 return bDataInColumns; 293 } 294 295 virtual void apply( const Reference< XAnyDescriptionAccess >& xDataAccess ) 296 { 297 if( xDataAccess.is() ) 298 xDataAccess->setAnyRowDescriptions( m_rAnyRowDescriptions ); 299 } 300 301 const Sequence< Sequence< uno::Any > >& m_rAnyRowDescriptions; 302 }; 303 304 //-------------------------------------------------------------------------- 305 306 struct lcl_ColumnDescriptionsOperator : public lcl_Operator 307 { 308 lcl_ColumnDescriptionsOperator( const Sequence< OUString >& rColumnDescriptions 309 , const Reference< chart2::XChartDocument >& xChartDoc ) 310 : lcl_Operator() 311 , m_rColumnDescriptions( rColumnDescriptions ) 312 , m_xChartDoc(xChartDoc) 313 , m_bDataInColumns(true) 314 { 315 } 316 317 virtual bool setsCategories( bool bDataInColumns ) 318 { 319 m_bDataInColumns = bDataInColumns; 320 return !bDataInColumns; 321 } 322 323 virtual void apply( const Reference< XAnyDescriptionAccess >& xDataAccess ) 324 { 325 if( xDataAccess.is() ) 326 { 327 xDataAccess->setColumnDescriptions( m_rColumnDescriptions ); 328 if( !m_bDataInColumns ) 329 DiagramHelper::switchToTextCategories( m_xChartDoc ); 330 } 331 } 332 333 const Sequence< OUString >& m_rColumnDescriptions; 334 Reference< chart2::XChartDocument > m_xChartDoc; 335 bool m_bDataInColumns; 336 }; 337 338 //-------------------------------------------------------------------------- 339 340 struct lcl_ComplexColumnDescriptionsOperator : public lcl_Operator 341 { 342 lcl_ComplexColumnDescriptionsOperator( const Sequence< Sequence< OUString > >& rComplexColumnDescriptions 343 , const Reference< chart2::XChartDocument >& xChartDoc ) 344 : lcl_Operator() 345 , m_rComplexColumnDescriptions( rComplexColumnDescriptions ) 346 , m_xChartDoc(xChartDoc) 347 , m_bDataInColumns(true) 348 { 349 } 350 351 virtual bool setsCategories( bool bDataInColumns ) 352 { 353 m_bDataInColumns = bDataInColumns; 354 return !bDataInColumns; 355 } 356 357 virtual void apply( const Reference< XAnyDescriptionAccess >& xDataAccess ) 358 { 359 if( xDataAccess.is() ) 360 { 361 xDataAccess->setComplexColumnDescriptions( m_rComplexColumnDescriptions ); 362 if( !m_bDataInColumns ) 363 DiagramHelper::switchToTextCategories( m_xChartDoc ); 364 } 365 } 366 367 const Sequence< Sequence< OUString > >& m_rComplexColumnDescriptions; 368 Reference< chart2::XChartDocument > m_xChartDoc; 369 bool m_bDataInColumns; 370 }; 371 372 //-------------------------------------------------------------------------- 373 374 struct lcl_AnyColumnDescriptionsOperator : public lcl_Operator 375 { 376 lcl_AnyColumnDescriptionsOperator( const Sequence< Sequence< uno::Any > >& rAnyColumnDescriptions ) 377 : lcl_Operator() 378 , m_rAnyColumnDescriptions( rAnyColumnDescriptions ) 379 { 380 } 381 382 virtual bool setsCategories( bool bDataInColumns ) 383 { 384 return bDataInColumns; 385 } 386 387 virtual void apply( const Reference< XAnyDescriptionAccess >& xDataAccess ) 388 { 389 if( xDataAccess.is() ) 390 xDataAccess->setAnyColumnDescriptions( m_rAnyColumnDescriptions ); 391 } 392 393 const Sequence< Sequence< uno::Any > >& m_rAnyColumnDescriptions; 394 }; 395 396 //-------------------------------------------------------------------------- 397 398 struct lcl_DateCategoriesOperator : public lcl_Operator 399 { 400 lcl_DateCategoriesOperator( const Sequence< double >& rDates ) 401 : lcl_Operator() 402 , m_rDates( rDates ) 403 { 404 } 405 406 virtual bool setsCategories( bool /*bDataInColumns*/ ) 407 { 408 return true; 409 } 410 411 virtual void apply( const Reference< XAnyDescriptionAccess >& xDataAccess ) 412 { 413 Reference< XDateCategories > xDateCategories( xDataAccess, uno::UNO_QUERY ); 414 if( xDateCategories.is() ) 415 xDateCategories->setDateCategories( m_rDates ); 416 } 417 418 const Sequence< double >& m_rDates; 419 }; 420 421 //-------------------------------------------------------------------------- 422 423 ChartDataWrapper::ChartDataWrapper( ::boost::shared_ptr< Chart2ModelContact > spChart2ModelContact ) : 424 m_spChart2ModelContact( spChart2ModelContact ), 425 m_aEventListenerContainer( m_aMutex ) 426 { 427 osl_incrementInterlockedCount( &m_refCount ); 428 initDataAccess(); 429 osl_decrementInterlockedCount( &m_refCount ); 430 } 431 432 ChartDataWrapper::ChartDataWrapper( ::boost::shared_ptr< Chart2ModelContact > spChart2ModelContact, 433 const Reference< XChartData >& xNewData ) : 434 m_spChart2ModelContact( spChart2ModelContact ), 435 m_aEventListenerContainer( m_aMutex ) 436 { 437 osl_incrementInterlockedCount( &m_refCount ); 438 lcl_AllOperator aOperator( xNewData ); 439 applyData( aOperator ); 440 osl_decrementInterlockedCount( &m_refCount ); 441 } 442 443 ChartDataWrapper::~ChartDataWrapper() 444 { 445 // @todo: implement XComponent and call this in dispose(). In the DTOR the 446 // ref-count is 0, thus creating a stack reference to this calls the DTOR at 447 // the end of the block recursively 448 // uno::Reference< uno::XInterface > xSource( static_cast< ::cppu::OWeakObject* >( this ) ); 449 // m_aEventListenerContainer.disposeAndClear( lang::EventObject( xSource ) ); 450 } 451 452 // ____ XChartDataArray (read)____ 453 Sequence< Sequence< double > > SAL_CALL ChartDataWrapper::getData() 454 throw (uno::RuntimeException) 455 { 456 initDataAccess(); 457 if( m_xDataAccess.is() ) 458 return lcl_getDBL_MINInsteadNAN( m_xDataAccess->getData() ); 459 return Sequence< Sequence< double > >(); 460 } 461 Sequence< OUString > SAL_CALL ChartDataWrapper::getRowDescriptions() 462 throw (uno::RuntimeException) 463 { 464 initDataAccess(); 465 if( m_xDataAccess.is() ) 466 return m_xDataAccess->getRowDescriptions(); 467 return Sequence< OUString >(); 468 } 469 Sequence< OUString > SAL_CALL ChartDataWrapper::getColumnDescriptions() 470 throw (uno::RuntimeException) 471 { 472 initDataAccess(); 473 if( m_xDataAccess.is() ) 474 return m_xDataAccess->getColumnDescriptions(); 475 return Sequence< OUString > (); 476 } 477 478 // ____ XComplexDescriptionAccess (read) ____ 479 Sequence< Sequence< OUString > > SAL_CALL ChartDataWrapper::getComplexRowDescriptions() throw (uno::RuntimeException) 480 { 481 initDataAccess(); 482 if( m_xDataAccess.is() ) 483 return m_xDataAccess->getComplexRowDescriptions(); 484 return Sequence< Sequence< OUString > >(); 485 } 486 Sequence< Sequence< OUString > > SAL_CALL ChartDataWrapper::getComplexColumnDescriptions() throw (uno::RuntimeException) 487 { 488 initDataAccess(); 489 if( m_xDataAccess.is() ) 490 return m_xDataAccess->getComplexColumnDescriptions(); 491 return Sequence< Sequence< OUString > >(); 492 } 493 494 // ____ XAnyDescriptionAccess (read) ____ 495 Sequence< Sequence< uno::Any > > SAL_CALL ChartDataWrapper::getAnyRowDescriptions() throw (uno::RuntimeException) 496 { 497 initDataAccess(); 498 if( m_xDataAccess.is() ) 499 return m_xDataAccess->getAnyRowDescriptions(); 500 return Sequence< Sequence< uno::Any > >(); 501 } 502 Sequence< Sequence< uno::Any > > SAL_CALL ChartDataWrapper::getAnyColumnDescriptions() throw (uno::RuntimeException) 503 { 504 initDataAccess(); 505 if( m_xDataAccess.is() ) 506 return m_xDataAccess->getAnyColumnDescriptions(); 507 return Sequence< Sequence< uno::Any > >(); 508 } 509 510 // ____ XDateCategories (read) ____ 511 Sequence< double > SAL_CALL ChartDataWrapper::getDateCategories() throw (uno::RuntimeException) 512 { 513 initDataAccess(); 514 Reference< XDateCategories > xDateCategories( m_xDataAccess, uno::UNO_QUERY ); 515 if( xDateCategories.is() ) 516 return xDateCategories->getDateCategories(); 517 return Sequence< double >(); 518 } 519 520 // ____ XChartDataArray (write)____ 521 void SAL_CALL ChartDataWrapper::setData( const Sequence< Sequence< double > >& rData ) 522 throw (uno::RuntimeException) 523 { 524 lcl_DataOperator aOperator( rData ); 525 applyData( aOperator ); 526 } 527 void SAL_CALL ChartDataWrapper::setRowDescriptions( const Sequence< OUString >& rRowDescriptions ) 528 throw (uno::RuntimeException) 529 { 530 lcl_RowDescriptionsOperator aOperator( rRowDescriptions, m_spChart2ModelContact->getChart2Document() ); 531 applyData( aOperator ); 532 } 533 void SAL_CALL ChartDataWrapper::setColumnDescriptions( const Sequence< OUString >& rColumnDescriptions ) 534 throw (uno::RuntimeException) 535 { 536 lcl_ColumnDescriptionsOperator aOperator( rColumnDescriptions, m_spChart2ModelContact->getChart2Document() ); 537 applyData( aOperator ); 538 } 539 540 // ____ XComplexDescriptionAccess (write) ____ 541 void SAL_CALL ChartDataWrapper::setComplexRowDescriptions( const Sequence< Sequence< ::rtl::OUString > >& rRowDescriptions ) throw (uno::RuntimeException) 542 { 543 lcl_ComplexRowDescriptionsOperator aOperator( rRowDescriptions, m_spChart2ModelContact->getChart2Document() ); 544 applyData( aOperator ); 545 } 546 void SAL_CALL ChartDataWrapper::setComplexColumnDescriptions( const Sequence< Sequence< ::rtl::OUString > >& rColumnDescriptions ) throw (uno::RuntimeException) 547 { 548 lcl_ComplexColumnDescriptionsOperator aOperator( rColumnDescriptions, m_spChart2ModelContact->getChart2Document() ); 549 applyData( aOperator ); 550 } 551 552 // ____ XAnyDescriptionAccess (write) ____ 553 void SAL_CALL ChartDataWrapper::setAnyRowDescriptions( const Sequence< Sequence< uno::Any > >& rRowDescriptions ) throw (uno::RuntimeException) 554 { 555 lcl_AnyRowDescriptionsOperator aOperator( rRowDescriptions ); 556 applyData( aOperator ); 557 } 558 void SAL_CALL ChartDataWrapper::setAnyColumnDescriptions( const Sequence< Sequence< uno::Any > >& rColumnDescriptions ) throw (uno::RuntimeException) 559 { 560 lcl_AnyColumnDescriptionsOperator aOperator( rColumnDescriptions ); 561 applyData( aOperator ); 562 } 563 564 // ____ XDateCategories (write) ____ 565 void SAL_CALL ChartDataWrapper::setDateCategories( const Sequence< double >& rDates ) throw (uno::RuntimeException) 566 { 567 Reference< chart2::XChartDocument > xChartDoc( m_spChart2ModelContact->getChart2Document() ); 568 ControllerLockGuard aCtrlLockGuard( uno::Reference< frame::XModel >( xChartDoc, uno::UNO_QUERY )); 569 lcl_DateCategoriesOperator aOperator( rDates ); 570 applyData( aOperator ); 571 DiagramHelper::switchToDateCategories( xChartDoc ); 572 } 573 574 //-------------------------------------------------------------------------------------- 575 576 // ____ XChartData (base of XChartDataArray) ____ 577 void SAL_CALL ChartDataWrapper::addChartDataChangeEventListener( 578 const uno::Reference< 579 ::com::sun::star::chart::XChartDataChangeEventListener >& aListener ) 580 throw (uno::RuntimeException) 581 { 582 m_aEventListenerContainer.addInterface( aListener ); 583 } 584 585 void SAL_CALL ChartDataWrapper::removeChartDataChangeEventListener( 586 const uno::Reference< 587 ::com::sun::star::chart::XChartDataChangeEventListener >& aListener ) 588 throw (uno::RuntimeException) 589 { 590 m_aEventListenerContainer.removeInterface( aListener ); 591 } 592 593 double SAL_CALL ChartDataWrapper::getNotANumber() 594 throw (uno::RuntimeException) 595 { 596 return DBL_MIN; 597 } 598 599 sal_Bool SAL_CALL ChartDataWrapper::isNotANumber( double nNumber ) 600 throw (uno::RuntimeException) 601 { 602 return DBL_MIN == nNumber 603 || ::rtl::math::isNan( nNumber ) 604 || ::rtl::math::isInf( nNumber ); 605 } 606 607 // ____ XComponent ____ 608 void SAL_CALL ChartDataWrapper::dispose() 609 throw (uno::RuntimeException) 610 { 611 m_aEventListenerContainer.disposeAndClear( lang::EventObject( static_cast< ::cppu::OWeakObject* >( this ))); 612 m_xDataAccess=0; 613 } 614 615 void SAL_CALL ChartDataWrapper::addEventListener( 616 const uno::Reference< lang::XEventListener > & xListener ) 617 throw (uno::RuntimeException) 618 { 619 m_aEventListenerContainer.addInterface( xListener ); 620 } 621 622 void SAL_CALL ChartDataWrapper::removeEventListener( 623 const uno::Reference< lang::XEventListener >& aListener ) 624 throw (uno::RuntimeException) 625 { 626 m_aEventListenerContainer.removeInterface( aListener ); 627 } 628 629 // ____ XEventListener ____ 630 void SAL_CALL ChartDataWrapper::disposing( const lang::EventObject& /* Source */ ) 631 throw (uno::RuntimeException) 632 { 633 } 634 635 // ::com::sun::star::chart::ChartDataChangeEvent aEvent; 636 // aEvent.Type = chart::ChartDataChangeType_ALL; 637 // aEvent.StartColumn = 0; 638 // aEvent.EndColumn = 0; 639 // aEvent.StartRow = 0; 640 // aEvent.EndRow = 0; 641 void ChartDataWrapper::fireChartDataChangeEvent( 642 ::com::sun::star::chart::ChartDataChangeEvent& aEvent ) 643 { 644 if( ! m_aEventListenerContainer.getLength() ) 645 return; 646 647 uno::Reference< uno::XInterface > xSrc( static_cast< cppu::OWeakObject* >( this )); 648 OSL_ASSERT( xSrc.is()); 649 if( xSrc.is() ) 650 aEvent.Source = xSrc; 651 652 ::cppu::OInterfaceIteratorHelper aIter( m_aEventListenerContainer ); 653 654 while( aIter.hasMoreElements() ) 655 { 656 uno::Reference< 657 ::com::sun::star::chart::XChartDataChangeEventListener > xListener( 658 aIter.next(), uno::UNO_QUERY ); 659 if( xListener.is() ) 660 xListener->chartDataChanged( aEvent ); 661 } 662 } 663 664 // -------------------------------------------------------------------------------- 665 666 void ChartDataWrapper::switchToInternalDataProvider() 667 { 668 //create an internal data provider that is connected to the model 669 Reference< chart2::XChartDocument > xChartDoc( m_spChart2ModelContact->getChart2Document() ); 670 if( xChartDoc.is() ) 671 xChartDoc->createInternalDataProvider( true /*bCloneExistingData*/ ); 672 initDataAccess(); 673 } 674 675 void ChartDataWrapper::initDataAccess() 676 { 677 Reference< chart2::XChartDocument > xChartDoc( m_spChart2ModelContact->getChart2Document() ); 678 if( !xChartDoc.is() ) 679 return; 680 if( xChartDoc->hasInternalDataProvider() ) 681 m_xDataAccess = Reference< XAnyDescriptionAccess >( xChartDoc->getDataProvider(), uno::UNO_QUERY_THROW ); 682 else 683 { 684 //create a separate "internal data provider" that is not connected to the model 685 m_xDataAccess = Reference< XAnyDescriptionAccess >( ChartModelHelper::createInternalDataProvider( 686 xChartDoc, false /*bConnectToModel*/ ), uno::UNO_QUERY_THROW ); 687 } 688 } 689 690 void ChartDataWrapper::applyData( lcl_Operator& rDataOperator ) 691 { 692 //bool bSetValues, bool bSetRowDescriptions, bool bSetColumnDescriptions 693 Reference< chart2::XChartDocument > xChartDoc( m_spChart2ModelContact->getChart2Document() ); 694 if( !xChartDoc.is() ) 695 return; 696 697 // remember some diagram properties to reset later 698 sal_Bool bStacked = sal_False; 699 sal_Bool bPercent = sal_False; 700 sal_Bool bDeep = sal_False; 701 uno::Reference< ::com::sun::star::chart::XChartDocument > xOldDoc( xChartDoc, uno::UNO_QUERY ); 702 OSL_ASSERT( xOldDoc.is()); 703 uno::Reference< beans::XPropertySet > xDiaProp( xOldDoc->getDiagram(), uno::UNO_QUERY ); 704 if( xDiaProp.is()) 705 { 706 xDiaProp->getPropertyValue( C2U("Stacked")) >>= bStacked; 707 xDiaProp->getPropertyValue( C2U("Percent")) >>= bPercent; 708 xDiaProp->getPropertyValue( C2U("Deep")) >>= bDeep; 709 } 710 711 //detect arguments for the new data source 712 ::rtl::OUString aRangeString; 713 bool bUseColumns = true; 714 bool bFirstCellAsLabel = true; 715 bool bHasCategories = true; 716 uno::Sequence< sal_Int32 > aSequenceMapping; 717 718 DataSourceHelper::detectRangeSegmentation( 719 uno::Reference< frame::XModel >( xChartDoc, uno::UNO_QUERY ), 720 aRangeString, aSequenceMapping, bUseColumns, bFirstCellAsLabel, bHasCategories ); 721 722 if( !bHasCategories && rDataOperator.setsCategories( bUseColumns ) ) 723 bHasCategories = true; 724 725 aRangeString = C2U("all"); 726 uno::Sequence< beans::PropertyValue > aArguments( DataSourceHelper::createArguments( 727 aRangeString, aSequenceMapping, bUseColumns, bFirstCellAsLabel, bHasCategories ) ); 728 729 730 // /-- locked controllers 731 ControllerLockGuard aCtrlLockGuard( uno::Reference< frame::XModel >( xChartDoc, uno::UNO_QUERY )); 732 733 // create and attach new data source 734 switchToInternalDataProvider(); 735 rDataOperator.apply(m_xDataAccess); 736 uno::Reference< chart2::data::XDataProvider > xDataProvider( xChartDoc->getDataProvider() ); 737 OSL_ASSERT( xDataProvider.is() ); 738 if( !xDataProvider.is() ) 739 return; 740 uno::Reference< chart2::data::XDataSource > xSource( xDataProvider->createDataSource( aArguments ) ); 741 742 uno::Reference< chart2::XDiagram > xDia( xChartDoc->getFirstDiagram() ); 743 if( xDia.is() ) 744 xDia->setDiagramData( xSource, aArguments ); 745 746 //correct stacking mode 747 if( bStacked || bPercent || bDeep ) 748 { 749 StackMode eStackMode = StackMode_Y_STACKED; 750 if( bDeep ) 751 eStackMode = StackMode_Z_STACKED; 752 else if( bPercent ) 753 eStackMode = StackMode_Y_STACKED_PERCENT; 754 DiagramHelper::setStackMode( xDia, eStackMode ); 755 } 756 757 // notify listeners 758 ::com::sun::star::chart::ChartDataChangeEvent aEvent( 759 static_cast< ::cppu::OWeakObject* >( this ), 760 ::com::sun::star::chart::ChartDataChangeType_ALL, 0, 0, 0, 0 ); 761 fireChartDataChangeEvent( aEvent ); 762 // \-- locked controllers 763 } 764 765 // -------------------------------------------------------------------------------- 766 767 uno::Sequence< ::rtl::OUString > ChartDataWrapper::getSupportedServiceNames_Static() 768 { 769 uno::Sequence< ::rtl::OUString > aServices( 2 ); 770 aServices[ 0 ] = C2U( "com.sun.star.chart.ChartDataArray" ); 771 aServices[ 1 ] = C2U( "com.sun.star.chart.ChartData" ); 772 773 return aServices; 774 } 775 776 // ================================================================================ 777 778 // implement XServiceInfo methods basing upon getSupportedServiceNames_Static 779 APPHELPER_XSERVICEINFO_IMPL( ChartDataWrapper, lcl_aServiceName ); 780 781 } // namespace wrapper 782 } // namespace chart 783