merged tag ooo/OOO330_m14
[LibreOffice.git] / chart2 / source / tools / InternalDataProvider.cxx
blob4abc51be31afdf4f52c959cd8145b30193db7f17
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>
33 #include <valarray>
35 #include "InternalDataProvider.hxx"
36 #include "LabeledDataSequence.hxx"
37 #include "DataSource.hxx"
38 #include "PropertyHelper.hxx"
39 #include "macros.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>
57 #include <vector>
58 #include <algorithm>
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;
68 namespace chart
71 // ================================================================================
73 namespace
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 > >
94 lcl_tSequenceMap;
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 );
102 if( xSeq.is())
104 Reference< util::XModifiable > xMod( xSeq, uno::UNO_QUERY );
105 if( xMod.is())
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;
138 if( xValues.is() )
140 ::std::vector< double > aValues( ContainerHelper::SequenceToVector( xValues->getNumericalData()));
141 if( m_bDataInColumns )
142 m_rInternalData.setColumnValues( nNewIndex, aValues );
143 else
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 ));
154 if( xLabel.is() )
156 if( m_bDataInColumns )
157 m_rInternalData.setComplexColumnLabel( nNewIndex, ContainerHelper::SequenceToVector( xLabel->getTextualData() ) );
158 else
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 ));
171 else
173 if( m_bConnectToModel )
174 aNewSeriesData[i] = Reference< chart2::data::XLabeledDataSequence >(
175 new LabeledDataSequence( xNewValues ));
178 if( m_bConnectToModel )
179 xSink->setData( aNewSeriesData );
183 private:
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 >
192 public:
194 explicit lcl_makeAnyFromLevelVector( sal_Int32 nLevel ) : m_nLevel( nLevel )
197 uno::Any operator() ( const vector< OUString >& rVector )
199 OUString aString;
200 if( m_nLevel < static_cast< sal_Int32 >(rVector.size()) )
201 aString = rVector[m_nLevel];
202 return uno::makeAny( aString );
205 private:
206 sal_Int32 m_nLevel;
209 struct lcl_getStringFromLevelVector : public ::std::unary_function< vector< OUString >, OUString >
211 public:
213 explicit lcl_getStringFromLevelVector( sal_Int32 nLevel ) : m_nLevel( nLevel )
216 OUString operator() ( const vector< OUString >& rVector )
218 OUString aString;
219 if( m_nLevel < static_cast< sal_Int32 >(rVector.size()) )
220 aString = rVector[m_nLevel];
221 return aString;
224 private:
225 sal_Int32 m_nLevel;
229 struct lcl_setStringAtLevel : public ::std::binary_function< vector< OUString >, OUString, vector< OUString > >
231 public:
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;
242 return aRet;
245 private:
246 sal_Int32 m_nLevel;
249 struct lcl_insertStringAtLevel : public ::std::unary_function< vector< OUString >, void >
251 public:
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++)
264 if( nN==m_nLevel )
265 break;
267 rVector.insert( aIt, OUString() );
270 private:
271 sal_Int32 m_nLevel;
274 struct lcl_removeStringAtLevel : public ::std::unary_function< vector< OUString >, void >
276 public:
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++)
286 if( nN==m_nLevel )
288 rVector.erase( aIt );
289 break;
294 private:
295 sal_Int32 m_nLevel;
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() );
303 return aStringVec;
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() );
312 return aResult;
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 ) );
329 if( xDiagram.is())
331 Reference< frame::XModel > xChartModel( xChartDoc, uno::UNO_QUERY );
333 //data in columns?
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 );
342 // categories
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] );
352 if( !xLDS.is() )
353 continue;
354 Reference< chart2::data::XTextualDataSequence > xSeq( xLDS->getValues(), uno::UNO_QUERY );
355 Sequence< OUString > aStringSeq;
356 if( xSeq.is() )
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) );
365 if( !nLevelCount )
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 );
381 else
382 m_aInternalData.setComplexColumnLabels( aNewCategories );
383 if( bConnectToModel )
384 DiagramHelper::setCategoriesToDiagram( new LabeledDataSequence(
385 createDataSequenceByRangeRepresentation( lcl_aCategoriesRangeName )), xDiagram );
388 // data series
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 );
399 // copy-CTOR
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 );
427 if( xSeq.is())
429 Reference< container::XNamed > xNamed( xSeq, uno::UNO_QUERY );
430 if( xNamed.is())
431 xNamed->setName( OUString());
434 // remove from map
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 );
447 if( xSeq.is())
449 Reference< container::XNamed > xNamed( xSeq, uno::UNO_QUERY );
450 if( xNamed.is())
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 );
493 return 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 );
503 return 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)
515 return true;
518 namespace
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 );
531 return 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 ) ) );
562 else
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;
579 // categories
580 if( bHasCategories )
581 aResultLSeqVec.push_back(
582 new LabeledDataSequence( lcl_createDataSequenceAndAddToMap( lcl_aCategoriesRangeName, lcl_aCategoriesRoleName ) ) );
584 // data with labels
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 )
589 aDataVec.push_back(
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)
620 if( aIt->is() )
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(
637 m_bDataInColumns
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.
650 return aArguments;
653 ::sal_Bool SAL_CALL InternalDataProvider::createDataSequenceByRangeRepresentationPossible( const OUString& /* aRangeRepresentation */ )
654 throw (uno::RuntimeException)
656 return true;
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
668 // categories
669 return lcl_createDataSequenceAndAddToMap( lcl_aCategoriesRangeName, lcl_aCategoriesRoleName );
671 else if( aRangeRepresentation.match( lcl_aLabelRangePrefix ))
673 // label
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())
686 // data
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
710 bResult = true;
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()));
717 else
719 sal_Int32 nIndex = aRange.toInt32();
720 bResult = (nIndex < (m_bDataInColumns ? m_aInternalData.getColumnCount(): m_aInternalData.getRowCount()));
723 return bResult;
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 >() );
775 else
777 sal_Int32 nIndex = aRange.toInt32();
778 if( nIndex >= 0 )
780 Sequence< double > aData;
781 if( m_bDataInColumns )
782 aData = m_aInternalData.getColumnValues(nIndex);
783 else
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 >());
794 return aResult;
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 );
807 else
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 );
816 else
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 );
836 else
837 m_aInternalData.setComplexColumnLabels( aComplexCategories );
839 else if( aRange.equals( lcl_aCategoriesRangeName ) )
841 if( m_bDataInColumns )
842 this->setRowDescriptions( lcl_AnyToStringSequence(aNewData) );
843 else
844 this->setColumnDescriptions( lcl_AnyToStringSequence(aNewData) );
846 else
848 sal_Int32 nIndex = aRange.toInt32();
849 if( nIndex>=0 )
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 );
856 else
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 );
870 else
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 );
887 else
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();
899 else
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
907 if( nLevel>0 )
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 );
913 else
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
924 if( nLevel>0 )
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 );
930 else
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();
947 else
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();
971 else
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 );
991 else
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)
1009 if( xSeq.is())
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();
1037 else
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;
1055 else
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();
1070 else
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();
1081 else
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" );
1101 return OUString();
1104 // "all"
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
1115 // data in columns
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 );
1126 // data in rows
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 );
1135 namespace
1137 Sequence< Sequence< OUString > > lcl_convertComplexVectorToSequence( const vector< vector< OUString > >& rIn )
1139 Sequence< Sequence< OUString > > aRet;
1140 sal_Int32 nOuterCount = rIn.size();
1141 if( nOuterCount )
1143 aRet.realloc(nOuterCount);
1144 for( sal_Int32 nN=0; nN<nOuterCount; nN++)
1145 aRet[nN]=ContainerHelper::ContainerToSequence( rIn[nN] );
1147 return aRet;
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] ) );
1156 return aRet;
1159 class SplitCategoriesProvider_ForComplexDescriptions : public SplitCategoriesProvider
1161 public:
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;
1172 private:
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) );
1189 return aResult;
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)
1275 double fNan;
1276 ::rtl::math::setNan( & fNan );
1277 return 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" ));
1307 return aServices;
1310 // ================================================================================
1312 APPHELPER_XSERVICEINFO_IMPL( InternalDataProvider, lcl_aServiceName );
1314 } // namespace chart