LCOV - code coverage report
Current view: top level - chart2/source/tools - DataSeriesHelper.cxx (source / functions) Hit Total Coverage
Test: commit 0e63ca4fde4e446f346e35849c756a30ca294aab Lines: 226 441 51.2 %
Date: 2014-04-11 Functions: 24 37 64.9 %
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 "DataSeriesHelper.hxx"
      21             : #include "DiagramHelper.hxx"
      22             : #include "DataSource.hxx"
      23             : #include "macros.hxx"
      24             : #include "ContainerHelper.hxx"
      25             : #include <com/sun/star/beans/XPropertySet.hpp>
      26             : #include <com/sun/star/chart2/DataPointLabel.hpp>
      27             : #include <com/sun/star/chart2/data/XTextualDataSequence.hpp>
      28             : #include <com/sun/star/chart2/StackingDirection.hpp>
      29             : #include <com/sun/star/chart2/data/LabelOrigin.hpp>
      30             : #include <com/sun/star/chart2/AxisType.hpp>
      31             : #include <com/sun/star/chart2/SymbolStyle.hpp>
      32             : #include <com/sun/star/chart2/Symbol.hpp>
      33             : #include <com/sun/star/drawing/LineStyle.hpp>
      34             : 
      35             : #include <com/sun/star/chart2/XCoordinateSystemContainer.hpp>
      36             : #include <com/sun/star/chart2/XChartTypeContainer.hpp>
      37             : #include <com/sun/star/chart2/XDataSeriesContainer.hpp>
      38             : #include <rtl/ustrbuf.hxx>
      39             : 
      40             : #include <functional>
      41             : #include <algorithm>
      42             : #include <iterator>
      43             : #include <vector>
      44             : #include <set>
      45             : 
      46             : using namespace ::com::sun::star;
      47             : using namespace ::com::sun::star::chart2;
      48             : 
      49             : using ::com::sun::star::uno::Reference;
      50             : using ::com::sun::star::uno::Sequence;
      51             : 
      52             : namespace
      53             : {
      54             : 
      55      251604 : class lcl_MatchesRole : public ::std::unary_function< Reference< chart2::data::XLabeledDataSequence >, bool >
      56             : {
      57             : public:
      58       83868 :     explicit lcl_MatchesRole( const OUString & aRole, bool bMatchPrefix ) :
      59             :             m_aRole( aRole ),
      60       83868 :             m_bMatchPrefix( bMatchPrefix )
      61       83868 :     {}
      62             : 
      63      108390 :     bool operator () ( const Reference< chart2::data::XLabeledDataSequence > & xSeq ) const
      64             :     {
      65      108390 :         if(!xSeq.is())
      66           0 :             return false;
      67      108390 :         Reference< beans::XPropertySet > xProp( xSeq->getValues(), uno::UNO_QUERY );
      68      216780 :         OUString aRole;
      69             : 
      70      108390 :         if( m_bMatchPrefix )
      71      289749 :             return ( xProp.is() &&
      72      579498 :                      (xProp->getPropertyValue( "Role" ) >>= aRole ) &&
      73      193166 :                      aRole.match( m_aRole ));
      74             : 
      75       35421 :         return ( xProp.is() &&
      76       70842 :                  (xProp->getPropertyValue( "Role" ) >>= aRole ) &&
      77      132004 :                  m_aRole.equals( aRole ));
      78             :     }
      79             : 
      80             : private:
      81             :     OUString m_aRole;
      82             :     bool     m_bMatchPrefix;
      83             : };
      84             : 
      85           2 : Reference< chart2::data::XLabeledDataSequence > lcl_findLSequenceWithOnlyLabel(
      86             :     const Reference< chart2::data::XDataSource > & xDataSource )
      87             : {
      88           2 :     Reference< chart2::data::XLabeledDataSequence > xResult;
      89           4 :     Sequence< Reference< chart2::data::XLabeledDataSequence > > aSequences( xDataSource->getDataSequences());
      90             : 
      91           4 :     for( sal_Int32 i=0; i<aSequences.getLength(); ++i )
      92             :     {
      93             :         OSL_ENSURE( aSequences[i].is(), "empty LabeledDataSequence" );
      94             :         // no values are set but a label exists
      95           8 :         if( aSequences[i].is() &&
      96           8 :             ( ! aSequences[i]->getValues().is() &&
      97           2 :               aSequences[i]->getLabel().is()))
      98             :         {
      99           0 :             xResult.set( aSequences[i] );
     100           0 :             break;
     101             :         }
     102             :     }
     103             : 
     104           4 :     return xResult;
     105             : }
     106             : 
     107        1601 : void lcl_getCooSysAndChartTypeOfSeries(
     108             :     const Reference< chart2::XDataSeries > & xSeries,
     109             :     const Reference< chart2::XDiagram > & xDiagram,
     110             :     Reference< chart2::XCoordinateSystem > & xOutCooSys,
     111             :     Reference< chart2::XChartType > & xOutChartType )
     112             : {
     113        1601 :     Reference< chart2::XCoordinateSystemContainer > xCooSysCnt( xDiagram, uno::UNO_QUERY );
     114        1601 :     if( xCooSysCnt.is())
     115             :     {
     116        1601 :         Sequence< Reference< chart2::XCoordinateSystem > > aCooSysSeq( xCooSysCnt->getCoordinateSystems());
     117        3202 :         for( sal_Int32 nCooSysIdx=0; nCooSysIdx<aCooSysSeq.getLength(); ++nCooSysIdx )
     118             :         {
     119        1601 :             Reference< chart2::XChartTypeContainer > xCTCnt( aCooSysSeq[nCooSysIdx], uno::UNO_QUERY_THROW );
     120        3202 :             Sequence< Reference< chart2::XChartType > > aChartTypes( xCTCnt->getChartTypes());
     121        3274 :             for( sal_Int32 nCTIdx=0; nCTIdx<aChartTypes.getLength(); ++nCTIdx )
     122             :             {
     123        1673 :                 Reference< chart2::XDataSeriesContainer > xSeriesCnt( aChartTypes[nCTIdx], uno::UNO_QUERY );
     124        1673 :                 if( xSeriesCnt.is())
     125             :                 {
     126        1673 :                     Sequence< Reference< chart2::XDataSeries > > aSeries( xSeriesCnt->getDataSeries());
     127        6730 :                     for( sal_Int32 nSeriesIdx=0; nSeriesIdx<aSeries.getLength(); ++nSeriesIdx )
     128             :                     {
     129        5057 :                         if( aSeries[nSeriesIdx] == xSeries )
     130             :                         {
     131        1601 :                             xOutCooSys.set( aCooSysSeq[nCooSysIdx] );
     132        1601 :                             xOutChartType.set( aChartTypes[nCTIdx] );
     133             :                         }
     134        1673 :                     }
     135             :                 }
     136        1673 :             }
     137        3202 :         }
     138        1601 :     }
     139        1601 : }
     140             : 
     141           0 : void lcl_insertOrDeleteDataLabelsToSeriesAndAllPoints( const Reference< chart2::XDataSeries >& xSeries, bool bInsert )
     142             : {
     143             :     try
     144             :     {
     145           0 :         Reference< beans::XPropertySet > xSeriesProperties( xSeries, uno::UNO_QUERY );
     146           0 :         if( xSeriesProperties.is() )
     147             :         {
     148           0 :             DataPointLabel aLabelAtSeries;
     149           0 :             xSeriesProperties->getPropertyValue( "Label" ) >>= aLabelAtSeries;
     150           0 :             aLabelAtSeries.ShowNumber = bInsert;
     151           0 :             if( !bInsert )
     152             :             {
     153           0 :                 aLabelAtSeries.ShowNumberInPercent = false;
     154           0 :                 aLabelAtSeries.ShowCategoryName = false;
     155             :             }
     156           0 :             xSeriesProperties->setPropertyValue( "Label", uno::makeAny( aLabelAtSeries ) );
     157           0 :             uno::Sequence< sal_Int32 > aAttributedDataPointIndexList;
     158           0 :             if( xSeriesProperties->getPropertyValue( "AttributedDataPoints" ) >>= aAttributedDataPointIndexList )
     159             :             {
     160           0 :                 for(sal_Int32 nN=aAttributedDataPointIndexList.getLength();nN--;)
     161             :                 {
     162           0 :                     Reference< beans::XPropertySet > xPointProp( xSeries->getDataPointByIndex(aAttributedDataPointIndexList[nN]) );
     163           0 :                     if( xPointProp.is() )
     164             :                     {
     165           0 :                         DataPointLabel aLabel;
     166           0 :                         xPointProp->getPropertyValue( "Label" ) >>= aLabel;
     167           0 :                         aLabel.ShowNumber = bInsert;
     168           0 :                         if( !bInsert )
     169             :                         {
     170           0 :                             aLabel.ShowNumberInPercent = false;
     171           0 :                             aLabel.ShowCategoryName = false;
     172             :                         }
     173           0 :                         xPointProp->setPropertyValue( "Label", uno::makeAny( aLabel ) );
     174             :                     }
     175           0 :                 }
     176           0 :             }
     177           0 :         }
     178             :     }
     179           0 :     catch(const uno::Exception &e)
     180             :     {
     181             :         ASSERT_EXCEPTION( e );
     182             :     }
     183           0 : }
     184             : 
     185             : } // anonymous namespace
     186             : 
     187             : namespace chart
     188             : {
     189             : 
     190             : namespace DataSeriesHelper
     191             : {
     192             : 
     193        2729 : OUString GetRole( const uno::Reference< chart2::data::XLabeledDataSequence >& xLabeledDataSequence )
     194             : {
     195        2729 :     OUString aRet;
     196        2729 :     if( xLabeledDataSequence.is() )
     197             :     {
     198        2729 :         Reference< beans::XPropertySet > xProp( xLabeledDataSequence->getValues(), uno::UNO_QUERY );
     199        2729 :         if( xProp.is() )
     200        2729 :             xProp->getPropertyValue( "Role" ) >>= aRet;
     201             :     }
     202        2729 :     return aRet;
     203             : }
     204             : 
     205             : Reference< chart2::data::XLabeledDataSequence >
     206       10084 :     getDataSequenceByRole(
     207             :         const Reference< chart2::data::XDataSource > & xSource,
     208             :         const OUString& aRole,
     209             :         bool bMatchPrefix /* = false */ )
     210             : {
     211       10084 :     Reference< chart2::data::XLabeledDataSequence > aNoResult;
     212       10084 :     if( ! xSource.is())
     213           0 :         return aNoResult;
     214       20168 :     Sequence< Reference< chart2::data::XLabeledDataSequence > > aLabeledSeq( xSource->getDataSequences());
     215             : 
     216       10084 :     const Reference< chart2::data::XLabeledDataSequence > * pBegin = aLabeledSeq.getConstArray();
     217       10084 :     const Reference< chart2::data::XLabeledDataSequence > * pEnd = pBegin + aLabeledSeq.getLength();
     218             :     const Reference< chart2::data::XLabeledDataSequence > * pMatch =
     219       10084 :         ::std::find_if( pBegin, pEnd, lcl_MatchesRole( aRole, bMatchPrefix ));
     220             : 
     221       10084 :     if( pMatch != pEnd )
     222        8305 :         return *pMatch;
     223             : 
     224       11863 :     return aNoResult;
     225             : }
     226             : 
     227             : ::std::vector< Reference< chart2::data::XLabeledDataSequence > >
     228       73784 :     getAllDataSequencesByRole( const Sequence< Reference< chart2::data::XLabeledDataSequence > > & aDataSequences,
     229             :                                const OUString& aRole, bool bMatchPrefix /* = false */ )
     230             : {
     231       73784 :     ::std::vector< Reference< chart2::data::XLabeledDataSequence > > aResultVec;
     232       73784 :     ::std::remove_copy_if( aDataSequences.getConstArray(), aDataSequences.getConstArray() + aDataSequences.getLength(),
     233             :                            ::std::back_inserter( aResultVec ),
     234      147568 :                            ::std::not1( lcl_MatchesRole( aRole, bMatchPrefix )));
     235       73784 :     return aResultVec;
     236             : }
     237             : 
     238             : Reference< chart2::data::XDataSource >
     239        1138 :     getDataSource( const Sequence< Reference< chart2::XDataSeries > > & aSeries )
     240             : {
     241        1138 :     ::std::vector< Reference< chart2::data::XLabeledDataSequence > > aSeqVec;
     242             : 
     243        3749 :     for( sal_Int32 i = 0; i < aSeries.getLength(); ++i )
     244             :     {
     245        2611 :         Reference< chart2::data::XDataSource > xSource( aSeries[ i ], uno::UNO_QUERY );
     246        2611 :         if( xSource.is())
     247             :         {
     248        2611 :             Sequence< Reference< chart2::data::XLabeledDataSequence > > aSeq( xSource->getDataSequences());
     249        2611 :             ::std::copy( aSeq.getConstArray(), aSeq.getConstArray() + aSeq.getLength(),
     250        5222 :                          ::std::back_inserter( aSeqVec ));
     251             :         }
     252        2611 :     }
     253             : 
     254             :     return Reference< chart2::data::XDataSource >(
     255        1138 :         new DataSource( ContainerHelper::ContainerToSequence( aSeqVec )));
     256             : }
     257             : 
     258             : namespace
     259             : {
     260        4189 : OUString lcl_getDataSequenceLabel( const Reference< chart2::data::XDataSequence > & xSequence )
     261             : {
     262        4189 :     OUString aResult;
     263             : 
     264        8378 :     Reference< chart2::data::XTextualDataSequence > xTextSeq( xSequence, uno::UNO_QUERY );
     265        4189 :     if( xTextSeq.is())
     266             :     {
     267        4189 :         Sequence< OUString > aSeq( xTextSeq->getTextualData());
     268             : 
     269        4189 :         const sal_Int32 nMax = aSeq.getLength() - 1;
     270        8378 :         OUStringBuffer aBuf;
     271             : 
     272        8378 :         for( sal_Int32 i = 0; i <= nMax; ++i )
     273             :         {
     274        4189 :             aBuf.append( aSeq[i] );
     275        4189 :             if( i < nMax )
     276           0 :                 aBuf.append( ' ');
     277             :         }
     278        8378 :         aResult = aBuf.makeStringAndClear();
     279             :     }
     280           0 :     else if( xSequence.is())
     281             :     {
     282           0 :         Sequence< uno::Any > aSeq( xSequence->getData());
     283             : 
     284           0 :         const sal_Int32 nMax = aSeq.getLength() - 1;
     285           0 :         OUString aVal;
     286           0 :         OUStringBuffer aBuf;
     287           0 :         double fNum = 0;
     288             : 
     289           0 :         for( sal_Int32 i = 0; i <= nMax; ++i )
     290             :         {
     291           0 :             if( aSeq[i] >>= aVal )
     292             :             {
     293           0 :                 aBuf.append( aVal );
     294           0 :                 if( i < nMax )
     295           0 :                     aBuf.append(  ' ');
     296             :             }
     297           0 :             else if( aSeq[ i ] >>= fNum )
     298             :             {
     299           0 :                 aBuf.append( fNum );
     300           0 :                 if( i < nMax )
     301           0 :                     aBuf.append( ' ');
     302             :             }
     303             :         }
     304           0 :         aResult = aBuf.makeStringAndClear();
     305             :     }
     306             : 
     307        8378 :     return aResult;
     308             : }
     309             : }
     310             : 
     311        4204 : OUString getLabelForLabeledDataSequence(
     312             :     const Reference< chart2::data::XLabeledDataSequence > & xLabeledSeq )
     313             : {
     314        4204 :     OUString aResult;
     315        4204 :     if( xLabeledSeq.is())
     316             :     {
     317        4204 :         Reference< chart2::data::XDataSequence > xSeq( xLabeledSeq->getLabel());
     318        4204 :         if( xSeq.is() )
     319        4189 :             aResult = lcl_getDataSequenceLabel( xSeq );
     320        4204 :         if( !xSeq.is() || aResult.isEmpty() )
     321             :         {
     322             :             // no label set or label content is empty -> use auto-generated one
     323          16 :             Reference< chart2::data::XDataSequence > xValueSeq( xLabeledSeq->getValues() );
     324          16 :             if( xValueSeq.is() )
     325             :             {
     326          16 :                 Sequence< OUString > aLabels( xValueSeq->generateLabel(
     327          16 :                     chart2::data::LabelOrigin_SHORT_SIDE ) );
     328             :                 // no labels returned is interpreted as: auto-generation not
     329             :                 // supported by sequence
     330          16 :                 if( aLabels.getLength() )
     331          16 :                     aResult=aLabels[0];
     332             :                 else
     333             :                 {
     334             :                     //todo?: maybe use the index of the series as name
     335             :                     //but as the index may change it would be better to have such a name persistent
     336             :                     //what is not possible at the moment
     337             :                     //--> maybe use the identifier as part of the name ...
     338           0 :                     aResult = lcl_getDataSequenceLabel( xValueSeq );
     339          16 :                 }
     340          16 :             }
     341        4204 :         }
     342             :     }
     343        4204 :     return aResult;
     344             : }
     345             : 
     346        4206 : OUString getDataSeriesLabel(
     347             :     const Reference< chart2::XDataSeries > & xSeries,
     348             :     const OUString & rLabelSequenceRole )
     349             : {
     350        4206 :     OUString aResult;
     351             : 
     352        8412 :     Reference< chart2::data::XDataSource > xSource( xSeries, uno::UNO_QUERY );
     353        4206 :     if( xSource.is())
     354             :     {
     355             :         Reference< chart2::data::XLabeledDataSequence > xLabeledSeq(
     356        4206 :             ::chart::DataSeriesHelper::getDataSequenceByRole( xSource, rLabelSequenceRole ));
     357        4206 :         if( xLabeledSeq.is())
     358        4204 :             aResult = getLabelForLabeledDataSequence( xLabeledSeq );
     359             :         else
     360             :         {
     361             :             // special case: labeled data series with only a label and no values may
     362             :             // serve as label
     363           2 :             xLabeledSeq.set( lcl_findLSequenceWithOnlyLabel( xSource ));
     364           2 :             if( xLabeledSeq.is())
     365             :             {
     366           0 :                 Reference< chart2::data::XDataSequence > xSeq( xLabeledSeq->getLabel());
     367           0 :                 if( xSeq.is())
     368           0 :                     aResult = lcl_getDataSequenceLabel( xSeq );
     369             :             }
     370        4206 :         }
     371             : 
     372             :     }
     373             : 
     374        8412 :     return aResult;
     375             : }
     376             : 
     377           2 : void setStackModeAtSeries(
     378             :     const Sequence< Reference< chart2::XDataSeries > > & aSeries,
     379             :     const Reference< chart2::XCoordinateSystem > & xCorrespondingCoordinateSystem,
     380             :     StackMode eStackMode )
     381             : {
     382           2 :     if( eStackMode == StackMode_AMBIGUOUS )
     383           2 :         return;
     384             : 
     385           2 :     const OUString aPropName( "StackingDirection" );
     386             :     const uno::Any aPropValue = uno::makeAny(
     387           2 :         ( (eStackMode == StackMode_Y_STACKED) ||
     388             :           (eStackMode == StackMode_Y_STACKED_PERCENT) )
     389             :         ? chart2::StackingDirection_Y_STACKING
     390             :         : (eStackMode == StackMode_Z_STACKED )
     391             :         ? chart2::StackingDirection_Z_STACKING
     392           6 :         : chart2::StackingDirection_NO_STACKING );
     393             : 
     394           4 :     std::set< sal_Int32 > aAxisIndexSet;
     395           8 :     for( sal_Int32 i=0; i<aSeries.getLength(); ++i )
     396             :     {
     397             :         try
     398             :         {
     399           6 :             Reference< beans::XPropertySet > xProp( aSeries[i], uno::UNO_QUERY );
     400           6 :             if( xProp.is() )
     401             :             {
     402           6 :                 xProp->setPropertyValue( aPropName, aPropValue );
     403             : 
     404             :                 sal_Int32 nAxisIndex;
     405           6 :                 xProp->getPropertyValue( "AttachedAxisIndex" ) >>= nAxisIndex;
     406           6 :                 aAxisIndexSet.insert(nAxisIndex);
     407           6 :             }
     408             :         }
     409           0 :         catch( const uno::Exception & ex )
     410             :         {
     411             :             ASSERT_EXCEPTION( ex );
     412             :         }
     413             :     }
     414             : 
     415           4 :     if( xCorrespondingCoordinateSystem.is() &&
     416           2 :         1 < xCorrespondingCoordinateSystem->getDimension() )
     417             :     {
     418           2 :         sal_Int32 nAxisIndexCount = aAxisIndexSet.size();
     419           2 :         if( !nAxisIndexCount )
     420             :         {
     421           0 :             aAxisIndexSet.insert(0);
     422           0 :             nAxisIndexCount = aAxisIndexSet.size();
     423             :         }
     424             : 
     425          12 :         for( ::std::set< sal_Int32 >::const_iterator aIt = aAxisIndexSet.begin();
     426           8 :             aIt != aAxisIndexSet.end(); ++aIt )
     427             :         {
     428           2 :             sal_Int32 nAxisIndex = *aIt;
     429             :             Reference< chart2::XAxis > xAxis(
     430           2 :                 xCorrespondingCoordinateSystem->getAxisByDimension( 1, nAxisIndex ));
     431           2 :             if( xAxis.is())
     432             :             {
     433           2 :                 bool bPercent = (eStackMode == StackMode_Y_STACKED_PERCENT);
     434           2 :                 chart2::ScaleData aScaleData = xAxis->getScaleData();
     435             : 
     436           2 :                 if( bPercent != (aScaleData.AxisType==chart2::AxisType::PERCENT) )
     437             :                 {
     438           0 :                     if( bPercent )
     439           0 :                         aScaleData.AxisType = chart2::AxisType::PERCENT;
     440             :                     else
     441           0 :                         aScaleData.AxisType = chart2::AxisType::REALNUMBER;
     442           0 :                     xAxis->setScaleData( aScaleData );
     443           2 :                 }
     444             :             }
     445           2 :         }
     446           2 :     }
     447             : }
     448             : 
     449        7588 : sal_Int32 getAttachedAxisIndex( const Reference< chart2::XDataSeries > & xSeries )
     450             : {
     451        7588 :     sal_Int32 nRet = 0;
     452             :     try
     453             :     {
     454        7588 :         Reference< beans::XPropertySet > xProp( xSeries, uno::UNO_QUERY );
     455        7588 :         if( xProp.is() )
     456             :         {
     457        7588 :             xProp->getPropertyValue( "AttachedAxisIndex" ) >>= nRet;
     458        7588 :         }
     459             :     }
     460           0 :     catch( const uno::Exception & ex )
     461             :     {
     462             :         ASSERT_EXCEPTION( ex );
     463             :     }
     464        7588 :     return nRet;
     465             : }
     466             : 
     467           0 : sal_Int32 getNumberFormatKeyFromAxis(
     468             :     const Reference< chart2::XDataSeries > & xSeries,
     469             :     const Reference< chart2::XCoordinateSystem > & xCorrespondingCoordinateSystem,
     470             :     sal_Int32 nDimensionIndex,
     471             :     sal_Int32 nAxisIndex /* = -1 */ )
     472             : {
     473           0 :     sal_Int32 nResult =  0;
     474           0 :     if( nAxisIndex == -1 )
     475           0 :         nAxisIndex = getAttachedAxisIndex( xSeries );
     476             :     try
     477             :     {
     478             :         Reference< beans::XPropertySet > xAxisProp(
     479           0 :             xCorrespondingCoordinateSystem->getAxisByDimension( nDimensionIndex, nAxisIndex ), uno::UNO_QUERY );
     480           0 :         if( xAxisProp.is())
     481           0 :             xAxisProp->getPropertyValue( "NumberFormat") >>= nResult;
     482             :     }
     483           0 :     catch( const uno::Exception & ex )
     484             :     {
     485             :         ASSERT_EXCEPTION( ex );
     486             :     }
     487             : 
     488           0 :     return nResult;
     489             : }
     490             : 
     491           0 : Reference< chart2::XCoordinateSystem > getCoordinateSystemOfSeries(
     492             :     const Reference< chart2::XDataSeries > & xSeries,
     493             :     const Reference< chart2::XDiagram > & xDiagram )
     494             : {
     495           0 :     Reference< chart2::XCoordinateSystem > xResult;
     496           0 :     Reference< chart2::XChartType > xDummy;
     497           0 :     lcl_getCooSysAndChartTypeOfSeries( xSeries, xDiagram, xResult, xDummy );
     498             : 
     499           0 :     return xResult;
     500             : }
     501             : 
     502        1601 : Reference< chart2::XChartType > getChartTypeOfSeries(
     503             :     const Reference< chart2::XDataSeries > & xSeries,
     504             :     const Reference< chart2::XDiagram > & xDiagram )
     505             : {
     506        1601 :     Reference< chart2::XChartType > xResult;
     507        3202 :     Reference< chart2::XCoordinateSystem > xDummy;
     508        1601 :     lcl_getCooSysAndChartTypeOfSeries( xSeries, xDiagram, xDummy, xResult );
     509             : 
     510        3202 :     return xResult;
     511             : }
     512             : 
     513           0 : void deleteSeries(
     514             :     const Reference< chart2::XDataSeries > & xSeries,
     515             :     const Reference< chart2::XChartType > & xChartType )
     516             : {
     517             :     try
     518             :     {
     519           0 :         Reference< chart2::XDataSeriesContainer > xSeriesCnt( xChartType, uno::UNO_QUERY_THROW );
     520             :         ::std::vector< Reference< chart2::XDataSeries > > aSeries(
     521           0 :             ContainerHelper::SequenceToVector( xSeriesCnt->getDataSeries()));
     522             :         ::std::vector< Reference< chart2::XDataSeries > >::iterator aIt =
     523           0 :               ::std::find( aSeries.begin(), aSeries.end(), xSeries );
     524           0 :         if( aIt != aSeries.end())
     525             :         {
     526           0 :             aSeries.erase( aIt );
     527           0 :             xSeriesCnt->setDataSeries( ContainerHelper::ContainerToSequence( aSeries ));
     528           0 :         }
     529             :     }
     530           0 :     catch( const uno::Exception & ex )
     531             :     {
     532             :         ASSERT_EXCEPTION( ex );
     533             :     }
     534           0 : }
     535             : 
     536          58 : void switchSymbolsOnOrOff( const Reference< beans::XPropertySet > & xSeriesProperties,
     537             :                     bool bSymbolsOn, sal_Int32 nSeriesIndex )
     538             : {
     539          58 :     if( !xSeriesProperties.is() )
     540          58 :         return;
     541             : 
     542          58 :     chart2::Symbol aSymbProp;
     543          58 :     if( (xSeriesProperties->getPropertyValue( "Symbol") >>= aSymbProp ) )
     544             :     {
     545          58 :         if( !bSymbolsOn )
     546          29 :             aSymbProp.Style = chart2::SymbolStyle_NONE;
     547          29 :         else if( aSymbProp.Style == chart2::SymbolStyle_NONE )
     548             :         {
     549          29 :             aSymbProp.Style = chart2::SymbolStyle_STANDARD;
     550          29 :             aSymbProp.StandardSymbol = nSeriesIndex;
     551             :         }
     552          58 :         xSeriesProperties->setPropertyValue( "Symbol", uno::makeAny( aSymbProp ));
     553          58 :     }
     554             :     //todo: check attributed data points
     555             : }
     556             : 
     557          58 : void switchLinesOnOrOff( const Reference< beans::XPropertySet > & xSeriesProperties, bool bLinesOn )
     558             : {
     559          58 :     if( !xSeriesProperties.is() )
     560          58 :         return;
     561             : 
     562          58 :     if( bLinesOn )
     563             :     {
     564             :         // keep line-styles that are not NONE
     565             :         drawing::LineStyle eLineStyle;
     566         116 :         if( (xSeriesProperties->getPropertyValue( "LineStyle") >>= eLineStyle ) &&
     567          58 :             eLineStyle == drawing::LineStyle_NONE )
     568             :         {
     569           0 :             xSeriesProperties->setPropertyValue( "LineStyle", uno::makeAny( drawing::LineStyle_SOLID ) );
     570             :         }
     571             :     }
     572             :     else
     573           0 :         xSeriesProperties->setPropertyValue( "LineStyle", uno::makeAny( drawing::LineStyle_NONE ) );
     574             : }
     575             : 
     576          58 : void makeLinesThickOrThin( const Reference< beans::XPropertySet > & xSeriesProperties, bool bThick )
     577             : {
     578          58 :     if( !xSeriesProperties.is() )
     579          58 :         return;
     580             : 
     581          58 :     sal_Int32 nNewValue = bThick ? 80 : 0;
     582          58 :     sal_Int32 nOldValue = 0;
     583         116 :     if( (xSeriesProperties->getPropertyValue( "LineWidth") >>= nOldValue ) &&
     584          58 :         nOldValue != nNewValue )
     585             :     {
     586          32 :         if( !(bThick && nOldValue>0))
     587          32 :             xSeriesProperties->setPropertyValue( "LineWidth", uno::makeAny( nNewValue ) );
     588             :     }
     589             : }
     590             : 
     591        1499 : void setPropertyAlsoToAllAttributedDataPoints( const Reference< chart2::XDataSeries >& xSeries,
     592             :                                               const OUString& rPropertyName, const uno::Any& rPropertyValue )
     593             : {
     594        1499 :     Reference< beans::XPropertySet > xSeriesProperties( xSeries, uno::UNO_QUERY );
     595        1499 :     if( !xSeriesProperties.is() )
     596        1499 :         return;
     597             : 
     598        1499 :     xSeriesProperties->setPropertyValue( rPropertyName, rPropertyValue );
     599        2998 :     uno::Sequence< sal_Int32 > aAttributedDataPointIndexList;
     600        1499 :     if( xSeriesProperties->getPropertyValue( "AttributedDataPoints" ) >>= aAttributedDataPointIndexList )
     601             :     {
     602        2998 :         for(sal_Int32 nN=aAttributedDataPointIndexList.getLength();nN--;)
     603             :         {
     604           0 :             Reference< beans::XPropertySet > xPointProp( xSeries->getDataPointByIndex(aAttributedDataPointIndexList[nN]) );
     605           0 :             if(!xPointProp.is())
     606           0 :                 continue;
     607           0 :             xPointProp->setPropertyValue( rPropertyName, rPropertyValue );
     608           0 :         }
     609        1499 :     }
     610             : }
     611             : 
     612         186 : bool hasAttributedDataPointDifferentValue( const Reference< chart2::XDataSeries >& xSeries,
     613             :                                               const OUString& rPropertyName, const uno::Any& rPropertyValue )
     614             : {
     615         186 :     Reference< beans::XPropertySet > xSeriesProperties( xSeries, uno::UNO_QUERY );
     616         186 :     if( !xSeriesProperties.is() )
     617           0 :         return false;
     618             : 
     619         372 :     uno::Sequence< sal_Int32 > aAttributedDataPointIndexList;
     620         186 :     if( xSeriesProperties->getPropertyValue( "AttributedDataPoints" ) >>= aAttributedDataPointIndexList )
     621             :     {
     622         372 :         for(sal_Int32 nN=aAttributedDataPointIndexList.getLength();nN--;)
     623             :         {
     624           0 :             Reference< beans::XPropertySet > xPointProp( xSeries->getDataPointByIndex(aAttributedDataPointIndexList[nN]) );
     625           0 :             if(!xPointProp.is())
     626           0 :                 continue;
     627           0 :             uno::Any aPointValue( xPointProp->getPropertyValue( rPropertyName ) );
     628           0 :             if( !( rPropertyValue==aPointValue ) )
     629           0 :                 return true;
     630           0 :         }
     631             :     }
     632         372 :     return false;
     633             : }
     634             : 
     635           0 : bool areAllSeriesAttachedToSameAxis( const uno::Reference< chart2::XChartType >& xChartType, sal_Int32 & rOutAxisIndex )
     636             : {
     637             :     try
     638             :     {
     639           0 :         uno::Reference< chart2::XDataSeriesContainer > xDataSeriesContainer( xChartType, uno::UNO_QUERY_THROW );
     640           0 :         uno::Sequence< uno::Reference< chart2::XDataSeries > > aSeriesSeq( xDataSeriesContainer->getDataSeries());
     641             : 
     642           0 :         const sal_Int32 nSeriesCount( aSeriesSeq.getLength());
     643             :         // AxisIndex can only be 0 or 1
     644           0 :         sal_Int32 nSeriesAtFirstAxis = 0;
     645           0 :         sal_Int32 nSeriesAtSecondAxis = 0;
     646             : 
     647           0 :         for( sal_Int32 nI = 0; nI < nSeriesCount; ++nI )
     648             :         {
     649           0 :             uno::Reference< chart2::XDataSeries > xSeries( aSeriesSeq[nI], uno::UNO_QUERY );
     650           0 :             sal_Int32 nAxisIndex = DataSeriesHelper::getAttachedAxisIndex( xSeries );
     651           0 :             if( nAxisIndex == 0 )
     652           0 :                 ++nSeriesAtFirstAxis;
     653           0 :             else if( nAxisIndex == 1 )
     654           0 :                 ++nSeriesAtSecondAxis;
     655           0 :         }
     656             :         OSL_ENSURE( nSeriesAtFirstAxis + nSeriesAtSecondAxis == nSeriesCount, "Invalid axis index found" );
     657             : 
     658           0 :         if( nSeriesAtFirstAxis == nSeriesCount )
     659           0 :             rOutAxisIndex = 0;
     660           0 :         else if( nSeriesAtSecondAxis == nSeriesCount )
     661           0 :             rOutAxisIndex = 1;
     662             : 
     663           0 :         return ( nSeriesAtFirstAxis == nSeriesCount ||
     664           0 :                  nSeriesAtSecondAxis == nSeriesCount );
     665             :     }
     666           0 :     catch( const uno::Exception & ex )
     667             :     {
     668             :         ASSERT_EXCEPTION( ex );
     669           0 :         return false;
     670             :     }
     671             : }
     672             : 
     673             : namespace
     674             : {
     675             : 
     676        1437 : bool lcl_SequenceHasUnhiddenData( const uno::Reference< chart2::data::XDataSequence >& xDataSequence )
     677             : {
     678        1437 :     if( !xDataSequence.is() )
     679           0 :         return false;
     680        1437 :     uno::Reference< beans::XPropertySet > xProp( xDataSequence, uno::UNO_QUERY );
     681        1437 :     if( xProp.is() )
     682             :     {
     683        1437 :         uno::Sequence< sal_Int32 > aHiddenValues;
     684             :         try
     685             :         {
     686        1437 :             xProp->getPropertyValue( "HiddenValues" ) >>= aHiddenValues;
     687         352 :             if( !aHiddenValues.getLength() )
     688         352 :                 return true;
     689             :         }
     690        2170 :         catch( const uno::Exception& )
     691             :         {
     692        1085 :             return true;
     693           0 :         }
     694             :     }
     695           0 :     if( xDataSequence->getData().getLength() )
     696           0 :         return true;
     697           0 :     return false;
     698             : }
     699             : 
     700             : }
     701             : 
     702        1448 : bool hasUnhiddenData( const uno::Reference< chart2::XDataSeries >& xSeries )
     703             : {
     704             :     uno::Reference< chart2::data::XDataSource > xDataSource =
     705        1448 :         uno::Reference< chart2::data::XDataSource >( xSeries, uno::UNO_QUERY );
     706             : 
     707        2896 :     uno::Sequence< uno::Reference< chart2::data::XLabeledDataSequence > > aDataSequences = xDataSource->getDataSequences();
     708             : 
     709        2896 :     for(sal_Int32 nN = aDataSequences.getLength();nN--;)
     710             :     {
     711        1437 :         if( !aDataSequences[nN].is() )
     712           0 :             continue;
     713        1437 :         if( lcl_SequenceHasUnhiddenData( aDataSequences[nN]->getValues() ) )
     714        1437 :             return true;
     715           0 :         if( lcl_SequenceHasUnhiddenData( aDataSequences[nN]->getLabel() ) )
     716           0 :             return true;
     717             :     }
     718        1459 :     return false;
     719             : }
     720             : 
     721             : struct lcl_LessIndex
     722             : {
     723           0 :     inline bool operator() ( const sal_Int32& first, const sal_Int32& second ) const
     724             :     {
     725           0 :         return ( first < second );
     726             :     }
     727             : };
     728             : 
     729           0 : sal_Int32 translateIndexFromHiddenToFullSequence( sal_Int32 nIndex, const Reference< chart2::data::XDataSequence >& xDataSequence, bool bTranslate )
     730             : {
     731           0 :     if( !bTranslate )
     732           0 :         return nIndex;
     733             : 
     734             :     try
     735             :     {
     736           0 :         uno::Reference<beans::XPropertySet> xProp( xDataSequence, uno::UNO_QUERY );
     737           0 :         if( xProp.is())
     738             :         {
     739           0 :             Sequence<sal_Int32> aHiddenIndicesSeq;
     740           0 :             xProp->getPropertyValue( "HiddenValues" ) >>= aHiddenIndicesSeq;
     741           0 :             if( aHiddenIndicesSeq.getLength() )
     742             :             {
     743           0 :                 ::std::vector< sal_Int32 > aHiddenIndices( ContainerHelper::SequenceToVector( aHiddenIndicesSeq ) );
     744           0 :                 ::std::sort( aHiddenIndices.begin(), aHiddenIndices.end(), lcl_LessIndex() );
     745             : 
     746           0 :                 sal_Int32 nHiddenCount = static_cast<sal_Int32>(aHiddenIndices.size());
     747           0 :                 for( sal_Int32 nN = 0; nN < nHiddenCount; ++nN)
     748             :                 {
     749           0 :                     if( aHiddenIndices[nN] <= nIndex )
     750           0 :                         nIndex += 1;
     751             :                     else
     752           0 :                         break;
     753           0 :                 }
     754           0 :             }
     755           0 :         }
     756             :     }
     757           0 :     catch (const beans::UnknownPropertyException&)
     758             :     {
     759             :     }
     760           0 :     return nIndex;
     761             : }
     762             : 
     763        2297 : bool hasDataLabelsAtSeries( const Reference< chart2::XDataSeries >& xSeries )
     764             : {
     765        2297 :     bool bRet = false;
     766             :     try
     767             :     {
     768        2297 :         Reference< beans::XPropertySet > xProp( xSeries, uno::UNO_QUERY );
     769        2297 :         if( xProp.is() )
     770             :         {
     771        2297 :             DataPointLabel aLabel;
     772        2297 :             if( (xProp->getPropertyValue( "Label" ) >>= aLabel) )
     773        2297 :                 bRet = aLabel.ShowNumber || aLabel.ShowNumberInPercent || aLabel.ShowCategoryName;
     774        2297 :         }
     775             :     }
     776           0 :     catch(const uno::Exception &e)
     777             :     {
     778             :         ASSERT_EXCEPTION( e );
     779             :     }
     780        2297 :     return bRet;
     781             : }
     782             : 
     783           0 : bool hasDataLabelsAtPoints( const Reference< chart2::XDataSeries >& xSeries )
     784             : {
     785           0 :     bool bRet = false;
     786             :     try
     787             :     {
     788           0 :         Reference< beans::XPropertySet > xSeriesProperties( xSeries, uno::UNO_QUERY );
     789           0 :         if( xSeriesProperties.is() )
     790             :         {
     791           0 :             uno::Sequence< sal_Int32 > aAttributedDataPointIndexList;
     792           0 :             if( xSeriesProperties->getPropertyValue( "AttributedDataPoints" ) >>= aAttributedDataPointIndexList )
     793             :             {
     794           0 :                 for(sal_Int32 nN=aAttributedDataPointIndexList.getLength();nN--;)
     795             :                 {
     796           0 :                     Reference< beans::XPropertySet > xPointProp( xSeries->getDataPointByIndex(aAttributedDataPointIndexList[nN]) );
     797           0 :                     if( xPointProp.is() )
     798             :                     {
     799           0 :                         DataPointLabel aLabel;
     800           0 :                         if( (xPointProp->getPropertyValue( "Label" ) >>= aLabel) )
     801           0 :                             bRet = aLabel.ShowNumber || aLabel.ShowNumberInPercent || aLabel.ShowCategoryName;
     802           0 :                         if( bRet )
     803           0 :                             break;
     804             :                     }
     805           0 :                 }
     806           0 :             }
     807           0 :         }
     808             :     }
     809           0 :     catch(const uno::Exception &e)
     810             :     {
     811             :         ASSERT_EXCEPTION( e );
     812             :     }
     813           0 :     return bRet;
     814             : }
     815             : 
     816           0 : bool hasDataLabelAtPoint( const Reference< chart2::XDataSeries >& xSeries, sal_Int32 nPointIndex )
     817             : {
     818           0 :     bool bRet = false;
     819             :     try
     820             :     {
     821           0 :         Reference< beans::XPropertySet > xProp;
     822           0 :         Reference< beans::XPropertySet > xSeriesProperties( xSeries, uno::UNO_QUERY );
     823           0 :         if( xSeriesProperties.is() )
     824             :         {
     825           0 :             uno::Sequence< sal_Int32 > aAttributedDataPointIndexList;
     826           0 :             if( xSeriesProperties->getPropertyValue( "AttributedDataPoints" ) >>= aAttributedDataPointIndexList )
     827             :             {
     828           0 :                 ::std::vector< sal_Int32 > aIndices( ContainerHelper::SequenceToVector( aAttributedDataPointIndexList ) );
     829           0 :                 ::std::vector< sal_Int32 >::iterator aIt = ::std::find( aIndices.begin(), aIndices.end(), nPointIndex );
     830           0 :                 if( aIt != aIndices.end())
     831           0 :                     xProp = xSeries->getDataPointByIndex(nPointIndex);
     832             :                 else
     833           0 :                     xProp = xSeriesProperties;
     834             :             }
     835           0 :             if( xProp.is() )
     836             :             {
     837           0 :                 DataPointLabel aLabel;
     838           0 :                 if( (xProp->getPropertyValue( "Label" ) >>= aLabel) )
     839           0 :                     bRet = aLabel.ShowNumber || aLabel.ShowNumberInPercent || aLabel.ShowCategoryName;
     840           0 :             }
     841           0 :         }
     842             :     }
     843           0 :     catch(const uno::Exception &e)
     844             :     {
     845             :         ASSERT_EXCEPTION( e );
     846             :     }
     847           0 :     return bRet;
     848             : }
     849             : 
     850           0 : void insertDataLabelsToSeriesAndAllPoints( const Reference< chart2::XDataSeries >& xSeries )
     851             : {
     852           0 :     lcl_insertOrDeleteDataLabelsToSeriesAndAllPoints( xSeries, true /*bInsert*/ );
     853           0 : }
     854             : 
     855           0 : void deleteDataLabelsFromSeriesAndAllPoints( const Reference< chart2::XDataSeries >& xSeries )
     856             : {
     857           0 :     lcl_insertOrDeleteDataLabelsToSeriesAndAllPoints( xSeries, false /*bInsert*/ );
     858           0 : }
     859             : 
     860           0 : void insertDataLabelToPoint( const Reference< beans::XPropertySet >& xPointProp )
     861             : {
     862             :     try
     863             :     {
     864           0 :         if( xPointProp.is() )
     865             :         {
     866           0 :             DataPointLabel aLabel;
     867           0 :             xPointProp->getPropertyValue( "Label" ) >>= aLabel;
     868           0 :             aLabel.ShowNumber = true;
     869           0 :             xPointProp->setPropertyValue( "Label", uno::makeAny( aLabel ) );
     870             :         }
     871             :     }
     872           0 :     catch(const uno::Exception &e)
     873             :     {
     874             :         ASSERT_EXCEPTION( e );
     875             :     }
     876           0 : }
     877             : 
     878           0 : void deleteDataLabelsFromPoint( const Reference< beans::XPropertySet >& xPointProp )
     879             : {
     880             :     try
     881             :     {
     882           0 :         if( xPointProp.is() )
     883             :         {
     884           0 :             DataPointLabel aLabel;
     885           0 :             xPointProp->getPropertyValue( "Label" ) >>= aLabel;
     886           0 :             aLabel.ShowNumber = false;
     887           0 :             aLabel.ShowNumberInPercent = false;
     888           0 :             aLabel.ShowCategoryName = false;
     889           0 :             xPointProp->setPropertyValue( "Label", uno::makeAny( aLabel ) );
     890             :         }
     891             :     }
     892           0 :     catch(const uno::Exception &e)
     893             :     {
     894             :         ASSERT_EXCEPTION( e );
     895             :     }
     896           0 : }
     897             : 
     898             : } //  namespace DataSeriesHelper
     899             : } //  namespace chart
     900             : 
     901             : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.10