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( const Reference< chart2::XChartDocument > & xChartDoc, bool bConnectToModel ) 341 : m_bDataInColumns( true ) 342 { 343 try 344 { 345 Reference< chart2::XDiagram > xDiagram( ChartModelHelper::findDiagram( xChartDoc ) ); 346 if( xDiagram.is()) 347 { 348 Reference< frame::XModel > xChartModel( xChartDoc, uno::UNO_QUERY ); 349 350 //data in columns? 351 { 352 ::rtl::OUString aRangeString; 353 bool bFirstCellAsLabel = true; 354 bool bHasCategories = true; 355 uno::Sequence< sal_Int32 > aSequenceMapping; 356 DataSourceHelper::detectRangeSegmentation( xChartModel, aRangeString, aSequenceMapping, m_bDataInColumns, bFirstCellAsLabel, bHasCategories ); 357 } 358 359 // categories 360 { 361 vector< vector< uno::Any > > aNewCategories;//inner count is level 362 { 363 ExplicitCategoriesProvider aExplicitCategoriesProvider( ChartModelHelper::getFirstCoordinateSystem(xChartModel), xChartModel ); 364 365 const Sequence< Reference< chart2::data::XLabeledDataSequence> >& rSplitCategoriesList( aExplicitCategoriesProvider.getSplitCategoriesList() ); 366 sal_Int32 nLevelCount = rSplitCategoriesList.getLength(); 367 for( sal_Int32 nL = 0; nL<nLevelCount; nL++ ) 368 { 369 Reference< chart2::data::XLabeledDataSequence > xLDS( rSplitCategoriesList[nL] ); 370 if( !xLDS.is() ) 371 continue; 372 Sequence< uno::Any > aDataSeq; 373 Reference< chart2::data::XDataSequence > xSeq( xLDS->getValues() ); 374 if( xSeq.is() ) 375 aDataSeq = xSeq->getData(); 376 sal_Int32 nLength = aDataSeq.getLength(); 377 sal_Int32 nCatLength = static_cast< sal_Int32 >(aNewCategories.size()); 378 if( nCatLength < nLength ) 379 aNewCategories.resize( nLength ); 380 else if( nLength < nCatLength ) 381 aDataSeq.realloc( nCatLength ); 382 transform( aNewCategories.begin(), aNewCategories.end(), aDataSeq.getConstArray(), 383 aNewCategories.begin(), lcl_setAnyAtLevel(nL) ); 384 } 385 if( !nLevelCount ) 386 { 387 Sequence< OUString > aSimplecategories = aExplicitCategoriesProvider.getSimpleCategories(); 388 sal_Int32 nLength = aSimplecategories.getLength(); 389 aNewCategories.reserve( nLength ); 390 for( sal_Int32 nN=0; nN<nLength; nN++) 391 { 392 vector< uno::Any > aVector(1); 393 aVector[0] = uno::makeAny( aSimplecategories[nN] ); 394 aNewCategories.push_back( aVector ); 395 } 396 } 397 } 398 399 if( m_bDataInColumns ) 400 m_aInternalData.setComplexRowLabels( aNewCategories ); 401 else 402 m_aInternalData.setComplexColumnLabels( aNewCategories ); 403 if( bConnectToModel ) 404 DiagramHelper::setCategoriesToDiagram( new LabeledDataSequence( 405 createDataSequenceByRangeRepresentation( lcl_aCategoriesRangeName )), xDiagram ); 406 } 407 408 // data series 409 ::std::vector< Reference< chart2::XDataSeries > > aSeriesVector( ChartModelHelper::getDataSeries( xChartDoc )); 410 ::std::for_each( aSeriesVector.begin(), aSeriesVector.end(), lcl_internalizeSeries( m_aInternalData, *this, bConnectToModel, m_bDataInColumns ) ); 411 } 412 } 413 catch( const uno::Exception & ex ) 414 { 415 ASSERT_EXCEPTION( ex ); 416 } 417 } 418 419 // copy-CTOR 420 InternalDataProvider::InternalDataProvider( const InternalDataProvider & rOther ) : 421 impl::InternalDataProvider_Base(), 422 m_aSequenceMap( rOther.m_aSequenceMap ), 423 m_aInternalData( rOther.m_aInternalData ), 424 m_bDataInColumns( rOther.m_bDataInColumns ) 425 {} 426 427 InternalDataProvider::~InternalDataProvider() 428 {} 429 430 void InternalDataProvider::lcl_addDataSequenceToMap( 431 const OUString & rRangeRepresentation, 432 const Reference< chart2::data::XDataSequence > & xSequence ) 433 { 434 m_aSequenceMap.insert( 435 tSequenceMap::value_type( 436 rRangeRepresentation, 437 uno::WeakReference< chart2::data::XDataSequence >( xSequence ))); 438 } 439 440 void InternalDataProvider::lcl_deleteMapReferences( const OUString & rRangeRepresentation ) 441 { 442 // set sequence to deleted by setting its range to an empty string 443 tSequenceMapRange aRange( m_aSequenceMap.equal_range( rRangeRepresentation )); 444 for( tSequenceMap::iterator aIt( aRange.first ); aIt != aRange.second; ++aIt ) 445 { 446 Reference< chart2::data::XDataSequence > xSeq( aIt->second ); 447 if( xSeq.is()) 448 { 449 Reference< container::XNamed > xNamed( xSeq, uno::UNO_QUERY ); 450 if( xNamed.is()) 451 xNamed->setName( OUString()); 452 } 453 } 454 // remove from map 455 m_aSequenceMap.erase( aRange.first, aRange.second ); 456 } 457 458 void InternalDataProvider::lcl_adaptMapReferences( 459 const OUString & rOldRangeRepresentation, 460 const OUString & rNewRangeRepresentation ) 461 { 462 tSequenceMapRange aRange( m_aSequenceMap.equal_range( rOldRangeRepresentation )); 463 tSequenceMap aNewElements; 464 for( tSequenceMap::iterator aIt( aRange.first ); aIt != aRange.second; ++aIt ) 465 { 466 Reference< chart2::data::XDataSequence > xSeq( aIt->second ); 467 if( xSeq.is()) 468 { 469 Reference< container::XNamed > xNamed( xSeq, uno::UNO_QUERY ); 470 if( xNamed.is()) 471 xNamed->setName( rNewRangeRepresentation ); 472 } 473 aNewElements.insert( tSequenceMap::value_type( rNewRangeRepresentation, aIt->second )); 474 } 475 // erase map values for old index 476 m_aSequenceMap.erase( aRange.first, aRange.second ); 477 // add new entries for values with new index 478 ::std::copy( aNewElements.begin(), aNewElements.end(), 479 ::std::inserter( m_aSequenceMap, 480 m_aSequenceMap.upper_bound( rNewRangeRepresentation ))); 481 } 482 483 void InternalDataProvider::lcl_increaseMapReferences( 484 sal_Int32 nBegin, sal_Int32 nEnd ) 485 { 486 for( sal_Int32 nIndex = nEnd - 1; nIndex >= nBegin; --nIndex ) 487 { 488 lcl_adaptMapReferences( OUString::valueOf( nIndex ), 489 OUString::valueOf( nIndex + 1 )); 490 lcl_adaptMapReferences( lcl_aLabelRangePrefix + OUString::valueOf( nIndex ), 491 lcl_aLabelRangePrefix + OUString::valueOf( nIndex + 1 )); 492 } 493 } 494 495 void InternalDataProvider::lcl_decreaseMapReferences( 496 sal_Int32 nBegin, sal_Int32 nEnd ) 497 { 498 for( sal_Int32 nIndex = nBegin; nIndex < nEnd; ++nIndex ) 499 { 500 lcl_adaptMapReferences( OUString::valueOf( nIndex ), 501 OUString::valueOf( nIndex - 1 )); 502 lcl_adaptMapReferences( lcl_aLabelRangePrefix + OUString::valueOf( nIndex ), 503 lcl_aLabelRangePrefix + OUString::valueOf( nIndex - 1 )); 504 } 505 } 506 507 Reference< chart2::data::XDataSequence > InternalDataProvider::lcl_createDataSequenceAndAddToMap( 508 const OUString & rRangeRepresentation ) 509 { 510 Reference< chart2::data::XDataSequence > xSeq( 511 new UncachedDataSequence( this, rRangeRepresentation )); 512 lcl_addDataSequenceToMap( rRangeRepresentation, xSeq ); 513 return xSeq; 514 } 515 516 Reference< chart2::data::XDataSequence > InternalDataProvider::lcl_createDataSequenceAndAddToMap( 517 const OUString & rRangeRepresentation, 518 const OUString & rRole ) 519 { 520 Reference< chart2::data::XDataSequence > xSeq( 521 new UncachedDataSequence( this, rRangeRepresentation, rRole )); 522 lcl_addDataSequenceToMap( rRangeRepresentation, xSeq ); 523 return xSeq; 524 } 525 526 void InternalDataProvider::createDefaultData() 527 { 528 m_aInternalData.createDefaultData(); 529 } 530 531 // ____ XDataProvider ____ 532 ::sal_Bool SAL_CALL InternalDataProvider::createDataSourcePossible( const Sequence< beans::PropertyValue >& /* aArguments */ ) 533 throw (uno::RuntimeException) 534 { 535 return true; 536 } 537 538 namespace 539 { 540 541 sal_Int32 lcl_getInnerLevelCount( const vector< vector< uno::Any > >& rLabels ) 542 { 543 sal_Int32 nCount = 1;//minimum is 1! 544 vector< vector< uno::Any > >::const_iterator aLevelIt( rLabels.begin() ); 545 vector< vector< uno::Any > >::const_iterator aLevelEnd( rLabels.end() ); 546 for( ;aLevelIt!=aLevelEnd; ++aLevelIt ) 547 { 548 const vector< uno::Any >& rCurrentLevelLabels = *aLevelIt; 549 nCount = std::max<sal_Int32>( rCurrentLevelLabels.size(), nCount ); 550 } 551 return nCount; 552 } 553 554 }//end anonymous namespace 555 556 Reference< chart2::data::XDataSource > SAL_CALL InternalDataProvider::createDataSource( 557 const Sequence< beans::PropertyValue >& aArguments ) 558 throw (lang::IllegalArgumentException, 559 uno::RuntimeException) 560 { 561 OUString aRangeRepresentation; 562 bool bUseColumns = true; 563 bool bFirstCellAsLabel = true; 564 bool bHasCategories = true; 565 uno::Sequence< sal_Int32 > aSequenceMapping; 566 DataSourceHelper::readArguments( aArguments, aRangeRepresentation, aSequenceMapping, bUseColumns, bFirstCellAsLabel, bHasCategories ); 567 568 if( aRangeRepresentation.equals( lcl_aCategoriesRangeName ) ) 569 { 570 //return split complex categories if we have any: 571 ::std::vector< Reference< chart2::data::XLabeledDataSequence > > aComplexCategories; 572 vector< vector< uno::Any > > aCategories( m_bDataInColumns ? m_aInternalData.getComplexRowLabels() : m_aInternalData.getComplexColumnLabels()); 573 if( bUseColumns==m_bDataInColumns ) 574 { 575 sal_Int32 nLevelCount = lcl_getInnerLevelCount( aCategories ); 576 for( sal_Int32 nL=0; nL<nLevelCount; nL++ ) 577 aComplexCategories.push_back( new LabeledDataSequence( 578 new UncachedDataSequence( this 579 , lcl_aCategoriesLevelRangeNamePrefix + OUString::valueOf( nL ) 580 , lcl_aCategoriesRoleName ) ) ); 581 } 582 else 583 { 584 sal_Int32 nPointCount = m_bDataInColumns ? m_aInternalData.getRowCount() : m_aInternalData.getColumnCount(); 585 for( sal_Int32 nP=0; nP<nPointCount; nP++ ) 586 aComplexCategories.push_back( new LabeledDataSequence( 587 new UncachedDataSequence( this 588 , lcl_aCategoriesPointRangeNamePrefix + OUString::valueOf( nP ) 589 , lcl_aCategoriesRoleName ) ) ); 590 } 591 //don't add the created sequences to the map as they are used temporarily only ... 592 return new DataSource( ContainerHelper::ContainerToSequence(aComplexCategories) ); 593 } 594 595 OSL_ASSERT( aRangeRepresentation.equals( lcl_aCompleteRange )); 596 597 ::std::vector< Reference< chart2::data::XLabeledDataSequence > > aResultLSeqVec; 598 599 // categories 600 if( bHasCategories ) 601 aResultLSeqVec.push_back( 602 new LabeledDataSequence( lcl_createDataSequenceAndAddToMap( lcl_aCategoriesRangeName, lcl_aCategoriesRoleName ) ) ); 603 604 // data with labels 605 ::std::vector< Reference< chart2::data::XLabeledDataSequence > > aDataVec; 606 const sal_Int32 nCount = (bUseColumns ? m_aInternalData.getColumnCount() : m_aInternalData.getRowCount()); 607 for( sal_Int32 nIdx=0; nIdx<nCount; ++nIdx ) 608 { 609 aDataVec.push_back( 610 new LabeledDataSequence( 611 lcl_createDataSequenceAndAddToMap( OUString::valueOf( nIdx )), 612 lcl_createDataSequenceAndAddToMap( lcl_aLabelRangePrefix + OUString::valueOf( nIdx )))); 613 } 614 615 // attention: this data provider has the limitation that it stores 616 // internally if data comes from columns or rows. It is intended for 617 // creating only one used data source. 618 // @todo: add this information in the range representation strings 619 m_bDataInColumns = bUseColumns; 620 621 //reorder labeled sequences according to aSequenceMapping; ignore categories 622 for( sal_Int32 nNewIndex = 0; nNewIndex < aSequenceMapping.getLength(); nNewIndex++ ) 623 { 624 std::vector< LabeledDataSequence* >::size_type nOldIndex = aSequenceMapping[nNewIndex]; 625 if( nOldIndex < aDataVec.size() ) 626 { 627 if( aDataVec[nOldIndex].is() ) 628 { 629 aResultLSeqVec.push_back( aDataVec[nOldIndex] ); 630 aDataVec[nOldIndex] = 0; 631 } 632 } 633 } 634 635 //add left over data sequences to result 636 ::std::vector< Reference< chart2::data::XLabeledDataSequence > >::iterator aIt(aDataVec.begin()); 637 const ::std::vector< Reference< chart2::data::XLabeledDataSequence > >::const_iterator aEndIt(aDataVec.end()); 638 for( ;aIt!=aEndIt; ++aIt) 639 { 640 if( aIt->is() ) 641 aResultLSeqVec.push_back( *aIt ); 642 } 643 644 return new DataSource( ContainerHelper::ContainerToSequence(aResultLSeqVec) ); 645 } 646 647 Sequence< beans::PropertyValue > SAL_CALL InternalDataProvider::detectArguments( 648 const Reference< chart2::data::XDataSource >& /* xDataSource */ ) 649 throw (uno::RuntimeException) 650 { 651 Sequence< beans::PropertyValue > aArguments( 4 ); 652 aArguments[0] = beans::PropertyValue( 653 C2U("CellRangeRepresentation"), -1, uno::makeAny( lcl_aCompleteRange ), 654 beans::PropertyState_DIRECT_VALUE ); 655 aArguments[1] = beans::PropertyValue( 656 C2U("DataRowSource"), -1, uno::makeAny( 657 m_bDataInColumns 658 ? ::com::sun::star::chart::ChartDataRowSource_COLUMNS 659 : ::com::sun::star::chart::ChartDataRowSource_ROWS ), 660 beans::PropertyState_DIRECT_VALUE ); 661 // internal data always contains labels and categories 662 aArguments[2] = beans::PropertyValue( 663 C2U("FirstCellAsLabel"), -1, uno::makeAny( true ), beans::PropertyState_DIRECT_VALUE ); 664 aArguments[3] = beans::PropertyValue( 665 C2U("HasCategories"), -1, uno::makeAny( true ), beans::PropertyState_DIRECT_VALUE ); 666 667 // #i85913# Sequence Mapping is not needed for internal data, as it is 668 // applied to the data when the data source is created. 669 670 return aArguments; 671 } 672 673 ::sal_Bool SAL_CALL InternalDataProvider::createDataSequenceByRangeRepresentationPossible( const OUString& /* aRangeRepresentation */ ) 674 throw (uno::RuntimeException) 675 { 676 return true; 677 } 678 679 Reference< chart2::data::XDataSequence > SAL_CALL InternalDataProvider::createDataSequenceByRangeRepresentation( 680 const OUString& aRangeRepresentation ) 681 throw (lang::IllegalArgumentException, 682 uno::RuntimeException) 683 { 684 if( aRangeRepresentation.match( lcl_aCategoriesRangeName )) 685 { 686 OSL_ASSERT( aRangeRepresentation.equals( lcl_aCategoriesRangeName ) );//it is not expected nor implmented that only parts of the categories are really requested 687 688 // categories 689 return lcl_createDataSequenceAndAddToMap( lcl_aCategoriesRangeName, lcl_aCategoriesRoleName ); 690 } 691 else if( aRangeRepresentation.match( lcl_aLabelRangePrefix )) 692 { 693 // label 694 sal_Int32 nIndex = aRangeRepresentation.copy( lcl_aLabelRangePrefix.getLength()).toInt32(); 695 return lcl_createDataSequenceAndAddToMap( lcl_aLabelRangePrefix + OUString::valueOf( nIndex )); 696 } 697 else if( aRangeRepresentation.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "last" ))) 698 { 699 sal_Int32 nIndex = (m_bDataInColumns 700 ? m_aInternalData.getColumnCount() 701 : m_aInternalData.getRowCount()) - 1; 702 return lcl_createDataSequenceAndAddToMap( OUString::valueOf( nIndex )); 703 } 704 else if( aRangeRepresentation.getLength()) 705 { 706 // data 707 sal_Int32 nIndex = aRangeRepresentation.toInt32(); 708 return lcl_createDataSequenceAndAddToMap( OUString::valueOf( nIndex )); 709 } 710 711 return Reference< chart2::data::XDataSequence >(); 712 } 713 714 Reference< sheet::XRangeSelection > SAL_CALL InternalDataProvider::getRangeSelection() 715 throw (uno::RuntimeException) 716 { 717 // there is no range selection component 718 return Reference< sheet::XRangeSelection >(); 719 } 720 721 // ____ XInternalDataProvider ____ 722 ::sal_Bool SAL_CALL InternalDataProvider::hasDataByRangeRepresentation( const OUString& aRange ) 723 throw (uno::RuntimeException) 724 { 725 sal_Bool bResult = false; 726 727 if( aRange.match( lcl_aCategoriesRangeName )) 728 { 729 OSL_ASSERT( aRange.equals( lcl_aCategoriesRangeName ) );//it is not expected nor implmented that only parts of the categories are really requested 730 bResult = true; 731 } 732 else if( aRange.match( lcl_aLabelRangePrefix )) 733 { 734 sal_Int32 nIndex = aRange.copy( lcl_aLabelRangePrefix.getLength()).toInt32(); 735 bResult = (nIndex < (m_bDataInColumns ? m_aInternalData.getColumnCount(): m_aInternalData.getRowCount())); 736 } 737 else 738 { 739 sal_Int32 nIndex = aRange.toInt32(); 740 bResult = (nIndex < (m_bDataInColumns ? m_aInternalData.getColumnCount(): m_aInternalData.getRowCount())); 741 } 742 743 return bResult; 744 } 745 746 Sequence< uno::Any > SAL_CALL InternalDataProvider::getDataByRangeRepresentation( const OUString& aRange ) 747 throw (uno::RuntimeException) 748 { 749 Sequence< uno::Any > aResult; 750 751 if( aRange.match( lcl_aLabelRangePrefix ) ) 752 { 753 sal_Int32 nIndex = aRange.copy( lcl_aLabelRangePrefix.getLength()).toInt32(); 754 vector< uno::Any > aComplexLabel = m_bDataInColumns 755 ? m_aInternalData.getComplexColumnLabel( nIndex ) 756 : m_aInternalData.getComplexRowLabel( nIndex ); 757 if( !aComplexLabel.empty() ) 758 aResult = ContainerHelper::ContainerToSequence(aComplexLabel); 759 } 760 else if( aRange.match( lcl_aCategoriesPointRangeNamePrefix ) ) 761 { 762 sal_Int32 nPointIndex = aRange.copy( lcl_aCategoriesPointRangeNamePrefix.getLength() ).toInt32(); 763 vector< uno::Any > aComplexCategory = m_bDataInColumns 764 ? m_aInternalData.getComplexRowLabel( nPointIndex ) 765 : m_aInternalData.getComplexColumnLabel( nPointIndex ); 766 if( !aComplexCategory.empty() ) 767 aResult = ContainerHelper::ContainerToSequence(aComplexCategory); 768 } 769 else if( aRange.match( lcl_aCategoriesLevelRangeNamePrefix ) ) 770 { 771 sal_Int32 nLevel = aRange.copy( lcl_aCategoriesLevelRangeNamePrefix.getLength() ).toInt32(); 772 vector< vector< uno::Any > > aCategories( m_bDataInColumns ? m_aInternalData.getComplexRowLabels() : m_aInternalData.getComplexColumnLabels()); 773 if( nLevel < lcl_getInnerLevelCount( aCategories ) ) 774 { 775 aResult.realloc( aCategories.size() ); 776 transform( aCategories.begin(), aCategories.end(), 777 aResult.getArray(), lcl_copyFromLevel(nLevel) ); 778 } 779 } 780 else if( aRange.equals( lcl_aCategoriesRangeName ) ) 781 { 782 vector< vector< uno::Any > > aCategories( m_bDataInColumns ? m_aInternalData.getComplexRowLabels() : m_aInternalData.getComplexColumnLabels()); 783 sal_Int32 nLevelCount = lcl_getInnerLevelCount( aCategories ); 784 if( nLevelCount == 1 ) 785 { 786 sal_Int32 nL=0; 787 aResult = this->getDataByRangeRepresentation( lcl_aCategoriesLevelRangeNamePrefix + OUString::valueOf( nL ) ); 788 } 789 else 790 { 791 Sequence< OUString > aLabels = m_bDataInColumns ? this->getRowDescriptions() : this->getColumnDescriptions(); 792 aResult.realloc( aLabels.getLength() ); 793 transform( aLabels.getConstArray(), aLabels.getConstArray() + aLabels.getLength(), 794 aResult.getArray(), CommonFunctors::makeAny< OUString >() ); 795 } 796 } 797 else 798 { 799 sal_Int32 nIndex = aRange.toInt32(); 800 if( nIndex >= 0 ) 801 { 802 Sequence< double > aData; 803 if( m_bDataInColumns ) 804 aData = m_aInternalData.getColumnValues(nIndex); 805 else 806 aData = m_aInternalData.getRowValues(nIndex); 807 if( aData.getLength() ) 808 { 809 aResult.realloc( aData.getLength()); 810 transform( aData.getConstArray(), aData.getConstArray() + aData.getLength(), 811 aResult.getArray(), CommonFunctors::makeAny< double >()); 812 } 813 } 814 } 815 816 return aResult; 817 } 818 819 void SAL_CALL InternalDataProvider::setDataByRangeRepresentation( 820 const OUString& aRange, const Sequence< uno::Any >& aNewData ) 821 throw (uno::RuntimeException) 822 { 823 vector< uno::Any > aNewVector( ContainerHelper::SequenceToVector(aNewData) ); 824 if( aRange.match( lcl_aLabelRangePrefix ) ) 825 { 826 sal_uInt32 nIndex = aRange.copy( lcl_aLabelRangePrefix.getLength()).toInt32(); 827 if( m_bDataInColumns ) 828 m_aInternalData.setComplexColumnLabel( nIndex, aNewVector ); 829 else 830 m_aInternalData.setComplexRowLabel( nIndex, aNewVector ); 831 } 832 else if( aRange.match( lcl_aCategoriesPointRangeNamePrefix ) ) 833 { 834 sal_Int32 nPointIndex = aRange.copy( lcl_aCategoriesLevelRangeNamePrefix.getLength()).toInt32(); 835 if( m_bDataInColumns ) 836 m_aInternalData.setComplexRowLabel( nPointIndex, aNewVector ); 837 else 838 m_aInternalData.setComplexColumnLabel( nPointIndex, aNewVector ); 839 } 840 else if( aRange.match( lcl_aCategoriesLevelRangeNamePrefix ) ) 841 { 842 sal_Int32 nLevel = aRange.copy( lcl_aCategoriesLevelRangeNamePrefix.getLength()).toInt32(); 843 vector< vector< uno::Any > > aComplexCategories = m_bDataInColumns ? m_aInternalData.getComplexRowLabels() : m_aInternalData.getComplexColumnLabels(); 844 845 //ensure equal length 846 if( aNewVector.size() > aComplexCategories.size() ) 847 aComplexCategories.resize( aNewVector.size() ); 848 else if( aNewVector.size() < aComplexCategories.size() ) 849 aNewVector.resize( aComplexCategories.size() ); 850 851 transform( aComplexCategories.begin(), aComplexCategories.end(), aNewVector.begin(), 852 aComplexCategories.begin(), lcl_setAnyAtLevel(nLevel) ); 853 854 if( m_bDataInColumns ) 855 m_aInternalData.setComplexRowLabels( aComplexCategories ); 856 else 857 m_aInternalData.setComplexColumnLabels( aComplexCategories ); 858 } 859 else if( aRange.equals( lcl_aCategoriesRangeName ) ) 860 { 861 vector< vector< uno::Any > > aComplexCategories; 862 aComplexCategories.resize( aNewVector.size() ); 863 transform( aComplexCategories.begin(), aComplexCategories.end(), aNewVector.begin(), 864 aComplexCategories.begin(), lcl_setAnyAtLevel(0) ); 865 if( m_bDataInColumns ) 866 m_aInternalData.setComplexRowLabels( aComplexCategories ); 867 else 868 m_aInternalData.setComplexColumnLabels( aComplexCategories ); 869 } 870 else 871 { 872 sal_Int32 nIndex = aRange.toInt32(); 873 if( nIndex>=0 ) 874 { 875 vector< double > aNewDataVec; 876 transform( aNewData.getConstArray(), aNewData.getConstArray() + aNewData.getLength(), 877 back_inserter( aNewDataVec ), CommonFunctors::AnyToDouble()); 878 if( m_bDataInColumns ) 879 m_aInternalData.setColumnValues( nIndex, aNewDataVec ); 880 else 881 m_aInternalData.setRowValues( nIndex, aNewDataVec ); 882 } 883 } 884 } 885 886 void SAL_CALL InternalDataProvider::insertSequence( ::sal_Int32 nAfterIndex ) 887 throw (uno::RuntimeException) 888 { 889 if( m_bDataInColumns ) 890 { 891 lcl_increaseMapReferences( nAfterIndex + 1, m_aInternalData.getColumnCount()); 892 m_aInternalData.insertColumn( nAfterIndex ); 893 } 894 else 895 { 896 lcl_increaseMapReferences( nAfterIndex + 1, m_aInternalData.getRowCount()); 897 m_aInternalData.insertRow( nAfterIndex ); 898 } 899 } 900 901 void SAL_CALL InternalDataProvider::deleteSequence( ::sal_Int32 nAtIndex ) 902 throw (uno::RuntimeException) 903 { 904 lcl_deleteMapReferences( OUString::valueOf( nAtIndex )); 905 lcl_deleteMapReferences( lcl_aLabelRangePrefix + OUString::valueOf( nAtIndex )); 906 if( m_bDataInColumns ) 907 { 908 lcl_decreaseMapReferences( nAtIndex + 1, m_aInternalData.getColumnCount()); 909 m_aInternalData.deleteColumn( nAtIndex ); 910 } 911 else 912 { 913 lcl_decreaseMapReferences( nAtIndex + 1, m_aInternalData.getRowCount()); 914 m_aInternalData.deleteRow( nAtIndex ); 915 } 916 } 917 918 void SAL_CALL InternalDataProvider::appendSequence() 919 throw (uno::RuntimeException) 920 { 921 if( m_bDataInColumns ) 922 m_aInternalData.appendColumn(); 923 else 924 m_aInternalData.appendRow(); 925 } 926 927 void SAL_CALL InternalDataProvider::insertComplexCategoryLevel( sal_Int32 nLevel ) 928 throw (uno::RuntimeException) 929 { 930 OSL_ENSURE( nLevel> 0, "you can only insert category levels > 0" );//the first categories level cannot be deleted, check the calling code for error 931 if( nLevel>0 ) 932 { 933 vector< vector< uno::Any > > aComplexCategories = m_bDataInColumns ? m_aInternalData.getComplexRowLabels() : m_aInternalData.getComplexColumnLabels(); 934 ::std::for_each( aComplexCategories.begin(), aComplexCategories.end(), lcl_insertAnyAtLevel(nLevel) ); 935 if( m_bDataInColumns ) 936 m_aInternalData.setComplexRowLabels( aComplexCategories ); 937 else 938 m_aInternalData.setComplexColumnLabels( aComplexCategories ); 939 940 tSequenceMapRange aRange( m_aSequenceMap.equal_range( lcl_aCategoriesRangeName )); 941 ::std::for_each( aRange.first, aRange.second, lcl_setModified()); 942 } 943 } 944 void SAL_CALL InternalDataProvider::deleteComplexCategoryLevel( sal_Int32 nLevel ) 945 throw (uno::RuntimeException) 946 { 947 OSL_ENSURE( nLevel>0, "you can only delete category levels > 0" );//the first categories level cannot be deleted, check the calling code for error 948 if( nLevel>0 ) 949 { 950 vector< vector< uno::Any > > aComplexCategories = m_bDataInColumns ? m_aInternalData.getComplexRowLabels() : m_aInternalData.getComplexColumnLabels(); 951 ::std::for_each( aComplexCategories.begin(), aComplexCategories.end(), lcl_removeAnyAtLevel(nLevel) ); 952 if( m_bDataInColumns ) 953 m_aInternalData.setComplexRowLabels( aComplexCategories ); 954 else 955 m_aInternalData.setComplexColumnLabels( aComplexCategories ); 956 957 tSequenceMapRange aRange( m_aSequenceMap.equal_range( lcl_aCategoriesRangeName )); 958 ::std::for_each( aRange.first, aRange.second, lcl_setModified()); 959 } 960 } 961 962 void SAL_CALL InternalDataProvider::insertDataPointForAllSequences( ::sal_Int32 nAfterIndex ) 963 throw (uno::RuntimeException) 964 { 965 sal_Int32 nMaxRep = 0; 966 if( m_bDataInColumns ) 967 { 968 m_aInternalData.insertRow( nAfterIndex ); 969 nMaxRep = m_aInternalData.getColumnCount(); 970 } 971 else 972 { 973 m_aInternalData.insertColumn( nAfterIndex ); 974 nMaxRep = m_aInternalData.getRowCount(); 975 } 976 977 // notify change to all affected ranges 978 tSequenceMap::const_iterator aBegin( m_aSequenceMap.lower_bound( C2U("0"))); 979 tSequenceMap::const_iterator aEnd( m_aSequenceMap.upper_bound( OUString::valueOf( nMaxRep ))); 980 ::std::for_each( aBegin, aEnd, lcl_setModified()); 981 982 tSequenceMapRange aRange( m_aSequenceMap.equal_range( lcl_aCategoriesRangeName )); 983 ::std::for_each( aRange.first, aRange.second, lcl_setModified()); 984 } 985 986 void SAL_CALL InternalDataProvider::deleteDataPointForAllSequences( ::sal_Int32 nAtIndex ) 987 throw (uno::RuntimeException) 988 { 989 sal_Int32 nMaxRep = 0; 990 if( m_bDataInColumns ) 991 { 992 m_aInternalData.deleteRow( nAtIndex ); 993 nMaxRep = m_aInternalData.getColumnCount(); 994 } 995 else 996 { 997 m_aInternalData.deleteColumn( nAtIndex ); 998 nMaxRep = m_aInternalData.getRowCount(); 999 } 1000 1001 // notify change to all affected ranges 1002 tSequenceMap::const_iterator aBegin( m_aSequenceMap.lower_bound( C2U("0"))); 1003 tSequenceMap::const_iterator aEnd( m_aSequenceMap.upper_bound( OUString::valueOf( nMaxRep ))); 1004 ::std::for_each( aBegin, aEnd, lcl_setModified()); 1005 1006 tSequenceMapRange aRange( m_aSequenceMap.equal_range( lcl_aCategoriesRangeName )); 1007 ::std::for_each( aRange.first, aRange.second, lcl_setModified()); 1008 } 1009 1010 void SAL_CALL InternalDataProvider::swapDataPointWithNextOneForAllSequences( ::sal_Int32 nAtIndex ) 1011 throw (uno::RuntimeException) 1012 { 1013 if( m_bDataInColumns ) 1014 m_aInternalData.swapRowWithNext( nAtIndex ); 1015 else 1016 m_aInternalData.swapColumnWithNext( nAtIndex ); 1017 sal_Int32 nMaxRep = (m_bDataInColumns 1018 ? m_aInternalData.getColumnCount() 1019 : m_aInternalData.getRowCount()); 1020 1021 // notify change to all affected ranges 1022 tSequenceMap::const_iterator aBegin( m_aSequenceMap.lower_bound( C2U("0"))); 1023 tSequenceMap::const_iterator aEnd( m_aSequenceMap.upper_bound( OUString::valueOf( nMaxRep ))); 1024 ::std::for_each( aBegin, aEnd, lcl_setModified()); 1025 1026 tSequenceMapRange aRange( m_aSequenceMap.equal_range( lcl_aCategoriesRangeName )); 1027 ::std::for_each( aRange.first, aRange.second, lcl_setModified()); 1028 } 1029 1030 void SAL_CALL InternalDataProvider::registerDataSequenceForChanges( const Reference< chart2::data::XDataSequence >& xSeq ) 1031 throw (uno::RuntimeException) 1032 { 1033 if( xSeq.is()) 1034 lcl_addDataSequenceToMap( xSeq->getSourceRangeRepresentation(), xSeq ); 1035 } 1036 1037 1038 // ____ XRangeXMLConversion ____ 1039 OUString SAL_CALL InternalDataProvider::convertRangeToXML( const OUString& aRangeRepresentation ) 1040 throw (lang::IllegalArgumentException, 1041 uno::RuntimeException) 1042 { 1043 XMLRangeHelper::CellRange aRange; 1044 aRange.aTableName = OUString(RTL_CONSTASCII_USTRINGPARAM("local-table")); 1045 1046 // attention: this data provider has the limitation that it stores 1047 // internally if data comes from columns or rows. It is intended for 1048 // creating only one used data source. 1049 // @todo: add this information in the range representation strings 1050 if( aRangeRepresentation.match( lcl_aCategoriesRangeName )) 1051 { 1052 OSL_ASSERT( aRangeRepresentation.equals( lcl_aCategoriesRangeName ) );//it is not expected nor implmented that only parts of the categories are really requested 1053 aRange.aUpperLeft.bIsEmpty = false; 1054 if( m_bDataInColumns ) 1055 { 1056 aRange.aUpperLeft.nColumn = 0; 1057 aRange.aUpperLeft.nRow = 1; 1058 aRange.aLowerRight = aRange.aUpperLeft; 1059 aRange.aLowerRight.nRow = m_aInternalData.getRowCount(); 1060 } 1061 else 1062 { 1063 aRange.aUpperLeft.nColumn = 1; 1064 aRange.aUpperLeft.nRow = 0; 1065 aRange.aLowerRight = aRange.aUpperLeft; 1066 aRange.aLowerRight.nColumn = m_aInternalData.getColumnCount(); 1067 } 1068 } 1069 else if( aRangeRepresentation.match( lcl_aLabelRangePrefix )) 1070 { 1071 sal_Int32 nIndex = aRangeRepresentation.copy( lcl_aLabelRangePrefix.getLength()).toInt32(); 1072 aRange.aUpperLeft.bIsEmpty = false; 1073 aRange.aLowerRight.bIsEmpty = true; 1074 if( m_bDataInColumns ) 1075 { 1076 aRange.aUpperLeft.nColumn = nIndex + 1; 1077 aRange.aUpperLeft.nRow = 0; 1078 } 1079 else 1080 { 1081 aRange.aUpperLeft.nColumn = 0; 1082 aRange.aUpperLeft.nRow = nIndex + 1; 1083 } 1084 } 1085 else if( aRangeRepresentation.equals( lcl_aCompleteRange )) 1086 { 1087 aRange.aUpperLeft.bIsEmpty = false; 1088 aRange.aLowerRight.bIsEmpty = false; 1089 aRange.aUpperLeft.nColumn = 0; 1090 aRange.aUpperLeft.nRow = 0; 1091 aRange.aLowerRight.nColumn = m_aInternalData.getColumnCount(); 1092 aRange.aLowerRight.nRow = m_aInternalData.getRowCount(); 1093 } 1094 else 1095 { 1096 sal_Int32 nIndex = aRangeRepresentation.toInt32(); 1097 aRange.aUpperLeft.bIsEmpty = false; 1098 if( m_bDataInColumns ) 1099 { 1100 aRange.aUpperLeft.nColumn = nIndex + 1; 1101 aRange.aUpperLeft.nRow = 1; 1102 aRange.aLowerRight = aRange.aUpperLeft; 1103 aRange.aLowerRight.nRow = m_aInternalData.getRowCount(); 1104 } 1105 else 1106 { 1107 aRange.aUpperLeft.nColumn = 1; 1108 aRange.aUpperLeft.nRow = nIndex + 1; 1109 aRange.aLowerRight = aRange.aUpperLeft; 1110 aRange.aLowerRight.nColumn = m_aInternalData.getColumnCount(); 1111 } 1112 } 1113 1114 return XMLRangeHelper::getXMLStringFromCellRange( aRange ); 1115 } 1116 1117 OUString SAL_CALL InternalDataProvider::convertRangeFromXML( const OUString& aXMLRange ) 1118 throw (lang::IllegalArgumentException, 1119 uno::RuntimeException) 1120 { 1121 XMLRangeHelper::CellRange aRange( XMLRangeHelper::getCellRangeFromXMLString( aXMLRange )); 1122 if( aRange.aUpperLeft.bIsEmpty ) 1123 { 1124 OSL_ENSURE( aRange.aLowerRight.bIsEmpty, "Weird Range" ); 1125 return OUString(); 1126 } 1127 1128 // "all" 1129 if( !aRange.aLowerRight.bIsEmpty && 1130 ( aRange.aUpperLeft.nColumn != aRange.aLowerRight.nColumn ) && 1131 ( aRange.aUpperLeft.nRow != aRange.aLowerRight.nRow ) ) 1132 return lcl_aCompleteRange; 1133 1134 // attention: this data provider has the limitation that it stores 1135 // internally if data comes from columns or rows. It is intended for 1136 // creating only one used data source. 1137 // @todo: add this information in the range representation strings 1138 1139 // data in columns 1140 if( m_bDataInColumns ) 1141 { 1142 if( aRange.aUpperLeft.nColumn == 0 ) 1143 return lcl_aCategoriesRangeName; 1144 if( aRange.aUpperLeft.nRow == 0 ) 1145 return lcl_aLabelRangePrefix + OUString::valueOf( aRange.aUpperLeft.nColumn - 1 ); 1146 1147 return OUString::valueOf( aRange.aUpperLeft.nColumn - 1 ); 1148 } 1149 1150 // data in rows 1151 if( aRange.aUpperLeft.nRow == 0 ) 1152 return lcl_aCategoriesRangeName; 1153 if( aRange.aUpperLeft.nColumn == 0 ) 1154 return lcl_aLabelRangePrefix + OUString::valueOf( aRange.aUpperLeft.nRow - 1 ); 1155 1156 return OUString::valueOf( aRange.aUpperLeft.nRow - 1 ); 1157 } 1158 1159 namespace 1160 { 1161 1162 template< class Type > 1163 Sequence< Sequence< Type > > lcl_convertVectorVectorToSequenceSequence( const vector< vector< Type > >& rIn ) 1164 { 1165 Sequence< Sequence< Type > > aRet; 1166 sal_Int32 nOuterCount = rIn.size(); 1167 if( nOuterCount ) 1168 { 1169 aRet.realloc(nOuterCount); 1170 for( sal_Int32 nN=0; nN<nOuterCount; nN++) 1171 aRet[nN]= ContainerHelper::ContainerToSequence( rIn[nN] ); 1172 } 1173 return aRet; 1174 } 1175 1176 template< class Type > 1177 vector< vector< Type > > lcl_convertSequenceSequenceToVectorVector( const Sequence< Sequence< Type > >& rIn ) 1178 { 1179 vector< vector< Type > > aRet; 1180 sal_Int32 nOuterCount = rIn.getLength(); 1181 if( nOuterCount ) 1182 { 1183 aRet.resize(nOuterCount); 1184 for( sal_Int32 nN=0; nN<nOuterCount; nN++) 1185 aRet[nN]= ContainerHelper::SequenceToVector( rIn[nN] ); 1186 } 1187 return aRet; 1188 } 1189 1190 Sequence< Sequence< OUString > > lcl_convertComplexAnyVectorToStringSequence( const vector< vector< uno::Any > >& rIn ) 1191 { 1192 Sequence< Sequence< OUString > > aRet; 1193 sal_Int32 nOuterCount = rIn.size(); 1194 if( nOuterCount ) 1195 { 1196 aRet.realloc(nOuterCount); 1197 for( sal_Int32 nN=0; nN<nOuterCount; nN++) 1198 aRet[nN]= lcl_AnyToStringSequence( ContainerHelper::ContainerToSequence( rIn[nN] ) ); 1199 } 1200 return aRet; 1201 } 1202 1203 vector< vector< uno::Any > > lcl_convertComplexStringSequenceToAnyVector( const Sequence< Sequence< OUString > >& rIn ) 1204 { 1205 vector< vector< uno::Any > > aRet; 1206 sal_Int32 nOuterCount = rIn.getLength(); 1207 for( sal_Int32 nN=0; nN<nOuterCount; nN++) 1208 aRet.push_back( ContainerHelper::SequenceToVector( lcl_StringToAnySequence( rIn[nN] ) ) ); 1209 return aRet; 1210 } 1211 1212 class SplitCategoriesProvider_ForComplexDescriptions : public SplitCategoriesProvider 1213 { 1214 public: 1215 1216 explicit SplitCategoriesProvider_ForComplexDescriptions( const ::std::vector< ::std::vector< uno::Any > >& rComplexDescriptions ) 1217 : m_rComplexDescriptions( rComplexDescriptions ) 1218 {} 1219 virtual ~SplitCategoriesProvider_ForComplexDescriptions() 1220 {} 1221 1222 virtual sal_Int32 getLevelCount() const; 1223 virtual uno::Sequence< rtl::OUString > getStringsForLevel( sal_Int32 nIndex ) const; 1224 1225 private: 1226 const ::std::vector< ::std::vector< uno::Any > >& m_rComplexDescriptions; 1227 }; 1228 1229 sal_Int32 SplitCategoriesProvider_ForComplexDescriptions::getLevelCount() const 1230 { 1231 return lcl_getInnerLevelCount( m_rComplexDescriptions ); 1232 } 1233 uno::Sequence< rtl::OUString > SplitCategoriesProvider_ForComplexDescriptions::getStringsForLevel( sal_Int32 nLevel ) const 1234 { 1235 uno::Sequence< rtl::OUString > aResult; 1236 if( nLevel < lcl_getInnerLevelCount( m_rComplexDescriptions ) ) 1237 { 1238 aResult.realloc( m_rComplexDescriptions.size() ); 1239 transform( m_rComplexDescriptions.begin(), m_rComplexDescriptions.end(), 1240 aResult.getArray(), lcl_getStringFromLevelVector(nLevel) ); 1241 } 1242 return aResult; 1243 } 1244 1245 }//anonymous namespace 1246 1247 // ____ XDateCategories ____ 1248 Sequence< double > SAL_CALL InternalDataProvider::getDateCategories() throw (uno::RuntimeException) 1249 { 1250 double fNan = InternalDataProvider::getNotANumber(); 1251 double fValue = fNan; 1252 vector< vector< uno::Any > > aCategories( m_bDataInColumns ? m_aInternalData.getComplexRowLabels() : m_aInternalData.getComplexColumnLabels()); 1253 sal_Int32 nCount = aCategories.size(); 1254 Sequence< double > aDoubles( nCount ); 1255 vector< vector< uno::Any > >::iterator aIt( aCategories.begin() ); 1256 vector< vector< uno::Any > >::const_iterator aEnd( aCategories.end() ); 1257 for(sal_Int32 nN=0; nN<nCount && aIt!=aEnd; ++nN, ++aIt ) 1258 { 1259 if( !( !aIt->empty() && ((*aIt)[0]>>=fValue) ) ) 1260 fValue = fNan; 1261 aDoubles[nN]=fValue; 1262 } 1263 return aDoubles; 1264 } 1265 1266 void SAL_CALL InternalDataProvider::setDateCategories( const Sequence< double >& rDates ) throw (uno::RuntimeException) 1267 { 1268 sal_Int32 nCount = rDates.getLength(); 1269 vector< vector< uno::Any > > aNewCategories; 1270 aNewCategories.reserve(nCount); 1271 vector< uno::Any > aSingleLabel(1); 1272 1273 for(sal_Int32 nN=0; nN<nCount; ++nN ) 1274 { 1275 aSingleLabel[0]=uno::makeAny(rDates[nN]); 1276 aNewCategories.push_back(aSingleLabel); 1277 } 1278 1279 if( m_bDataInColumns ) 1280 m_aInternalData.setComplexRowLabels( aNewCategories ); 1281 else 1282 m_aInternalData.setComplexColumnLabels( aNewCategories ); 1283 } 1284 1285 // ____ XAnyDescriptionAccess ____ 1286 Sequence< Sequence< uno::Any > > SAL_CALL InternalDataProvider::getAnyRowDescriptions() throw (uno::RuntimeException) 1287 { 1288 return lcl_convertVectorVectorToSequenceSequence( m_aInternalData.getComplexRowLabels() ); 1289 } 1290 void SAL_CALL InternalDataProvider::setAnyRowDescriptions( const Sequence< Sequence< uno::Any > >& aRowDescriptions ) throw (uno::RuntimeException) 1291 { 1292 m_aInternalData.setComplexRowLabels( lcl_convertSequenceSequenceToVectorVector( aRowDescriptions ) ); 1293 } 1294 Sequence< Sequence< uno::Any > > SAL_CALL InternalDataProvider::getAnyColumnDescriptions() throw (uno::RuntimeException) 1295 { 1296 return lcl_convertVectorVectorToSequenceSequence( m_aInternalData.getComplexColumnLabels() ); 1297 } 1298 void SAL_CALL InternalDataProvider::setAnyColumnDescriptions( const Sequence< Sequence< uno::Any > >& aColumnDescriptions ) throw (uno::RuntimeException) 1299 { 1300 m_aInternalData.setComplexColumnLabels( lcl_convertSequenceSequenceToVectorVector( aColumnDescriptions ) ); 1301 } 1302 1303 // ____ XComplexDescriptionAccess ____ 1304 Sequence< Sequence< OUString > > SAL_CALL InternalDataProvider::getComplexRowDescriptions() throw (uno::RuntimeException) 1305 { 1306 return lcl_convertComplexAnyVectorToStringSequence( m_aInternalData.getComplexRowLabels() ); 1307 } 1308 void SAL_CALL InternalDataProvider::setComplexRowDescriptions( const Sequence< Sequence< ::rtl::OUString > >& aRowDescriptions ) throw (uno::RuntimeException) 1309 { 1310 m_aInternalData.setComplexRowLabels( lcl_convertComplexStringSequenceToAnyVector(aRowDescriptions) ); 1311 } 1312 Sequence< Sequence< ::rtl::OUString > > SAL_CALL InternalDataProvider::getComplexColumnDescriptions() throw (uno::RuntimeException) 1313 { 1314 return lcl_convertComplexAnyVectorToStringSequence( m_aInternalData.getComplexColumnLabels() ); 1315 } 1316 void SAL_CALL InternalDataProvider::setComplexColumnDescriptions( const Sequence< Sequence< ::rtl::OUString > >& aColumnDescriptions ) throw (uno::RuntimeException) 1317 { 1318 m_aInternalData.setComplexColumnLabels( lcl_convertComplexStringSequenceToAnyVector(aColumnDescriptions) ); 1319 } 1320 1321 // ____ XChartDataArray ____ 1322 Sequence< Sequence< double > > SAL_CALL InternalDataProvider::getData() 1323 throw (uno::RuntimeException) 1324 { 1325 return m_aInternalData.getData(); 1326 } 1327 1328 void SAL_CALL InternalDataProvider::setData( const Sequence< Sequence< double > >& rDataInRows ) 1329 throw (uno::RuntimeException) 1330 { 1331 return m_aInternalData.setData( rDataInRows ); 1332 } 1333 1334 void SAL_CALL InternalDataProvider::setRowDescriptions( const Sequence< OUString >& aRowDescriptions ) 1335 throw (uno::RuntimeException) 1336 { 1337 vector< vector< uno::Any > > aComplexDescriptions( aRowDescriptions.getLength() ); 1338 transform( aComplexDescriptions.begin(), aComplexDescriptions.end(), aRowDescriptions.getConstArray(), 1339 aComplexDescriptions.begin(), lcl_setAnyAtLevelFromStringSequence(0) ); 1340 m_aInternalData.setComplexRowLabels( aComplexDescriptions ); 1341 } 1342 1343 void SAL_CALL InternalDataProvider::setColumnDescriptions( const Sequence< OUString >& aColumnDescriptions ) 1344 throw (uno::RuntimeException) 1345 { 1346 vector< vector< uno::Any > > aComplexDescriptions( aColumnDescriptions.getLength() ); 1347 transform( aComplexDescriptions.begin(), aComplexDescriptions.end(), aColumnDescriptions.getConstArray(), 1348 aComplexDescriptions.begin(), lcl_setAnyAtLevelFromStringSequence(0) ); 1349 m_aInternalData.setComplexColumnLabels( aComplexDescriptions ); 1350 } 1351 1352 Sequence< OUString > SAL_CALL InternalDataProvider::getRowDescriptions() 1353 throw (uno::RuntimeException) 1354 { 1355 vector< vector< uno::Any > > aComplexLabels( m_aInternalData.getComplexRowLabels() ); 1356 SplitCategoriesProvider_ForComplexDescriptions aProvider( aComplexLabels ); 1357 return ExplicitCategoriesProvider::getExplicitSimpleCategories( aProvider ); 1358 } 1359 1360 Sequence< OUString > SAL_CALL InternalDataProvider::getColumnDescriptions() 1361 throw (uno::RuntimeException) 1362 { 1363 vector< vector< uno::Any > > aComplexLabels( m_aInternalData.getComplexColumnLabels() ); 1364 SplitCategoriesProvider_ForComplexDescriptions aProvider( aComplexLabels ); 1365 return ExplicitCategoriesProvider::getExplicitSimpleCategories( aProvider ); 1366 } 1367 1368 // ____ XChartData (base of XChartDataArray) ____ 1369 void SAL_CALL InternalDataProvider::addChartDataChangeEventListener( 1370 const Reference< ::com::sun::star::chart::XChartDataChangeEventListener >& ) 1371 throw (uno::RuntimeException) 1372 { 1373 } 1374 1375 void SAL_CALL InternalDataProvider::removeChartDataChangeEventListener( 1376 const Reference< ::com::sun::star::chart::XChartDataChangeEventListener >& ) 1377 throw (uno::RuntimeException) 1378 { 1379 } 1380 1381 double SAL_CALL InternalDataProvider::getNotANumber() 1382 throw (uno::RuntimeException) 1383 { 1384 double fNan; 1385 ::rtl::math::setNan( & fNan ); 1386 return fNan; 1387 } 1388 1389 ::sal_Bool SAL_CALL InternalDataProvider::isNotANumber( double nNumber ) 1390 throw (uno::RuntimeException) 1391 { 1392 return ::rtl::math::isNan( nNumber ) 1393 || ::rtl::math::isInf( nNumber ); 1394 } 1395 // lang::XInitialization: 1396 void SAL_CALL InternalDataProvider::initialize(const uno::Sequence< uno::Any > & _aArguments) throw (uno::RuntimeException, uno::Exception) 1397 { 1398 comphelper::SequenceAsHashMap aArgs(_aArguments); 1399 if ( aArgs.getUnpackedValueOrDefault(::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("CreateDefaultData")),sal_False) ) 1400 createDefaultData(); 1401 } 1402 // ____ XCloneable ____ 1403 Reference< util::XCloneable > SAL_CALL InternalDataProvider::createClone() 1404 throw (uno::RuntimeException) 1405 { 1406 return Reference< util::XCloneable >( new InternalDataProvider( *this )); 1407 } 1408 1409 1410 // ================================================================================ 1411 1412 Sequence< OUString > InternalDataProvider::getSupportedServiceNames_Static() 1413 { 1414 Sequence< OUString > aServices( 1 ); 1415 aServices[ 0 ] = OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.chart2.data.DataProvider" )); 1416 return aServices; 1417 } 1418 1419 // ================================================================================ 1420 1421 APPHELPER_XSERVICEINFO_IMPL( InternalDataProvider, lcl_aServiceName ); 1422 1423 } // namespace chart 1424