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 
lcl_AnyToStringSequence(const Sequence<uno::Any> & aAnySeq)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 
lcl_StringToAnySequence(const Sequence<OUString> & aStringSeq)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 {
operator ()chart::__anonb552f7a40111::lcl_setModified112     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 {
lcl_internalizeSerieschart::__anonb552f7a40111::lcl_internalizeSeries127     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     {}
operator ()chart::__anonb552f7a40111::lcl_internalizeSeries135     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 
lcl_copyFromLevelchart::__anonb552f7a40111::lcl_copyFromLevel208     explicit lcl_copyFromLevel( sal_Int32 nLevel ) : m_nLevel( nLevel )
209     {}
210 
operator ()chart::__anonb552f7a40111::lcl_copyFromLevel211     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 
lcl_getStringFromLevelVectorchart::__anonb552f7a40111::lcl_getStringFromLevelVector227     explicit lcl_getStringFromLevelVector( sal_Int32 nLevel ) : m_nLevel( nLevel )
228     {}
229 
operator ()chart::__anonb552f7a40111::lcl_getStringFromLevelVector230     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 
lcl_setAnyAtLevelchart::__anonb552f7a40111::lcl_setAnyAtLevel247     explicit lcl_setAnyAtLevel( sal_Int32 nLevel ) : m_nLevel( nLevel )
248     {}
249 
operator ()chart::__anonb552f7a40111::lcl_setAnyAtLevel250     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 
lcl_setAnyAtLevelFromStringSequencechart::__anonb552f7a40111::lcl_setAnyAtLevelFromStringSequence267     explicit lcl_setAnyAtLevelFromStringSequence( sal_Int32 nLevel ) : m_nLevel( nLevel )
268     {}
269 
operator ()chart::__anonb552f7a40111::lcl_setAnyAtLevelFromStringSequence270     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 
lcl_insertAnyAtLevelchart::__anonb552f7a40111::lcl_insertAnyAtLevel287     explicit lcl_insertAnyAtLevel( sal_Int32 nLevel ) : m_nLevel( nLevel )
288     {}
289 
operator ()chart::__anonb552f7a40111::lcl_insertAnyAtLevel290     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 
lcl_removeAnyAtLevelchart::__anonb552f7a40111::lcl_removeAnyAtLevel312     explicit lcl_removeAnyAtLevel( sal_Int32 nLevel ) : m_nLevel( nLevel )
313     {}
314 
operator ()chart::__anonb552f7a40111::lcl_removeAnyAtLevel315     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 
InternalDataProvider(const Reference<uno::XComponentContext> &)336 InternalDataProvider::InternalDataProvider( const Reference< uno::XComponentContext > & /*_xContext*/)
337     : m_bDataInColumns( true )
338 {}
339 
InternalDataProvider(const Reference<chart2::XChartDocument> & xChartDoc,bool bConnectToModel,bool bDefaultDataInColumns)340 InternalDataProvider::InternalDataProvider(
341     const Reference< chart2::XChartDocument > & xChartDoc,
342     bool bConnectToModel,
343     bool bDefaultDataInColumns)
344 :   m_bDataInColumns( bDefaultDataInColumns )
345 {
346     try
347     {
348         Reference< chart2::XDiagram > xDiagram( ChartModelHelper::findDiagram( xChartDoc ) );
349         if( xDiagram.is())
350         {
351             Reference< frame::XModel > xChartModel( xChartDoc, uno::UNO_QUERY );
352 
353             //data in columns?
354             {
355                 ::rtl::OUString aRangeString;
356                 bool bFirstCellAsLabel = true;
357                 bool bHasCategories = true;
358                 uno::Sequence< sal_Int32 > aSequenceMapping;
359                 const bool bSomethingDetected(
360                     DataSourceHelper::detectRangeSegmentation(
361                         xChartModel, aRangeString, aSequenceMapping, m_bDataInColumns, bFirstCellAsLabel, bHasCategories ));
362 
363                 // #120559# if no data was available, restore default
364                 if(!bSomethingDetected && m_bDataInColumns != bDefaultDataInColumns)
365                 {
366                     m_bDataInColumns = bDefaultDataInColumns;
367                 }
368             }
369 
370             // categories
371             {
372                 vector< vector< uno::Any > > aNewCategories;//inner count is level
373                 {
374                     ExplicitCategoriesProvider aExplicitCategoriesProvider( ChartModelHelper::getFirstCoordinateSystem(xChartModel), xChartModel );
375 
376                     const Sequence< Reference< chart2::data::XLabeledDataSequence> >& rSplitCategoriesList( aExplicitCategoriesProvider.getSplitCategoriesList() );
377                     sal_Int32 nLevelCount = rSplitCategoriesList.getLength();
378                     for( sal_Int32 nL = 0; nL<nLevelCount; nL++ )
379                     {
380                         Reference< chart2::data::XLabeledDataSequence > xLDS( rSplitCategoriesList[nL] );
381                         if( !xLDS.is() )
382                             continue;
383                         Sequence< uno::Any > aDataSeq;
384                         Reference< chart2::data::XDataSequence > xSeq( xLDS->getValues() );
385                         if( xSeq.is() )
386                             aDataSeq = xSeq->getData();
387                         sal_Int32 nLength = aDataSeq.getLength();
388                         sal_Int32 nCatLength = static_cast< sal_Int32 >(aNewCategories.size());
389                         if( nCatLength < nLength )
390                             aNewCategories.resize( nLength );
391                         else if( nLength < nCatLength )
392                             aDataSeq.realloc( nCatLength );
393                         transform( aNewCategories.begin(), aNewCategories.end(), aDataSeq.getConstArray(),
394                             aNewCategories.begin(), lcl_setAnyAtLevel(nL) );
395                     }
396                     if( !nLevelCount )
397                     {
398                         Sequence< OUString > aSimplecategories = aExplicitCategoriesProvider.getSimpleCategories();
399                         sal_Int32 nLength = aSimplecategories.getLength();
400                         aNewCategories.reserve( nLength );
401                         for( sal_Int32 nN=0; nN<nLength; nN++)
402                         {
403                             vector< uno::Any > aVector(1);
404                             aVector[0] = uno::makeAny( aSimplecategories[nN] );
405                             aNewCategories.push_back( aVector );
406                         }
407                     }
408                 }
409 
410                 if( m_bDataInColumns )
411                     m_aInternalData.setComplexRowLabels( aNewCategories );
412                 else
413                     m_aInternalData.setComplexColumnLabels( aNewCategories );
414                 if( bConnectToModel )
415                     DiagramHelper::setCategoriesToDiagram( new LabeledDataSequence(
416                         createDataSequenceByRangeRepresentation( lcl_aCategoriesRangeName )), xDiagram );
417             }
418 
419             // data series
420             ::std::vector< Reference< chart2::XDataSeries > > aSeriesVector( ChartModelHelper::getDataSeries( xChartDoc ));
421             ::std::for_each( aSeriesVector.begin(), aSeriesVector.end(), lcl_internalizeSeries( m_aInternalData, *this, bConnectToModel, m_bDataInColumns ) );
422         }
423     }
424     catch( const uno::Exception & ex )
425     {
426         ASSERT_EXCEPTION( ex );
427     }
428 }
429 
430 // copy-CTOR
InternalDataProvider(const InternalDataProvider & rOther)431 InternalDataProvider::InternalDataProvider( const InternalDataProvider & rOther ) :
432         impl::InternalDataProvider_Base(),
433         m_aSequenceMap( rOther.m_aSequenceMap ),
434         m_aInternalData( rOther.m_aInternalData ),
435         m_bDataInColumns( rOther.m_bDataInColumns )
436 {}
437 
~InternalDataProvider()438 InternalDataProvider::~InternalDataProvider()
439 {}
440 
lcl_addDataSequenceToMap(const OUString & rRangeRepresentation,const Reference<chart2::data::XDataSequence> & xSequence)441 void InternalDataProvider::lcl_addDataSequenceToMap(
442     const OUString & rRangeRepresentation,
443     const Reference< chart2::data::XDataSequence > & xSequence )
444 {
445     m_aSequenceMap.insert(
446         tSequenceMap::value_type(
447             rRangeRepresentation,
448             uno::WeakReference< chart2::data::XDataSequence >( xSequence )));
449 }
450 
lcl_deleteMapReferences(const OUString & rRangeRepresentation)451 void InternalDataProvider::lcl_deleteMapReferences( const OUString & rRangeRepresentation )
452 {
453     // set sequence to deleted by setting its range to an empty string
454     tSequenceMapRange aRange( m_aSequenceMap.equal_range( rRangeRepresentation ));
455     for( tSequenceMap::iterator aIt( aRange.first ); aIt != aRange.second; ++aIt )
456     {
457         Reference< chart2::data::XDataSequence > xSeq( aIt->second );
458         if( xSeq.is())
459         {
460             Reference< container::XNamed > xNamed( xSeq, uno::UNO_QUERY );
461             if( xNamed.is())
462                 xNamed->setName( OUString());
463         }
464     }
465     // remove from map
466     m_aSequenceMap.erase( aRange.first, aRange.second );
467 }
468 
lcl_adaptMapReferences(const OUString & rOldRangeRepresentation,const OUString & rNewRangeRepresentation)469 void InternalDataProvider::lcl_adaptMapReferences(
470     const OUString & rOldRangeRepresentation,
471     const OUString & rNewRangeRepresentation )
472 {
473     tSequenceMapRange aRange( m_aSequenceMap.equal_range( rOldRangeRepresentation ));
474     tSequenceMap aNewElements;
475     for( tSequenceMap::iterator aIt( aRange.first ); aIt != aRange.second; ++aIt )
476     {
477         Reference< chart2::data::XDataSequence > xSeq( aIt->second );
478         if( xSeq.is())
479         {
480             Reference< container::XNamed > xNamed( xSeq, uno::UNO_QUERY );
481             if( xNamed.is())
482                 xNamed->setName( rNewRangeRepresentation );
483         }
484         aNewElements.insert( tSequenceMap::value_type( rNewRangeRepresentation, aIt->second ));
485     }
486     // erase map values for old index
487     m_aSequenceMap.erase( aRange.first, aRange.second );
488     // add new entries for values with new index
489     ::std::copy( aNewElements.begin(), aNewElements.end(),
490                  ::std::inserter( m_aSequenceMap,
491                                   m_aSequenceMap.upper_bound( rNewRangeRepresentation )));
492 }
493 
lcl_increaseMapReferences(sal_Int32 nBegin,sal_Int32 nEnd)494 void InternalDataProvider::lcl_increaseMapReferences(
495     sal_Int32 nBegin, sal_Int32 nEnd )
496 {
497     for( sal_Int32 nIndex = nEnd - 1; nIndex >= nBegin; --nIndex )
498     {
499         lcl_adaptMapReferences( OUString::valueOf( nIndex ),
500                             OUString::valueOf( nIndex + 1 ));
501         lcl_adaptMapReferences( lcl_aLabelRangePrefix + OUString::valueOf( nIndex ),
502                             lcl_aLabelRangePrefix + OUString::valueOf( nIndex + 1 ));
503     }
504 }
505 
lcl_decreaseMapReferences(sal_Int32 nBegin,sal_Int32 nEnd)506 void InternalDataProvider::lcl_decreaseMapReferences(
507     sal_Int32 nBegin, sal_Int32 nEnd )
508 {
509     for( sal_Int32 nIndex = nBegin; nIndex < nEnd; ++nIndex )
510     {
511         lcl_adaptMapReferences( OUString::valueOf( nIndex ),
512                             OUString::valueOf( nIndex - 1 ));
513         lcl_adaptMapReferences( lcl_aLabelRangePrefix + OUString::valueOf( nIndex ),
514                             lcl_aLabelRangePrefix + OUString::valueOf( nIndex - 1 ));
515     }
516 }
517 
lcl_createDataSequenceAndAddToMap(const OUString & rRangeRepresentation)518 Reference< chart2::data::XDataSequence > InternalDataProvider::lcl_createDataSequenceAndAddToMap(
519     const OUString & rRangeRepresentation )
520 {
521     Reference< chart2::data::XDataSequence > xSeq(
522         new UncachedDataSequence( this, rRangeRepresentation ));
523     lcl_addDataSequenceToMap( rRangeRepresentation, xSeq );
524     return xSeq;
525 }
526 
lcl_createDataSequenceAndAddToMap(const OUString & rRangeRepresentation,const OUString & rRole)527 Reference< chart2::data::XDataSequence > InternalDataProvider::lcl_createDataSequenceAndAddToMap(
528     const OUString & rRangeRepresentation,
529     const OUString & rRole )
530 {
531     Reference< chart2::data::XDataSequence > xSeq(
532         new UncachedDataSequence( this, rRangeRepresentation, rRole ));
533     lcl_addDataSequenceToMap( rRangeRepresentation, xSeq );
534     return xSeq;
535 }
536 
createDefaultData()537 void InternalDataProvider::createDefaultData()
538 {
539     m_aInternalData.createDefaultData();
540 }
541 
542 // ____ XDataProvider ____
createDataSourcePossible(const Sequence<beans::PropertyValue> &)543 ::sal_Bool SAL_CALL InternalDataProvider::createDataSourcePossible( const Sequence< beans::PropertyValue >& /* aArguments */ )
544     throw (uno::RuntimeException)
545 {
546     return true;
547 }
548 
549 namespace
550 {
551 
lcl_getInnerLevelCount(const vector<vector<uno::Any>> & rLabels)552 sal_Int32 lcl_getInnerLevelCount( const vector< vector< uno::Any > >& rLabels )
553 {
554     sal_Int32 nCount = 1;//minimum is 1!
555     vector< vector< uno::Any > >::const_iterator aLevelIt( rLabels.begin() );
556     vector< vector< uno::Any > >::const_iterator aLevelEnd( rLabels.end() );
557     for( ;aLevelIt!=aLevelEnd; ++aLevelIt )
558     {
559         const vector< uno::Any >& rCurrentLevelLabels = *aLevelIt;
560         nCount = std::max<sal_Int32>( rCurrentLevelLabels.size(), nCount );
561     }
562     return nCount;
563 }
564 
565 }//end anonymous namespace
566 
createDataSource(const Sequence<beans::PropertyValue> & aArguments)567 Reference< chart2::data::XDataSource > SAL_CALL InternalDataProvider::createDataSource(
568     const Sequence< beans::PropertyValue >& aArguments )
569     throw (lang::IllegalArgumentException,
570            uno::RuntimeException)
571 {
572     OUString aRangeRepresentation;
573     bool bUseColumns = true;
574     bool bFirstCellAsLabel = true;
575     bool bHasCategories = true;
576     uno::Sequence< sal_Int32 > aSequenceMapping;
577     DataSourceHelper::readArguments( aArguments, aRangeRepresentation, aSequenceMapping, bUseColumns, bFirstCellAsLabel, bHasCategories );
578 
579     if( aRangeRepresentation.equals( lcl_aCategoriesRangeName ) )
580     {
581         //return split complex categories if we have any:
582         ::std::vector< Reference< chart2::data::XLabeledDataSequence > > aComplexCategories;
583         vector< vector< uno::Any > > aCategories( m_bDataInColumns ? m_aInternalData.getComplexRowLabels() : m_aInternalData.getComplexColumnLabels());
584         if( bUseColumns==m_bDataInColumns )
585         {
586             sal_Int32 nLevelCount = lcl_getInnerLevelCount( aCategories );
587             for( sal_Int32 nL=0; nL<nLevelCount; nL++ )
588                 aComplexCategories.push_back( new LabeledDataSequence(
589                     new UncachedDataSequence( this
590                         , lcl_aCategoriesLevelRangeNamePrefix + OUString::valueOf( nL )
591                         , lcl_aCategoriesRoleName ) ) );
592         }
593         else
594         {
595             sal_Int32 nPointCount = m_bDataInColumns ? m_aInternalData.getRowCount() : m_aInternalData.getColumnCount();
596             for( sal_Int32 nP=0; nP<nPointCount; nP++ )
597                 aComplexCategories.push_back( new LabeledDataSequence(
598                     new UncachedDataSequence( this
599                         , lcl_aCategoriesPointRangeNamePrefix + OUString::valueOf( nP )
600                         , lcl_aCategoriesRoleName ) ) );
601         }
602         //don't add the created sequences to the map as they are used temporarily only ...
603         return new DataSource( ContainerHelper::ContainerToSequence(aComplexCategories) );
604     }
605 
606     OSL_ASSERT( aRangeRepresentation.equals( lcl_aCompleteRange ));
607 
608     ::std::vector< Reference< chart2::data::XLabeledDataSequence > > aResultLSeqVec;
609 
610     // categories
611     if( bHasCategories )
612         aResultLSeqVec.push_back(
613             new LabeledDataSequence( lcl_createDataSequenceAndAddToMap( lcl_aCategoriesRangeName, lcl_aCategoriesRoleName ) ) );
614 
615     // data with labels
616     ::std::vector< Reference< chart2::data::XLabeledDataSequence > > aDataVec;
617     const sal_Int32 nCount = (bUseColumns ? m_aInternalData.getColumnCount() : m_aInternalData.getRowCount());
618     for( sal_Int32 nIdx=0; nIdx<nCount; ++nIdx )
619     {
620         aDataVec.push_back(
621             new LabeledDataSequence(
622                 lcl_createDataSequenceAndAddToMap( OUString::valueOf( nIdx )),
623                 lcl_createDataSequenceAndAddToMap( lcl_aLabelRangePrefix + OUString::valueOf( nIdx ))));
624     }
625 
626     // attention: this data provider has the limitation that it stores
627     // internally if data comes from columns or rows. It is intended for
628     // creating only one used data source.
629     // @todo: add this information in the range representation strings
630     m_bDataInColumns = bUseColumns;
631 
632     //reorder labeled sequences according to aSequenceMapping; ignore categories
633     for( sal_Int32 nNewIndex = 0; nNewIndex < aSequenceMapping.getLength(); nNewIndex++ )
634     {
635         std::vector< LabeledDataSequence* >::size_type nOldIndex = aSequenceMapping[nNewIndex];
636         if( nOldIndex < aDataVec.size() )
637         {
638             if( aDataVec[nOldIndex].is() )
639             {
640                 aResultLSeqVec.push_back( aDataVec[nOldIndex] );
641                 aDataVec[nOldIndex] = 0;
642             }
643         }
644     }
645 
646     //add left over data sequences to result
647     ::std::vector< Reference< chart2::data::XLabeledDataSequence > >::iterator aIt(aDataVec.begin());
648     const ::std::vector< Reference< chart2::data::XLabeledDataSequence > >::const_iterator aEndIt(aDataVec.end());
649     for( ;aIt!=aEndIt; ++aIt)
650     {
651         if( aIt->is() )
652             aResultLSeqVec.push_back( *aIt );
653     }
654 
655     return new DataSource( ContainerHelper::ContainerToSequence(aResultLSeqVec) );
656 }
657 
detectArguments(const Reference<chart2::data::XDataSource> &)658 Sequence< beans::PropertyValue > SAL_CALL InternalDataProvider::detectArguments(
659     const Reference< chart2::data::XDataSource >& /* xDataSource */ )
660     throw (uno::RuntimeException)
661 {
662     Sequence< beans::PropertyValue > aArguments( 4 );
663     aArguments[0] = beans::PropertyValue(
664         C2U("CellRangeRepresentation"), -1, uno::makeAny( lcl_aCompleteRange ),
665         beans::PropertyState_DIRECT_VALUE );
666     aArguments[1] = beans::PropertyValue(
667         C2U("DataRowSource"), -1, uno::makeAny(
668             m_bDataInColumns
669             ? ::com::sun::star::chart::ChartDataRowSource_COLUMNS
670             : ::com::sun::star::chart::ChartDataRowSource_ROWS ),
671         beans::PropertyState_DIRECT_VALUE );
672     // internal data always contains labels and categories
673     aArguments[2] = beans::PropertyValue(
674         C2U("FirstCellAsLabel"), -1, uno::makeAny( true ), beans::PropertyState_DIRECT_VALUE );
675     aArguments[3] = beans::PropertyValue(
676         C2U("HasCategories"), -1, uno::makeAny( true ), beans::PropertyState_DIRECT_VALUE );
677 
678     // #i85913# Sequence Mapping is not needed for internal data, as it is
679     // applied to the data when the data source is created.
680 
681     return aArguments;
682 }
683 
createDataSequenceByRangeRepresentationPossible(const OUString &)684 ::sal_Bool SAL_CALL InternalDataProvider::createDataSequenceByRangeRepresentationPossible( const OUString& /* aRangeRepresentation */ )
685     throw (uno::RuntimeException)
686 {
687     return true;
688 }
689 
createDataSequenceByRangeRepresentation(const OUString & aRangeRepresentation)690 Reference< chart2::data::XDataSequence > SAL_CALL InternalDataProvider::createDataSequenceByRangeRepresentation(
691     const OUString& aRangeRepresentation )
692     throw (lang::IllegalArgumentException,
693            uno::RuntimeException)
694 {
695     if( aRangeRepresentation.match( lcl_aCategoriesRangeName ))
696     {
697         OSL_ASSERT( aRangeRepresentation.equals( lcl_aCategoriesRangeName ) );//it is not expected nor implmented that only parts of the categories are really requested
698 
699         // categories
700         return lcl_createDataSequenceAndAddToMap( lcl_aCategoriesRangeName, lcl_aCategoriesRoleName );
701     }
702     else if( aRangeRepresentation.match( lcl_aLabelRangePrefix ))
703     {
704         // label
705         sal_Int32 nIndex = aRangeRepresentation.copy( lcl_aLabelRangePrefix.getLength()).toInt32();
706         return lcl_createDataSequenceAndAddToMap( lcl_aLabelRangePrefix + OUString::valueOf( nIndex ));
707     }
708     else if( aRangeRepresentation.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "last" )))
709     {
710         sal_Int32 nIndex = (m_bDataInColumns
711                             ? m_aInternalData.getColumnCount()
712                             : m_aInternalData.getRowCount()) - 1;
713         return lcl_createDataSequenceAndAddToMap( OUString::valueOf( nIndex ));
714     }
715     else if( !aRangeRepresentation.isEmpty() )
716     {
717         // data
718         sal_Int32 nIndex = aRangeRepresentation.toInt32();
719         return lcl_createDataSequenceAndAddToMap( OUString::valueOf( nIndex ));
720     }
721 
722     return Reference< chart2::data::XDataSequence >();
723 }
724 
getRangeSelection()725 Reference< sheet::XRangeSelection > SAL_CALL InternalDataProvider::getRangeSelection()
726     throw (uno::RuntimeException)
727 {
728     // there is no range selection component
729     return Reference< sheet::XRangeSelection >();
730 }
731 
732 // ____ XInternalDataProvider ____
hasDataByRangeRepresentation(const OUString & aRange)733 ::sal_Bool SAL_CALL InternalDataProvider::hasDataByRangeRepresentation( const OUString& aRange )
734     throw (uno::RuntimeException)
735 {
736     sal_Bool bResult = false;
737 
738     if( aRange.match( lcl_aCategoriesRangeName ))
739     {
740         OSL_ASSERT( aRange.equals( lcl_aCategoriesRangeName ) );//it is not expected nor implmented that only parts of the categories are really requested
741         bResult = true;
742     }
743     else if( aRange.match( lcl_aLabelRangePrefix ))
744     {
745         sal_Int32 nIndex = aRange.copy( lcl_aLabelRangePrefix.getLength()).toInt32();
746         bResult = (nIndex < (m_bDataInColumns ? m_aInternalData.getColumnCount(): m_aInternalData.getRowCount()));
747     }
748     else
749     {
750         sal_Int32 nIndex = aRange.toInt32();
751         bResult = (nIndex < (m_bDataInColumns ? m_aInternalData.getColumnCount(): m_aInternalData.getRowCount()));
752     }
753 
754     return bResult;
755 }
756 
getDataByRangeRepresentation(const OUString & aRange)757 Sequence< uno::Any > SAL_CALL InternalDataProvider::getDataByRangeRepresentation( const OUString& aRange )
758     throw (uno::RuntimeException)
759 {
760     Sequence< uno::Any > aResult;
761 
762     if( aRange.match( lcl_aLabelRangePrefix ) )
763     {
764         sal_Int32 nIndex = aRange.copy( lcl_aLabelRangePrefix.getLength()).toInt32();
765         vector< uno::Any > aComplexLabel = m_bDataInColumns
766             ? m_aInternalData.getComplexColumnLabel( nIndex )
767             : m_aInternalData.getComplexRowLabel( nIndex );
768         if( !aComplexLabel.empty() )
769             aResult = ContainerHelper::ContainerToSequence(aComplexLabel);
770     }
771     else if( aRange.match( lcl_aCategoriesPointRangeNamePrefix ) )
772     {
773         sal_Int32 nPointIndex = aRange.copy( lcl_aCategoriesPointRangeNamePrefix.getLength() ).toInt32();
774         vector< uno::Any > aComplexCategory = m_bDataInColumns
775             ? m_aInternalData.getComplexRowLabel( nPointIndex )
776             : m_aInternalData.getComplexColumnLabel( nPointIndex );
777         if( !aComplexCategory.empty() )
778             aResult = ContainerHelper::ContainerToSequence(aComplexCategory);
779     }
780     else if( aRange.match( lcl_aCategoriesLevelRangeNamePrefix ) )
781     {
782         sal_Int32 nLevel = aRange.copy( lcl_aCategoriesLevelRangeNamePrefix.getLength() ).toInt32();
783         vector< vector< uno::Any > > aCategories( m_bDataInColumns ? m_aInternalData.getComplexRowLabels() : m_aInternalData.getComplexColumnLabels());
784         if( nLevel < lcl_getInnerLevelCount( aCategories ) )
785         {
786             aResult.realloc( aCategories.size() );
787             transform( aCategories.begin(), aCategories.end(),
788                        aResult.getArray(), lcl_copyFromLevel(nLevel) );
789         }
790     }
791     else if( aRange.equals( lcl_aCategoriesRangeName ) )
792     {
793         vector< vector< uno::Any > > aCategories( m_bDataInColumns ? m_aInternalData.getComplexRowLabels() : m_aInternalData.getComplexColumnLabels());
794         sal_Int32 nLevelCount = lcl_getInnerLevelCount( aCategories );
795         if( nLevelCount == 1 )
796         {
797             sal_Int32 nL=0;
798             aResult = this->getDataByRangeRepresentation( lcl_aCategoriesLevelRangeNamePrefix + OUString::valueOf( nL ) );
799         }
800         else
801         {
802             Sequence< OUString > aLabels = m_bDataInColumns ? this->getRowDescriptions() : this->getColumnDescriptions();
803             aResult.realloc( aLabels.getLength() );
804             transform( aLabels.getConstArray(), aLabels.getConstArray() + aLabels.getLength(),
805                        aResult.getArray(), CommonFunctors::makeAny< OUString >() );
806         }
807     }
808     else
809     {
810         sal_Int32 nIndex = aRange.toInt32();
811         if( nIndex >= 0 )
812         {
813             Sequence< double > aData;
814             if( m_bDataInColumns )
815                 aData = m_aInternalData.getColumnValues(nIndex);
816             else
817                 aData = m_aInternalData.getRowValues(nIndex);
818             if( aData.getLength() )
819             {
820 			    aResult.realloc( aData.getLength());
821                 transform( aData.getConstArray(), aData.getConstArray() + aData.getLength(),
822                            aResult.getArray(), CommonFunctors::makeAny< double >());
823             }
824         }
825     }
826 
827     return aResult;
828 }
829 
setDataByRangeRepresentation(const OUString & aRange,const Sequence<uno::Any> & aNewData)830 void SAL_CALL InternalDataProvider::setDataByRangeRepresentation(
831     const OUString& aRange, const Sequence< uno::Any >& aNewData )
832     throw (uno::RuntimeException)
833 {
834     vector< uno::Any > aNewVector( ContainerHelper::SequenceToVector(aNewData) );
835     if( aRange.match( lcl_aLabelRangePrefix ) )
836     {
837         sal_uInt32 nIndex = aRange.copy( lcl_aLabelRangePrefix.getLength()).toInt32();
838         if( m_bDataInColumns )
839             m_aInternalData.setComplexColumnLabel( nIndex, aNewVector );
840         else
841             m_aInternalData.setComplexRowLabel( nIndex, aNewVector );
842     }
843     else if( aRange.match( lcl_aCategoriesPointRangeNamePrefix ) )
844     {
845         sal_Int32 nPointIndex = aRange.copy( lcl_aCategoriesLevelRangeNamePrefix.getLength()).toInt32();
846         if( m_bDataInColumns )
847             m_aInternalData.setComplexRowLabel( nPointIndex, aNewVector );
848         else
849             m_aInternalData.setComplexColumnLabel( nPointIndex, aNewVector );
850     }
851     else if( aRange.match( lcl_aCategoriesLevelRangeNamePrefix ) )
852     {
853         sal_Int32 nLevel = aRange.copy( lcl_aCategoriesLevelRangeNamePrefix.getLength()).toInt32();
854         vector< vector< uno::Any > > aComplexCategories = m_bDataInColumns ? m_aInternalData.getComplexRowLabels() : m_aInternalData.getComplexColumnLabels();
855 
856         //ensure equal length
857         if( aNewVector.size() > aComplexCategories.size() )
858             aComplexCategories.resize( aNewVector.size() );
859         else if( aNewVector.size() < aComplexCategories.size() )
860             aNewVector.resize( aComplexCategories.size() );
861 
862         transform( aComplexCategories.begin(), aComplexCategories.end(), aNewVector.begin(),
863                    aComplexCategories.begin(), lcl_setAnyAtLevel(nLevel) );
864 
865         if( m_bDataInColumns )
866             m_aInternalData.setComplexRowLabels( aComplexCategories );
867         else
868             m_aInternalData.setComplexColumnLabels( aComplexCategories );
869     }
870     else if( aRange.equals( lcl_aCategoriesRangeName ) )
871     {
872         vector< vector< uno::Any > > aComplexCategories;
873         aComplexCategories.resize( aNewVector.size() );
874         transform( aComplexCategories.begin(), aComplexCategories.end(), aNewVector.begin(),
875                             aComplexCategories.begin(), lcl_setAnyAtLevel(0) );
876         if( m_bDataInColumns )
877             m_aInternalData.setComplexRowLabels( aComplexCategories );
878         else
879             m_aInternalData.setComplexColumnLabels( aComplexCategories );
880     }
881     else
882     {
883         sal_Int32 nIndex = aRange.toInt32();
884         if( nIndex>=0 )
885         {
886             vector< double > aNewDataVec;
887             transform( aNewData.getConstArray(), aNewData.getConstArray() + aNewData.getLength(),
888                        back_inserter( aNewDataVec ), CommonFunctors::AnyToDouble());
889             if( m_bDataInColumns )
890                 m_aInternalData.setColumnValues( nIndex, aNewDataVec );
891             else
892                 m_aInternalData.setRowValues( nIndex, aNewDataVec );
893         }
894     }
895 }
896 
insertSequence(::sal_Int32 nAfterIndex)897 void SAL_CALL InternalDataProvider::insertSequence( ::sal_Int32 nAfterIndex )
898     throw (uno::RuntimeException)
899 {
900     if( m_bDataInColumns )
901     {
902         lcl_increaseMapReferences( nAfterIndex + 1, m_aInternalData.getColumnCount());
903         m_aInternalData.insertColumn( nAfterIndex );
904     }
905     else
906     {
907         lcl_increaseMapReferences( nAfterIndex + 1, m_aInternalData.getRowCount());
908         m_aInternalData.insertRow( nAfterIndex );
909     }
910 }
911 
deleteSequence(::sal_Int32 nAtIndex)912 void SAL_CALL InternalDataProvider::deleteSequence( ::sal_Int32 nAtIndex )
913     throw (uno::RuntimeException)
914 {
915     lcl_deleteMapReferences( OUString::valueOf( nAtIndex ));
916     lcl_deleteMapReferences( lcl_aLabelRangePrefix + OUString::valueOf( nAtIndex ));
917     if( m_bDataInColumns )
918     {
919         lcl_decreaseMapReferences( nAtIndex + 1, m_aInternalData.getColumnCount());
920         m_aInternalData.deleteColumn( nAtIndex );
921     }
922     else
923     {
924         lcl_decreaseMapReferences( nAtIndex + 1, m_aInternalData.getRowCount());
925         m_aInternalData.deleteRow( nAtIndex );
926     }
927 }
928 
appendSequence()929 void SAL_CALL InternalDataProvider::appendSequence()
930     throw (uno::RuntimeException)
931 {
932     if( m_bDataInColumns )
933         m_aInternalData.appendColumn();
934     else
935         m_aInternalData.appendRow();
936 }
937 
insertComplexCategoryLevel(sal_Int32 nLevel)938 void SAL_CALL InternalDataProvider::insertComplexCategoryLevel( sal_Int32 nLevel )
939         throw (uno::RuntimeException)
940 {
941     OSL_ENSURE( nLevel> 0, "you can only insert category levels > 0" );//the first categories level cannot be deleted, check the calling code for error
942     if( nLevel>0 )
943     {
944         vector< vector< uno::Any > > aComplexCategories = m_bDataInColumns ? m_aInternalData.getComplexRowLabels() : m_aInternalData.getComplexColumnLabels();
945         ::std::for_each( aComplexCategories.begin(), aComplexCategories.end(), lcl_insertAnyAtLevel(nLevel) );
946         if( m_bDataInColumns )
947             m_aInternalData.setComplexRowLabels( aComplexCategories );
948         else
949             m_aInternalData.setComplexColumnLabels( aComplexCategories );
950 
951         tSequenceMapRange aRange( m_aSequenceMap.equal_range( lcl_aCategoriesRangeName ));
952         ::std::for_each( aRange.first, aRange.second, lcl_setModified());
953     }
954 }
deleteComplexCategoryLevel(sal_Int32 nLevel)955 void SAL_CALL InternalDataProvider::deleteComplexCategoryLevel( sal_Int32 nLevel )
956         throw (uno::RuntimeException)
957 {
958     OSL_ENSURE( nLevel>0, "you can only delete category levels > 0" );//the first categories level cannot be deleted, check the calling code for error
959     if( nLevel>0 )
960     {
961         vector< vector< uno::Any > > aComplexCategories = m_bDataInColumns ? m_aInternalData.getComplexRowLabels() : m_aInternalData.getComplexColumnLabels();
962         ::std::for_each( aComplexCategories.begin(), aComplexCategories.end(), lcl_removeAnyAtLevel(nLevel) );
963         if( m_bDataInColumns )
964             m_aInternalData.setComplexRowLabels( aComplexCategories );
965         else
966             m_aInternalData.setComplexColumnLabels( aComplexCategories );
967 
968         tSequenceMapRange aRange( m_aSequenceMap.equal_range( lcl_aCategoriesRangeName ));
969         ::std::for_each( aRange.first, aRange.second, lcl_setModified());
970     }
971 }
972 
insertDataPointForAllSequences(::sal_Int32 nAfterIndex)973 void SAL_CALL InternalDataProvider::insertDataPointForAllSequences( ::sal_Int32 nAfterIndex )
974     throw (uno::RuntimeException)
975 {
976     sal_Int32 nMaxRep = 0;
977     if( m_bDataInColumns )
978     {
979         m_aInternalData.insertRow( nAfterIndex );
980         nMaxRep = m_aInternalData.getColumnCount();
981     }
982     else
983     {
984         m_aInternalData.insertColumn( nAfterIndex );
985         nMaxRep = m_aInternalData.getRowCount();
986     }
987 
988     // notify change to all affected ranges
989     tSequenceMap::const_iterator aBegin( m_aSequenceMap.lower_bound( C2U("0")));
990     tSequenceMap::const_iterator aEnd( m_aSequenceMap.upper_bound( OUString::valueOf( nMaxRep )));
991     ::std::for_each( aBegin, aEnd, lcl_setModified());
992 
993     tSequenceMapRange aRange( m_aSequenceMap.equal_range( lcl_aCategoriesRangeName ));
994     ::std::for_each( aRange.first, aRange.second, lcl_setModified());
995 }
996 
deleteDataPointForAllSequences(::sal_Int32 nAtIndex)997 void SAL_CALL InternalDataProvider::deleteDataPointForAllSequences( ::sal_Int32 nAtIndex )
998     throw (uno::RuntimeException)
999 {
1000     sal_Int32 nMaxRep = 0;
1001     if( m_bDataInColumns )
1002     {
1003         m_aInternalData.deleteRow( nAtIndex );
1004         nMaxRep = m_aInternalData.getColumnCount();
1005     }
1006     else
1007     {
1008         m_aInternalData.deleteColumn( nAtIndex );
1009         nMaxRep = m_aInternalData.getRowCount();
1010     }
1011 
1012     // notify change to all affected ranges
1013     tSequenceMap::const_iterator aBegin( m_aSequenceMap.lower_bound( C2U("0")));
1014     tSequenceMap::const_iterator aEnd( m_aSequenceMap.upper_bound( OUString::valueOf( nMaxRep )));
1015     ::std::for_each( aBegin, aEnd, lcl_setModified());
1016 
1017     tSequenceMapRange aRange( m_aSequenceMap.equal_range( lcl_aCategoriesRangeName ));
1018     ::std::for_each( aRange.first, aRange.second, lcl_setModified());
1019 }
1020 
swapDataPointWithNextOneForAllSequences(::sal_Int32 nAtIndex)1021 void SAL_CALL InternalDataProvider::swapDataPointWithNextOneForAllSequences( ::sal_Int32 nAtIndex )
1022     throw (uno::RuntimeException)
1023 {
1024     if( m_bDataInColumns )
1025         m_aInternalData.swapRowWithNext( nAtIndex );
1026     else
1027         m_aInternalData.swapColumnWithNext( nAtIndex );
1028     sal_Int32 nMaxRep = (m_bDataInColumns
1029                          ? m_aInternalData.getColumnCount()
1030                          : m_aInternalData.getRowCount());
1031 
1032     // notify change to all affected ranges
1033     tSequenceMap::const_iterator aBegin( m_aSequenceMap.lower_bound( C2U("0")));
1034     tSequenceMap::const_iterator aEnd( m_aSequenceMap.upper_bound( OUString::valueOf( nMaxRep )));
1035     ::std::for_each( aBegin, aEnd, lcl_setModified());
1036 
1037     tSequenceMapRange aRange( m_aSequenceMap.equal_range( lcl_aCategoriesRangeName ));
1038     ::std::for_each( aRange.first, aRange.second, lcl_setModified());
1039 }
1040 
registerDataSequenceForChanges(const Reference<chart2::data::XDataSequence> & xSeq)1041 void SAL_CALL InternalDataProvider::registerDataSequenceForChanges( const Reference< chart2::data::XDataSequence >& xSeq )
1042     throw (uno::RuntimeException)
1043 {
1044     if( xSeq.is())
1045         lcl_addDataSequenceToMap( xSeq->getSourceRangeRepresentation(), xSeq );
1046 }
1047 
1048 
1049 // ____ XRangeXMLConversion ____
convertRangeToXML(const OUString & aRangeRepresentation)1050 OUString SAL_CALL InternalDataProvider::convertRangeToXML( const OUString& aRangeRepresentation )
1051     throw (lang::IllegalArgumentException,
1052            uno::RuntimeException)
1053 {
1054     XMLRangeHelper::CellRange aRange;
1055     aRange.aTableName = OUString(RTL_CONSTASCII_USTRINGPARAM("local-table"));
1056 
1057     // attention: this data provider has the limitation that it stores
1058     // internally if data comes from columns or rows. It is intended for
1059     // creating only one used data source.
1060     // @todo: add this information in the range representation strings
1061     if( aRangeRepresentation.match( lcl_aCategoriesRangeName ))
1062     {
1063         OSL_ASSERT( aRangeRepresentation.equals( lcl_aCategoriesRangeName ) );//it is not expected nor implmented that only parts of the categories are really requested
1064         aRange.aUpperLeft.bIsEmpty = false;
1065         if( m_bDataInColumns )
1066         {
1067             aRange.aUpperLeft.nColumn = 0;
1068             aRange.aUpperLeft.nRow = 1;
1069             aRange.aLowerRight = aRange.aUpperLeft;
1070             aRange.aLowerRight.nRow = m_aInternalData.getRowCount();
1071         }
1072         else
1073         {
1074             aRange.aUpperLeft.nColumn = 1;
1075             aRange.aUpperLeft.nRow = 0;
1076             aRange.aLowerRight = aRange.aUpperLeft;
1077             aRange.aLowerRight.nColumn = m_aInternalData.getColumnCount();
1078         }
1079     }
1080     else if( aRangeRepresentation.match( lcl_aLabelRangePrefix ))
1081     {
1082         sal_Int32 nIndex = aRangeRepresentation.copy( lcl_aLabelRangePrefix.getLength()).toInt32();
1083         aRange.aUpperLeft.bIsEmpty = false;
1084         aRange.aLowerRight.bIsEmpty = true;
1085         if( m_bDataInColumns )
1086         {
1087             aRange.aUpperLeft.nColumn = nIndex + 1;
1088             aRange.aUpperLeft.nRow = 0;
1089         }
1090         else
1091         {
1092             aRange.aUpperLeft.nColumn = 0;
1093             aRange.aUpperLeft.nRow = nIndex + 1;
1094         }
1095     }
1096     else if( aRangeRepresentation.equals( lcl_aCompleteRange ))
1097     {
1098         aRange.aUpperLeft.bIsEmpty = false;
1099         aRange.aLowerRight.bIsEmpty = false;
1100         aRange.aUpperLeft.nColumn = 0;
1101         aRange.aUpperLeft.nRow = 0;
1102         aRange.aLowerRight.nColumn = m_aInternalData.getColumnCount();
1103         aRange.aLowerRight.nRow = m_aInternalData.getRowCount();
1104     }
1105     else
1106     {
1107         sal_Int32 nIndex = aRangeRepresentation.toInt32();
1108         aRange.aUpperLeft.bIsEmpty = false;
1109         if( m_bDataInColumns )
1110         {
1111             aRange.aUpperLeft.nColumn = nIndex + 1;
1112             aRange.aUpperLeft.nRow = 1;
1113             aRange.aLowerRight = aRange.aUpperLeft;
1114             aRange.aLowerRight.nRow = m_aInternalData.getRowCount();
1115         }
1116         else
1117         {
1118             aRange.aUpperLeft.nColumn = 1;
1119             aRange.aUpperLeft.nRow = nIndex + 1;
1120             aRange.aLowerRight = aRange.aUpperLeft;
1121             aRange.aLowerRight.nColumn = m_aInternalData.getColumnCount();
1122         }
1123     }
1124 
1125     return XMLRangeHelper::getXMLStringFromCellRange( aRange );
1126 }
1127 
convertRangeFromXML(const OUString & aXMLRange)1128 OUString SAL_CALL InternalDataProvider::convertRangeFromXML( const OUString& aXMLRange )
1129     throw (lang::IllegalArgumentException,
1130            uno::RuntimeException)
1131 {
1132     XMLRangeHelper::CellRange aRange( XMLRangeHelper::getCellRangeFromXMLString( aXMLRange ));
1133     if( aRange.aUpperLeft.bIsEmpty )
1134     {
1135         OSL_ENSURE( aRange.aLowerRight.bIsEmpty, "Weird Range" );
1136         return OUString();
1137     }
1138 
1139     // "all"
1140     if( !aRange.aLowerRight.bIsEmpty &&
1141         ( aRange.aUpperLeft.nColumn != aRange.aLowerRight.nColumn ) &&
1142         ( aRange.aUpperLeft.nRow != aRange.aLowerRight.nRow ) )
1143         return lcl_aCompleteRange;
1144 
1145     // attention: this data provider has the limitation that it stores
1146     // internally if data comes from columns or rows. It is intended for
1147     // creating only one used data source.
1148     // @todo: add this information in the range representation strings
1149 
1150     // data in columns
1151     if( m_bDataInColumns )
1152     {
1153         if( aRange.aUpperLeft.nColumn == 0 )
1154             return lcl_aCategoriesRangeName;
1155         if( aRange.aUpperLeft.nRow == 0 )
1156             return lcl_aLabelRangePrefix + OUString::valueOf( aRange.aUpperLeft.nColumn - 1 );
1157 
1158         return OUString::valueOf( aRange.aUpperLeft.nColumn - 1 );
1159     }
1160 
1161     // data in rows
1162     if( aRange.aUpperLeft.nRow == 0 )
1163         return lcl_aCategoriesRangeName;
1164     if( aRange.aUpperLeft.nColumn == 0 )
1165         return lcl_aLabelRangePrefix + OUString::valueOf( aRange.aUpperLeft.nRow - 1 );
1166 
1167     return OUString::valueOf( aRange.aUpperLeft.nRow - 1 );
1168 }
1169 
1170 namespace
1171 {
1172 
1173 template< class Type >
lcl_convertVectorVectorToSequenceSequence(const vector<vector<Type>> & rIn)1174 Sequence< Sequence< Type > > lcl_convertVectorVectorToSequenceSequence( const vector< vector< Type > >& rIn )
1175 {
1176     Sequence< Sequence< Type > > aRet;
1177     sal_Int32 nOuterCount = rIn.size();
1178     if( nOuterCount )
1179     {
1180         aRet.realloc(nOuterCount);
1181         for( sal_Int32 nN=0; nN<nOuterCount; nN++)
1182             aRet[nN]= ContainerHelper::ContainerToSequence( rIn[nN] );
1183     }
1184     return aRet;
1185 }
1186 
1187 template< class Type >
lcl_convertSequenceSequenceToVectorVector(const Sequence<Sequence<Type>> & rIn)1188 vector< vector< Type > > lcl_convertSequenceSequenceToVectorVector( const Sequence< Sequence< Type > >& rIn )
1189 {
1190     vector< vector< Type > > aRet;
1191     sal_Int32 nOuterCount = rIn.getLength();
1192     if( nOuterCount )
1193     {
1194         aRet.resize(nOuterCount);
1195         for( sal_Int32 nN=0; nN<nOuterCount; nN++)
1196             aRet[nN]= ContainerHelper::SequenceToVector( rIn[nN] );
1197     }
1198     return aRet;
1199 }
1200 
lcl_convertComplexAnyVectorToStringSequence(const vector<vector<uno::Any>> & rIn)1201 Sequence< Sequence< OUString > > lcl_convertComplexAnyVectorToStringSequence( const vector< vector< uno::Any > >& rIn )
1202 {
1203     Sequence< Sequence< OUString > > aRet;
1204     sal_Int32 nOuterCount = rIn.size();
1205     if( nOuterCount )
1206     {
1207         aRet.realloc(nOuterCount);
1208         for( sal_Int32 nN=0; nN<nOuterCount; nN++)
1209             aRet[nN]= lcl_AnyToStringSequence( ContainerHelper::ContainerToSequence( rIn[nN] ) );
1210     }
1211     return aRet;
1212 }
1213 
lcl_convertComplexStringSequenceToAnyVector(const Sequence<Sequence<OUString>> & rIn)1214 vector< vector< uno::Any > > lcl_convertComplexStringSequenceToAnyVector( const Sequence< Sequence< OUString > >& rIn )
1215 {
1216     vector< vector< uno::Any > > aRet;
1217     sal_Int32 nOuterCount = rIn.getLength();
1218     for( sal_Int32 nN=0; nN<nOuterCount; nN++)
1219         aRet.push_back( ContainerHelper::SequenceToVector( lcl_StringToAnySequence( rIn[nN] ) ) );
1220     return aRet;
1221 }
1222 
1223 class SplitCategoriesProvider_ForComplexDescriptions : public SplitCategoriesProvider
1224 {
1225 public:
1226 
SplitCategoriesProvider_ForComplexDescriptions(const::std::vector<::std::vector<uno::Any>> & rComplexDescriptions)1227     explicit SplitCategoriesProvider_ForComplexDescriptions( const ::std::vector< ::std::vector< uno::Any > >& rComplexDescriptions )
1228         : m_rComplexDescriptions( rComplexDescriptions )
1229     {}
~SplitCategoriesProvider_ForComplexDescriptions()1230     virtual ~SplitCategoriesProvider_ForComplexDescriptions()
1231     {}
1232 
1233     virtual sal_Int32 getLevelCount() const;
1234     virtual uno::Sequence< rtl::OUString > getStringsForLevel( sal_Int32 nIndex ) const;
1235 
1236 private:
1237     const ::std::vector< ::std::vector< uno::Any > >& m_rComplexDescriptions;
1238 };
1239 
getLevelCount() const1240 sal_Int32 SplitCategoriesProvider_ForComplexDescriptions::getLevelCount() const
1241 {
1242     return lcl_getInnerLevelCount( m_rComplexDescriptions );
1243 }
getStringsForLevel(sal_Int32 nLevel) const1244 uno::Sequence< rtl::OUString > SplitCategoriesProvider_ForComplexDescriptions::getStringsForLevel( sal_Int32 nLevel ) const
1245 {
1246     uno::Sequence< rtl::OUString > aResult;
1247     if( nLevel < lcl_getInnerLevelCount( m_rComplexDescriptions ) )
1248     {
1249         aResult.realloc( m_rComplexDescriptions.size() );
1250         transform( m_rComplexDescriptions.begin(), m_rComplexDescriptions.end(),
1251                    aResult.getArray(), lcl_getStringFromLevelVector(nLevel) );
1252     }
1253     return aResult;
1254 }
1255 
1256 }//anonymous namespace
1257 
1258 // ____ XDateCategories ____
getDateCategories()1259 Sequence< double > SAL_CALL InternalDataProvider::getDateCategories() throw (uno::RuntimeException)
1260 {
1261     double fNan = InternalDataProvider::getNotANumber();
1262     double fValue = fNan;
1263     vector< vector< uno::Any > > aCategories( m_bDataInColumns ? m_aInternalData.getComplexRowLabels() : m_aInternalData.getComplexColumnLabels());
1264     sal_Int32 nCount = aCategories.size();
1265     Sequence< double > aDoubles( nCount );
1266     vector< vector< uno::Any > >::iterator aIt( aCategories.begin() );
1267     vector< vector< uno::Any > >::const_iterator aEnd( aCategories.end() );
1268     for(sal_Int32 nN=0; nN<nCount && aIt!=aEnd; ++nN, ++aIt )
1269     {
1270         if( !( !aIt->empty() && ((*aIt)[0]>>=fValue) ) )
1271             fValue = fNan;
1272         aDoubles[nN]=fValue;
1273     }
1274     return aDoubles;
1275 }
1276 
setDateCategories(const Sequence<double> & rDates)1277 void SAL_CALL InternalDataProvider::setDateCategories( const Sequence< double >& rDates ) throw (uno::RuntimeException)
1278 {
1279     sal_Int32 nCount = rDates.getLength();
1280     vector< vector< uno::Any > > aNewCategories;
1281     aNewCategories.reserve(nCount);
1282     vector< uno::Any > aSingleLabel(1);
1283 
1284     for(sal_Int32 nN=0; nN<nCount; ++nN )
1285     {
1286         aSingleLabel[0]=uno::makeAny(rDates[nN]);
1287         aNewCategories.push_back(aSingleLabel);
1288     }
1289 
1290     if( m_bDataInColumns )
1291         m_aInternalData.setComplexRowLabels( aNewCategories );
1292     else
1293         m_aInternalData.setComplexColumnLabels( aNewCategories );
1294 }
1295 
1296 // ____ XAnyDescriptionAccess ____
getAnyRowDescriptions()1297 Sequence< Sequence< uno::Any > > SAL_CALL InternalDataProvider::getAnyRowDescriptions() throw (uno::RuntimeException)
1298 {
1299     return lcl_convertVectorVectorToSequenceSequence( m_aInternalData.getComplexRowLabels() );
1300 }
setAnyRowDescriptions(const Sequence<Sequence<uno::Any>> & aRowDescriptions)1301 void SAL_CALL InternalDataProvider::setAnyRowDescriptions( const Sequence< Sequence< uno::Any > >& aRowDescriptions ) throw (uno::RuntimeException)
1302 {
1303     m_aInternalData.setComplexRowLabels( lcl_convertSequenceSequenceToVectorVector( aRowDescriptions ) );
1304 }
getAnyColumnDescriptions()1305 Sequence< Sequence< uno::Any > > SAL_CALL InternalDataProvider::getAnyColumnDescriptions() throw (uno::RuntimeException)
1306 {
1307     return lcl_convertVectorVectorToSequenceSequence( m_aInternalData.getComplexColumnLabels() );
1308 }
setAnyColumnDescriptions(const Sequence<Sequence<uno::Any>> & aColumnDescriptions)1309 void SAL_CALL InternalDataProvider::setAnyColumnDescriptions( const Sequence< Sequence< uno::Any > >& aColumnDescriptions ) throw (uno::RuntimeException)
1310 {
1311     m_aInternalData.setComplexColumnLabels( lcl_convertSequenceSequenceToVectorVector( aColumnDescriptions ) );
1312 }
1313 
1314 // ____ XComplexDescriptionAccess ____
getComplexRowDescriptions()1315 Sequence< Sequence< OUString > > SAL_CALL InternalDataProvider::getComplexRowDescriptions() throw (uno::RuntimeException)
1316 {
1317     return lcl_convertComplexAnyVectorToStringSequence( m_aInternalData.getComplexRowLabels() );
1318 }
setComplexRowDescriptions(const Sequence<Sequence<::rtl::OUString>> & aRowDescriptions)1319 void SAL_CALL InternalDataProvider::setComplexRowDescriptions( const Sequence< Sequence< ::rtl::OUString > >& aRowDescriptions ) throw (uno::RuntimeException)
1320 {
1321     m_aInternalData.setComplexRowLabels( lcl_convertComplexStringSequenceToAnyVector(aRowDescriptions) );
1322 }
getComplexColumnDescriptions()1323 Sequence< Sequence< ::rtl::OUString > > SAL_CALL InternalDataProvider::getComplexColumnDescriptions() throw (uno::RuntimeException)
1324 {
1325     return lcl_convertComplexAnyVectorToStringSequence( m_aInternalData.getComplexColumnLabels() );
1326 }
setComplexColumnDescriptions(const Sequence<Sequence<::rtl::OUString>> & aColumnDescriptions)1327 void SAL_CALL InternalDataProvider::setComplexColumnDescriptions( const Sequence< Sequence< ::rtl::OUString > >& aColumnDescriptions ) throw (uno::RuntimeException)
1328 {
1329     m_aInternalData.setComplexColumnLabels( lcl_convertComplexStringSequenceToAnyVector(aColumnDescriptions) );
1330 }
1331 
1332 // ____ XChartDataArray ____
getData()1333 Sequence< Sequence< double > > SAL_CALL InternalDataProvider::getData()
1334     throw (uno::RuntimeException)
1335 {
1336     return m_aInternalData.getData();
1337 }
1338 
setData(const Sequence<Sequence<double>> & rDataInRows)1339 void SAL_CALL InternalDataProvider::setData( const Sequence< Sequence< double > >& rDataInRows )
1340     throw (uno::RuntimeException)
1341 {
1342     return m_aInternalData.setData( rDataInRows );
1343 }
1344 
setRowDescriptions(const Sequence<OUString> & aRowDescriptions)1345 void SAL_CALL InternalDataProvider::setRowDescriptions( const Sequence< OUString >& aRowDescriptions )
1346     throw (uno::RuntimeException)
1347 {
1348     vector< vector< uno::Any > > aComplexDescriptions( aRowDescriptions.getLength() );
1349     transform( aComplexDescriptions.begin(), aComplexDescriptions.end(), aRowDescriptions.getConstArray(),
1350                aComplexDescriptions.begin(), lcl_setAnyAtLevelFromStringSequence(0) );
1351     m_aInternalData.setComplexRowLabels( aComplexDescriptions );
1352 }
1353 
setColumnDescriptions(const Sequence<OUString> & aColumnDescriptions)1354 void SAL_CALL InternalDataProvider::setColumnDescriptions( const Sequence< OUString >& aColumnDescriptions )
1355     throw (uno::RuntimeException)
1356 {
1357     vector< vector< uno::Any > > aComplexDescriptions( aColumnDescriptions.getLength() );
1358     transform( aComplexDescriptions.begin(), aComplexDescriptions.end(), aColumnDescriptions.getConstArray(),
1359                aComplexDescriptions.begin(), lcl_setAnyAtLevelFromStringSequence(0) );
1360     m_aInternalData.setComplexColumnLabels( aComplexDescriptions );
1361 }
1362 
getRowDescriptions()1363 Sequence< OUString > SAL_CALL InternalDataProvider::getRowDescriptions()
1364     throw (uno::RuntimeException)
1365 {
1366     vector< vector< uno::Any > > aComplexLabels( m_aInternalData.getComplexRowLabels() );
1367     SplitCategoriesProvider_ForComplexDescriptions aProvider( aComplexLabels );
1368     return ExplicitCategoriesProvider::getExplicitSimpleCategories( aProvider );
1369 }
1370 
getColumnDescriptions()1371 Sequence< OUString > SAL_CALL InternalDataProvider::getColumnDescriptions()
1372     throw (uno::RuntimeException)
1373 {
1374     vector< vector< uno::Any > > aComplexLabels( m_aInternalData.getComplexColumnLabels() );
1375     SplitCategoriesProvider_ForComplexDescriptions aProvider( aComplexLabels );
1376     return ExplicitCategoriesProvider::getExplicitSimpleCategories( aProvider );
1377 }
1378 
1379 // ____ XChartData (base of XChartDataArray) ____
addChartDataChangeEventListener(const Reference<::com::sun::star::chart::XChartDataChangeEventListener> &)1380 void SAL_CALL InternalDataProvider::addChartDataChangeEventListener(
1381     const Reference< ::com::sun::star::chart::XChartDataChangeEventListener >& )
1382     throw (uno::RuntimeException)
1383 {
1384 }
1385 
removeChartDataChangeEventListener(const Reference<::com::sun::star::chart::XChartDataChangeEventListener> &)1386 void SAL_CALL InternalDataProvider::removeChartDataChangeEventListener(
1387     const Reference< ::com::sun::star::chart::XChartDataChangeEventListener >& )
1388     throw (uno::RuntimeException)
1389 {
1390 }
1391 
getNotANumber()1392 double SAL_CALL InternalDataProvider::getNotANumber()
1393     throw (uno::RuntimeException)
1394 {
1395     double fNan;
1396     ::rtl::math::setNan( & fNan );
1397     return fNan;
1398 }
1399 
isNotANumber(double nNumber)1400 ::sal_Bool SAL_CALL InternalDataProvider::isNotANumber( double nNumber )
1401     throw (uno::RuntimeException)
1402 {
1403     return ::rtl::math::isNan( nNumber )
1404         || ::rtl::math::isInf( nNumber );
1405 }
1406 // lang::XInitialization:
initialize(const uno::Sequence<uno::Any> & _aArguments)1407 void SAL_CALL InternalDataProvider::initialize(const uno::Sequence< uno::Any > & _aArguments) throw (uno::RuntimeException, uno::Exception)
1408 {
1409 	comphelper::SequenceAsHashMap aArgs(_aArguments);
1410     if ( aArgs.getUnpackedValueOrDefault(::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("CreateDefaultData")),sal_False) )
1411 		createDefaultData();
1412 }
1413 // ____ XCloneable ____
createClone()1414 Reference< util::XCloneable > SAL_CALL InternalDataProvider::createClone()
1415     throw (uno::RuntimeException)
1416 {
1417     return Reference< util::XCloneable >( new InternalDataProvider( *this ));
1418 }
1419 
1420 
1421 // ================================================================================
1422 
getSupportedServiceNames_Static()1423 Sequence< OUString > InternalDataProvider::getSupportedServiceNames_Static()
1424 {
1425     Sequence< OUString > aServices( 1 );
1426     aServices[ 0 ] = OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.chart2.data.DataProvider" ));
1427     return aServices;
1428 }
1429 
1430 // ================================================================================
1431 
1432 APPHELPER_XSERVICEINFO_IMPL( InternalDataProvider, lcl_aServiceName );
1433 
1434 } //  namespace chart
1435