LCOV - code coverage report
Current view: top level - chart2/source/tools - ExplicitCategoriesProvider.cxx (source / functions) Hit Total Coverage
Test: commit e02a6cb2c3e2b23b203b422e4e0680877f232636 Lines: 0 297 0.0 %
Date: 2014-04-14 Functions: 0 28 0.0 %
Legend: Lines: hit not hit

          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: */

Generated by: LCOV version 1.10