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::__anon5f1857ed0111::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::__anon5f1857ed0111::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::__anon5f1857ed0111::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::__anon5f1857ed0111::lcl_copyFromLevel208 explicit lcl_copyFromLevel( sal_Int32 nLevel ) : m_nLevel( nLevel )
209 {}
210
operator ()chart::__anon5f1857ed0111::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::__anon5f1857ed0111::lcl_getStringFromLevelVector227 explicit lcl_getStringFromLevelVector( sal_Int32 nLevel ) : m_nLevel( nLevel )
228 {}
229
operator ()chart::__anon5f1857ed0111::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::__anon5f1857ed0111::lcl_setAnyAtLevel247 explicit lcl_setAnyAtLevel( sal_Int32 nLevel ) : m_nLevel( nLevel )
248 {}
249
operator ()chart::__anon5f1857ed0111::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::__anon5f1857ed0111::lcl_setAnyAtLevelFromStringSequence267 explicit lcl_setAnyAtLevelFromStringSequence( sal_Int32 nLevel ) : m_nLevel( nLevel )
268 {}
269
operator ()chart::__anon5f1857ed0111::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::__anon5f1857ed0111::lcl_insertAnyAtLevel287 explicit lcl_insertAnyAtLevel( sal_Int32 nLevel ) : m_nLevel( nLevel )
288 {}
289
operator ()chart::__anon5f1857ed0111::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::__anon5f1857ed0111::lcl_removeAnyAtLevel312 explicit lcl_removeAnyAtLevel( sal_Int32 nLevel ) : m_nLevel( nLevel )
313 {}
314
operator ()chart::__anon5f1857ed0111::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