Line data Source code
1 : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 : /*
3 : * This file is part of the LibreOffice project.
4 : *
5 : * This Source Code Form is subject to the terms of the Mozilla Public
6 : * License, v. 2.0. If a copy of the MPL was not distributed with this
7 : * file, You can obtain one at http://mozilla.org/MPL/2.0/.
8 : *
9 : * This file incorporates work covered by the following license notice:
10 : *
11 : * Licensed to the Apache Software Foundation (ASF) under one or more
12 : * contributor license agreements. See the NOTICE file distributed
13 : * with this work for additional information regarding copyright
14 : * ownership. The ASF licenses this file to you under the Apache
15 : * License, Version 2.0 (the "License"); you may not use this file
16 : * except in compliance with the License. You may obtain a copy of
17 : * the License at http://www.apache.org/licenses/LICENSE-2.0 .
18 : */
19 :
20 : #include "ExplicitCategoriesProvider.hxx"
21 : #include "DiagramHelper.hxx"
22 : #include "ChartTypeHelper.hxx"
23 : #include "AxisHelper.hxx"
24 : #include "CommonConverters.hxx"
25 : #include "DataSourceHelper.hxx"
26 : #include "ChartModelHelper.hxx"
27 : #include "ContainerHelper.hxx"
28 : #include "macros.hxx"
29 : #include "NumberFormatterWrapper.hxx"
30 :
31 : #include <com/sun/star/chart2/AxisType.hpp>
32 : #include <com/sun/star/util/NumberFormat.hpp>
33 : #include <com/sun/star/util/XNumberFormatsSupplier.hpp>
34 : #include <com/sun/star/frame/XModel.hpp>
35 :
36 : namespace chart
37 : {
38 :
39 : using namespace ::com::sun::star;
40 : using namespace ::com::sun::star::chart2;
41 : using ::com::sun::star::uno::Reference;
42 : using ::com::sun::star::uno::Sequence;
43 : using ::std::vector;
44 :
45 0 : ExplicitCategoriesProvider::ExplicitCategoriesProvider( const Reference< chart2::XCoordinateSystem >& xCooSysModel
46 : , ChartModel& rModel )
47 : : m_bDirty(true)
48 : , m_xCooSysModel( xCooSysModel )
49 : , mrModel(rModel)
50 : , m_xOriginalCategories()
51 : , m_bIsExplicitCategoriesInited(false)
52 : , m_bIsDateAxis(false)
53 0 : , m_bIsAutoDate(false)
54 : {
55 : try
56 : {
57 0 : if( xCooSysModel.is() )
58 : {
59 0 : uno::Reference< XAxis > xAxis( xCooSysModel->getAxisByDimension(0,0) );
60 0 : if( xAxis.is() )
61 : {
62 0 : ScaleData aScale( xAxis->getScaleData() );
63 0 : m_xOriginalCategories = aScale.Categories;
64 0 : m_bIsAutoDate = (aScale.AutoDateAxis && aScale.AxisType==chart2::AxisType::CATEGORY);
65 0 : m_bIsDateAxis = (aScale.AxisType == chart2::AxisType::DATE || m_bIsAutoDate);
66 0 : }
67 : }
68 :
69 0 : if( m_xOriginalCategories.is() )
70 : {
71 0 : uno::Reference< data::XDataProvider > xDataProvider( mrModel.getDataProvider() );
72 :
73 0 : OUString aCategoriesRange( DataSourceHelper::getRangeFromValues( m_xOriginalCategories ) );
74 0 : if( xDataProvider.is() && !aCategoriesRange.isEmpty() )
75 : {
76 0 : const bool bFirstCellAsLabel = false;
77 0 : const bool bHasCategories = false;
78 0 : const uno::Sequence< sal_Int32 > aSequenceMapping;
79 :
80 0 : uno::Reference< data::XDataSource > xColumnCategoriesSource( xDataProvider->createDataSource(
81 : DataSourceHelper::createArguments( aCategoriesRange, aSequenceMapping, true /*bUseColumns*/
82 0 : , bFirstCellAsLabel, bHasCategories ) ) );
83 :
84 0 : uno::Reference< data::XDataSource > xRowCategoriesSource( xDataProvider->createDataSource(
85 : DataSourceHelper::createArguments( aCategoriesRange, aSequenceMapping, false /*bUseColumns*/
86 0 : , bFirstCellAsLabel, bHasCategories ) ) );
87 :
88 0 : if( xColumnCategoriesSource.is() && xRowCategoriesSource.is() )
89 : {
90 0 : Sequence< Reference< data::XLabeledDataSequence> > aColumns = xColumnCategoriesSource->getDataSequences();
91 0 : Sequence< Reference< data::XLabeledDataSequence> > aRows = xRowCategoriesSource->getDataSequences();
92 :
93 0 : sal_Int32 nColumnCount = aColumns.getLength();
94 0 : sal_Int32 nRowCount = aRows.getLength();
95 0 : if( nColumnCount>1 && nRowCount>1 )
96 : {
97 : //we have complex categories
98 : //->split them in the direction of the first series
99 : //detect whether the first series is a row or a column
100 0 : bool bSeriesUsesColumns = true;
101 0 : ::std::vector< Reference< XDataSeries > > aSeries( ChartModelHelper::getDataSeries( mrModel ) );
102 0 : if( !aSeries.empty() )
103 : {
104 0 : uno::Reference< data::XDataSource > xSeriesSource( aSeries.front(), uno::UNO_QUERY );
105 0 : OUString aStringDummy;
106 : bool bDummy;
107 0 : uno::Sequence< sal_Int32 > aSeqDummy;
108 0 : DataSourceHelper::readArguments( xDataProvider->detectArguments( xSeriesSource),
109 0 : aStringDummy, aSeqDummy, bSeriesUsesColumns, bDummy, bDummy );
110 : }
111 0 : if( bSeriesUsesColumns )
112 0 : m_aSplitCategoriesList=aColumns;
113 : else
114 0 : m_aSplitCategoriesList=aRows;
115 0 : }
116 0 : }
117 : }
118 0 : if( !m_aSplitCategoriesList.getLength() )
119 : {
120 0 : m_aSplitCategoriesList.realloc(1);
121 0 : m_aSplitCategoriesList[0]=m_xOriginalCategories;
122 0 : }
123 : }
124 : }
125 0 : catch( const uno::Exception & ex )
126 : {
127 : ASSERT_EXCEPTION( ex );
128 : }
129 0 : }
130 :
131 0 : ExplicitCategoriesProvider::~ExplicitCategoriesProvider()
132 : {
133 0 : }
134 :
135 0 : Reference< chart2::data::XDataSequence > ExplicitCategoriesProvider::getOriginalCategories()
136 : {
137 0 : if( m_xOriginalCategories.is() )
138 0 : return m_xOriginalCategories->getValues();
139 0 : return 0;
140 : }
141 :
142 0 : const Sequence< Reference< data::XLabeledDataSequence> >& ExplicitCategoriesProvider::getSplitCategoriesList()
143 : {
144 0 : return m_aSplitCategoriesList;
145 : }
146 :
147 0 : bool ExplicitCategoriesProvider::hasComplexCategories() const
148 : {
149 0 : return m_aSplitCategoriesList.getLength() > 1;
150 : }
151 :
152 0 : sal_Int32 ExplicitCategoriesProvider::getCategoryLevelCount() const
153 : {
154 0 : sal_Int32 nCount = m_aSplitCategoriesList.getLength();
155 0 : if(!nCount)
156 0 : nCount = 1;
157 0 : return nCount;
158 : }
159 :
160 0 : std::vector<sal_Int32> lcl_getLimitingBorders( const std::vector< ComplexCategory >& rComplexCategories )
161 : {
162 0 : std::vector<sal_Int32> aLimitingBorders;
163 0 : std::vector< ComplexCategory >::const_iterator aIt( rComplexCategories.begin() );
164 0 : std::vector< ComplexCategory >::const_iterator aEnd( rComplexCategories.end() );
165 0 : sal_Int32 nBorderIndex = 0; /*border below the index*/
166 0 : for( ; aIt != aEnd; ++aIt )
167 : {
168 0 : ComplexCategory aComplexCategory(*aIt);
169 0 : nBorderIndex += aComplexCategory.Count;
170 0 : aLimitingBorders.push_back(nBorderIndex);
171 0 : }
172 0 : return aLimitingBorders;
173 : }
174 :
175 0 : void ExplicitCategoriesProvider::convertCategoryAnysToText( uno::Sequence< OUString >& rOutTexts, const uno::Sequence< uno::Any >& rInAnys, ChartModel& rModel )
176 : {
177 0 : sal_Int32 nCount = rInAnys.getLength();
178 0 : if(!nCount)
179 0 : return;
180 0 : rOutTexts.realloc(nCount);
181 0 : Reference< util::XNumberFormats > xNumberFormats;
182 0 : xNumberFormats = Reference< util::XNumberFormats >( rModel.getNumberFormats() );
183 :
184 0 : sal_Int32 nAxisNumberFormat = 0;
185 0 : Reference< XCoordinateSystem > xCooSysModel( ChartModelHelper::getFirstCoordinateSystem( rModel ) );
186 0 : if( xCooSysModel.is() )
187 : {
188 0 : Reference< chart2::XAxis > xAxis( xCooSysModel->getAxisByDimension(0,0) );
189 : nAxisNumberFormat = AxisHelper::getExplicitNumberFormatKeyForAxis(
190 0 : xAxis, xCooSysModel, uno::Reference< util::XNumberFormatsSupplier> (static_cast< ::cppu::OWeakObject* >( &rModel ), uno::UNO_QUERY), false );
191 : }
192 :
193 : sal_Int32 nLabelColor;
194 0 : bool bColorChanged = false;
195 :
196 0 : NumberFormatterWrapper aNumberFormatterWrapper( rModel.getNumberFormatsSupplier() );
197 :
198 0 : for(sal_Int32 nN=0;nN<nCount;nN++)
199 : {
200 0 : OUString aText;
201 0 : uno::Any aAny = rInAnys[nN];
202 0 : if( aAny.hasValue() )
203 : {
204 0 : double fDouble = 0;
205 0 : if( aAny>>=fDouble )
206 : {
207 0 : if( !::rtl::math::isNan(fDouble) )
208 0 : aText = aNumberFormatterWrapper.getFormattedString(
209 0 : nAxisNumberFormat, fDouble, nLabelColor, bColorChanged );
210 : }
211 : else
212 : {
213 0 : aAny>>=aText;
214 : }
215 : }
216 0 : rOutTexts[nN] = aText;
217 0 : }
218 : }
219 :
220 0 : SplitCategoriesProvider::~SplitCategoriesProvider()
221 : {
222 0 : }
223 :
224 : class SplitCategoriesProvider_ForLabeledDataSequences : public SplitCategoriesProvider
225 : {
226 : public:
227 :
228 0 : explicit SplitCategoriesProvider_ForLabeledDataSequences(
229 : const ::com::sun::star::uno::Sequence<
230 : ::com::sun::star::uno::Reference<
231 : ::com::sun::star::chart2::data::XLabeledDataSequence> >& rSplitCategoriesList
232 : , ChartModel& rModel )
233 : : m_rSplitCategoriesList( rSplitCategoriesList )
234 0 : , mrModel( rModel )
235 0 : {}
236 0 : virtual ~SplitCategoriesProvider_ForLabeledDataSequences()
237 0 : {}
238 :
239 : virtual sal_Int32 getLevelCount() const SAL_OVERRIDE;
240 : virtual uno::Sequence< OUString > getStringsForLevel( sal_Int32 nIndex ) const SAL_OVERRIDE;
241 :
242 : private:
243 : const ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Reference<
244 : ::com::sun::star::chart2::data::XLabeledDataSequence> >& m_rSplitCategoriesList;
245 :
246 : ChartModel& mrModel;
247 : };
248 :
249 0 : sal_Int32 SplitCategoriesProvider_ForLabeledDataSequences::getLevelCount() const
250 : {
251 0 : return m_rSplitCategoriesList.getLength();
252 : }
253 0 : uno::Sequence< OUString > SplitCategoriesProvider_ForLabeledDataSequences::getStringsForLevel( sal_Int32 nLevel ) const
254 : {
255 0 : uno::Sequence< OUString > aRet;
256 0 : Reference< data::XLabeledDataSequence > xLabeledDataSequence( m_rSplitCategoriesList[nLevel] );
257 0 : if( xLabeledDataSequence.is() )
258 : {
259 0 : uno::Reference< data::XDataSequence > xDataSequence( xLabeledDataSequence->getValues() );
260 0 : if( xDataSequence.is() )
261 0 : ExplicitCategoriesProvider::convertCategoryAnysToText( aRet, xDataSequence->getData(), mrModel );
262 : }
263 0 : return aRet;
264 : }
265 :
266 0 : std::vector< ComplexCategory > lcl_DataSequenceToComplexCategoryVector(
267 : const uno::Sequence< OUString >& rStrings
268 : , const std::vector<sal_Int32>& rLimitingBorders, bool bCreateSingleCategories )
269 : {
270 0 : std::vector< ComplexCategory > aResult;
271 :
272 0 : sal_Int32 nMaxCount = rStrings.getLength();
273 0 : OUString aPrevious;
274 0 : sal_Int32 nCurrentCount=0;
275 0 : for( sal_Int32 nN=0; nN<nMaxCount; nN++ )
276 : {
277 0 : const OUString& aCurrent = rStrings[nN];
278 0 : if( bCreateSingleCategories || ::std::find( rLimitingBorders.begin(), rLimitingBorders.end(), nN ) != rLimitingBorders.end() )
279 : {
280 0 : aResult.push_back( ComplexCategory(aPrevious,nCurrentCount) );
281 0 : nCurrentCount=1;
282 0 : aPrevious = aCurrent;
283 : }
284 : else
285 : {
286 : // Empty value is interpreted as a continuation of the previous
287 : // category. Note that having the same value as the previous one
288 : // does not equate to a continuation of the category.
289 :
290 0 : if (aCurrent.isEmpty())
291 0 : ++nCurrentCount;
292 : else
293 : {
294 0 : aResult.push_back( ComplexCategory(aPrevious,nCurrentCount) );
295 0 : nCurrentCount=1;
296 0 : aPrevious = aCurrent;
297 : }
298 : }
299 : }
300 0 : if( nCurrentCount )
301 0 : aResult.push_back( ComplexCategory(aPrevious,nCurrentCount) );
302 :
303 0 : return aResult;
304 : }
305 :
306 0 : sal_Int32 lcl_getCategoryCount( std::vector< ComplexCategory >& rComplexCategories )
307 : {
308 0 : sal_Int32 nCount = 0;
309 0 : std::vector< ComplexCategory >::const_iterator aIt( rComplexCategories.begin() );
310 0 : std::vector< ComplexCategory >::const_iterator aEnd( rComplexCategories.end() );
311 0 : for( ; aIt != aEnd; ++aIt )
312 0 : nCount+=aIt->Count;
313 0 : return nCount;
314 : }
315 :
316 0 : Sequence< OUString > lcl_getExplicitSimpleCategories(
317 : const SplitCategoriesProvider& rSplitCategoriesProvider,
318 : ::std::vector< ::std::vector< ComplexCategory > >& rComplexCats )
319 : {
320 0 : Sequence< OUString > aRet;
321 :
322 0 : rComplexCats.clear();
323 0 : sal_Int32 nLCount = rSplitCategoriesProvider.getLevelCount();
324 0 : for( sal_Int32 nL = 0; nL < nLCount; nL++ )
325 : {
326 0 : std::vector<sal_Int32> aLimitingBorders;
327 0 : if(nL>0)
328 0 : aLimitingBorders = lcl_getLimitingBorders( rComplexCats.back() );
329 : rComplexCats.push_back( lcl_DataSequenceToComplexCategoryVector(
330 0 : rSplitCategoriesProvider.getStringsForLevel(nL), aLimitingBorders, nL==(nLCount-1) ) );
331 0 : }
332 :
333 0 : std::vector< std::vector< ComplexCategory > >::iterator aOuterIt( rComplexCats.begin() );
334 0 : std::vector< std::vector< ComplexCategory > >::const_iterator aOuterEnd( rComplexCats.end() );
335 :
336 : //ensure that the category count is the same on each level
337 0 : sal_Int32 nMaxCategoryCount = 0;
338 : {
339 0 : for( aOuterIt=rComplexCats.begin(); aOuterIt != aOuterEnd; ++aOuterIt )
340 : {
341 0 : sal_Int32 nCurrentCount = lcl_getCategoryCount( *aOuterIt );
342 0 : nMaxCategoryCount = std::max( nCurrentCount, nMaxCategoryCount );
343 : }
344 0 : for( aOuterIt=rComplexCats.begin(); aOuterIt != aOuterEnd; ++aOuterIt )
345 : {
346 0 : if ( !aOuterIt->empty() )
347 : {
348 0 : sal_Int32 nCurrentCount = lcl_getCategoryCount( *aOuterIt );
349 0 : if( nCurrentCount< nMaxCategoryCount )
350 : {
351 0 : ComplexCategory& rComplexCategory = aOuterIt->back();
352 0 : rComplexCategory.Count += (nMaxCategoryCount-nCurrentCount);
353 : }
354 : }
355 : }
356 : }
357 :
358 : //create a list with an element for every index
359 0 : std::vector< std::vector< ComplexCategory > > aComplexCatsPerIndex;
360 0 : for( aOuterIt=rComplexCats.begin() ; aOuterIt != aOuterEnd; ++aOuterIt )
361 : {
362 0 : std::vector< ComplexCategory > aSingleLevel;
363 0 : std::vector< ComplexCategory >::iterator aIt( aOuterIt->begin() );
364 0 : std::vector< ComplexCategory >::const_iterator aEnd( aOuterIt->end() );
365 0 : for( ; aIt != aEnd; ++aIt )
366 : {
367 0 : ComplexCategory aComplexCategory( *aIt );
368 0 : sal_Int32 nCount = aComplexCategory.Count;
369 0 : while( nCount-- )
370 0 : aSingleLevel.push_back(aComplexCategory);
371 0 : }
372 0 : aComplexCatsPerIndex.push_back( aSingleLevel );
373 0 : }
374 :
375 0 : if(nMaxCategoryCount)
376 : {
377 0 : aRet.realloc(nMaxCategoryCount);
378 0 : aOuterEnd = aComplexCatsPerIndex.end();
379 0 : OUString aSpace(" ");
380 0 : for(sal_Int32 nN=0; nN<nMaxCategoryCount; nN++)
381 : {
382 0 : OUString aText;
383 0 : for( aOuterIt=aComplexCatsPerIndex.begin() ; aOuterIt != aOuterEnd; ++aOuterIt )
384 : {
385 0 : if ( static_cast<size_t>(nN) < aOuterIt->size() )
386 : {
387 0 : OUString aAddText = (*aOuterIt)[nN].Text;
388 0 : if( !aAddText.isEmpty() )
389 : {
390 0 : if(!aText.isEmpty())
391 0 : aText += aSpace;
392 0 : aText += aAddText;
393 0 : }
394 : }
395 : }
396 0 : aRet[nN]=aText;
397 0 : }
398 : }
399 0 : return aRet;
400 : }
401 :
402 0 : Sequence< OUString > ExplicitCategoriesProvider::getExplicitSimpleCategories(
403 : const SplitCategoriesProvider& rSplitCategoriesProvider )
404 : {
405 0 : vector< vector< ComplexCategory > > aComplexCats;
406 0 : return lcl_getExplicitSimpleCategories( rSplitCategoriesProvider, aComplexCats );
407 : }
408 :
409 : struct DatePlusIndexComparator
410 : {
411 0 : inline bool operator() ( const DatePlusIndex& aFirst,
412 : const DatePlusIndex& aSecond ) const
413 : {
414 0 : return ( aFirst.fValue < aSecond.fValue );
415 : }
416 : };
417 :
418 0 : bool lcl_fillDateCategories( const uno::Reference< data::XDataSequence >& xDataSequence, std::vector< DatePlusIndex >& rDateCategories, bool bIsAutoDate, ChartModel& rModel )
419 : {
420 0 : bool bOnlyDatesFound = true;
421 0 : bool bAnyDataFound = false;
422 :
423 0 : if( xDataSequence.is() )
424 : {
425 0 : uno::Sequence< uno::Any > aValues = xDataSequence->getData();
426 0 : sal_Int32 nCount = aValues.getLength();
427 0 : rDateCategories.reserve(nCount);
428 0 : Reference< util::XNumberFormats > xNumberFormats;
429 0 : xNumberFormats = Reference< util::XNumberFormats >( rModel.getNumberFormats() );
430 :
431 0 : bool bOwnData = false;
432 0 : bool bOwnDataAnddAxisHasAnyFormat = false;
433 0 : bool bOwnDataAnddAxisHasDateFormat = false;
434 0 : Reference< XCoordinateSystem > xCooSysModel( ChartModelHelper::getFirstCoordinateSystem( rModel ) );
435 0 : if( xCooSysModel.is() )
436 : {
437 0 : if( rModel.hasInternalDataProvider() )
438 : {
439 0 : bOwnData = true;
440 0 : Reference< beans::XPropertySet > xAxisProps( xCooSysModel->getAxisByDimension(0,0), uno::UNO_QUERY );
441 0 : sal_Int32 nAxisNumberFormat = 0;
442 0 : if( xAxisProps.is() && (xAxisProps->getPropertyValue( "NumberFormat" ) >>= nAxisNumberFormat) )
443 : {
444 0 : bOwnDataAnddAxisHasAnyFormat = true;
445 0 : bOwnDataAnddAxisHasDateFormat = DiagramHelper::isDateNumberFormat( nAxisNumberFormat, xNumberFormats );
446 0 : }
447 : }
448 : }
449 :
450 0 : for(sal_Int32 nN=0;nN<nCount;nN++)
451 : {
452 0 : bool bIsDate = false;
453 0 : if( bIsAutoDate )
454 : {
455 0 : if( bOwnData )
456 0 : bIsDate = bOwnDataAnddAxisHasAnyFormat ? bOwnDataAnddAxisHasDateFormat : true;
457 : else
458 0 : bIsDate = DiagramHelper::isDateNumberFormat( xDataSequence->getNumberFormatKeyByIndex( nN ), xNumberFormats );
459 : }
460 : else
461 0 : bIsDate = true;
462 :
463 0 : bool bContainsEmptyString = false;
464 0 : uno::Any aAny = aValues[nN];
465 0 : if( aAny.hasValue() )
466 : {
467 0 : OUString aTest;
468 0 : double fTest = 0;
469 0 : bool bContainsNan = false;
470 0 : if( (aAny>>=aTest) && aTest.isEmpty() ) //empty String
471 0 : bContainsEmptyString = true;
472 0 : else if( (aAny>>=fTest) && ::rtl::math::isNan(fTest) )
473 0 : bContainsNan = true;
474 :
475 0 : if( !bContainsEmptyString && !bContainsNan )
476 0 : bAnyDataFound = true;
477 : }
478 0 : DatePlusIndex aDatePlusIndex( 1.0, nN );
479 0 : if( bIsDate && (aAny >>= aDatePlusIndex.fValue) )
480 0 : rDateCategories.push_back( aDatePlusIndex );
481 : else
482 : {
483 0 : if( aAny.hasValue() && !bContainsEmptyString )//empty string does not count as non date value!
484 0 : bOnlyDatesFound=false;
485 0 : ::rtl::math::setNan( &aDatePlusIndex.fValue );
486 0 : rDateCategories.push_back( aDatePlusIndex );
487 : }
488 0 : }
489 0 : ::std::sort( rDateCategories.begin(), rDateCategories.end(), DatePlusIndexComparator() );
490 : }
491 :
492 0 : return bAnyDataFound && bOnlyDatesFound;
493 : }
494 :
495 0 : void ExplicitCategoriesProvider::init()
496 : {
497 0 : if( m_bDirty )
498 : {
499 0 : m_aComplexCats.clear();//not one per index
500 0 : m_aDateCategories.clear();
501 :
502 0 : if( m_xOriginalCategories.is() )
503 : {
504 0 : if( !hasComplexCategories() )
505 : {
506 0 : if(m_bIsDateAxis)
507 : {
508 0 : if( ChartTypeHelper::isSupportingDateAxis( AxisHelper::getChartTypeByIndex( m_xCooSysModel, 0 ), 2, 0 ) )
509 0 : m_bIsDateAxis = lcl_fillDateCategories( m_xOriginalCategories->getValues(), m_aDateCategories, m_bIsAutoDate, mrModel );
510 : else
511 0 : m_bIsDateAxis = false;
512 : }
513 : }
514 : else
515 : {
516 0 : m_bIsDateAxis = false;
517 : }
518 : }
519 : else
520 0 : m_bIsDateAxis=false;
521 0 : m_bDirty = false;
522 : }
523 0 : }
524 :
525 0 : Sequence< OUString > ExplicitCategoriesProvider::getSimpleCategories()
526 : {
527 0 : if( !m_bIsExplicitCategoriesInited )
528 : {
529 0 : init();
530 0 : m_aExplicitCategories.realloc(0);
531 0 : if( m_xOriginalCategories.is() )
532 : {
533 0 : if( !hasComplexCategories() )
534 : {
535 0 : uno::Reference< data::XDataSequence > xDataSequence( m_xOriginalCategories->getValues() );
536 0 : if( xDataSequence.is() )
537 0 : ExplicitCategoriesProvider::convertCategoryAnysToText( m_aExplicitCategories, xDataSequence->getData(), mrModel );
538 : }
539 : else
540 : {
541 0 : m_aExplicitCategories = lcl_getExplicitSimpleCategories(
542 0 : SplitCategoriesProvider_ForLabeledDataSequences( m_aSplitCategoriesList, mrModel ), m_aComplexCats );
543 : }
544 : }
545 0 : if(!m_aExplicitCategories.getLength())
546 0 : m_aExplicitCategories = DiagramHelper::generateAutomaticCategoriesFromCooSys( m_xCooSysModel );
547 0 : m_bIsExplicitCategoriesInited = true;
548 : }
549 0 : return m_aExplicitCategories;
550 : }
551 :
552 0 : const std::vector<ComplexCategory>* ExplicitCategoriesProvider::getCategoriesByLevel( sal_Int32 nLevel )
553 : {
554 0 : init();
555 0 : sal_Int32 nMaxIndex = m_aComplexCats.size()-1;
556 0 : if (nLevel >= 0 && nLevel <= nMaxIndex)
557 0 : return &m_aComplexCats[nMaxIndex-nLevel];
558 0 : return NULL;
559 : }
560 :
561 0 : OUString ExplicitCategoriesProvider::getCategoryByIndex(
562 : const Reference< XCoordinateSystem >& xCooSysModel
563 : , ChartModel& rModel
564 : , sal_Int32 nIndex )
565 : {
566 0 : if( xCooSysModel.is())
567 : {
568 0 : ExplicitCategoriesProvider aExplicitCategoriesProvider( xCooSysModel, rModel );
569 0 : Sequence< OUString > aCategories( aExplicitCategoriesProvider.getSimpleCategories());
570 0 : if( nIndex < aCategories.getLength())
571 0 : return aCategories[ nIndex ];
572 : }
573 0 : return OUString();
574 : }
575 :
576 0 : bool ExplicitCategoriesProvider::isDateAxis()
577 : {
578 0 : init();
579 0 : return m_bIsDateAxis;
580 : }
581 :
582 0 : const std::vector< DatePlusIndex >& ExplicitCategoriesProvider::getDateCategories()
583 : {
584 0 : init();
585 0 : return m_aDateCategories;
586 : }
587 :
588 : } //namespace chart
589 :
590 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|