1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
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>
25 #include "InternalDataProvider.hxx"
26 #include "LabeledDataSequence.hxx"
27 #include "DataSource.hxx"
28 #include "PropertyHelper.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>
50 using namespace ::com::sun::star
;
51 using namespace ::std
;
53 using ::com::sun::star::uno::Reference
;
54 using ::com::sun::star::uno::Sequence
;
59 // ================================================================================
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
> >
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() );
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
>() );
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
);
103 Reference
< util::XModifiable
> xMod( xSeq
, uno::UNO_QUERY
);
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
;
139 ::std::vector
< double > aValues( ContainerHelper::SequenceToVector( xValues
->getNumericalData()));
140 if( m_bDataInColumns
)
141 m_rInternalData
.setColumnValues( nNewIndex
, aValues
);
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
));
155 if( m_bDataInColumns
)
156 m_rInternalData
.setComplexColumnLabel( nNewIndex
, ContainerHelper::SequenceToVector( lcl_StringToAnySequence( xLabel
->getTextualData() ) ) );
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
));
172 if( m_bConnectToModel
)
173 aNewSeriesData
[i
] = Reference
< chart2::data::XLabeledDataSequence
>(
174 new LabeledDataSequence( xNewValues
));
177 if( m_bConnectToModel
)
178 xSink
->setData( aNewSeriesData
);
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
>
193 explicit lcl_copyFromLevel( sal_Int32 nLevel
) : m_nLevel( nLevel
)
196 uno::Any
operator() ( const vector
< uno::Any
>& rVector
)
199 if( m_nLevel
< static_cast< sal_Int32
>(rVector
.size()) )
200 aRet
= rVector
[m_nLevel
];
208 struct lcl_getStringFromLevelVector
: public ::std::unary_function
< vector
< uno::Any
>, OUString
>
212 explicit lcl_getStringFromLevelVector( sal_Int32 nLevel
) : m_nLevel( nLevel
)
215 OUString
operator() ( const vector
< uno::Any
>& rVector
)
218 if( m_nLevel
< static_cast< sal_Int32
>(rVector
.size()) )
219 aString
= CommonFunctors::AnyToString()(rVector
[m_nLevel
]);
228 struct lcl_setAnyAtLevel
: public ::std::binary_function
< vector
< uno::Any
>, uno::Any
, vector
< uno::Any
> >
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
;
248 struct lcl_setAnyAtLevelFromStringSequence
: public ::std::binary_function
< vector
< uno::Any
>, OUString
, vector
< uno::Any
> >
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
);
268 struct lcl_insertAnyAtLevel
: public ::std::unary_function
< vector
< uno::Any
>, void >
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 );
283 rVector
.insert( rVector
.begin() + m_nLevel
, uno::Any() );
291 struct lcl_removeAnyAtLevel
: public ::std::unary_function
< vector
< uno::Any
>, void >
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
);
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
) );
326 Reference
< frame::XModel
> xChartModel( xChartDoc
, uno::UNO_QUERY
);
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
);
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
] );
350 Sequence
< uno::Any
> aDataSeq
;
351 Reference
< chart2::data::XDataSequence
> xSeq( xLDS
->getValues() );
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
) );
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
);
380 m_aInternalData
.setComplexColumnLabels( aNewCategories
);
381 if( bConnectToModel
)
382 DiagramHelper::setCategoriesToDiagram( new LabeledDataSequence(
383 createDataSequenceByRangeRepresentation( lcl_aCategoriesRangeName
)), xDiagram
);
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
);
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
);
427 Reference
< container::XNamed
> xNamed( xSeq
, uno::UNO_QUERY
);
429 xNamed
->setName( OUString());
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
);
447 Reference
< container::XNamed
> xNamed( xSeq
, uno::UNO_QUERY
);
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
;
494 sal_Int32 nCategories
= 0;
495 sal_Int32 nIndex
= 0;
497 bool bLabelSet
= false;
498 OUString str
= aRangeRepresentation
.replace('{',' ').replace('}',' ');
500 m_aInternalData
.clearDefaultData();
501 sal_Int32 n
= m_aInternalData
.getColumnCount();
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() )
512 if( aToken
.indexOf('"') < 0 )
514 aNewData
.push_back( aToken
.toDouble() );
518 aNewLabels
.push_back( uno::makeAny(aToken
.replace('"', ' ').trim()) );
520 ( !m_aInternalData
.getComplexColumnLabel(n
).size() ||
521 !m_aInternalData
.getComplexColumnLabel(n
).front().hasValue() ) )
523 m_aInternalData
.setComplexColumnLabel( n
, aNewLabels
);
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();
540 } while( nIndex
>= 0 );
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
;
554 aRangeRepresentation
= lcl_aLabelRangePrefix
+OUString::valueOf( n
);
558 Reference
< chart2::data::XDataSequence
> xSeq(
559 new UncachedDataSequence( this, aRangeRepresentation
));
560 lcl_addDataSequenceToMap( aRangeRepresentation
, 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
);
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
)
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
);
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
) ) );
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
;
649 aResultLSeqVec
.push_back(
650 new LabeledDataSequence( lcl_createDataSequenceAndAddToMap( lcl_aCategoriesRangeName
, lcl_aCategoriesRoleName
) ) );
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
)
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
)
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(
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.
721 ::sal_Bool SAL_CALL
InternalDataProvider::createDataSequenceByRangeRepresentationPossible( const OUString
& /* aRangeRepresentation */ )
722 throw (uno::RuntimeException
)
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
737 return lcl_createDataSequenceAndAddToMap( lcl_aCategoriesRangeName
, lcl_aCategoriesRoleName
);
739 else if( aRangeRepresentation
.match( lcl_aLabelRangePrefix
))
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())
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
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()));
786 sal_Int32 nIndex
= aRange
.toInt32();
787 bResult
= (nIndex
< (m_bDataInColumns
? m_aInternalData
.getColumnCount(): m_aInternalData
.getRowCount()));
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 )
834 aResult
= this->getDataByRangeRepresentation( lcl_aCategoriesLevelRangeNamePrefix
+ OUString::valueOf( nL
) );
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
>() );
846 sal_Int32 nIndex
= aRange
.toInt32();
849 Sequence
< double > aData
;
850 if( m_bDataInColumns
)
851 aData
= m_aInternalData
.getColumnValues(nIndex
);
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 >());
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
);
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
);
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
);
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
);
915 m_aInternalData
.setComplexColumnLabels( aComplexCategories
);
919 sal_Int32 nIndex
= aRange
.toInt32();
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
);
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
);
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
);
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();
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
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
);
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
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
);
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();
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();
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
);
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
)
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();
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;
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();
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();
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" );
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
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 );
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 );
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();
1216 aRet
.realloc(nOuterCount
);
1217 for( sal_Int32 nN
=0; nN
<nOuterCount
; nN
++)
1218 aRet
[nN
]= ContainerHelper::ContainerToSequence( rIn
[nN
] );
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();
1230 aRet
.resize(nOuterCount
);
1231 for( sal_Int32 nN
=0; nN
<nOuterCount
; nN
++)
1232 aRet
[nN
]= ContainerHelper::SequenceToVector( rIn
[nN
] );
1237 Sequence
< Sequence
< OUString
> > lcl_convertComplexAnyVectorToStringSequence( const vector
< vector
< uno::Any
> >& rIn
)
1239 Sequence
< Sequence
< OUString
> > aRet
;
1240 sal_Int32 nOuterCount
= rIn
.size();
1243 aRet
.realloc(nOuterCount
);
1244 for( sal_Int32 nN
=0; nN
<nOuterCount
; nN
++)
1245 aRet
[nN
]= lcl_AnyToStringSequence( ContainerHelper::ContainerToSequence( rIn
[nN
] ) );
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
] ) ) );
1259 class SplitCategoriesProvider_ForComplexDescriptions
: public SplitCategoriesProvider
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;
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
) );
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
) ) )
1308 aDoubles
[nN
]=fValue
;
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
);
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
)
1432 ::rtl::math::setNan( & 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";
1466 // ================================================================================
1468 APPHELPER_XSERVICEINFO_IMPL( InternalDataProvider
, lcl_aServiceName
);
1470 } // namespace chart
1472 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */