/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/*
 * This file is part of the LibreOffice project.
 *
 * This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
 *
 * This file incorporates work covered by the following license notice:
 *
 *   Licensed to the Apache Software Foundation (ASF) under one or more
 *   contributor license agreements. See the NOTICE file distributed
 *   with this work for additional information regarding copyright
 *   ownership. The ASF licenses this file to you under the Apache
 *   License, Version 2.0 (the "License"); you may not use this file
 *   except in compliance with the License. You may obtain a copy of
 *   the License at http://www.apache.org/licenses/LICENSE-2.0 .
 */
 
#include "PieChartTypeTemplate.hxx"
#include "PieChartType.hxx"
#include <BaseCoordinateSystem.hxx>
#include <CommonConverters.hxx>
#include <ChartType.hxx>
#include <Diagram.hxx>
#include <DataSeries.hxx>
#include <DataSeriesHelper.hxx>
#include <DataSeriesProperties.hxx>
#include <Axis.hxx>
#include <AxisHelper.hxx>
#include <PropertyHelper.hxx>
#include <com/sun/star/beans/PropertyAttribute.hpp>
#include <com/sun/star/drawing/LineStyle.hpp>
#include <com/sun/star/uno/XComponentContext.hpp>
#include <officecfg/Office/Compatibility.hxx>
#include <comphelper/diagnose_ex.hxx>
 
#include <rtl/math.hxx>
 
#include <algorithm>
 
using namespace ::com::sun::star;
using namespace ::chart::DataSeriesProperties;
 
using ::com::sun::star::beans::Property;
using ::com::sun::star::uno::Sequence;
using ::com::sun::star::uno::Reference;
 
namespace
{
 
enum
{
    PROP_PIE_TEMPLATE_DEFAULT_OFFSET,
    PROP_PIE_TEMPLATE_OFFSET_MODE,
    PROP_PIE_TEMPLATE_DIMENSION,
    PROP_PIE_TEMPLATE_USE_RINGS,
    PROP_PIE_TEMPLATE_SUB_PIE_TYPE,
    PROP_PIE_TEMPLATE_COMPOSITE_SIZE
};
 
::chart::tPropertyValueMap& StaticPieChartTypeTemplateDefaults()
{
    static ::chart::tPropertyValueMap aStaticDefaults =
        []{
            ::chart::tPropertyValueMap aOutMap;
            ::chart::PropertyHelper::setPropertyValueDefault( aOutMap, PROP_PIE_TEMPLATE_OFFSET_MODE, chart2::PieChartOffsetMode_NONE );
            ::chart::PropertyHelper::setPropertyValueDefault< double >( aOutMap, PROP_PIE_TEMPLATE_DEFAULT_OFFSET, 0.5 );
            ::chart::PropertyHelper::setPropertyValueDefault< sal_Int32 >( aOutMap, PROP_PIE_TEMPLATE_DIMENSION, 2 );
            ::chart::PropertyHelper::setPropertyValueDefault( aOutMap, PROP_PIE_TEMPLATE_USE_RINGS, false );
            ::chart::PropertyHelper::setPropertyValueDefault( aOutMap, PROP_PIE_TEMPLATE_SUB_PIE_TYPE, chart2::PieChartSubType_NONE );
            ::chart::PropertyHelper::setPropertyValueDefault< sal_Int32 >( aOutMap, PROP_PIE_TEMPLATE_COMPOSITE_SIZE, 2 );
            return aOutMap;
        }();
    return aStaticDefaults;
}
 
::cppu::OPropertyArrayHelper& StaticPieChartTypeTemplateInfoHelper()
{
    static ::cppu::OPropertyArrayHelper aPropHelper(
        []()
        {
            std::vector< css::beans::Property > aProperties {
                { u"OffsetMode"_ustr,
                  PROP_PIE_TEMPLATE_OFFSET_MODE,
                  cppu::UnoType<chart2::PieChartOffsetMode>::get(),
                  beans::PropertyAttribute::BOUND
                  | beans::PropertyAttribute::MAYBEDEFAULT },
                { u"DefaultOffset"_ustr,
                  PROP_PIE_TEMPLATE_DEFAULT_OFFSET,
                  cppu::UnoType<double>::get(),
                  beans::PropertyAttribute::BOUND
                  | beans::PropertyAttribute::MAYBEDEFAULT },
                { u"Dimension"_ustr,
                  PROP_PIE_TEMPLATE_DIMENSION,
                  cppu::UnoType<sal_Int32>::get(),
                  beans::PropertyAttribute::BOUND
                  | beans::PropertyAttribute::MAYBEDEFAULT },
                { u"UseRings"_ustr,
                  PROP_PIE_TEMPLATE_USE_RINGS,
                  cppu::UnoType<bool>::get(),
                  beans::PropertyAttribute::BOUND
                  | beans::PropertyAttribute::MAYBEDEFAULT },
                { u"SubPieType"_ustr,
                  PROP_PIE_TEMPLATE_SUB_PIE_TYPE,
                  cppu::UnoType<chart2::PieChartSubType>::get(),
                  beans::PropertyAttribute::BOUND
                  | beans::PropertyAttribute::MAYBEDEFAULT },
                { u"CompositeSize"_ustr,
                  PROP_PIE_TEMPLATE_COMPOSITE_SIZE,
                  cppu::UnoType<sal_Int32>::get(),
                  beans::PropertyAttribute::BOUND
                  | beans::PropertyAttribute::MAYBEDEFAULT }
            };
 
            std::sort( aProperties.begin(), aProperties.end(),
                         ::chart::PropertyNameLess() );
 
            return comphelper::containerToSequence( aProperties );
        }() );
    return aPropHelper;
}
 
uno::Reference< beans::XPropertySetInfo >& StaticPieChartTypeTemplateInfo()
{
    static uno::Reference< beans::XPropertySetInfo > xPropertySetInfo(
        ::cppu::OPropertySetHelper::createPropertySetInfo(StaticPieChartTypeTemplateInfoHelper() ) );
    return xPropertySetInfo;
}
 
} // anonymous namespace
 
