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 29 // MARKER(update_precomp.py): autogen include statement, do not remove 30 #include "precompiled_chart2.hxx" 31 #include <rtl/math.hxx> 32 33 #include <valarray> 34 35 #include "InternalDataProvider.hxx" 36 #include "LabeledDataSequence.hxx" 37 #include "DataSource.hxx" 38 #include "PropertyHelper.hxx" 39 #include "macros.hxx" 40 #include "XMLRangeHelper.hxx" 41 #include "ContainerHelper.hxx" 42 #include "CommonConverters.hxx" 43 #include "CommonFunctors.hxx" 44 #include "UncachedDataSequence.hxx" 45 #include "DataSourceHelper.hxx" 46 #include "ChartModelHelper.hxx" 47 #include "DiagramHelper.hxx" 48 #include "ExplicitCategoriesProvider.hxx" 49 50 #include <com/sun/star/chart2/XChartDocument.hpp> 51 #include <com/sun/star/chart2/data/XDataSequence.hpp> 52 #include <com/sun/star/chart/ChartDataRowSource.hpp> 53 #include <rtl/ustrbuf.hxx> 54 #include <unotools/charclass.hxx> 55 #include <comphelper/sequenceashashmap.hxx> 56 57 #include <vector> 58 #include <algorithm> 59 60 using namespace ::com::sun::star; 61 using namespace ::std; 62 63 using ::com::sun::star::uno::Reference; 64 using ::com::sun::star::uno::Sequence; 65 using ::rtl::OUString; 66 using ::rtl::OUStringBuffer; 67 68 namespace chart 69 { 70 71 // ================================================================================ 72 73 namespace 74 { 75 76 // note: in xmloff this name is used to indicate usage of own data 77 static const ::rtl::OUString lcl_aServiceName( 78 RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.comp.chart.InternalDataProvider" )); 79 80 static const ::rtl::OUString lcl_aCategoriesRangeName( 81 RTL_CONSTASCII_USTRINGPARAM( "categories" )); 82 static const ::rtl::OUString lcl_aCategoriesLevelRangeNamePrefix( 83 RTL_CONSTASCII_USTRINGPARAM( "categoriesL " )); //L <-> level 84 static const ::rtl::OUString lcl_aCategoriesPointRangeNamePrefix( 85 RTL_CONSTASCII_USTRINGPARAM( "categoriesP " )); //P <-> point 86 static const ::rtl::OUString lcl_aCategoriesRoleName( 87 RTL_CONSTASCII_USTRINGPARAM( "categories" )); 88 static const ::rtl::OUString lcl_aLabelRangePrefix( 89 RTL_CONSTASCII_USTRINGPARAM( "label " )); 90 static const ::rtl::OUString lcl_aCompleteRange( 91 RTL_CONSTASCII_USTRINGPARAM( "all" )); 92 93 typedef ::std::multimap< OUString, uno::WeakReference< chart2::data::XDataSequence > > 94 lcl_tSequenceMap; 95 96 Sequence< OUString > lcl_AnyToStringSequence( const Sequence< uno::Any >& aAnySeq ) 97 { 98 Sequence< OUString > aResult; 99 aResult.realloc( aAnySeq.getLength() ); 100 transform( aAnySeq.getConstArray(), aAnySeq.getConstArray() + aAnySeq.getLength(), 101 aResult.getArray(), CommonFunctors::AnyToString() ); 102 return aResult; 103 } 104 105 Sequence< uno::Any > lcl_StringToAnySequence( const Sequence< OUString >& aStringSeq ) 106 { 107 Sequence< uno::Any > aResult; 108 aResult.realloc( aStringSeq.getLength() ); 109 transform( aStringSeq.getConstArray(), aStringSeq.getConstArray() + aStringSeq.getLength(), 110 aResult.getArray(), CommonFunctors::makeAny< OUString >() ); 111 return aResult; 112 } 113 114 struct lcl_setModified : public ::std::unary_function< lcl_tSequenceMap, void > 115 { 116 void operator() ( const lcl_tSequenceMap::value_type & rMapEntry ) 117 { 118 // convert weak reference to reference 119 Reference< chart2::data::XDataSequence > xSeq( rMapEntry.second ); 120 if( xSeq.is()) 121 { 122 Reference< util::XModifiable > xMod( xSeq, uno::UNO_QUERY ); 123 if( xMod.is()) 124 xMod->setModified( sal_True ); 125 } 126 } 127 }; 128 129 struct lcl_internalizeSeries : public ::std::unary_function< Reference< chart2::XDataSeries >, void > 130 { 131 lcl_internalizeSeries( InternalData & rInternalData, 132 InternalDataProvider & rProvider, 133 bool bConnectToModel, bool bDataInColumns ) : 134 m_rInternalData( rInternalData ), 135 m_rProvider( rProvider ), 136 m_bConnectToModel( bConnectToModel ), 137 m_bDataInColumns( bDataInColumns ) 138 {} 139 void operator() ( const Reference< chart2::XDataSeries > & xSeries ) 140 { 141 Reference< chart2::data::XDataSource > xSource( xSeries, uno::UNO_QUERY ); 142 Reference< chart2::data::XDataSink > xSink( xSeries, uno::UNO_QUERY ); 143 if( xSource.is() && xSink.is() ) 144 { 145 Sequence< Reference< chart2::data::XLabeledDataSequence > > aOldSeriesData = xSource->getDataSequences(); 146 Sequence< Reference< chart2::data::XLabeledDataSequence > > aNewSeriesData( aOldSeriesData.getLength() ); 147 for( sal_Int32 i=0; i<aOldSeriesData.getLength(); ++i ) 148 { 149 sal_Int32 nNewIndex( m_bDataInColumns ? m_rInternalData.appendColumn() : m_rInternalData.appendRow() ); 150 OUString aIdentifier( OUString::valueOf( nNewIndex )); 151 //@todo: deal also with genericXDataSequence 152 Reference< chart2::data::XNumericalDataSequence > xValues( aOldSeriesData[i]->getValues(), uno::UNO_QUERY ); 153 Reference< chart2::data::XTextualDataSequence > xLabel( aOldSeriesData[i]->getLabel(), uno::UNO_QUERY ); 154 Reference< chart2::data::XDataSequence > xNewValues; 155 156 if( xValues.is() ) 157 { 158 ::std::vector< double > aValues( ContainerHelper::SequenceToVector( xValues->getNumericalData())); 159 if( m_bDataInColumns ) 160 m_rInternalData.setColumnValues( nNewIndex, aValues ); 161 else 162 m_rInternalData.setRowValues( nNewIndex, aValues ); 163 if( m_bConnectToModel ) 164 { 165 xNewValues.set( m_rProvider.createDataSequenceByRangeRepresentation( aIdentifier )); 166 comphelper::copyProperties( 167 Reference< beans::XPropertySet >( xValues, uno::UNO_QUERY ), 168 Reference< beans::XPropertySet >( xNewValues, uno::UNO_QUERY )); 169 } 170 } 171 172 if( xLabel.is() ) 173 { 174 if( m_bDataInColumns ) 175 m_rInternalData.setComplexColumnLabel( nNewIndex, ContainerHelper::SequenceToVector( lcl_StringToAnySequence( xLabel->getTextualData() ) ) ); 176 else 177 m_rInternalData.setComplexRowLabel( nNewIndex, ContainerHelper::SequenceToVector( lcl_StringToAnySequence( xLabel->getTextualData() ) ) ); 178 if( m_bConnectToModel ) 179 { 180 Reference< chart2::data::XDataSequence > xNewLabel( 181 m_rProvider.createDataSequenceByRangeRepresentation( lcl_aLabelRangePrefix + aIdentifier )); 182 comphelper::copyProperties( 183 Reference< beans::XPropertySet >( xLabel, uno::UNO_QUERY ), 184 Reference< beans::XPropertySet >( xNewLabel, uno::UNO_QUERY )); 185 aNewSeriesData[i] = Reference< chart2::data::XLabeledDataSequence >( 186 new LabeledDataSequence( xNewValues, xNewLabel )); 187 } 188 } 189 else 190 { 191 if( m_bConnectToModel ) 192 aNewSeriesData[i] = Reference< chart2::data::XLabeledDataSequence >( 193 new LabeledDataSequence( xNewValues )); 194 } 195 } 196 if( m_bConnectToModel ) 197 xSink->setData( aNewSeriesData ); 198 } 199 } 200 201 private: 202 InternalData & m_rInternalData; 203 InternalDataProvider & m_rProvider; 204 bool m_bConnectToModel; 205 bool m_bDataInColumns; 206 }; 207 208 struct lcl_copyFromLevel : public ::std::unary_function< vector< uno::Any >, uno::Any > 209 { 210 public: 211 212 explicit lcl_copyFromLevel( sal_Int32 nLevel ) : m_nLevel( nLevel ) 213 {} 214 215 uno::Any operator() ( const vector< uno::Any >& rVector ) 216 { 217 uno::Any aRet; 218 if( m_nLevel < static_cast< sal_Int32 >(rVector.size()) ) 219 aRet = rVector[m_nLevel]; 220 return aRet; 221 } 222 223 private: 224 sal_Int32 m_nLevel; 225 }; 226 227 struct lcl_getStringFromLevelVector : public ::std::unary_function< vector< uno::Any >, OUString > 228 { 229 public: 230 231 explicit lcl_getStringFromLevelVector( sal_Int32 nLevel ) : m_nLevel( nLevel ) 232 {} 233 234 OUString operator() ( const vector< uno::Any >& rVector ) 235 { 236 OUString aString; 237 if( m_nLevel < static_cast< sal_Int32 >(rVector.size()) ) 238 aString = CommonFunctors::AnyToString()(rVector[m_nLevel]); 239 return aString; 240 } 241 242 private: 243 sal_Int32 m_nLevel; 244 }; 245 246 247 struct lcl_setAnyAtLevel : public ::std::binary_function< vector< uno::Any >, uno::Any, vector< uno::Any > > 248 { 249 public: 250 251 explicit lcl_setAnyAtLevel( sal_Int32 nLevel ) : m_nLevel( nLevel ) 252 {} 253 254 vector< uno::Any > operator() ( const vector< uno::Any >& rVector, const uno::Any& rNewValue ) 255 { 256 vector< uno::Any > aRet( rVector ); 257 if( m_nLevel >= static_cast< sal_Int32 >(aRet.size()) ) 258 aRet.resize( m_nLevel+1 ); 259 aRet[ m_nLevel ]=rNewValue; 260 return aRet; 261 } 262 263 private: 264 sal_Int32 m_nLevel; 265 }; 266 267 struct lcl_setAnyAtLevelFromStringSequence : public ::std::binary_function< vector< uno::Any >, OUString, vector< uno::Any > > 268 { 269 public: 270 271 explicit lcl_setAnyAtLevelFromStringSequence( sal_Int32 nLevel ) : m_nLevel( nLevel ) 272 {} 273 274 vector< uno::Any > operator() ( const vector< uno::Any >& rVector, const OUString& rNewValue ) 275 { 276 vector< uno::Any > aRet( rVector ); 277 if( m_nLevel >= static_cast< sal_Int32 >(aRet.size()) ) 278 aRet.resize( m_nLevel+1 ); 279 aRet[ m_nLevel ]=uno::makeAny(rNewValue); 280 return aRet; 281 } 282 283 private: 284 sal_Int32 m_nLevel; 285 }; 286 287 struct lcl_insertAnyAtLevel : public ::std::unary_function< vector< uno::Any >, void > 288 { 289 public: 290 291 explicit lcl_insertAnyAtLevel( sal_Int32 nLevel ) : m_nLevel( nLevel ) 292 {} 293 294 void operator() ( vector< uno::Any >& rVector ) 295 { 296 if( m_nLevel > static_cast< sal_Int32 >(rVector.size()) ) 297 rVector.resize( m_nLevel ); 298 299 vector< uno::Any >::iterator aIt( rVector.begin() ); 300 for( sal_Int32 nN=0; aIt<rVector.end(); aIt++, nN++) 301 { 302 if( nN==m_nLevel ) 303 break; 304 } 305 rVector.insert( aIt, uno::Any() ); 306 } 307 308 private: 309 sal_Int32 m_nLevel; 310 }; 311 312 struct lcl_removeAnyAtLevel : public ::std::unary_function< vector< uno::Any >, void > 313 { 314 public: 315 316 explicit lcl_removeAnyAtLevel( sal_Int32 nLevel ) : m_nLevel( nLevel ) 317 {} 318 319 void operator() ( vector< uno::Any >& rVector ) 320 { 321 vector< uno::Any >::iterator aIt( rVector.begin() ); 322 for( sal_Int32 nN=0; aIt<rVector.end(); aIt++, nN++) 323 { 324 if( nN==m_nLevel ) 325 { 326 rVector.erase( aIt ); 327 break; 328 } 329 } 330 } 331 332 private: 333 sal_Int32 m_nLevel; 334 }; 335 336 } // anonymous namespace 337 338 // ================================================================================ 339 340 InternalDataProvider::InternalDataProvider( const Reference< uno::XComponentContext > & /*_xContext*/) 341 : m_bDataInColumns( true ) 342 {} 343 344 InternalDataProvider::InternalDataProvider( const Reference< chart2::XChartDocument > & xChartDoc, bool bConnectToModel ) 345 : m_bDataInColumns( true ) 346 { 347 try 348 { 349 Reference< chart2::XDiagram > xDiagram( ChartModelHelper::findDiagram( xChartDoc ) ); 350 if( xDiagram.is()) 351 { 352 Reference< frame::XModel > xChartModel( xChartDoc, uno::UNO_QUERY ); 353 354 //data in columns? 355 { 356 ::rtl::OUString aRangeString; 357 bool bFirstCellAsLabel = true; 358 bool bHasCategories = true; 359 uno::Sequence< sal_Int32 > aSequenceMapping; 360 DataSourceHelper::detectRangeSegmentation( xChartModel, aRangeString, aSequenceMapping, m_bDataInColumns, bFirstCellAsLabel, bHasCategories ); 361 } 362 363 // categories 364 { 365 vector< vector< uno::Any > > aNewCategories;//inner count is level 366 { 367 ExplicitCategoriesProvider aExplicitCategoriesProvider( ChartModelHelper::getFirstCoordinateSystem(xChartModel), xChartModel ); 368 369 const Sequence< Reference< chart2::data::XLabeledDataSequence> >& rSplitCategoriesList( aExplicitCategoriesProvider.getSplitCategoriesList() ); 370 sal_Int32 nLevelCount = rSplitCategoriesList.getLength(); 371 for( sal_Int32 nL = 0; nL<nLevelCount; nL++ ) 372 { 373 Reference< chart2::data::XLabeledDataSequence > xLDS( rSplitCategoriesList[nL] ); 374 if( !xLDS.is() ) 375 continue; 376 Sequence< uno::Any > aDataSeq; 377 Reference< chart2::data::XDataSequence > xSeq( xLDS->getValues() ); 378 if( xSeq.is() ) 379 aDataSeq = xSeq->getData(); 380 sal_Int32 nLength = aDataSeq.getLength(); 381 sal_Int32 nCatLength = static_cast< sal_Int32 >(aNewCategories.size()); 382 if( nCatLength < nLength ) 383 aNewCategories.resize( nLength ); 384 else if( nLength < nCatLength ) 385 aDataSeq.realloc( nCatLength ); 386 transform( aNewCategories.begin(), aNewCategories.end(), aDataSeq.getConstArray(), 387 aNewCategories.begin(), lcl_setAnyAtLevel(nL) ); 388 } 389 if( !nLevelCount ) 390 { 391 Sequence< OUString > aSimplecategories = aExplicitCategoriesProvider.getSimpleCategories(); 392 sal_Int32 nLength = aSimplecategories.getLength(); 393 aNewCategories.reserve( nLength ); 394 for( sal_Int32 nN=0; nN<nLength; nN++) 395 { 396 vector< uno::Any > aVector(1); 397 aVector[0] = uno::makeAny( aSimplecategories[nN] ); 398 aNewCategories.push_back( aVector ); 399 } 400 } 401 } 402 403 if( m_bDataInColumns ) 404 m_aInternalData.setComplexRowLabels( aNewCategories ); 405 else 406 m_aInternalData.setComplexColumnLabels( aNewCategories ); 407 if( bConnectToModel ) 408 DiagramHelper::setCategoriesToDiagram( new LabeledDataSequence( 409 createDataSequenceByRangeRepresentation( lcl_aCategoriesRangeName )), xDiagram ); 410 } 411 412 // data series 413 ::std::vector< Reference< chart2::XDataSeries > > aSeriesVector( ChartModelHelper::getDataSeries( xChartDoc )); 414 ::std::for_each( aSeriesVector.begin(), aSeriesVector.end(), lcl_internalizeSeries( m_aInternalData, *this, bConnectToModel, m_bDataInColumns ) ); 415 } 416 } 417 catch( const uno::Exception & ex ) 418 { 419 ASSERT_EXCEPTION( ex ); 420 } 421 } 422 423 // copy-CTOR 424 InternalDataProvider::InternalDataProvider( const InternalDataProvider & rOther ) : 425 impl::InternalDataProvider_Base(), 426 m_aSequenceMap( rOther.m_aSequenceMap ), 427 m_aInternalData( rOther.m_aInternalData ), 428 m_bDataInColumns( rOther.m_bDataInColumns ) 429 {} 430 431 InternalDataProvider::~InternalDataProvider() 432 {} 433 434 void InternalDataProvider::lcl_addDataSequenceToMap( 435 const OUString & rRangeRepresentation, 436 const Reference< chart2::data::XDataSequence > & xSequence ) 437 { 438 m_aSequenceMap.insert( 439 tSequenceMap::value_type( 440 rRangeRepresentation, 441 uno::WeakReference< chart2::data::XDataSequence >( xSequence ))); 442 } 443 444 void InternalDataProvider::lcl_deleteMapReferences( const OUString & rRangeRepresentation ) 445 { 446 // set sequence to deleted by setting its range to an empty string 447 tSequenceMapRange aRange( m_aSequenceMap.equal_range( rRangeRepresentation )); 448 for( tSequenceMap::iterator aIt( aRange.first ); aIt != aRange.second; ++aIt ) 449 { 450 Reference< chart2::data::XDataSequence > xSeq( aIt->second ); 451 if( xSeq.is()) 452 { 453 Reference< container::XNamed > xNamed( xSeq, uno::UNO_QUERY ); 454 if( xNamed.is()) 455 xNamed->setName( OUString()); 456 } 457 } 458 // remove from map 459 m_aSequenceMap.erase( aRange.first, aRange.second ); 460 } 461 462 void InternalDataProvider::lcl_adaptMapReferences( 463 const OUString & rOldRangeRepresentation, 464 const OUString & rNewRangeRepresentation ) 465 { 466 tSequenceMapRange aRange( m_aSequenceMap.equal_range( rOldRangeRepresentation )); 467 tSequenceMap aNewElements; 468 for( tSequenceMap::iterator aIt( aRange.first ); aIt != aRange.second; ++aIt ) 469 { 470 Reference< chart2::data::XDataSequence > xSeq( aIt->second ); 471 if( xSeq.is()) 472 { 473 Reference< container::XNamed > xNamed( xSeq, uno::UNO_QUERY ); 474 if( xNamed.is()) 475 xNamed->setName( rNewRangeRepresentation ); 476 } 477 aNewElements.insert( tSequenceMap::value_type( rNewRangeRepresentation, aIt->second )); 478 } 479 // erase map values for old index 480 m_aSequenceMap.erase( aRange.first, aRange.second ); 481 // add new entries for values with new index 482 ::std::copy( aNewElements.begin(), aNewElements.end(), 483 ::std::inserter( m_aSequenceMap, 484 m_aSequenceMap.upper_bound( rNewRangeRepresentation ))); 485 } 486 487 void InternalDataProvider::lcl_increaseMapReferences( 488 sal_Int32 nBegin, sal_Int32 nEnd ) 489 { 490 for( sal_Int32 nIndex = nEnd - 1; nIndex >= nBegin; --nIndex ) 491 { 492 lcl_adaptMapReferences( OUString::valueOf( nIndex ), 493 OUString::valueOf( nIndex + 1 )); 494 lcl_adaptMapReferences( lcl_aLabelRangePrefix + OUString::valueOf( nIndex ), 495 lcl_aLabelRangePrefix + OUString::valueOf( nIndex + 1 )); 496 } 497 } 498 499 void InternalDataProvider::lcl_decreaseMapReferences( 500 sal_Int32 nBegin, sal_Int32 nEnd ) 501 { 502 for( sal_Int32 nIndex = nBegin; nIndex < nEnd; ++nIndex ) 503 { 504 lcl_adaptMapReferences( OUString::valueOf( nIndex ), 505 OUString::valueOf( nIndex - 1 )); 506 lcl_adaptMapReferences( lcl_aLabelRangePrefix + OUString::valueOf( nIndex ), 507 lcl_aLabelRangePrefix + OUString::valueOf( nIndex - 1 )); 508 } 509 } 510 511 Reference< chart2::data::XDataSequence > InternalDataProvider::lcl_createDataSequenceAndAddToMap( 512 const OUString & rRangeRepresentation ) 513 { 514 Reference< chart2::data::XDataSequence > xSeq( 515 new UncachedDataSequence( this, rRangeRepresentation )); 516 lcl_addDataSequenceToMap( rRangeRepresentation, xSeq ); 517 return xSeq; 518 } 519 520 Reference< chart2::data::XDataSequence > InternalDataProvider::lcl_createDataSequenceAndAddToMap( 521 const OUString & rRangeRepresentation, 522 const OUString & rRole ) 523 { 524 Reference< chart2::data::XDataSequence > xSeq( 525 new UncachedDataSequence( this, rRangeRepresentation, rRole )); 526 lcl_addDataSequenceToMap( rRangeRepresentation, xSeq ); 527 return xSeq; 528 } 529 530 void InternalDataProvider::createDefaultData() 531 { 532 m_aInternalData.createDefaultData(); 533 } 534 535 // ____ XDataProvider ____ 536 ::sal_Bool SAL_CALL InternalDataProvider::createDataSourcePossible( const Sequence< beans::PropertyValue >& /* aArguments */ ) 537 throw (uno::RuntimeException) 538 { 539 return true; 540 } 541 542 namespace 543 { 544 545 sal_Int32 lcl_getInnerLevelCount( const vector< vector< uno::Any > >& rLabels ) 546 { 547 sal_Int32 nCount = 1;//minimum is 1! 548 vector< vector< uno::Any > >::const_iterator aLevelIt( rLabels.begin() ); 549 vector< vector< uno::Any > >::const_iterator aLevelEnd( rLabels.end() ); 550 for( ;aLevelIt!=aLevelEnd; ++aLevelIt ) 551 { 552 const vector< uno::Any >& rCurrentLevelLabels = *aLevelIt; 553 nCount = std::max<sal_Int32>( rCurrentLevelLabels.size(), nCount ); 554 } 555 return nCount; 556 } 557 558 }//end anonymous namespace 559 560 Reference< chart2::data::XDataSource > SAL_CALL InternalDataProvider::createDataSource( 561 const Sequence< beans::PropertyValue >& aArguments ) 562 throw (lang::IllegalArgumentException, 563 uno::RuntimeException) 564 { 565 OUString aRangeRepresentation; 566 bool bUseColumns = true; 567 bool bFirstCellAsLabel = true; 568 bool bHasCategories = true; 569 uno::Sequence< sal_Int32 > aSequenceMapping; 570 DataSourceHelper::readArguments( aArguments, aRangeRepresentation, aSequenceMapping, bUseColumns, bFirstCellAsLabel, bHasCategories ); 571 572 if( aRangeRepresentation.equals( lcl_aCategoriesRangeName ) ) 573 { 574 //return split complex categories if we have any: 575 ::std::vector< Reference< chart2::data::XLabeledDataSequence > > aComplexCategories; 576 vector< vector< uno::Any > > aCategories( m_bDataInColumns ? m_aInternalData.getComplexRowLabels() : m_aInternalData.getComplexColumnLabels()); 577 if( bUseColumns==m_bDataInColumns ) 578 { 579 sal_Int32 nLevelCount = lcl_getInnerLevelCount( aCategories ); 580 for( sal_Int32 nL=0; nL<nLevelCount; nL++ ) 581 aComplexCategories.push_back( new LabeledDataSequence( 582 new UncachedDataSequence( this 583 , lcl_aCategoriesLevelRangeNamePrefix + OUString::valueOf( nL ) 584 , lcl_aCategoriesRoleName ) ) ); 585 } 586 else 587 { 588 sal_Int32 nPointCount = m_bDataInColumns ? m_aInternalData.getRowCount() : m_aInternalData.getColumnCount(); 589 for( sal_Int32 nP=0; nP<nPointCount; nP++ ) 590 aComplexCategories.push_back( new LabeledDataSequence( 591 new UncachedDataSequence( this 592 , lcl_aCategoriesPointRangeNamePrefix + OUString::valueOf( nP ) 593 , lcl_aCategoriesRoleName ) ) ); 594 } 595 //don't add the created sequences to the map as they are used temporarily only ... 596 return new DataSource( ContainerHelper::ContainerToSequence(aComplexCategories) ); 597 } 598 599 OSL_ASSERT( aRangeRepresentation.equals( lcl_aCompleteRange )); 600 601 ::std::vector< Reference< chart2::data::XLabeledDataSequence > > aResultLSeqVec; 602 603 // categories 604 if( bHasCategories ) 605 aResultLSeqVec.push_back( 606 new LabeledDataSequence( lcl_createDataSequenceAndAddToMap( lcl_aCategoriesRangeName, lcl_aCategoriesRoleName ) ) ); 607 608 // data with labels 609 ::std::vector< Reference< chart2::data::XLabeledDataSequence > > aDataVec; 610 const sal_Int32 nCount = (bUseColumns ? m_aInternalData.getColumnCount() : m_aInternalData.getRowCount()); 611 for( sal_Int32 nIdx=0; nIdx<nCount; ++nIdx ) 612 { 613 aDataVec.push_back( 614 new LabeledDataSequence( 615 lcl_createDataSequenceAndAddToMap( OUString::valueOf( nIdx )), 616 lcl_createDataSequenceAndAddToMap( lcl_aLabelRangePrefix + OUString::valueOf( nIdx )))); 617 } 618 619 // attention: this data provider has the limitation that it stores 620 // internally if data comes from columns or rows. It is intended for 621 // creating only one used data source. 622 // @todo: add this information in the range representation strings 623 m_bDataInColumns = bUseColumns; 624 625 //reorder labeled sequences according to aSequenceMapping; ignore categories 626 for( sal_Int32 nNewIndex = 0; nNewIndex < aSequenceMapping.getLength(); nNewIndex++ ) 627 { 628 std::vector< LabeledDataSequence* >::size_type nOldIndex = aSequenceMapping[nNewIndex]; 629 if( nOldIndex < aDataVec.size() ) 630 { 631 if( aDataVec[nOldIndex].is() ) 632 { 633 aResultLSeqVec.push_back( aDataVec[nOldIndex] ); 634 aDataVec[nOldIndex] = 0; 635 } 636 } 637 } 638 639 //add left over data sequences to result 640 ::std::vector< Reference< chart2::data::XLabeledDataSequence > >::iterator aIt(aDataVec.begin()); 641 const ::std::vector< Reference< chart2::data::XLabeledDataSequence > >::const_iterator aEndIt(aDataVec.end()); 642 for( ;aIt!=aEndIt; ++aIt) 643 { 644 if( aIt->is() ) 645 aResultLSeqVec.push_back( *aIt ); 646 } 647 648 return new DataSource( ContainerHelper::ContainerToSequence(aResultLSeqVec) ); 649 } 650 651 Sequence< beans::PropertyValue > SAL_CALL InternalDataProvider::detectArguments( 652 const Reference< chart2::data::XDataSource >& /* xDataSource */ ) 653 throw (uno::RuntimeException) 654 { 655 Sequence< beans::PropertyValue > aArguments( 4 ); 656 aArguments[0] = beans::PropertyValue( 657 C2U("CellRangeRepresentation"), -1, uno::makeAny( lcl_aCompleteRange ), 658 beans::PropertyState_DIRECT_VALUE ); 659 aArguments[1] = beans::PropertyValue( 660 C2U("DataRowSource"), -1, uno::makeAny( 661 m_bDataInColumns 662 ? ::com::sun::star::chart::ChartDataRowSource_COLUMNS 663 : ::com::sun::star::chart::ChartDataRowSource_ROWS ), 664 beans::PropertyState_DIRECT_VALUE ); 665 // internal data always contains labels and categories 666 aArguments[2] = beans::PropertyValue( 667 C2U("FirstCellAsLabel"), -1, uno::makeAny( true ), beans::PropertyState_DIRECT_VALUE ); 668 aArguments[3] = beans::PropertyValue( 669 C2U("HasCategories"), -1, uno::makeAny( true ), beans::PropertyState_DIRECT_VALUE ); 670 671 // #i85913# Sequence Mapping is not needed for internal data, as it is 672 // applied to the data when the data source is created. 673 674 return aArguments; 675 } 676 677 ::sal_Bool SAL_CALL InternalDataProvider::createDataSequenceByRangeRepresentationPossible( const OUString& /* aRangeRepresentation */ ) 678 throw (uno::RuntimeException) 679 { 680 return true; 681 } 682 683 Reference< chart2::data::XDataSequence > SAL_CALL InternalDataProvider::createDataSequenceByRangeRepresentation( 684 const OUString& aRangeRepresentation ) 685 throw (lang::IllegalArgumentException, 686 uno::RuntimeException) 687 { 688 if( aRangeRepresentation.match( lcl_aCategoriesRangeName )) 689 { 690 OSL_ASSERT( aRangeRepresentation.equals( lcl_aCategoriesRangeName ) );//it is not expected nor implmented that only parts of the categories are really requested 691 692 // categories 693 return lcl_createDataSequenceAndAddToMap( lcl_aCategoriesRangeName, lcl_aCategoriesRoleName ); 694 } 695 else if( aRangeRepresentation.match( lcl_aLabelRangePrefix )) 696 { 697 // label 698 sal_Int32 nIndex = aRangeRepresentation.copy( lcl_aLabelRangePrefix.getLength()).toInt32(); 699 return lcl_createDataSequenceAndAddToMap( lcl_aLabelRangePrefix + OUString::valueOf( nIndex )); 700 } 701 else if( aRangeRepresentation.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "last" ))) 702 { 703 sal_Int32 nIndex = (m_bDataInColumns 704 ? m_aInternalData.getColumnCount() 705 : m_aInternalData.getRowCount()) - 1; 706 return lcl_createDataSequenceAndAddToMap( OUString::valueOf( nIndex )); 707 } 708 else if( aRangeRepresentation.getLength()) 709 { 710 // data 711 sal_Int32 nIndex = aRangeRepresentation.toInt32(); 712 return lcl_createDataSequenceAndAddToMap( OUString::valueOf( nIndex )); 713 } 714 715 return Reference< chart2::data::XDataSequence >(); 716 } 717 718 Reference< sheet::XRangeSelection > SAL_CALL InternalDataProvider::getRangeSelection() 719 throw (uno::RuntimeException) 720 { 721 // there is no range selection component 722 return Reference< sheet::XRangeSelection >(); 723 } 724 725 // ____ XInternalDataProvider ____ 726 ::sal_Bool SAL_CALL InternalDataProvider::hasDataByRangeRepresentation( const OUString& aRange ) 727 throw (uno::RuntimeException) 728 { 729 sal_Bool bResult = false; 730 731 if( aRange.match( lcl_aCategoriesRangeName )) 732 { 733 OSL_ASSERT( aRange.equals( lcl_aCategoriesRangeName ) );//it is not expected nor implmented that only parts of the categories are really requested 734 bResult = true; 735 } 736 else if( aRange.match( lcl_aLabelRangePrefix )) 737 { 738 sal_Int32 nIndex = aRange.copy( lcl_aLabelRangePrefix.getLength()).toInt32(); 739 bResult = (nIndex < (m_bDataInColumns ? m_aInternalData.getColumnCount(): m_aInternalData.getRowCount())); 740 } 741 else 742 { 743 sal_Int32 nIndex = aRange.toInt32(); 744 bResult = (nIndex < (m_bDataInColumns ? m_aInternalData.getColumnCount(): m_aInternalData.getRowCount())); 745 } 746 747 return bResult; 748 } 749 750 Sequence< uno::Any > SAL_CALL InternalDataProvider::getDataByRangeRepresentation( const OUString& aRange ) 751 throw (uno::RuntimeException) 752 { 753 Sequence< uno::Any > aResult; 754 755 if( aRange.match( lcl_aLabelRangePrefix ) ) 756 { 757 sal_Int32 nIndex = aRange.copy( lcl_aLabelRangePrefix.getLength()).toInt32(); 758 vector< uno::Any > aComplexLabel = m_bDataInColumns 759 ? m_aInternalData.getComplexColumnLabel( nIndex ) 760 : m_aInternalData.getComplexRowLabel( nIndex ); 761 if( !aComplexLabel.empty() ) 762 aResult = ContainerHelper::ContainerToSequence(aComplexLabel); 763 } 764 else if( aRange.match( lcl_aCategoriesPointRangeNamePrefix ) ) 765 { 766 sal_Int32 nPointIndex = aRange.copy( lcl_aCategoriesPointRangeNamePrefix.getLength() ).toInt32(); 767 vector< uno::Any > aComplexCategory = m_bDataInColumns 768 ? m_aInternalData.getComplexRowLabel( nPointIndex ) 769 : m_aInternalData.getComplexColumnLabel( nPointIndex ); 770 if( !aComplexCategory.empty() ) 771 aResult = ContainerHelper::ContainerToSequence(aComplexCategory); 772 } 773 else if( aRange.match( lcl_aCategoriesLevelRangeNamePrefix ) ) 774 { 775 sal_Int32 nLevel = aRange.copy( lcl_aCategoriesLevelRangeNamePrefix.getLength() ).toInt32(); 776 vector< vector< uno::Any > > aCategories( m_bDataInColumns ? m_aInternalData.getComplexRowLabels() : m_aInternalData.getComplexColumnLabels()); 777 if( nLevel < lcl_getInnerLevelCount( aCategories ) ) 778 { 779 aResult.realloc( aCategories.size() ); 780 transform( aCategories.begin(), aCategories.end(), 781 aResult.getArray(), lcl_copyFromLevel(nLevel) ); 782 } 783 } 784 else if( aRange.equals( lcl_aCategoriesRangeName ) ) 785 { 786 vector< vector< uno::Any > > aCategories( m_bDataInColumns ? m_aInternalData.getComplexRowLabels() : m_aInternalData.getComplexColumnLabels()); 787 sal_Int32 nLevelCount = lcl_getInnerLevelCount( aCategories ); 788 if( nLevelCount == 1 ) 789 { 790 sal_Int32 nL=0; 791 aResult = this->getDataByRangeRepresentation( lcl_aCategoriesLevelRangeNamePrefix + OUString::valueOf( nL ) ); 792 } 793 else 794 { 795 Sequence< OUString > aLabels = m_bDataInColumns ? this->getRowDescriptions() : this->getColumnDescriptions(); 796 aResult.realloc( aLabels.getLength() ); 797 transform( aLabels.getConstArray(), aLabels.getConstArray() + aLabels.getLength(), 798 aResult.getArray(), CommonFunctors::makeAny< OUString >() ); 799 } 800 } 801 else 802 { 803 sal_Int32 nIndex = aRange.toInt32(); 804 if( nIndex >= 0 ) 805 { 806 Sequence< double > aData; 807 if( m_bDataInColumns ) 808 aData = m_aInternalData.getColumnValues(nIndex); 809 else 810 aData = m_aInternalData.getRowValues(nIndex); 811 if( aData.getLength() ) 812 { 813 aResult.realloc( aData.getLength()); 814 transform( aData.getConstArray(), aData.getConstArray() + aData.getLength(), 815 aResult.getArray(), CommonFunctors::makeAny< double >()); 816 } 817 } 818 } 819 820 return aResult; 821 } 822 823 void SAL_CALL InternalDataProvider::setDataByRangeRepresentation( 824 const OUString& aRange, const Sequence< uno::Any >& aNewData ) 825 throw (uno::RuntimeException) 826 { 827 vector< uno::Any > aNewVector( ContainerHelper::SequenceToVector(aNewData) ); 828 if( aRange.match( lcl_aLabelRangePrefix ) ) 829 { 830 sal_uInt32 nIndex = aRange.copy( lcl_aLabelRangePrefix.getLength()).toInt32(); 831 if( m_bDataInColumns ) 832 m_aInternalData.setComplexColumnLabel( nIndex, aNewVector ); 833 else 834 m_aInternalData.setComplexRowLabel( nIndex, aNewVector ); 835 } 836 else if( aRange.match( lcl_aCategoriesPointRangeNamePrefix ) ) 837 { 838 sal_Int32 nPointIndex = aRange.copy( lcl_aCategoriesLevelRangeNamePrefix.getLength()).toInt32(); 839 if( m_bDataInColumns ) 840 m_aInternalData.setComplexRowLabel( nPointIndex, aNewVector ); 841 else 842 m_aInternalData.setComplexColumnLabel( nPointIndex, aNewVector ); 843 } 844 else if( aRange.match( lcl_aCategoriesLevelRangeNamePrefix ) ) 845 { 846 sal_Int32 nLevel = aRange.copy( lcl_aCategoriesLevelRangeNamePrefix.getLength()).toInt32(); 847 vector< vector< uno::Any > > aComplexCategories = m_bDataInColumns ? m_aInternalData.getComplexRowLabels() : m_aInternalData.getComplexColumnLabels(); 848 849 //ensure equal length 850 if( aNewVector.size() > aComplexCategories.size() ) 851 aComplexCategories.resize( aNewVector.size() ); 852 else if( aNewVector.size() < aComplexCategories.size() ) 853 aNewVector.resize( aComplexCategories.size() ); 854 855 transform( aComplexCategories.begin(), aComplexCategories.end(), aNewVector.begin(), 856 aComplexCategories.begin(), lcl_setAnyAtLevel(nLevel) ); 857 858 if( m_bDataInColumns ) 859 m_aInternalData.setComplexRowLabels( aComplexCategories ); 860 else 861 m_aInternalData.setComplexColumnLabels( aComplexCategories ); 862 } 863 else if( aRange.equals( lcl_aCategoriesRangeName ) ) 864 { 865 vector< vector< uno::Any > > aComplexCategories; 866 aComplexCategories.resize( aNewVector.size() ); 867 transform( aComplexCategories.begin(), aComplexCategories.end(), aNewVector.begin(), 868 aComplexCategories.begin(), lcl_setAnyAtLevel(0) ); 869 if( m_bDataInColumns ) 870 m_aInternalData.setComplexRowLabels( aComplexCategories ); 871 else 872 m_aInternalData.setComplexColumnLabels( aComplexCategories ); 873 } 874 else 875 { 876 sal_Int32 nIndex = aRange.toInt32(); 877 if( nIndex>=0 ) 878 { 879 vector< double > aNewDataVec; 880 transform( aNewData.getConstArray(), aNewData.getConstArray() + aNewData.getLength(), 881 back_inserter( aNewDataVec ), CommonFunctors::AnyToDouble()); 882 if( m_bDataInColumns ) 883 m_aInternalData.setColumnValues( nIndex, aNewDataVec ); 884 else 885 m_aInternalData.setRowValues( nIndex, aNewDataVec ); 886 } 887 } 888 } 889 890 void SAL_CALL InternalDataProvider::insertSequence( ::sal_Int32 nAfterIndex ) 891 throw (uno::RuntimeException) 892 { 893 if( m_bDataInColumns ) 894 { 895 lcl_increaseMapReferences( nAfterIndex + 1, m_aInternalData.getColumnCount()); 896 m_aInternalData.insertColumn( nAfterIndex ); 897 } 898 else 899 { 900 lcl_increaseMapReferences( nAfterIndex + 1, m_aInternalData.getRowCount()); 901 m_aInternalData.insertRow( nAfterIndex ); 902 } 903 } 904 905 void SAL_CALL InternalDataProvider::deleteSequence( ::sal_Int32 nAtIndex ) 906 throw (uno::RuntimeException) 907 { 908 lcl_deleteMapReferences( OUString::valueOf( nAtIndex )); 909 lcl_deleteMapReferences( lcl_aLabelRangePrefix + OUString::valueOf( nAtIndex )); 910 if( m_bDataInColumns ) 911 { 912 lcl_decreaseMapReferences( nAtIndex + 1, m_aInternalData.getColumnCount()); 913 m_aInternalData.deleteColumn( nAtIndex ); 914 } 915 else 916 { 917 lcl_decreaseMapReferences( nAtIndex + 1, m_aInternalData.getRowCount()); 918 m_aInternalData.deleteRow( nAtIndex ); 919 } 920 } 921 922 void SAL_CALL InternalDataProvider::appendSequence() 923 throw (uno::RuntimeException) 924 { 925 if( m_bDataInColumns ) 926 m_aInternalData.appendColumn(); 927 else 928 m_aInternalData.appendRow(); 929 } 930 931 void SAL_CALL InternalDataProvider::insertComplexCategoryLevel( sal_Int32 nLevel ) 932 throw (uno::RuntimeException) 933 { 934 OSL_ENSURE( nLevel> 0, "you can only insert category levels > 0" );//the first categories level cannot be deleted, check the calling code for error 935 if( nLevel>0 ) 936 { 937 vector< vector< uno::Any > > aComplexCategories = m_bDataInColumns ? m_aInternalData.getComplexRowLabels() : m_aInternalData.getComplexColumnLabels(); 938 ::std::for_each( aComplexCategories.begin(), aComplexCategories.end(), lcl_insertAnyAtLevel(nLevel) ); 939 if( m_bDataInColumns ) 940 m_aInternalData.setComplexRowLabels( aComplexCategories ); 941 else 942 m_aInternalData.setComplexColumnLabels( aComplexCategories ); 943 944 tSequenceMapRange aRange( m_aSequenceMap.equal_range( lcl_aCategoriesRangeName )); 945 ::std::for_each( aRange.first, aRange.second, lcl_setModified()); 946 } 947 } 948 void SAL_CALL InternalDataProvider::deleteComplexCategoryLevel( sal_Int32 nLevel ) 949 throw (uno::RuntimeException) 950 { 951 OSL_ENSURE( nLevel>0, "you can only delete category levels > 0" );//the first categories level cannot be deleted, check the calling code for error 952 if( nLevel>0 ) 953 { 954 vector< vector< uno::Any > > aComplexCategories = m_bDataInColumns ? m_aInternalData.getComplexRowLabels() : m_aInternalData.getComplexColumnLabels(); 955 ::std::for_each( aComplexCategories.begin(), aComplexCategories.end(), lcl_removeAnyAtLevel(nLevel) ); 956 if( m_bDataInColumns ) 957 m_aInternalData.setComplexRowLabels( aComplexCategories ); 958 else 959 m_aInternalData.setComplexColumnLabels( aComplexCategories ); 960 961 tSequenceMapRange aRange( m_aSequenceMap.equal_range( lcl_aCategoriesRangeName )); 962 ::std::for_each( aRange.first, aRange.second, lcl_setModified()); 963 } 964 } 965 966 void SAL_CALL InternalDataProvider::insertDataPointForAllSequences( ::sal_Int32 nAfterIndex ) 967 throw (uno::RuntimeException) 968 { 969 sal_Int32 nMaxRep = 0; 970 if( m_bDataInColumns ) 971 { 972 m_aInternalData.insertRow( nAfterIndex ); 973 nMaxRep = m_aInternalData.getColumnCount(); 974 } 975 else 976 { 977 m_aInternalData.insertColumn( nAfterIndex ); 978 nMaxRep = m_aInternalData.getRowCount(); 979 } 980 981 // notify change to all affected ranges 982 tSequenceMap::const_iterator aBegin( m_aSequenceMap.lower_bound( C2U("0"))); 983 tSequenceMap::const_iterator aEnd( m_aSequenceMap.upper_bound( OUString::valueOf( nMaxRep ))); 984 ::std::for_each( aBegin, aEnd, lcl_setModified()); 985 986 tSequenceMapRange aRange( m_aSequenceMap.equal_range( lcl_aCategoriesRangeName )); 987 ::std::for_each( aRange.first, aRange.second, lcl_setModified()); 988 } 989 990 void SAL_CALL InternalDataProvider::deleteDataPointForAllSequences( ::sal_Int32 nAtIndex ) 991 throw (uno::RuntimeException) 992 { 993 sal_Int32 nMaxRep = 0; 994 if( m_bDataInColumns ) 995 { 996 m_aInternalData.deleteRow( nAtIndex ); 997 nMaxRep = m_aInternalData.getColumnCount(); 998 } 999 else 1000 { 1001 m_aInternalData.deleteColumn( nAtIndex ); 1002 nMaxRep = m_aInternalData.getRowCount(); 1003 } 1004 1005 // notify change to all affected ranges 1006 tSequenceMap::const_iterator aBegin( m_aSequenceMap.lower_bound( C2U("0"))); 1007 tSequenceMap::const_iterator aEnd( m_aSequenceMap.upper_bound( OUString::valueOf( nMaxRep ))); 1008 ::std::for_each( aBegin, aEnd, lcl_setModified()); 1009 1010 tSequenceMapRange aRange( m_aSequenceMap.equal_range( lcl_aCategoriesRangeName )); 1011 ::std::for_each( aRange.first, aRange.second, lcl_setModified()); 1012 } 1013 1014 void SAL_CALL InternalDataProvider::swapDataPointWithNextOneForAllSequences( ::sal_Int32 nAtIndex ) 1015 throw (uno::RuntimeException) 1016 { 1017 if( m_bDataInColumns ) 1018 m_aInternalData.swapRowWithNext( nAtIndex ); 1019 else 1020 m_aInternalData.swapColumnWithNext( nAtIndex ); 1021 sal_Int32 nMaxRep = (m_bDataInColumns 1022 ? m_aInternalData.getColumnCount() 1023 : m_aInternalData.getRowCount()); 1024 1025 // notify change to all affected ranges 1026 tSequenceMap::const_iterator aBegin( m_aSequenceMap.lower_bound( C2U("0"))); 1027 tSequenceMap::const_iterator aEnd( m_aSequenceMap.upper_bound( OUString::valueOf( nMaxRep ))); 1028 ::std::for_each( aBegin, aEnd, lcl_setModified()); 1029 1030 tSequenceMapRange aRange( m_aSequenceMap.equal_range( lcl_aCategoriesRangeName )); 1031 ::std::for_each( aRange.first, aRange.second, lcl_setModified()); 1032 } 1033 1034 void SAL_CALL InternalDataProvider::registerDataSequenceForChanges( const Reference< chart2::data::XDataSequence >& xSeq ) 1035 throw (uno::RuntimeException) 1036 { 1037 if( xSeq.is()) 1038 lcl_addDataSequenceToMap( xSeq->getSourceRangeRepresentation(), xSeq ); 1039 } 1040 1041 1042 // ____ XRangeXMLConversion ____ 1043 OUString SAL_CALL InternalDataProvider::convertRangeToXML( const OUString& aRangeRepresentation ) 1044 throw (lang::IllegalArgumentException, 1045 uno::RuntimeException) 1046 { 1047 XMLRangeHelper::CellRange aRange; 1048 aRange.aTableName = OUString(RTL_CONSTASCII_USTRINGPARAM("local-table")); 1049 1050 // attention: this data provider has the limitation that it stores 1051 // internally if data comes from columns or rows. It is intended for 1052 // creating only one used data source. 1053 // @todo: add this information in the range representation strings 1054 if( aRangeRepresentation.match( lcl_aCategoriesRangeName )) 1055 { 1056 OSL_ASSERT( aRangeRepresentation.equals( lcl_aCategoriesRangeName ) );//it is not expected nor implmented that only parts of the categories are really requested 1057 aRange.aUpperLeft.bIsEmpty = false; 1058 if( m_bDataInColumns ) 1059 { 1060 aRange.aUpperLeft.nColumn = 0; 1061 aRange.aUpperLeft.nRow = 1; 1062 aRange.aLowerRight = aRange.aUpperLeft; 1063 aRange.aLowerRight.nRow = m_aInternalData.getRowCount(); 1064 } 1065 else 1066 { 1067 aRange.aUpperLeft.nColumn = 1; 1068 aRange.aUpperLeft.nRow = 0; 1069 aRange.aLowerRight = aRange.aUpperLeft; 1070 aRange.aLowerRight.nColumn = m_aInternalData.getColumnCount(); 1071 } 1072 } 1073 else if( aRangeRepresentation.match( lcl_aLabelRangePrefix )) 1074 { 1075 sal_Int32 nIndex = aRangeRepresentation.copy( lcl_aLabelRangePrefix.getLength()).toInt32(); 1076 aRange.aUpperLeft.bIsEmpty = false; 1077 aRange.aLowerRight.bIsEmpty = true; 1078 if( m_bDataInColumns ) 1079 { 1080 aRange.aUpperLeft.nColumn = nIndex + 1; 1081 aRange.aUpperLeft.nRow = 0; 1082 } 1083 else 1084 { 1085 aRange.aUpperLeft.nColumn = 0; 1086 aRange.aUpperLeft.nRow = nIndex + 1; 1087 } 1088 } 1089 else if( aRangeRepresentation.equals( lcl_aCompleteRange )) 1090 { 1091 aRange.aUpperLeft.bIsEmpty = false; 1092 aRange.aLowerRight.bIsEmpty = false; 1093 aRange.aUpperLeft.nColumn = 0; 1094 aRange.aUpperLeft.nRow = 0; 1095 aRange.aLowerRight.nColumn = m_aInternalData.getColumnCount(); 1096 aRange.aLowerRight.nRow = m_aInternalData.getRowCount(); 1097 } 1098 else 1099 { 1100 sal_Int32 nIndex = aRangeRepresentation.toInt32(); 1101 aRange.aUpperLeft.bIsEmpty = false; 1102 if( m_bDataInColumns ) 1103 { 1104 aRange.aUpperLeft.nColumn = nIndex + 1; 1105 aRange.aUpperLeft.nRow = 1; 1106 aRange.aLowerRight = aRange.aUpperLeft; 1107 aRange.aLowerRight.nRow = m_aInternalData.getRowCount(); 1108 } 1109 else 1110 { 1111 aRange.aUpperLeft.nColumn = 1; 1112 aRange.aUpperLeft.nRow = nIndex + 1; 1113 aRange.aLowerRight = aRange.aUpperLeft; 1114 aRange.aLowerRight.nColumn = m_aInternalData.getColumnCount(); 1115 } 1116 } 1117 1118 return XMLRangeHelper::getXMLStringFromCellRange( aRange ); 1119 } 1120 1121 OUString SAL_CALL InternalDataProvider::convertRangeFromXML( const OUString& aXMLRange ) 1122 throw (lang::IllegalArgumentException, 1123 uno::RuntimeException) 1124 { 1125 XMLRangeHelper::CellRange aRange( XMLRangeHelper::getCellRangeFromXMLString( aXMLRange )); 1126 if( aRange.aUpperLeft.bIsEmpty ) 1127 { 1128 OSL_ENSURE( aRange.aLowerRight.bIsEmpty, "Weird Range" ); 1129 return OUString(); 1130 } 1131 1132 // "all" 1133 if( !aRange.aLowerRight.bIsEmpty && 1134 ( aRange.aUpperLeft.nColumn != aRange.aLowerRight.nColumn ) && 1135 ( aRange.aUpperLeft.nRow != aRange.aLowerRight.nRow ) ) 1136 return lcl_aCompleteRange; 1137 1138 // attention: this data provider has the limitation that it stores 1139 // internally if data comes from columns or rows. It is intended for 1140 // creating only one used data source. 1141 // @todo: add this information in the range representation strings 1142 1143 // data in columns 1144 if( m_bDataInColumns ) 1145 { 1146 if( aRange.aUpperLeft.nColumn == 0 ) 1147 return lcl_aCategoriesRangeName; 1148 if( aRange.aUpperLeft.nRow == 0 ) 1149 return lcl_aLabelRangePrefix + OUString::valueOf( aRange.aUpperLeft.nColumn - 1 ); 1150 1151 return OUString::valueOf( aRange.aUpperLeft.nColumn - 1 ); 1152 } 1153 1154 // data in rows 1155 if( aRange.aUpperLeft.nRow == 0 ) 1156 return lcl_aCategoriesRangeName; 1157 if( aRange.aUpperLeft.nColumn == 0 ) 1158 return lcl_aLabelRangePrefix + OUString::valueOf( aRange.aUpperLeft.nRow - 1 ); 1159 1160 return OUString::valueOf( aRange.aUpperLeft.nRow - 1 ); 1161 } 1162 1163 namespace 1164 { 1165 1166 template< class Type > 1167 Sequence< Sequence< Type > > lcl_convertVectorVectorToSequenceSequence( const vector< vector< Type > >& rIn ) 1168 { 1169 Sequence< Sequence< Type > > aRet; 1170 sal_Int32 nOuterCount = rIn.size(); 1171 if( nOuterCount ) 1172 { 1173 aRet.realloc(nOuterCount); 1174 for( sal_Int32 nN=0; nN<nOuterCount; nN++) 1175 aRet[nN]= ContainerHelper::ContainerToSequence( rIn[nN] ); 1176 } 1177 return aRet; 1178 } 1179 1180 template< class Type > 1181 vector< vector< Type > > lcl_convertSequenceSequenceToVectorVector( const Sequence< Sequence< Type > >& rIn ) 1182 { 1183 vector< vector< Type > > aRet; 1184 sal_Int32 nOuterCount = rIn.getLength(); 1185 if( nOuterCount ) 1186 { 1187 aRet.resize(nOuterCount); 1188 for( sal_Int32 nN=0; nN<nOuterCount; nN++) 1189 aRet[nN]= ContainerHelper::SequenceToVector( rIn[nN] ); 1190 } 1191 return aRet; 1192 } 1193 1194 Sequence< Sequence< OUString > > lcl_convertComplexAnyVectorToStringSequence( const vector< vector< uno::Any > >& rIn ) 1195 { 1196 Sequence< Sequence< OUString > > aRet; 1197 sal_Int32 nOuterCount = rIn.size(); 1198 if( nOuterCount ) 1199 { 1200 aRet.realloc(nOuterCount); 1201 for( sal_Int32 nN=0; nN<nOuterCount; nN++) 1202 aRet[nN]= lcl_AnyToStringSequence( ContainerHelper::ContainerToSequence( rIn[nN] ) ); 1203 } 1204 return aRet; 1205 } 1206 1207 vector< vector< uno::Any > > lcl_convertComplexStringSequenceToAnyVector( const Sequence< Sequence< OUString > >& rIn ) 1208 { 1209 vector< vector< uno::Any > > aRet; 1210 sal_Int32 nOuterCount = rIn.getLength(); 1211 for( sal_Int32 nN=0; nN<nOuterCount; nN++) 1212 aRet.push_back( ContainerHelper::SequenceToVector( lcl_StringToAnySequence( rIn[nN] ) ) ); 1213 return aRet; 1214 } 1215 1216 class SplitCategoriesProvider_ForComplexDescriptions : public SplitCategoriesProvider 1217 { 1218 public: 1219 1220 explicit SplitCategoriesProvider_ForComplexDescriptions( const ::std::vector< ::std::vector< uno::Any > >& rComplexDescriptions ) 1221 : m_rComplexDescriptions( rComplexDescriptions ) 1222 {} 1223 virtual ~SplitCategoriesProvider_ForComplexDescriptions() 1224 {} 1225 1226 virtual sal_Int32 getLevelCount() const; 1227 virtual uno::Sequence< rtl::OUString > getStringsForLevel( sal_Int32 nIndex ) const; 1228 1229 private: 1230 const ::std::vector< ::std::vector< uno::Any > >& m_rComplexDescriptions; 1231 }; 1232 1233 sal_Int32 SplitCategoriesProvider_ForComplexDescriptions::getLevelCount() const 1234 { 1235 return lcl_getInnerLevelCount( m_rComplexDescriptions ); 1236 } 1237 uno::Sequence< rtl::OUString > SplitCategoriesProvider_ForComplexDescriptions::getStringsForLevel( sal_Int32 nLevel ) const 1238 { 1239 uno::Sequence< rtl::OUString > aResult; 1240 if( nLevel < lcl_getInnerLevelCount( m_rComplexDescriptions ) ) 1241 { 1242 aResult.realloc( m_rComplexDescriptions.size() ); 1243 transform( m_rComplexDescriptions.begin(), m_rComplexDescriptions.end(), 1244 aResult.getArray(), lcl_getStringFromLevelVector(nLevel) ); 1245 } 1246 return aResult; 1247 } 1248 1249 }//anonymous namespace 1250 1251 // ____ XDateCategories ____ 1252 Sequence< double > SAL_CALL InternalDataProvider::getDateCategories() throw (uno::RuntimeException) 1253 { 1254 double fNan = InternalDataProvider::getNotANumber(); 1255 double fValue = fNan; 1256 vector< vector< uno::Any > > aCategories( m_bDataInColumns ? m_aInternalData.getComplexRowLabels() : m_aInternalData.getComplexColumnLabels()); 1257 sal_Int32 nCount = aCategories.size(); 1258 Sequence< double > aDoubles( nCount ); 1259 vector< vector< uno::Any > >::iterator aIt( aCategories.begin() ); 1260 vector< vector< uno::Any > >::const_iterator aEnd( aCategories.end() ); 1261 for(sal_Int32 nN=0; nN<nCount && aIt!=aEnd; ++nN, ++aIt ) 1262 { 1263 if( !( !aIt->empty() && ((*aIt)[0]>>=fValue) ) ) 1264 fValue = fNan; 1265 aDoubles[nN]=fValue; 1266 } 1267 return aDoubles; 1268 } 1269 1270 void SAL_CALL InternalDataProvider::setDateCategories( const Sequence< double >& rDates ) throw (uno::RuntimeException) 1271 { 1272 sal_Int32 nCount = rDates.getLength(); 1273 vector< vector< uno::Any > > aNewCategories; 1274 aNewCategories.reserve(nCount); 1275 vector< uno::Any > aSingleLabel(1); 1276 1277 for(sal_Int32 nN=0; nN<nCount; ++nN ) 1278 { 1279 aSingleLabel[0]=uno::makeAny(rDates[nN]); 1280 aNewCategories.push_back(aSingleLabel); 1281 } 1282 1283 if( m_bDataInColumns ) 1284 m_aInternalData.setComplexRowLabels( aNewCategories ); 1285 else 1286 m_aInternalData.setComplexColumnLabels( aNewCategories ); 1287 } 1288 1289 // ____ XAnyDescriptionAccess ____ 1290 Sequence< Sequence< uno::Any > > SAL_CALL InternalDataProvider::getAnyRowDescriptions() throw (uno::RuntimeException) 1291 { 1292 return lcl_convertVectorVectorToSequenceSequence( m_aInternalData.getComplexRowLabels() ); 1293 } 1294 void SAL_CALL InternalDataProvider::setAnyRowDescriptions( const Sequence< Sequence< uno::Any > >& aRowDescriptions ) throw (uno::RuntimeException) 1295 { 1296 m_aInternalData.setComplexRowLabels( lcl_convertSequenceSequenceToVectorVector( aRowDescriptions ) ); 1297 } 1298 Sequence< Sequence< uno::Any > > SAL_CALL InternalDataProvider::getAnyColumnDescriptions() throw (uno::RuntimeException) 1299 { 1300 return lcl_convertVectorVectorToSequenceSequence( m_aInternalData.getComplexColumnLabels() ); 1301 } 1302 void SAL_CALL InternalDataProvider::setAnyColumnDescriptions( const Sequence< Sequence< uno::Any > >& aColumnDescriptions ) throw (uno::RuntimeException) 1303 { 1304 m_aInternalData.setComplexColumnLabels( lcl_convertSequenceSequenceToVectorVector( aColumnDescriptions ) ); 1305 } 1306 1307 // ____ XComplexDescriptionAccess ____ 1308 Sequence< Sequence< OUString > > SAL_CALL InternalDataProvider::getComplexRowDescriptions() throw (uno::RuntimeException) 1309 { 1310 return lcl_convertComplexAnyVectorToStringSequence( m_aInternalData.getComplexRowLabels() ); 1311 } 1312 void SAL_CALL InternalDataProvider::setComplexRowDescriptions( const Sequence< Sequence< ::rtl::OUString > >& aRowDescriptions ) throw (uno::RuntimeException) 1313 { 1314 m_aInternalData.setComplexRowLabels( lcl_convertComplexStringSequenceToAnyVector(aRowDescriptions) ); 1315 } 1316 Sequence< Sequence< ::rtl::OUString > > SAL_CALL InternalDataProvider::getComplexColumnDescriptions() throw (uno::RuntimeException) 1317 { 1318 return lcl_convertComplexAnyVectorToStringSequence( m_aInternalData.getComplexColumnLabels() ); 1319 } 1320 void SAL_CALL InternalDataProvider::setComplexColumnDescriptions( const Sequence< Sequence< ::rtl::OUString > >& aColumnDescriptions ) throw (uno::RuntimeException) 1321 { 1322 m_aInternalData.setComplexColumnLabels( lcl_convertComplexStringSequenceToAnyVector(aColumnDescriptions) ); 1323 } 1324 1325 // ____ XChartDataArray ____ 1326 Sequence< Sequence< double > > SAL_CALL InternalDataProvider::getData() 1327 throw (uno::RuntimeException) 1328 { 1329 return m_aInternalData.getData(); 1330 } 1331 1332 void SAL_CALL InternalDataProvider::setData( const Sequence< Sequence< double > >& rDataInRows ) 1333 throw (uno::RuntimeException) 1334 { 1335 return m_aInternalData.setData( rDataInRows ); 1336 } 1337 1338 void SAL_CALL InternalDataProvider::setRowDescriptions( const Sequence< OUString >& aRowDescriptions ) 1339 throw (uno::RuntimeException) 1340 { 1341 vector< vector< uno::Any > > aComplexDescriptions( aRowDescriptions.getLength() ); 1342 transform( aComplexDescriptions.begin(), aComplexDescriptions.end(), aRowDescriptions.getConstArray(), 1343 aComplexDescriptions.begin(), lcl_setAnyAtLevelFromStringSequence(0) ); 1344 m_aInternalData.setComplexRowLabels( aComplexDescriptions ); 1345 } 1346 1347 void SAL_CALL InternalDataProvider::setColumnDescriptions( const Sequence< OUString >& aColumnDescriptions ) 1348 throw (uno::RuntimeException) 1349 { 1350 vector< vector< uno::Any > > aComplexDescriptions( aColumnDescriptions.getLength() ); 1351 transform( aComplexDescriptions.begin(), aComplexDescriptions.end(), aColumnDescriptions.getConstArray(), 1352 aComplexDescriptions.begin(), lcl_setAnyAtLevelFromStringSequence(0) ); 1353 m_aInternalData.setComplexColumnLabels( aComplexDescriptions ); 1354 } 1355 1356 Sequence< OUString > SAL_CALL InternalDataProvider::getRowDescriptions() 1357 throw (uno::RuntimeException) 1358 { 1359 vector< vector< uno::Any > > aComplexLabels( m_aInternalData.getComplexRowLabels() ); 1360 SplitCategoriesProvider_ForComplexDescriptions aProvider( aComplexLabels ); 1361 return ExplicitCategoriesProvider::getExplicitSimpleCategories( aProvider ); 1362 } 1363 1364 Sequence< OUString > SAL_CALL InternalDataProvider::getColumnDescriptions() 1365 throw (uno::RuntimeException) 1366 { 1367 vector< vector< uno::Any > > aComplexLabels( m_aInternalData.getComplexColumnLabels() ); 1368 SplitCategoriesProvider_ForComplexDescriptions aProvider( aComplexLabels ); 1369 return ExplicitCategoriesProvider::getExplicitSimpleCategories( aProvider ); 1370 } 1371 1372 // ____ XChartData (base of XChartDataArray) ____ 1373 void SAL_CALL InternalDataProvider::addChartDataChangeEventListener( 1374 const Reference< ::com::sun::star::chart::XChartDataChangeEventListener >& ) 1375 throw (uno::RuntimeException) 1376 { 1377 } 1378 1379 void SAL_CALL InternalDataProvider::removeChartDataChangeEventListener( 1380 const Reference< ::com::sun::star::chart::XChartDataChangeEventListener >& ) 1381 throw (uno::RuntimeException) 1382 { 1383 } 1384 1385 double SAL_CALL InternalDataProvider::getNotANumber() 1386 throw (uno::RuntimeException) 1387 { 1388 double fNan; 1389 ::rtl::math::setNan( & fNan ); 1390 return fNan; 1391 } 1392 1393 ::sal_Bool SAL_CALL InternalDataProvider::isNotANumber( double nNumber ) 1394 throw (uno::RuntimeException) 1395 { 1396 return ::rtl::math::isNan( nNumber ) 1397 || ::rtl::math::isInf( nNumber ); 1398 } 1399 // lang::XInitialization: 1400 void SAL_CALL InternalDataProvider::initialize(const uno::Sequence< uno::Any > & _aArguments) throw (uno::RuntimeException, uno::Exception) 1401 { 1402 comphelper::SequenceAsHashMap aArgs(_aArguments); 1403 if ( aArgs.getUnpackedValueOrDefault(::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("CreateDefaultData")),sal_False) ) 1404 createDefaultData(); 1405 } 1406 // ____ XCloneable ____ 1407 Reference< util::XCloneable > SAL_CALL InternalDataProvider::createClone() 1408 throw (uno::RuntimeException) 1409 { 1410 return Reference< util::XCloneable >( new InternalDataProvider( *this )); 1411 } 1412 1413 1414 // ================================================================================ 1415 1416 Sequence< OUString > InternalDataProvider::getSupportedServiceNames_Static() 1417 { 1418 Sequence< OUString > aServices( 1 ); 1419 aServices[ 0 ] = OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.chart2.data.DataProvider" )); 1420 return aServices; 1421 } 1422 1423 // ================================================================================ 1424 1425 APPHELPER_XSERVICEINFO_IMPL( InternalDataProvider, lcl_aServiceName ); 1426 1427 } // namespace chart 1428