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