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