<commit_before>/*************************************************************************
 *
 *  OpenOffice.org - a multi-platform office productivity suite
 *
 *  $RCSfile: ObjectHierarchy.cxx,v $
 *
 *  $Revision: 1.3 $
 *
 *  last change: $Author: ihi $ $Date: 2007-08-17 12:13:35 $
 *
 *  The Contents of this file are made available subject to
 *  the terms of GNU Lesser General Public License Version 2.1.
 *
 *
 *    GNU Lesser General Public License Version 2.1
 *    =============================================
 *    Copyright 2005 by Sun Microsystems, Inc.
 *    901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *    This library is free software; you can redistribute it and/or
 *    modify it under the terms of the GNU Lesser General Public
 *    License version 2.1, as published by the Free Software Foundation.
 *
 *    This library is distributed in the hope that it will be useful,
 *    but WITHOUT ANY WARRANTY; without even the implied warranty of
 *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 *    Lesser General Public License for more details.
 *
 *    You should have received a copy of the GNU Lesser General Public
 *    License along with this library; if not, write to the Free Software
 *    Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 *    MA  02111-1307  USA
 *
 ************************************************************************/

// MARKER(update_precomp.py): autogen include statement, do not remove
#include "precompiled_chart2.hxx"

#include "ObjectHierarchy.hxx"
#include "ObjectIdentifier.hxx"
#include "ChartModelHelper.hxx"
#include "DiagramHelper.hxx"
#include "RegressionCurveHelper.hxx"
#include "AxisHelper.hxx"
#include "chartview/ExplicitValueProvider.hxx"
#include "macros.hxx"
#include "LineProperties.hxx"

#include <map>
#include <algorithm>

#include <com/sun/star/chart2/XTitled.hpp>
#include <com/sun/star/chart2/XCoordinateSystemContainer.hpp>
#include <com/sun/star/chart2/XChartTypeContainer.hpp>
#include <com/sun/star/chart2/XDataSeriesContainer.hpp>

#include <com/sun/star/container/XIndexAccess.hpp>
#include <com/sun/star/awt/Key.hpp>
#include <com/sun/star/awt/KeyModifier.hpp>

using namespace ::com::sun::star;
using namespace ::com::sun::star::chart2;

using ::com::sun::star::uno::Reference;
using ::com::sun::star::uno::Sequence;
using ::rtl::OUString;

namespace
{
struct lcl_ObjectToCID : public ::std::unary_function< Reference< uno::XInterface >, OUString >
{
    explicit lcl_ObjectToCID( const Reference< chart2::XChartDocument > & xChartDoc ) :
            m_xModel( xChartDoc, uno::UNO_QUERY )
    {}

    OUString operator() ( const Reference< uno::XInterface > & xObj )
    {
        return ::chart::ObjectIdentifier::createClassifiedIdentifierForObject( xObj, m_xModel );
    }

private:
    Reference< frame::XModel > m_xModel;
};

void lcl_getChildCIDs(
    ::chart::ObjectHierarchy::tChildContainer & rOutChildren,
    const Reference< container::XIndexAccess > & xShapes )
{
    if( xShapes.is())
    {
        sal_Int32 nCount = xShapes->getCount();
        for( sal_Int32 i=0; i<nCount; ++i)
        {
            Reference< beans::XPropertySet > xShapeProp( xShapes->getByIndex( i ), uno::UNO_QUERY );
            if( xShapeProp.is())
            {
                Reference< beans::XPropertySetInfo > xInfo( xShapeProp->getPropertySetInfo());
                OUString aName;
                if( xInfo.is() &&
                    xInfo->hasPropertyByName( C2U("Name")) &&
                    (xShapeProp->getPropertyValue( C2U("Name")) >>= aName ) &&
                    aName.getLength() > 0 &&
                    ::chart::ObjectIdentifier::isCID( aName ))
                {
                    rOutChildren.push_back( aName );
                }
                Reference< container::XIndexAccess > xNewShapes( xShapeProp, uno::UNO_QUERY );
                if( xNewShapes.is())
                    lcl_getChildCIDs( rOutChildren, xNewShapes );
            }
        }
    }
}

} // anonymous namespace


