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