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