Bump for 3.6-28
[LibreOffice.git] / chart2 / source / tools / InternalDataProvider.cxx
blob62de736f16adf9b4d018d0c8b0f2910d9c383c86
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*************************************************************************
4 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
6 * Copyright 2000, 2010 Oracle and/or its affiliates.
8 * OpenOffice.org - a multi-platform office productivity suite
10 * This file is part of OpenOffice.org.
12 * OpenOffice.org is free software: you can redistribute it and/or modify
13 * it under the terms of the GNU Lesser General Public License version 3
14 * only, as published by the Free Software Foundation.
16 * OpenOffice.org is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 * GNU Lesser General Public License version 3 for more details
20 * (a copy is included in the LICENSE file that accompanied this code).
22 * You should have received a copy of the GNU Lesser General Public License
23 * version 3 along with OpenOffice.org. If not, see
24 * <http://www.openoffice.org/license.html>
25 * for a copy of the LGPLv3 License.
27 ************************************************************************/
30 #include <rtl/math.hxx>
32 #include <valarray>
34 #include "InternalDataProvider.hxx"
35 #include "LabeledDataSequence.hxx"
36 #include "DataSource.hxx"
37 #include "PropertyHelper.hxx"
38 #include "macros.hxx"
39 #include "XMLRangeHelper.hxx"
40 #include "ContainerHelper.hxx"
41 #include "CommonConverters.hxx"
42 #include "CommonFunctors.hxx"
43 #include "UncachedDataSequence.hxx"
44 #include "DataSourceHelper.hxx"
45 #include "ChartModelHelper.hxx"
46 #include "DiagramHelper.hxx"
47 #include "ExplicitCategoriesProvider.hxx"
49 #include <com/sun/star/chart2/XChartDocument.hpp>
50 #include <com/sun/star/chart2/data/XDataSequence.hpp>
51 #include <com/sun/star/chart/ChartDataRowSource.hpp>
52 #include <rtl/ustrbuf.hxx>
53 #include <unotools/charclass.hxx>
54 #include <comphelper/sequenceashashmap.hxx>
56 #include <vector>
57 #include <algorithm>
59 using namespace ::com::sun::star;
60 using namespace ::std;
62 using ::com::sun::star::uno::Reference;
63 using ::com::sun::star::uno::Sequence;
64 using ::rtl::OUString;
65 using ::rtl::OUStringBuffer;
67 namespace chart
70 // ================================================================================
72 namespace
75 // note: in xmloff this name is used to indicate usage of own data
76 static const ::rtl::OUString lcl_aServiceName(
77 RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.comp.chart.InternalDataProvider" ));
79 static const ::rtl::OUString lcl_aCategoriesRangeName(
80 RTL_CONSTASCII_USTRINGPARAM( "categories" ));
81 static const ::rtl::OUString lcl_aCategoriesLevelRangeNamePrefix(
82 RTL_CONSTASCII_USTRINGPARAM( "categoriesL " )); //L <-> level
83 static const ::rtl::OUString lcl_aCategoriesPointRangeNamePrefix(
84 RTL_CONSTASCII_USTRINGPARAM( "categoriesP " )); //P <-> point
85 static const ::rtl::OUString lcl_aCategoriesRoleName(
86 RTL_CONSTASCII_USTRINGPARAM( "categories" ));
87 static const ::rtl::OUString lcl_aLabelRangePrefix(
88 RTL_CONSTASCII_USTRINGPARAM( "label " ));
89 static const ::rtl::OUString lcl_aCompleteRange(
90 RTL_CONSTASCII_USTRINGPARAM( "all" ));
92 typedef ::std::multimap< OUString, uno::WeakReference< chart2::data::XDataSequence > >
93 lcl_tSequenceMap;
95 Sequence< OUString > lcl_AnyToStringSequence( const Sequence< uno::Any >& aAnySeq )
97 Sequence< OUString > aResult;
98 aResult.realloc( aAnySeq.getLength() );
99 transform( aAnySeq.getConstArray(), aAnySeq.getConstArray() + aAnySeq.getLength(),
100 aResult.getArray(), CommonFunctors::AnyToString() );
101 return aResult;
104 Sequence< uno::Any > lcl_StringToAnySequence( const Sequence< OUString >& aStringSeq )
106 Sequence< uno::Any > aResult;
107 aResult.realloc( aStringSeq.getLength() );
108 transform( aStringSeq.getConstArray(), aStringSeq.getConstArray() + aStringSeq.getLength(),
109 aResult.getArray(), CommonFunctors::makeAny< OUString >() );
110 return aResult;
113 struct lcl_setModified : public ::std::unary_function< lcl_tSequenceMap, void >
115 void operator() ( const lcl_tSequenceMap::value_type & rMapEntry )
117 // convert weak reference to reference
118 Reference< chart2::data::XDataSequence > xSeq( rMapEntry.second );
119 if( xSeq.is())
121 Reference< util::XModifiable > xMod( xSeq, uno::UNO_QUERY );
122 if( xMod.is())
123 xMod->setModified( sal_True );
128 struct lcl_internalizeSeries : public ::std::unary_function< Reference< chart2::XDataSeries >, void >
130 lcl_internalizeSeries( InternalData & rInternalData,
131 InternalDataProvider & rProvider,
132 bool bConnectToModel, bool bDataInColumns ) :
133 m_rInternalData( rInternalData ),
134 m_rProvider( rProvider ),
135 m_bConnectToModel( bConnectToModel ),
136 m_bDataInColumns( bDataInColumns )
138 void operator() ( const Reference< chart2::XDataSeries > & xSeries )
140 Reference< chart2::data::XDataSource > xSource( xSeries, uno::UNO_QUERY );
141 Reference< chart2::data::XDataSink > xSink( xSeries, uno::UNO_QUERY );
142 if( xSource.is() && xSink.is() )
144 Sequence< Reference< chart2::data::XLabeledDataSequence > > aOldSeriesData = xSource->getDataSequences();
145 Sequence< Reference< chart2::data::XLabeledDataSequence > > aNewSeriesData( aOldSeriesData.getLength() );
146 for( sal_Int32 i=0; i<aOldSeriesData.getLength(); ++i )
148 sal_Int32 nNewIndex( m_bDataInColumns ? m_rInternalData.appendColumn() : m_rInternalData.appendRow() );
149 OUString aIdentifier( OUString::valueOf( nNewIndex ));
150 //@todo: deal also with genericXDataSequence
151 Reference< chart2::data::XNumericalDataSequence > xValues( aOldSeriesData[i]->getValues(), uno::UNO_QUERY );
152 Reference< chart2::data::XTextualDataSequence > xLabel( aOldSeriesData[i]->getLabel(), uno::UNO_QUERY );
153 Reference< chart2::data::XDataSequence > xNewValues;
155 if( xValues.is() )
157 ::std::vector< double > aValues( ContainerHelper::SequenceToVector( xValues->getNumericalData()));
158 if( m_bDataInColumns )
159 m_rInternalData.setColumnValues( nNewIndex, aValues );
160 else
161 m_rInternalData.setRowValues( nNewIndex, aValues );
162 if( m_bConnectToModel )
164 xNewValues.set( m_rProvider.createDataSequenceByRangeRepresentation( aIdentifier ));
165 comphelper::copyProperties(
166 Reference< beans::XPropertySet >( xValues, uno::UNO_QUERY ),
167 Reference< beans::XPropertySet >( xNewValues, uno::UNO_QUERY ));
171 if( xLabel.is() )
173 if( m_bDataInColumns )
174 m_rInternalData.setComplexColumnLabel( nNewIndex, ContainerHelper::SequenceToVector( lcl_StringToAnySequence( xLabel->getTextualData() ) ) );
175 else
176 m_rInternalData.setComplexRowLabel( nNewIndex, ContainerHelper::SequenceToVector( lcl_StringToAnySequence( xLabel->getTextualData() ) ) );
177 if( m_bConnectToModel )
179 Reference< chart2::data::XDataSequence > xNewLabel(
180 m_rProvider.createDataSequenceByRangeRepresentation( lcl_aLabelRangePrefix + aIdentifier ));
181 comphelper::copyProperties(
182 Reference< beans::XPropertySet >( xLabel, uno::UNO_QUERY ),
183 Reference< beans::XPropertySet >( xNewLabel, uno::UNO_QUERY ));
184 aNewSeriesData[i] = Reference< chart2::data::XLabeledDataSequence >(
185 new LabeledDataSequence( xNewValues, xNewLabel ));
188 else
190 if( m_bConnectToModel )
191 aNewSeriesData[i] = Reference< chart2::data::XLabeledDataSequence >(
192 new LabeledDataSequence( xNewValues ));
195 if( m_bConnectToModel )
196 xSink->setData( aNewSeriesData );
200 private:
201 InternalData & m_rInternalData;
202 InternalDataProvider & m_rProvider;
203 bool m_bConnectToModel;
204 bool m_bDataInColumns;
207 struct lcl_copyFromLevel : public ::std::unary_function< vector< uno::Any >, uno::Any >
209 public:
211 explicit lcl_copyFromLevel( sal_Int32 nLevel ) : m_nLevel( nLevel )
214 uno::Any operator() ( const vector< uno::Any >& rVector )
216 uno::Any aRet;
217 if( m_nLevel < static_cast< sal_Int32 >(rVector.size()) )
218 aRet = rVector[m_nLevel];
219 return aRet;
222 private:
223 sal_Int32 m_nLevel;
226 struct lcl_getStringFromLevelVector : public ::std::unary_function< vector< uno::Any >, OUString >
228 public:
230 explicit lcl_getStringFromLevelVector( sal_Int32 nLevel ) : m_nLevel( nLevel )
233 OUString operator() ( const vector< uno::Any >& rVector )
235 OUString aString;
236 if( m_nLevel < static_cast< sal_Int32 >(rVector.size()) )
237 aString = CommonFunctors::AnyToString()(rVector[m_nLevel]);
238 return aString;
241 private:
242 sal_Int32 m_nLevel;
246 struct lcl_setAnyAtLevel : public ::std::binary_function< vector< uno::Any >, uno::Any, vector< uno::Any > >
248 public:
250 explicit lcl_setAnyAtLevel( sal_Int32 nLevel ) : m_nLevel( nLevel )
253 vector< uno::Any > operator() ( const vector< uno::Any >& rVector, const uno::Any& rNewValue )
255 vector< uno::Any > aRet( rVector );
256 if( m_nLevel >= static_cast< sal_Int32 >(aRet.size()) )
257 aRet.resize( m_nLevel+1 );
258 aRet[ m_nLevel ]=rNewValue;
259 return aRet;
262 private:
263 sal_Int32 m_nLevel;
266 struct lcl_setAnyAtLevelFromStringSequence : public ::std::binary_function< vector< uno::Any >, OUString, vector< uno::Any > >
268 public:
270 explicit lcl_setAnyAtLevelFromStringSequence( sal_Int32 nLevel ) : m_nLevel( nLevel )
273 vector< uno::Any > operator() ( const vector< uno::Any >& rVector, const OUString& rNewValue )
275 vector< uno::Any > aRet( rVector );
276 if( m_nLevel >= static_cast< sal_Int32 >(aRet.size()) )
277 aRet.resize( m_nLevel+1 );
278 aRet[ m_nLevel ]=uno::makeAny(rNewValue);
279 return aRet;
282 private:
283 sal_Int32 m_nLevel;
286 struct lcl_insertAnyAtLevel : public ::std::unary_function< vector< uno::Any >, void >
288 public:
290 explicit lcl_insertAnyAtLevel( sal_Int32 nLevel ) : m_nLevel( nLevel )
293 void operator() ( vector< uno::Any >& rVector )
295 if( m_nLevel > static_cast< sal_Int32 >(rVector.size()) )
296 rVector.resize( m_nLevel );
298 vector< uno::Any >::iterator aIt( rVector.begin() );
299 for( sal_Int32 nN=0; aIt<rVector.end(); aIt++, nN++)
301 if( nN==m_nLevel )
302 break;
304 rVector.insert( aIt, uno::Any() );
307 private:
308 sal_Int32 m_nLevel;
311 struct lcl_removeAnyAtLevel : public ::std::unary_function< vector< uno::Any >, void >
313 public:
315 explicit lcl_removeAnyAtLevel( sal_Int32 nLevel ) : m_nLevel( nLevel )
318 void operator() ( vector< uno::Any >& rVector )
320 vector< uno::Any >::iterator aIt( rVector.begin() );
321 for( sal_Int32 nN=0; aIt<rVector.end(); aIt++, nN++)
323 if( nN==m_nLevel )
325 rVector.erase( aIt );
326 break;
331 private:
332 sal_Int32 m_nLevel;
335 } // anonymous namespace
337 // ================================================================================
339 InternalDataProvider::InternalDataProvider( const Reference< uno::XComponentContext > & /*_xContext*/)
340 : m_bDataInColumns( true )
343 InternalDataProvider::InternalDataProvider( const Reference< chart2::XChartDocument > & xChartDoc, bool bConnectToModel )
344 : m_bDataInColumns( true )
348 Reference< chart2::XDiagram > xDiagram( ChartModelHelper::findDiagram( xChartDoc ) );
349 if( xDiagram.is())
351 Reference< frame::XModel > xChartModel( xChartDoc, uno::UNO_QUERY );
353 //data in columns?
355 ::rtl::OUString aRangeString;
356 bool bFirstCellAsLabel = true;
357 bool bHasCategories = true;
358 uno::Sequence< sal_Int32 > aSequenceMapping;
359 DataSourceHelper::detectRangeSegmentation( xChartModel, aRangeString, aSequenceMapping, m_bDataInColumns, bFirstCellAsLabel, bHasCategories );
362 // categories
364 vector< vector< uno::Any > > aNewCategories;//inner count is level
366 ExplicitCategoriesProvider aExplicitCategoriesProvider( ChartModelHelper::getFirstCoordinateSystem(xChartModel), xChartModel );
368 const Sequence< Reference< chart2::data::XLabeledDataSequence> >& rSplitCategoriesList( aExplicitCategoriesProvider.getSplitCategoriesList() );
369 sal_Int32 nLevelCount = rSplitCategoriesList.getLength();
370 for( sal_Int32 nL = 0; nL<nLevelCount; nL++ )
372 Reference< chart2::data::XLabeledDataSequence > xLDS( rSplitCategoriesList[nL] );
373 if( !xLDS.is() )
374 continue;
375 Sequence< uno::Any > aDataSeq;
376 Reference< chart2::data::XDataSequence > xSeq( xLDS->getValues() );
377 if( xSeq.is() )
378 aDataSeq = xSeq->getData();
379 sal_Int32 nLength = aDataSeq.getLength();
380 sal_Int32 nCatLength = static_cast< sal_Int32 >(aNewCategories.size());
381 if( nCatLength < nLength )
382 aNewCategories.resize( nLength );
383 else if( nLength < nCatLength )
384 aDataSeq.realloc( nCatLength );
385 transform( aNewCategories.begin(), aNewCategories.end(), aDataSeq.getConstArray(),
386 aNewCategories.begin(), lcl_setAnyAtLevel(nL) );
388 if( !nLevelCount )
390 Sequence< OUString > aSimplecategories = aExplicitCategoriesProvider.getSimpleCategories();
391 sal_Int32 nLength = aSimplecategories.getLength();
392 aNewCategories.reserve( nLength );
393 for( sal_Int32 nN=0; nN<nLength; nN++)
395 vector< uno::Any > aVector(1);
396 aVector[0] = uno::makeAny( aSimplecategories[nN] );
397 aNewCategories.push_back( aVector );
402 if( m_bDataInColumns )
403 m_aInternalData.setComplexRowLabels( aNewCategories );
404 else
405 m_aInternalData.setComplexColumnLabels( aNewCategories );
406 if( bConnectToModel )
407 DiagramHelper::setCategoriesToDiagram( new LabeledDataSequence(
408 createDataSequenceByRangeRepresentation( lcl_aCategoriesRangeName )), xDiagram );
411 // data series
412 ::std::vector< Reference< chart2::XDataSeries > > aSeriesVector( ChartModelHelper::getDataSeries( xChartDoc ));
413 ::std::for_each( aSeriesVector.begin(), aSeriesVector.end(), lcl_internalizeSeries( m_aInternalData, *this, bConnectToModel, m_bDataInColumns ) );
416 catch( const uno::Exception & ex )
418 ASSERT_EXCEPTION( ex );
422 // copy-CTOR
423 InternalDataProvider::InternalDataProvider( const InternalDataProvider & rOther ) :
424 impl::InternalDataProvider_Base(),
425 m_aSequenceMap( rOther.m_aSequenceMap ),
426 m_aInternalData( rOther.m_aInternalData ),
427 m_bDataInColumns( rOther.m_bDataInColumns )
430 InternalDataProvider::~InternalDataProvider()
433 void InternalDataProvider::lcl_addDataSequenceToMap(
434 const OUString & rRangeRepresentation,
435 const Reference< chart2::data::XDataSequence > & xSequence )
437 m_aSequenceMap.insert(
438 tSequenceMap::value_type(
439 rRangeRepresentation,
440 uno::WeakReference< chart2::data::XDataSequence >( xSequence )));
443 void InternalDataProvider::lcl_deleteMapReferences( const OUString & rRangeRepresentation )
445 // set sequence to deleted by setting its range to an empty string
446 tSequenceMapRange aRange( m_aSequenceMap.equal_range( rRangeRepresentation ));
447 for( tSequenceMap::iterator aIt( aRange.first ); aIt != aRange.second; ++aIt )
449 Reference< chart2::data::XDataSequence > xSeq( aIt->second );
450 if( xSeq.is())
452 Reference< container::XNamed > xNamed( xSeq, uno::UNO_QUERY );
453 if( xNamed.is())
454 xNamed->setName( OUString());
457 // remove from map
458 m_aSequenceMap.erase( aRange.first, aRange.second );
461 void InternalDataProvider::lcl_adaptMapReferences(
462 const OUString & rOldRangeRepresentation,
463 const OUString & rNewRangeRepresentation )
465 tSequenceMapRange aRange( m_aSequenceMap.equal_range( rOldRangeRepresentation ));
466 tSequenceMap aNewElements;
467 for( tSequenceMap::iterator aIt( aRange.first ); aIt != aRange.second; ++aIt )
469 Reference< chart2::data::XDataSequence > xSeq( aIt->second );
470 if( xSeq.is())
472 Reference< container::XNamed > xNamed( xSeq, uno::UNO_QUERY );
473 if( xNamed.is())
474 xNamed->setName( rNewRangeRepresentation );
476 aNewElements.insert( tSequenceMap::value_type( rNewRangeRepresentation, aIt->second ));
478 // erase map values for old index
479 m_aSequenceMap.erase( aRange.first, aRange.second );
480 // add new entries for values with new index
481 ::std::copy( aNewElements.begin(), aNewElements.end(),
482 ::std::inserter( m_aSequenceMap,
483 m_aSequenceMap.upper_bound( rNewRangeRepresentation )));
486 void InternalDataProvider::lcl_increaseMapReferences(
487 sal_Int32 nBegin, sal_Int32 nEnd )
489 for( sal_Int32 nIndex = nEnd - 1; nIndex >= nBegin; --nIndex )
491 lcl_adaptMapReferences( OUString::valueOf( nIndex ),
492 OUString::valueOf( nIndex + 1 ));
493 lcl_adaptMapReferences( lcl_aLabelRangePrefix + OUString::valueOf( nIndex ),
494 lcl_aLabelRangePrefix + OUString::valueOf( nIndex + 1 ));
498 void InternalDataProvider::lcl_decreaseMapReferences(
499 sal_Int32 nBegin, sal_Int32 nEnd )
501 for( sal_Int32 nIndex = nBegin; nIndex < nEnd; ++nIndex )
503 lcl_adaptMapReferences( OUString::valueOf( nIndex ),
504 OUString::valueOf( nIndex - 1 ));
505 lcl_adaptMapReferences( lcl_aLabelRangePrefix + OUString::valueOf( nIndex ),
506 lcl_aLabelRangePrefix + OUString::valueOf( nIndex - 1 ));
510 Reference< chart2::data::XDataSequence > InternalDataProvider::lcl_createDataSequenceAndAddToMap(
511 const OUString & rRangeRepresentation )
513 OUString aRangeRepresentation = rRangeRepresentation;
514 if( aRangeRepresentation.indexOf('{') >= 0 )
516 ::std::vector< double > aNewData;
517 ::std::vector< uno::Any > aNewLabels;
518 OUString aToken;
519 sal_Int32 nCategories = 0;
520 sal_Int32 nIndex = 0;
521 bool bValues = true;
522 bool bLabelSet = false;
523 OUString str = aRangeRepresentation.replace('{',' ').replace('}',' ');
525 m_aInternalData.clearDefaultData();
526 sal_Int32 n = m_aInternalData.getColumnCount();
527 if( n )
528 n = n - 1;
532 // TODO: This will be problematic if ';' is used in label names
533 // '"' character also needs to be considered in such cases
534 aToken = str.getToken(0,';',nIndex);
535 if( aToken.isEmpty() )
536 break;
537 if( aToken.indexOf('"') < 0 )
539 aNewData.push_back( aToken.toDouble() );
541 else
543 aNewLabels.push_back( uno::makeAny(aToken.replace('"', ' ').trim()) );
544 if( !nCategories &&
545 ( !m_aInternalData.getComplexColumnLabel(n).size() ||
546 !m_aInternalData.getComplexColumnLabel(n).front().hasValue() ) )
548 m_aInternalData.setComplexColumnLabel( n, aNewLabels );
549 bLabelSet = true;
551 else
553 m_aInternalData.setComplexRowLabel(nCategories, aNewLabels);
554 if(nCategories==1 && bLabelSet)
556 ::std::vector< uno::Any > aLabels;
557 m_aInternalData.setComplexRowLabel( 0, m_aInternalData.getComplexColumnLabel( n ) );
558 m_aInternalData.setComplexColumnLabel( n, aLabels );
561 aNewLabels.pop_back();
562 nCategories++;
563 bValues = false;
565 } while( nIndex >= 0 );
567 if( bValues )
569 m_aInternalData.insertColumn( n );
570 m_aInternalData.setColumnValues( n, aNewData );
571 aRangeRepresentation = OUString::valueOf( n );
573 else if( nCategories > 1 )
575 aRangeRepresentation = lcl_aCategoriesRangeName;
577 else
579 aRangeRepresentation = lcl_aLabelRangePrefix+OUString::valueOf( n );
583 Reference< chart2::data::XDataSequence > xSeq(
584 new UncachedDataSequence( this, aRangeRepresentation ));
585 lcl_addDataSequenceToMap( aRangeRepresentation, xSeq );
586 return xSeq;
589 Reference< chart2::data::XDataSequence > InternalDataProvider::lcl_createDataSequenceAndAddToMap(
590 const OUString & rRangeRepresentation,
591 const OUString & rRole )
593 Reference< chart2::data::XDataSequence > xSeq(
594 new UncachedDataSequence( this, rRangeRepresentation, rRole ));
595 lcl_addDataSequenceToMap( rRangeRepresentation, xSeq );
596 return xSeq;
599 void InternalDataProvider::createDefaultData()
601 m_aInternalData.createDefaultData();
604 // ____ XDataProvider ____
605 ::sal_Bool SAL_CALL InternalDataProvider::createDataSourcePossible( const Sequence< beans::PropertyValue >& /* aArguments */ )
606 throw (uno::RuntimeException)
608 return true;
611 namespace
614 sal_Int32 lcl_getInnerLevelCount( const vector< vector< uno::Any > >& rLabels )
616 sal_Int32 nCount = 1;//minimum is 1!
617 vector< vector< uno::Any > >::const_iterator aLevelIt( rLabels.begin() );
618 vector< vector< uno::Any > >::const_iterator aLevelEnd( rLabels.end() );
619 for( ;aLevelIt!=aLevelEnd; ++aLevelIt )
621 const vector< uno::Any >& rCurrentLevelLabels = *aLevelIt;
622 nCount = std::max<sal_Int32>( rCurrentLevelLabels.size(), nCount );
624 return nCount;
627 }//end anonymous namespace
629 Reference< chart2::data::XDataSource > SAL_CALL InternalDataProvider::createDataSource(
630 const Sequence< beans::PropertyValue >& aArguments )
631 throw (lang::IllegalArgumentException,
632 uno::RuntimeException)
634 OUString aRangeRepresentation;
635 bool bUseColumns = true;
636 bool bFirstCellAsLabel = true;
637 bool bHasCategories = true;
638 uno::Sequence< sal_Int32 > aSequenceMapping;
639 DataSourceHelper::readArguments( aArguments, aRangeRepresentation, aSequenceMapping, bUseColumns, bFirstCellAsLabel, bHasCategories );
641 if( aRangeRepresentation.equals( lcl_aCategoriesRangeName ) )
643 //return split complex categories if we have any:
644 ::std::vector< Reference< chart2::data::XLabeledDataSequence > > aComplexCategories;
645 vector< vector< uno::Any > > aCategories( m_bDataInColumns ? m_aInternalData.getComplexRowLabels() : m_aInternalData.getComplexColumnLabels());
646 if( bUseColumns==m_bDataInColumns )
648 sal_Int32 nLevelCount = lcl_getInnerLevelCount( aCategories );
649 for( sal_Int32 nL=0; nL<nLevelCount; nL++ )
650 aComplexCategories.push_back( new LabeledDataSequence(
651 new UncachedDataSequence( this
652 , lcl_aCategoriesLevelRangeNamePrefix + OUString::valueOf( nL )
653 , lcl_aCategoriesRoleName ) ) );
655 else
657 sal_Int32 nPointCount = m_bDataInColumns ? m_aInternalData.getRowCount() : m_aInternalData.getColumnCount();
658 for( sal_Int32 nP=0; nP<nPointCount; nP++ )
659 aComplexCategories.push_back( new LabeledDataSequence(
660 new UncachedDataSequence( this
661 , lcl_aCategoriesPointRangeNamePrefix + OUString::valueOf( nP )
662 , lcl_aCategoriesRoleName ) ) );
664 //don't add the created sequences to the map as they are used temporarily only ...
665 return new DataSource( ContainerHelper::ContainerToSequence(aComplexCategories) );
668 OSL_ASSERT( aRangeRepresentation.equals( lcl_aCompleteRange ));
670 ::std::vector< Reference< chart2::data::XLabeledDataSequence > > aResultLSeqVec;
672 // categories
673 if( bHasCategories )
674 aResultLSeqVec.push_back(
675 new LabeledDataSequence( lcl_createDataSequenceAndAddToMap( lcl_aCategoriesRangeName, lcl_aCategoriesRoleName ) ) );
677 // data with labels
678 ::std::vector< Reference< chart2::data::XLabeledDataSequence > > aDataVec;
679 const sal_Int32 nCount = (bUseColumns ? m_aInternalData.getColumnCount() : m_aInternalData.getRowCount());
680 for( sal_Int32 nIdx=0; nIdx<nCount; ++nIdx )
682 aDataVec.push_back(
683 new LabeledDataSequence(
684 lcl_createDataSequenceAndAddToMap( OUString::valueOf( nIdx )),
685 lcl_createDataSequenceAndAddToMap( lcl_aLabelRangePrefix + OUString::valueOf( nIdx ))));
688 // attention: this data provider has the limitation that it stores
689 // internally if data comes from columns or rows. It is intended for
690 // creating only one used data source.
691 // @todo: add this information in the range representation strings
692 m_bDataInColumns = bUseColumns;
694 //reorder labeled sequences according to aSequenceMapping; ignore categories
695 for( sal_Int32 nNewIndex = 0; nNewIndex < aSequenceMapping.getLength(); nNewIndex++ )
697 std::vector< LabeledDataSequence* >::size_type nOldIndex = aSequenceMapping[nNewIndex];
698 if( nOldIndex < aDataVec.size() )
700 if( aDataVec[nOldIndex].is() )
702 aResultLSeqVec.push_back( aDataVec[nOldIndex] );
703 aDataVec[nOldIndex] = 0;
708 //add left over data sequences to result
709 ::std::vector< Reference< chart2::data::XLabeledDataSequence > >::iterator aIt(aDataVec.begin());
710 const ::std::vector< Reference< chart2::data::XLabeledDataSequence > >::const_iterator aEndIt(aDataVec.end());
711 for( ;aIt!=aEndIt; ++aIt)
713 if( aIt->is() )
714 aResultLSeqVec.push_back( *aIt );
717 return new DataSource( ContainerHelper::ContainerToSequence(aResultLSeqVec) );
720 Sequence< beans::PropertyValue > SAL_CALL InternalDataProvider::detectArguments(
721 const Reference< chart2::data::XDataSource >& /* xDataSource */ )
722 throw (uno::RuntimeException)
724 Sequence< beans::PropertyValue > aArguments( 4 );
725 aArguments[0] = beans::PropertyValue(
726 C2U("CellRangeRepresentation"), -1, uno::makeAny( lcl_aCompleteRange ),
727 beans::PropertyState_DIRECT_VALUE );
728 aArguments[1] = beans::PropertyValue(
729 C2U("DataRowSource"), -1, uno::makeAny(
730 m_bDataInColumns
731 ? ::com::sun::star::chart::ChartDataRowSource_COLUMNS
732 : ::com::sun::star::chart::ChartDataRowSource_ROWS ),
733 beans::PropertyState_DIRECT_VALUE );
734 // internal data always contains labels and categories
735 aArguments[2] = beans::PropertyValue(
736 C2U("FirstCellAsLabel"), -1, uno::makeAny( true ), beans::PropertyState_DIRECT_VALUE );
737 aArguments[3] = beans::PropertyValue(
738 C2U("HasCategories"), -1, uno::makeAny( true ), beans::PropertyState_DIRECT_VALUE );
740 // #i85913# Sequence Mapping is not needed for internal data, as it is
741 // applied to the data when the data source is created.
743 return aArguments;
746 ::sal_Bool SAL_CALL InternalDataProvider::createDataSequenceByRangeRepresentationPossible( const OUString& /* aRangeRepresentation */ )
747 throw (uno::RuntimeException)
749 return true;
752 Reference< chart2::data::XDataSequence > SAL_CALL InternalDataProvider::createDataSequenceByRangeRepresentation(
753 const OUString& aRangeRepresentation )
754 throw (lang::IllegalArgumentException,
755 uno::RuntimeException)
757 if( aRangeRepresentation.match( lcl_aCategoriesRangeName ))
759 OSL_ASSERT( aRangeRepresentation.equals( lcl_aCategoriesRangeName ) );//it is not expected nor implmented that only parts of the categories are really requested
761 // categories
762 return lcl_createDataSequenceAndAddToMap( lcl_aCategoriesRangeName, lcl_aCategoriesRoleName );
764 else if( aRangeRepresentation.match( lcl_aLabelRangePrefix ))
766 // label
767 sal_Int32 nIndex = aRangeRepresentation.copy( lcl_aLabelRangePrefix.getLength()).toInt32();
768 return lcl_createDataSequenceAndAddToMap( lcl_aLabelRangePrefix + OUString::valueOf( nIndex ));
770 else if ( aRangeRepresentation == "last" )
772 sal_Int32 nIndex = (m_bDataInColumns
773 ? m_aInternalData.getColumnCount()
774 : m_aInternalData.getRowCount()) - 1;
775 return lcl_createDataSequenceAndAddToMap( OUString::valueOf( nIndex ));
777 else if( !aRangeRepresentation.isEmpty())
779 // data
780 return lcl_createDataSequenceAndAddToMap( aRangeRepresentation );
783 return Reference< chart2::data::XDataSequence >();
786 Reference< sheet::XRangeSelection > SAL_CALL InternalDataProvider::getRangeSelection()
787 throw (uno::RuntimeException)
789 // there is no range selection component
790 return Reference< sheet::XRangeSelection >();
793 // ____ XInternalDataProvider ____
794 ::sal_Bool SAL_CALL InternalDataProvider::hasDataByRangeRepresentation( const OUString& aRange )
795 throw (uno::RuntimeException)
797 sal_Bool bResult = false;
799 if( aRange.match( lcl_aCategoriesRangeName ))
801 OSL_ASSERT( aRange.equals( lcl_aCategoriesRangeName ) );//it is not expected nor implmented that only parts of the categories are really requested
802 bResult = true;
804 else if( aRange.match( lcl_aLabelRangePrefix ))
806 sal_Int32 nIndex = aRange.copy( lcl_aLabelRangePrefix.getLength()).toInt32();
807 bResult = (nIndex < (m_bDataInColumns ? m_aInternalData.getColumnCount(): m_aInternalData.getRowCount()));
809 else
811 sal_Int32 nIndex = aRange.toInt32();
812 bResult = (nIndex < (m_bDataInColumns ? m_aInternalData.getColumnCount(): m_aInternalData.getRowCount()));
815 return bResult;
818 Sequence< uno::Any > SAL_CALL InternalDataProvider::getDataByRangeRepresentation( const OUString& aRange )
819 throw (uno::RuntimeException)
821 Sequence< uno::Any > aResult;
823 if( aRange.match( lcl_aLabelRangePrefix ) )
825 sal_Int32 nIndex = aRange.copy( lcl_aLabelRangePrefix.getLength()).toInt32();
826 vector< uno::Any > aComplexLabel = m_bDataInColumns
827 ? m_aInternalData.getComplexColumnLabel( nIndex )
828 : m_aInternalData.getComplexRowLabel( nIndex );
829 if( !aComplexLabel.empty() )
830 aResult = ContainerHelper::ContainerToSequence(aComplexLabel);
832 else if( aRange.match( lcl_aCategoriesPointRangeNamePrefix ) )
834 sal_Int32 nPointIndex = aRange.copy( lcl_aCategoriesPointRangeNamePrefix.getLength() ).toInt32();
835 vector< uno::Any > aComplexCategory = m_bDataInColumns
836 ? m_aInternalData.getComplexRowLabel( nPointIndex )
837 : m_aInternalData.getComplexColumnLabel( nPointIndex );
838 if( !aComplexCategory.empty() )
839 aResult = ContainerHelper::ContainerToSequence(aComplexCategory);
841 else if( aRange.match( lcl_aCategoriesLevelRangeNamePrefix ) )
843 sal_Int32 nLevel = aRange.copy( lcl_aCategoriesLevelRangeNamePrefix.getLength() ).toInt32();
844 vector< vector< uno::Any > > aCategories( m_bDataInColumns ? m_aInternalData.getComplexRowLabels() : m_aInternalData.getComplexColumnLabels());
845 if( nLevel < lcl_getInnerLevelCount( aCategories ) )
847 aResult.realloc( aCategories.size() );
848 transform( aCategories.begin(), aCategories.end(),
849 aResult.getArray(), lcl_copyFromLevel(nLevel) );
852 else if( aRange.equals( lcl_aCategoriesRangeName ) )
854 vector< vector< uno::Any > > aCategories( m_bDataInColumns ? m_aInternalData.getComplexRowLabels() : m_aInternalData.getComplexColumnLabels());
855 sal_Int32 nLevelCount = lcl_getInnerLevelCount( aCategories );
856 if( nLevelCount == 1 )
858 sal_Int32 nL=0;
859 aResult = this->getDataByRangeRepresentation( lcl_aCategoriesLevelRangeNamePrefix + OUString::valueOf( nL ) );
861 else
863 Sequence< OUString > aLabels = m_bDataInColumns ? this->getRowDescriptions() : this->getColumnDescriptions();
864 aResult.realloc( aLabels.getLength() );
865 transform( aLabels.getConstArray(), aLabels.getConstArray() + aLabels.getLength(),
866 aResult.getArray(), CommonFunctors::makeAny< OUString >() );
869 else
871 sal_Int32 nIndex = aRange.toInt32();
872 if( nIndex >= 0 )
874 Sequence< double > aData;
875 if( m_bDataInColumns )
876 aData = m_aInternalData.getColumnValues(nIndex);
877 else
878 aData = m_aInternalData.getRowValues(nIndex);
879 if( aData.getLength() )
881 aResult.realloc( aData.getLength());
882 transform( aData.getConstArray(), aData.getConstArray() + aData.getLength(),
883 aResult.getArray(), CommonFunctors::makeAny< double >());
888 return aResult;
891 void SAL_CALL InternalDataProvider::setDataByRangeRepresentation(
892 const OUString& aRange, const Sequence< uno::Any >& aNewData )
893 throw (uno::RuntimeException)
895 vector< uno::Any > aNewVector( ContainerHelper::SequenceToVector(aNewData) );
896 if( aRange.match( lcl_aLabelRangePrefix ) )
898 sal_uInt32 nIndex = aRange.copy( lcl_aLabelRangePrefix.getLength()).toInt32();
899 if( m_bDataInColumns )
900 m_aInternalData.setComplexColumnLabel( nIndex, aNewVector );
901 else
902 m_aInternalData.setComplexRowLabel( nIndex, aNewVector );
904 else if( aRange.match( lcl_aCategoriesPointRangeNamePrefix ) )
906 sal_Int32 nPointIndex = aRange.copy( lcl_aCategoriesLevelRangeNamePrefix.getLength()).toInt32();
907 if( m_bDataInColumns )
908 m_aInternalData.setComplexRowLabel( nPointIndex, aNewVector );
909 else
910 m_aInternalData.setComplexColumnLabel( nPointIndex, aNewVector );
912 else if( aRange.match( lcl_aCategoriesLevelRangeNamePrefix ) )
914 sal_Int32 nLevel = aRange.copy( lcl_aCategoriesLevelRangeNamePrefix.getLength()).toInt32();
915 vector< vector< uno::Any > > aComplexCategories = m_bDataInColumns ? m_aInternalData.getComplexRowLabels() : m_aInternalData.getComplexColumnLabels();
917 //ensure equal length
918 if( aNewVector.size() > aComplexCategories.size() )
919 aComplexCategories.resize( aNewVector.size() );
920 else if( aNewVector.size() < aComplexCategories.size() )
921 aNewVector.resize( aComplexCategories.size() );
923 transform( aComplexCategories.begin(), aComplexCategories.end(), aNewVector.begin(),
924 aComplexCategories.begin(), lcl_setAnyAtLevel(nLevel) );
926 if( m_bDataInColumns )
927 m_aInternalData.setComplexRowLabels( aComplexCategories );
928 else
929 m_aInternalData.setComplexColumnLabels( aComplexCategories );
931 else if( aRange.equals( lcl_aCategoriesRangeName ) )
933 vector< vector< uno::Any > > aComplexCategories;
934 aComplexCategories.resize( aNewVector.size() );
935 transform( aComplexCategories.begin(), aComplexCategories.end(), aNewVector.begin(),
936 aComplexCategories.begin(), lcl_setAnyAtLevel(0) );
937 if( m_bDataInColumns )
938 m_aInternalData.setComplexRowLabels( aComplexCategories );
939 else
940 m_aInternalData.setComplexColumnLabels( aComplexCategories );
942 else
944 sal_Int32 nIndex = aRange.toInt32();
945 if( nIndex>=0 )
947 vector< double > aNewDataVec;
948 transform( aNewData.getConstArray(), aNewData.getConstArray() + aNewData.getLength(),
949 back_inserter( aNewDataVec ), CommonFunctors::AnyToDouble());
950 if( m_bDataInColumns )
951 m_aInternalData.setColumnValues( nIndex, aNewDataVec );
952 else
953 m_aInternalData.setRowValues( nIndex, aNewDataVec );
958 void SAL_CALL InternalDataProvider::insertSequence( ::sal_Int32 nAfterIndex )
959 throw (uno::RuntimeException)
961 if( m_bDataInColumns )
963 lcl_increaseMapReferences( nAfterIndex + 1, m_aInternalData.getColumnCount());
964 m_aInternalData.insertColumn( nAfterIndex );
966 else
968 lcl_increaseMapReferences( nAfterIndex + 1, m_aInternalData.getRowCount());
969 m_aInternalData.insertRow( nAfterIndex );
973 void SAL_CALL InternalDataProvider::deleteSequence( ::sal_Int32 nAtIndex )
974 throw (uno::RuntimeException)
976 lcl_deleteMapReferences( OUString::valueOf( nAtIndex ));
977 lcl_deleteMapReferences( lcl_aLabelRangePrefix + OUString::valueOf( nAtIndex ));
978 if( m_bDataInColumns )
980 lcl_decreaseMapReferences( nAtIndex + 1, m_aInternalData.getColumnCount());
981 m_aInternalData.deleteColumn( nAtIndex );
983 else
985 lcl_decreaseMapReferences( nAtIndex + 1, m_aInternalData.getRowCount());
986 m_aInternalData.deleteRow( nAtIndex );
990 void SAL_CALL InternalDataProvider::appendSequence()
991 throw (uno::RuntimeException)
993 if( m_bDataInColumns )
994 m_aInternalData.appendColumn();
995 else
996 m_aInternalData.appendRow();
999 void SAL_CALL InternalDataProvider::insertComplexCategoryLevel( sal_Int32 nLevel )
1000 throw (uno::RuntimeException)
1002 OSL_ENSURE( nLevel> 0, "you can only insert category levels > 0" );//the first categories level cannot be deleted, check the calling code for error
1003 if( nLevel>0 )
1005 vector< vector< uno::Any > > aComplexCategories = m_bDataInColumns ? m_aInternalData.getComplexRowLabels() : m_aInternalData.getComplexColumnLabels();
1006 ::std::for_each( aComplexCategories.begin(), aComplexCategories.end(), lcl_insertAnyAtLevel(nLevel) );
1007 if( m_bDataInColumns )
1008 m_aInternalData.setComplexRowLabels( aComplexCategories );
1009 else
1010 m_aInternalData.setComplexColumnLabels( aComplexCategories );
1012 tSequenceMapRange aRange( m_aSequenceMap.equal_range( lcl_aCategoriesRangeName ));
1013 ::std::for_each( aRange.first, aRange.second, lcl_setModified());
1016 void SAL_CALL InternalDataProvider::deleteComplexCategoryLevel( sal_Int32 nLevel )
1017 throw (uno::RuntimeException)
1019 OSL_ENSURE( nLevel>0, "you can only delete category levels > 0" );//the first categories level cannot be deleted, check the calling code for error
1020 if( nLevel>0 )
1022 vector< vector< uno::Any > > aComplexCategories = m_bDataInColumns ? m_aInternalData.getComplexRowLabels() : m_aInternalData.getComplexColumnLabels();
1023 ::std::for_each( aComplexCategories.begin(), aComplexCategories.end(), lcl_removeAnyAtLevel(nLevel) );
1024 if( m_bDataInColumns )
1025 m_aInternalData.setComplexRowLabels( aComplexCategories );
1026 else
1027 m_aInternalData.setComplexColumnLabels( aComplexCategories );
1029 tSequenceMapRange aRange( m_aSequenceMap.equal_range( lcl_aCategoriesRangeName ));
1030 ::std::for_each( aRange.first, aRange.second, lcl_setModified());
1034 void SAL_CALL InternalDataProvider::insertDataPointForAllSequences( ::sal_Int32 nAfterIndex )
1035 throw (uno::RuntimeException)
1037 sal_Int32 nMaxRep = 0;
1038 if( m_bDataInColumns )
1040 m_aInternalData.insertRow( nAfterIndex );
1041 nMaxRep = m_aInternalData.getColumnCount();
1043 else
1045 m_aInternalData.insertColumn( nAfterIndex );
1046 nMaxRep = m_aInternalData.getRowCount();
1049 // notify change to all affected ranges
1050 tSequenceMap::const_iterator aBegin( m_aSequenceMap.lower_bound( C2U("0")));
1051 tSequenceMap::const_iterator aEnd( m_aSequenceMap.upper_bound( OUString::valueOf( nMaxRep )));
1052 ::std::for_each( aBegin, aEnd, lcl_setModified());
1054 tSequenceMapRange aRange( m_aSequenceMap.equal_range( lcl_aCategoriesRangeName ));
1055 ::std::for_each( aRange.first, aRange.second, lcl_setModified());
1058 void SAL_CALL InternalDataProvider::deleteDataPointForAllSequences( ::sal_Int32 nAtIndex )
1059 throw (uno::RuntimeException)
1061 sal_Int32 nMaxRep = 0;
1062 if( m_bDataInColumns )
1064 m_aInternalData.deleteRow( nAtIndex );
1065 nMaxRep = m_aInternalData.getColumnCount();
1067 else
1069 m_aInternalData.deleteColumn( nAtIndex );
1070 nMaxRep = m_aInternalData.getRowCount();
1073 // notify change to all affected ranges
1074 tSequenceMap::const_iterator aBegin( m_aSequenceMap.lower_bound( C2U("0")));
1075 tSequenceMap::const_iterator aEnd( m_aSequenceMap.upper_bound( OUString::valueOf( nMaxRep )));
1076 ::std::for_each( aBegin, aEnd, lcl_setModified());
1078 tSequenceMapRange aRange( m_aSequenceMap.equal_range( lcl_aCategoriesRangeName ));
1079 ::std::for_each( aRange.first, aRange.second, lcl_setModified());
1082 void SAL_CALL InternalDataProvider::swapDataPointWithNextOneForAllSequences( ::sal_Int32 nAtIndex )
1083 throw (uno::RuntimeException)
1085 if( m_bDataInColumns )
1086 m_aInternalData.swapRowWithNext( nAtIndex );
1087 else
1088 m_aInternalData.swapColumnWithNext( nAtIndex );
1089 sal_Int32 nMaxRep = (m_bDataInColumns
1090 ? m_aInternalData.getColumnCount()
1091 : m_aInternalData.getRowCount());
1093 // notify change to all affected ranges
1094 tSequenceMap::const_iterator aBegin( m_aSequenceMap.lower_bound( C2U("0")));
1095 tSequenceMap::const_iterator aEnd( m_aSequenceMap.upper_bound( OUString::valueOf( nMaxRep )));
1096 ::std::for_each( aBegin, aEnd, lcl_setModified());
1098 tSequenceMapRange aRange( m_aSequenceMap.equal_range( lcl_aCategoriesRangeName ));
1099 ::std::for_each( aRange.first, aRange.second, lcl_setModified());
1102 void SAL_CALL InternalDataProvider::registerDataSequenceForChanges( const Reference< chart2::data::XDataSequence >& xSeq )
1103 throw (uno::RuntimeException)
1105 if( xSeq.is())
1106 lcl_addDataSequenceToMap( xSeq->getSourceRangeRepresentation(), xSeq );
1110 // ____ XRangeXMLConversion ____
1111 OUString SAL_CALL InternalDataProvider::convertRangeToXML( const OUString& aRangeRepresentation )
1112 throw (lang::IllegalArgumentException,
1113 uno::RuntimeException)
1115 XMLRangeHelper::CellRange aRange;
1116 aRange.aTableName = OUString(RTL_CONSTASCII_USTRINGPARAM("local-table"));
1118 // attention: this data provider has the limitation that it stores
1119 // internally if data comes from columns or rows. It is intended for
1120 // creating only one used data source.
1121 // @todo: add this information in the range representation strings
1122 if( aRangeRepresentation.match( lcl_aCategoriesRangeName ))
1124 OSL_ASSERT( aRangeRepresentation.equals( lcl_aCategoriesRangeName ) );//it is not expected nor implmented that only parts of the categories are really requested
1125 aRange.aUpperLeft.bIsEmpty = false;
1126 if( m_bDataInColumns )
1128 aRange.aUpperLeft.nColumn = 0;
1129 aRange.aUpperLeft.nRow = 1;
1130 aRange.aLowerRight = aRange.aUpperLeft;
1131 aRange.aLowerRight.nRow = m_aInternalData.getRowCount();
1133 else
1135 aRange.aUpperLeft.nColumn = 1;
1136 aRange.aUpperLeft.nRow = 0;
1137 aRange.aLowerRight = aRange.aUpperLeft;
1138 aRange.aLowerRight.nColumn = m_aInternalData.getColumnCount();
1141 else if( aRangeRepresentation.match( lcl_aLabelRangePrefix ))
1143 sal_Int32 nIndex = aRangeRepresentation.copy( lcl_aLabelRangePrefix.getLength()).toInt32();
1144 aRange.aUpperLeft.bIsEmpty = false;
1145 aRange.aLowerRight.bIsEmpty = true;
1146 if( m_bDataInColumns )
1148 aRange.aUpperLeft.nColumn = nIndex + 1;
1149 aRange.aUpperLeft.nRow = 0;
1151 else
1153 aRange.aUpperLeft.nColumn = 0;
1154 aRange.aUpperLeft.nRow = nIndex + 1;
1157 else if( aRangeRepresentation.equals( lcl_aCompleteRange ))
1159 aRange.aUpperLeft.bIsEmpty = false;
1160 aRange.aLowerRight.bIsEmpty = false;
1161 aRange.aUpperLeft.nColumn = 0;
1162 aRange.aUpperLeft.nRow = 0;
1163 aRange.aLowerRight.nColumn = m_aInternalData.getColumnCount();
1164 aRange.aLowerRight.nRow = m_aInternalData.getRowCount();
1166 else
1168 sal_Int32 nIndex = aRangeRepresentation.toInt32();
1169 aRange.aUpperLeft.bIsEmpty = false;
1170 if( m_bDataInColumns )
1172 aRange.aUpperLeft.nColumn = nIndex + 1;
1173 aRange.aUpperLeft.nRow = 1;
1174 aRange.aLowerRight = aRange.aUpperLeft;
1175 aRange.aLowerRight.nRow = m_aInternalData.getRowCount();
1177 else
1179 aRange.aUpperLeft.nColumn = 1;
1180 aRange.aUpperLeft.nRow = nIndex + 1;
1181 aRange.aLowerRight = aRange.aUpperLeft;
1182 aRange.aLowerRight.nColumn = m_aInternalData.getColumnCount();
1186 return XMLRangeHelper::getXMLStringFromCellRange( aRange );
1189 OUString SAL_CALL InternalDataProvider::convertRangeFromXML( const OUString& aXMLRange )
1190 throw (lang::IllegalArgumentException,
1191 uno::RuntimeException)
1193 XMLRangeHelper::CellRange aRange( XMLRangeHelper::getCellRangeFromXMLString( aXMLRange ));
1194 if( aRange.aUpperLeft.bIsEmpty )
1196 OSL_ENSURE( aRange.aLowerRight.bIsEmpty, "Weird Range" );
1197 return OUString();
1200 // "all"
1201 if( !aRange.aLowerRight.bIsEmpty &&
1202 ( aRange.aUpperLeft.nColumn != aRange.aLowerRight.nColumn ) &&
1203 ( aRange.aUpperLeft.nRow != aRange.aLowerRight.nRow ) )
1204 return lcl_aCompleteRange;
1206 // attention: this data provider has the limitation that it stores
1207 // internally if data comes from columns or rows. It is intended for
1208 // creating only one used data source.
1209 // @todo: add this information in the range representation strings
1211 // data in columns
1212 if( m_bDataInColumns )
1214 if( aRange.aUpperLeft.nColumn == 0 )
1215 return lcl_aCategoriesRangeName;
1216 if( aRange.aUpperLeft.nRow == 0 )
1217 return lcl_aLabelRangePrefix + OUString::valueOf( aRange.aUpperLeft.nColumn - 1 );
1219 return OUString::valueOf( aRange.aUpperLeft.nColumn - 1 );
1222 // data in rows
1223 if( aRange.aUpperLeft.nRow == 0 )
1224 return lcl_aCategoriesRangeName;
1225 if( aRange.aUpperLeft.nColumn == 0 )
1226 return lcl_aLabelRangePrefix + OUString::valueOf( aRange.aUpperLeft.nRow - 1 );
1228 return OUString::valueOf( aRange.aUpperLeft.nRow - 1 );
1231 namespace
1234 template< class Type >
1235 Sequence< Sequence< Type > > lcl_convertVectorVectorToSequenceSequence( const vector< vector< Type > >& rIn )
1237 Sequence< Sequence< Type > > aRet;
1238 sal_Int32 nOuterCount = rIn.size();
1239 if( nOuterCount )
1241 aRet.realloc(nOuterCount);
1242 for( sal_Int32 nN=0; nN<nOuterCount; nN++)
1243 aRet[nN]= ContainerHelper::ContainerToSequence( rIn[nN] );
1245 return aRet;
1248 template< class Type >
1249 vector< vector< Type > > lcl_convertSequenceSequenceToVectorVector( const Sequence< Sequence< Type > >& rIn )
1251 vector< vector< Type > > aRet;
1252 sal_Int32 nOuterCount = rIn.getLength();
1253 if( nOuterCount )
1255 aRet.resize(nOuterCount);
1256 for( sal_Int32 nN=0; nN<nOuterCount; nN++)
1257 aRet[nN]= ContainerHelper::SequenceToVector( rIn[nN] );
1259 return aRet;
1262 Sequence< Sequence< OUString > > lcl_convertComplexAnyVectorToStringSequence( const vector< vector< uno::Any > >& rIn )
1264 Sequence< Sequence< OUString > > aRet;
1265 sal_Int32 nOuterCount = rIn.size();
1266 if( nOuterCount )
1268 aRet.realloc(nOuterCount);
1269 for( sal_Int32 nN=0; nN<nOuterCount; nN++)
1270 aRet[nN]= lcl_AnyToStringSequence( ContainerHelper::ContainerToSequence( rIn[nN] ) );
1272 return aRet;
1275 vector< vector< uno::Any > > lcl_convertComplexStringSequenceToAnyVector( const Sequence< Sequence< OUString > >& rIn )
1277 vector< vector< uno::Any > > aRet;
1278 sal_Int32 nOuterCount = rIn.getLength();
1279 for( sal_Int32 nN=0; nN<nOuterCount; nN++)
1280 aRet.push_back( ContainerHelper::SequenceToVector( lcl_StringToAnySequence( rIn[nN] ) ) );
1281 return aRet;
1284 class SplitCategoriesProvider_ForComplexDescriptions : public SplitCategoriesProvider
1286 public:
1288 explicit SplitCategoriesProvider_ForComplexDescriptions( const ::std::vector< ::std::vector< uno::Any > >& rComplexDescriptions )
1289 : m_rComplexDescriptions( rComplexDescriptions )
1291 virtual ~SplitCategoriesProvider_ForComplexDescriptions()
1294 virtual sal_Int32 getLevelCount() const;
1295 virtual uno::Sequence< rtl::OUString > getStringsForLevel( sal_Int32 nIndex ) const;
1297 private:
1298 const ::std::vector< ::std::vector< uno::Any > >& m_rComplexDescriptions;
1301 sal_Int32 SplitCategoriesProvider_ForComplexDescriptions::getLevelCount() const
1303 return lcl_getInnerLevelCount( m_rComplexDescriptions );
1305 uno::Sequence< rtl::OUString > SplitCategoriesProvider_ForComplexDescriptions::getStringsForLevel( sal_Int32 nLevel ) const
1307 uno::Sequence< rtl::OUString > aResult;
1308 if( nLevel < lcl_getInnerLevelCount( m_rComplexDescriptions ) )
1310 aResult.realloc( m_rComplexDescriptions.size() );
1311 transform( m_rComplexDescriptions.begin(), m_rComplexDescriptions.end(),
1312 aResult.getArray(), lcl_getStringFromLevelVector(nLevel) );
1314 return aResult;
1317 }//anonymous namespace
1319 // ____ XDateCategories ____
1320 Sequence< double > SAL_CALL InternalDataProvider::getDateCategories() throw (uno::RuntimeException)
1322 double fNan = InternalDataProvider::getNotANumber();
1323 double fValue = fNan;
1324 vector< vector< uno::Any > > aCategories( m_bDataInColumns ? m_aInternalData.getComplexRowLabels() : m_aInternalData.getComplexColumnLabels());
1325 sal_Int32 nCount = aCategories.size();
1326 Sequence< double > aDoubles( nCount );
1327 vector< vector< uno::Any > >::iterator aIt( aCategories.begin() );
1328 vector< vector< uno::Any > >::const_iterator aEnd( aCategories.end() );
1329 for(sal_Int32 nN=0; nN<nCount && aIt!=aEnd; ++nN, ++aIt )
1331 if( !( !aIt->empty() && ((*aIt)[0]>>=fValue) ) )
1332 fValue = fNan;
1333 aDoubles[nN]=fValue;
1335 return aDoubles;
1338 void SAL_CALL InternalDataProvider::setDateCategories( const Sequence< double >& rDates ) throw (uno::RuntimeException)
1340 sal_Int32 nCount = rDates.getLength();
1341 vector< vector< uno::Any > > aNewCategories;
1342 aNewCategories.reserve(nCount);
1343 vector< uno::Any > aSingleLabel(1);
1345 for(sal_Int32 nN=0; nN<nCount; ++nN )
1347 aSingleLabel[0]=uno::makeAny(rDates[nN]);
1348 aNewCategories.push_back(aSingleLabel);
1351 if( m_bDataInColumns )
1352 m_aInternalData.setComplexRowLabels( aNewCategories );
1353 else
1354 m_aInternalData.setComplexColumnLabels( aNewCategories );
1357 // ____ XAnyDescriptionAccess ____
1358 Sequence< Sequence< uno::Any > > SAL_CALL InternalDataProvider::getAnyRowDescriptions() throw (uno::RuntimeException)
1360 return lcl_convertVectorVectorToSequenceSequence( m_aInternalData.getComplexRowLabels() );
1362 void SAL_CALL InternalDataProvider::setAnyRowDescriptions( const Sequence< Sequence< uno::Any > >& aRowDescriptions ) throw (uno::RuntimeException)
1364 m_aInternalData.setComplexRowLabels( lcl_convertSequenceSequenceToVectorVector( aRowDescriptions ) );
1366 Sequence< Sequence< uno::Any > > SAL_CALL InternalDataProvider::getAnyColumnDescriptions() throw (uno::RuntimeException)
1368 return lcl_convertVectorVectorToSequenceSequence( m_aInternalData.getComplexColumnLabels() );
1370 void SAL_CALL InternalDataProvider::setAnyColumnDescriptions( const Sequence< Sequence< uno::Any > >& aColumnDescriptions ) throw (uno::RuntimeException)
1372 m_aInternalData.setComplexColumnLabels( lcl_convertSequenceSequenceToVectorVector( aColumnDescriptions ) );
1375 // ____ XComplexDescriptionAccess ____
1376 Sequence< Sequence< OUString > > SAL_CALL InternalDataProvider::getComplexRowDescriptions() throw (uno::RuntimeException)
1378 return lcl_convertComplexAnyVectorToStringSequence( m_aInternalData.getComplexRowLabels() );
1380 void SAL_CALL InternalDataProvider::setComplexRowDescriptions( const Sequence< Sequence< ::rtl::OUString > >& aRowDescriptions ) throw (uno::RuntimeException)
1382 m_aInternalData.setComplexRowLabels( lcl_convertComplexStringSequenceToAnyVector(aRowDescriptions) );
1384 Sequence< Sequence< ::rtl::OUString > > SAL_CALL InternalDataProvider::getComplexColumnDescriptions() throw (uno::RuntimeException)
1386 return lcl_convertComplexAnyVectorToStringSequence( m_aInternalData.getComplexColumnLabels() );
1388 void SAL_CALL InternalDataProvider::setComplexColumnDescriptions( const Sequence< Sequence< ::rtl::OUString > >& aColumnDescriptions ) throw (uno::RuntimeException)
1390 m_aInternalData.setComplexColumnLabels( lcl_convertComplexStringSequenceToAnyVector(aColumnDescriptions) );
1393 // ____ XChartDataArray ____
1394 Sequence< Sequence< double > > SAL_CALL InternalDataProvider::getData()
1395 throw (uno::RuntimeException)
1397 return m_aInternalData.getData();
1400 void SAL_CALL InternalDataProvider::setData( const Sequence< Sequence< double > >& rDataInRows )
1401 throw (uno::RuntimeException)
1403 return m_aInternalData.setData( rDataInRows );
1406 void SAL_CALL InternalDataProvider::setRowDescriptions( const Sequence< OUString >& aRowDescriptions )
1407 throw (uno::RuntimeException)
1409 vector< vector< uno::Any > > aComplexDescriptions( aRowDescriptions.getLength() );
1410 transform( aComplexDescriptions.begin(), aComplexDescriptions.end(), aRowDescriptions.getConstArray(),
1411 aComplexDescriptions.begin(), lcl_setAnyAtLevelFromStringSequence(0) );
1412 m_aInternalData.setComplexRowLabels( aComplexDescriptions );
1415 void SAL_CALL InternalDataProvider::setColumnDescriptions( const Sequence< OUString >& aColumnDescriptions )
1416 throw (uno::RuntimeException)
1418 vector< vector< uno::Any > > aComplexDescriptions( aColumnDescriptions.getLength() );
1419 transform( aComplexDescriptions.begin(), aComplexDescriptions.end(), aColumnDescriptions.getConstArray(),
1420 aComplexDescriptions.begin(), lcl_setAnyAtLevelFromStringSequence(0) );
1421 m_aInternalData.setComplexColumnLabels( aComplexDescriptions );
1424 Sequence< OUString > SAL_CALL InternalDataProvider::getRowDescriptions()
1425 throw (uno::RuntimeException)
1427 vector< vector< uno::Any > > aComplexLabels( m_aInternalData.getComplexRowLabels() );
1428 SplitCategoriesProvider_ForComplexDescriptions aProvider( aComplexLabels );
1429 return ExplicitCategoriesProvider::getExplicitSimpleCategories( aProvider );
1432 Sequence< OUString > SAL_CALL InternalDataProvider::getColumnDescriptions()
1433 throw (uno::RuntimeException)
1435 vector< vector< uno::Any > > aComplexLabels( m_aInternalData.getComplexColumnLabels() );
1436 SplitCategoriesProvider_ForComplexDescriptions aProvider( aComplexLabels );
1437 return ExplicitCategoriesProvider::getExplicitSimpleCategories( aProvider );
1440 // ____ XChartData (base of XChartDataArray) ____
1441 void SAL_CALL InternalDataProvider::addChartDataChangeEventListener(
1442 const Reference< ::com::sun::star::chart::XChartDataChangeEventListener >& )
1443 throw (uno::RuntimeException)
1447 void SAL_CALL InternalDataProvider::removeChartDataChangeEventListener(
1448 const Reference< ::com::sun::star::chart::XChartDataChangeEventListener >& )
1449 throw (uno::RuntimeException)
1453 double SAL_CALL InternalDataProvider::getNotANumber()
1454 throw (uno::RuntimeException)
1456 double fNan;
1457 ::rtl::math::setNan( & fNan );
1458 return fNan;
1461 ::sal_Bool SAL_CALL InternalDataProvider::isNotANumber( double nNumber )
1462 throw (uno::RuntimeException)
1464 return ::rtl::math::isNan( nNumber )
1465 || ::rtl::math::isInf( nNumber );
1467 // lang::XInitialization:
1468 void SAL_CALL InternalDataProvider::initialize(const uno::Sequence< uno::Any > & _aArguments) throw (uno::RuntimeException, uno::Exception)
1470 comphelper::SequenceAsHashMap aArgs(_aArguments);
1471 if ( aArgs.getUnpackedValueOrDefault(::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("CreateDefaultData")),sal_False) )
1472 createDefaultData();
1474 // ____ XCloneable ____
1475 Reference< util::XCloneable > SAL_CALL InternalDataProvider::createClone()
1476 throw (uno::RuntimeException)
1478 return Reference< util::XCloneable >( new InternalDataProvider( *this ));
1482 // ================================================================================
1484 Sequence< OUString > InternalDataProvider::getSupportedServiceNames_Static()
1486 Sequence< OUString > aServices( 1 );
1487 aServices[ 0 ] = OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.chart2.data.DataProvider" ));
1488 return aServices;
1491 // ================================================================================
1493 APPHELPER_XSERVICEINFO_IMPL( InternalDataProvider, lcl_aServiceName );
1495 } // namespace chart
1497 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */