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>
34 #include "InternalDataProvider.hxx"
35 #include "LabeledDataSequence.hxx"
36 #include "DataSource.hxx"
37 #include "PropertyHelper.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>
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
;
70 // ================================================================================
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
> >
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() );
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
>() );
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
);
121 Reference
< util::XModifiable
> xMod( xSeq
, uno::UNO_QUERY
);
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
;
157 ::std::vector
< double > aValues( ContainerHelper::SequenceToVector( xValues
->getNumericalData()));
158 if( m_bDataInColumns
)
159 m_rInternalData
.setColumnValues( nNewIndex
, aValues
);
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
));
173 if( m_bDataInColumns
)
174 m_rInternalData
.setComplexColumnLabel( nNewIndex
, ContainerHelper::SequenceToVector( lcl_StringToAnySequence( xLabel
->getTextualData() ) ) );
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
));
190 if( m_bConnectToModel
)
191 aNewSeriesData
[i
] = Reference
< chart2::data::XLabeledDataSequence
>(
192 new LabeledDataSequence( xNewValues
));
195 if( m_bConnectToModel
)
196 xSink
->setData( aNewSeriesData
);
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
>
211 explicit lcl_copyFromLevel( sal_Int32 nLevel
) : m_nLevel( nLevel
)
214 uno::Any
operator() ( const vector
< uno::Any
>& rVector
)
217 if( m_nLevel
< static_cast< sal_Int32
>(rVector
.size()) )
218 aRet
= rVector
[m_nLevel
];
226 struct lcl_getStringFromLevelVector
: public ::std::unary_function
< vector
< uno::Any
>, OUString
>
230 explicit lcl_getStringFromLevelVector( sal_Int32 nLevel
) : m_nLevel( nLevel
)
233 OUString
operator() ( const vector
< uno::Any
>& rVector
)
236 if( m_nLevel
< static_cast< sal_Int32
>(rVector
.size()) )
237 aString
= CommonFunctors::AnyToString()(rVector
[m_nLevel
]);
246 struct lcl_setAnyAtLevel
: public ::std::binary_function
< vector
< uno::Any
>, uno::Any
, vector
< uno::Any
> >
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
;
266 struct lcl_setAnyAtLevelFromStringSequence
: public ::std::binary_function
< vector
< uno::Any
>, OUString
, vector
< uno::Any
> >
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
);
286 struct lcl_insertAnyAtLevel
: public ::std::unary_function
< vector
< uno::Any
>, void >
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
++)
304 rVector
.insert( aIt
, uno::Any() );
311 struct lcl_removeAnyAtLevel
: public ::std::unary_function
< vector
< uno::Any
>, void >
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
++)
325 rVector
.erase( aIt
);
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
) );
351 Reference
< frame::XModel
> xChartModel( xChartDoc
, uno::UNO_QUERY
);
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
);
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
] );
375 Sequence
< uno::Any
> aDataSeq
;
376 Reference
< chart2::data::XDataSequence
> xSeq( xLDS
->getValues() );
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
) );
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
);
405 m_aInternalData
.setComplexColumnLabels( aNewCategories
);
406 if( bConnectToModel
)
407 DiagramHelper::setCategoriesToDiagram( new LabeledDataSequence(
408 createDataSequenceByRangeRepresentation( lcl_aCategoriesRangeName
)), xDiagram
);
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
);
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
);
452 Reference
< container::XNamed
> xNamed( xSeq
, uno::UNO_QUERY
);
454 xNamed
->setName( OUString());
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
);
472 Reference
< container::XNamed
> xNamed( xSeq
, uno::UNO_QUERY
);
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
;
519 sal_Int32 nCategories
= 0;
520 sal_Int32 nIndex
= 0;
522 bool bLabelSet
= false;
523 OUString str
= aRangeRepresentation
.replace('{',' ').replace('}',' ');
525 m_aInternalData
.clearDefaultData();
526 sal_Int32 n
= m_aInternalData
.getColumnCount();
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() )
537 if( aToken
.indexOf('"') < 0 )
539 aNewData
.push_back( aToken
.toDouble() );
543 aNewLabels
.push_back( uno::makeAny(aToken
.replace('"', ' ').trim()) );
545 ( !m_aInternalData
.getComplexColumnLabel(n
).size() ||
546 !m_aInternalData
.getComplexColumnLabel(n
).front().hasValue() ) )
548 m_aInternalData
.setComplexColumnLabel( n
, aNewLabels
);
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();
565 } while( nIndex
>= 0 );
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
;
579 aRangeRepresentation
= lcl_aLabelRangePrefix
+OUString::valueOf( n
);
583 Reference
< chart2::data::XDataSequence
> xSeq(
584 new UncachedDataSequence( this, aRangeRepresentation
));
585 lcl_addDataSequenceToMap( aRangeRepresentation
, 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
);
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
)
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
);
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
) ) );
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
;
674 aResultLSeqVec
.push_back(
675 new LabeledDataSequence( lcl_createDataSequenceAndAddToMap( lcl_aCategoriesRangeName
, lcl_aCategoriesRoleName
) ) );
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
)
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
)
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(
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.
746 ::sal_Bool SAL_CALL
InternalDataProvider::createDataSequenceByRangeRepresentationPossible( const OUString
& /* aRangeRepresentation */ )
747 throw (uno::RuntimeException
)
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
762 return lcl_createDataSequenceAndAddToMap( lcl_aCategoriesRangeName
, lcl_aCategoriesRoleName
);
764 else if( aRangeRepresentation
.match( lcl_aLabelRangePrefix
))
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())
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
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()));
811 sal_Int32 nIndex
= aRange
.toInt32();
812 bResult
= (nIndex
< (m_bDataInColumns
? m_aInternalData
.getColumnCount(): m_aInternalData
.getRowCount()));
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 )
859 aResult
= this->getDataByRangeRepresentation( lcl_aCategoriesLevelRangeNamePrefix
+ OUString::valueOf( nL
) );
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
>() );
871 sal_Int32 nIndex
= aRange
.toInt32();
874 Sequence
< double > aData
;
875 if( m_bDataInColumns
)
876 aData
= m_aInternalData
.getColumnValues(nIndex
);
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 >());
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
);
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
);
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
);
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
);
940 m_aInternalData
.setComplexColumnLabels( aComplexCategories
);
944 sal_Int32 nIndex
= aRange
.toInt32();
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
);
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
);
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
);
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();
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
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
);
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
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
);
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();
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();
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
);
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
)
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();
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;
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();
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();
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" );
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
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 );
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 );
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();
1241 aRet
.realloc(nOuterCount
);
1242 for( sal_Int32 nN
=0; nN
<nOuterCount
; nN
++)
1243 aRet
[nN
]= ContainerHelper::ContainerToSequence( rIn
[nN
] );
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();
1255 aRet
.resize(nOuterCount
);
1256 for( sal_Int32 nN
=0; nN
<nOuterCount
; nN
++)
1257 aRet
[nN
]= ContainerHelper::SequenceToVector( rIn
[nN
] );
1262 Sequence
< Sequence
< OUString
> > lcl_convertComplexAnyVectorToStringSequence( const vector
< vector
< uno::Any
> >& rIn
)
1264 Sequence
< Sequence
< OUString
> > aRet
;
1265 sal_Int32 nOuterCount
= rIn
.size();
1268 aRet
.realloc(nOuterCount
);
1269 for( sal_Int32 nN
=0; nN
<nOuterCount
; nN
++)
1270 aRet
[nN
]= lcl_AnyToStringSequence( ContainerHelper::ContainerToSequence( rIn
[nN
] ) );
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
] ) ) );
1284 class SplitCategoriesProvider_ForComplexDescriptions
: public SplitCategoriesProvider
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;
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
) );
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
) ) )
1333 aDoubles
[nN
]=fValue
;
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
);
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
)
1457 ::rtl::math::setNan( & 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" ));
1491 // ================================================================================
1493 APPHELPER_XSERVICEINFO_IMPL( InternalDataProvider
, lcl_aServiceName
);
1495 } // namespace chart
1497 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */