1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 * Copyright 2000, 2010 Oracle and/or its affiliates.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * This file is part of OpenOffice.org.
11 * OpenOffice.org is free software: you can redistribute it and/or modify
12 * it under the terms of the GNU Lesser General Public License version 3
13 * only, as published by the Free Software Foundation.
15 * OpenOffice.org is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 * GNU Lesser General Public License version 3 for more details
19 * (a copy is included in the LICENSE file that accompanied this code).
21 * You should have received a copy of the GNU Lesser General Public License
22 * version 3 along with OpenOffice.org. If not, see
23 * <http://www.openoffice.org/license.html>
24 * for a copy of the LGPLv3 License.
26 ************************************************************************/
29 // MARKER(update_precomp.py): autogen include statement, do not remove
30 #include "precompiled_chart2.hxx"
31 #include <rtl/math.hxx>
35 #include "InternalDataProvider.hxx"
36 #include "LabeledDataSequence.hxx"
37 #include "DataSource.hxx"
38 #include "PropertyHelper.hxx"
40 #include "XMLRangeHelper.hxx"
41 #include "ContainerHelper.hxx"
42 #include "CommonConverters.hxx"
43 #include "CommonFunctors.hxx"
44 #include "UncachedDataSequence.hxx"
45 #include "DataSourceHelper.hxx"
46 #include "ChartModelHelper.hxx"
47 #include "DiagramHelper.hxx"
48 #include "ExplicitCategoriesProvider.hxx"
50 #include <com/sun/star/chart2/XChartDocument.hpp>
51 #include <com/sun/star/chart2/data/XDataSequence.hpp>
52 #include <com/sun/star/chart/ChartDataRowSource.hpp>
53 #include <rtl/ustrbuf.hxx>
54 #include <unotools/charclass.hxx>
55 #include <comphelper/sequenceashashmap.hxx>
60 using namespace ::com::sun::star
;
61 using namespace ::std
;
63 using ::com::sun::star::uno::Reference
;
64 using ::com::sun::star::uno::Sequence
;
65 using ::rtl::OUString
;
66 using ::rtl::OUStringBuffer
;
71 // ================================================================================
76 // note: in xmloff this name is used to indicate usage of own data
77 static const ::rtl::OUString
lcl_aServiceName(
78 RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.comp.chart.InternalDataProvider" ));
80 static const ::rtl::OUString
lcl_aCategoriesRangeName(
81 RTL_CONSTASCII_USTRINGPARAM( "categories" ));
82 static const ::rtl::OUString
lcl_aCategoriesLevelRangeNamePrefix(
83 RTL_CONSTASCII_USTRINGPARAM( "categoriesL " )); //L <-> level
84 static const ::rtl::OUString
lcl_aCategoriesPointRangeNamePrefix(
85 RTL_CONSTASCII_USTRINGPARAM( "categoriesP " )); //P <-> point
86 static const ::rtl::OUString
lcl_aCategoriesRoleName(
87 RTL_CONSTASCII_USTRINGPARAM( "categories" ));
88 static const ::rtl::OUString
lcl_aLabelRangePrefix(
89 RTL_CONSTASCII_USTRINGPARAM( "label " ));
90 static const ::rtl::OUString
lcl_aCompleteRange(
91 RTL_CONSTASCII_USTRINGPARAM( "all" ));
93 typedef ::std::multimap
< OUString
, uno::WeakReference
< chart2::data::XDataSequence
> >
96 struct lcl_setModified
: public ::std::unary_function
< lcl_tSequenceMap
, void >
98 void operator() ( const lcl_tSequenceMap::value_type
& rMapEntry
)
100 // convert weak reference to reference
101 Reference
< chart2::data::XDataSequence
> xSeq( rMapEntry
.second
);
104 Reference
< util::XModifiable
> xMod( xSeq
, uno::UNO_QUERY
);
106 xMod
->setModified( sal_True
);
111 struct lcl_internalizeSeries
: public ::std::unary_function
< Reference
< chart2::XDataSeries
>, void >
113 lcl_internalizeSeries( InternalData
& rInternalData
,
114 InternalDataProvider
& rProvider
,
115 bool bConnectToModel
, bool bDataInColumns
) :
116 m_rInternalData( rInternalData
),
117 m_rProvider( rProvider
),
118 m_bConnectToModel( bConnectToModel
),
119 m_bDataInColumns( bDataInColumns
)
121 void operator() ( const Reference
< chart2::XDataSeries
> & xSeries
)
123 Reference
< chart2::data::XDataSource
> xSource( xSeries
, uno::UNO_QUERY
);
124 Reference
< chart2::data::XDataSink
> xSink( xSeries
, uno::UNO_QUERY
);
125 if( xSource
.is() && xSink
.is() )
127 Sequence
< Reference
< chart2::data::XLabeledDataSequence
> > aOldSeriesData
= xSource
->getDataSequences();
128 Sequence
< Reference
< chart2::data::XLabeledDataSequence
> > aNewSeriesData( aOldSeriesData
.getLength() );
129 for( sal_Int32 i
=0; i
<aOldSeriesData
.getLength(); ++i
)
131 sal_Int32
nNewIndex( m_bDataInColumns
? m_rInternalData
.appendColumn() : m_rInternalData
.appendRow() );
132 OUString
aIdentifier( OUString::valueOf( nNewIndex
));
133 //@todo: deal also with genericXDataSequence
134 Reference
< chart2::data::XNumericalDataSequence
> xValues( aOldSeriesData
[i
]->getValues(), uno::UNO_QUERY
);
135 Reference
< chart2::data::XTextualDataSequence
> xLabel( aOldSeriesData
[i
]->getLabel(), uno::UNO_QUERY
);
136 Reference
< chart2::data::XDataSequence
> xNewValues
;
140 ::std::vector
< double > aValues( ContainerHelper::SequenceToVector( xValues
->getNumericalData()));
141 if( m_bDataInColumns
)
142 m_rInternalData
.setColumnValues( nNewIndex
, aValues
);
144 m_rInternalData
.setRowValues( nNewIndex
, aValues
);
145 if( m_bConnectToModel
)
147 xNewValues
.set( m_rProvider
.createDataSequenceByRangeRepresentation( aIdentifier
));
148 comphelper::copyProperties(
149 Reference
< beans::XPropertySet
>( xValues
, uno::UNO_QUERY
),
150 Reference
< beans::XPropertySet
>( xNewValues
, uno::UNO_QUERY
));
156 if( m_bDataInColumns
)
157 m_rInternalData
.setComplexColumnLabel( nNewIndex
, ContainerHelper::SequenceToVector( xLabel
->getTextualData() ) );
159 m_rInternalData
.setComplexRowLabel( nNewIndex
, ContainerHelper::SequenceToVector( xLabel
->getTextualData() ) );
160 if( m_bConnectToModel
)
162 Reference
< chart2::data::XDataSequence
> xNewLabel(
163 m_rProvider
.createDataSequenceByRangeRepresentation( lcl_aLabelRangePrefix
+ aIdentifier
));
164 comphelper::copyProperties(
165 Reference
< beans::XPropertySet
>( xLabel
, uno::UNO_QUERY
),
166 Reference
< beans::XPropertySet
>( xNewLabel
, uno::UNO_QUERY
));
167 aNewSeriesData
[i
] = Reference
< chart2::data::XLabeledDataSequence
>(
168 new LabeledDataSequence( xNewValues
, xNewLabel
));
173 if( m_bConnectToModel
)
174 aNewSeriesData
[i
] = Reference
< chart2::data::XLabeledDataSequence
>(
175 new LabeledDataSequence( xNewValues
));
178 if( m_bConnectToModel
)
179 xSink
->setData( aNewSeriesData
);
184 InternalData
& m_rInternalData
;
185 InternalDataProvider
& m_rProvider
;
186 bool m_bConnectToModel
;
187 bool m_bDataInColumns
;
190 struct lcl_makeAnyFromLevelVector
: public ::std::unary_function
< vector
< OUString
>, uno::Any
>
194 explicit lcl_makeAnyFromLevelVector( sal_Int32 nLevel
) : m_nLevel( nLevel
)
197 uno::Any
operator() ( const vector
< OUString
>& rVector
)
200 if( m_nLevel
< static_cast< sal_Int32
>(rVector
.size()) )
201 aString
= rVector
[m_nLevel
];
202 return uno::makeAny( aString
);
209 struct lcl_getStringFromLevelVector
: public ::std::unary_function
< vector
< OUString
>, OUString
>
213 explicit lcl_getStringFromLevelVector( sal_Int32 nLevel
) : m_nLevel( nLevel
)
216 OUString
operator() ( const vector
< OUString
>& rVector
)
219 if( m_nLevel
< static_cast< sal_Int32
>(rVector
.size()) )
220 aString
= rVector
[m_nLevel
];
229 struct lcl_setStringAtLevel
: public ::std::binary_function
< vector
< OUString
>, OUString
, vector
< OUString
> >
233 explicit lcl_setStringAtLevel( sal_Int32 nLevel
) : m_nLevel( nLevel
)
236 vector
< OUString
> operator() ( const vector
< OUString
>& rVector
, const OUString
& rNewText
)
238 vector
< OUString
> aRet( rVector
);
239 if( m_nLevel
>= static_cast< sal_Int32
>(aRet
.size()) )
240 aRet
.resize( m_nLevel
+1 );
241 aRet
[ m_nLevel
]=rNewText
;
249 struct lcl_insertStringAtLevel
: public ::std::unary_function
< vector
< OUString
>, void >
253 explicit lcl_insertStringAtLevel( sal_Int32 nLevel
) : m_nLevel( nLevel
)
256 void operator() ( vector
< OUString
>& rVector
)
258 if( m_nLevel
> static_cast< sal_Int32
>(rVector
.size()) )
259 rVector
.resize( m_nLevel
);
261 vector
< OUString
>::iterator
aIt( rVector
.begin() );
262 for( sal_Int32 nN
=0; aIt
<rVector
.end(); aIt
++, nN
++)
267 rVector
.insert( aIt
, OUString() );
274 struct lcl_removeStringAtLevel
: public ::std::unary_function
< vector
< OUString
>, void >
278 explicit lcl_removeStringAtLevel( sal_Int32 nLevel
) : m_nLevel( nLevel
)
281 void operator() ( vector
< OUString
>& rVector
)
283 vector
< OUString
>::iterator
aIt( rVector
.begin() );
284 for( sal_Int32 nN
=0; aIt
<rVector
.end(); aIt
++, nN
++)
288 rVector
.erase( aIt
);
298 vector
< OUString
> lcl_AnyToStringVector( const Sequence
< uno::Any
>& aAnySeq
)
300 vector
< OUString
> aStringVec
;
301 transform( aAnySeq
.getConstArray(), aAnySeq
.getConstArray() + aAnySeq
.getLength(),
302 back_inserter( aStringVec
), CommonFunctors::AnyToString() );
306 Sequence
< OUString
> lcl_AnyToStringSequence( const Sequence
< uno::Any
>& aAnySeq
)
308 Sequence
< OUString
> aResult
;
309 aResult
.realloc( aAnySeq
.getLength() );
310 transform( aAnySeq
.getConstArray(), aAnySeq
.getConstArray() + aAnySeq
.getLength(),
311 aResult
.getArray(), CommonFunctors::AnyToString() );
315 } // anonymous namespace
317 // ================================================================================
319 InternalDataProvider::InternalDataProvider( const Reference
< uno::XComponentContext
> & /*_xContext*/)
320 : m_bDataInColumns( true )
323 InternalDataProvider::InternalDataProvider( const Reference
< chart2::XChartDocument
> & xChartDoc
, bool bConnectToModel
)
324 : m_bDataInColumns( true )
328 Reference
< chart2::XDiagram
> xDiagram( ChartModelHelper::findDiagram( xChartDoc
) );
331 Reference
< frame::XModel
> xChartModel( xChartDoc
, uno::UNO_QUERY
);
335 ::rtl::OUString aRangeString
;
336 bool bFirstCellAsLabel
= true;
337 bool bHasCategories
= true;
338 uno::Sequence
< sal_Int32
> aSequenceMapping
;
339 DataSourceHelper::detectRangeSegmentation( xChartModel
, aRangeString
, aSequenceMapping
, m_bDataInColumns
, bFirstCellAsLabel
, bHasCategories
);
344 vector
< vector
< OUString
> > aNewCategories
;//inner count is level
346 ExplicitCategoriesProvider
aExplicitCategoriesProvider( ChartModelHelper::getFirstCoordinateSystem(xChartModel
), xChartModel
);
347 const Sequence
< Reference
< chart2::data::XLabeledDataSequence
> >& rSplitCategoriesList( aExplicitCategoriesProvider
.getSplitCategoriesList() );
348 sal_Int32 nLevelCount
= rSplitCategoriesList
.getLength();
349 for( sal_Int32 nL
= 0; nL
<nLevelCount
; nL
++ )
351 Reference
< chart2::data::XLabeledDataSequence
> xLDS( rSplitCategoriesList
[nL
] );
354 Reference
< chart2::data::XTextualDataSequence
> xSeq( xLDS
->getValues(), uno::UNO_QUERY
);
355 Sequence
< OUString
> aStringSeq
;
357 aStringSeq
= xSeq
->getTextualData(); // @todo: be able to deal with XDataSequence, too
358 sal_Int32 nLength
= aStringSeq
.getLength();
359 if( static_cast< sal_Int32
>(aNewCategories
.size()) < nLength
)
360 aNewCategories
.resize( nLength
);
362 transform( aNewCategories
.begin(), aNewCategories
.end(), aStringSeq
.getConstArray(),
363 aNewCategories
.begin(), lcl_setStringAtLevel(nL
) );
367 Sequence
< OUString
> aSimplecategories
= aExplicitCategoriesProvider
.getSimpleCategories();
368 sal_Int32 nLength
= aSimplecategories
.getLength();
369 aNewCategories
.reserve( nLength
);
370 for( sal_Int32 nN
=0; nN
<nLength
; nN
++)
372 vector
< OUString
> aStringVector(1);
373 aStringVector
[0] = aSimplecategories
[nN
];
374 aNewCategories
.push_back( aStringVector
);
379 if( m_bDataInColumns
)
380 m_aInternalData
.setComplexRowLabels( aNewCategories
);
382 m_aInternalData
.setComplexColumnLabels( aNewCategories
);
383 if( bConnectToModel
)
384 DiagramHelper::setCategoriesToDiagram( new LabeledDataSequence(
385 createDataSequenceByRangeRepresentation( lcl_aCategoriesRangeName
)), xDiagram
);
389 ::std::vector
< Reference
< chart2::XDataSeries
> > aSeriesVector( ChartModelHelper::getDataSeries( xChartDoc
));
390 ::std::for_each( aSeriesVector
.begin(), aSeriesVector
.end(), lcl_internalizeSeries( m_aInternalData
, *this, bConnectToModel
, m_bDataInColumns
) );
393 catch( const uno::Exception
& ex
)
395 ASSERT_EXCEPTION( ex
);
400 InternalDataProvider::InternalDataProvider( const InternalDataProvider
& rOther
) :
401 impl::InternalDataProvider_Base(),
402 m_aSequenceMap( rOther
.m_aSequenceMap
),
403 m_aInternalData( rOther
.m_aInternalData
),
404 m_bDataInColumns( rOther
.m_bDataInColumns
)
407 InternalDataProvider::~InternalDataProvider()
410 void InternalDataProvider::lcl_addDataSequenceToMap(
411 const OUString
& rRangeRepresentation
,
412 const Reference
< chart2::data::XDataSequence
> & xSequence
)
414 m_aSequenceMap
.insert(
415 tSequenceMap::value_type(
416 rRangeRepresentation
,
417 uno::WeakReference
< chart2::data::XDataSequence
>( xSequence
)));
420 void InternalDataProvider::lcl_deleteMapReferences( const OUString
& rRangeRepresentation
)
422 // set sequence to deleted by setting its range to an empty string
423 tSequenceMapRange
aRange( m_aSequenceMap
.equal_range( rRangeRepresentation
));
424 for( tSequenceMap::iterator
aIt( aRange
.first
); aIt
!= aRange
.second
; ++aIt
)
426 Reference
< chart2::data::XDataSequence
> xSeq( aIt
->second
);
429 Reference
< container::XNamed
> xNamed( xSeq
, uno::UNO_QUERY
);
431 xNamed
->setName( OUString());
435 m_aSequenceMap
.erase( aRange
.first
, aRange
.second
);
438 void InternalDataProvider::lcl_adaptMapReferences(
439 const OUString
& rOldRangeRepresentation
,
440 const OUString
& rNewRangeRepresentation
)
442 tSequenceMapRange
aRange( m_aSequenceMap
.equal_range( rOldRangeRepresentation
));
443 tSequenceMap aNewElements
;
444 for( tSequenceMap::iterator
aIt( aRange
.first
); aIt
!= aRange
.second
; ++aIt
)
446 Reference
< chart2::data::XDataSequence
> xSeq( aIt
->second
);
449 Reference
< container::XNamed
> xNamed( xSeq
, uno::UNO_QUERY
);
451 xNamed
->setName( rNewRangeRepresentation
);
453 aNewElements
.insert( tSequenceMap::value_type( rNewRangeRepresentation
, aIt
->second
));
455 // erase map values for old index
456 m_aSequenceMap
.erase( aRange
.first
, aRange
.second
);
457 // add new entries for values with new index
458 ::std::copy( aNewElements
.begin(), aNewElements
.end(),
459 ::std::inserter( m_aSequenceMap
,
460 m_aSequenceMap
.upper_bound( rNewRangeRepresentation
)));
463 void InternalDataProvider::lcl_increaseMapReferences(
464 sal_Int32 nBegin
, sal_Int32 nEnd
)
466 for( sal_Int32 nIndex
= nEnd
- 1; nIndex
>= nBegin
; --nIndex
)
468 lcl_adaptMapReferences( OUString::valueOf( nIndex
),
469 OUString::valueOf( nIndex
+ 1 ));
470 lcl_adaptMapReferences( lcl_aLabelRangePrefix
+ OUString::valueOf( nIndex
),
471 lcl_aLabelRangePrefix
+ OUString::valueOf( nIndex
+ 1 ));
475 void InternalDataProvider::lcl_decreaseMapReferences(
476 sal_Int32 nBegin
, sal_Int32 nEnd
)
478 for( sal_Int32 nIndex
= nBegin
; nIndex
< nEnd
; ++nIndex
)
480 lcl_adaptMapReferences( OUString::valueOf( nIndex
),
481 OUString::valueOf( nIndex
- 1 ));
482 lcl_adaptMapReferences( lcl_aLabelRangePrefix
+ OUString::valueOf( nIndex
),
483 lcl_aLabelRangePrefix
+ OUString::valueOf( nIndex
- 1 ));
487 Reference
< chart2::data::XDataSequence
> InternalDataProvider::lcl_createDataSequenceAndAddToMap(
488 const OUString
& rRangeRepresentation
)
490 Reference
< chart2::data::XDataSequence
> xSeq(
491 new UncachedDataSequence( this, rRangeRepresentation
));
492 lcl_addDataSequenceToMap( rRangeRepresentation
, xSeq
);
496 Reference
< chart2::data::XDataSequence
> InternalDataProvider::lcl_createDataSequenceAndAddToMap(
497 const OUString
& rRangeRepresentation
,
498 const OUString
& rRole
)
500 Reference
< chart2::data::XDataSequence
> xSeq(
501 new UncachedDataSequence( this, rRangeRepresentation
, rRole
));
502 lcl_addDataSequenceToMap( rRangeRepresentation
, xSeq
);
506 void InternalDataProvider::createDefaultData()
508 m_aInternalData
.createDefaultData();
511 // ____ XDataProvider ____
512 ::sal_Bool SAL_CALL
InternalDataProvider::createDataSourcePossible( const Sequence
< beans::PropertyValue
>& /* aArguments */ )
513 throw (uno::RuntimeException
)
521 sal_Int32
lcl_getInnerLevelCount( const vector
< vector
< OUString
> >& rLabels
)
523 sal_Int32 nCount
= 1;//minimum is 1!
524 vector
< vector
< OUString
> >::const_iterator
aLevelIt( rLabels
.begin() );
525 vector
< vector
< OUString
> >::const_iterator
aLevelEnd( rLabels
.end() );
526 for( ;aLevelIt
!=aLevelEnd
; ++aLevelIt
)
528 const vector
< ::rtl::OUString
>& rCurrentLevelLabels
= *aLevelIt
;
529 nCount
= std::max
<sal_Int32
>( rCurrentLevelLabels
.size(), nCount
);
534 }//end anonymous namespace
536 Reference
< chart2::data::XDataSource
> SAL_CALL
InternalDataProvider::createDataSource(
537 const Sequence
< beans::PropertyValue
>& aArguments
)
538 throw (lang::IllegalArgumentException
,
539 uno::RuntimeException
)
541 OUString aRangeRepresentation
;
542 bool bUseColumns
= true;
543 bool bFirstCellAsLabel
= true;
544 bool bHasCategories
= true;
545 uno::Sequence
< sal_Int32
> aSequenceMapping
;
546 DataSourceHelper::readArguments( aArguments
, aRangeRepresentation
, aSequenceMapping
, bUseColumns
, bFirstCellAsLabel
, bHasCategories
);
548 if( aRangeRepresentation
.equals( lcl_aCategoriesRangeName
) )
550 //return split complex categories if we have any:
551 ::std::vector
< Reference
< chart2::data::XLabeledDataSequence
> > aComplexCategories
;
552 vector
< vector
< OUString
> > aCategories( m_bDataInColumns
? m_aInternalData
.getComplexRowLabels() : m_aInternalData
.getComplexColumnLabels());
553 if( bUseColumns
==m_bDataInColumns
)
555 sal_Int32 nLevelCount
= lcl_getInnerLevelCount( aCategories
);
556 for( sal_Int32 nL
=0; nL
<nLevelCount
; nL
++ )
557 aComplexCategories
.push_back( new LabeledDataSequence(
558 new UncachedDataSequence( this
559 , lcl_aCategoriesLevelRangeNamePrefix
+ OUString::valueOf( nL
)
560 , lcl_aCategoriesRoleName
) ) );
564 sal_Int32 nPointCount
= m_bDataInColumns
? m_aInternalData
.getRowCount() : m_aInternalData
.getColumnCount();
565 for( sal_Int32 nP
=0; nP
<nPointCount
; nP
++ )
566 aComplexCategories
.push_back( new LabeledDataSequence(
567 new UncachedDataSequence( this
568 , lcl_aCategoriesPointRangeNamePrefix
+ OUString::valueOf( nP
)
569 , lcl_aCategoriesRoleName
) ) );
571 //don't add the created sequences to the map as they are used temporarily only ...
572 return new DataSource( ContainerHelper::ContainerToSequence(aComplexCategories
) );
575 OSL_ASSERT( aRangeRepresentation
.equals( lcl_aCompleteRange
));
577 ::std::vector
< Reference
< chart2::data::XLabeledDataSequence
> > aResultLSeqVec
;
581 aResultLSeqVec
.push_back(
582 new LabeledDataSequence( lcl_createDataSequenceAndAddToMap( lcl_aCategoriesRangeName
, lcl_aCategoriesRoleName
) ) );
585 ::std::vector
< Reference
< chart2::data::XLabeledDataSequence
> > aDataVec
;
586 const sal_Int32 nCount
= (bUseColumns
? m_aInternalData
.getColumnCount() : m_aInternalData
.getRowCount());
587 for( sal_Int32 nIdx
=0; nIdx
<nCount
; ++nIdx
)
590 new LabeledDataSequence(
591 lcl_createDataSequenceAndAddToMap( OUString::valueOf( nIdx
)),
592 lcl_createDataSequenceAndAddToMap( lcl_aLabelRangePrefix
+ OUString::valueOf( nIdx
))));
595 // attention: this data provider has the limitation that it stores
596 // internally if data comes from columns or rows. It is intended for
597 // creating only one used data source.
598 // @todo: add this information in the range representation strings
599 m_bDataInColumns
= bUseColumns
;
601 //reorder labeled sequences according to aSequenceMapping; ignore categories
602 for( sal_Int32 nNewIndex
= 0; nNewIndex
< aSequenceMapping
.getLength(); nNewIndex
++ )
604 std::vector
< LabeledDataSequence
* >::size_type nOldIndex
= aSequenceMapping
[nNewIndex
];
605 if( nOldIndex
< aDataVec
.size() )
607 if( aDataVec
[nOldIndex
].is() )
609 aResultLSeqVec
.push_back( aDataVec
[nOldIndex
] );
610 aDataVec
[nOldIndex
] = 0;
615 //add left over data sequences to result
616 ::std::vector
< Reference
< chart2::data::XLabeledDataSequence
> >::iterator
aIt(aDataVec
.begin());
617 const ::std::vector
< Reference
< chart2::data::XLabeledDataSequence
> >::const_iterator
aEndIt(aDataVec
.end());
618 for( ;aIt
!=aEndIt
; ++aIt
)
621 aResultLSeqVec
.push_back( *aIt
);
624 return new DataSource( ContainerHelper::ContainerToSequence(aResultLSeqVec
) );
627 Sequence
< beans::PropertyValue
> SAL_CALL
InternalDataProvider::detectArguments(
628 const Reference
< chart2::data::XDataSource
>& /* xDataSource */ )
629 throw (uno::RuntimeException
)
631 Sequence
< beans::PropertyValue
> aArguments( 4 );
632 aArguments
[0] = beans::PropertyValue(
633 C2U("CellRangeRepresentation"), -1, uno::makeAny( lcl_aCompleteRange
),
634 beans::PropertyState_DIRECT_VALUE
);
635 aArguments
[1] = beans::PropertyValue(
636 C2U("DataRowSource"), -1, uno::makeAny(
638 ? ::com::sun::star::chart::ChartDataRowSource_COLUMNS
639 : ::com::sun::star::chart::ChartDataRowSource_ROWS
),
640 beans::PropertyState_DIRECT_VALUE
);
641 // internal data always contains labels and categories
642 aArguments
[2] = beans::PropertyValue(
643 C2U("FirstCellAsLabel"), -1, uno::makeAny( true ), beans::PropertyState_DIRECT_VALUE
);
644 aArguments
[3] = beans::PropertyValue(
645 C2U("HasCategories"), -1, uno::makeAny( true ), beans::PropertyState_DIRECT_VALUE
);
647 // #i85913# Sequence Mapping is not needed for internal data, as it is
648 // applied to the data when the data source is created.
653 ::sal_Bool SAL_CALL
InternalDataProvider::createDataSequenceByRangeRepresentationPossible( const OUString
& /* aRangeRepresentation */ )
654 throw (uno::RuntimeException
)
659 Reference
< chart2::data::XDataSequence
> SAL_CALL
InternalDataProvider::createDataSequenceByRangeRepresentation(
660 const OUString
& aRangeRepresentation
)
661 throw (lang::IllegalArgumentException
,
662 uno::RuntimeException
)
664 if( aRangeRepresentation
.match( lcl_aCategoriesRangeName
))
666 OSL_ASSERT( aRangeRepresentation
.equals( lcl_aCategoriesRangeName
) );//it is not expected nor implmented that only parts of the categories are really requested
669 return lcl_createDataSequenceAndAddToMap( lcl_aCategoriesRangeName
, lcl_aCategoriesRoleName
);
671 else if( aRangeRepresentation
.match( lcl_aLabelRangePrefix
))
674 sal_Int32 nIndex
= aRangeRepresentation
.copy( lcl_aLabelRangePrefix
.getLength()).toInt32();
675 return lcl_createDataSequenceAndAddToMap( lcl_aLabelRangePrefix
+ OUString::valueOf( nIndex
));
677 else if( aRangeRepresentation
.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "last" )))
679 sal_Int32 nIndex
= (m_bDataInColumns
680 ? m_aInternalData
.getColumnCount()
681 : m_aInternalData
.getRowCount()) - 1;
682 return lcl_createDataSequenceAndAddToMap( OUString::valueOf( nIndex
));
684 else if( aRangeRepresentation
.getLength())
687 sal_Int32 nIndex
= aRangeRepresentation
.toInt32();
688 return lcl_createDataSequenceAndAddToMap( OUString::valueOf( nIndex
));
691 return Reference
< chart2::data::XDataSequence
>();
694 Reference
< sheet::XRangeSelection
> SAL_CALL
InternalDataProvider::getRangeSelection()
695 throw (uno::RuntimeException
)
697 // there is no range selection component
698 return Reference
< sheet::XRangeSelection
>();
701 // ____ XInternalDataProvider ____
702 ::sal_Bool SAL_CALL
InternalDataProvider::hasDataByRangeRepresentation( const OUString
& aRange
)
703 throw (uno::RuntimeException
)
705 sal_Bool bResult
= false;
707 if( aRange
.match( lcl_aCategoriesRangeName
))
709 OSL_ASSERT( aRange
.equals( lcl_aCategoriesRangeName
) );//it is not expected nor implmented that only parts of the categories are really requested
712 else if( aRange
.match( lcl_aLabelRangePrefix
))
714 sal_Int32 nIndex
= aRange
.copy( lcl_aLabelRangePrefix
.getLength()).toInt32();
715 bResult
= (nIndex
< (m_bDataInColumns
? m_aInternalData
.getColumnCount(): m_aInternalData
.getRowCount()));
719 sal_Int32 nIndex
= aRange
.toInt32();
720 bResult
= (nIndex
< (m_bDataInColumns
? m_aInternalData
.getColumnCount(): m_aInternalData
.getRowCount()));
726 Sequence
< uno::Any
> SAL_CALL
InternalDataProvider::getDataByRangeRepresentation( const OUString
& aRange
)
727 throw (uno::RuntimeException
)
729 Sequence
< uno::Any
> aResult
;
731 if( aRange
.match( lcl_aLabelRangePrefix
) )
733 sal_Int32 nIndex
= aRange
.copy( lcl_aLabelRangePrefix
.getLength()).toInt32();
734 vector
< OUString
> aComplexLabel
= m_bDataInColumns
735 ? m_aInternalData
.getComplexColumnLabel( nIndex
)
736 : m_aInternalData
.getComplexRowLabel( nIndex
);
737 if( !aComplexLabel
.empty() )
739 aResult
.realloc( aComplexLabel
.size() );
740 transform( aComplexLabel
.begin(), aComplexLabel
.end(),
741 aResult
.getArray(), CommonFunctors::makeAny
< OUString
>());
744 else if( aRange
.match( lcl_aCategoriesPointRangeNamePrefix
) )
746 sal_Int32 nPointIndex
= aRange
.copy( lcl_aCategoriesPointRangeNamePrefix
.getLength() ).toInt32();
747 vector
< OUString
> aComplexCategory
= m_bDataInColumns
748 ? m_aInternalData
.getComplexRowLabel( nPointIndex
)
749 : m_aInternalData
.getComplexColumnLabel( nPointIndex
);
750 if( !aComplexCategory
.empty() )
752 aResult
.realloc( aComplexCategory
.size() );
753 transform( aComplexCategory
.begin(), aComplexCategory
.end(),
754 aResult
.getArray(), CommonFunctors::makeAny
< OUString
>());
757 else if( aRange
.match( lcl_aCategoriesLevelRangeNamePrefix
) )
759 sal_Int32 nLevel
= aRange
.copy( lcl_aCategoriesLevelRangeNamePrefix
.getLength() ).toInt32();
760 vector
< vector
< OUString
> > aCategories( m_bDataInColumns
? m_aInternalData
.getComplexRowLabels() : m_aInternalData
.getComplexColumnLabels());
761 if( nLevel
< lcl_getInnerLevelCount( aCategories
) )
763 aResult
.realloc( aCategories
.size() );
764 transform( aCategories
.begin(), aCategories
.end(),
765 aResult
.getArray(), lcl_makeAnyFromLevelVector(nLevel
) );
768 else if( aRange
.equals( lcl_aCategoriesRangeName
) )
770 Sequence
< OUString
> aLabels
= m_bDataInColumns
? this->getRowDescriptions() : this->getColumnDescriptions();
771 aResult
.realloc( aLabels
.getLength() );
772 transform( aLabels
.getConstArray(), aLabels
.getConstArray() + aLabels
.getLength(),
773 aResult
.getArray(), CommonFunctors::makeAny
< OUString
>() );
777 sal_Int32 nIndex
= aRange
.toInt32();
780 Sequence
< double > aData
;
781 if( m_bDataInColumns
)
782 aData
= m_aInternalData
.getColumnValues(nIndex
);
784 aData
= m_aInternalData
.getRowValues(nIndex
);
785 if( aData
.getLength() )
787 aResult
.realloc( aData
.getLength());
788 transform( aData
.getConstArray(), aData
.getConstArray() + aData
.getLength(),
789 aResult
.getArray(), CommonFunctors::makeAny
< double >());
797 void SAL_CALL
InternalDataProvider::setDataByRangeRepresentation(
798 const OUString
& aRange
, const Sequence
< uno::Any
>& aNewData
)
799 throw (uno::RuntimeException
)
801 if( aRange
.match( lcl_aLabelRangePrefix
) )
803 vector
< OUString
> aNewStrings( lcl_AnyToStringVector( aNewData
) );
804 sal_uInt32 nIndex
= aRange
.copy( lcl_aLabelRangePrefix
.getLength()).toInt32();
805 if( m_bDataInColumns
)
806 m_aInternalData
.setComplexColumnLabel( nIndex
, aNewStrings
);
808 m_aInternalData
.setComplexRowLabel( nIndex
, aNewStrings
);
810 else if( aRange
.match( lcl_aCategoriesPointRangeNamePrefix
) )
812 vector
< OUString
> aNewStrings( lcl_AnyToStringVector( aNewData
) );
813 sal_Int32 nPointIndex
= aRange
.copy( lcl_aCategoriesLevelRangeNamePrefix
.getLength()).toInt32();
814 if( m_bDataInColumns
)
815 m_aInternalData
.setComplexRowLabel( nPointIndex
, aNewStrings
);
817 m_aInternalData
.setComplexColumnLabel( nPointIndex
, aNewStrings
);
819 else if( aRange
.match( lcl_aCategoriesLevelRangeNamePrefix
) )
821 vector
< OUString
> aNewStrings( lcl_AnyToStringVector( aNewData
) );
822 sal_Int32 nLevel
= aRange
.copy( lcl_aCategoriesLevelRangeNamePrefix
.getLength()).toInt32();
823 vector
< vector
< OUString
> > aComplexCategories
= m_bDataInColumns
? m_aInternalData
.getComplexRowLabels() : m_aInternalData
.getComplexColumnLabels();
825 //ensure equal length
826 if( aNewStrings
.size() > aComplexCategories
.size() )
827 aComplexCategories
.resize( aNewStrings
.size() );
828 else if( aNewStrings
.size() < aComplexCategories
.size() )
829 aNewStrings
.resize( aComplexCategories
.size() );
831 transform( aComplexCategories
.begin(), aComplexCategories
.end(), aNewStrings
.begin(),
832 aComplexCategories
.begin(), lcl_setStringAtLevel(nLevel
) );
834 if( m_bDataInColumns
)
835 m_aInternalData
.setComplexRowLabels( aComplexCategories
);
837 m_aInternalData
.setComplexColumnLabels( aComplexCategories
);
839 else if( aRange
.equals( lcl_aCategoriesRangeName
) )
841 if( m_bDataInColumns
)
842 this->setRowDescriptions( lcl_AnyToStringSequence(aNewData
) );
844 this->setColumnDescriptions( lcl_AnyToStringSequence(aNewData
) );
848 sal_Int32 nIndex
= aRange
.toInt32();
851 vector
< double > aNewDataVec
;
852 transform( aNewData
.getConstArray(), aNewData
.getConstArray() + aNewData
.getLength(),
853 back_inserter( aNewDataVec
), CommonFunctors::AnyToDouble());
854 if( m_bDataInColumns
)
855 m_aInternalData
.setColumnValues( nIndex
, aNewDataVec
);
857 m_aInternalData
.setRowValues( nIndex
, aNewDataVec
);
862 void SAL_CALL
InternalDataProvider::insertSequence( ::sal_Int32 nAfterIndex
)
863 throw (uno::RuntimeException
)
865 if( m_bDataInColumns
)
867 lcl_increaseMapReferences( nAfterIndex
+ 1, m_aInternalData
.getColumnCount());
868 m_aInternalData
.insertColumn( nAfterIndex
);
872 lcl_increaseMapReferences( nAfterIndex
+ 1, m_aInternalData
.getRowCount());
873 m_aInternalData
.insertRow( nAfterIndex
);
877 void SAL_CALL
InternalDataProvider::deleteSequence( ::sal_Int32 nAtIndex
)
878 throw (uno::RuntimeException
)
880 lcl_deleteMapReferences( OUString::valueOf( nAtIndex
));
881 lcl_deleteMapReferences( lcl_aLabelRangePrefix
+ OUString::valueOf( nAtIndex
));
882 if( m_bDataInColumns
)
884 lcl_decreaseMapReferences( nAtIndex
+ 1, m_aInternalData
.getColumnCount());
885 m_aInternalData
.deleteColumn( nAtIndex
);
889 lcl_decreaseMapReferences( nAtIndex
+ 1, m_aInternalData
.getRowCount());
890 m_aInternalData
.deleteRow( nAtIndex
);
894 void SAL_CALL
InternalDataProvider::appendSequence()
895 throw (uno::RuntimeException
)
897 if( m_bDataInColumns
)
898 m_aInternalData
.appendColumn();
900 m_aInternalData
.appendRow();
903 void SAL_CALL
InternalDataProvider::insertComplexCategoryLevel( sal_Int32 nLevel
)
904 throw (uno::RuntimeException
)
906 OSL_ENSURE( nLevel
> 0, "you can only insert category levels > 0" );//the first categories level cannot be deleted, check the calling code for error
909 vector
< vector
< OUString
> > aComplexCategories
= m_bDataInColumns
? m_aInternalData
.getComplexRowLabels() : m_aInternalData
.getComplexColumnLabels();
910 ::std::for_each( aComplexCategories
.begin(), aComplexCategories
.end(), lcl_insertStringAtLevel(nLevel
) );
911 if( m_bDataInColumns
)
912 m_aInternalData
.setComplexRowLabels( aComplexCategories
);
914 m_aInternalData
.setComplexColumnLabels( aComplexCategories
);
916 tSequenceMapRange
aRange( m_aSequenceMap
.equal_range( lcl_aCategoriesRangeName
));
917 ::std::for_each( aRange
.first
, aRange
.second
, lcl_setModified());
920 void SAL_CALL
InternalDataProvider::deleteComplexCategoryLevel( sal_Int32 nLevel
)
921 throw (uno::RuntimeException
)
923 OSL_ENSURE( nLevel
>0, "you can only delete category levels > 0" );//the first categories level cannot be deleted, check the calling code for error
926 vector
< vector
< OUString
> > aComplexCategories
= m_bDataInColumns
? m_aInternalData
.getComplexRowLabels() : m_aInternalData
.getComplexColumnLabels();
927 ::std::for_each( aComplexCategories
.begin(), aComplexCategories
.end(), lcl_removeStringAtLevel(nLevel
) );
928 if( m_bDataInColumns
)
929 m_aInternalData
.setComplexRowLabels( aComplexCategories
);
931 m_aInternalData
.setComplexColumnLabels( aComplexCategories
);
933 tSequenceMapRange
aRange( m_aSequenceMap
.equal_range( lcl_aCategoriesRangeName
));
934 ::std::for_each( aRange
.first
, aRange
.second
, lcl_setModified());
938 void SAL_CALL
InternalDataProvider::insertDataPointForAllSequences( ::sal_Int32 nAfterIndex
)
939 throw (uno::RuntimeException
)
941 sal_Int32 nMaxRep
= 0;
942 if( m_bDataInColumns
)
944 m_aInternalData
.insertRow( nAfterIndex
);
945 nMaxRep
= m_aInternalData
.getColumnCount();
949 m_aInternalData
.insertColumn( nAfterIndex
);
950 nMaxRep
= m_aInternalData
.getRowCount();
953 // notify change to all affected ranges
954 tSequenceMap::const_iterator
aBegin( m_aSequenceMap
.lower_bound( C2U("0")));
955 tSequenceMap::const_iterator
aEnd( m_aSequenceMap
.upper_bound( OUString::valueOf( nMaxRep
)));
956 ::std::for_each( aBegin
, aEnd
, lcl_setModified());
958 tSequenceMapRange
aRange( m_aSequenceMap
.equal_range( lcl_aCategoriesRangeName
));
959 ::std::for_each( aRange
.first
, aRange
.second
, lcl_setModified());
962 void SAL_CALL
InternalDataProvider::deleteDataPointForAllSequences( ::sal_Int32 nAtIndex
)
963 throw (uno::RuntimeException
)
965 sal_Int32 nMaxRep
= 0;
966 if( m_bDataInColumns
)
968 m_aInternalData
.deleteRow( nAtIndex
);
969 nMaxRep
= m_aInternalData
.getColumnCount();
973 m_aInternalData
.deleteColumn( nAtIndex
);
974 nMaxRep
= m_aInternalData
.getRowCount();
977 // notify change to all affected ranges
978 tSequenceMap::const_iterator
aBegin( m_aSequenceMap
.lower_bound( C2U("0")));
979 tSequenceMap::const_iterator
aEnd( m_aSequenceMap
.upper_bound( OUString::valueOf( nMaxRep
)));
980 ::std::for_each( aBegin
, aEnd
, lcl_setModified());
982 tSequenceMapRange
aRange( m_aSequenceMap
.equal_range( lcl_aCategoriesRangeName
));
983 ::std::for_each( aRange
.first
, aRange
.second
, lcl_setModified());
986 void SAL_CALL
InternalDataProvider::swapDataPointWithNextOneForAllSequences( ::sal_Int32 nAtIndex
)
987 throw (uno::RuntimeException
)
989 if( m_bDataInColumns
)
990 m_aInternalData
.swapRowWithNext( nAtIndex
);
992 m_aInternalData
.swapColumnWithNext( nAtIndex
);
993 sal_Int32 nMaxRep
= (m_bDataInColumns
994 ? m_aInternalData
.getColumnCount()
995 : m_aInternalData
.getRowCount());
997 // notify change to all affected ranges
998 tSequenceMap::const_iterator
aBegin( m_aSequenceMap
.lower_bound( C2U("0")));
999 tSequenceMap::const_iterator
aEnd( m_aSequenceMap
.upper_bound( OUString::valueOf( nMaxRep
)));
1000 ::std::for_each( aBegin
, aEnd
, lcl_setModified());
1002 tSequenceMapRange
aRange( m_aSequenceMap
.equal_range( lcl_aCategoriesRangeName
));
1003 ::std::for_each( aRange
.first
, aRange
.second
, lcl_setModified());
1006 void SAL_CALL
InternalDataProvider::registerDataSequenceForChanges( const Reference
< chart2::data::XDataSequence
>& xSeq
)
1007 throw (uno::RuntimeException
)
1010 lcl_addDataSequenceToMap( xSeq
->getSourceRangeRepresentation(), xSeq
);
1014 // ____ XRangeXMLConversion ____
1015 OUString SAL_CALL
InternalDataProvider::convertRangeToXML( const OUString
& aRangeRepresentation
)
1016 throw (lang::IllegalArgumentException
,
1017 uno::RuntimeException
)
1019 XMLRangeHelper::CellRange aRange
;
1020 aRange
.aTableName
= OUString(RTL_CONSTASCII_USTRINGPARAM("local-table"));
1022 // attention: this data provider has the limitation that it stores
1023 // internally if data comes from columns or rows. It is intended for
1024 // creating only one used data source.
1025 // @todo: add this information in the range representation strings
1026 if( aRangeRepresentation
.match( lcl_aCategoriesRangeName
))
1028 OSL_ASSERT( aRangeRepresentation
.equals( lcl_aCategoriesRangeName
) );//it is not expected nor implmented that only parts of the categories are really requested
1029 aRange
.aUpperLeft
.bIsEmpty
= false;
1030 if( m_bDataInColumns
)
1032 aRange
.aUpperLeft
.nColumn
= 0;
1033 aRange
.aUpperLeft
.nRow
= 1;
1034 aRange
.aLowerRight
= aRange
.aUpperLeft
;
1035 aRange
.aLowerRight
.nRow
= m_aInternalData
.getRowCount();
1039 aRange
.aUpperLeft
.nColumn
= 1;
1040 aRange
.aUpperLeft
.nRow
= 0;
1041 aRange
.aLowerRight
= aRange
.aUpperLeft
;
1042 aRange
.aLowerRight
.nColumn
= m_aInternalData
.getColumnCount();
1045 else if( aRangeRepresentation
.match( lcl_aLabelRangePrefix
))
1047 sal_Int32 nIndex
= aRangeRepresentation
.copy( lcl_aLabelRangePrefix
.getLength()).toInt32();
1048 aRange
.aUpperLeft
.bIsEmpty
= false;
1049 aRange
.aLowerRight
.bIsEmpty
= true;
1050 if( m_bDataInColumns
)
1052 aRange
.aUpperLeft
.nColumn
= nIndex
+ 1;
1053 aRange
.aUpperLeft
.nRow
= 0;
1057 aRange
.aUpperLeft
.nColumn
= 0;
1058 aRange
.aUpperLeft
.nRow
= nIndex
+ 1;
1061 else if( aRangeRepresentation
.equals( lcl_aCompleteRange
))
1063 aRange
.aUpperLeft
.bIsEmpty
= false;
1064 aRange
.aLowerRight
.bIsEmpty
= false;
1065 aRange
.aUpperLeft
.nColumn
= 0;
1066 aRange
.aUpperLeft
.nRow
= 0;
1067 aRange
.aLowerRight
.nColumn
= m_aInternalData
.getColumnCount();
1068 aRange
.aLowerRight
.nRow
= m_aInternalData
.getRowCount();
1072 sal_Int32 nIndex
= aRangeRepresentation
.toInt32();
1073 aRange
.aUpperLeft
.bIsEmpty
= false;
1074 if( m_bDataInColumns
)
1076 aRange
.aUpperLeft
.nColumn
= nIndex
+ 1;
1077 aRange
.aUpperLeft
.nRow
= 1;
1078 aRange
.aLowerRight
= aRange
.aUpperLeft
;
1079 aRange
.aLowerRight
.nRow
= m_aInternalData
.getRowCount();
1083 aRange
.aUpperLeft
.nColumn
= 1;
1084 aRange
.aUpperLeft
.nRow
= nIndex
+ 1;
1085 aRange
.aLowerRight
= aRange
.aUpperLeft
;
1086 aRange
.aLowerRight
.nColumn
= m_aInternalData
.getColumnCount();
1090 return XMLRangeHelper::getXMLStringFromCellRange( aRange
);
1093 OUString SAL_CALL
InternalDataProvider::convertRangeFromXML( const OUString
& aXMLRange
)
1094 throw (lang::IllegalArgumentException
,
1095 uno::RuntimeException
)
1097 XMLRangeHelper::CellRange
aRange( XMLRangeHelper::getCellRangeFromXMLString( aXMLRange
));
1098 if( aRange
.aUpperLeft
.bIsEmpty
)
1100 OSL_ENSURE( aRange
.aLowerRight
.bIsEmpty
, "Weird Range" );
1105 if( !aRange
.aLowerRight
.bIsEmpty
&&
1106 ( aRange
.aUpperLeft
.nColumn
!= aRange
.aLowerRight
.nColumn
) &&
1107 ( aRange
.aUpperLeft
.nRow
!= aRange
.aLowerRight
.nRow
) )
1108 return lcl_aCompleteRange
;
1110 // attention: this data provider has the limitation that it stores
1111 // internally if data comes from columns or rows. It is intended for
1112 // creating only one used data source.
1113 // @todo: add this information in the range representation strings
1116 if( m_bDataInColumns
)
1118 if( aRange
.aUpperLeft
.nColumn
== 0 )
1119 return lcl_aCategoriesRangeName
;
1120 if( aRange
.aUpperLeft
.nRow
== 0 )
1121 return lcl_aLabelRangePrefix
+ OUString::valueOf( aRange
.aUpperLeft
.nColumn
- 1 );
1123 return OUString::valueOf( aRange
.aUpperLeft
.nColumn
- 1 );
1127 if( aRange
.aUpperLeft
.nRow
== 0 )
1128 return lcl_aCategoriesRangeName
;
1129 if( aRange
.aUpperLeft
.nColumn
== 0 )
1130 return lcl_aLabelRangePrefix
+ OUString::valueOf( aRange
.aUpperLeft
.nRow
- 1 );
1132 return OUString::valueOf( aRange
.aUpperLeft
.nRow
- 1 );
1137 Sequence
< Sequence
< OUString
> > lcl_convertComplexVectorToSequence( const vector
< vector
< OUString
> >& rIn
)
1139 Sequence
< Sequence
< OUString
> > aRet
;
1140 sal_Int32 nOuterCount
= rIn
.size();
1143 aRet
.realloc(nOuterCount
);
1144 for( sal_Int32 nN
=0; nN
<nOuterCount
; nN
++)
1145 aRet
[nN
]=ContainerHelper::ContainerToSequence( rIn
[nN
] );
1150 vector
< vector
< OUString
> > lcl_convertComplexSequenceToVector( const Sequence
< Sequence
< OUString
> >& rIn
)
1152 vector
< vector
< OUString
> > aRet
;
1153 sal_Int32 nOuterCount
= rIn
.getLength();
1154 for( sal_Int32 nN
=0; nN
<nOuterCount
; nN
++)
1155 aRet
.push_back( ContainerHelper::SequenceToVector( rIn
[nN
] ) );
1159 class SplitCategoriesProvider_ForComplexDescriptions
: public SplitCategoriesProvider
1163 explicit SplitCategoriesProvider_ForComplexDescriptions( const ::std::vector
< ::std::vector
< ::rtl::OUString
> >& rComplexDescriptions
)
1164 : m_rComplexDescriptions( rComplexDescriptions
)
1166 virtual ~SplitCategoriesProvider_ForComplexDescriptions()
1169 virtual sal_Int32
getLevelCount() const;
1170 virtual uno::Sequence
< rtl::OUString
> getStringsForLevel( sal_Int32 nIndex
) const;
1173 const ::std::vector
< ::std::vector
< ::rtl::OUString
> >& m_rComplexDescriptions
;
1176 sal_Int32
SplitCategoriesProvider_ForComplexDescriptions::getLevelCount() const
1178 return lcl_getInnerLevelCount( m_rComplexDescriptions
);
1180 uno::Sequence
< rtl::OUString
> SplitCategoriesProvider_ForComplexDescriptions::getStringsForLevel( sal_Int32 nLevel
) const
1182 uno::Sequence
< rtl::OUString
> aResult
;
1183 if( nLevel
< lcl_getInnerLevelCount( m_rComplexDescriptions
) )
1185 aResult
.realloc( m_rComplexDescriptions
.size() );
1186 transform( m_rComplexDescriptions
.begin(), m_rComplexDescriptions
.end(),
1187 aResult
.getArray(), lcl_getStringFromLevelVector(nLevel
) );
1192 }//anonymous namespace
1194 // ____ XComplexDescriptionAccess ____
1195 Sequence
< Sequence
< OUString
> > SAL_CALL
InternalDataProvider::getComplexRowDescriptions() throw (uno::RuntimeException
)
1197 return lcl_convertComplexVectorToSequence( m_aInternalData
.getComplexRowLabels() );
1199 void SAL_CALL
InternalDataProvider::setComplexRowDescriptions( const Sequence
< Sequence
< ::rtl::OUString
> >& aRowDescriptions
) throw (uno::RuntimeException
)
1201 m_aInternalData
.setComplexRowLabels( lcl_convertComplexSequenceToVector(aRowDescriptions
) );
1203 Sequence
< Sequence
< ::rtl::OUString
> > SAL_CALL
InternalDataProvider::getComplexColumnDescriptions() throw (uno::RuntimeException
)
1205 return lcl_convertComplexVectorToSequence( m_aInternalData
.getComplexColumnLabels() );
1207 void SAL_CALL
InternalDataProvider::setComplexColumnDescriptions( const Sequence
< Sequence
< ::rtl::OUString
> >& aColumnDescriptions
) throw (uno::RuntimeException
)
1209 m_aInternalData
.setComplexColumnLabels( lcl_convertComplexSequenceToVector(aColumnDescriptions
) );
1212 // ____ XChartDataArray ____
1213 Sequence
< Sequence
< double > > SAL_CALL
InternalDataProvider::getData()
1214 throw (uno::RuntimeException
)
1216 return m_aInternalData
.getData();
1219 void SAL_CALL
InternalDataProvider::setData( const Sequence
< Sequence
< double > >& rDataInRows
)
1220 throw (uno::RuntimeException
)
1222 return m_aInternalData
.setData( rDataInRows
);
1225 void SAL_CALL
InternalDataProvider::setRowDescriptions( const Sequence
< OUString
>& aRowDescriptions
)
1226 throw (uno::RuntimeException
)
1228 vector
< vector
< OUString
> > aComplexDescriptions( aRowDescriptions
.getLength() );
1229 transform( aComplexDescriptions
.begin(), aComplexDescriptions
.end(), aRowDescriptions
.getConstArray(),
1230 aComplexDescriptions
.begin(), lcl_setStringAtLevel(0) );
1231 m_aInternalData
.setComplexRowLabels( aComplexDescriptions
);
1234 void SAL_CALL
InternalDataProvider::setColumnDescriptions( const Sequence
< OUString
>& aColumnDescriptions
)
1235 throw (uno::RuntimeException
)
1237 vector
< vector
< OUString
> > aComplexDescriptions( aColumnDescriptions
.getLength() );
1238 transform( aComplexDescriptions
.begin(), aComplexDescriptions
.end(), aColumnDescriptions
.getConstArray(),
1239 aComplexDescriptions
.begin(), lcl_setStringAtLevel(0) );
1240 m_aInternalData
.setComplexColumnLabels( aComplexDescriptions
);
1243 Sequence
< OUString
> SAL_CALL
InternalDataProvider::getRowDescriptions()
1244 throw (uno::RuntimeException
)
1246 vector
< vector
< OUString
> > aComplexLabels( m_aInternalData
.getComplexRowLabels() );
1247 SplitCategoriesProvider_ForComplexDescriptions
aProvider( aComplexLabels
);
1248 return ExplicitCategoriesProvider::getExplicitSimpleCategories( aProvider
);
1251 Sequence
< OUString
> SAL_CALL
InternalDataProvider::getColumnDescriptions()
1252 throw (uno::RuntimeException
)
1254 vector
< vector
< OUString
> > aComplexLabels( m_aInternalData
.getComplexColumnLabels() );
1255 SplitCategoriesProvider_ForComplexDescriptions
aProvider( aComplexLabels
);
1256 return ExplicitCategoriesProvider::getExplicitSimpleCategories( aProvider
);
1259 // ____ XChartData (base of XChartDataArray) ____
1260 void SAL_CALL
InternalDataProvider::addChartDataChangeEventListener(
1261 const Reference
< ::com::sun::star::chart::XChartDataChangeEventListener
>& )
1262 throw (uno::RuntimeException
)
1266 void SAL_CALL
InternalDataProvider::removeChartDataChangeEventListener(
1267 const Reference
< ::com::sun::star::chart::XChartDataChangeEventListener
>& )
1268 throw (uno::RuntimeException
)
1272 double SAL_CALL
InternalDataProvider::getNotANumber()
1273 throw (uno::RuntimeException
)
1276 ::rtl::math::setNan( & fNan
);
1280 ::sal_Bool SAL_CALL
InternalDataProvider::isNotANumber( double nNumber
)
1281 throw (uno::RuntimeException
)
1283 return ::rtl::math::isNan( nNumber
)
1284 || ::rtl::math::isInf( nNumber
);
1286 // lang::XInitialization:
1287 void SAL_CALL
InternalDataProvider::initialize(const uno::Sequence
< uno::Any
> & _aArguments
) throw (uno::RuntimeException
, uno::Exception
)
1289 comphelper::SequenceAsHashMap
aArgs(_aArguments
);
1290 if ( aArgs
.getUnpackedValueOrDefault(::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("CreateDefaultData")),sal_False
) )
1291 createDefaultData();
1293 // ____ XCloneable ____
1294 Reference
< util::XCloneable
> SAL_CALL
InternalDataProvider::createClone()
1295 throw (uno::RuntimeException
)
1297 return Reference
< util::XCloneable
>( new InternalDataProvider( *this ));
1301 // ================================================================================
1303 Sequence
< OUString
> InternalDataProvider::getSupportedServiceNames_Static()
1305 Sequence
< OUString
> aServices( 1 );
1306 aServices
[ 0 ] = OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.chart2.data.DataProvider" ));
1310 // ================================================================================
1312 APPHELPER_XSERVICEINFO_IMPL( InternalDataProvider
, lcl_aServiceName
);
1314 } // namespace chart