namespace chart
{
 
PieChartTypeTemplate::PieChartTypeTemplate(
    uno::Reference<
        uno::XComponentContext > const & xContext,
    const OUString & rServiceName,
    chart2::PieChartOffsetMode eMode,
    bool bRings,
    chart2::PieChartSubType eSubType,
    sal_Int32 nDim         /* = 2 */    ) :
        ChartTypeTemplate( xContext, rServiceName )
{
    setFastPropertyValue_NoBroadcast( PROP_PIE_TEMPLATE_OFFSET_MODE,    uno::Any( eMode ));
    setFastPropertyValue_NoBroadcast( PROP_PIE_TEMPLATE_DIMENSION,      uno::Any( nDim ));
    setFastPropertyValue_NoBroadcast( PROP_PIE_TEMPLATE_USE_RINGS,      uno::Any( bRings ));
    setFastPropertyValue_NoBroadcast( PROP_PIE_TEMPLATE_SUB_PIE_TYPE,   uno::Any( eSubType ));
    setFastPropertyValue_NoBroadcast( PROP_PIE_TEMPLATE_COMPOSITE_SIZE, uno::Any( sal_Int32(2) ));
}
 
PieChartTypeTemplate::~PieChartTypeTemplate()
{}
 
// ____ OPropertySet ____
void PieChartTypeTemplate::GetDefaultValue( sal_Int32 nHandle, uno::Any& rAny ) const
{
    const tPropertyValueMap& rStaticDefaults = StaticPieChartTypeTemplateDefaults();
    tPropertyValueMap::const_iterator aFound( rStaticDefaults.find( nHandle ) );
    if( aFound == rStaticDefaults.end() )
        rAny.clear();
    else
        rAny = (*aFound).second;
}
 
::cppu::IPropertyArrayHelper & SAL_CALL PieChartTypeTemplate::getInfoHelper()
{
    return StaticPieChartTypeTemplateInfoHelper();
}
 
// ____ XPropertySet ____
uno::Reference< beans::XPropertySetInfo > SAL_CALL PieChartTypeTemplate::getPropertySetInfo()
{
    return StaticPieChartTypeTemplateInfo();
}
 
// ____ ChartTypeTemplate ____
sal_Int32 PieChartTypeTemplate::getDimension() const
{
    sal_Int32 nDim = 2;
    try
    {
        // note: UNO-methods are never const
        const_cast< PieChartTypeTemplate * >( this )->
            getFastPropertyValue( PROP_PIE_TEMPLATE_DIMENSION ) >>= nDim;
    }
    catch( const beans::UnknownPropertyException & )
    {
        DBG_UNHANDLED_EXCEPTION("chart2");
    }
 
    return nDim;
}
 
sal_Int32 PieChartTypeTemplate::getAxisCountByDimension( sal_Int32 /*nDimension*/ )
{
    return 0;
}
 
void PieChartTypeTemplate::adaptAxes(
    const std::vector< rtl::Reference< BaseCoordinateSystem > > & /*rCoordSys*/ )
{
    // hide existing axes
    //hhhh todo
}
 
void PieChartTypeTemplate::adaptScales(
    const std::vector< rtl::Reference< BaseCoordinateSystem > > & aCooSysSeq,
    const Reference< chart2::data::XLabeledDataSequence > & xCategories //@todo: in future there may be more than one sequence of categories (e.g. charttype with categories at x and y axis )
    )
{
    ChartTypeTemplate::adaptScales( aCooSysSeq, xCategories );
 
    //remove explicit scalings from radius axis
    //and ensure correct orientation of scales for donuts
 
    for( rtl::Reference< BaseCoordinateSystem > const & coords : aCooSysSeq )
    {
        try
        {
            rtl::Reference< Axis > xAxis = AxisHelper::getAxis( 1 /*nDimensionIndex*/,0 /*nAxisIndex*/
                    , coords );
            if( xAxis.is() )
            {
                chart2::ScaleData aScaleData( xAxis->getScaleData() );
                AxisHelper::removeExplicitScaling( aScaleData );
                // tdf#108059 Create new pie/donut charts with clockwise orientation
                if (!officecfg::Office::Compatibility::View::ClockwisePieChartDirection::get())
                {
                    aScaleData.Orientation = chart2::AxisOrientation_MATHEMATICAL;
                }
                else
                {
                    aScaleData.Orientation = chart2::AxisOrientation_REVERSE;
                }
                xAxis->setScaleData( aScaleData );
            }
 
            xAxis = AxisHelper::getAxis( 0 /*nDimensionIndex*/,0 /*nAxisIndex*/
                    , coords );
            if( xAxis.is() )
            {
                chart2::ScaleData aScaleData( xAxis->getScaleData() );
 
                //tdf#123218 Don't reverse the orientation in OOXML-heavy environments
                if( officecfg::Office::Compatibility::View::ReverseXAxisOrientationDoughnutChart::get() )
                    aScaleData.Orientation = chart2::AxisOrientation_REVERSE;
                else
                    aScaleData.Orientation = chart2::AxisOrientation_MATHEMATICAL;
                xAxis->setScaleData( aScaleData );
            }
        }
        catch( const uno::Exception & )
        {
            DBG_UNHANDLED_EXCEPTION("chart2");
        }
    }
}
 
void PieChartTypeTemplate::createChartTypes(
    const std::vector< std::vector< rtl::Reference< DataSeries > > > & aSeriesSeq,
    const std::vector< rtl::Reference< BaseCoordinateSystem > > & rCoordSys,
    const std::vector< rtl::Reference< ChartType > >& /* aOldChartTypesSeq */ )
{
    if( rCoordSys.empty() )
        return;
 
    try
    {
        rtl::Reference< ChartType > xCT = new PieChartType();
        xCT->setFastPropertyValue(
            PROP_PIECHARTTYPE_USE_RINGS, getFastPropertyValue( PROP_PIE_TEMPLATE_USE_RINGS )); // "UseRings"
        xCT->setFastPropertyValue(
            PROP_PIECHARTTYPE_SUBTYPE, getFastPropertyValue( PROP_PIE_TEMPLATE_SUB_PIE_TYPE )); // "SubType"
        xCT->setFastPropertyValue(
            PROP_PIECHARTTYPE_COMPOSITESIZE, getFastPropertyValue( PROP_PIE_TEMPLATE_COMPOSITE_SIZE )); // "CompositeSize"
        rCoordSys[0]->setChartTypes( std::vector{xCT} );
 
        if( !aSeriesSeq.empty() )
        {
            std::vector< rtl::Reference< DataSeries > > aFlatSeriesSeq = FlattenSequence( aSeriesSeq );
            xCT->setDataSeries( aFlatSeriesSeq );
 
            DataSeriesHelper::setStackModeAtSeries(
                aFlatSeriesSeq, rCoordSys[0], getStackMode( 0 ));
        }
    }
    catch( const uno::Exception & )
    {
        DBG_UNHANDLED_EXCEPTION("chart2");
    }
}
 
// ____ XChartTypeTemplate ____
bool PieChartTypeTemplate::matchesTemplate2(
    const rtl::Reference< ::chart::Diagram >& xDiagram,
    bool bAdaptProperties )
{
    bool bResult = ChartTypeTemplate::matchesTemplate2( xDiagram, bAdaptProperties );
 
    bool bTemplateUsesRings = false;
    getFastPropertyValue( PROP_PIE_TEMPLATE_USE_RINGS ) >>= bTemplateUsesRings;
    chart2::PieChartOffsetMode ePieOffsetMode;
    getFastPropertyValue( PROP_PIE_TEMPLATE_OFFSET_MODE ) >>= ePieOffsetMode;
    chart2::PieChartSubType eTemplateSubType;
    getFastPropertyValue( PROP_PIE_TEMPLATE_SUB_PIE_TYPE ) >>= eTemplateSubType;
 
    //check offset-mode
    if( bResult )
    {
        try
        {
            double fOffset=0.0;
            bool bAllOffsetsEqual = true;
            sal_Int32 nOuterSeriesIndex = 0;
 
            std::vector< rtl::Reference< DataSeries > > aSeriesVec =
                xDiagram->getDataSeries();
 
            //tdf#108067 The outer series is the last series in OOXML-heavy environments
            if( !officecfg::Office::Compatibility::View::ReverseXAxisOrientationDoughnutChart::get() )
                nOuterSeriesIndex = aSeriesVec.size() - 1;
 
            //check offset of outer series
            if( !aSeriesVec.empty() )
            {
                //@todo in future this will depend on Orientation of the radius axis scale
                const rtl::Reference< DataSeries >& xSeries( aSeriesVec[nOuterSeriesIndex] );
                xSeries->getPropertyValue( u"Offset"_ustr) >>= fOffset;
 
                // "AttributedDataPoints"
                uno::Sequence< sal_Int32 > aAttributedDataPointIndexList;
                if( xSeries->getFastPropertyValue( PROP_DATASERIES_ATTRIBUTED_DATA_POINTS ) >>= aAttributedDataPointIndexList )
                {
                    for(sal_Int32 nN=aAttributedDataPointIndexList.getLength();nN--;)
                    {
                        uno::Reference< beans::XPropertySet > xPointProp( xSeries->getDataPointByIndex(aAttributedDataPointIndexList[nN]) );
                        if(xPointProp.is())
                        {
                            double fPointOffset=0.0;
                            if( xSeries->getPropertyValue( u"Offset"_ustr) >>= fPointOffset )
                            {
                                if( ! ::rtl::math::approxEqual( fPointOffset, fOffset ) )
                                {
                                    bAllOffsetsEqual = false;
                                    break;
                                }
                            }
                        }
                    }
                }
            }
 
            chart2::PieChartOffsetMode eOffsetMode = chart2::PieChartOffsetMode_NONE;
            if( bAllOffsetsEqual && fOffset > 0.0 )
            {
                eOffsetMode = chart2::PieChartOffsetMode_ALL_EXPLODED;
                if( bAdaptProperties )
                    setFastPropertyValue_NoBroadcast( PROP_PIE_TEMPLATE_DEFAULT_OFFSET, uno::Any( fOffset ));
            }
 
            bResult = ( eOffsetMode == ePieOffsetMode );
        }
        catch( const uno::Exception & )
        {
            DBG_UNHANDLED_EXCEPTION("chart2");
            bResult = false;
        }
    }
 
    //check UseRings
    if( bResult )
    {
        rtl::Reference< ChartType > xCTProp = xDiagram->getChartTypeByIndex( 0 );
        bool bUseRings = false;
        if( xCTProp->getFastPropertyValue( PROP_PIECHARTTYPE_USE_RINGS ) >>= bUseRings ) // "UseRings"
        {
            bResult = ( bTemplateUsesRings == bUseRings );
        }
    }
    if( bResult )
    {
        rtl::Reference< ChartType > xCTProp = xDiagram->getChartTypeByIndex( 0 );
        chart2::PieChartSubType eSubType = chart2::PieChartSubType_NONE;
        if( xCTProp->getFastPropertyValue( PROP_PIECHARTTYPE_SUBTYPE ) >>= eSubType )
        {
            bResult = ( eTemplateSubType == eSubType );
        }
    }
 
    return bResult;
}
 
rtl::Reference< ChartType > PieChartTypeTemplate::getChartTypeForIndex( sal_Int32 /*nChartTypeIndex*/ )
{
    rtl::Reference< ChartType > xResult;
 
    try
    {
        xResult = new PieChartType();
        xResult->setFastPropertyValue(
            PROP_PIECHARTTYPE_USE_RINGS, getFastPropertyValue( PROP_PIE_TEMPLATE_USE_RINGS )); // "UseRings"
        xResult->setFastPropertyValue(
            PROP_PIECHARTTYPE_SUBTYPE, getFastPropertyValue( PROP_PIE_TEMPLATE_SUB_PIE_TYPE ));
    }
    catch( const uno::Exception & )
    {
        DBG_UNHANDLED_EXCEPTION("chart2");
    }
 
    return xResult;
}
 
rtl::Reference< ChartType > PieChartTypeTemplate::getChartTypeForNewSeries2(
        const std::vector< rtl::Reference< ChartType > >& aFormerlyUsedChartTypes )
{
    rtl::Reference< ChartType > xResult;
 
    try
    {
        xResult = new PieChartType();
        ChartTypeTemplate::copyPropertiesFromOldToNewCoordinateSystem( aFormerlyUsedChartTypes, xResult );
        xResult->setFastPropertyValue(
            PROP_PIECHARTTYPE_USE_RINGS, getFastPropertyValue( PROP_PIE_TEMPLATE_USE_RINGS )); // "UseRings"
        xResult->setFastPropertyValue(
            PROP_PIECHARTTYPE_SUBTYPE, getFastPropertyValue( PROP_PIE_TEMPLATE_SUB_PIE_TYPE ));
    }
    catch( const uno::Exception & )
    {
        DBG_UNHANDLED_EXCEPTION("chart2");
    }
 
    return xResult;
}
 
void PieChartTypeTemplate::applyStyle2(
    const rtl::Reference< DataSeries >& xSeries,
    ::sal_Int32 nChartTypeIndex,
    ::sal_Int32 nSeriesIndex,
    ::sal_Int32 nSeriesCount )
{
    ChartTypeTemplate::applyStyle2( xSeries, nChartTypeIndex, nSeriesIndex, nSeriesCount );
 
    try
    {
        bool bTemplateUsesRings = false;
        sal_Int32 nOuterSeriesIndex = 0;
        getFastPropertyValue( PROP_PIE_TEMPLATE_USE_RINGS ) >>= bTemplateUsesRings;
 
        //tdf#108067 The outer series is the last series in OOXML-heavy environments
        if( !officecfg::Office::Compatibility::View::ReverseXAxisOrientationDoughnutChart::get() )
            nOuterSeriesIndex = nSeriesCount - 1;
 
        if( nSeriesIndex == nOuterSeriesIndex ) //@todo in future this will depend on Orientation of the radius axis scale
        {
            static constexpr OUString aOffsetPropName( u"Offset"_ustr );
            // get offset mode
            chart2::PieChartOffsetMode ePieOffsetMode;
            getFastPropertyValue( PROP_PIE_TEMPLATE_OFFSET_MODE ) >>= ePieOffsetMode;
 
            // get default offset
            double fDefaultOffset = 0.5;
            getFastPropertyValue( PROP_PIE_TEMPLATE_DEFAULT_OFFSET ) >>= fDefaultOffset;
            double fOffsetToSet = fDefaultOffset;
 
            uno::Sequence< sal_Int32 > aAttributedDataPointIndexList;
            // "AttributedDataPoints"
            xSeries->getFastPropertyValue( PROP_DATASERIES_ATTRIBUTED_DATA_POINTS ) >>= aAttributedDataPointIndexList;
 
            // determine whether to set the new offset
            bool bSetOffset = ( ePieOffsetMode == chart2::PieChartOffsetMode_ALL_EXPLODED );
            if( !bSetOffset &&
                (ePieOffsetMode == chart2::PieChartOffsetMode_NONE) )
            {
                // set offset to 0 if the offset was exactly "all exploded"
                // before (individual offsets are kept)
                double fOffset = 0.0;
                if( (xSeries->getPropertyValue( aOffsetPropName ) >>= fOffset) &&
                    ::rtl::math::approxEqual( fOffset, fDefaultOffset ))
                {
                    fOffsetToSet = 0.0;
                    bSetOffset = true;
                    for (auto const& pointIndex : aAttributedDataPointIndexList)
                    {
                        uno::Reference< beans::XPropertySet > xPointProp(
                            xSeries->getDataPointByIndex( pointIndex ));
                        uno::Reference< beans::XPropertyState > xPointState( xPointProp, uno::UNO_QUERY );
                        double fPointOffset = 0.0;
                        if( xPointState.is() &&
                            (xPointState->getPropertyState( aOffsetPropName ) == beans::PropertyState_DIRECT_VALUE) &&
                            xPointProp.is() &&
                            (xPointProp->getPropertyValue( aOffsetPropName ) >>= fPointOffset ) &&
                            ! ::rtl::math::approxEqual( fPointOffset, fDefaultOffset ) )
                        {
                            bSetOffset = false;
                            break;
                        }
                    }
                }
            }
 
            if( bSetOffset )
            {
                // set the offset to the series and to the attributed data points
                xSeries->setPropertyValue( aOffsetPropName, uno::Any( fOffsetToSet ));
 
                // remove hard attributes from data points
                for (auto const& pointIndex : aAttributedDataPointIndexList)
                {
                    uno::Reference< beans::XPropertyState > xPointState(
                        xSeries->getDataPointByIndex( pointIndex ), uno::UNO_QUERY );
                    if( xPointState.is())
                        xPointState->setPropertyToDefault( aOffsetPropName );
                }
            }
        }
 
        // line style
        DataSeriesHelper::setPropertyAlsoToAllAttributedDataPoints( xSeries, u"BorderStyle"_ustr, uno::Any( drawing::LineStyle_NONE ) );
 
        // vary colors by point
        xSeries->setFastPropertyValue( PROP_DATASERIES_VARY_COLORS_BY_POINT, uno::Any( true )); // "VaryColorsByPoint"
    }
    catch( const uno::Exception & )
    {
        DBG_UNHANDLED_EXCEPTION("chart2");
    }
}
 
void PieChartTypeTemplate::resetStyles2( const rtl::Reference< ::chart::Diagram >& xDiagram )
{
    // reset axes and grids
    if( xDiagram.is())
    {
        const std::vector< rtl::Reference< BaseCoordinateSystem > > aCooSysSeq( xDiagram->getBaseCoordinateSystems());
        ChartTypeTemplate::createAxes( aCooSysSeq );
 
        //reset scale orientation
        for( rtl::Reference< BaseCoordinateSystem > const & coords : aCooSysSeq )
        {
            try
            {
                rtl::Reference< Axis > xAxis = AxisHelper::getAxis( 0 /*nDimensionIndex*/,0 /*nAxisIndex*/
                        , coords );
                if( xAxis.is() )
                {
                    chart2::ScaleData aScaleData( xAxis->getScaleData() );
                    aScaleData.Orientation = chart2::AxisOrientation_MATHEMATICAL;
                    xAxis->setScaleData( aScaleData );
                }
 
                xAxis = AxisHelper::getAxis( 1, 0, coords );
                if( xAxis.is() )
                {
                    chart2::ScaleData aScaleData( xAxis->getScaleData() );
                    aScaleData.Orientation = chart2::AxisOrientation_MATHEMATICAL;
                    xAxis->setScaleData( aScaleData );
                }
            }
            catch( const uno::Exception & )
            {
                DBG_UNHANDLED_EXCEPTION("chart2");
            }
        }
    }
 
    ChartTypeTemplate::resetStyles2( xDiagram );
 
    // vary colors by point,
    // line style
    std::vector< rtl::Reference< DataSeries > > aSeriesVec =
        xDiagram->getDataSeries();
    uno::Any aLineStyleAny( drawing::LineStyle_NONE );
    for (auto const& series : aSeriesVec)
    {
        series->setPropertyToDefault( u"VaryColorsByPoint"_ustr);
        if( series->getPropertyValue( u"BorderStyle"_ustr) == aLineStyleAny )
        {
            series->setPropertyToDefault( u"BorderStyle"_ustr);
        }
    }
 
    //reset scene properties
    xDiagram->setDefaultRotation( false );
}
 
// ____ XChartTypeTemplate ____
void PieChartTypeTemplate::adaptDiagram( const rtl::Reference< ::chart::Diagram >& xDiagram )
{
    if( !xDiagram.is() )
        return;
 
    //different default for scene geometry:
    xDiagram->setDefaultRotation( true );
}
 
IMPLEMENT_FORWARD_XINTERFACE2( PieChartTypeTemplate, ChartTypeTemplate, OPropertySet )
IMPLEMENT_FORWARD_XTYPEPROVIDER2( PieChartTypeTemplate, ChartTypeTemplate, OPropertySet )
 
} //  namespace chart
 
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */

V547 Expression 'bTemplateUsesRings == bUseRings' is always true.

V614 Uninitialized variable 'ePieOffsetMode' used.

V614 Uninitialized variable 'eTemplateSubType' used.

V614 Uninitialized variable 'ePieOffsetMode' used.

V1053 Calling the 'setFastPropertyValue_NoBroadcast' virtual function in the constructor may lead to unexpected result at runtime.

V1053 Calling the 'setFastPropertyValue_NoBroadcast' virtual function in the constructor may lead to unexpected result at runtime.

V1053 Calling the 'setFastPropertyValue_NoBroadcast' virtual function in the constructor may lead to unexpected result at runtime.

V1053 Calling the 'setFastPropertyValue_NoBroadcast' virtual function in the constructor may lead to unexpected result at runtime.

V1053 Calling the 'setFastPropertyValue_NoBroadcast' virtual function in the constructor may lead to unexpected result at runtime.

V1048 The 'bResult' variable was assigned the same value.