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

Generated by: LCOV version 1.10