LCOV - code coverage report
Current view: top level - usr/local/src/libreoffice/chart2/source/controller/main - ObjectHierarchy.cxx (source / functions) Hit Total Coverage
Test: libreoffice_filtered.info Lines: 170 390 43.6 %
Date: 2013-07-09 Functions: 16 43 37.2 %
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             : 
      21             : #include "ObjectHierarchy.hxx"
      22             : #include "ObjectIdentifier.hxx"
      23             : #include "ChartModelHelper.hxx"
      24             : #include "DiagramHelper.hxx"
      25             : #include "RegressionCurveHelper.hxx"
      26             : #include "AxisHelper.hxx"
      27             : #include "chartview/ExplicitValueProvider.hxx"
      28             : #include "macros.hxx"
      29             : #include "LineProperties.hxx"
      30             : #include "ChartTypeHelper.hxx"
      31             : #include "DataSeriesHelper.hxx"
      32             : #include "LegendHelper.hxx"
      33             : #include "chartview/DrawModelWrapper.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        1525 : void lcl_addAxisTitle( const Reference< XAxis >& xAxis, ::chart::ObjectHierarchy::tChildContainer& rContainer, const Reference< frame::XModel >& xChartModel )
     103             : {
     104        1525 :     Reference< XTitled > xAxisTitled( xAxis, uno::UNO_QUERY );
     105        1525 :     if( xAxisTitled.is())
     106             :     {
     107        1525 :         Reference< XTitle > xAxisTitle( xAxisTitled->getTitleObject());
     108        1525 :         if( xAxisTitle.is())
     109             :             rContainer.push_back(
     110           0 :                 ::chart::ObjectIdentifier( ::chart::ObjectIdentifier::createClassifiedIdentifierForObject( xAxisTitle, xChartModel ) ) );
     111        1525 :     }
     112        1525 : }
     113             : 
     114             : } // anonymous namespace
     115             : 
     116             : namespace chart
     117             : {
     118             : 
     119             : namespace impl
     120             : {
     121             : 
     122         779 : 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             :     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         779 : 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         779 :         m_bOrderingForElementSelector( bOrderingForElementSelector )
     178             : {
     179         779 :     createTree( xChartDocument );
     180             :     // don't remember this helper to avoid access after lifetime
     181         779 :     m_pExplicitValueProvider = 0;
     182         779 : }
     183             : 
     184         779 : void ImplObjectHierarchy::createTree( const Reference< XChartDocument >& xChartDocument )
     185             : {
     186         779 :     m_aChildMap = tChildMap();//clear tree
     187             : 
     188         779 :     if( !xChartDocument.is() )
     189         779 :         return;
     190             : 
     191             :     //@todo: change ObjectIdentifier to take an XChartDocument rather than XModel
     192         779 :     Reference< frame::XModel > xModel( xChartDocument, uno::UNO_QUERY );
     193        1558 :     Reference< XDiagram > xDiagram( ChartModelHelper::findDiagram( xChartDocument ) );
     194        1558 :     ObjectHierarchy::tOID aDiaOID;
     195         779 :     if( xDiagram.is() )
     196         776 :         aDiaOID = ObjectIdentifier( ObjectIdentifier::createClassifiedIdentifierForObject( xDiagram, xModel ) );
     197        1558 :     ObjectHierarchy::tChildContainer aTopLevelContainer;
     198             : 
     199             :     // First Level
     200             : 
     201             :     // Chart Area
     202         779 :     if( m_bOrderingForElementSelector )
     203             :     {
     204         779 :         aTopLevelContainer.push_back( ObjectIdentifier( ObjectIdentifier::createClassifiedIdentifier( OBJECTTYPE_PAGE, OUString() ) ) );
     205         779 :         if( xDiagram.is() )
     206             :         {
     207         776 :             aTopLevelContainer.push_back( aDiaOID );
     208         776 :             createWallAndFloor( aTopLevelContainer, xDiagram );
     209         776 :             createLegendTree( aTopLevelContainer, xChartDocument, xDiagram  );
     210             :         }
     211             :     }
     212             : 
     213             :     // Main Title
     214        1558 :     Reference< XTitled > xDocTitled( xChartDocument, uno::UNO_QUERY );
     215         779 :     if( xDocTitled.is())
     216             :     {
     217         779 :         Reference< XTitle > xMainTitle( xDocTitled->getTitleObject());
     218         779 :         if( xMainTitle.is())
     219             :             aTopLevelContainer.push_back(
     220         465 :                 ObjectIdentifier( ObjectIdentifier::createClassifiedIdentifierForObject( xMainTitle, xModel ) ) );
     221             :     }
     222             : 
     223         779 :     if( xDiagram.is())
     224             :     {
     225             :         // Sub Title.  Note: This is interpreted of being top level
     226         776 :         Reference< XTitled > xDiaTitled( xDiagram, uno::UNO_QUERY );
     227         776 :         if( xDiaTitled.is())
     228             :         {
     229         776 :             Reference< XTitle > xSubTitle( xDiaTitled->getTitleObject());
     230         776 :             if( xSubTitle.is())
     231             :                 aTopLevelContainer.push_back(
     232         292 :                     ObjectIdentifier( ObjectIdentifier::createClassifiedIdentifierForObject( xSubTitle, xModel ) ) );
     233             :         }
     234             : 
     235         776 :         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         776 :         if( m_bFlattenDiagram )
     247         776 :             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         776 :         if( !m_bOrderingForElementSelector )
     257           0 :             createLegendTree( aTopLevelContainer, xChartDocument, xDiagram  );
     258             :     }
     259             : 
     260             :     // #i12587# support for shapes in chart
     261         779 :     if ( !m_bOrderingForElementSelector )
     262             :     {
     263           0 :         createAdditionalShapesTree( aTopLevelContainer );
     264             :     }
     265             : 
     266             :     // Chart Area
     267         779 :     if( !m_bOrderingForElementSelector )
     268             :         aTopLevelContainer.push_back(
     269           0 :             ObjectIdentifier( ObjectIdentifier::createClassifiedIdentifier( OBJECTTYPE_PAGE, OUString() ) ) );
     270             : 
     271         779 :     if( ! aTopLevelContainer.empty())
     272        1558 :         m_aChildMap[ ObjectHierarchy::getRootNodeOID() ] = aTopLevelContainer;
     273             : }
     274             : 
     275         776 : void ImplObjectHierarchy::createLegendTree(
     276             :     ObjectHierarchy::tChildContainer & rContainer,
     277             :     const Reference< XChartDocument > & xChartDoc,
     278             :     const Reference< XDiagram > & xDiagram  )
     279             : {
     280         776 :     if( xDiagram.is() && LegendHelper::hasLegend( xDiagram ) )
     281             :     {
     282         748 :         ObjectHierarchy::tOID aLegendOID( ObjectIdentifier( ObjectIdentifier::createClassifiedIdentifierForObject( xDiagram->getLegend(), Reference< frame::XModel >( xChartDoc, uno::UNO_QUERY ) ) ) );
     283         748 :         rContainer.push_back( aLegendOID );
     284             : 
     285             :         // iterate over child shapes of legend and search for matching CIDs
     286         748 :         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         748 :         }
     295             :     }
     296         776 : }
     297             : 
     298         776 : void ImplObjectHierarchy::createAxesTree(
     299             :     ObjectHierarchy::tChildContainer & rContainer,
     300             :     const Reference< XChartDocument > & xChartDoc,
     301             :     const Reference< XDiagram > & xDiagram  )
     302             : {
     303         776 :     Reference< XCoordinateSystemContainer > xCooSysCnt( xDiagram, uno::UNO_QUERY_THROW );
     304         776 :     sal_Int32 nDimensionCount = DiagramHelper::getDimension( xDiagram );
     305        1552 :     uno::Reference< chart2::XChartType > xChartType( DiagramHelper::getChartTypeByIndex( xDiagram, 0 ) );
     306         776 :     bool bSupportsAxesGrids = ChartTypeHelper::isSupportingMainAxis( xChartType, nDimensionCount, 0 );
     307         776 :     if( bSupportsAxesGrids )
     308             :     {
     309         762 :         Sequence< Reference< XAxis > > aAxes( AxisHelper::getAllAxesOfDiagram( xDiagram, /* bOnlyVisible = */ true ) );
     310         762 :         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         762 :         aAxes = AxisHelper::getAllAxesOfDiagram( xDiagram, /* bOnlyVisible = */ false );
     317             :         // Grids
     318        1524 :         Reference< frame::XModel > xChartModel( xChartDoc, uno::UNO_QUERY );
     319        2287 :         for( sal_Int32 nA=0; nA<aAxes.getLength(); ++nA )
     320             :         {
     321        1525 :             Reference< XAxis > xAxis( aAxes[nA] );
     322        1525 :             if(!xAxis.is())
     323           0 :                 continue;
     324             : 
     325        1525 :             sal_Int32 nCooSysIndex = 0;
     326        1525 :             sal_Int32 nDimensionIndex = 0;
     327        1525 :             sal_Int32 nAxisIndex = 0;
     328        1525 :             AxisHelper::getIndicesForAxis( xAxis, xDiagram, nCooSysIndex, nDimensionIndex, nAxisIndex );
     329        1525 :             if( nAxisIndex>0 && !ChartTypeHelper::isSupportingSecondaryAxis( xChartType, nDimensionCount, nDimensionIndex ) )
     330           0 :                 continue;
     331             : 
     332        1525 :             if( m_bOrderingForElementSelector )
     333             :             {
     334             :                 // axis
     335        1525 :                 if( AxisHelper::isAxisVisible( xAxis ) )
     336             :                     rContainer.push_back(
     337        1320 :                         ObjectIdentifier( ObjectIdentifier::createClassifiedIdentifierForObject( xAxis, xChartModel ) ) );
     338             : 
     339             :                 // axis title
     340        1525 :                 lcl_addAxisTitle( aAxes[nA], rContainer, xChartModel );
     341             :             }
     342             : 
     343        3050 :             Reference< beans::XPropertySet > xGridProperties( xAxis->getGridProperties() );
     344        1525 :             if( AxisHelper::isGridVisible( xGridProperties ) )
     345             :             {
     346             :                 //main grid
     347             :                 rContainer.push_back(
     348         617 :                     ObjectIdentifier( ObjectIdentifier( ObjectIdentifier::createClassifiedIdentifierForGrid( xAxis, xChartModel ) ) ) );
     349             :             }
     350             : 
     351        3050 :             Sequence< Reference< beans::XPropertySet > > aSubGrids( xAxis->getSubGridProperties() );;
     352        1525 :             sal_Int32 nSubGrid = 0;
     353        3050 :             for( nSubGrid = 0; nSubGrid < aSubGrids.getLength(); ++nSubGrid )
     354             :             {
     355        1525 :                 Reference< beans::XPropertySet > xSubGridProperties( aSubGrids[nSubGrid] );
     356        1525 :                 if( AxisHelper::isGridVisible( xSubGridProperties ) )
     357             :                 {
     358             :                     //sub grid
     359             :                     rContainer.push_back(
     360           0 :                         ObjectIdentifier( ObjectIdentifier( ObjectIdentifier::createClassifiedIdentifierForGrid( xAxis, xChartModel, nSubGrid ) ) ) );
     361             :                 }
     362        1525 :             }
     363        2287 :         }
     364         776 :     }
     365         776 : }
     366             : 
     367         776 : void ImplObjectHierarchy::createWallAndFloor(
     368             :     ObjectHierarchy::tChildContainer & rContainer,
     369             :     const Reference< XDiagram > & xDiagram )
     370             : {
     371         776 :     sal_Int32 nDimensionCount = DiagramHelper::getDimension( xDiagram );
     372         776 :     bool bIsThreeD = ( nDimensionCount == 3 );
     373         776 :     bool bHasWall = DiagramHelper::isSupportingFloorAndWall( xDiagram );
     374         776 :     if( bHasWall && bIsThreeD )
     375             :     {
     376             :         rContainer.push_back(
     377           5 :             ObjectIdentifier( ObjectIdentifier::createClassifiedIdentifier( OBJECTTYPE_DIAGRAM_WALL, OUString() ) ) );
     378             : 
     379           5 :         Reference< beans::XPropertySet > xFloor( xDiagram->getFloor());
     380           5 :         if( xFloor.is())
     381             :             rContainer.push_back(
     382           5 :                 ObjectIdentifier( ObjectIdentifier::createClassifiedIdentifier( OBJECTTYPE_DIAGRAM_FLOOR, OUString() ) ) );
     383             :     }
     384             : 
     385         776 : }
     386             : 
     387         776 : void ImplObjectHierarchy::createDiagramTree(
     388             :     ObjectHierarchy::tChildContainer & rContainer,
     389             :     const Reference< XChartDocument > & xChartDoc,
     390             :     const Reference< XDiagram > & xDiagram )
     391             : {
     392         776 :     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         776 :         createAxesTree( rContainer, xChartDoc, xDiagram  );
     401         776 :         createDataSeriesTree( rContainer, xDiagram );
     402             :     }
     403         776 : }
     404             : 
     405         776 : void ImplObjectHierarchy::createDataSeriesTree(
     406             :     ObjectHierarchy::tChildContainer & rOutDiagramSubContainer,
     407             :     const Reference< XDiagram > & xDiagram )
     408             : {
     409         776 :     Reference< XCoordinateSystemContainer > xCooSysCnt( xDiagram, uno::UNO_QUERY_THROW );
     410             : 
     411             :     try
     412             :     {
     413         776 :         sal_Int32 nDiagramIndex = 0;
     414         776 :         sal_Int32 nDimensionCount = DiagramHelper::getDimension( xDiagram );
     415             :         Sequence< Reference< XCoordinateSystem > > aCooSysSeq(
     416         776 :             xCooSysCnt->getCoordinateSystems());
     417        1550 :         for( sal_Int32 nCooSysIdx=0; nCooSysIdx<aCooSysSeq.getLength(); ++nCooSysIdx )
     418             :         {
     419         774 :             Reference< XChartTypeContainer > xCTCnt( aCooSysSeq[nCooSysIdx], uno::UNO_QUERY_THROW );
     420        1548 :             Sequence< Reference< XChartType > > aChartTypeSeq( xCTCnt->getChartTypes());
     421        1548 :             for( sal_Int32 nCTIdx=0; nCTIdx<aChartTypeSeq.getLength(); ++nCTIdx )
     422             :             {
     423         774 :                 Reference< XChartType > xChartType( aChartTypeSeq[nCTIdx] );
     424        1548 :                 Reference< XDataSeriesContainer > xDSCnt( xChartType, uno::UNO_QUERY_THROW );
     425        1548 :                 Sequence< Reference< XDataSeries > > aSeriesSeq( xDSCnt->getDataSeries() );
     426             :                 const sal_Int32 nNumberOfSeries =
     427         774 :                     ChartTypeHelper::getNumberOfDisplayedSeries( xChartType, aSeriesSeq.getLength());
     428             : 
     429        3068 :                 for( sal_Int32 nSeriesIdx=0; nSeriesIdx<nNumberOfSeries; ++nSeriesIdx )
     430             :                 {
     431             :                     OUString aSeriesParticle(
     432             :                         ObjectIdentifier::createParticleForSeries(
     433        2294 :                             nDiagramIndex, nCooSysIdx, nCTIdx, nSeriesIdx ));
     434             :                     ObjectHierarchy::tOID aSeriesOID(
     435        4588 :                         ObjectIdentifier( ObjectIdentifier::createClassifiedIdentifierForParticle( aSeriesParticle ) ) );
     436        2294 :                     rOutDiagramSubContainer.push_back( aSeriesOID );
     437             : 
     438        4588 :                     ObjectHierarchy::tChildContainer aSeriesSubContainer;
     439             : 
     440        4588 :                     Reference< chart2::XDataSeries > xSeries( aSeriesSeq[nSeriesIdx], uno::UNO_QUERY );
     441             : 
     442             :                     // data lablels
     443        2294 :                     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        2294 :                     if( ChartTypeHelper::isSupportingStatisticProperties( xChartType, nDimensionCount ) )
     453             :                     {
     454        2265 :                         Reference< chart2::XRegressionCurveContainer > xCurveCnt( xSeries, uno::UNO_QUERY );
     455        2265 :                         if( xCurveCnt.is())
     456             :                         {
     457        2265 :                             Sequence< Reference< chart2::XRegressionCurve > > aCurves( xCurveCnt->getRegressionCurves());
     458        2271 :                             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        4530 :                             Reference< beans::XPropertySet > xSeriesProp( xSeries, uno::UNO_QUERY );
     470        4530 :                             Reference< beans::XPropertySet > xErrorBarProp;
     471       11325 :                             if( xSeriesProp.is() &&
     472       13590 :                                 (xSeriesProp->getPropertyValue( "ErrorBarY") >>= xErrorBarProp) &&
     473        2265 :                                 xErrorBarProp.is())
     474             :                             {
     475         834 :                                 sal_Int32 nStyle = ::com::sun::star::chart::ErrorBarStyle::NONE;
     476        1668 :                                 if( ( xErrorBarProp->getPropertyValue( "ErrorBarStyle") >>= nStyle ) &&
     477         834 :                                     ( 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       11325 :                             if( xSeriesProp.is() &&
     486       13590 :                                 (xSeriesProp->getPropertyValue( "ErrorBarX") >>= xErrorBarProp) &&
     487        2265 :                                 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        2265 :                             }
     498        2265 :                         }
     499             :                     }
     500             : 
     501             :                     // Data Points
     502             :                     // iterate over child shapes of legend and search for matching CIDs
     503        2294 :                     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        2294 :                     if( ! aSeriesSubContainer.empty())
     511           6 :                         m_aChildMap[ aSeriesOID ] = aSeriesSubContainer;
     512        2294 :                 }
     513         774 :             }
     514        1550 :         }
     515             :     }
     516           0 :     catch( const uno::Exception & ex )
     517             :     {
     518             :         ASSERT_EXCEPTION( ex );
     519         776 :     }
     520         776 : }
     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        8086 : ObjectHierarchy::tChildContainer ImplObjectHierarchy::getChildren( const ObjectHierarchy::tOID& rParent )
     563             : {
     564        8086 :     if ( rParent.isValid() )
     565             :     {
     566        8086 :         tChildMap::const_iterator aIt( m_aChildMap.find( rParent ));
     567        8086 :         if( aIt != m_aChildMap.end())
     568         785 :             return aIt->second;
     569             :     }
     570        7301 :     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             : 
     625         779 : ObjectHierarchy::ObjectHierarchy(
     626             :     const Reference< XChartDocument > & xChartDocument,
     627             :     ExplicitValueProvider * pExplicitValueProvider /* = 0 */,
     628             :     bool bFlattenDiagram /* = false */,
     629             :     bool bOrderingForElementSelector /* = false */) :
     630         779 :         m_apImpl( new impl::ImplObjectHierarchy( xChartDocument, pExplicitValueProvider, bFlattenDiagram, bOrderingForElementSelector ))
     631         779 : {}
     632             : 
     633         779 : ObjectHierarchy::~ObjectHierarchy()
     634         779 : {}
     635             : 
     636        1558 : ObjectHierarchy::tOID ObjectHierarchy::getRootNodeOID()
     637             : {
     638        1558 :     return ObjectIdentifier( "ROOT" );
     639             : }
     640             : 
     641           0 : bool ObjectHierarchy::isRootNode( const ObjectHierarchy::tOID& rOID )
     642             : {
     643           0 :     return ( rOID == ObjectHierarchy::getRootNodeOID() );
     644             : }
     645             : 
     646           0 : ObjectHierarchy::tChildContainer ObjectHierarchy::getTopLevelChildren() const
     647             : {
     648           0 :     return m_apImpl->getChildren( ObjectHierarchy::getRootNodeOID());
     649             : }
     650             : 
     651           0 : bool ObjectHierarchy::hasChildren( const tOID& rParent ) const
     652             : {
     653           0 :     return m_apImpl->hasChildren( rParent );
     654             : }
     655             : 
     656        8086 : ObjectHierarchy::tChildContainer ObjectHierarchy::getChildren(
     657             :     const ObjectHierarchy::tOID& rParent ) const
     658             : {
     659        8086 :     if ( rParent.isValid() )
     660        8086 :         return m_apImpl->getChildren( rParent );
     661             : 
     662           0 :     return ObjectHierarchy::tChildContainer();
     663             : }
     664             : 
     665           0 : ObjectHierarchy::tChildContainer ObjectHierarchy::getSiblings(
     666             :     const ObjectHierarchy::tOID& rNode ) const
     667             : {
     668           0 :     if ( rNode.isValid() && !isRootNode( rNode ) )
     669           0 :         return m_apImpl->getSiblings( rNode );
     670             : 
     671           0 :     return ObjectHierarchy::tChildContainer();
     672             : }
     673             : 
     674           0 : ObjectHierarchy::tOID ObjectHierarchy::getParent(
     675             :     const ObjectHierarchy::tOID& rNode ) const
     676             : {
     677           0 :     return m_apImpl->getParent( rNode );
     678             : }
     679             : 
     680           0 : sal_Int32 ObjectHierarchy::getIndexInParent(
     681             :     const ObjectHierarchy::tOID& rNode ) const
     682             : {
     683           0 :     tOID aParentOID( m_apImpl->getParent( rNode ));
     684           0 :     tChildContainer aChildren( m_apImpl->getChildren( aParentOID ) );
     685           0 :     tChildContainer::const_iterator aIt( aChildren.begin() );
     686           0 :     for( sal_Int32 nIndex = 0; aIt != aChildren.end(); ++nIndex, ++aIt )
     687             :     {
     688           0 :         if ( *aIt == rNode )
     689           0 :             return nIndex;
     690             :     }
     691           0 :     return -1;
     692             : }
     693             : 
     694             : // ================================================================================
     695             : 
     696           0 : ObjectKeyNavigation::ObjectKeyNavigation(
     697             :     const ObjectHierarchy::tOID & rCurrentOID,
     698             :     const Reference< chart2::XChartDocument > & xChartDocument,
     699             :     ExplicitValueProvider * pExplicitValueProvider /* = 0 */ ) :
     700             :         m_aCurrentOID( rCurrentOID ),
     701             :         m_xChartDocument( xChartDocument ),
     702             :         m_pExplicitValueProvider( pExplicitValueProvider ),
     703           0 :         m_bStepDownInDiagram( true )
     704             : {
     705           0 :     if ( !m_aCurrentOID.isValid() )
     706             :     {
     707           0 :         setCurrentSelection( ObjectHierarchy::getRootNodeOID() );
     708             :     }
     709           0 : }
     710             : 
     711           0 : bool ObjectKeyNavigation::handleKeyEvent(
     712             :     const awt::KeyEvent & rEvent )
     713             : {
     714           0 :     bool bResult = false;
     715             : 
     716           0 :     switch( rEvent.KeyCode )
     717             :     {
     718             :         case awt::Key::TAB:
     719           0 :             if( rEvent.Modifiers & awt::KeyModifier::SHIFT )
     720           0 :                 bResult = previous();
     721             :             else
     722           0 :                 bResult = next();
     723           0 :             break;
     724             :         case awt::Key::HOME:
     725           0 :             bResult = first();
     726           0 :             break;
     727             :         case awt::Key::END:
     728           0 :             bResult = last();
     729           0 :             break;
     730             :         case awt::Key::F3:
     731           0 :             if( rEvent.Modifiers & awt::KeyModifier::SHIFT )
     732           0 :                 bResult = up();
     733             :             else
     734           0 :                 bResult = down();
     735           0 :             break;
     736             :         case awt::Key::ESCAPE:
     737           0 :             setCurrentSelection( ObjectIdentifier() );
     738           0 :             bResult = true;
     739           0 :             break;
     740             :         default:
     741           0 :             bResult = false;
     742           0 :             break;
     743             :     }
     744           0 :     return bResult;
     745             : }
     746             : 
     747           0 : void ObjectKeyNavigation::setCurrentSelection( const ObjectHierarchy::tOID& rOID )
     748             : {
     749           0 :     m_aCurrentOID = rOID;
     750           0 : }
     751             : 
     752           0 : ObjectHierarchy::tOID ObjectKeyNavigation::getCurrentSelection() const
     753             : {
     754           0 :     return m_aCurrentOID;
     755             : }
     756             : 
     757           0 : bool ObjectKeyNavigation::first()
     758             : {
     759           0 :     ObjectHierarchy aHierarchy( m_xChartDocument, m_pExplicitValueProvider, m_bStepDownInDiagram );
     760           0 :     ObjectHierarchy::tChildContainer aSiblings( aHierarchy.getSiblings( getCurrentSelection() ) );
     761           0 :     bool bResult = !aSiblings.empty();
     762           0 :     if( bResult )
     763           0 :         setCurrentSelection( aSiblings.front());
     764             :     else
     765           0 :         bResult = veryFirst();
     766           0 :     return bResult;
     767             : }
     768             : 
     769           0 : bool ObjectKeyNavigation::last()
     770             : {
     771           0 :     ObjectHierarchy aHierarchy( m_xChartDocument, m_pExplicitValueProvider, m_bStepDownInDiagram );
     772           0 :     ObjectHierarchy::tChildContainer aSiblings( aHierarchy.getSiblings( getCurrentSelection() ) );
     773           0 :     bool bResult = !aSiblings.empty();
     774           0 :     if( bResult )
     775           0 :         setCurrentSelection( aSiblings.back());
     776             :     else
     777           0 :         bResult = veryLast();
     778           0 :     return bResult;
     779             : }
     780             : 
     781           0 : bool ObjectKeyNavigation::next()
     782             : {
     783           0 :     ObjectHierarchy aHierarchy( m_xChartDocument, m_pExplicitValueProvider, m_bStepDownInDiagram );
     784           0 :     ObjectHierarchy::tChildContainer aSiblings( aHierarchy.getSiblings( getCurrentSelection() ) );
     785           0 :     bool bResult = !aSiblings.empty();
     786           0 :     if( bResult )
     787             :     {
     788             :         ObjectHierarchy::tChildContainer::const_iterator aIt(
     789           0 :             ::std::find( aSiblings.begin(), aSiblings.end(), getCurrentSelection()));
     790             :         OSL_ASSERT( aIt != aSiblings.end());
     791           0 :         if( ++aIt == aSiblings.end())
     792           0 :             aIt = aSiblings.begin();
     793           0 :         setCurrentSelection( *aIt );
     794             :     }
     795             :     else
     796           0 :         bResult = veryFirst();
     797             : 
     798           0 :     return bResult;
     799             : }
     800             : 
     801           0 : bool ObjectKeyNavigation::previous()
     802             : {
     803           0 :     ObjectHierarchy aHierarchy( m_xChartDocument, m_pExplicitValueProvider, m_bStepDownInDiagram );
     804           0 :     ObjectHierarchy::tChildContainer aSiblings( aHierarchy.getSiblings( getCurrentSelection()));
     805           0 :     bool bResult = !aSiblings.empty();
     806           0 :     if( bResult )
     807             :     {
     808             :         ObjectHierarchy::tChildContainer::const_iterator aIt(
     809           0 :             ::std::find( aSiblings.begin(), aSiblings.end(), getCurrentSelection()));
     810             :         OSL_ASSERT( aIt != aSiblings.end());
     811           0 :         if( aIt == aSiblings.begin())
     812           0 :             aIt = aSiblings.end();
     813           0 :         --aIt;
     814           0 :         setCurrentSelection( *aIt );
     815             :     }
     816             :     else
     817           0 :         bResult = veryLast();
     818           0 :     return bResult;
     819             : }
     820             : 
     821           0 : bool ObjectKeyNavigation::up()
     822             : {
     823           0 :     ObjectHierarchy aHierarchy( m_xChartDocument, m_pExplicitValueProvider, m_bStepDownInDiagram );
     824           0 :     bool bResult = !ObjectHierarchy::isRootNode( getCurrentSelection());
     825           0 :     if( bResult )
     826           0 :         setCurrentSelection( aHierarchy.getParent( getCurrentSelection()));
     827           0 :     return bResult;
     828             : }
     829             : 
     830           0 : bool ObjectKeyNavigation::down()
     831             : {
     832           0 :     ObjectHierarchy aHierarchy( m_xChartDocument, m_pExplicitValueProvider, m_bStepDownInDiagram );
     833           0 :     bool bResult = aHierarchy.hasChildren( getCurrentSelection());
     834           0 :     if( bResult )
     835             :     {
     836           0 :         ObjectHierarchy::tChildContainer aChildren = aHierarchy.getChildren( getCurrentSelection());
     837             :         OSL_ASSERT( !aChildren.empty());
     838           0 :         setCurrentSelection( aChildren.front());
     839             :     }
     840           0 :     return bResult;
     841             : }
     842             : 
     843           0 : bool ObjectKeyNavigation::veryFirst()
     844             : {
     845           0 :     ObjectHierarchy aHierarchy( m_xChartDocument, m_pExplicitValueProvider, m_bStepDownInDiagram );
     846           0 :     ObjectHierarchy::tChildContainer aChildren( aHierarchy.getTopLevelChildren());
     847           0 :     bool bResult = !aChildren.empty();
     848           0 :     if( bResult )
     849           0 :         setCurrentSelection( aChildren.front());
     850           0 :     return bResult;
     851             : }
     852             : 
     853           0 : bool ObjectKeyNavigation::veryLast()
     854             : {
     855           0 :     ObjectHierarchy aHierarchy( m_xChartDocument, m_pExplicitValueProvider, m_bStepDownInDiagram );
     856           0 :     ObjectHierarchy::tChildContainer aChildren( aHierarchy.getTopLevelChildren());
     857           0 :     bool bResult = !aChildren.empty();
     858           0 :     if( bResult )
     859           0 :         setCurrentSelection( aChildren.back());
     860           0 :     return bResult;
     861             : }
     862             : 
     863          33 : } //  namespace chart
     864             : 
     865             : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.10