namespace chart
{

namespace impl
{
class ImplObjectHierarchy
{
public:
    explicit ImplObjectHierarchy(
        const Reference< XChartDocument > & xChartDocument,
        ExplicitValueProvider * pExplicitValueProvider,
        bool bFlattenDiagram );

    bool                              hasChildren( const OUString & rParent );
    ObjectHierarchy::tChildContainer  getChildren( const OUString & rParent );
    ObjectHierarchy::tChildContainer  getSiblings( const OUString & rNode );

    ObjectHierarchy::tCID             getParent( const ObjectHierarchy::tCID & rCID );

private:
    void createTree( const Reference< XChartDocument > & xChartDocument );
    void createDiagramTree(
        ObjectHierarchy::tChildContainer & rContainer,
        const Reference< XChartDocument > & xChartDoc,
        const Reference< XDiagram > & xDiagram );
    void createDataSeriesTree(
        ObjectHierarchy::tChildContainer & rOutDiagramSubContainer,
        const Reference< XCoordinateSystemContainer > & xCooSysCnt );
    ObjectHierarchy::tCID getParentImpl(
        const ObjectHierarchy::tCID & rParentCID,
        const ObjectHierarchy::tCID & rCID );

    typedef ::std::map< OUString, ObjectHierarchy::tChildContainer >
        tChildMap;
    tChildMap m_aChildMap;
    ExplicitValueProvider * m_pExplicitValueProvider;
    bool m_bFlattenDiagram;
};

ImplObjectHierarchy::ImplObjectHierarchy(
    const Reference< XChartDocument > & xChartDocument,
    ExplicitValueProvider * pExplicitValueProvider,
    bool bFlattenDiagram ) :
        m_pExplicitValueProvider( pExplicitValueProvider ),
        m_bFlattenDiagram( bFlattenDiagram )
{
    createTree( xChartDocument );
    // don't remember this helper to avoid access after lifetime
    m_pExplicitValueProvider = 0;
}

void ImplObjectHierarchy::createTree( const Reference< XChartDocument > & xChartDocument )
{
    if( !xChartDocument.is())
        return;

    //@todo: change ObjectIdentifier to take an XChartDocument rather than XModel
    Reference< frame::XModel > xModel( xChartDocument, uno::UNO_QUERY );
    ObjectHierarchy::tChildContainer aTopLevelContainer;

    // First Level

    // Main Title
    Reference< XTitled > xDocTitled( xChartDocument, uno::UNO_QUERY );
    if( xDocTitled.is())
    {
        Reference< XTitle > xMainTitle( xDocTitled->getTitleObject());
        if( xMainTitle.is())
            aTopLevelContainer.push_back(
                ObjectIdentifier::createClassifiedIdentifierForObject( xMainTitle, xModel ));
    }

    Reference< XDiagram > xDiagram( ChartModelHelper::findDiagram( xChartDocument ));
    if( xDiagram.is())
    {
        // Sub Title.  Note: This is interpreted of being top level
        Reference< XTitled > xDiaTitled( xDiagram, uno::UNO_QUERY );
        if( xDiaTitled.is())
        {
            Reference< XTitle > xSubTitle( xDiaTitled->getTitleObject());
            if( xSubTitle.is())
                aTopLevelContainer.push_back(
                    ObjectIdentifier::createClassifiedIdentifierForObject( xSubTitle, xModel ));
        }

        // Axis Titles. Note: These are interpreted of being top level
        Sequence< Reference< XAxis > > aAxes( AxisHelper::getAllAxisOfDiagram( xDiagram ) );
        for( sal_Int32 i=0; i<aAxes.getLength(); ++i )
        {
            Reference< XTitled > xAxisTitled( aAxes[i], uno::UNO_QUERY );
            if( xAxisTitled.is())
            {
                Reference< XTitle > xAxisTitle( xAxisTitled->getTitleObject());
                if( xAxisTitle.is())
                    aTopLevelContainer.push_back(
                        ObjectIdentifier::createClassifiedIdentifierForObject( xAxisTitle, xModel ));
            }
        }

        // Diagram
        OUString aDiaCID( ObjectIdentifier::createClassifiedIdentifierForObject( xDiagram, xModel ));
        OSL_ASSERT( aDiaCID.getLength());
        aTopLevelContainer.push_back( aDiaCID );
        if( m_bFlattenDiagram )
            createDiagramTree( aTopLevelContainer, xChartDocument, xDiagram );
        else
        {
            ObjectHierarchy::tChildContainer aSubContainer;
            createDiagramTree( aSubContainer, xChartDocument, xDiagram );
            if( ! aSubContainer.empty())
                m_aChildMap[ aDiaCID ] = aSubContainer;
        }


        // Legend. Note: This is interpreted of being top level
        Reference< XLegend > xLegend( xDiagram->getLegend());
        if( xLegend.is())
        {
            Reference< beans::XPropertySet > xLegendProp( xLegend, uno::UNO_QUERY );
            bool bShow = false;
            if( xLegendProp.is() &&
                (xLegendProp->getPropertyValue( C2U("Show")) >>= bShow) &&
                bShow )
            {
                OUString aLegendCID( ObjectIdentifier::createClassifiedIdentifierForObject( xLegend, xModel ));
                aTopLevelContainer.push_back( aLegendCID );

                // iterate over child shapes of legend and search for matching CIDs
                if( m_pExplicitValueProvider )
                {
                    Reference< container::XIndexAccess > xLegendShapeContainer(
                        m_pExplicitValueProvider->getShapeForCID( aLegendCID ), uno::UNO_QUERY );
                    ObjectHierarchy::tChildContainer aLegendEntryCIDs;
                    lcl_getChildCIDs( aLegendEntryCIDs, xLegendShapeContainer );

                    m_aChildMap[ aLegendCID ] = aLegendEntryCIDs;
                }
            }
        }
    }

    // Chart Area
    aTopLevelContainer.push_back(
        ObjectIdentifier::createClassifiedIdentifier( OBJECTTYPE_PAGE, OUString() ) );

    if( ! aTopLevelContainer.empty())
        m_aChildMap[ ObjectHierarchy::getRootNodeCID() ] = aTopLevelContainer;
}

void ImplObjectHierarchy::createDiagramTree(
    ObjectHierarchy::tChildContainer & rContainer,
    const Reference< XChartDocument > & xChartDoc,
    const Reference< XDiagram > & xDiagram )
{
    // Data Series
    Reference< XCoordinateSystemContainer > xCooSysCnt( xDiagram, uno::UNO_QUERY_THROW );
    createDataSeriesTree( rContainer, xCooSysCnt );

    // Axes
    Sequence< Reference< XAxis > > aAxes( AxisHelper::getAllAxisOfDiagram( xDiagram ) );
    ::std::transform( aAxes.getConstArray(), aAxes.getConstArray() + aAxes.getLength(),
                        ::std::back_inserter( rContainer ),
                        lcl_ObjectToCID( xChartDoc ));

    // Grids
    Reference< frame::XModel > xChartModel( xChartDoc, uno::UNO_QUERY );
    for( sal_Int32 nA=0; nA<aAxes.getLength(); ++nA )
    {
        Reference< XAxis > xAxis( aAxes[nA] );
        if(!xAxis.is())
            continue;

        Reference< beans::XPropertySet > xGridProperties( xAxis->getGridProperties() );
        if( AxisHelper::isGridVisible( xGridProperties ) )
        {
            //main grid
            rContainer.push_back(
                ObjectIdentifier::createClassifiedIdentifierForGrid( xAxis, xChartModel ) );
        }

        Sequence< Reference< beans::XPropertySet > > aSubGrids( xAxis->getSubGridProperties() );;
        sal_Int32 nSubGrid = 0;
        for( nSubGrid = 0; nSubGrid < aSubGrids.getLength(); ++nSubGrid )
        {
            Reference< beans::XPropertySet > xSubGridProperties( aSubGrids[nSubGrid] );
            if( AxisHelper::isGridVisible( xSubGridProperties ) )
            {
                //sub grid
                rContainer.push_back(
                    ObjectIdentifier::createClassifiedIdentifierForGrid( xAxis, xChartModel, nSubGrid ) );
            }
        }
    }

    // Wall
    rContainer.push_back(
        ObjectIdentifier::createClassifiedIdentifier( OBJECTTYPE_DIAGRAM_WALL, rtl::OUString()));

    // Floor
    if( DiagramHelper::getDimension( xDiagram ) == 3 )
    {
        Reference< beans::XPropertySet > xFloor( xDiagram->getFloor());
        if( xFloor.is())
            rContainer.push_back(
                ObjectIdentifier::createClassifiedIdentifier( OBJECTTYPE_DIAGRAM_FLOOR, rtl::OUString()));
    }
}

void ImplObjectHierarchy::createDataSeriesTree(
    ObjectHierarchy::tChildContainer & rOutDiagramSubContainer,
    const Reference< XCoordinateSystemContainer > & xCooSysCnt )
{
    try
    {
        sal_Int32 nDiagramIndex = 0;
        Sequence< Reference< XCoordinateSystem > > aCooSysSeq(
            xCooSysCnt->getCoordinateSystems());
        for( sal_Int32 nCooSysIdx=0; nCooSysIdx<aCooSysSeq.getLength(); ++nCooSysIdx )
        {
            Reference< XChartTypeContainer > xCTCnt( aCooSysSeq[nCooSysIdx], uno::UNO_QUERY_THROW );
            Sequence< Reference< XChartType > > aChartTypeSeq( xCTCnt->getChartTypes());
            for( sal_Int32 nCTIdx=0; nCTIdx<aChartTypeSeq.getLength(); ++nCTIdx )
            {
                Reference< XDataSeriesContainer > xDSCnt( aChartTypeSeq[nCTIdx], uno::UNO_QUERY_THROW );
                Sequence< Reference< XDataSeries > > aSeriesSeq( xDSCnt->getDataSeries() );
                for( sal_Int32 nSeriesIdx=0; nSeriesIdx<aSeriesSeq.getLength(); ++nSeriesIdx )
                {
                    OUString aSeriesParticle(
                        ObjectIdentifier::createParticleForSeries(
                            nDiagramIndex, nCooSysIdx, nCTIdx, nSeriesIdx ));
                    ObjectHierarchy::tCID aSeriesCID(
                        ObjectIdentifier::createClassifiedIdentifierForParticle( aSeriesParticle ));
                    rOutDiagramSubContainer.push_back( aSeriesCID );

                    ObjectHierarchy::tChildContainer aSeriesSubContainer;

                    // Statistics
                    Reference< chart2::XRegressionCurveContainer > xCurveCnt( aSeriesSeq[nSeriesIdx], uno::UNO_QUERY );
                    if( xCurveCnt.is())
                    {
                        Sequence< Reference< chart2::XRegressionCurve > > aCurves( xCurveCnt->getRegressionCurves());
                        for( sal_Int32 nCurveIdx=0; nCurveIdx<aCurves.getLength(); ++nCurveIdx )
                        {<commit_msg>INTEGRATION: CWS chart11 (1.2.38); FILE MERGED 2007/08/23 12:36:03 bm 1.2.38.4: RESYNC: (1.2-1.3); FILE MERGED 2007/08/22 10:24:30 bm 1.2.38.3: #i67225# need to have all axes (also invisible ones) for the grid, of course 2007/08/22 09:04:15 bm 1.2.38.2: #i67225# rename getAllAxis... to getAllAxes... (plural), add bOnlyVisible parameter to retrieve only axes with Show==true 2007/08/17 16:30:20 bm 1.2.38.1: #i67225# do not include invisible objects in ObjectHierarchy for a11y and keyboard navigation<commit_after>/*************************************************************************
 *
 *  OpenOffice.org - a multi-platform office productivity suite
 *
 *  $RCSfile: ObjectHierarchy.cxx,v $
 *
 *  $Revision: 1.4 $
 *
 *  last change: $Author: vg $ $Date: 2007-09-18 14:56:50 $
 *
 *  The Contents of this file are made available subject to
 *  the terms of GNU Lesser General Public License Version 2.1.
 *
 *
 *    GNU Lesser General Public License Version 2.1
 *    =============================================
 *    Copyright 2005 by Sun Microsystems, Inc.
 *    901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *    This library is free software; you can redistribute it and/or
 *    modify it under the terms of the GNU Lesser General Public
 *    License version 2.1, as published by the Free Software Foundation.
 *
 *    This library is distributed in the hope that it will be useful,
 *    but WITHOUT ANY WARRANTY; without even the implied warranty of
 *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 *    Lesser General Public License for more details.
 *
 *    You should have received a copy of the GNU Lesser General Public
 *    License along with this library; if not, write to the Free Software
 *    Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 *    MA  02111-1307  USA
 *
 ************************************************************************/

// MARKER(update_precomp.py): autogen include statement, do not remove
#include "precompiled_chart2.hxx"

#include "ObjectHierarchy.hxx"
#include "ObjectIdentifier.hxx"
#include "ChartModelHelper.hxx"
#include "DiagramHelper.hxx"
#include "RegressionCurveHelper.hxx"
#include "AxisHelper.hxx"
#include "chartview/ExplicitValueProvider.hxx"
#include "macros.hxx"
#include "LineProperties.hxx"
#include "ChartTypeHelper.hxx"

#include <map>
#include <algorithm>

#include <com/sun/star/chart2/XTitled.hpp>
#include <com/sun/star/chart2/XCoordinateSystemContainer.hpp>
#include <com/sun/star/chart2/XChartTypeContainer.hpp>
#include <com/sun/star/chart2/XDataSeriesContainer.hpp>

#include <com/sun/star/container/XIndexAccess.hpp>
#include <com/sun/star/awt/Key.hpp>
#include <com/sun/star/awt/KeyModifier.hpp>

using namespace ::com::sun::star;
using namespace ::com::sun::star::chart2;

using ::com::sun::star::uno::Reference;
using ::com::sun::star::uno::Sequence;
using ::rtl::OUString;

namespace
{
struct lcl_ObjectToCID : public ::std::unary_function< Reference< uno::XInterface >, OUString >
{
    explicit lcl_ObjectToCID( const Reference< chart2::XChartDocument > & xChartDoc ) :
            m_xModel( xChartDoc, uno::UNO_QUERY )
    {}

    OUString operator() ( const Reference< uno::XInterface > & xObj )
    {
        return ::chart::ObjectIdentifier::createClassifiedIdentifierForObject( xObj, m_xModel );
    }

private:
    Reference< frame::XModel > m_xModel;
};

void lcl_getChildCIDs(
    ::chart::ObjectHierarchy::tChildContainer & rOutChildren,
    const Reference< container::XIndexAccess > & xShapes )
{
    if( xShapes.is())
    {
        sal_Int32 nCount = xShapes->getCount();
        for( sal_Int32 i=0; i<nCount; ++i)
        {
            Reference< beans::XPropertySet > xShapeProp( xShapes->getByIndex( i ), uno::UNO_QUERY );
            if( xShapeProp.is())
            {
                Reference< beans::XPropertySetInfo > xInfo( xShapeProp->getPropertySetInfo());
                OUString aName;
                if( xInfo.is() &&
                    xInfo->hasPropertyByName( C2U("Name")) &&
                    (xShapeProp->getPropertyValue( C2U("Name")) >>= aName ) &&
                    aName.getLength() > 0 &&
                    ::chart::ObjectIdentifier::isCID( aName ))
                {
                    rOutChildren.push_back( aName );
                }
                Reference< container::XIndexAccess > xNewShapes( xShapeProp, uno::UNO_QUERY );
                if( xNewShapes.is())
                    lcl_getChildCIDs( rOutChildren, xNewShapes );
            }
        }
    }
}

} // anonymous namespace


namespace chart
{

namespace impl
{
class ImplObjectHierarchy
{
public:
    explicit ImplObjectHierarchy(
        const Reference< XChartDocument > & xChartDocument,
        ExplicitValueProvider * pExplicitValueProvider,
        bool bFlattenDiagram );

    bool                              hasChildren( const OUString & rParent );
    ObjectHierarchy::tChildContainer  getChildren( const OUString & rParent );
    ObjectHierarchy::tChildContainer  getSiblings( const OUString & rNode );

    ObjectHierarchy::tCID             getParent( const ObjectHierarchy::tCID & rCID );

private:
    void createTree( const Reference< XChartDocument > & xChartDocument );
    void createDiagramTree(
        ObjectHierarchy::tChildContainer & rContainer,
        const Reference< XChartDocument > & xChartDoc,
        const Reference< XDiagram > & xDiagram );
    void createDataSeriesTree(
        ObjectHierarchy::tChildContainer & rOutDiagramSubContainer,
        const Reference< XCoordinateSystemContainer > & xCooSysCnt );
    ObjectHierarchy::tCID getParentImpl(
        const ObjectHierarchy::tCID & rParentCID,
        const ObjectHierarchy::tCID & rCID );

    typedef ::std::map< OUString, ObjectHierarchy::tChildContainer >
        tChildMap;
    tChildMap m_aChildMap;
    ExplicitValueProvider * m_pExplicitValueProvider;
    bool m_bFlattenDiagram;
};

ImplObjectHierarchy::ImplObjectHierarchy(
    const Reference< XChartDocument > & xChartDocument,
    ExplicitValueProvider * pExplicitValueProvider,
    bool bFlattenDiagram ) :
        m_pExplicitValueProvider( pExplicitValueProvider ),
        m_bFlattenDiagram( bFlattenDiagram )
{
    createTree( xChartDocument );
    // don't remember this helper to avoid access after lifetime
    m_pExplicitValueProvider = 0;
}

void ImplObjectHierarchy::createTree( const Reference< XChartDocument > & xChartDocument )
{
    if( !xChartDocument.is())
        return;

    //@todo: change ObjectIdentifier to take an XChartDocument rather than XModel
    Reference< frame::XModel > xModel( xChartDocument, uno::UNO_QUERY );
    ObjectHierarchy::tChildContainer aTopLevelContainer;

    // First Level

    // Main Title
    Reference< XTitled > xDocTitled( xChartDocument, uno::UNO_QUERY );
    if( xDocTitled.is())
    {
        Reference< XTitle > xMainTitle( xDocTitled->getTitleObject());
        if( xMainTitle.is())
            aTopLevelContainer.push_back(
                ObjectIdentifier::createClassifiedIdentifierForObject( xMainTitle, xModel ));
    }

    Reference< XDiagram > xDiagram( ChartModelHelper::findDiagram( xChartDocument ));
    if( xDiagram.is())
    {
        // Sub Title.  Note: This is interpreted of being top level
        Reference< XTitled > xDiaTitled( xDiagram, uno::UNO_QUERY );
        if( xDiaTitled.is())
        {
            Reference< XTitle > xSubTitle( xDiaTitled->getTitleObject());
            if( xSubTitle.is())
                aTopLevelContainer.push_back(
                    ObjectIdentifier::createClassifiedIdentifierForObject( xSubTitle, xModel ));
        }

        // Axis Titles. Note: These are interpreted of being top level
        Sequence< Reference< XAxis > > aAxes( AxisHelper::getAllAxesOfDiagram( xDiagram ) );
        for( sal_Int32 i=0; i<aAxes.getLength(); ++i )
        {
            Reference< XTitled > xAxisTitled( aAxes[i], uno::UNO_QUERY );
            if( xAxisTitled.is())
            {
                Reference< XTitle > xAxisTitle( xAxisTitled->getTitleObject());
                if( xAxisTitle.is())
                    aTopLevelContainer.push_back(
                        ObjectIdentifier::createClassifiedIdentifierForObject( xAxisTitle, xModel ));
            }
        }

        // Diagram
        OUString aDiaCID( ObjectIdentifier::createClassifiedIdentifierForObject( xDiagram, xModel ));
        OSL_ASSERT( aDiaCID.getLength());
        aTopLevelContainer.push_back( aDiaCID );
        if( m_bFlattenDiagram )
            createDiagramTree( aTopLevelContainer, xChartDocument, xDiagram );
        else
        {
            ObjectHierarchy::tChildContainer aSubContainer;
            createDiagramTree( aSubContainer, xChartDocument, xDiagram );
            if( ! aSubContainer.empty())
                m_aChildMap[ aDiaCID ] = aSubContainer;
        }


        // Legend. Note: This is interpreted of being top level
        Reference< XLegend > xLegend( xDiagram->getLegend());
        if( xLegend.is())
        {
            Reference< beans::XPropertySet > xLegendProp( xLegend, uno::UNO_QUERY );
            bool bShow = false;
            if( xLegendProp.is() &&
                (xLegendProp->getPropertyValue( C2U("Show")) >>= bShow) &&
                bShow )
            {
                OUString aLegendCID( ObjectIdentifier::createClassifiedIdentifierForObject( xLegend, xModel ));
                aTopLevelContainer.push_back( aLegendCID );

                // iterate over child shapes of legend and search for matching CIDs
                if( m_pExplicitValueProvider )
                {
                    Reference< container::XIndexAccess > xLegendShapeContainer(
                        m_pExplicitValueProvider->getShapeForCID( aLegendCID ), uno::UNO_QUERY );
                    ObjectHierarchy::tChildContainer aLegendEntryCIDs;
                    lcl_getChildCIDs( aLegendEntryCIDs, xLegendShapeContainer );

                    m_aChildMap[ aLegendCID ] = aLegendEntryCIDs;
                }
            }
        }
    }

    // Chart Area
    aTopLevelContainer.push_back(
        ObjectIdentifier::createClassifiedIdentifier( OBJECTTYPE_PAGE, OUString() ) );

    if( ! aTopLevelContainer.empty())
        m_aChildMap[ ObjectHierarchy::getRootNodeCID() ] = aTopLevelContainer;
}

void ImplObjectHierarchy::createDiagramTree(
    ObjectHierarchy::tChildContainer & rContainer,
    const Reference< XChartDocument > & xChartDoc,
    const Reference< XDiagram > & xDiagram )
{
    // Data Series
    Reference< XCoordinateSystemContainer > xCooSysCnt( xDiagram, uno::UNO_QUERY_THROW );
    createDataSeriesTree( rContainer, xCooSysCnt );

    // Axes
    sal_Int32 nDimensionCount = DiagramHelper::getDimension( xDiagram );
    uno::Reference< chart2::XChartType > xChartType( DiagramHelper::getChartTypeByIndex( xDiagram, 0 ) );
    bool bSupportsAxesGrids = ChartTypeHelper::isSupportingMainAxis( xChartType, nDimensionCount, 0 );
    bool bIsThreeD = ( nDimensionCount == 3 );
    bool bHasWall = DiagramHelper::isSupportingFloorAndWall( xDiagram );
    if( bSupportsAxesGrids )
    {
        Sequence< Reference< XAxis > > aAxes( AxisHelper::getAllAxesOfDiagram( xDiagram, /* bOnlyVisible = */ true ) );
        ::std::transform( aAxes.getConstArray(), aAxes.getConstArray() + aAxes.getLength(),
                          ::std::back_inserter( rContainer ),
                          lcl_ObjectToCID( xChartDoc ));

        // get all axes, also invisible ones
        aAxes = AxisHelper::getAllAxesOfDiagram( xDiagram, /* bOnlyVisible = */ false );
        // Grids
        Reference< frame::XModel > xChartModel( xChartDoc, uno::UNO_QUERY );
        for( sal_Int32 nA=0; nA<aAxes.getLength(); ++nA )
        {
            Reference< XAxis > xAxis( aAxes[nA] );
            if(!xAxis.is())
                continue;

            Reference< beans::XPropertySet > xGridProperties( xAxis->getGridProperties() );
            if( AxisHelper::isGridVisible( xGridProperties ) )
            {
                //main grid
                rContainer.push_back(
                    ObjectIdentifier::createClassifiedIdentifierForGrid( xAxis, xChartModel ) );
            }

            Sequence< Reference< beans::XPropertySet > > aSubGrids( xAxis->getSubGridProperties() );;
            sal_Int32 nSubGrid = 0;
            for( nSubGrid = 0; nSubGrid < aSubGrids.getLength(); ++nSubGrid )
            {
                Reference< beans::XPropertySet > xSubGridProperties( aSubGrids[nSubGrid] );
                if( AxisHelper::isGridVisible( xSubGridProperties ) )
                {
                    //sub grid
                    rContainer.push_back(
                        ObjectIdentifier::createClassifiedIdentifierForGrid( xAxis, xChartModel, nSubGrid ) );
                }
            }
        }
    }

    // Wall
    if( bHasWall )
    {
        rContainer.push_back(
            ObjectIdentifier::createClassifiedIdentifier( OBJECTTYPE_DIAGRAM_WALL, rtl::OUString()));
    }

    // Floor
    if( bHasWall && bIsThreeD )
    {
        Reference< beans::XPropertySet > xFloor( xDiagram->getFloor());
        if( xFloor.is())
            rContainer.push_back(
                ObjectIdentifier::createClassifiedIdentifier( OBJECTTYPE_DIAGRAM_FLOOR, rtl::OUString()));
    }
}

void ImplObjectHierarchy::createDataSeriesTree(
    ObjectHierarchy::tChildContainer & rOutDiagramSubContainer,
    const Reference< XCoordinateSystemContainer > & xCooSysCnt )
{
    try
    {
        sal_Int32 nDiagramIndex = 0;
        Sequence< Reference< XCoordinateSystem > > aCooSysSeq(
            xCooSysCnt->getCoordinateSystems());
        for( sal_Int32 nCooSysIdx=0; nCooSysIdx<aCooSysSeq.getLength(); ++nCooSysIdx )
        {
            Reference< XChartTypeContainer > xCTCnt( aCooSysSeq[nCooSysIdx], uno::UNO_QUERY_THROW );
            Sequence< Reference< XChartType > > aChartTypeSeq( xCTCnt->getChartTypes());
            for( sal_Int32 nCTIdx=0; nCTIdx<aChartTypeSeq.getLength(); ++nCTIdx )
            {
                Reference< XDataSeriesContainer > xDSCnt( aChartTypeSeq[nCTIdx], uno::UNO_QUERY_THROW );
                Sequence< Reference< XDataSeries > > aSeriesSeq( xDSCnt->getDataSeries() );
                const sal_Int32 nNumberOfSeries =
                    ChartTypeHelper::getNumberOfDisplayedSeries( aChartTypeSeq[nCTIdx], aSeriesSeq.getLength());

                for( sal_Int32 nSeriesIdx=0; nSeriesIdx<nNumberOfSeries; ++nSeriesIdx )
                {
                    OUString aSeriesParticle(
                        ObjectIdentifier::createParticleForSeries(
                            nDiagramIndex, nCooSysIdx, nCTIdx, nSeriesIdx ));
                    ObjectHierarchy::tCID aSeriesCID(
                        ObjectIdentifier::createClassifiedIdentifierForParticle( aSeriesParticle ));
                    rOutDiagramSubContainer.push_back( aSeriesCID );

                    ObjectHierarchy::tChildContainer aSeriesSubContainer;

                    // Statistics
                    Reference< chart2::XRegressionCurveContainer > xCurveCnt( aSeriesSeq[nSeriesIdx], uno::UNO_QUERY );
                    if( xCurveCnt.is())
                    {
                        Sequence< Reference< chart2::XRegressionCurve > > aCurves( xCurveCnt->getRegressionCurves());
                        for( sal_Int32 nCurveIdx=0; nCurveIdx<aCurves.getLength(); ++nCurveIdx )
                        {
{'fraction_non_alphanumeric': 0.11049779884862851, 'fraction_numerical': 0.010023704707077549, 'mean_word_length': 2.672553165029225, 'pattern_counts': {'":': 0, '<': 146, '<?xml version=': 0, '>': 176, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 4, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '2760693', 'n_tokens_mistral': 8996, 'n_tokens_neox': 8588, 'n_words': 1795}