LCOV - code coverage report
Current view: top level - chart2/source/controller/main - ObjectHierarchy.cxx (source / functions) Hit Total Coverage
Test: commit 0e63ca4fde4e446f346e35849c756a30ca294aab Lines: 169 389 43.4 %
Date: 2014-04-11 Functions: 14 41 34.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 "ObjectHierarchy.hxx"
      21             : #include "ObjectIdentifier.hxx"
      22             : #include "ChartModelHelper.hxx"
      23             : #include "DiagramHelper.hxx"
      24             : #include "RegressionCurveHelper.hxx"
      25             : #include "AxisHelper.hxx"
      26             : #include "chartview/ExplicitValueProvider.hxx"
      27             : #include "macros.hxx"
      28             : #include "LineProperties.hxx"
      29             : #include "ChartTypeHelper.hxx"
      30             : #include "DataSeriesHelper.hxx"
      31             : #include "LegendHelper.hxx"
      32             : #include "chartview/DrawModelWrapper.hxx"
      33             : 
      34             : #include <map>
      35             : #include <algorithm>
      36             : 
      37             : #include <com/sun/star/chart2/XTitled.hpp>
      38             : #include <com/sun/star/chart2/XCoordinateSystemContainer.hpp>
      39             : #include <com/sun/star/chart2/XChartTypeContainer.hpp>
      40             : #include <com/sun/star/chart2/XDataSeriesContainer.hpp>
      41             : #include <com/sun/star/chart/ErrorBarStyle.hpp>
      42             : 
      43             : #include <com/sun/star/container/XIndexAccess.hpp>
      44             : #include <com/sun/star/awt/Key.hpp>
      45             : #include <com/sun/star/awt/KeyModifier.hpp>
      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             : 
      53             : namespace
      54             : {
      55             : 
      56           0 : struct lcl_ObjectToOID : public ::std::unary_function< Reference< uno::XInterface >, ::chart::ObjectIdentifier >
      57             : {
      58           0 :     explicit lcl_ObjectToOID( const Reference< chart2::XChartDocument > & xChartDoc ) :
      59           0 :             m_xModel( xChartDoc, uno::UNO_QUERY )
      60           0 :     {}
      61             : 
      62           0 :     ::chart::ObjectIdentifier operator() ( const Reference< uno::XInterface > & xObj )
      63             :     {
      64           0 :         return ::chart::ObjectIdentifier( ::chart::ObjectIdentifier::createClassifiedIdentifierForObject( xObj, m_xModel ) );
      65             :     }
      66             : 
      67             : private:
      68             :     Reference< frame::XModel > m_xModel;
      69             : };
      70             : 
      71           0 : void lcl_getChildOIDs(
      72             :     ::chart::ObjectHierarchy::tChildContainer& rOutChildren,
      73             :     const Reference< container::XIndexAccess >& xShapes )
      74             : {
      75           0 :     if( xShapes.is())
      76             :     {
      77           0 :         sal_Int32 nCount = xShapes->getCount();
      78           0 :         for( sal_Int32 i=0; i<nCount; ++i)
      79             :         {
      80           0 :             Reference< beans::XPropertySet > xShapeProp( xShapes->getByIndex( i ), uno::UNO_QUERY );
      81           0 :             if( xShapeProp.is())
      82             :             {
      83           0 :                 Reference< beans::XPropertySetInfo > xInfo( xShapeProp->getPropertySetInfo());
      84           0 :                 OUString aName;
      85           0 :                 if( xInfo.is() &&
      86           0 :                     xInfo->hasPropertyByName( "Name") &&
      87           0 :                     (xShapeProp->getPropertyValue( "Name") >>= aName ) &&
      88           0 :                     !aName.isEmpty() &&
      89           0 :                     ::chart::ObjectIdentifier::isCID( aName ))
      90             :                 {
      91           0 :                     rOutChildren.push_back( ::chart::ObjectIdentifier( aName ) );
      92             :                 }
      93           0 :                 Reference< container::XIndexAccess > xNewShapes( xShapeProp, uno::UNO_QUERY );
      94           0 :                 if( xNewShapes.is())
      95           0 :                     lcl_getChildOIDs( rOutChildren, xNewShapes );
      96             :             }
      97           0 :         }
      98             :     }
      99           0 : }
     100             : 
     101        1527 : void lcl_addAxisTitle( const Reference< XAxis >& xAxis, ::chart::ObjectHierarchy::tChildContainer& rContainer, const Reference< frame::XModel >& xChartModel )
     102             : {
     103        1527 :     Reference< XTitled > xAxisTitled( xAxis, uno::UNO_QUERY );
     104        1527 :     if( xAxisTitled.is())
     105             :     {
     106        1527 :         Reference< XTitle > xAxisTitle( xAxisTitled->getTitleObject());
     107        1527 :         if( xAxisTitle.is())
     108             :             rContainer.push_back(
     109           0 :                 ::chart::ObjectIdentifier( ::chart::ObjectIdentifier::createClassifiedIdentifierForObject( xAxisTitle, xChartModel ) ) );
     110        1527 :     }
     111        1527 : }
     112             : 
     113             : } // anonymous namespace
     114             : 
     115             : namespace chart
     116             : {
     117             : 
     118             : namespace impl
     119             : {
     120             : 
     121         780 : class ImplObjectHierarchy
     122             : {
     123             : public:
     124             :     explicit ImplObjectHierarchy(
     125             :         const Reference< XChartDocument >& xChartDocument,
     126             :         ExplicitValueProvider* pExplicitValueProvider,
     127             :         bool bFlattenDiagram, bool bOrderingForElementSelector );
     128             : 
     129             :     bool                              hasChildren( const ObjectHierarchy::tOID& rParent );
     130             :     ObjectHierarchy::tChildContainer  getChildren( const ObjectHierarchy::tOID& rParent );
     131             :     ObjectHierarchy::tChildContainer  getSiblings( const ObjectHierarchy::tOID& rNode );
     132             : 
     133             :     ObjectHierarchy::tOID             getParent( const ObjectHierarchy::tOID& rOID );
     134             : 
     135             : private:
     136             :     void createTree( const Reference< XChartDocument > & xChartDocument );
     137             :     void createAxesTree(
     138             :         ObjectHierarchy::tChildContainer & rContainer,
     139             :         const Reference< XChartDocument > & xChartDoc,
     140             :         const Reference< XDiagram > & xDiagram  );
     141             :     void createDiagramTree(
     142             :         ObjectHierarchy::tChildContainer& rContainer,
     143             :         const Reference< XChartDocument >& xChartDoc,
     144             :         const Reference< XDiagram >& xDiagram );
     145             :     void createDataSeriesTree(
     146             :         ObjectHierarchy::tChildContainer & rOutDiagramSubContainer,
     147             :         const Reference< XDiagram > & xDiagram );
     148             :     void createWallAndFloor(
     149             :         ObjectHierarchy::tChildContainer & rContainer,
     150             :         const Reference< XDiagram > & xDiagram );
     151             :     void createLegendTree(
     152             :         ObjectHierarchy::tChildContainer & rContainer,
     153             :         const Reference< XChartDocument > & xChartDoc,
     154             :         const Reference< XDiagram > & xDiagram  );
     155             :     void createAdditionalShapesTree( ObjectHierarchy::tChildContainer& rContainer );
     156             : 
     157             :     ObjectHierarchy::tOID getParentImpl(
     158             :         const ObjectHierarchy::tOID& rParentOID,
     159             :         const ObjectHierarchy::tOID& rOID );
     160             : 
     161             :     typedef ::std::map< ObjectHierarchy::tOID, ObjectHierarchy::tChildContainer >
     162             :         tChildMap;
     163             :     tChildMap m_aChildMap;
     164             :     ExplicitValueProvider* m_pExplicitValueProvider;
     165             :     bool m_bFlattenDiagram;
     166             :     bool m_bOrderingForElementSelector;
     167             : };
     168             : 
     169         780 : ImplObjectHierarchy::ImplObjectHierarchy(
     170             :     const Reference< XChartDocument >& xChartDocument,
     171             :     ExplicitValueProvider* pExplicitValueProvider,
     172             :     bool bFlattenDiagram,
     173             :     bool bOrderingForElementSelector ) :
     174             :         m_pExplicitValueProvider( pExplicitValueProvider ),
     175             :         m_bFlattenDiagram( bFlattenDiagram ),
     176         780 :         m_bOrderingForElementSelector( bOrderingForElementSelector )
     177             : {
     178         780 :     createTree( xChartDocument );
     179             :     // don't remember this helper to avoid access after lifetime
     180         780 :     m_pExplicitValueProvider = 0;
     181         780 : }
     182             : 
     183         780 : void ImplObjectHierarchy::createTree( const Reference< XChartDocument >& xChartDocument )
     184             : {
     185         780 :     m_aChildMap = tChildMap();//clear tree
     186             : 
     187         780 :     if( !xChartDocument.is() )
     188         780 :         return;
     189             : 
     190             :     //@todo: change ObjectIdentifier to take an XChartDocument rather than XModel
     191         780 :     Reference< frame::XModel > xModel( xChartDocument, uno::UNO_QUERY );
     192        1560 :     Reference< XDiagram > xDiagram( ChartModelHelper::findDiagram( xChartDocument ) );
     193        1560 :     ObjectHierarchy::tOID aDiaOID;
     194         780 :     if( xDiagram.is() )
     195         777 :         aDiaOID = ObjectIdentifier( ObjectIdentifier::createClassifiedIdentifierForObject( xDiagram, xModel ) );
     196        1560 :     ObjectHierarchy::tChildContainer aTopLevelContainer;
     197             : 
     198             :     // First Level
     199             : 
     200             :     // Chart Area
     201         780 :     if( m_bOrderingForElementSelector )
     202             :     {
     203         780 :         aTopLevelContainer.push_back( ObjectIdentifier( ObjectIdentifier::createClassifiedIdentifier( OBJECTTYPE_PAGE, OUString() ) ) );
     204         780 :         if( xDiagram.is() )
     205             :         {
     206         777 :             aTopLevelContainer.push_back( aDiaOID );
     207         777 :             createWallAndFloor( aTopLevelContainer, xDiagram );
     208         777 :             createLegendTree( aTopLevelContainer, xChartDocument, xDiagram  );
     209             :         }
     210             :     }
     211             : 
     212             :     // Main Title
     213        1560 :     Reference< XTitled > xDocTitled( xChartDocument, uno::UNO_QUERY );
     214         780 :     if( xDocTitled.is())
     215             :     {
     216         780 :         Reference< XTitle > xMainTitle( xDocTitled->getTitleObject());
     217         780 :         if( xMainTitle.is())
     218             :             aTopLevelContainer.push_back(
     219         462 :                 ObjectIdentifier( ObjectIdentifier::createClassifiedIdentifierForObject( xMainTitle, xModel ) ) );
     220             :     }
     221             : 
     222         780 :     if( xDiagram.is())
     223             :     {
     224             :         // Sub Title.  Note: This is interpreted of being top level
     225         777 :         Reference< XTitled > xDiaTitled( xDiagram, uno::UNO_QUERY );
     226         777 :         if( xDiaTitled.is())
     227             :         {
     228         777 :             Reference< XTitle > xSubTitle( xDiaTitled->getTitleObject());
     229         777 :             if( xSubTitle.is())
     230             :                 aTopLevelContainer.push_back(
     231         289 :                     ObjectIdentifier( ObjectIdentifier::createClassifiedIdentifierForObject( xSubTitle, xModel ) ) );
     232             :         }
     233             : 
     234         777 :         if( !m_bOrderingForElementSelector )
     235             :         {
     236             :             // Axis Titles. Note: These are interpreted of being top level
     237           0 :             Sequence< Reference< XAxis > > aAxes( AxisHelper::getAllAxesOfDiagram( xDiagram ) );
     238           0 :             for( sal_Int32 i=0; i<aAxes.getLength(); ++i )
     239           0 :                 lcl_addAxisTitle( aAxes[i], aTopLevelContainer, xModel );
     240             : 
     241             :             // Diagram
     242           0 :             aTopLevelContainer.push_back( aDiaOID );
     243             :         }
     244             : 
     245         777 :         if( m_bFlattenDiagram )
     246         777 :             createDiagramTree( aTopLevelContainer, xChartDocument, xDiagram );
     247             :         else
     248             :         {
     249           0 :             ObjectHierarchy::tChildContainer aSubContainer;
     250           0 :             createDiagramTree( aSubContainer, xChartDocument, xDiagram );
     251           0 :             if( !aSubContainer.empty() )
     252           0 :                 m_aChildMap[ aDiaOID ] = aSubContainer;
     253             :         }
     254             : 
     255         777 :         if( !m_bOrderingForElementSelector )
     256           0 :             createLegendTree( aTopLevelContainer, xChartDocument, xDiagram  );
     257             :     }
     258             : 
     259             :     // #i12587# support for shapes in chart
     260         780 :     if ( !m_bOrderingForElementSelector )
     261             :     {
     262           0 :         createAdditionalShapesTree( aTopLevelContainer );
     263             :     }
     264             : 
     265             :     // Chart Area
     266         780 :     if( !m_bOrderingForElementSelector )
     267             :         aTopLevelContainer.push_back(
     268           0 :             ObjectIdentifier( ObjectIdentifier::createClassifiedIdentifier( OBJECTTYPE_PAGE, OUString() ) ) );
     269             : 
     270         780 :     if( ! aTopLevelContainer.empty())
     271        1560 :         m_aChildMap[ ObjectHierarchy::getRootNodeOID() ] = aTopLevelContainer;
     272             : }
     273             : 
     274         777 : void ImplObjectHierarchy::createLegendTree(
     275             :     ObjectHierarchy::tChildContainer & rContainer,
     276             :     const Reference< XChartDocument > & xChartDoc,
     277             :     const Reference< XDiagram > & xDiagram  )
     278             : {
     279         777 :     if( xDiagram.is() && LegendHelper::hasLegend( xDiagram ) )
     280             :     {
     281         749 :         ObjectHierarchy::tOID aLegendOID( ObjectIdentifier( ObjectIdentifier::createClassifiedIdentifierForObject( xDiagram->getLegend(), Reference< frame::XModel >( xChartDoc, uno::UNO_QUERY ) ) ) );
     282         749 :         rContainer.push_back( aLegendOID );
     283             : 
     284             :         // iterate over child shapes of legend and search for matching CIDs
     285         749 :         if( m_pExplicitValueProvider )
     286             :         {
     287             :             Reference< container::XIndexAccess > xLegendShapeContainer(
     288           0 :                 m_pExplicitValueProvider->getShapeForCID( aLegendOID.getObjectCID() ), uno::UNO_QUERY );
     289           0 :             ObjectHierarchy::tChildContainer aLegendEntryOIDs;
     290           0 :             lcl_getChildOIDs( aLegendEntryOIDs, xLegendShapeContainer );
     291             : 
     292           0 :             m_aChildMap[ aLegendOID ] = aLegendEntryOIDs;
     293         749 :         }
     294             :     }
     295         777 : }
     296             : 
     297         777 : void ImplObjectHierarchy::createAxesTree(
     298             :     ObjectHierarchy::tChildContainer & rContainer,
     299             :     const Reference< XChartDocument > & xChartDoc,
     300             :     const Reference< XDiagram > & xDiagram  )
     301             : {
     302         777 :     Reference< XCoordinateSystemContainer > xCooSysCnt( xDiagram, uno::UNO_QUERY_THROW );
     303         777 :     sal_Int32 nDimensionCount = DiagramHelper::getDimension( xDiagram );
     304        1554 :     uno::Reference< chart2::XChartType > xChartType( DiagramHelper::getChartTypeByIndex( xDiagram, 0 ) );
     305         777 :     bool bSupportsAxesGrids = ChartTypeHelper::isSupportingMainAxis( xChartType, nDimensionCount, 0 );
     306         777 :     if( bSupportsAxesGrids )
     307             :     {
     308         763 :         Sequence< Reference< XAxis > > aAxes( AxisHelper::getAllAxesOfDiagram( xDiagram, /* bOnlyVisible = */ true ) );
     309         763 :         if( !m_bOrderingForElementSelector )
     310           0 :             ::std::transform( aAxes.getConstArray(), aAxes.getConstArray() + aAxes.getLength(),
     311             :                           ::std::back_inserter( rContainer ),
     312           0 :                           lcl_ObjectToOID( xChartDoc ));
     313             : 
     314             :         // get all axes, also invisible ones
     315         763 :         aAxes = AxisHelper::getAllAxesOfDiagram( xDiagram, /* bOnlyVisible = */ false );
     316             :         // Grids
     317        1526 :         Reference< frame::XModel > xChartModel( xChartDoc, uno::UNO_QUERY );
     318        2290 :         for( sal_Int32 nA=0; nA<aAxes.getLength(); ++nA )
     319             :         {
     320        1527 :             Reference< XAxis > xAxis( aAxes[nA] );
     321        1527 :             if(!xAxis.is())
     322           0 :                 continue;
     323             : 
     324        1527 :             sal_Int32 nCooSysIndex = 0;
     325        1527 :             sal_Int32 nDimensionIndex = 0;
     326        1527 :             sal_Int32 nAxisIndex = 0;
     327        1527 :             AxisHelper::getIndicesForAxis( xAxis, xDiagram, nCooSysIndex, nDimensionIndex, nAxisIndex );
     328        1527 :             if( nAxisIndex>0 && !ChartTypeHelper::isSupportingSecondaryAxis( xChartType, nDimensionCount, nDimensionIndex ) )
     329           0 :                 continue;
     330             : 
     331        1527 :             if( m_bOrderingForElementSelector )
     332             :             {
     333             :                 // axis
     334        1527 :                 if( AxisHelper::isAxisVisible( xAxis ) )
     335             :                     rContainer.push_back(
     336        1320 :                         ObjectIdentifier( ObjectIdentifier::createClassifiedIdentifierForObject( xAxis, xChartModel ) ) );
     337             : 
     338             :                 // axis title
     339        1527 :                 lcl_addAxisTitle( aAxes[nA], rContainer, xChartModel );
     340             :             }
     341             : 
     342        3054 :             Reference< beans::XPropertySet > xGridProperties( xAxis->getGridProperties() );
     343        1527 :             if( AxisHelper::isGridVisible( xGridProperties ) )
     344             :             {
     345             :                 //main grid
     346             :                 rContainer.push_back(
     347         615 :                     ObjectIdentifier( ObjectIdentifier( ObjectIdentifier::createClassifiedIdentifierForGrid( xAxis, xChartModel ) ) ) );
     348             :             }
     349             : 
     350        3054 :             Sequence< Reference< beans::XPropertySet > > aSubGrids( xAxis->getSubGridProperties() );;
     351        1527 :             sal_Int32 nSubGrid = 0;
     352        3054 :             for( nSubGrid = 0; nSubGrid < aSubGrids.getLength(); ++nSubGrid )
     353             :             {
     354        1527 :                 Reference< beans::XPropertySet > xSubGridProperties( aSubGrids[nSubGrid] );
     355        1527 :                 if( AxisHelper::isGridVisible( xSubGridProperties ) )
     356             :                 {
     357             :                     //sub grid
     358             :                     rContainer.push_back(
     359           0 :                         ObjectIdentifier( ObjectIdentifier( ObjectIdentifier::createClassifiedIdentifierForGrid( xAxis, xChartModel, nSubGrid ) ) ) );
     360             :                 }
     361        1527 :             }
     362        2290 :         }
     363         777 :     }
     364         777 : }
     365             : 
     366         777 : void ImplObjectHierarchy::createWallAndFloor(
     367             :     ObjectHierarchy::tChildContainer & rContainer,
     368             :     const Reference< XDiagram > & xDiagram )
     369             : {
     370         777 :     sal_Int32 nDimensionCount = DiagramHelper::getDimension( xDiagram );
     371         777 :     bool bIsThreeD = ( nDimensionCount == 3 );
     372         777 :     bool bHasWall = DiagramHelper::isSupportingFloorAndWall( xDiagram );
     373         777 :     if( bHasWall && bIsThreeD )
     374             :     {
     375             :         rContainer.push_back(
     376           5 :             ObjectIdentifier( ObjectIdentifier::createClassifiedIdentifier( OBJECTTYPE_DIAGRAM_WALL, OUString() ) ) );
     377             : 
     378           5 :         Reference< beans::XPropertySet > xFloor( xDiagram->getFloor());
     379           5 :         if( xFloor.is())
     380             :             rContainer.push_back(
     381           5 :                 ObjectIdentifier( ObjectIdentifier::createClassifiedIdentifier( OBJECTTYPE_DIAGRAM_FLOOR, OUString() ) ) );
     382             :     }
     383             : 
     384         777 : }
     385             : 
     386         777 : void ImplObjectHierarchy::createDiagramTree(
     387             :     ObjectHierarchy::tChildContainer & rContainer,
     388             :     const Reference< XChartDocument > & xChartDoc,
     389             :     const Reference< XDiagram > & xDiagram )
     390             : {
     391         777 :     if( !m_bOrderingForElementSelector )
     392             :     {
     393           0 :         createDataSeriesTree( rContainer, xDiagram );
     394           0 :         createAxesTree( rContainer, xChartDoc, xDiagram  );
     395           0 :         createWallAndFloor( rContainer, xDiagram );
     396             :     }
     397             :     else
     398             :     {
     399         777 :         createAxesTree( rContainer, xChartDoc, xDiagram  );
     400         777 :         createDataSeriesTree( rContainer, xDiagram );
     401             :     }
     402         777 : }
     403             : 
     404         777 : void ImplObjectHierarchy::createDataSeriesTree(
     405             :     ObjectHierarchy::tChildContainer & rOutDiagramSubContainer,
     406             :     const Reference< XDiagram > & xDiagram )
     407             : {
     408         777 :     Reference< XCoordinateSystemContainer > xCooSysCnt( xDiagram, uno::UNO_QUERY_THROW );
     409             : 
     410             :     try
     411             :     {
     412         777 :         sal_Int32 nDiagramIndex = 0;
     413         777 :         sal_Int32 nDimensionCount = DiagramHelper::getDimension( xDiagram );
     414             :         Sequence< Reference< XCoordinateSystem > > aCooSysSeq(
     415         777 :             xCooSysCnt->getCoordinateSystems());
     416        1552 :         for( sal_Int32 nCooSysIdx=0; nCooSysIdx<aCooSysSeq.getLength(); ++nCooSysIdx )
     417             :         {
     418         775 :             Reference< XChartTypeContainer > xCTCnt( aCooSysSeq[nCooSysIdx], uno::UNO_QUERY_THROW );
     419        1550 :             Sequence< Reference< XChartType > > aChartTypeSeq( xCTCnt->getChartTypes());
     420        1550 :             for( sal_Int32 nCTIdx=0; nCTIdx<aChartTypeSeq.getLength(); ++nCTIdx )
     421             :             {
     422         775 :                 Reference< XChartType > xChartType( aChartTypeSeq[nCTIdx] );
     423        1550 :                 Reference< XDataSeriesContainer > xDSCnt( xChartType, uno::UNO_QUERY_THROW );
     424        1550 :                 Sequence< Reference< XDataSeries > > aSeriesSeq( xDSCnt->getDataSeries() );
     425             :                 const sal_Int32 nNumberOfSeries =
     426         775 :                     ChartTypeHelper::getNumberOfDisplayedSeries( xChartType, aSeriesSeq.getLength());
     427             : 
     428        3072 :                 for( sal_Int32 nSeriesIdx=0; nSeriesIdx<nNumberOfSeries; ++nSeriesIdx )
     429             :                 {
     430             :                     OUString aSeriesParticle(
     431             :                         ObjectIdentifier::createParticleForSeries(
     432        2297 :                             nDiagramIndex, nCooSysIdx, nCTIdx, nSeriesIdx ));
     433             :                     ObjectHierarchy::tOID aSeriesOID(
     434        4594 :                         ObjectIdentifier( ObjectIdentifier::createClassifiedIdentifierForParticle( aSeriesParticle ) ) );
     435        2297 :                     rOutDiagramSubContainer.push_back( aSeriesOID );
     436             : 
     437        4594 :                     ObjectHierarchy::tChildContainer aSeriesSubContainer;
     438             : 
     439        4594 :                     Reference< chart2::XDataSeries > xSeries( aSeriesSeq[nSeriesIdx], uno::UNO_QUERY );
     440             : 
     441             :                     // data lablels
     442        2297 :                     if( DataSeriesHelper::hasDataLabelsAtSeries( xSeries ) )
     443             :                     {
     444           0 :                         OUString aChildParticle( ObjectIdentifier::getStringForType( OBJECTTYPE_DATA_LABELS ) );
     445           0 :                         aChildParticle+=("=");
     446             :                         aSeriesSubContainer.push_back(
     447           0 :                                     ObjectIdentifier( ObjectIdentifier::createClassifiedIdentifierForParticles( aSeriesParticle, aChildParticle ) ) );
     448             :                     }
     449             : 
     450             :                     // Statistics
     451        2297 :                     if( ChartTypeHelper::isSupportingStatisticProperties( xChartType, nDimensionCount ) )
     452             :                     {
     453        2268 :                         Reference< chart2::XRegressionCurveContainer > xCurveCnt( xSeries, uno::UNO_QUERY );
     454        2268 :                         if( xCurveCnt.is())
     455             :                         {
     456        2268 :                             Sequence< Reference< chart2::XRegressionCurve > > aCurves( xCurveCnt->getRegressionCurves());
     457        2274 :                             for( sal_Int32 nCurveIdx=0; nCurveIdx<aCurves.getLength(); ++nCurveIdx )
     458             :                             {
     459           6 :                                 bool bIsAverageLine = RegressionCurveHelper::isMeanValueLine( aCurves[nCurveIdx] );
     460             :                                 aSeriesSubContainer.push_back(
     461           6 :                                     ObjectIdentifier( ObjectIdentifier::createDataCurveCID( aSeriesParticle, nCurveIdx, bIsAverageLine ) ) );
     462           6 :                                 if( RegressionCurveHelper::hasEquation( aCurves[nCurveIdx] ) )
     463             :                                 {
     464             :                                     aSeriesSubContainer.push_back(
     465           0 :                                         ObjectIdentifier( ObjectIdentifier::createDataCurveEquationCID( aSeriesParticle, nCurveIdx ) ) );
     466             :                                 }
     467             :                             }
     468        4536 :                             Reference< beans::XPropertySet > xSeriesProp( xSeries, uno::UNO_QUERY );
     469        4536 :                             Reference< beans::XPropertySet > xErrorBarProp;
     470       11340 :                             if( xSeriesProp.is() &&
     471       13608 :                                 (xSeriesProp->getPropertyValue( "ErrorBarY") >>= xErrorBarProp) &&
     472        2268 :                                 xErrorBarProp.is())
     473             :                             {
     474         825 :                                 sal_Int32 nStyle = ::com::sun::star::chart::ErrorBarStyle::NONE;
     475        1650 :                                 if( ( xErrorBarProp->getPropertyValue( "ErrorBarStyle") >>= nStyle ) &&
     476         825 :                                     ( nStyle != ::com::sun::star::chart::ErrorBarStyle::NONE ) )
     477             :                                 {
     478             :                                     aSeriesSubContainer.push_back(
     479             :                                         ObjectIdentifier( ObjectIdentifier::createClassifiedIdentifierWithParent(
     480           0 :                                             OBJECTTYPE_DATA_ERRORS_Y, OUString(), aSeriesParticle ) ) );
     481             :                                 }
     482             :                             }
     483             : 
     484       11340 :                             if( xSeriesProp.is() &&
     485       13608 :                                 (xSeriesProp->getPropertyValue( "ErrorBarX") >>= xErrorBarProp) &&
     486        2268 :                                 xErrorBarProp.is())
     487             :                             {
     488           0 :                                 sal_Int32 nStyle = ::com::sun::star::chart::ErrorBarStyle::NONE;
     489           0 :                                 if( ( xErrorBarProp->getPropertyValue( "ErrorBarStyle") >>= nStyle ) &&
     490           0 :                                     ( nStyle != ::com::sun::star::chart::ErrorBarStyle::NONE ) )
     491             :                                 {
     492             :                                     aSeriesSubContainer.push_back(
     493             :                                         ObjectIdentifier( ObjectIdentifier::createClassifiedIdentifierWithParent(
     494           0 :                                             OBJECTTYPE_DATA_ERRORS_X, OUString(), aSeriesParticle ) ) );
     495             :                                 }
     496        2268 :                             }
     497        2268 :                         }
     498             :                     }
     499             : 
     500             :                     // Data Points
     501             :                     // iterate over child shapes of legend and search for matching CIDs
     502        2297 :                     if( m_pExplicitValueProvider )
     503             :                     {
     504             :                         Reference< container::XIndexAccess > xSeriesShapeContainer(
     505           0 :                             m_pExplicitValueProvider->getShapeForCID( aSeriesOID.getObjectCID() ), uno::UNO_QUERY );
     506           0 :                         lcl_getChildOIDs( aSeriesSubContainer, xSeriesShapeContainer );
     507             :                     }
     508             : 
     509        2297 :                     if( ! aSeriesSubContainer.empty())
     510           6 :                         m_aChildMap[ aSeriesOID ] = aSeriesSubContainer;
     511        2297 :                 }
     512         775 :             }
     513        1552 :         }
     514             :     }
     515           0 :     catch( const uno::Exception & ex )
     516             :     {
     517             :         ASSERT_EXCEPTION( ex );
     518         777 :     }
     519         777 : }
     520             : 
     521           0 : void ImplObjectHierarchy::createAdditionalShapesTree( ObjectHierarchy::tChildContainer& rContainer )
     522             : {
     523             :     try
     524             :     {
     525           0 :         if ( m_pExplicitValueProvider )
     526             :         {
     527           0 :             Reference< drawing::XDrawPage > xDrawPage( m_pExplicitValueProvider->getDrawModelWrapper()->getMainDrawPage() );
     528           0 :             Reference< drawing::XShapes > xDrawPageShapes( xDrawPage, uno::UNO_QUERY_THROW );
     529           0 :             Reference< drawing::XShapes > xChartRoot( DrawModelWrapper::getChartRootShape( xDrawPage ) );
     530           0 :             sal_Int32 nCount = xDrawPageShapes->getCount();
     531           0 :             for ( sal_Int32 i = 0; i < nCount; ++i )
     532             :             {
     533           0 :                 Reference< drawing::XShape > xShape;
     534           0 :                 if ( xDrawPageShapes->getByIndex( i ) >>= xShape )
     535             :                 {
     536           0 :                     if ( xShape.is() && xShape != xChartRoot )
     537             :                     {
     538           0 :                         rContainer.push_back( ObjectIdentifier( xShape ) );
     539             :                     }
     540             :                 }
     541           0 :             }
     542             :         }
     543             :     }
     544           0 :     catch ( const uno::Exception& ex )
     545             :     {
     546             :         ASSERT_EXCEPTION( ex );
     547             :     }
     548           0 : }
     549             : 
     550           0 : bool ImplObjectHierarchy::hasChildren( const ObjectHierarchy::tOID& rParent )
     551             : {
     552           0 :     if ( rParent.isValid() )
     553             :     {
     554           0 :         tChildMap::const_iterator aIt( m_aChildMap.find( rParent ));
     555           0 :         if( aIt != m_aChildMap.end())
     556           0 :             return ! (aIt->second.empty());
     557             :     }
     558           0 :     return false;
     559             : }
     560             : 
     561        8085 : ObjectHierarchy::tChildContainer ImplObjectHierarchy::getChildren( const ObjectHierarchy::tOID& rParent )
     562             : {
     563        8085 :     if ( rParent.isValid() )
     564             :     {
     565        8085 :         tChildMap::const_iterator aIt( m_aChildMap.find( rParent ));
     566        8085 :         if( aIt != m_aChildMap.end())
     567         786 :             return aIt->second;
     568             :     }
     569        7299 :     return ObjectHierarchy::tChildContainer();
     570             : }
     571             : 
     572           0 : ObjectHierarchy::tChildContainer ImplObjectHierarchy::getSiblings( const ObjectHierarchy::tOID& rNode )
     573             : {
     574           0 :     if ( rNode.isValid() && !ObjectHierarchy::isRootNode( rNode ) )
     575             :     {
     576           0 :         for( tChildMap::const_iterator aIt( m_aChildMap.begin());
     577           0 :              aIt != m_aChildMap.end(); ++aIt )
     578             :         {
     579             :             ObjectHierarchy::tChildContainer::const_iterator aElemIt(
     580           0 :                 ::std::find( aIt->second.begin(), aIt->second.end(), rNode ));
     581           0 :             if( aElemIt != aIt->second.end())
     582           0 :                 return aIt->second;
     583             :         }
     584             :     }
     585           0 :     return ObjectHierarchy::tChildContainer();
     586             : }
     587             : 
     588           0 : ObjectHierarchy::tOID ImplObjectHierarchy::getParentImpl(
     589             :     const ObjectHierarchy::tOID & rParentOID,
     590             :     const ObjectHierarchy::tOID & rOID )
     591             : {
     592             :     // search children
     593           0 :     ObjectHierarchy::tChildContainer aChildren( getChildren( rParentOID ));
     594             :     ObjectHierarchy::tChildContainer::const_iterator aIt(
     595           0 :         ::std::find( aChildren.begin(), aChildren.end(), rOID ));
     596             :     // recursion end
     597           0 :     if( aIt != aChildren.end())
     598           0 :         return rParentOID;
     599             : 
     600           0 :     for( aIt = aChildren.begin(); aIt != aChildren.end(); ++aIt )
     601             :     {
     602             :         // recursion
     603           0 :         ObjectHierarchy::tOID aTempParent( getParentImpl( *aIt, rOID ));
     604           0 :         if ( aTempParent.isValid() )
     605             :         {
     606             :             // exit on success
     607           0 :             return aTempParent;
     608             :         }
     609           0 :     }
     610             : 
     611             :     // exit on fail
     612           0 :     return ObjectHierarchy::tOID();
     613             : }
     614             : 
     615           0 : ObjectHierarchy::tOID ImplObjectHierarchy::getParent(
     616             :     const ObjectHierarchy::tOID & rOID )
     617             : {
     618           0 :     return getParentImpl( ObjectHierarchy::getRootNodeOID(), rOID );
     619             : }
     620             : 
     621             : } // namespace impl
     622             : 
     623         780 : ObjectHierarchy::ObjectHierarchy(
     624             :     const Reference< XChartDocument > & xChartDocument,
     625             :     ExplicitValueProvider * pExplicitValueProvider /* = 0 */,
     626             :     bool bFlattenDiagram /* = false */,
     627             :     bool bOrderingForElementSelector /* = false */) :
     628         780 :         m_apImpl( new impl::ImplObjectHierarchy( xChartDocument, pExplicitValueProvider, bFlattenDiagram, bOrderingForElementSelector ))
     629         780 : {}
     630             : 
     631         780 : ObjectHierarchy::~ObjectHierarchy()
     632         780 : {}
     633             : 
     634        1560 : ObjectHierarchy::tOID ObjectHierarchy::getRootNodeOID()
     635             : {
     636        1560 :     return ObjectIdentifier( "ROOT" );
     637             : }
     638             : 
     639           0 : bool ObjectHierarchy::isRootNode( const ObjectHierarchy::tOID& rOID )
     640             : {
     641           0 :     return ( rOID == ObjectHierarchy::getRootNodeOID() );
     642             : }
     643             : 
     644           0 : ObjectHierarchy::tChildContainer ObjectHierarchy::getTopLevelChildren() const
     645             : {
     646           0 :     return m_apImpl->getChildren( ObjectHierarchy::getRootNodeOID());
     647             : }
     648             : 
     649           0 : bool ObjectHierarchy::hasChildren( const tOID& rParent ) const
     650             : {
     651           0 :     return m_apImpl->hasChildren( rParent );
     652             : }
     653             : 
     654        8085 : ObjectHierarchy::tChildContainer ObjectHierarchy::getChildren(
     655             :     const ObjectHierarchy::tOID& rParent ) const
     656             : {
     657        8085 :     if ( rParent.isValid() )
     658        8085 :         return m_apImpl->getChildren( rParent );
     659             : 
     660           0 :     return ObjectHierarchy::tChildContainer();
     661             : }
     662             : 
     663           0 : ObjectHierarchy::tChildContainer ObjectHierarchy::getSiblings(
     664             :     const ObjectHierarchy::tOID& rNode ) const
     665             : {
     666           0 :     if ( rNode.isValid() && !isRootNode( rNode ) )
     667           0 :         return m_apImpl->getSiblings( rNode );
     668             : 
     669           0 :     return ObjectHierarchy::tChildContainer();
     670             : }
     671             : 
     672           0 : ObjectHierarchy::tOID ObjectHierarchy::getParent(
     673             :     const ObjectHierarchy::tOID& rNode ) const
     674             : {
     675           0 :     return m_apImpl->getParent( rNode );
     676             : }
     677             : 
     678           0 : sal_Int32 ObjectHierarchy::getIndexInParent(
     679             :     const ObjectHierarchy::tOID& rNode ) const
     680             : {
     681           0 :     tOID aParentOID( m_apImpl->getParent( rNode ));
     682           0 :     tChildContainer aChildren( m_apImpl->getChildren( aParentOID ) );
     683           0 :     tChildContainer::const_iterator aIt( aChildren.begin() );
     684           0 :     for( sal_Int32 nIndex = 0; aIt != aChildren.end(); ++nIndex, ++aIt )
     685             :     {
     686           0 :         if ( *aIt == rNode )
     687           0 :             return nIndex;
     688             :     }
     689           0 :     return -1;
     690             : }
     691             : 
     692           0 : ObjectKeyNavigation::ObjectKeyNavigation(
     693             :     const ObjectHierarchy::tOID & rCurrentOID,
     694             :     const Reference< chart2::XChartDocument > & xChartDocument,
     695             :     ExplicitValueProvider * pExplicitValueProvider /* = 0 */ ) :
     696             :         m_aCurrentOID( rCurrentOID ),
     697             :         m_xChartDocument( xChartDocument ),
     698             :         m_pExplicitValueProvider( pExplicitValueProvider ),
     699           0 :         m_bStepDownInDiagram( true )
     700             : {
     701           0 :     if ( !m_aCurrentOID.isValid() )
     702             :     {
     703           0 :         setCurrentSelection( ObjectHierarchy::getRootNodeOID() );
     704             :     }
     705           0 : }
     706             : 
     707           0 : bool ObjectKeyNavigation::handleKeyEvent(
     708             :     const awt::KeyEvent & rEvent )
     709             : {
     710           0 :     bool bResult = false;
     711             : 
     712           0 :     switch( rEvent.KeyCode )
     713             :     {
     714             :         case awt::Key::TAB:
     715           0 :             if( rEvent.Modifiers & awt::KeyModifier::SHIFT )
     716           0 :                 bResult = previous();
     717             :             else
     718           0 :                 bResult = next();
     719           0 :             break;
     720             :         case awt::Key::HOME:
     721           0 :             bResult = first();
     722           0 :             break;
     723             :         case awt::Key::END:
     724           0 :             bResult = last();
     725           0 :             break;
     726             :         case awt::Key::F3:
     727           0 :             if( rEvent.Modifiers & awt::KeyModifier::SHIFT )
     728           0 :                 bResult = up();
     729             :             else
     730           0 :                 bResult = down();
     731           0 :             break;
     732             :         case awt::Key::ESCAPE:
     733           0 :             setCurrentSelection( ObjectIdentifier() );
     734           0 :             bResult = true;
     735           0 :             break;
     736             :         default:
     737           0 :             bResult = false;
     738           0 :             break;
     739             :     }
     740           0 :     return bResult;
     741             : }
     742             : 
     743           0 : void ObjectKeyNavigation::setCurrentSelection( const ObjectHierarchy::tOID& rOID )
     744             : {
     745           0 :     m_aCurrentOID = rOID;
     746           0 : }
     747             : 
     748           0 : ObjectHierarchy::tOID ObjectKeyNavigation::getCurrentSelection() const
     749             : {
     750           0 :     return m_aCurrentOID;
     751             : }
     752             : 
     753           0 : bool ObjectKeyNavigation::first()
     754             : {
     755           0 :     ObjectHierarchy aHierarchy( m_xChartDocument, m_pExplicitValueProvider, m_bStepDownInDiagram );
     756           0 :     ObjectHierarchy::tChildContainer aSiblings( aHierarchy.getSiblings( getCurrentSelection() ) );
     757           0 :     bool bResult = !aSiblings.empty();
     758           0 :     if( bResult )
     759           0 :         setCurrentSelection( aSiblings.front());
     760             :     else
     761           0 :         bResult = veryFirst();
     762           0 :     return bResult;
     763             : }
     764             : 
     765           0 : bool ObjectKeyNavigation::last()
     766             : {
     767           0 :     ObjectHierarchy aHierarchy( m_xChartDocument, m_pExplicitValueProvider, m_bStepDownInDiagram );
     768           0 :     ObjectHierarchy::tChildContainer aSiblings( aHierarchy.getSiblings( getCurrentSelection() ) );
     769           0 :     bool bResult = !aSiblings.empty();
     770           0 :     if( bResult )
     771           0 :         setCurrentSelection( aSiblings.back());
     772             :     else
     773           0 :         bResult = veryLast();
     774           0 :     return bResult;
     775             : }
     776             : 
     777           0 : bool ObjectKeyNavigation::next()
     778             : {
     779           0 :     ObjectHierarchy aHierarchy( m_xChartDocument, m_pExplicitValueProvider, m_bStepDownInDiagram );
     780           0 :     ObjectHierarchy::tChildContainer aSiblings( aHierarchy.getSiblings( getCurrentSelection() ) );
     781           0 :     bool bResult = !aSiblings.empty();
     782           0 :     if( bResult )
     783             :     {
     784             :         ObjectHierarchy::tChildContainer::const_iterator aIt(
     785           0 :             ::std::find( aSiblings.begin(), aSiblings.end(), getCurrentSelection()));
     786             :         OSL_ASSERT( aIt != aSiblings.end());
     787           0 :         if( ++aIt == aSiblings.end())
     788           0 :             aIt = aSiblings.begin();
     789           0 :         setCurrentSelection( *aIt );
     790             :     }
     791             :     else
     792           0 :         bResult = veryFirst();
     793             : 
     794           0 :     return bResult;
     795             : }
     796             : 
     797           0 : bool ObjectKeyNavigation::previous()
     798             : {
     799           0 :     ObjectHierarchy aHierarchy( m_xChartDocument, m_pExplicitValueProvider, m_bStepDownInDiagram );
     800           0 :     ObjectHierarchy::tChildContainer aSiblings( aHierarchy.getSiblings( getCurrentSelection()));
     801           0 :     bool bResult = !aSiblings.empty();
     802           0 :     if( bResult )
     803             :     {
     804             :         ObjectHierarchy::tChildContainer::const_iterator aIt(
     805           0 :             ::std::find( aSiblings.begin(), aSiblings.end(), getCurrentSelection()));
     806             :         OSL_ASSERT( aIt != aSiblings.end());
     807           0 :         if( aIt == aSiblings.begin())
     808           0 :             aIt = aSiblings.end();
     809           0 :         --aIt;
     810           0 :         setCurrentSelection( *aIt );
     811             :     }
     812             :     else
     813           0 :         bResult = veryLast();
     814           0 :     return bResult;
     815             : }
     816             : 
     817           0 : bool ObjectKeyNavigation::up()
     818             : {
     819           0 :     ObjectHierarchy aHierarchy( m_xChartDocument, m_pExplicitValueProvider, m_bStepDownInDiagram );
     820           0 :     bool bResult = !ObjectHierarchy::isRootNode( getCurrentSelection());
     821           0 :     if( bResult )
     822           0 :         setCurrentSelection( aHierarchy.getParent( getCurrentSelection()));
     823           0 :     return bResult;
     824             : }
     825             : 
     826           0 : bool ObjectKeyNavigation::down()
     827             : {
     828           0 :     ObjectHierarchy aHierarchy( m_xChartDocument, m_pExplicitValueProvider, m_bStepDownInDiagram );
     829           0 :     bool bResult = aHierarchy.hasChildren( getCurrentSelection());
     830           0 :     if( bResult )
     831             :     {
     832           0 :         ObjectHierarchy::tChildContainer aChildren = aHierarchy.getChildren( getCurrentSelection());
     833             :         OSL_ASSERT( !aChildren.empty());
     834           0 :         setCurrentSelection( aChildren.front());
     835             :     }
     836           0 :     return bResult;
     837             : }
     838             : 
     839           0 : bool ObjectKeyNavigation::veryFirst()
     840             : {
     841           0 :     ObjectHierarchy aHierarchy( m_xChartDocument, m_pExplicitValueProvider, m_bStepDownInDiagram );
     842           0 :     ObjectHierarchy::tChildContainer aChildren( aHierarchy.getTopLevelChildren());
     843           0 :     bool bResult = !aChildren.empty();
     844           0 :     if( bResult )
     845           0 :         setCurrentSelection( aChildren.front());
     846           0 :     return bResult;
     847             : }
     848             : 
     849           0 : bool ObjectKeyNavigation::veryLast()
     850             : {
     851           0 :     ObjectHierarchy aHierarchy( m_xChartDocument, m_pExplicitValueProvider, m_bStepDownInDiagram );
     852           0 :     ObjectHierarchy::tChildContainer aChildren( aHierarchy.getTopLevelChildren());
     853           0 :     bool bResult = !aChildren.empty();
     854           0 :     if( bResult )
     855           0 :         setCurrentSelection( aChildren.back());
     856           0 :     return bResult;
     857             : }
     858             : 
     859             : } //  namespace chart
     860             : 
     861             : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.10