xref: /AOO41X/main/chart2/source/tools/InternalDataProvider.cxx (revision cdf0e10c4e3984b49a9502b011690b615761d4a3)
1 /*************************************************************************
2  *
3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4  *
5  * Copyright 2000, 2010 Oracle and/or its affiliates.
6  *
7  * OpenOffice.org - a multi-platform office productivity suite
8  *
9  * This file is part of OpenOffice.org.
10  *
11  * OpenOffice.org is free software: you can redistribute it and/or modify
12  * it under the terms of the GNU Lesser General Public License version 3
13  * only, as published by the Free Software Foundation.
14  *
15  * OpenOffice.org is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18  * GNU Lesser General Public License version 3 for more details
19  * (a copy is included in the LICENSE file that accompanied this code).
20  *
21  * You should have received a copy of the GNU Lesser General Public License
22  * version 3 along with OpenOffice.org.  If not, see
23  * <http://www.openoffice.org/license.html>
24  * for a copy of the LGPLv3 License.
25  *
26  ************************************************************************/
27 
28 
29 // MARKER(update_precomp.py): autogen include statement, do not remove
30 #include "precompiled_chart2.hxx"
31 #include <rtl/math.hxx>
32 
33 #include <valarray>
34 
35 #include "InternalDataProvider.hxx"
36 #include "LabeledDataSequence.hxx"
37 #include "DataSource.hxx"
38 #include "PropertyHelper.hxx"
39 #include "macros.hxx"
40 #include "XMLRangeHelper.hxx"
41 #include "ContainerHelper.hxx"
42 #include "CommonConverters.hxx"
43 #include "CommonFunctors.hxx"
44 #include "UncachedDataSequence.hxx"
45 #include "DataSourceHelper.hxx"
46 #include "ChartModelHelper.hxx"
47 #include "DiagramHelper.hxx"
48 #include "ExplicitCategoriesProvider.hxx"
49 
50 #include <com/sun/star/chart2/XChartDocument.hpp>
51 #include <com/sun/star/chart2/data/XDataSequence.hpp>
52 #include <com/sun/star/chart/ChartDataRowSource.hpp>
53 #include <rtl/ustrbuf.hxx>
54 #include <unotools/charclass.hxx>
55 #include <comphelper/sequenceashashmap.hxx>
56 
57 #include <vector>
58 #include <algorithm>
59 
60 using namespace ::com::sun::star;
61 using namespace ::std;
62 
63 using ::com::sun::star::uno::Reference;
64 using ::com::sun::star::uno::Sequence;
65 using ::rtl::OUString;
66 using ::rtl::OUStringBuffer;
67 
68 namespace chart
69 {
70 
71 // ================================================================================
72 
73 namespace
74 {
75 
76 // note: in xmloff this name is used to indicate usage of own data
77 static const ::rtl::OUString lcl_aServiceName(
78     RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.comp.chart.InternalDataProvider" ));
79 
80 static const ::rtl::OUString lcl_aCategoriesRangeName(
81     RTL_CONSTASCII_USTRINGPARAM( "categories" ));
82 static const ::rtl::OUString lcl_aCategoriesLevelRangeNamePrefix(
83     RTL_CONSTASCII_USTRINGPARAM( "categoriesL " )); //L <-> level
84 static const ::rtl::OUString lcl_aCategoriesPointRangeNamePrefix(
85     RTL_CONSTASCII_USTRINGPARAM( "categoriesP " )); //P <-> point
86 static const ::rtl::OUString lcl_aCategoriesRoleName(
87     RTL_CONSTASCII_USTRINGPARAM( "categories" ));
88 static const ::rtl::OUString lcl_aLabelRangePrefix(
89     RTL_CONSTASCII_USTRINGPARAM( "label " ));
90 static const ::rtl::OUString lcl_aCompleteRange(
91     RTL_CONSTASCII_USTRINGPARAM( "all" ));
92 
93 typedef ::std::multimap< OUString, uno::WeakReference< chart2::data::XDataSequence > >
94     lcl_tSequenceMap;
95 
96 Sequence< OUString > lcl_AnyToStringSequence( const Sequence< uno::Any >& aAnySeq )
97 {
98     Sequence< OUString > aResult;
99     aResult.realloc( aAnySeq.getLength() );
100     transform( aAnySeq.getConstArray(), aAnySeq.getConstArray() + aAnySeq.getLength(),
101                aResult.getArray(), CommonFunctors::AnyToString() );
102     return aResult;
103 }
104 
105 Sequence< uno::Any > lcl_StringToAnySequence( const Sequence< OUString >& aStringSeq )
106 {
107     Sequence< uno::Any > aResult;
108     aResult.realloc( aStringSeq.getLength() );
109     transform( aStringSeq.getConstArray(), aStringSeq.getConstArray() + aStringSeq.getLength(),
110                aResult.getArray(), CommonFunctors::makeAny< OUString >() );
111     return aResult;
112 }
113 
114 struct lcl_setModified : public ::std::unary_function< lcl_tSequenceMap, void >
115 {
116     void operator() ( const lcl_tSequenceMap::value_type & rMapEntry )
117     {
118         // convert weak reference to reference
119         Reference< chart2::data::XDataSequence > xSeq( rMapEntry.second );
120         if( xSeq.is())
121         {
122             Reference< util::XModifiable > xMod( xSeq, uno::UNO_QUERY );
123             if( xMod.is())
124                 xMod->setModified( sal_True );
125         }
126     }
127 };
128 
129 struct lcl_internalizeSeries : public ::std::unary_function< Reference< chart2::XDataSeries >, void >
130 {
131     lcl_internalizeSeries( InternalData & rInternalData,
132                            InternalDataProvider & rProvider,
133                            bool bConnectToModel, bool bDataInColumns ) :
134             m_rInternalData( rInternalData ),
135             m_rProvider( rProvider ),
136             m_bConnectToModel( bConnectToModel ),
137             m_bDataInColumns( bDataInColumns )
138     {}
139     void operator() ( const Reference< chart2::XDataSeries > & xSeries )
140     {
141         Reference< chart2::data::XDataSource > xSource( xSeries, uno::UNO_QUERY );
142         Reference< chart2::data::XDataSink >   xSink(   xSeries, uno::UNO_QUERY );
143         if( xSource.is() && xSink.is() )
144         {
145             Sequence< Reference< chart2::data::XLabeledDataSequence > > aOldSeriesData = xSource->getDataSequences();
146             Sequence< Reference< chart2::data::XLabeledDataSequence > > aNewSeriesData( aOldSeriesData.getLength() );
147             for( sal_Int32 i=0; i<aOldSeriesData.getLength(); ++i )
148             {
149                 sal_Int32 nNewIndex( m_bDataInColumns ? m_rInternalData.appendColumn() : m_rInternalData.appendRow() );
150                 OUString aIdentifier( OUString::valueOf( nNewIndex ));
151                 //@todo: deal also with genericXDataSequence
152                 Reference< chart2::data::XNumericalDataSequence > xValues( aOldSeriesData[i]->getValues(), uno::UNO_QUERY );
153                 Reference< chart2::data::XTextualDataSequence > xLabel( aOldSeriesData[i]->getLabel(), uno::UNO_QUERY );
154                 Reference< chart2::data::XDataSequence > xNewValues;
155 
156                 if( xValues.is() )
157                 {
158                     ::std::vector< double > aValues( ContainerHelper::SequenceToVector( xValues->getNumericalData()));
159                     if( m_bDataInColumns )
160                         m_rInternalData.setColumnValues( nNewIndex, aValues );
161                     else
162                         m_rInternalData.setRowValues( nNewIndex, aValues );
163                     if( m_bConnectToModel )
164                     {
165                         xNewValues.set( m_rProvider.createDataSequenceByRangeRepresentation( aIdentifier ));
166                         comphelper::copyProperties(
167                             Reference< beans::XPropertySet >( xValues, uno::UNO_QUERY ),
168                             Reference< beans::XPropertySet >( xNewValues, uno::UNO_QUERY ));
169                     }
170                 }
171 
172                 if( xLabel.is() )
173                 {
174                     if( m_bDataInColumns )
175                         m_rInternalData.setComplexColumnLabel( nNewIndex, ContainerHelper::SequenceToVector( lcl_StringToAnySequence( xLabel->getTextualData() ) ) );
176                     else
177                         m_rInternalData.setComplexRowLabel( nNewIndex, ContainerHelper::SequenceToVector( lcl_StringToAnySequence( xLabel->getTextualData() ) ) );
178                     if( m_bConnectToModel )
179                     {
180                         Reference< chart2::data::XDataSequence > xNewLabel(
181                             m_rProvider.createDataSequenceByRangeRepresentation( lcl_aLabelRangePrefix + aIdentifier ));
182                         comphelper::copyProperties(
183                             Reference< beans::XPropertySet >( xLabel, uno::UNO_QUERY ),
184                             Reference< beans::XPropertySet >( xNewLabel, uno::UNO_QUERY ));
185                         aNewSeriesData[i] = Reference< chart2::data::XLabeledDataSequence >(
186                                 new LabeledDataSequence( xNewValues, xNewLabel ));
187                     }
188                 }
189                 else
190                 {
191                     if( m_bConnectToModel )
192                         aNewSeriesData[i] = Reference< chart2::data::XLabeledDataSequence >(
193                             new LabeledDataSequence( xNewValues ));
194                 }
195             }
196             if( m_bConnectToModel )
197                 xSink->setData( aNewSeriesData );
198         }
199      }
200 
201 private:
202     InternalData &          m_rInternalData;
203     InternalDataProvider &  m_rProvider;
204     bool                    m_bConnectToModel;
205     bool                    m_bDataInColumns;
206 };
207 
208 struct lcl_copyFromLevel : public ::std::unary_function< vector< uno::Any >, uno::Any >
209 {
210 public:
211 
212     explicit lcl_copyFromLevel( sal_Int32 nLevel ) : m_nLevel( nLevel )
213     {}
214 
215     uno::Any operator() ( const vector< uno::Any >& rVector )
216     {
217         uno::Any aRet;
218         if( m_nLevel <  static_cast< sal_Int32 >(rVector.size()) )
219             aRet = rVector[m_nLevel];
220         return aRet;
221     }
222 
223 private:
224     sal_Int32 m_nLevel;
225 };
226 
227 struct lcl_getStringFromLevelVector : public ::std::unary_function< vector< uno::Any >, OUString >
228 {
229 public:
230 
231     explicit lcl_getStringFromLevelVector( sal_Int32 nLevel ) : m_nLevel( nLevel )
232     {}
233 
234     OUString operator() ( const vector< uno::Any >& rVector )
235     {
236         OUString aString;
237         if( m_nLevel < static_cast< sal_Int32 >(rVector.size()) )
238             aString = CommonFunctors::AnyToString()(rVector[m_nLevel]);
239         return aString;
240     }
241 
242 private:
243     sal_Int32 m_nLevel;
244 };
245 
246 
247 struct lcl_setAnyAtLevel : public ::std::binary_function< vector< uno::Any >, uno::Any, vector< uno::Any > >
248 {
249 public:
250 
251     explicit lcl_setAnyAtLevel( sal_Int32 nLevel ) : m_nLevel( nLevel )
252     {}
253 
254     vector< uno::Any > operator() ( const vector< uno::Any >& rVector, const uno::Any& rNewValue )
255     {
256         vector< uno::Any > aRet( rVector );
257         if( m_nLevel >= static_cast< sal_Int32 >(aRet.size()) )
258             aRet.resize( m_nLevel+1 );
259         aRet[ m_nLevel ]=rNewValue;
260         return aRet;
261     }
262 
263 private:
264     sal_Int32 m_nLevel;
265 };
266 
267 struct lcl_setAnyAtLevelFromStringSequence : public ::std::binary_function< vector< uno::Any >, OUString, vector< uno::Any > >
268 {
269 public:
270 
271     explicit lcl_setAnyAtLevelFromStringSequence( sal_Int32 nLevel ) : m_nLevel( nLevel )
272     {}
273 
274     vector< uno::Any > operator() ( const vector< uno::Any >& rVector, const OUString& rNewValue )
275     {
276         vector< uno::Any > aRet( rVector );
277         if( m_nLevel >= static_cast< sal_Int32 >(aRet.size()) )
278             aRet.resize( m_nLevel+1 );
279         aRet[ m_nLevel ]=uno::makeAny(rNewValue);
280         return aRet;
281     }
282 
283 private:
284     sal_Int32 m_nLevel;
285 };
286 
287 struct lcl_insertAnyAtLevel : public ::std::unary_function< vector< uno::Any >, void >
288 {
289 public:
290 
291     explicit lcl_insertAnyAtLevel( sal_Int32 nLevel ) : m_nLevel( nLevel )
292     {}
293 
294     void operator() ( vector< uno::Any >& rVector )
295     {
296         if( m_nLevel > static_cast< sal_Int32 >(rVector.size()) )
297             rVector.resize( m_nLevel );
298 
299         vector< uno::Any >::iterator aIt( rVector.begin() );
300         for( sal_Int32 nN=0; aIt<rVector.end(); aIt++, nN++)
301         {
302             if( nN==m_nLevel )
303                 break;
304         }
305         rVector.insert( aIt, uno::Any() );
306     }
307 
308 private:
309     sal_Int32 m_nLevel;
310 };
311 
312 struct lcl_removeAnyAtLevel : public ::std::unary_function< vector< uno::Any >, void >
313 {
314 public:
315 
316     explicit lcl_removeAnyAtLevel( sal_Int32 nLevel ) : m_nLevel( nLevel )
317     {}
318 
319     void operator() ( vector< uno::Any >& rVector )
320     {
321         vector< uno::Any >::iterator aIt( rVector.begin() );
322         for( sal_Int32 nN=0; aIt<rVector.end(); aIt++, nN++)
323         {
324             if( nN==m_nLevel )
325             {
326                 rVector.erase( aIt );
327                 break;
328             }
329         }
330     }
331 
332 private:
333     sal_Int32 m_nLevel;
334 };
335 
336 } // anonymous namespace
337 
338 // ================================================================================
339 
340 InternalDataProvider::InternalDataProvider( const Reference< uno::XComponentContext > & /*_xContext*/)
341     : m_bDataInColumns( true )
342 {}
343 
344 InternalDataProvider::InternalDataProvider( const Reference< chart2::XChartDocument > & xChartDoc, bool bConnectToModel )
345     : m_bDataInColumns( true )
346 {
347     try
348     {
349         Reference< chart2::XDiagram > xDiagram( ChartModelHelper::findDiagram( xChartDoc ) );
350         if( xDiagram.is())
351         {
352             Reference< frame::XModel > xChartModel( xChartDoc, uno::UNO_QUERY );
353 
354             //data in columns?
355             {
356                 ::rtl::OUString aRangeString;
357                 bool bFirstCellAsLabel = true;
358                 bool bHasCategories = true;
359                 uno::Sequence< sal_Int32 > aSequenceMapping;
360                 DataSourceHelper::detectRangeSegmentation( xChartModel, aRangeString, aSequenceMapping, m_bDataInColumns, bFirstCellAsLabel, bHasCategories );
361             }
362 
363             // categories
364             {
365                 vector< vector< uno::Any > > aNewCategories;//inner count is level
366                 {
367                     ExplicitCategoriesProvider aExplicitCategoriesProvider( ChartModelHelper::getFirstCoordinateSystem(xChartModel), xChartModel );
368 
369                     const Sequence< Reference< chart2::data::XLabeledDataSequence> >& rSplitCategoriesList( aExplicitCategoriesProvider.getSplitCategoriesList() );
370                     sal_Int32 nLevelCount = rSplitCategoriesList.getLength();
371                     for( sal_Int32 nL = 0; nL<nLevelCount; nL++ )
372                     {
373                         Reference< chart2::data::XLabeledDataSequence > xLDS( rSplitCategoriesList[nL] );
374                         if( !xLDS.is() )
375                             continue;
376                         Sequence< uno::Any > aDataSeq;
377                         Reference< chart2::data::XDataSequence > xSeq( xLDS->getValues() );
378                         if( xSeq.is() )
379                             aDataSeq = xSeq->getData();
380                         sal_Int32 nLength = aDataSeq.getLength();
381                         sal_Int32 nCatLength = static_cast< sal_Int32 >(aNewCategories.size());
382                         if( nCatLength < nLength )
383                             aNewCategories.resize( nLength );
384                         else if( nLength < nCatLength )
385                             aDataSeq.realloc( nCatLength );
386                         transform( aNewCategories.begin(), aNewCategories.end(), aDataSeq.getConstArray(),
387                             aNewCategories.begin(), lcl_setAnyAtLevel(nL) );
388                     }
389                     if( !nLevelCount )
390                     {
391                         Sequence< OUString > aSimplecategories = aExplicitCategoriesProvider.getSimpleCategories();
392                         sal_Int32 nLength = aSimplecategories.getLength();
393                         aNewCategories.reserve( nLength );
394                         for( sal_Int32 nN=0; nN<nLength; nN++)
395                         {
396                             vector< uno::Any > aVector(1);
397                             aVector[0] = uno::makeAny( aSimplecategories[nN] );
398                             aNewCategories.push_back( aVector );
399                         }
400                     }
401                 }
402 
403                 if( m_bDataInColumns )
404                     m_aInternalData.setComplexRowLabels( aNewCategories );
405                 else
406                     m_aInternalData.setComplexColumnLabels( aNewCategories );
407                 if( bConnectToModel )
408                     DiagramHelper::setCategoriesToDiagram( new LabeledDataSequence(
409                         createDataSequenceByRangeRepresentation( lcl_aCategoriesRangeName )), xDiagram );
410             }
411 
412             // data series
413             ::std::vector< Reference< chart2::XDataSeries > > aSeriesVector( ChartModelHelper::getDataSeries( xChartDoc ));
414             ::std::for_each( aSeriesVector.begin(), aSeriesVector.end(), lcl_internalizeSeries( m_aInternalData, *this, bConnectToModel, m_bDataInColumns ) );
415         }
416     }
417     catch( const uno::Exception & ex )
418     {
419         ASSERT_EXCEPTION( ex );
420     }
421 }
422 
423 // copy-CTOR
424 InternalDataProvider::InternalDataProvider( const InternalDataProvider & rOther ) :
425         impl::InternalDataProvider_Base(),
426         m_aSequenceMap( rOther.m_aSequenceMap ),
427         m_aInternalData( rOther.m_aInternalData ),
428         m_bDataInColumns( rOther.m_bDataInColumns )
429 {}
430 
431 InternalDataProvider::~InternalDataProvider()
432 {}
433 
434 void InternalDataProvider::lcl_addDataSequenceToMap(
435     const OUString & rRangeRepresentation,
436     const Reference< chart2::data::XDataSequence > & xSequence )
437 {
438     m_aSequenceMap.insert(
439         tSequenceMap::value_type(
440             rRangeRepresentation,
441             uno::WeakReference< chart2::data::XDataSequence >( xSequence )));
442 }
443 
444 void InternalDataProvider::lcl_deleteMapReferences( const OUString & rRangeRepresentation )
445 {
446     // set sequence to deleted by setting its range to an empty string
447     tSequenceMapRange aRange( m_aSequenceMap.equal_range( rRangeRepresentation ));
448     for( tSequenceMap::iterator aIt( aRange.first ); aIt != aRange.second; ++aIt )
449     {
450         Reference< chart2::data::XDataSequence > xSeq( aIt->second );
451         if( xSeq.is())
452         {
453             Reference< container::XNamed > xNamed( xSeq, uno::UNO_QUERY );
454             if( xNamed.is())
455                 xNamed->setName( OUString());
456         }
457     }
458     // remove from map
459     m_aSequenceMap.erase( aRange.first, aRange.second );
460 }
461 
462 void InternalDataProvider::lcl_adaptMapReferences(
463     const OUString & rOldRangeRepresentation,
464     const OUString & rNewRangeRepresentation )
465 {
466     tSequenceMapRange aRange( m_aSequenceMap.equal_range( rOldRangeRepresentation ));
467     tSequenceMap aNewElements;
468     for( tSequenceMap::iterator aIt( aRange.first ); aIt != aRange.second; ++aIt )
469     {
470         Reference< chart2::data::XDataSequence > xSeq( aIt->second );
471         if( xSeq.is())
472         {
473             Reference< container::XNamed > xNamed( xSeq, uno::UNO_QUERY );
474             if( xNamed.is())
475                 xNamed->setName( rNewRangeRepresentation );
476         }
477         aNewElements.insert( tSequenceMap::value_type( rNewRangeRepresentation, aIt->second ));
478     }
479     // erase map values for old index
480     m_aSequenceMap.erase( aRange.first, aRange.second );
481     // add new entries for values with new index
482     ::std::copy( aNewElements.begin(), aNewElements.end(),
483                  ::std::inserter( m_aSequenceMap,
484                                   m_aSequenceMap.upper_bound( rNewRangeRepresentation )));
485 }
486 
487 void InternalDataProvider::lcl_increaseMapReferences(
488     sal_Int32 nBegin, sal_Int32 nEnd )
489 {
490     for( sal_Int32 nIndex = nEnd - 1; nIndex >= nBegin; --nIndex )
491     {
492         lcl_adaptMapReferences( OUString::valueOf( nIndex ),
493                             OUString::valueOf( nIndex + 1 ));
494         lcl_adaptMapReferences( lcl_aLabelRangePrefix + OUString::valueOf( nIndex ),
495                             lcl_aLabelRangePrefix + OUString::valueOf( nIndex + 1 ));
496     }
497 }
498 
499 void InternalDataProvider::lcl_decreaseMapReferences(
500     sal_Int32 nBegin, sal_Int32 nEnd )
501 {
502     for( sal_Int32 nIndex = nBegin; nIndex < nEnd; ++nIndex )
503     {
504         lcl_adaptMapReferences( OUString::valueOf( nIndex ),
505                             OUString::valueOf( nIndex - 1 ));
506         lcl_adaptMapReferences( lcl_aLabelRangePrefix + OUString::valueOf( nIndex ),
507                             lcl_aLabelRangePrefix + OUString::valueOf( nIndex - 1 ));
508     }
509 }
510 
511 Reference< chart2::data::XDataSequence > InternalDataProvider::lcl_createDataSequenceAndAddToMap(
512     const OUString & rRangeRepresentation )
513 {
514     Reference< chart2::data::XDataSequence > xSeq(
515         new UncachedDataSequence( this, rRangeRepresentation ));
516     lcl_addDataSequenceToMap( rRangeRepresentation, xSeq );
517     return xSeq;
518 }
519 
520 Reference< chart2::data::XDataSequence > InternalDataProvider::lcl_createDataSequenceAndAddToMap(
521     const OUString & rRangeRepresentation,
522     const OUString & rRole )
523 {
524     Reference< chart2::data::XDataSequence > xSeq(
525         new UncachedDataSequence( this, rRangeRepresentation, rRole ));
526     lcl_addDataSequenceToMap( rRangeRepresentation, xSeq );
527     return xSeq;
528 }
529 
530 void InternalDataProvider::createDefaultData()
531 {
532     m_aInternalData.createDefaultData();
533 }
534 
535 // ____ XDataProvider ____
536 ::sal_Bool SAL_CALL InternalDataProvider::createDataSourcePossible( const Sequence< beans::PropertyValue >& /* aArguments */ )
537     throw (uno::RuntimeException)
538 {
539     return true;
540 }
541 
542 namespace
543 {
544 
545 sal_Int32 lcl_getInnerLevelCount( const vector< vector< uno::Any > >& rLabels )
546 {
547     sal_Int32 nCount = 1;//minimum is 1!
548     vector< vector< uno::Any > >::const_iterator aLevelIt( rLabels.begin() );
549     vector< vector< uno::Any > >::const_iterator aLevelEnd( rLabels.end() );
550     for( ;aLevelIt!=aLevelEnd; ++aLevelIt )
551     {
552         const vector< uno::Any >& rCurrentLevelLabels = *aLevelIt;
553         nCount = std::max<sal_Int32>( rCurrentLevelLabels.size(), nCount );
554     }
555     return nCount;
556 }
557 
558 }//end anonymous namespace
559 
560 Reference< chart2::data::XDataSource > SAL_CALL InternalDataProvider::createDataSource(
561     const Sequence< beans::PropertyValue >& aArguments )
562     throw (lang::IllegalArgumentException,
563            uno::RuntimeException)
564 {
565     OUString aRangeRepresentation;
566     bool bUseColumns = true;
567     bool bFirstCellAsLabel = true;
568     bool bHasCategories = true;
569     uno::Sequence< sal_Int32 > aSequenceMapping;
570     DataSourceHelper::readArguments( aArguments, aRangeRepresentation, aSequenceMapping, bUseColumns, bFirstCellAsLabel, bHasCategories );
571 
572     if( aRangeRepresentation.equals( lcl_aCategoriesRangeName ) )
573     {
574         //return split complex categories if we have any:
575         ::std::vector< Reference< chart2::data::XLabeledDataSequence > > aComplexCategories;
576         vector< vector< uno::Any > > aCategories( m_bDataInColumns ? m_aInternalData.getComplexRowLabels() : m_aInternalData.getComplexColumnLabels());
577         if( bUseColumns==m_bDataInColumns )
578         {
579             sal_Int32 nLevelCount = lcl_getInnerLevelCount( aCategories );
580             for( sal_Int32 nL=0; nL<nLevelCount; nL++ )
581                 aComplexCategories.push_back( new LabeledDataSequence(
582                     new UncachedDataSequence( this
583                         , lcl_aCategoriesLevelRangeNamePrefix + OUString::valueOf( nL )
584                         , lcl_aCategoriesRoleName ) ) );
585         }
586         else
587         {
588             sal_Int32 nPointCount = m_bDataInColumns ? m_aInternalData.getRowCount() : m_aInternalData.getColumnCount();
589             for( sal_Int32 nP=0; nP<nPointCount; nP++ )
590                 aComplexCategories.push_back( new LabeledDataSequence(
591                     new UncachedDataSequence( this
592                         , lcl_aCategoriesPointRangeNamePrefix + OUString::valueOf( nP )
593                         , lcl_aCategoriesRoleName ) ) );
594         }
595         //don't add the created sequences to the map as they are used temporarily only ...
596         return new DataSource( ContainerHelper::ContainerToSequence(aComplexCategories) );
597     }
598 
599     OSL_ASSERT( aRangeRepresentation.equals( lcl_aCompleteRange ));
600 
601     ::std::vector< Reference< chart2::data::XLabeledDataSequence > > aResultLSeqVec;
602 
603     // categories
604     if( bHasCategories )
605         aResultLSeqVec.push_back(
606             new LabeledDataSequence( lcl_createDataSequenceAndAddToMap( lcl_aCategoriesRangeName, lcl_aCategoriesRoleName ) ) );
607 
608     // data with labels
609     ::std::vector< Reference< chart2::data::XLabeledDataSequence > > aDataVec;
610     const sal_Int32 nCount = (bUseColumns ? m_aInternalData.getColumnCount() : m_aInternalData.getRowCount());
611     for( sal_Int32 nIdx=0; nIdx<nCount; ++nIdx )
612     {
613         aDataVec.push_back(
614             new LabeledDataSequence(
615                 lcl_createDataSequenceAndAddToMap( OUString::valueOf( nIdx )),
616                 lcl_createDataSequenceAndAddToMap( lcl_aLabelRangePrefix + OUString::valueOf( nIdx ))));
617     }
618 
619     // attention: this data provider has the limitation that it stores
620     // internally if data comes from columns or rows. It is intended for
621     // creating only one used data source.
622     // @todo: add this information in the range representation strings
623     m_bDataInColumns = bUseColumns;
624 
625     //reorder labeled sequences according to aSequenceMapping; ignore categories
626     for( sal_Int32 nNewIndex = 0; nNewIndex < aSequenceMapping.getLength(); nNewIndex++ )
627     {
628         std::vector< LabeledDataSequence* >::size_type nOldIndex = aSequenceMapping[nNewIndex];
629         if( nOldIndex < aDataVec.size() )
630         {
631             if( aDataVec[nOldIndex].is() )
632             {
633                 aResultLSeqVec.push_back( aDataVec[nOldIndex] );
634                 aDataVec[nOldIndex] = 0;
635             }
636         }
637     }
638 
639     //add left over data sequences to result
640     ::std::vector< Reference< chart2::data::XLabeledDataSequence > >::iterator aIt(aDataVec.begin());
641     const ::std::vector< Reference< chart2::data::XLabeledDataSequence > >::const_iterator aEndIt(aDataVec.end());
642     for( ;aIt!=aEndIt; ++aIt)
643     {
644         if( aIt->is() )
645             aResultLSeqVec.push_back( *aIt );
646     }
647 
648     return new DataSource( ContainerHelper::ContainerToSequence(aResultLSeqVec) );
649 }
650 
651 Sequence< beans::PropertyValue > SAL_CALL InternalDataProvider::detectArguments(
652     const Reference< chart2::data::XDataSource >& /* xDataSource */ )
653     throw (uno::RuntimeException)
654 {
655     Sequence< beans::PropertyValue > aArguments( 4 );
656     aArguments[0] = beans::PropertyValue(
657         C2U("CellRangeRepresentation"), -1, uno::makeAny( lcl_aCompleteRange ),
658         beans::PropertyState_DIRECT_VALUE );
659     aArguments[1] = beans::PropertyValue(
660         C2U("DataRowSource"), -1, uno::makeAny(
661             m_bDataInColumns
662             ? ::com::sun::star::chart::ChartDataRowSource_COLUMNS
663             : ::com::sun::star::chart::ChartDataRowSource_ROWS ),
664         beans::PropertyState_DIRECT_VALUE );
665     // internal data always contains labels and categories
666     aArguments[2] = beans::PropertyValue(
667         C2U("FirstCellAsLabel"), -1, uno::makeAny( true ), beans::PropertyState_DIRECT_VALUE );
668     aArguments[3] = beans::PropertyValue(
669         C2U("HasCategories"), -1, uno::makeAny( true ), beans::PropertyState_DIRECT_VALUE );
670 
671     // #i85913# Sequence Mapping is not needed for internal data, as it is
672     // applied to the data when the data source is created.
673 
674     return aArguments;
675 }
676 
677 ::sal_Bool SAL_CALL InternalDataProvider::createDataSequenceByRangeRepresentationPossible( const OUString& /* aRangeRepresentation */ )
678     throw (uno::RuntimeException)
679 {
680     return true;
681 }
682 
683 Reference< chart2::data::XDataSequence > SAL_CALL InternalDataProvider::createDataSequenceByRangeRepresentation(
684     const OUString& aRangeRepresentation )
685     throw (lang::IllegalArgumentException,
686            uno::RuntimeException)
687 {
688     if( aRangeRepresentation.match( lcl_aCategoriesRangeName ))
689     {
690         OSL_ASSERT( aRangeRepresentation.equals( lcl_aCategoriesRangeName ) );//it is not expected nor implmented that only parts of the categories are really requested
691 
692         // categories
693         return lcl_createDataSequenceAndAddToMap( lcl_aCategoriesRangeName, lcl_aCategoriesRoleName );
694     }
695     else if( aRangeRepresentation.match( lcl_aLabelRangePrefix ))
696     {
697         // label
698         sal_Int32 nIndex = aRangeRepresentation.copy( lcl_aLabelRangePrefix.getLength()).toInt32();
699         return lcl_createDataSequenceAndAddToMap( lcl_aLabelRangePrefix + OUString::valueOf( nIndex ));
700     }
701     else if( aRangeRepresentation.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "last" )))
702     {
703         sal_Int32 nIndex = (m_bDataInColumns
704                             ? m_aInternalData.getColumnCount()
705                             : m_aInternalData.getRowCount()) - 1;
706         return lcl_createDataSequenceAndAddToMap( OUString::valueOf( nIndex ));
707     }
708     else if( aRangeRepresentation.getLength())
709     {
710         // data
711         sal_Int32 nIndex = aRangeRepresentation.toInt32();
712         return lcl_createDataSequenceAndAddToMap( OUString::valueOf( nIndex ));
713     }
714 
715     return Reference< chart2::data::XDataSequence >();
716 }
717 
718 Reference< sheet::XRangeSelection > SAL_CALL InternalDataProvider::getRangeSelection()
719     throw (uno::RuntimeException)
720 {
721     // there is no range selection component
722     return Reference< sheet::XRangeSelection >();
723 }
724 
725 // ____ XInternalDataProvider ____
726 ::sal_Bool SAL_CALL InternalDataProvider::hasDataByRangeRepresentation( const OUString& aRange )
727     throw (uno::RuntimeException)
728 {
729     sal_Bool bResult = false;
730 
731     if( aRange.match( lcl_aCategoriesRangeName ))
732     {
733         OSL_ASSERT( aRange.equals( lcl_aCategoriesRangeName ) );//it is not expected nor implmented that only parts of the categories are really requested
734         bResult = true;
735     }
736     else if( aRange.match( lcl_aLabelRangePrefix ))
737     {
738         sal_Int32 nIndex = aRange.copy( lcl_aLabelRangePrefix.getLength()).toInt32();
739         bResult = (nIndex < (m_bDataInColumns ? m_aInternalData.getColumnCount(): m_aInternalData.getRowCount()));
740     }
741     else
742     {
743         sal_Int32 nIndex = aRange.toInt32();
744         bResult = (nIndex < (m_bDataInColumns ? m_aInternalData.getColumnCount(): m_aInternalData.getRowCount()));
745     }
746 
747     return bResult;
748 }
749 
750 Sequence< uno::Any > SAL_CALL InternalDataProvider::getDataByRangeRepresentation( const OUString& aRange )
751     throw (uno::RuntimeException)
752 {
753     Sequence< uno::Any > aResult;
754 
755     if( aRange.match( lcl_aLabelRangePrefix ) )
756     {
757         sal_Int32 nIndex = aRange.copy( lcl_aLabelRangePrefix.getLength()).toInt32();
758         vector< uno::Any > aComplexLabel = m_bDataInColumns
759             ? m_aInternalData.getComplexColumnLabel( nIndex )
760             : m_aInternalData.getComplexRowLabel( nIndex );
761         if( !aComplexLabel.empty() )
762             aResult = ContainerHelper::ContainerToSequence(aComplexLabel);
763     }
764     else if( aRange.match( lcl_aCategoriesPointRangeNamePrefix ) )
765     {
766         sal_Int32 nPointIndex = aRange.copy( lcl_aCategoriesPointRangeNamePrefix.getLength() ).toInt32();
767         vector< uno::Any > aComplexCategory = m_bDataInColumns
768             ? m_aInternalData.getComplexRowLabel( nPointIndex )
769             : m_aInternalData.getComplexColumnLabel( nPointIndex );
770         if( !aComplexCategory.empty() )
771             aResult = ContainerHelper::ContainerToSequence(aComplexCategory);
772     }
773     else if( aRange.match( lcl_aCategoriesLevelRangeNamePrefix ) )
774     {
775         sal_Int32 nLevel = aRange.copy( lcl_aCategoriesLevelRangeNamePrefix.getLength() ).toInt32();
776         vector< vector< uno::Any > > aCategories( m_bDataInColumns ? m_aInternalData.getComplexRowLabels() : m_aInternalData.getComplexColumnLabels());
777         if( nLevel < lcl_getInnerLevelCount( aCategories ) )
778         {
779             aResult.realloc( aCategories.size() );
780             transform( aCategories.begin(), aCategories.end(),
781                        aResult.getArray(), lcl_copyFromLevel(nLevel) );
782         }
783     }
784     else if( aRange.equals( lcl_aCategoriesRangeName ) )
785     {
786         vector< vector< uno::Any > > aCategories( m_bDataInColumns ? m_aInternalData.getComplexRowLabels() : m_aInternalData.getComplexColumnLabels());
787         sal_Int32 nLevelCount = lcl_getInnerLevelCount( aCategories );
788         if( nLevelCount == 1 )
789         {
790             sal_Int32 nL=0;
791             aResult = this->getDataByRangeRepresentation( lcl_aCategoriesLevelRangeNamePrefix + OUString::valueOf( nL ) );
792         }
793         else
794         {
795             Sequence< OUString > aLabels = m_bDataInColumns ? this->getRowDescriptions() : this->getColumnDescriptions();
796             aResult.realloc( aLabels.getLength() );
797             transform( aLabels.getConstArray(), aLabels.getConstArray() + aLabels.getLength(),
798                        aResult.getArray(), CommonFunctors::makeAny< OUString >() );
799         }
800     }
801     else
802     {
803         sal_Int32 nIndex = aRange.toInt32();
804         if( nIndex >= 0 )
805         {
806             Sequence< double > aData;
807             if( m_bDataInColumns )
808                 aData = m_aInternalData.getColumnValues(nIndex);
809             else
810                 aData = m_aInternalData.getRowValues(nIndex);
811             if( aData.getLength() )
812             {
813 			    aResult.realloc( aData.getLength());
814                 transform( aData.getConstArray(), aData.getConstArray() + aData.getLength(),
815                            aResult.getArray(), CommonFunctors::makeAny< double >());
816             }
817         }
818     }
819 
820     return aResult;
821 }
822 
823 void SAL_CALL InternalDataProvider::setDataByRangeRepresentation(
824     const OUString& aRange, const Sequence< uno::Any >& aNewData )
825     throw (uno::RuntimeException)
826 {
827     vector< uno::Any > aNewVector( ContainerHelper::SequenceToVector(aNewData) );
828     if( aRange.match( lcl_aLabelRangePrefix ) )
829     {
830         sal_uInt32 nIndex = aRange.copy( lcl_aLabelRangePrefix.getLength()).toInt32();
831         if( m_bDataInColumns )
832             m_aInternalData.setComplexColumnLabel( nIndex, aNewVector );
833         else
834             m_aInternalData.setComplexRowLabel( nIndex, aNewVector );
835     }
836     else if( aRange.match( lcl_aCategoriesPointRangeNamePrefix ) )
837     {
838         sal_Int32 nPointIndex = aRange.copy( lcl_aCategoriesLevelRangeNamePrefix.getLength()).toInt32();
839         if( m_bDataInColumns )
840             m_aInternalData.setComplexRowLabel( nPointIndex, aNewVector );
841         else
842             m_aInternalData.setComplexColumnLabel( nPointIndex, aNewVector );
843     }
844     else if( aRange.match( lcl_aCategoriesLevelRangeNamePrefix ) )
845     {
846         sal_Int32 nLevel = aRange.copy( lcl_aCategoriesLevelRangeNamePrefix.getLength()).toInt32();
847         vector< vector< uno::Any > > aComplexCategories = m_bDataInColumns ? m_aInternalData.getComplexRowLabels() : m_aInternalData.getComplexColumnLabels();
848 
849         //ensure equal length
850         if( aNewVector.size() > aComplexCategories.size() )
851             aComplexCategories.resize( aNewVector.size() );
852         else if( aNewVector.size() < aComplexCategories.size() )
853             aNewVector.resize( aComplexCategories.size() );
854 
855         transform( aComplexCategories.begin(), aComplexCategories.end(), aNewVector.begin(),
856                    aComplexCategories.begin(), lcl_setAnyAtLevel(nLevel) );
857 
858         if( m_bDataInColumns )
859             m_aInternalData.setComplexRowLabels( aComplexCategories );
860         else
861             m_aInternalData.setComplexColumnLabels( aComplexCategories );
862     }
863     else if( aRange.equals( lcl_aCategoriesRangeName ) )
864     {
865         vector< vector< uno::Any > > aComplexCategories;
866         aComplexCategories.resize( aNewVector.size() );
867         transform( aComplexCategories.begin(), aComplexCategories.end(), aNewVector.begin(),
868                             aComplexCategories.begin(), lcl_setAnyAtLevel(0) );
869         if( m_bDataInColumns )
870             m_aInternalData.setComplexRowLabels( aComplexCategories );
871         else
872             m_aInternalData.setComplexColumnLabels( aComplexCategories );
873     }
874     else
875     {
876         sal_Int32 nIndex = aRange.toInt32();
877         if( nIndex>=0 )
878         {
879             vector< double > aNewDataVec;
880             transform( aNewData.getConstArray(), aNewData.getConstArray() + aNewData.getLength(),
881                        back_inserter( aNewDataVec ), CommonFunctors::AnyToDouble());
882             if( m_bDataInColumns )
883                 m_aInternalData.setColumnValues( nIndex, aNewDataVec );
884             else
885                 m_aInternalData.setRowValues( nIndex, aNewDataVec );
886         }
887     }
888 }
889 
890 void SAL_CALL InternalDataProvider::insertSequence( ::sal_Int32 nAfterIndex )
891     throw (uno::RuntimeException)
892 {
893     if( m_bDataInColumns )
894     {
895         lcl_increaseMapReferences( nAfterIndex + 1, m_aInternalData.getColumnCount());
896         m_aInternalData.insertColumn( nAfterIndex );
897     }
898     else
899     {
900         lcl_increaseMapReferences( nAfterIndex + 1, m_aInternalData.getRowCount());
901         m_aInternalData.insertRow( nAfterIndex );
902     }
903 }
904 
905 void SAL_CALL InternalDataProvider::deleteSequence( ::sal_Int32 nAtIndex )
906     throw (uno::RuntimeException)
907 {
908     lcl_deleteMapReferences( OUString::valueOf( nAtIndex ));
909     lcl_deleteMapReferences( lcl_aLabelRangePrefix + OUString::valueOf( nAtIndex ));
910     if( m_bDataInColumns )
911     {
912         lcl_decreaseMapReferences( nAtIndex + 1, m_aInternalData.getColumnCount());
913         m_aInternalData.deleteColumn( nAtIndex );
914     }
915     else
916     {
917         lcl_decreaseMapReferences( nAtIndex + 1, m_aInternalData.getRowCount());
918         m_aInternalData.deleteRow( nAtIndex );
919     }
920 }
921 
922 void SAL_CALL InternalDataProvider::appendSequence()
923     throw (uno::RuntimeException)
924 {
925     if( m_bDataInColumns )
926         m_aInternalData.appendColumn();
927     else
928         m_aInternalData.appendRow();
929 }
930 
931 void SAL_CALL InternalDataProvider::insertComplexCategoryLevel( sal_Int32 nLevel )
932         throw (uno::RuntimeException)
933 {
934     OSL_ENSURE( nLevel> 0, "you can only insert category levels > 0" );//the first categories level cannot be deleted, check the calling code for error
935     if( nLevel>0 )
936     {
937         vector< vector< uno::Any > > aComplexCategories = m_bDataInColumns ? m_aInternalData.getComplexRowLabels() : m_aInternalData.getComplexColumnLabels();
938         ::std::for_each( aComplexCategories.begin(), aComplexCategories.end(), lcl_insertAnyAtLevel(nLevel) );
939         if( m_bDataInColumns )
940             m_aInternalData.setComplexRowLabels( aComplexCategories );
941         else
942             m_aInternalData.setComplexColumnLabels( aComplexCategories );
943 
944         tSequenceMapRange aRange( m_aSequenceMap.equal_range( lcl_aCategoriesRangeName ));
945         ::std::for_each( aRange.first, aRange.second, lcl_setModified());
946     }
947 }
948 void SAL_CALL InternalDataProvider::deleteComplexCategoryLevel( sal_Int32 nLevel )
949         throw (uno::RuntimeException)
950 {
951     OSL_ENSURE( nLevel>0, "you can only delete category levels > 0" );//the first categories level cannot be deleted, check the calling code for error
952     if( nLevel>0 )
953     {
954         vector< vector< uno::Any > > aComplexCategories = m_bDataInColumns ? m_aInternalData.getComplexRowLabels() : m_aInternalData.getComplexColumnLabels();
955         ::std::for_each( aComplexCategories.begin(), aComplexCategories.end(), lcl_removeAnyAtLevel(nLevel) );
956         if( m_bDataInColumns )
957             m_aInternalData.setComplexRowLabels( aComplexCategories );
958         else
959             m_aInternalData.setComplexColumnLabels( aComplexCategories );
960 
961         tSequenceMapRange aRange( m_aSequenceMap.equal_range( lcl_aCategoriesRangeName ));
962         ::std::for_each( aRange.first, aRange.second, lcl_setModified());
963     }
964 }
965 
966 void SAL_CALL InternalDataProvider::insertDataPointForAllSequences( ::sal_Int32 nAfterIndex )
967     throw (uno::RuntimeException)
968 {
969     sal_Int32 nMaxRep = 0;
970     if( m_bDataInColumns )
971     {
972         m_aInternalData.insertRow( nAfterIndex );
973         nMaxRep = m_aInternalData.getColumnCount();
974     }
975     else
976     {
977         m_aInternalData.insertColumn( nAfterIndex );
978         nMaxRep = m_aInternalData.getRowCount();
979     }
980 
981     // notify change to all affected ranges
982     tSequenceMap::const_iterator aBegin( m_aSequenceMap.lower_bound( C2U("0")));
983     tSequenceMap::const_iterator aEnd( m_aSequenceMap.upper_bound( OUString::valueOf( nMaxRep )));
984     ::std::for_each( aBegin, aEnd, lcl_setModified());
985 
986     tSequenceMapRange aRange( m_aSequenceMap.equal_range( lcl_aCategoriesRangeName ));
987     ::std::for_each( aRange.first, aRange.second, lcl_setModified());
988 }
989 
990 void SAL_CALL InternalDataProvider::deleteDataPointForAllSequences( ::sal_Int32 nAtIndex )
991     throw (uno::RuntimeException)
992 {
993     sal_Int32 nMaxRep = 0;
994     if( m_bDataInColumns )
995     {
996         m_aInternalData.deleteRow( nAtIndex );
997         nMaxRep = m_aInternalData.getColumnCount();
998     }
999     else
1000     {
1001         m_aInternalData.deleteColumn( nAtIndex );
1002         nMaxRep = m_aInternalData.getRowCount();
1003     }
1004 
1005     // notify change to all affected ranges
1006     tSequenceMap::const_iterator aBegin( m_aSequenceMap.lower_bound( C2U("0")));
1007     tSequenceMap::const_iterator aEnd( m_aSequenceMap.upper_bound( OUString::valueOf( nMaxRep )));
1008     ::std::for_each( aBegin, aEnd, lcl_setModified());
1009 
1010     tSequenceMapRange aRange( m_aSequenceMap.equal_range( lcl_aCategoriesRangeName ));
1011     ::std::for_each( aRange.first, aRange.second, lcl_setModified());
1012 }
1013 
1014 void SAL_CALL InternalDataProvider::swapDataPointWithNextOneForAllSequences( ::sal_Int32 nAtIndex )
1015     throw (uno::RuntimeException)
1016 {
1017     if( m_bDataInColumns )
1018         m_aInternalData.swapRowWithNext( nAtIndex );
1019     else
1020         m_aInternalData.swapColumnWithNext( nAtIndex );
1021     sal_Int32 nMaxRep = (m_bDataInColumns
1022                          ? m_aInternalData.getColumnCount()
1023                          : m_aInternalData.getRowCount());
1024 
1025     // notify change to all affected ranges
1026     tSequenceMap::const_iterator aBegin( m_aSequenceMap.lower_bound( C2U("0")));
1027     tSequenceMap::const_iterator aEnd( m_aSequenceMap.upper_bound( OUString::valueOf( nMaxRep )));
1028     ::std::for_each( aBegin, aEnd, lcl_setModified());
1029 
1030     tSequenceMapRange aRange( m_aSequenceMap.equal_range( lcl_aCategoriesRangeName ));
1031     ::std::for_each( aRange.first, aRange.second, lcl_setModified());
1032 }
1033 
1034 void SAL_CALL InternalDataProvider::registerDataSequenceForChanges( const Reference< chart2::data::XDataSequence >& xSeq )
1035     throw (uno::RuntimeException)
1036 {
1037     if( xSeq.is())
1038         lcl_addDataSequenceToMap( xSeq->getSourceRangeRepresentation(), xSeq );
1039 }
1040 
1041 
1042 // ____ XRangeXMLConversion ____
1043 OUString SAL_CALL InternalDataProvider::convertRangeToXML( const OUString& aRangeRepresentation )
1044     throw (lang::IllegalArgumentException,
1045            uno::RuntimeException)
1046 {
1047     XMLRangeHelper::CellRange aRange;
1048     aRange.aTableName = OUString(RTL_CONSTASCII_USTRINGPARAM("local-table"));
1049 
1050     // attention: this data provider has the limitation that it stores
1051     // internally if data comes from columns or rows. It is intended for
1052     // creating only one used data source.
1053     // @todo: add this information in the range representation strings
1054     if( aRangeRepresentation.match( lcl_aCategoriesRangeName ))
1055     {
1056         OSL_ASSERT( aRangeRepresentation.equals( lcl_aCategoriesRangeName ) );//it is not expected nor implmented that only parts of the categories are really requested
1057         aRange.aUpperLeft.bIsEmpty = false;
1058         if( m_bDataInColumns )
1059         {
1060             aRange.aUpperLeft.nColumn = 0;
1061             aRange.aUpperLeft.nRow = 1;
1062             aRange.aLowerRight = aRange.aUpperLeft;
1063             aRange.aLowerRight.nRow = m_aInternalData.getRowCount();
1064         }
1065         else
1066         {
1067             aRange.aUpperLeft.nColumn = 1;
1068             aRange.aUpperLeft.nRow = 0;
1069             aRange.aLowerRight = aRange.aUpperLeft;
1070             aRange.aLowerRight.nColumn = m_aInternalData.getColumnCount();
1071         }
1072     }
1073     else if( aRangeRepresentation.match( lcl_aLabelRangePrefix ))
1074     {
1075         sal_Int32 nIndex = aRangeRepresentation.copy( lcl_aLabelRangePrefix.getLength()).toInt32();
1076         aRange.aUpperLeft.bIsEmpty = false;
1077         aRange.aLowerRight.bIsEmpty = true;
1078         if( m_bDataInColumns )
1079         {
1080             aRange.aUpperLeft.nColumn = nIndex + 1;
1081             aRange.aUpperLeft.nRow = 0;
1082         }
1083         else
1084         {
1085             aRange.aUpperLeft.nColumn = 0;
1086             aRange.aUpperLeft.nRow = nIndex + 1;
1087         }
1088     }
1089     else if( aRangeRepresentation.equals( lcl_aCompleteRange ))
1090     {
1091         aRange.aUpperLeft.bIsEmpty = false;
1092         aRange.aLowerRight.bIsEmpty = false;
1093         aRange.aUpperLeft.nColumn = 0;
1094         aRange.aUpperLeft.nRow = 0;
1095         aRange.aLowerRight.nColumn = m_aInternalData.getColumnCount();
1096         aRange.aLowerRight.nRow = m_aInternalData.getRowCount();
1097     }
1098     else
1099     {
1100         sal_Int32 nIndex = aRangeRepresentation.toInt32();
1101         aRange.aUpperLeft.bIsEmpty = false;
1102         if( m_bDataInColumns )
1103         {
1104             aRange.aUpperLeft.nColumn = nIndex + 1;
1105             aRange.aUpperLeft.nRow = 1;
1106             aRange.aLowerRight = aRange.aUpperLeft;
1107             aRange.aLowerRight.nRow = m_aInternalData.getRowCount();
1108         }
1109         else
1110         {
1111             aRange.aUpperLeft.nColumn = 1;
1112             aRange.aUpperLeft.nRow = nIndex + 1;
1113             aRange.aLowerRight = aRange.aUpperLeft;
1114             aRange.aLowerRight.nColumn = m_aInternalData.getColumnCount();
1115         }
1116     }
1117 
1118     return XMLRangeHelper::getXMLStringFromCellRange( aRange );
1119 }
1120 
1121 OUString SAL_CALL InternalDataProvider::convertRangeFromXML( const OUString& aXMLRange )
1122     throw (lang::IllegalArgumentException,
1123            uno::RuntimeException)
1124 {
1125     XMLRangeHelper::CellRange aRange( XMLRangeHelper::getCellRangeFromXMLString( aXMLRange ));
1126     if( aRange.aUpperLeft.bIsEmpty )
1127     {
1128         OSL_ENSURE( aRange.aLowerRight.bIsEmpty, "Weird Range" );
1129         return OUString();
1130     }
1131 
1132     // "all"
1133     if( !aRange.aLowerRight.bIsEmpty &&
1134         ( aRange.aUpperLeft.nColumn != aRange.aLowerRight.nColumn ) &&
1135         ( aRange.aUpperLeft.nRow != aRange.aLowerRight.nRow ) )
1136         return lcl_aCompleteRange;
1137 
1138     // attention: this data provider has the limitation that it stores
1139     // internally if data comes from columns or rows. It is intended for
1140     // creating only one used data source.
1141     // @todo: add this information in the range representation strings
1142 
1143     // data in columns
1144     if( m_bDataInColumns )
1145     {
1146         if( aRange.aUpperLeft.nColumn == 0 )
1147             return lcl_aCategoriesRangeName;
1148         if( aRange.aUpperLeft.nRow == 0 )
1149             return lcl_aLabelRangePrefix + OUString::valueOf( aRange.aUpperLeft.nColumn - 1 );
1150 
1151         return OUString::valueOf( aRange.aUpperLeft.nColumn - 1 );
1152     }
1153 
1154     // data in rows
1155     if( aRange.aUpperLeft.nRow == 0 )
1156         return lcl_aCategoriesRangeName;
1157     if( aRange.aUpperLeft.nColumn == 0 )
1158         return lcl_aLabelRangePrefix + OUString::valueOf( aRange.aUpperLeft.nRow - 1 );
1159 
1160     return OUString::valueOf( aRange.aUpperLeft.nRow - 1 );
1161 }
1162 
1163 namespace
1164 {
1165 
1166 template< class Type >
1167 Sequence< Sequence< Type > > lcl_convertVectorVectorToSequenceSequence( const vector< vector< Type > >& rIn )
1168 {
1169     Sequence< Sequence< Type > > aRet;
1170     sal_Int32 nOuterCount = rIn.size();
1171     if( nOuterCount )
1172     {
1173         aRet.realloc(nOuterCount);
1174         for( sal_Int32 nN=0; nN<nOuterCount; nN++)
1175             aRet[nN]= ContainerHelper::ContainerToSequence( rIn[nN] );
1176     }
1177     return aRet;
1178 }
1179 
1180 template< class Type >
1181 vector< vector< Type > > lcl_convertSequenceSequenceToVectorVector( const Sequence< Sequence< Type > >& rIn )
1182 {
1183     vector< vector< Type > > aRet;
1184     sal_Int32 nOuterCount = rIn.getLength();
1185     if( nOuterCount )
1186     {
1187         aRet.resize(nOuterCount);
1188         for( sal_Int32 nN=0; nN<nOuterCount; nN++)
1189             aRet[nN]= ContainerHelper::SequenceToVector( rIn[nN] );
1190     }
1191     return aRet;
1192 }
1193 
1194 Sequence< Sequence< OUString > > lcl_convertComplexAnyVectorToStringSequence( const vector< vector< uno::Any > >& rIn )
1195 {
1196     Sequence< Sequence< OUString > > aRet;
1197     sal_Int32 nOuterCount = rIn.size();
1198     if( nOuterCount )
1199     {
1200         aRet.realloc(nOuterCount);
1201         for( sal_Int32 nN=0; nN<nOuterCount; nN++)
1202             aRet[nN]= lcl_AnyToStringSequence( ContainerHelper::ContainerToSequence( rIn[nN] ) );
1203     }
1204     return aRet;
1205 }
1206 
1207 vector< vector< uno::Any > > lcl_convertComplexStringSequenceToAnyVector( const Sequence< Sequence< OUString > >& rIn )
1208 {
1209     vector< vector< uno::Any > > aRet;
1210     sal_Int32 nOuterCount = rIn.getLength();
1211     for( sal_Int32 nN=0; nN<nOuterCount; nN++)
1212         aRet.push_back( ContainerHelper::SequenceToVector( lcl_StringToAnySequence( rIn[nN] ) ) );
1213     return aRet;
1214 }
1215 
1216 class SplitCategoriesProvider_ForComplexDescriptions : public SplitCategoriesProvider
1217 {
1218 public:
1219 
1220     explicit SplitCategoriesProvider_ForComplexDescriptions( const ::std::vector< ::std::vector< uno::Any > >& rComplexDescriptions )
1221         : m_rComplexDescriptions( rComplexDescriptions )
1222     {}
1223     virtual ~SplitCategoriesProvider_ForComplexDescriptions()
1224     {}
1225 
1226     virtual sal_Int32 getLevelCount() const;
1227     virtual uno::Sequence< rtl::OUString > getStringsForLevel( sal_Int32 nIndex ) const;
1228 
1229 private:
1230     const ::std::vector< ::std::vector< uno::Any > >& m_rComplexDescriptions;
1231 };
1232 
1233 sal_Int32 SplitCategoriesProvider_ForComplexDescriptions::getLevelCount() const
1234 {
1235     return lcl_getInnerLevelCount( m_rComplexDescriptions );
1236 }
1237 uno::Sequence< rtl::OUString > SplitCategoriesProvider_ForComplexDescriptions::getStringsForLevel( sal_Int32 nLevel ) const
1238 {
1239     uno::Sequence< rtl::OUString > aResult;
1240     if( nLevel < lcl_getInnerLevelCount( m_rComplexDescriptions ) )
1241     {
1242         aResult.realloc( m_rComplexDescriptions.size() );
1243         transform( m_rComplexDescriptions.begin(), m_rComplexDescriptions.end(),
1244                    aResult.getArray(), lcl_getStringFromLevelVector(nLevel) );
1245     }
1246     return aResult;
1247 }
1248 
1249 }//anonymous namespace
1250 
1251 // ____ XDateCategories ____
1252 Sequence< double > SAL_CALL InternalDataProvider::getDateCategories() throw (uno::RuntimeException)
1253 {
1254     double fNan = InternalDataProvider::getNotANumber();
1255     double fValue = fNan;
1256     vector< vector< uno::Any > > aCategories( m_bDataInColumns ? m_aInternalData.getComplexRowLabels() : m_aInternalData.getComplexColumnLabels());
1257     sal_Int32 nCount = aCategories.size();
1258     Sequence< double > aDoubles( nCount );
1259     vector< vector< uno::Any > >::iterator aIt( aCategories.begin() );
1260     vector< vector< uno::Any > >::const_iterator aEnd( aCategories.end() );
1261     for(sal_Int32 nN=0; nN<nCount && aIt!=aEnd; ++nN, ++aIt )
1262     {
1263         if( !( !aIt->empty() && ((*aIt)[0]>>=fValue) ) )
1264             fValue = fNan;
1265         aDoubles[nN]=fValue;
1266     }
1267     return aDoubles;
1268 }
1269 
1270 void SAL_CALL InternalDataProvider::setDateCategories( const Sequence< double >& rDates ) throw (uno::RuntimeException)
1271 {
1272     sal_Int32 nCount = rDates.getLength();
1273     vector< vector< uno::Any > > aNewCategories;
1274     aNewCategories.reserve(nCount);
1275     vector< uno::Any > aSingleLabel(1);
1276 
1277     for(sal_Int32 nN=0; nN<nCount; ++nN )
1278     {
1279         aSingleLabel[0]=uno::makeAny(rDates[nN]);
1280         aNewCategories.push_back(aSingleLabel);
1281     }
1282 
1283     if( m_bDataInColumns )
1284         m_aInternalData.setComplexRowLabels( aNewCategories );
1285     else
1286         m_aInternalData.setComplexColumnLabels( aNewCategories );
1287 }
1288 
1289 // ____ XAnyDescriptionAccess ____
1290 Sequence< Sequence< uno::Any > > SAL_CALL InternalDataProvider::getAnyRowDescriptions() throw (uno::RuntimeException)
1291 {
1292     return lcl_convertVectorVectorToSequenceSequence( m_aInternalData.getComplexRowLabels() );
1293 }
1294 void SAL_CALL InternalDataProvider::setAnyRowDescriptions( const Sequence< Sequence< uno::Any > >& aRowDescriptions ) throw (uno::RuntimeException)
1295 {
1296     m_aInternalData.setComplexRowLabels( lcl_convertSequenceSequenceToVectorVector( aRowDescriptions ) );
1297 }
1298 Sequence< Sequence< uno::Any > > SAL_CALL InternalDataProvider::getAnyColumnDescriptions() throw (uno::RuntimeException)
1299 {
1300     return lcl_convertVectorVectorToSequenceSequence( m_aInternalData.getComplexColumnLabels() );
1301 }
1302 void SAL_CALL InternalDataProvider::setAnyColumnDescriptions( const Sequence< Sequence< uno::Any > >& aColumnDescriptions ) throw (uno::RuntimeException)
1303 {
1304     m_aInternalData.setComplexColumnLabels( lcl_convertSequenceSequenceToVectorVector( aColumnDescriptions ) );
1305 }
1306 
1307 // ____ XComplexDescriptionAccess ____
1308 Sequence< Sequence< OUString > > SAL_CALL InternalDataProvider::getComplexRowDescriptions() throw (uno::RuntimeException)
1309 {
1310     return lcl_convertComplexAnyVectorToStringSequence( m_aInternalData.getComplexRowLabels() );
1311 }
1312 void SAL_CALL InternalDataProvider::setComplexRowDescriptions( const Sequence< Sequence< ::rtl::OUString > >& aRowDescriptions ) throw (uno::RuntimeException)
1313 {
1314     m_aInternalData.setComplexRowLabels( lcl_convertComplexStringSequenceToAnyVector(aRowDescriptions) );
1315 }
1316 Sequence< Sequence< ::rtl::OUString > > SAL_CALL InternalDataProvider::getComplexColumnDescriptions() throw (uno::RuntimeException)
1317 {
1318     return lcl_convertComplexAnyVectorToStringSequence( m_aInternalData.getComplexColumnLabels() );
1319 }
1320 void SAL_CALL InternalDataProvider::setComplexColumnDescriptions( const Sequence< Sequence< ::rtl::OUString > >& aColumnDescriptions ) throw (uno::RuntimeException)
1321 {
1322     m_aInternalData.setComplexColumnLabels( lcl_convertComplexStringSequenceToAnyVector(aColumnDescriptions) );
1323 }
1324 
1325 // ____ XChartDataArray ____
1326 Sequence< Sequence< double > > SAL_CALL InternalDataProvider::getData()
1327     throw (uno::RuntimeException)
1328 {
1329     return m_aInternalData.getData();
1330 }
1331 
1332 void SAL_CALL InternalDataProvider::setData( const Sequence< Sequence< double > >& rDataInRows )
1333     throw (uno::RuntimeException)
1334 {
1335     return m_aInternalData.setData( rDataInRows );
1336 }
1337 
1338 void SAL_CALL InternalDataProvider::setRowDescriptions( const Sequence< OUString >& aRowDescriptions )
1339     throw (uno::RuntimeException)
1340 {
1341     vector< vector< uno::Any > > aComplexDescriptions( aRowDescriptions.getLength() );
1342     transform( aComplexDescriptions.begin(), aComplexDescriptions.end(), aRowDescriptions.getConstArray(),
1343                aComplexDescriptions.begin(), lcl_setAnyAtLevelFromStringSequence(0) );
1344     m_aInternalData.setComplexRowLabels( aComplexDescriptions );
1345 }
1346 
1347 void SAL_CALL InternalDataProvider::setColumnDescriptions( const Sequence< OUString >& aColumnDescriptions )
1348     throw (uno::RuntimeException)
1349 {
1350     vector< vector< uno::Any > > aComplexDescriptions( aColumnDescriptions.getLength() );
1351     transform( aComplexDescriptions.begin(), aComplexDescriptions.end(), aColumnDescriptions.getConstArray(),
1352                aComplexDescriptions.begin(), lcl_setAnyAtLevelFromStringSequence(0) );
1353     m_aInternalData.setComplexColumnLabels( aComplexDescriptions );
1354 }
1355 
1356 Sequence< OUString > SAL_CALL InternalDataProvider::getRowDescriptions()
1357     throw (uno::RuntimeException)
1358 {
1359     vector< vector< uno::Any > > aComplexLabels( m_aInternalData.getComplexRowLabels() );
1360     SplitCategoriesProvider_ForComplexDescriptions aProvider( aComplexLabels );
1361     return ExplicitCategoriesProvider::getExplicitSimpleCategories( aProvider );
1362 }
1363 
1364 Sequence< OUString > SAL_CALL InternalDataProvider::getColumnDescriptions()
1365     throw (uno::RuntimeException)
1366 {
1367     vector< vector< uno::Any > > aComplexLabels( m_aInternalData.getComplexColumnLabels() );
1368     SplitCategoriesProvider_ForComplexDescriptions aProvider( aComplexLabels );
1369     return ExplicitCategoriesProvider::getExplicitSimpleCategories( aProvider );
1370 }
1371 
1372 // ____ XChartData (base of XChartDataArray) ____
1373 void SAL_CALL InternalDataProvider::addChartDataChangeEventListener(
1374     const Reference< ::com::sun::star::chart::XChartDataChangeEventListener >& )
1375     throw (uno::RuntimeException)
1376 {
1377 }
1378 
1379 void SAL_CALL InternalDataProvider::removeChartDataChangeEventListener(
1380     const Reference< ::com::sun::star::chart::XChartDataChangeEventListener >& )
1381     throw (uno::RuntimeException)
1382 {
1383 }
1384 
1385 double SAL_CALL InternalDataProvider::getNotANumber()
1386     throw (uno::RuntimeException)
1387 {
1388     double fNan;
1389     ::rtl::math::setNan( & fNan );
1390     return fNan;
1391 }
1392 
1393 ::sal_Bool SAL_CALL InternalDataProvider::isNotANumber( double nNumber )
1394     throw (uno::RuntimeException)
1395 {
1396     return ::rtl::math::isNan( nNumber )
1397         || ::rtl::math::isInf( nNumber );
1398 }
1399 // lang::XInitialization:
1400 void SAL_CALL InternalDataProvider::initialize(const uno::Sequence< uno::Any > & _aArguments) throw (uno::RuntimeException, uno::Exception)
1401 {
1402 	comphelper::SequenceAsHashMap aArgs(_aArguments);
1403     if ( aArgs.getUnpackedValueOrDefault(::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("CreateDefaultData")),sal_False) )
1404 		createDefaultData();
1405 }
1406 // ____ XCloneable ____
1407 Reference< util::XCloneable > SAL_CALL InternalDataProvider::createClone()
1408     throw (uno::RuntimeException)
1409 {
1410     return Reference< util::XCloneable >( new InternalDataProvider( *this ));
1411 }
1412 
1413 
1414 // ================================================================================
1415 
1416 Sequence< OUString > InternalDataProvider::getSupportedServiceNames_Static()
1417 {
1418     Sequence< OUString > aServices( 1 );
1419     aServices[ 0 ] = OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.chart2.data.DataProvider" ));
1420     return aServices;
1421 }
1422 
1423 // ================================================================================
1424 
1425 APPHELPER_XSERVICEINFO_IMPL( InternalDataProvider, lcl_aServiceName );
1426 
1427 } //  namespace chart
1428