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

Generated by: LCOV version 1.11