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

Generated by: LCOV version 1.10