bump product version to 4.1.6.2
[LibreOffice.git] / chart2 / source / tools / InternalDataProvider.cxx
blob147afc8a29351f062c80309f1890d4c71dbef302
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
21 #include <rtl/math.hxx>
23 #include <valarray>
25 #include "InternalDataProvider.hxx"
26 #include "LabeledDataSequence.hxx"
27 #include "DataSource.hxx"
28 #include "PropertyHelper.hxx"
29 #include "macros.hxx"
30 #include "XMLRangeHelper.hxx"
31 #include "ContainerHelper.hxx"
32 #include "CommonConverters.hxx"
33 #include "CommonFunctors.hxx"
34 #include "UncachedDataSequence.hxx"
35 #include "DataSourceHelper.hxx"
36 #include "ChartModelHelper.hxx"
37 #include "DiagramHelper.hxx"
38 #include "ExplicitCategoriesProvider.hxx"
40 #include <com/sun/star/chart2/XChartDocument.hpp>
41 #include <com/sun/star/chart2/data/XDataSequence.hpp>
42 #include <com/sun/star/chart/ChartDataRowSource.hpp>
43 #include <rtl/ustrbuf.hxx>
44 #include <unotools/charclass.hxx>
45 #include <comphelper/sequenceashashmap.hxx>
47 #include <vector>
48 #include <algorithm>
50 using namespace ::com::sun::star;
51 using namespace ::std;
53 using ::com::sun::star::uno::Reference;
54 using ::com::sun::star::uno::Sequence;
56 namespace chart
59 // ================================================================================
61 namespace
64 // note: in xmloff this name is used to indicate usage of own data
65 static const OUString lcl_aServiceName( "com.sun.star.comp.chart.InternalDataProvider" );
67 static const OUString lcl_aCategoriesRangeName( "categories" );
68 static const OUString lcl_aCategoriesLevelRangeNamePrefix( "categoriesL " ); //L <-> level
69 static const OUString lcl_aCategoriesPointRangeNamePrefix( "categoriesP " ); //P <-> point
70 static const OUString lcl_aCategoriesRoleName( "categories" );
71 static const OUString lcl_aLabelRangePrefix( "label " );
72 static const OUString lcl_aCompleteRange( "all" );
74 typedef ::std::multimap< OUString, uno::WeakReference< chart2::data::XDataSequence > >
75 lcl_tSequenceMap;
77 Sequence< OUString > lcl_AnyToStringSequence( const Sequence< uno::Any >& aAnySeq )
79 Sequence< OUString > aResult;
80 aResult.realloc( aAnySeq.getLength() );
81 transform( aAnySeq.getConstArray(), aAnySeq.getConstArray() + aAnySeq.getLength(),
82 aResult.getArray(), CommonFunctors::AnyToString() );
83 return aResult;
86 Sequence< uno::Any > lcl_StringToAnySequence( const Sequence< OUString >& aStringSeq )
88 Sequence< uno::Any > aResult;
89 aResult.realloc( aStringSeq.getLength() );
90 transform( aStringSeq.getConstArray(), aStringSeq.getConstArray() + aStringSeq.getLength(),
91 aResult.getArray(), CommonFunctors::makeAny< OUString >() );
92 return aResult;
95 struct lcl_setModified : public ::std::unary_function< lcl_tSequenceMap, void >
97 void operator() ( const lcl_tSequenceMap::value_type & rMapEntry )
99 // convert weak reference to reference
100 Reference< chart2::data::XDataSequence > xSeq( rMapEntry.second );
101 if( xSeq.is())
103 Reference< util::XModifiable > xMod( xSeq, uno::UNO_QUERY );
104 if( xMod.is())
105 xMod->setModified( sal_True );
110 struct lcl_internalizeSeries : public ::std::unary_function< Reference< chart2::XDataSeries >, void >
112 lcl_internalizeSeries( InternalData & rInternalData,
113 InternalDataProvider & rProvider,
114 bool bConnectToModel, bool bDataInColumns ) :
115 m_rInternalData( rInternalData ),
116 m_rProvider( rProvider ),
117 m_bConnectToModel( bConnectToModel ),
118 m_bDataInColumns( bDataInColumns )
120 void operator() ( const Reference< chart2::XDataSeries > & xSeries )
122 Reference< chart2::data::XDataSource > xSource( xSeries, uno::UNO_QUERY );
123 Reference< chart2::data::XDataSink > xSink( xSeries, uno::UNO_QUERY );
124 if( xSource.is() && xSink.is() )
126 Sequence< Reference< chart2::data::XLabeledDataSequence > > aOldSeriesData = xSource->getDataSequences();
127 Sequence< Reference< chart2::data::XLabeledDataSequence > > aNewSeriesData( aOldSeriesData.getLength() );
128 for( sal_Int32 i=0; i<aOldSeriesData.getLength(); ++i )
130 sal_Int32 nNewIndex( m_bDataInColumns ? m_rInternalData.appendColumn() : m_rInternalData.appendRow() );
131 OUString aIdentifier( OUString::valueOf( nNewIndex ));
132 //@todo: deal also with genericXDataSequence
133 Reference< chart2::data::XNumericalDataSequence > xValues( aOldSeriesData[i]->getValues(), uno::UNO_QUERY );
134 Reference< chart2::data::XTextualDataSequence > xLabel( aOldSeriesData[i]->getLabel(), uno::UNO_QUERY );
135 Reference< chart2::data::XDataSequence > xNewValues;
137 if( xValues.is() )
139 ::std::vector< double > aValues( ContainerHelper::SequenceToVector( xValues->getNumericalData()));
140 if( m_bDataInColumns )
141 m_rInternalData.setColumnValues( nNewIndex, aValues );
142 else
143 m_rInternalData.setRowValues( nNewIndex, aValues );
144 if( m_bConnectToModel )
146 xNewValues.set( m_rProvider.createDataSequenceByRangeRepresentation( aIdentifier ));
147 comphelper::copyProperties(
148 Reference< beans::XPropertySet >( xValues, uno::UNO_QUERY ),
149 Reference< beans::XPropertySet >( xNewValues, uno::UNO_QUERY ));
153 if( xLabel.is() )
155 if( m_bDataInColumns )
156 m_rInternalData.setComplexColumnLabel( nNewIndex, ContainerHelper::SequenceToVector( lcl_StringToAnySequence( xLabel->getTextualData() ) ) );
157 else
158 m_rInternalData.setComplexRowLabel( nNewIndex, ContainerHelper::SequenceToVector( lcl_StringToAnySequence( xLabel->getTextualData() ) ) );
159 if( m_bConnectToModel )
161 Reference< chart2::data::XDataSequence > xNewLabel(
162 m_rProvider.createDataSequenceByRangeRepresentation( lcl_aLabelRangePrefix + aIdentifier ));
163 comphelper::copyProperties(
164 Reference< beans::XPropertySet >( xLabel, uno::UNO_QUERY ),
165 Reference< beans::XPropertySet >( xNewLabel, uno::UNO_QUERY ));
166 aNewSeriesData[i] = Reference< chart2::data::XLabeledDataSequence >(
167 new LabeledDataSequence( xNewValues, xNewLabel ));
170 else
172 if( m_bConnectToModel )
173 aNewSeriesData[i] = Reference< chart2::data::XLabeledDataSequence >(
174 new LabeledDataSequence( xNewValues ));
177 if( m_bConnectToModel )
178 xSink->setData( aNewSeriesData );
182 private:
183 InternalData & m_rInternalData;
184 InternalDataProvider & m_rProvider;
185 bool m_bConnectToModel;
186 bool m_bDataInColumns;
189 struct lcl_copyFromLevel : public ::std::unary_function< vector< uno::Any >, uno::Any >
191 public:
193 explicit lcl_copyFromLevel( sal_Int32 nLevel ) : m_nLevel( nLevel )
196 uno::Any operator() ( const vector< uno::Any >& rVector )
198 uno::Any aRet;
199 if( m_nLevel < static_cast< sal_Int32 >(rVector.size()) )
200 aRet = rVector[m_nLevel];
201 return aRet;
204 private:
205 sal_Int32 m_nLevel;
208 struct lcl_getStringFromLevelVector : public ::std::unary_function< vector< uno::Any >, OUString >
210 public:
212 explicit lcl_getStringFromLevelVector( sal_Int32 nLevel ) : m_nLevel( nLevel )
215 OUString operator() ( const vector< uno::Any >& rVector )
217 OUString aString;
218 if( m_nLevel < static_cast< sal_Int32 >(rVector.size()) )
219 aString = CommonFunctors::AnyToString()(rVector[m_nLevel]);
220 return aString;
223 private:
224 sal_Int32 m_nLevel;
228 struct lcl_setAnyAtLevel : public ::std::binary_function< vector< uno::Any >, uno::Any, vector< uno::Any > >
230 public:
232 explicit lcl_setAnyAtLevel( sal_Int32 nLevel ) : m_nLevel( nLevel )
235 vector< uno::Any > operator() ( const vector< uno::Any >& rVector, const uno::Any& rNewValue )
237 vector< uno::Any > aRet( rVector );
238 if( m_nLevel >= static_cast< sal_Int32 >(aRet.size()) )
239 aRet.resize( m_nLevel+1 );
240 aRet[ m_nLevel ]=rNewValue;
241 return aRet;
244 private:
245 sal_Int32 m_nLevel;
248 struct lcl_setAnyAtLevelFromStringSequence : public ::std::binary_function< vector< uno::Any >, OUString, vector< uno::Any > >
250 public:
252 explicit lcl_setAnyAtLevelFromStringSequence( sal_Int32 nLevel ) : m_nLevel( nLevel )
255 vector< uno::Any > operator() ( const vector< uno::Any >& rVector, const OUString& rNewValue )
257 vector< uno::Any > aRet( rVector );
258 if( m_nLevel >= static_cast< sal_Int32 >(aRet.size()) )
259 aRet.resize( m_nLevel+1 );
260 aRet[ m_nLevel ]=uno::makeAny(rNewValue);
261 return aRet;
264 private:
265 sal_Int32 m_nLevel;
268 struct lcl_insertAnyAtLevel : public ::std::unary_function< vector< uno::Any >, void >
270 public:
272 explicit lcl_insertAnyAtLevel( sal_Int32 nLevel ) : m_nLevel( nLevel )
275 void operator() ( vector< uno::Any >& rVector )
277 if( m_nLevel >= static_cast< sal_Int32 >(rVector.size()) )
279 rVector.resize( m_nLevel + 1 );
281 else
283 rVector.insert( rVector.begin() + m_nLevel, uno::Any() );
287 private:
288 sal_Int32 m_nLevel;
291 struct lcl_removeAnyAtLevel : public ::std::unary_function< vector< uno::Any >, void >
293 public:
295 explicit lcl_removeAnyAtLevel( sal_Int32 nLevel ) : m_nLevel( nLevel )
298 void operator() ( vector< uno::Any >& rVector )
300 if( m_nLevel < static_cast<sal_Int32>(rVector.size()) )
302 rVector.erase(rVector.begin() + m_nLevel);
306 private:
307 sal_Int32 m_nLevel;
310 } // anonymous namespace
312 // ================================================================================
314 InternalDataProvider::InternalDataProvider( const Reference< uno::XComponentContext > & /*_xContext*/)
315 : m_bDataInColumns( true )
318 InternalDataProvider::InternalDataProvider( const Reference< chart2::XChartDocument > & xChartDoc, bool bConnectToModel )
319 : m_bDataInColumns( true )
323 Reference< chart2::XDiagram > xDiagram( ChartModelHelper::findDiagram( xChartDoc ) );
324 if( xDiagram.is())
326 Reference< frame::XModel > xChartModel( xChartDoc, uno::UNO_QUERY );
328 //data in columns?
330 OUString aRangeString;
331 bool bFirstCellAsLabel = true;
332 bool bHasCategories = true;
333 uno::Sequence< sal_Int32 > aSequenceMapping;
334 DataSourceHelper::detectRangeSegmentation( xChartModel, aRangeString, aSequenceMapping, m_bDataInColumns, bFirstCellAsLabel, bHasCategories );
337 // categories
339 vector< vector< uno::Any > > aNewCategories;//inner count is level
341 ExplicitCategoriesProvider aExplicitCategoriesProvider( ChartModelHelper::getFirstCoordinateSystem(xChartModel), xChartModel );
343 const Sequence< Reference< chart2::data::XLabeledDataSequence> >& rSplitCategoriesList( aExplicitCategoriesProvider.getSplitCategoriesList() );
344 sal_Int32 nLevelCount = rSplitCategoriesList.getLength();
345 for( sal_Int32 nL = 0; nL<nLevelCount; nL++ )
347 Reference< chart2::data::XLabeledDataSequence > xLDS( rSplitCategoriesList[nL] );
348 if( !xLDS.is() )
349 continue;
350 Sequence< uno::Any > aDataSeq;
351 Reference< chart2::data::XDataSequence > xSeq( xLDS->getValues() );
352 if( xSeq.is() )
353 aDataSeq = xSeq->getData();
354 sal_Int32 nLength = aDataSeq.getLength();
355 sal_Int32 nCatLength = static_cast< sal_Int32 >(aNewCategories.size());
356 if( nCatLength < nLength )
357 aNewCategories.resize( nLength );
358 else if( nLength < nCatLength )
359 aDataSeq.realloc( nCatLength );
360 transform( aNewCategories.begin(), aNewCategories.end(), aDataSeq.getConstArray(),
361 aNewCategories.begin(), lcl_setAnyAtLevel(nL) );
363 if( !nLevelCount )
365 Sequence< OUString > aSimplecategories = aExplicitCategoriesProvider.getSimpleCategories();
366 sal_Int32 nLength = aSimplecategories.getLength();
367 aNewCategories.reserve( nLength );
368 for( sal_Int32 nN=0; nN<nLength; nN++)
370 vector< uno::Any > aVector(1);
371 aVector[0] = uno::makeAny( aSimplecategories[nN] );
372 aNewCategories.push_back( aVector );
377 if( m_bDataInColumns )
378 m_aInternalData.setComplexRowLabels( aNewCategories );
379 else
380 m_aInternalData.setComplexColumnLabels( aNewCategories );
381 if( bConnectToModel )
382 DiagramHelper::setCategoriesToDiagram( new LabeledDataSequence(
383 createDataSequenceByRangeRepresentation( lcl_aCategoriesRangeName )), xDiagram );
386 // data series
387 ::std::vector< Reference< chart2::XDataSeries > > aSeriesVector( ChartModelHelper::getDataSeries( xChartDoc ));
388 ::std::for_each( aSeriesVector.begin(), aSeriesVector.end(), lcl_internalizeSeries( m_aInternalData, *this, bConnectToModel, m_bDataInColumns ) );
391 catch( const uno::Exception & ex )
393 ASSERT_EXCEPTION( ex );
397 // copy-CTOR
398 InternalDataProvider::InternalDataProvider( const InternalDataProvider & rOther ) :
399 impl::InternalDataProvider_Base(),
400 m_aSequenceMap( rOther.m_aSequenceMap ),
401 m_aInternalData( rOther.m_aInternalData ),
402 m_bDataInColumns( rOther.m_bDataInColumns )
405 InternalDataProvider::~InternalDataProvider()
408 void InternalDataProvider::lcl_addDataSequenceToMap(
409 const OUString & rRangeRepresentation,
410 const Reference< chart2::data::XDataSequence > & xSequence )
412 m_aSequenceMap.insert(
413 tSequenceMap::value_type(
414 rRangeRepresentation,
415 uno::WeakReference< chart2::data::XDataSequence >( xSequence )));
418 void InternalDataProvider::lcl_deleteMapReferences( const OUString & rRangeRepresentation )
420 // set sequence to deleted by setting its range to an empty string
421 tSequenceMapRange aRange( m_aSequenceMap.equal_range( rRangeRepresentation ));
422 for( tSequenceMap::iterator aIt( aRange.first ); aIt != aRange.second; ++aIt )
424 Reference< chart2::data::XDataSequence > xSeq( aIt->second );
425 if( xSeq.is())
427 Reference< container::XNamed > xNamed( xSeq, uno::UNO_QUERY );
428 if( xNamed.is())
429 xNamed->setName( OUString());
432 // remove from map
433 m_aSequenceMap.erase( aRange.first, aRange.second );
436 void InternalDataProvider::lcl_adaptMapReferences(
437 const OUString & rOldRangeRepresentation,
438 const OUString & rNewRangeRepresentation )
440 tSequenceMapRange aRange( m_aSequenceMap.equal_range( rOldRangeRepresentation ));
441 tSequenceMap aNewElements;
442 for( tSequenceMap::iterator aIt( aRange.first ); aIt != aRange.second; ++aIt )
444 Reference< chart2::data::XDataSequence > xSeq( aIt->second );
445 if( xSeq.is())
447 Reference< container::XNamed > xNamed( xSeq, uno::UNO_QUERY );
448 if( xNamed.is())
449 xNamed->setName( rNewRangeRepresentation );
451 aNewElements.insert( tSequenceMap::value_type( rNewRangeRepresentation, aIt->second ));
453 // erase map values for old index
454 m_aSequenceMap.erase( aRange.first, aRange.second );
455 // add new entries for values with new index
456 ::std::copy( aNewElements.begin(), aNewElements.end(),
457 ::std::inserter( m_aSequenceMap,
458 m_aSequenceMap.upper_bound( rNewRangeRepresentation )));
461 void InternalDataProvider::lcl_increaseMapReferences(
462 sal_Int32 nBegin, sal_Int32 nEnd )
464 for( sal_Int32 nIndex = nEnd - 1; nIndex >= nBegin; --nIndex )
466 lcl_adaptMapReferences( OUString::valueOf( nIndex ),
467 OUString::valueOf( nIndex + 1 ));
468 lcl_adaptMapReferences( lcl_aLabelRangePrefix + OUString::valueOf( nIndex ),
469 lcl_aLabelRangePrefix + OUString::valueOf( nIndex + 1 ));
473 void InternalDataProvider::lcl_decreaseMapReferences(
474 sal_Int32 nBegin, sal_Int32 nEnd )
476 for( sal_Int32 nIndex = nBegin; nIndex < nEnd; ++nIndex )
478 lcl_adaptMapReferences( OUString::valueOf( nIndex ),
479 OUString::valueOf( nIndex - 1 ));
480 lcl_adaptMapReferences( lcl_aLabelRangePrefix + OUString::valueOf( nIndex ),
481 lcl_aLabelRangePrefix + OUString::valueOf( nIndex - 1 ));
485 Reference< chart2::data::XDataSequence > InternalDataProvider::lcl_createDataSequenceAndAddToMap(
486 const OUString & rRangeRepresentation )
488 OUString aRangeRepresentation = rRangeRepresentation;
489 if( aRangeRepresentation.indexOf('{') >= 0 )
491 ::std::vector< double > aNewData;
492 ::std::vector< uno::Any > aNewLabels;
493 OUString aToken;
494 sal_Int32 nCategories = 0;
495 sal_Int32 nIndex = 0;
496 bool bValues = true;
497 bool bLabelSet = false;
498 OUString str = aRangeRepresentation.replace('{',' ').replace('}',' ');
500 m_aInternalData.clearDefaultData();
501 sal_Int32 n = m_aInternalData.getColumnCount();
502 if( n )
503 n = n - 1;
507 // TODO: This will be problematic if ';' is used in label names
508 // '"' character also needs to be considered in such cases
509 aToken = str.getToken(0,';',nIndex);
510 if( aToken.isEmpty() )
511 break;
512 if( aToken.indexOf('"') < 0 )
514 aNewData.push_back( aToken.toDouble() );
516 else
518 aNewLabels.push_back( uno::makeAny(aToken.replace('"', ' ').trim()) );
519 if( !nCategories &&
520 ( !m_aInternalData.getComplexColumnLabel(n).size() ||
521 !m_aInternalData.getComplexColumnLabel(n).front().hasValue() ) )
523 m_aInternalData.setComplexColumnLabel( n, aNewLabels );
524 bLabelSet = true;
526 else
528 m_aInternalData.setComplexRowLabel(nCategories, aNewLabels);
529 if(nCategories==1 && bLabelSet)
531 ::std::vector< uno::Any > aLabels;
532 m_aInternalData.setComplexRowLabel( 0, m_aInternalData.getComplexColumnLabel( n ) );
533 m_aInternalData.setComplexColumnLabel( n, aLabels );
536 aNewLabels.pop_back();
537 nCategories++;
538 bValues = false;
540 } while( nIndex >= 0 );
542 if( bValues )
544 m_aInternalData.insertColumn( n );
545 m_aInternalData.setColumnValues( n, aNewData );
546 aRangeRepresentation = OUString::valueOf( n );
548 else if( nCategories > 1 )
550 aRangeRepresentation = lcl_aCategoriesRangeName;
552 else
554 aRangeRepresentation = lcl_aLabelRangePrefix+OUString::valueOf( n );
558 Reference< chart2::data::XDataSequence > xSeq(
559 new UncachedDataSequence( this, aRangeRepresentation ));
560 lcl_addDataSequenceToMap( aRangeRepresentation, xSeq );
561 return xSeq;
564 Reference< chart2::data::XDataSequence > InternalDataProvider::lcl_createDataSequenceAndAddToMap(
565 const OUString & rRangeRepresentation,
566 const OUString & rRole )
568 Reference< chart2::data::XDataSequence > xSeq(
569 new UncachedDataSequence( this, rRangeRepresentation, rRole ));
570 lcl_addDataSequenceToMap( rRangeRepresentation, xSeq );
571 return xSeq;
574 void InternalDataProvider::createDefaultData()
576 m_aInternalData.createDefaultData();
579 // ____ XDataProvider ____
580 ::sal_Bool SAL_CALL InternalDataProvider::createDataSourcePossible( const Sequence< beans::PropertyValue >& /* aArguments */ )
581 throw (uno::RuntimeException)
583 return true;
586 namespace
589 sal_Int32 lcl_getInnerLevelCount( const vector< vector< uno::Any > >& rLabels )
591 sal_Int32 nCount = 1;//minimum is 1!
592 vector< vector< uno::Any > >::const_iterator aLevelIt( rLabels.begin() );
593 vector< vector< uno::Any > >::const_iterator aLevelEnd( rLabels.end() );
594 for( ;aLevelIt!=aLevelEnd; ++aLevelIt )
596 const vector< uno::Any >& rCurrentLevelLabels = *aLevelIt;
597 nCount = std::max<sal_Int32>( rCurrentLevelLabels.size(), nCount );
599 return nCount;
602 }//end anonymous namespace
604 Reference< chart2::data::XDataSource > SAL_CALL InternalDataProvider::createDataSource(
605 const Sequence< beans::PropertyValue >& aArguments )
606 throw (lang::IllegalArgumentException,
607 uno::RuntimeException)
609 OUString aRangeRepresentation;
610 bool bUseColumns = true;
611 bool bFirstCellAsLabel = true;
612 bool bHasCategories = true;
613 uno::Sequence< sal_Int32 > aSequenceMapping;
614 DataSourceHelper::readArguments( aArguments, aRangeRepresentation, aSequenceMapping, bUseColumns, bFirstCellAsLabel, bHasCategories );
616 if( aRangeRepresentation.equals( lcl_aCategoriesRangeName ) )
618 //return split complex categories if we have any:
619 ::std::vector< Reference< chart2::data::XLabeledDataSequence > > aComplexCategories;
620 vector< vector< uno::Any > > aCategories( m_bDataInColumns ? m_aInternalData.getComplexRowLabels() : m_aInternalData.getComplexColumnLabels());
621 if( bUseColumns==m_bDataInColumns )
623 sal_Int32 nLevelCount = lcl_getInnerLevelCount( aCategories );
624 for( sal_Int32 nL=0; nL<nLevelCount; nL++ )
625 aComplexCategories.push_back( new LabeledDataSequence(
626 new UncachedDataSequence( this
627 , lcl_aCategoriesLevelRangeNamePrefix + OUString::valueOf( nL )
628 , lcl_aCategoriesRoleName ) ) );
630 else
632 sal_Int32 nPointCount = m_bDataInColumns ? m_aInternalData.getRowCount() : m_aInternalData.getColumnCount();
633 for( sal_Int32 nP=0; nP<nPointCount; nP++ )
634 aComplexCategories.push_back( new LabeledDataSequence(
635 new UncachedDataSequence( this
636 , lcl_aCategoriesPointRangeNamePrefix + OUString::valueOf( nP )
637 , lcl_aCategoriesRoleName ) ) );
639 //don't add the created sequences to the map as they are used temporarily only ...
640 return new DataSource( ContainerHelper::ContainerToSequence(aComplexCategories) );
643 OSL_ASSERT( aRangeRepresentation.equals( lcl_aCompleteRange ));
645 ::std::vector< Reference< chart2::data::XLabeledDataSequence > > aResultLSeqVec;
647 // categories
648 if( bHasCategories )
649 aResultLSeqVec.push_back(
650 new LabeledDataSequence( lcl_createDataSequenceAndAddToMap( lcl_aCategoriesRangeName, lcl_aCategoriesRoleName ) ) );
652 // data with labels
653 ::std::vector< Reference< chart2::data::XLabeledDataSequence > > aDataVec;
654 const sal_Int32 nCount = (bUseColumns ? m_aInternalData.getColumnCount() : m_aInternalData.getRowCount());
655 for( sal_Int32 nIdx=0; nIdx<nCount; ++nIdx )
657 aDataVec.push_back(
658 new LabeledDataSequence(
659 lcl_createDataSequenceAndAddToMap( OUString::valueOf( nIdx )),
660 lcl_createDataSequenceAndAddToMap( lcl_aLabelRangePrefix + OUString::valueOf( nIdx ))));
663 // attention: this data provider has the limitation that it stores
664 // internally if data comes from columns or rows. It is intended for
665 // creating only one used data source.
666 // @todo: add this information in the range representation strings
667 m_bDataInColumns = bUseColumns;
669 //reorder labeled sequences according to aSequenceMapping; ignore categories
670 for( sal_Int32 nNewIndex = 0; nNewIndex < aSequenceMapping.getLength(); nNewIndex++ )
672 std::vector< LabeledDataSequence* >::size_type nOldIndex = aSequenceMapping[nNewIndex];
673 if( nOldIndex < aDataVec.size() )
675 if( aDataVec[nOldIndex].is() )
677 aResultLSeqVec.push_back( aDataVec[nOldIndex] );
678 aDataVec[nOldIndex] = 0;
683 //add left over data sequences to result
684 ::std::vector< Reference< chart2::data::XLabeledDataSequence > >::iterator aIt(aDataVec.begin());
685 const ::std::vector< Reference< chart2::data::XLabeledDataSequence > >::const_iterator aEndIt(aDataVec.end());
686 for( ;aIt!=aEndIt; ++aIt)
688 if( aIt->is() )
689 aResultLSeqVec.push_back( *aIt );
692 return new DataSource( ContainerHelper::ContainerToSequence(aResultLSeqVec) );
695 Sequence< beans::PropertyValue > SAL_CALL InternalDataProvider::detectArguments(
696 const Reference< chart2::data::XDataSource >& /* xDataSource */ )
697 throw (uno::RuntimeException)
699 Sequence< beans::PropertyValue > aArguments( 4 );
700 aArguments[0] = beans::PropertyValue(
701 "CellRangeRepresentation", -1, uno::makeAny( lcl_aCompleteRange ),
702 beans::PropertyState_DIRECT_VALUE );
703 aArguments[1] = beans::PropertyValue(
704 "DataRowSource", -1, uno::makeAny(
705 m_bDataInColumns
706 ? ::com::sun::star::chart::ChartDataRowSource_COLUMNS
707 : ::com::sun::star::chart::ChartDataRowSource_ROWS ),
708 beans::PropertyState_DIRECT_VALUE );
709 // internal data always contains labels and categories
710 aArguments[2] = beans::PropertyValue(
711 "FirstCellAsLabel", -1, uno::makeAny( true ), beans::PropertyState_DIRECT_VALUE );
712 aArguments[3] = beans::PropertyValue(
713 "HasCategories", -1, uno::makeAny( true ), beans::PropertyState_DIRECT_VALUE );
715 // #i85913# Sequence Mapping is not needed for internal data, as it is
716 // applied to the data when the data source is created.
718 return aArguments;
721 ::sal_Bool SAL_CALL InternalDataProvider::createDataSequenceByRangeRepresentationPossible( const OUString& /* aRangeRepresentation */ )
722 throw (uno::RuntimeException)
724 return true;
727 Reference< chart2::data::XDataSequence > SAL_CALL InternalDataProvider::createDataSequenceByRangeRepresentation(
728 const OUString& aRangeRepresentation )
729 throw (lang::IllegalArgumentException,
730 uno::RuntimeException)
732 if( aRangeRepresentation.match( lcl_aCategoriesRangeName ))
734 OSL_ASSERT( aRangeRepresentation.equals( lcl_aCategoriesRangeName ) );//it is not expected nor implmented that only parts of the categories are really requested
736 // categories
737 return lcl_createDataSequenceAndAddToMap( lcl_aCategoriesRangeName, lcl_aCategoriesRoleName );
739 else if( aRangeRepresentation.match( lcl_aLabelRangePrefix ))
741 // label
742 sal_Int32 nIndex = aRangeRepresentation.copy( lcl_aLabelRangePrefix.getLength()).toInt32();
743 return lcl_createDataSequenceAndAddToMap( lcl_aLabelRangePrefix + OUString::valueOf( nIndex ));
745 else if ( aRangeRepresentation == "last" )
747 sal_Int32 nIndex = (m_bDataInColumns
748 ? m_aInternalData.getColumnCount()
749 : m_aInternalData.getRowCount()) - 1;
750 return lcl_createDataSequenceAndAddToMap( OUString::valueOf( nIndex ));
752 else if( !aRangeRepresentation.isEmpty())
754 // data
755 return lcl_createDataSequenceAndAddToMap( aRangeRepresentation );
758 return Reference< chart2::data::XDataSequence >();
761 Reference< sheet::XRangeSelection > SAL_CALL InternalDataProvider::getRangeSelection()
762 throw (uno::RuntimeException)
764 // there is no range selection component
765 return Reference< sheet::XRangeSelection >();
768 // ____ XInternalDataProvider ____
769 ::sal_Bool SAL_CALL InternalDataProvider::hasDataByRangeRepresentation( const OUString& aRange )
770 throw (uno::RuntimeException)
772 sal_Bool bResult = false;
774 if( aRange.match( lcl_aCategoriesRangeName ))
776 OSL_ASSERT( aRange.equals( lcl_aCategoriesRangeName ) );//it is not expected nor implmented that only parts of the categories are really requested
777 bResult = true;
779 else if( aRange.match( lcl_aLabelRangePrefix ))
781 sal_Int32 nIndex = aRange.copy( lcl_aLabelRangePrefix.getLength()).toInt32();
782 bResult = (nIndex < (m_bDataInColumns ? m_aInternalData.getColumnCount(): m_aInternalData.getRowCount()));
784 else
786 sal_Int32 nIndex = aRange.toInt32();
787 bResult = (nIndex < (m_bDataInColumns ? m_aInternalData.getColumnCount(): m_aInternalData.getRowCount()));
790 return bResult;
793 Sequence< uno::Any > SAL_CALL InternalDataProvider::getDataByRangeRepresentation( const OUString& aRange )
794 throw (uno::RuntimeException)
796 Sequence< uno::Any > aResult;
798 if( aRange.match( lcl_aLabelRangePrefix ) )
800 sal_Int32 nIndex = aRange.copy( lcl_aLabelRangePrefix.getLength()).toInt32();
801 vector< uno::Any > aComplexLabel = m_bDataInColumns
802 ? m_aInternalData.getComplexColumnLabel( nIndex )
803 : m_aInternalData.getComplexRowLabel( nIndex );
804 if( !aComplexLabel.empty() )
805 aResult = ContainerHelper::ContainerToSequence(aComplexLabel);
807 else if( aRange.match( lcl_aCategoriesPointRangeNamePrefix ) )
809 sal_Int32 nPointIndex = aRange.copy( lcl_aCategoriesPointRangeNamePrefix.getLength() ).toInt32();
810 vector< uno::Any > aComplexCategory = m_bDataInColumns
811 ? m_aInternalData.getComplexRowLabel( nPointIndex )
812 : m_aInternalData.getComplexColumnLabel( nPointIndex );
813 if( !aComplexCategory.empty() )
814 aResult = ContainerHelper::ContainerToSequence(aComplexCategory);
816 else if( aRange.match( lcl_aCategoriesLevelRangeNamePrefix ) )
818 sal_Int32 nLevel = aRange.copy( lcl_aCategoriesLevelRangeNamePrefix.getLength() ).toInt32();
819 vector< vector< uno::Any > > aCategories( m_bDataInColumns ? m_aInternalData.getComplexRowLabels() : m_aInternalData.getComplexColumnLabels());
820 if( nLevel < lcl_getInnerLevelCount( aCategories ) )
822 aResult.realloc( aCategories.size() );
823 transform( aCategories.begin(), aCategories.end(),
824 aResult.getArray(), lcl_copyFromLevel(nLevel) );
827 else if( aRange.equals( lcl_aCategoriesRangeName ) )
829 vector< vector< uno::Any > > aCategories( m_bDataInColumns ? m_aInternalData.getComplexRowLabels() : m_aInternalData.getComplexColumnLabels());
830 sal_Int32 nLevelCount = lcl_getInnerLevelCount( aCategories );
831 if( nLevelCount == 1 )
833 sal_Int32 nL=0;
834 aResult = this->getDataByRangeRepresentation( lcl_aCategoriesLevelRangeNamePrefix + OUString::valueOf( nL ) );
836 else
838 Sequence< OUString > aLabels = m_bDataInColumns ? this->getRowDescriptions() : this->getColumnDescriptions();
839 aResult.realloc( aLabels.getLength() );
840 transform( aLabels.getConstArray(), aLabels.getConstArray() + aLabels.getLength(),
841 aResult.getArray(), CommonFunctors::makeAny< OUString >() );
844 else
846 sal_Int32 nIndex = aRange.toInt32();
847 if( nIndex >= 0 )
849 Sequence< double > aData;
850 if( m_bDataInColumns )
851 aData = m_aInternalData.getColumnValues(nIndex);
852 else
853 aData = m_aInternalData.getRowValues(nIndex);
854 if( aData.getLength() )
856 aResult.realloc( aData.getLength());
857 transform( aData.getConstArray(), aData.getConstArray() + aData.getLength(),
858 aResult.getArray(), CommonFunctors::makeAny< double >());
863 return aResult;
866 void SAL_CALL InternalDataProvider::setDataByRangeRepresentation(
867 const OUString& aRange, const Sequence< uno::Any >& aNewData )
868 throw (uno::RuntimeException)
870 vector< uno::Any > aNewVector( ContainerHelper::SequenceToVector(aNewData) );
871 if( aRange.match( lcl_aLabelRangePrefix ) )
873 sal_uInt32 nIndex = aRange.copy( lcl_aLabelRangePrefix.getLength()).toInt32();
874 if( m_bDataInColumns )
875 m_aInternalData.setComplexColumnLabel( nIndex, aNewVector );
876 else
877 m_aInternalData.setComplexRowLabel( nIndex, aNewVector );
879 else if( aRange.match( lcl_aCategoriesPointRangeNamePrefix ) )
881 sal_Int32 nPointIndex = aRange.copy( lcl_aCategoriesLevelRangeNamePrefix.getLength()).toInt32();
882 if( m_bDataInColumns )
883 m_aInternalData.setComplexRowLabel( nPointIndex, aNewVector );
884 else
885 m_aInternalData.setComplexColumnLabel( nPointIndex, aNewVector );
887 else if( aRange.match( lcl_aCategoriesLevelRangeNamePrefix ) )
889 sal_Int32 nLevel = aRange.copy( lcl_aCategoriesLevelRangeNamePrefix.getLength()).toInt32();
890 vector< vector< uno::Any > > aComplexCategories = m_bDataInColumns ? m_aInternalData.getComplexRowLabels() : m_aInternalData.getComplexColumnLabels();
892 //ensure equal length
893 if( aNewVector.size() > aComplexCategories.size() )
894 aComplexCategories.resize( aNewVector.size() );
895 else if( aNewVector.size() < aComplexCategories.size() )
896 aNewVector.resize( aComplexCategories.size() );
898 transform( aComplexCategories.begin(), aComplexCategories.end(), aNewVector.begin(),
899 aComplexCategories.begin(), lcl_setAnyAtLevel(nLevel) );
901 if( m_bDataInColumns )
902 m_aInternalData.setComplexRowLabels( aComplexCategories );
903 else
904 m_aInternalData.setComplexColumnLabels( aComplexCategories );
906 else if( aRange.equals( lcl_aCategoriesRangeName ) )
908 vector< vector< uno::Any > > aComplexCategories;
909 aComplexCategories.resize( aNewVector.size() );
910 transform( aComplexCategories.begin(), aComplexCategories.end(), aNewVector.begin(),
911 aComplexCategories.begin(), lcl_setAnyAtLevel(0) );
912 if( m_bDataInColumns )
913 m_aInternalData.setComplexRowLabels( aComplexCategories );
914 else
915 m_aInternalData.setComplexColumnLabels( aComplexCategories );
917 else
919 sal_Int32 nIndex = aRange.toInt32();
920 if( nIndex>=0 )
922 vector< double > aNewDataVec;
923 transform( aNewData.getConstArray(), aNewData.getConstArray() + aNewData.getLength(),
924 back_inserter( aNewDataVec ), CommonFunctors::AnyToDouble());
925 if( m_bDataInColumns )
926 m_aInternalData.setColumnValues( nIndex, aNewDataVec );
927 else
928 m_aInternalData.setRowValues( nIndex, aNewDataVec );
933 void SAL_CALL InternalDataProvider::insertSequence( ::sal_Int32 nAfterIndex )
934 throw (uno::RuntimeException)
936 if( m_bDataInColumns )
938 lcl_increaseMapReferences( nAfterIndex + 1, m_aInternalData.getColumnCount());
939 m_aInternalData.insertColumn( nAfterIndex );
941 else
943 lcl_increaseMapReferences( nAfterIndex + 1, m_aInternalData.getRowCount());
944 m_aInternalData.insertRow( nAfterIndex );
948 void SAL_CALL InternalDataProvider::deleteSequence( ::sal_Int32 nAtIndex )
949 throw (uno::RuntimeException)
951 lcl_deleteMapReferences( OUString::valueOf( nAtIndex ));
952 lcl_deleteMapReferences( lcl_aLabelRangePrefix + OUString::valueOf( nAtIndex ));
953 if( m_bDataInColumns )
955 lcl_decreaseMapReferences( nAtIndex + 1, m_aInternalData.getColumnCount());
956 m_aInternalData.deleteColumn( nAtIndex );
958 else
960 lcl_decreaseMapReferences( nAtIndex + 1, m_aInternalData.getRowCount());
961 m_aInternalData.deleteRow( nAtIndex );
965 void SAL_CALL InternalDataProvider::appendSequence()
966 throw (uno::RuntimeException)
968 if( m_bDataInColumns )
969 m_aInternalData.appendColumn();
970 else
971 m_aInternalData.appendRow();
974 void SAL_CALL InternalDataProvider::insertComplexCategoryLevel( sal_Int32 nLevel )
975 throw (uno::RuntimeException)
977 OSL_ENSURE( nLevel> 0, "you can only insert category levels > 0" );//the first categories level cannot be deleted, check the calling code for error
978 if( nLevel>0 )
980 vector< vector< uno::Any > > aComplexCategories = m_bDataInColumns ? m_aInternalData.getComplexRowLabels() : m_aInternalData.getComplexColumnLabels();
981 ::std::for_each( aComplexCategories.begin(), aComplexCategories.end(), lcl_insertAnyAtLevel(nLevel) );
982 if( m_bDataInColumns )
983 m_aInternalData.setComplexRowLabels( aComplexCategories );
984 else
985 m_aInternalData.setComplexColumnLabels( aComplexCategories );
987 tSequenceMapRange aRange( m_aSequenceMap.equal_range( lcl_aCategoriesRangeName ));
988 ::std::for_each( aRange.first, aRange.second, lcl_setModified());
991 void SAL_CALL InternalDataProvider::deleteComplexCategoryLevel( sal_Int32 nLevel )
992 throw (uno::RuntimeException)
994 OSL_ENSURE( nLevel>0, "you can only delete category levels > 0" );//the first categories level cannot be deleted, check the calling code for error
995 if( nLevel>0 )
997 vector< vector< uno::Any > > aComplexCategories = m_bDataInColumns ? m_aInternalData.getComplexRowLabels() : m_aInternalData.getComplexColumnLabels();
998 ::std::for_each( aComplexCategories.begin(), aComplexCategories.end(), lcl_removeAnyAtLevel(nLevel) );
999 if( m_bDataInColumns )
1000 m_aInternalData.setComplexRowLabels( aComplexCategories );
1001 else
1002 m_aInternalData.setComplexColumnLabels( aComplexCategories );
1004 tSequenceMapRange aRange( m_aSequenceMap.equal_range( lcl_aCategoriesRangeName ));
1005 ::std::for_each( aRange.first, aRange.second, lcl_setModified());
1009 void SAL_CALL InternalDataProvider::insertDataPointForAllSequences( ::sal_Int32 nAfterIndex )
1010 throw (uno::RuntimeException)
1012 sal_Int32 nMaxRep = 0;
1013 if( m_bDataInColumns )
1015 m_aInternalData.insertRow( nAfterIndex );
1016 nMaxRep = m_aInternalData.getColumnCount();
1018 else
1020 m_aInternalData.insertColumn( nAfterIndex );
1021 nMaxRep = m_aInternalData.getRowCount();
1024 // notify change to all affected ranges
1025 tSequenceMap::const_iterator aBegin( m_aSequenceMap.lower_bound( "0"));
1026 tSequenceMap::const_iterator aEnd( m_aSequenceMap.upper_bound( OUString::valueOf( nMaxRep )));
1027 ::std::for_each( aBegin, aEnd, lcl_setModified());
1029 tSequenceMapRange aRange( m_aSequenceMap.equal_range( lcl_aCategoriesRangeName ));
1030 ::std::for_each( aRange.first, aRange.second, lcl_setModified());
1033 void SAL_CALL InternalDataProvider::deleteDataPointForAllSequences( ::sal_Int32 nAtIndex )
1034 throw (uno::RuntimeException)
1036 sal_Int32 nMaxRep = 0;
1037 if( m_bDataInColumns )
1039 m_aInternalData.deleteRow( nAtIndex );
1040 nMaxRep = m_aInternalData.getColumnCount();
1042 else
1044 m_aInternalData.deleteColumn( nAtIndex );
1045 nMaxRep = m_aInternalData.getRowCount();
1048 // notify change to all affected ranges
1049 tSequenceMap::const_iterator aBegin( m_aSequenceMap.lower_bound( "0"));
1050 tSequenceMap::const_iterator aEnd( m_aSequenceMap.upper_bound( OUString::valueOf( nMaxRep )));
1051 ::std::for_each( aBegin, aEnd, lcl_setModified());
1053 tSequenceMapRange aRange( m_aSequenceMap.equal_range( lcl_aCategoriesRangeName ));
1054 ::std::for_each( aRange.first, aRange.second, lcl_setModified());
1057 void SAL_CALL InternalDataProvider::swapDataPointWithNextOneForAllSequences( ::sal_Int32 nAtIndex )
1058 throw (uno::RuntimeException)
1060 if( m_bDataInColumns )
1061 m_aInternalData.swapRowWithNext( nAtIndex );
1062 else
1063 m_aInternalData.swapColumnWithNext( nAtIndex );
1064 sal_Int32 nMaxRep = (m_bDataInColumns
1065 ? m_aInternalData.getColumnCount()
1066 : m_aInternalData.getRowCount());
1068 // notify change to all affected ranges
1069 tSequenceMap::const_iterator aBegin( m_aSequenceMap.lower_bound( "0"));
1070 tSequenceMap::const_iterator aEnd( m_aSequenceMap.upper_bound( OUString::valueOf( nMaxRep )));
1071 ::std::for_each( aBegin, aEnd, lcl_setModified());
1073 tSequenceMapRange aRange( m_aSequenceMap.equal_range( lcl_aCategoriesRangeName ));
1074 ::std::for_each( aRange.first, aRange.second, lcl_setModified());
1077 void SAL_CALL InternalDataProvider::registerDataSequenceForChanges( const Reference< chart2::data::XDataSequence >& xSeq )
1078 throw (uno::RuntimeException)
1080 if( xSeq.is())
1081 lcl_addDataSequenceToMap( xSeq->getSourceRangeRepresentation(), xSeq );
1085 // ____ XRangeXMLConversion ____
1086 OUString SAL_CALL InternalDataProvider::convertRangeToXML( const OUString& aRangeRepresentation )
1087 throw (lang::IllegalArgumentException,
1088 uno::RuntimeException)
1090 XMLRangeHelper::CellRange aRange;
1091 aRange.aTableName = OUString( "local-table" );
1093 // attention: this data provider has the limitation that it stores
1094 // internally if data comes from columns or rows. It is intended for
1095 // creating only one used data source.
1096 // @todo: add this information in the range representation strings
1097 if( aRangeRepresentation.match( lcl_aCategoriesRangeName ))
1099 OSL_ASSERT( aRangeRepresentation.equals( lcl_aCategoriesRangeName ) );//it is not expected nor implmented that only parts of the categories are really requested
1100 aRange.aUpperLeft.bIsEmpty = false;
1101 if( m_bDataInColumns )
1103 aRange.aUpperLeft.nColumn = 0;
1104 aRange.aUpperLeft.nRow = 1;
1105 aRange.aLowerRight = aRange.aUpperLeft;
1106 aRange.aLowerRight.nRow = m_aInternalData.getRowCount();
1108 else
1110 aRange.aUpperLeft.nColumn = 1;
1111 aRange.aUpperLeft.nRow = 0;
1112 aRange.aLowerRight = aRange.aUpperLeft;
1113 aRange.aLowerRight.nColumn = m_aInternalData.getColumnCount();
1116 else if( aRangeRepresentation.match( lcl_aLabelRangePrefix ))
1118 sal_Int32 nIndex = aRangeRepresentation.copy( lcl_aLabelRangePrefix.getLength()).toInt32();
1119 aRange.aUpperLeft.bIsEmpty = false;
1120 aRange.aLowerRight.bIsEmpty = true;
1121 if( m_bDataInColumns )
1123 aRange.aUpperLeft.nColumn = nIndex + 1;
1124 aRange.aUpperLeft.nRow = 0;
1126 else
1128 aRange.aUpperLeft.nColumn = 0;
1129 aRange.aUpperLeft.nRow = nIndex + 1;
1132 else if( aRangeRepresentation.equals( lcl_aCompleteRange ))
1134 aRange.aUpperLeft.bIsEmpty = false;
1135 aRange.aLowerRight.bIsEmpty = false;
1136 aRange.aUpperLeft.nColumn = 0;
1137 aRange.aUpperLeft.nRow = 0;
1138 aRange.aLowerRight.nColumn = m_aInternalData.getColumnCount();
1139 aRange.aLowerRight.nRow = m_aInternalData.getRowCount();
1141 else
1143 sal_Int32 nIndex = aRangeRepresentation.toInt32();
1144 aRange.aUpperLeft.bIsEmpty = false;
1145 if( m_bDataInColumns )
1147 aRange.aUpperLeft.nColumn = nIndex + 1;
1148 aRange.aUpperLeft.nRow = 1;
1149 aRange.aLowerRight = aRange.aUpperLeft;
1150 aRange.aLowerRight.nRow = m_aInternalData.getRowCount();
1152 else
1154 aRange.aUpperLeft.nColumn = 1;
1155 aRange.aUpperLeft.nRow = nIndex + 1;
1156 aRange.aLowerRight = aRange.aUpperLeft;
1157 aRange.aLowerRight.nColumn = m_aInternalData.getColumnCount();
1161 return XMLRangeHelper::getXMLStringFromCellRange( aRange );
1164 OUString SAL_CALL InternalDataProvider::convertRangeFromXML( const OUString& aXMLRange )
1165 throw (lang::IllegalArgumentException,
1166 uno::RuntimeException)
1168 XMLRangeHelper::CellRange aRange( XMLRangeHelper::getCellRangeFromXMLString( aXMLRange ));
1169 if( aRange.aUpperLeft.bIsEmpty )
1171 OSL_ENSURE( aRange.aLowerRight.bIsEmpty, "Weird Range" );
1172 return OUString();
1175 // "all"
1176 if( !aRange.aLowerRight.bIsEmpty &&
1177 ( aRange.aUpperLeft.nColumn != aRange.aLowerRight.nColumn ) &&
1178 ( aRange.aUpperLeft.nRow != aRange.aLowerRight.nRow ) )
1179 return lcl_aCompleteRange;
1181 // attention: this data provider has the limitation that it stores
1182 // internally if data comes from columns or rows. It is intended for
1183 // creating only one used data source.
1184 // @todo: add this information in the range representation strings
1186 // data in columns
1187 if( m_bDataInColumns )
1189 if( aRange.aUpperLeft.nColumn == 0 )
1190 return lcl_aCategoriesRangeName;
1191 if( aRange.aUpperLeft.nRow == 0 )
1192 return lcl_aLabelRangePrefix + OUString::valueOf( aRange.aUpperLeft.nColumn - 1 );
1194 return OUString::valueOf( aRange.aUpperLeft.nColumn - 1 );
1197 // data in rows
1198 if( aRange.aUpperLeft.nRow == 0 )
1199 return lcl_aCategoriesRangeName;
1200 if( aRange.aUpperLeft.nColumn == 0 )
1201 return lcl_aLabelRangePrefix + OUString::valueOf( aRange.aUpperLeft.nRow - 1 );
1203 return OUString::valueOf( aRange.aUpperLeft.nRow - 1 );
1206 namespace
1209 template< class Type >
1210 Sequence< Sequence< Type > > lcl_convertVectorVectorToSequenceSequence( const vector< vector< Type > >& rIn )
1212 Sequence< Sequence< Type > > aRet;
1213 sal_Int32 nOuterCount = rIn.size();
1214 if( nOuterCount )
1216 aRet.realloc(nOuterCount);
1217 for( sal_Int32 nN=0; nN<nOuterCount; nN++)
1218 aRet[nN]= ContainerHelper::ContainerToSequence( rIn[nN] );
1220 return aRet;
1223 template< class Type >
1224 vector< vector< Type > > lcl_convertSequenceSequenceToVectorVector( const Sequence< Sequence< Type > >& rIn )
1226 vector< vector< Type > > aRet;
1227 sal_Int32 nOuterCount = rIn.getLength();
1228 if( nOuterCount )
1230 aRet.resize(nOuterCount);
1231 for( sal_Int32 nN=0; nN<nOuterCount; nN++)
1232 aRet[nN]= ContainerHelper::SequenceToVector( rIn[nN] );
1234 return aRet;
1237 Sequence< Sequence< OUString > > lcl_convertComplexAnyVectorToStringSequence( const vector< vector< uno::Any > >& rIn )
1239 Sequence< Sequence< OUString > > aRet;
1240 sal_Int32 nOuterCount = rIn.size();
1241 if( nOuterCount )
1243 aRet.realloc(nOuterCount);
1244 for( sal_Int32 nN=0; nN<nOuterCount; nN++)
1245 aRet[nN]= lcl_AnyToStringSequence( ContainerHelper::ContainerToSequence( rIn[nN] ) );
1247 return aRet;
1250 vector< vector< uno::Any > > lcl_convertComplexStringSequenceToAnyVector( const Sequence< Sequence< OUString > >& rIn )
1252 vector< vector< uno::Any > > aRet;
1253 sal_Int32 nOuterCount = rIn.getLength();
1254 for( sal_Int32 nN=0; nN<nOuterCount; nN++)
1255 aRet.push_back( ContainerHelper::SequenceToVector( lcl_StringToAnySequence( rIn[nN] ) ) );
1256 return aRet;
1259 class SplitCategoriesProvider_ForComplexDescriptions : public SplitCategoriesProvider
1261 public:
1263 explicit SplitCategoriesProvider_ForComplexDescriptions( const ::std::vector< ::std::vector< uno::Any > >& rComplexDescriptions )
1264 : m_rComplexDescriptions( rComplexDescriptions )
1266 virtual ~SplitCategoriesProvider_ForComplexDescriptions()
1269 virtual sal_Int32 getLevelCount() const;
1270 virtual uno::Sequence< OUString > getStringsForLevel( sal_Int32 nIndex ) const;
1272 private:
1273 const ::std::vector< ::std::vector< uno::Any > >& m_rComplexDescriptions;
1276 sal_Int32 SplitCategoriesProvider_ForComplexDescriptions::getLevelCount() const
1278 return lcl_getInnerLevelCount( m_rComplexDescriptions );
1280 uno::Sequence< OUString > SplitCategoriesProvider_ForComplexDescriptions::getStringsForLevel( sal_Int32 nLevel ) const
1282 uno::Sequence< OUString > aResult;
1283 if( nLevel < lcl_getInnerLevelCount( m_rComplexDescriptions ) )
1285 aResult.realloc( m_rComplexDescriptions.size() );
1286 transform( m_rComplexDescriptions.begin(), m_rComplexDescriptions.end(),
1287 aResult.getArray(), lcl_getStringFromLevelVector(nLevel) );
1289 return aResult;
1292 }//anonymous namespace
1294 // ____ XDateCategories ____
1295 Sequence< double > SAL_CALL InternalDataProvider::getDateCategories() throw (uno::RuntimeException)
1297 double fNan = InternalDataProvider::getNotANumber();
1298 double fValue = fNan;
1299 vector< vector< uno::Any > > aCategories( m_bDataInColumns ? m_aInternalData.getComplexRowLabels() : m_aInternalData.getComplexColumnLabels());
1300 sal_Int32 nCount = aCategories.size();
1301 Sequence< double > aDoubles( nCount );
1302 vector< vector< uno::Any > >::iterator aIt( aCategories.begin() );
1303 vector< vector< uno::Any > >::const_iterator aEnd( aCategories.end() );
1304 for(sal_Int32 nN=0; nN<nCount && aIt!=aEnd; ++nN, ++aIt )
1306 if( !( !aIt->empty() && ((*aIt)[0]>>=fValue) ) )
1307 fValue = fNan;
1308 aDoubles[nN]=fValue;
1310 return aDoubles;
1313 void SAL_CALL InternalDataProvider::setDateCategories( const Sequence< double >& rDates ) throw (uno::RuntimeException)
1315 sal_Int32 nCount = rDates.getLength();
1316 vector< vector< uno::Any > > aNewCategories;
1317 aNewCategories.reserve(nCount);
1318 vector< uno::Any > aSingleLabel(1);
1320 for(sal_Int32 nN=0; nN<nCount; ++nN )
1322 aSingleLabel[0]=uno::makeAny(rDates[nN]);
1323 aNewCategories.push_back(aSingleLabel);
1326 if( m_bDataInColumns )
1327 m_aInternalData.setComplexRowLabels( aNewCategories );
1328 else
1329 m_aInternalData.setComplexColumnLabels( aNewCategories );
1332 // ____ XAnyDescriptionAccess ____
1333 Sequence< Sequence< uno::Any > > SAL_CALL InternalDataProvider::getAnyRowDescriptions() throw (uno::RuntimeException)
1335 return lcl_convertVectorVectorToSequenceSequence( m_aInternalData.getComplexRowLabels() );
1337 void SAL_CALL InternalDataProvider::setAnyRowDescriptions( const Sequence< Sequence< uno::Any > >& aRowDescriptions ) throw (uno::RuntimeException)
1339 m_aInternalData.setComplexRowLabels( lcl_convertSequenceSequenceToVectorVector( aRowDescriptions ) );
1341 Sequence< Sequence< uno::Any > > SAL_CALL InternalDataProvider::getAnyColumnDescriptions() throw (uno::RuntimeException)
1343 return lcl_convertVectorVectorToSequenceSequence( m_aInternalData.getComplexColumnLabels() );
1345 void SAL_CALL InternalDataProvider::setAnyColumnDescriptions( const Sequence< Sequence< uno::Any > >& aColumnDescriptions ) throw (uno::RuntimeException)
1347 m_aInternalData.setComplexColumnLabels( lcl_convertSequenceSequenceToVectorVector( aColumnDescriptions ) );
1350 // ____ XComplexDescriptionAccess ____
1351 Sequence< Sequence< OUString > > SAL_CALL InternalDataProvider::getComplexRowDescriptions() throw (uno::RuntimeException)
1353 return lcl_convertComplexAnyVectorToStringSequence( m_aInternalData.getComplexRowLabels() );
1355 void SAL_CALL InternalDataProvider::setComplexRowDescriptions( const Sequence< Sequence< OUString > >& aRowDescriptions ) throw (uno::RuntimeException)
1357 m_aInternalData.setComplexRowLabels( lcl_convertComplexStringSequenceToAnyVector(aRowDescriptions) );
1359 Sequence< Sequence< OUString > > SAL_CALL InternalDataProvider::getComplexColumnDescriptions() throw (uno::RuntimeException)
1361 return lcl_convertComplexAnyVectorToStringSequence( m_aInternalData.getComplexColumnLabels() );
1363 void SAL_CALL InternalDataProvider::setComplexColumnDescriptions( const Sequence< Sequence< OUString > >& aColumnDescriptions ) throw (uno::RuntimeException)
1365 m_aInternalData.setComplexColumnLabels( lcl_convertComplexStringSequenceToAnyVector(aColumnDescriptions) );
1368 // ____ XChartDataArray ____
1369 Sequence< Sequence< double > > SAL_CALL InternalDataProvider::getData()
1370 throw (uno::RuntimeException)
1372 return m_aInternalData.getData();
1375 void SAL_CALL InternalDataProvider::setData( const Sequence< Sequence< double > >& rDataInRows )
1376 throw (uno::RuntimeException)
1378 return m_aInternalData.setData( rDataInRows );
1381 void SAL_CALL InternalDataProvider::setRowDescriptions( const Sequence< OUString >& aRowDescriptions )
1382 throw (uno::RuntimeException)
1384 vector< vector< uno::Any > > aComplexDescriptions( aRowDescriptions.getLength() );
1385 transform( aComplexDescriptions.begin(), aComplexDescriptions.end(), aRowDescriptions.getConstArray(),
1386 aComplexDescriptions.begin(), lcl_setAnyAtLevelFromStringSequence(0) );
1387 m_aInternalData.setComplexRowLabels( aComplexDescriptions );
1390 void SAL_CALL InternalDataProvider::setColumnDescriptions( const Sequence< OUString >& aColumnDescriptions )
1391 throw (uno::RuntimeException)
1393 vector< vector< uno::Any > > aComplexDescriptions( aColumnDescriptions.getLength() );
1394 transform( aComplexDescriptions.begin(), aComplexDescriptions.end(), aColumnDescriptions.getConstArray(),
1395 aComplexDescriptions.begin(), lcl_setAnyAtLevelFromStringSequence(0) );
1396 m_aInternalData.setComplexColumnLabels( aComplexDescriptions );
1399 Sequence< OUString > SAL_CALL InternalDataProvider::getRowDescriptions()
1400 throw (uno::RuntimeException)
1402 vector< vector< uno::Any > > aComplexLabels( m_aInternalData.getComplexRowLabels() );
1403 SplitCategoriesProvider_ForComplexDescriptions aProvider( aComplexLabels );
1404 return ExplicitCategoriesProvider::getExplicitSimpleCategories( aProvider );
1407 Sequence< OUString > SAL_CALL InternalDataProvider::getColumnDescriptions()
1408 throw (uno::RuntimeException)
1410 vector< vector< uno::Any > > aComplexLabels( m_aInternalData.getComplexColumnLabels() );
1411 SplitCategoriesProvider_ForComplexDescriptions aProvider( aComplexLabels );
1412 return ExplicitCategoriesProvider::getExplicitSimpleCategories( aProvider );
1415 // ____ XChartData (base of XChartDataArray) ____
1416 void SAL_CALL InternalDataProvider::addChartDataChangeEventListener(
1417 const Reference< ::com::sun::star::chart::XChartDataChangeEventListener >& )
1418 throw (uno::RuntimeException)
1422 void SAL_CALL InternalDataProvider::removeChartDataChangeEventListener(
1423 const Reference< ::com::sun::star::chart::XChartDataChangeEventListener >& )
1424 throw (uno::RuntimeException)
1428 double SAL_CALL InternalDataProvider::getNotANumber()
1429 throw (uno::RuntimeException)
1431 double fNan;
1432 ::rtl::math::setNan( & fNan );
1433 return fNan;
1436 ::sal_Bool SAL_CALL InternalDataProvider::isNotANumber( double nNumber )
1437 throw (uno::RuntimeException)
1439 return ::rtl::math::isNan( nNumber )
1440 || ::rtl::math::isInf( nNumber );
1442 // lang::XInitialization:
1443 void SAL_CALL InternalDataProvider::initialize(const uno::Sequence< uno::Any > & _aArguments) throw (uno::RuntimeException, uno::Exception)
1445 comphelper::SequenceAsHashMap aArgs(_aArguments);
1446 if ( aArgs.getUnpackedValueOrDefault( "CreateDefaultData" ,sal_False) )
1447 createDefaultData();
1449 // ____ XCloneable ____
1450 Reference< util::XCloneable > SAL_CALL InternalDataProvider::createClone()
1451 throw (uno::RuntimeException)
1453 return Reference< util::XCloneable >( new InternalDataProvider( *this ));
1457 // ================================================================================
1459 Sequence< OUString > InternalDataProvider::getSupportedServiceNames_Static()
1461 Sequence< OUString > aServices( 1 );
1462 aServices[ 0 ] = "com.sun.star.chart2.data.DataProvider";
1463 return aServices;
1466 // ================================================================================
1468 APPHELPER_XSERVICEINFO_IMPL( InternalDataProvider, lcl_aServiceName );
1470 } // namespace chart
1472 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */