    /* -*- 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 <ObjectNameProvider.hxx>
    #include <ResId.hxx>
    #include <strings.hrc>
    #include <AxisHelper.hxx>
    #include <ChartModel.hxx>
    #include <ChartModelHelper.hxx>
    #include <DiagramHelper.hxx>
    #include <DataSeriesHelper.hxx>
    #include <TitleHelper.hxx>
    #include <AxisIndexDefines.hxx>
    #include <ExplicitCategoriesProvider.hxx>
    #include <CommonConverters.hxx>
    #include <NumberFormatterWrapper.hxx>
    #include <RegressionCurveHelper.hxx>
    #include <rtl/math.hxx>
    #include <rtl/ustring.hxx>
    #include <sal/log.hxx>
    #include <vcl/settings.hxx>
    #include <vcl/svapp.hxx>

    #include <com/sun/star/chart2/XTitle.hpp>
    #include <com/sun/star/chart2/XRegressionCurveContainer.hpp>
    #include <tools/diagnose_ex.h>

    namespace chart
    {
    using namespace ::com::sun::star;
    using namespace ::com::sun::star::chart2;
    using ::com::sun::star::uno::Reference;
    using ::com::sun::star::uno::Sequence;
    using ::com::sun::star::uno::Any;

    namespace
    {

    OUString lcl_getDataSeriesName( const OUString& rObjectCID, const Reference< frame::XModel >& xChartModel )
    {
        OUString aRet;

        Reference< XDiagram > xDiagram( ChartModelHelper::findDiagram( xChartModel ) );
        Reference< XDataSeries > xSeries( ObjectIdentifier::getDataSeriesForCID( rObjectCID , xChartModel ), uno::UNO_QUERY );
        if( xDiagram.is() && xSeries.is() )
        {
            Reference< XChartType > xChartType( DiagramHelper::getChartTypeOfSeries( xDiagram, xSeries ) );
            if( xChartType.is() )
            {
                aRet = ::chart::DataSeriesHelper::getDataSeriesLabel(
                        xSeries, xChartType->getRoleOfSequenceForSeriesLabel() ) ;
            }
        }

        return aRet;
    }

    OUString lcl_getFullSeriesName( const OUString& rObjectCID, const Reference< frame::XModel >& xChartModel )
    {
        OUString aRet(SchResId(STR_TIP_DATASERIES));
        OUString aWildcard( "%SERIESNAME" );
        sal_Int32 nIndex = aRet.indexOf( aWildcard );
        if( nIndex != -1 )
            aRet = aRet.replaceAt( nIndex, aWildcard.getLength(), lcl_getDataSeriesName( rObjectCID, xChartModel ) );
        return aRet;
    }

    void lcl_addText( OUString& rOut, const OUString& rSeparator, const OUString& rNext )
    {
        if( !(rOut.isEmpty() || rNext.isEmpty()) )
            rOut+=rSeparator;
        if( !rNext.isEmpty() )
            rOut+=rNext;
    }

    OUString lcl_getDataPointValueText( const Reference< XDataSeries >& xSeries, sal_Int32 nPointIndex,
                                        const Reference< XCoordinateSystem >& xCooSys,
                                        const Reference< frame::XModel >& xChartModel )
    {

        OUString aRet;

        Reference<data::XDataSource> xDataSource(
                uno::Reference<data::XDataSource>( xSeries, uno::UNO_QUERY ) );
        if(!xDataSource.is())
            return aRet;

        Sequence< Reference< data::XLabeledDataSequence > > aDataSequences( xDataSource->getDataSequences() );

        OUString aX, aY, aY_Min, aY_Max, aY_First, aY_Last, a_Size;
        double fValue = 0;

        uno::Reference< util::XNumberFormatsSupplier > xNumberFormatsSupplier( xChartModel, uno::UNO_QUERY );
        NumberFormatterWrapper aNumberFormatterWrapper( xNumberFormatsSupplier );
        Color nLabelColor;//dummy
        bool bColorChanged;//dummy

        for(sal_Int32 nN = aDataSequences.getLength();nN--;)
        {
            uno::Reference<data::XDataSequence>  xDataSequence( aDataSequences[nN]->getValues());
            if( !xDataSequence.is() )
                continue;
            Sequence< Any > aData( xDataSequence->getData() );
            if( nPointIndex >= aData.getLength() )
                continue;
            uno::Reference<beans::XPropertySet> xProp(xDataSequence, uno::UNO_QUERY );
            if( xProp.is())
            {
                try
                {
                    uno::Any aARole = xProp->getPropertyValue( "Role" );
                    OUString aRole;
                    aARole >>= aRole;

                    if( aRole == "values-x" )
                    {
                        aData[nPointIndex]>>= fValue;
                        sal_Int32 nNumberFormatKey = xDataSequence->getNumberFormatKeyByIndex( nPointIndex );
                        aX = aNumberFormatterWrapper.getFormattedString( nNumberFormatKey, fValue, nLabelColor, bColorChanged );
                    }
                    else if( aRole == "values-y")
                    {
                        aData[nPointIndex]>>= fValue;
                        sal_Int32 nNumberFormatKey = xDataSequence->getNumberFormatKeyByIndex( nPointIndex );
                        aY = aNumberFormatterWrapper.getFormattedString( nNumberFormatKey, fValue, nLabelColor, bColorChanged );
                    }
                    else if( aRole == "values-first" )
                    {
                        aData[nPointIndex]>>= fValue;
                        sal_Int32 nNumberFormatKey = xDataSequence->getNumberFormatKeyByIndex( nPointIndex );
                        aY_First = aNumberFormatterWrapper.getFormattedString( nNumberFormatKey, fValue, nLabelColor, bColorChanged );
                    }
                    else if( aRole == "values-min" )
                    {
                        aData[nPointIndex]>>= fValue;
                        sal_Int32 nNumberFormatKey = xDataSequence->getNumberFormatKeyByIndex( nPointIndex );
                        aY_Min = aNumberFormatterWrapper.getFormattedString( nNumberFormatKey, fValue, nLabelColor, bColorChanged );
                    }
                    else if( aRole == "values-max" )
                    {
                        aData[nPointIndex]>>= fValue;
                        sal_Int32 nNumberFormatKey = xDataSequence->getNumberFormatKeyByIndex( nPointIndex );
                        aY_Max = aNumberFormatterWrapper.getFormattedString( nNumberFormatKey, fValue, nLabelColor, bColorChanged );
                    }
                    else if( aRole == "values-last" )
                    {
                        aData[nPointIndex]>>= fValue;
                        sal_Int32 nNumberFormatKey = xDataSequence->getNumberFormatKeyByIndex( nPointIndex );
                        aY_Last = aNumberFormatterWrapper.getFormattedString( nNumberFormatKey, fValue, nLabelColor, bColorChanged );
                    }
                    else if( aRole == "values-size" )
                    {
                        aData[nPointIndex]>>= fValue;
                        sal_Int32 nNumberFormatKey = xDataSequence->getNumberFormatKeyByIndex( nPointIndex );
                        a_Size = aNumberFormatterWrapper.getFormattedString( nNumberFormatKey, fValue, nLabelColor, bColorChanged );
                    }
                }
                catch( const uno::Exception& e )
                {
                    SAL_WARN("chart2", "Exception caught. " << e );
                }
            }
        }

        if( aX.isEmpty() )
        {
            ChartModel& rModel = dynamic_cast<ChartModel&>(*xChartModel.get());
            aRet = ExplicitCategoriesProvider::getCategoryByIndex( xCooSys, rModel, nPointIndex );
        }
        else
        {
            aRet = aX;
        }

        OUString aSeparator( " " );

        lcl_addText( aRet, aSeparator, aY );
        lcl_addText( aRet, aSeparator, aY_First );
        lcl_addText( aRet, aSeparator, aY_Min );
        lcl_addText( aRet, aSeparator, aY_Max );
        lcl_addText( aRet, aSeparator, aY_Last );
        lcl_addText( aRet, aSeparator, a_Size );

        return aRet;
    }

    } //end anonymous namespace

    OUString ObjectNameProvider::getName( ObjectType eObjectType, bool bPlural )
    {
        OUString aRet;
        switch( eObjectType )
        {
            case OBJECTTYPE_PAGE:
                    aRet=SchResId(STR_OBJECT_PAGE);
                    break;
            case OBJECTTYPE_TITLE:
                {
                    if(bPlural)
                        aRet=SchResId(STR_OBJECT_TITLES);
                    else
                        aRet=SchResId(STR_OBJECT_TITLE);
                }
                    break;
            case OBJECTTYPE_LEGEND:
                    aRet=SchResId(STR_OBJECT_LEGEND);
                    break;
            case OBJECTTYPE_LEGEND_ENTRY:
                    aRet=SchResId(STR_OBJECT_LEGEND_SYMBOL);//@todo change string if we do differentiate symbol and legend entry in future
                    break;
            case OBJECTTYPE_DIAGRAM:
                    aRet=SchResId(STR_OBJECT_DIAGRAM);
                    break;
            case OBJECTTYPE_DIAGRAM_WALL:
                    aRet=SchResId(STR_OBJECT_DIAGRAM_WALL);
                    break;
            case OBJECTTYPE_DIAGRAM_FLOOR:
                    aRet=SchResId(STR_OBJECT_DIAGRAM_FLOOR);
                    break;
            case OBJECTTYPE_AXIS:
                {
                    if(bPlural)
                        aRet=SchResId(STR_OBJECT_AXES);
                    else
                        aRet=SchResId(STR_OBJECT_AXIS);
                }
                    break;
            case OBJECTTYPE_AXIS_UNITLABEL:
                    aRet=SchResId(STR_OBJECT_LABEL);//@todo maybe a more concrete name
                    break;
            case OBJECTTYPE_GRID:
            case OBJECTTYPE_SUBGRID: //maybe todo: different names for subgrids
                {
                    if(bPlural)
                        aRet=SchResId(STR_OBJECT_GRIDS);
                    else
                        aRet=SchResId(STR_OBJECT_GRID);
                }
                    break;
            case OBJECTTYPE_DATA_SERIES:
                {
                    if(bPlural)
                        aRet=SchResId(STR_OBJECT_DATASERIES_PLURAL);
                    else
                        aRet=SchResId(STR_OBJECT_DATASERIES);
                }
                    break;
            case OBJECTTYPE_DATA_POINT:
                {
                    if(bPlural)
                        aRet=SchResId(STR_OBJECT_DATAPOINTS);
                    else
                        aRet=SchResId(STR_OBJECT_DATAPOINT);
                }
                    break;
            case OBJECTTYPE_DATA_LABELS:
                    aRet=SchResId(STR_OBJECT_DATALABELS);
                    break;
            case OBJECTTYPE_DATA_LABEL:
                    aRet=SchResId(STR_OBJECT_LABEL);
                    break;
            case OBJECTTYPE_DATA_ERRORS_X:
                    aRet=SchResId(STR_OBJECT_ERROR_BARS_X);
                    break;
            case OBJECTTYPE_DATA_ERRORS_Y:
                    aRet=SchResId(STR_OBJECT_ERROR_BARS_Y);
                    break;
            case OBJECTTYPE_DATA_ERRORS_Z:
                    aRet=SchResId(STR_OBJECT_ERROR_BARS_Z);
                    break;
            case OBJECTTYPE_DATA_AVERAGE_LINE:
                    aRet=SchResId(STR_OBJECT_AVERAGE_LINE);
                    break;
            case OBJECTTYPE_DATA_CURVE:
                {
                    if(bPlural)
                        aRet=SchResId(STR_OBJECT_CURVES);
                    else
                        aRet=SchResId(STR_OBJECT_CURVE);
                }
                    break;
            case OBJECTTYPE_DATA_STOCK_RANGE:
                    break;
            case OBJECTTYPE_DATA_STOCK_LOSS:
                    aRet=SchResId(STR_OBJECT_STOCK_LOSS);
                    break;
            case OBJECTTYPE_DATA_STOCK_GAIN:
                    aRet=SchResId(STR_OBJECT_STOCK_GAIN);
                    break;
            case OBJECTTYPE_DATA_CURVE_EQUATION:
                    aRet=SchResId(STR_OBJECT_CURVE_EQUATION);
                    break;
            default: //OBJECTTYPE_UNKNOWN
                ;
        }
        return aRet;
    }

    OUString ObjectNameProvider::getAxisName( const OUString& rObjectCID
                            , const uno::Reference< frame::XModel >& xChartModel  )
    {
        OUString aRet;

        Reference< XAxis > xAxis(
            ObjectIdentifier::getObjectPropertySet( rObjectCID , xChartModel ), uno::UNO_QUERY );

        sal_Int32 nCooSysIndex = 0;
        sal_Int32 nDimensionIndex = 0;
        sal_Int32 nAxisIndex = 0;
        AxisHelper::getIndicesForAxis( xAxis, ChartModelHelper::findDiagram( xChartModel ), nCooSysIndex, nDimensionIndex, nAxisIndex );

        switch(nDimensionIndex)
        {
            case 0://x-axis
                if( nAxisIndex == 0 )
                    aRet=SchResId(STR_OBJECT_AXIS_X);
                else
                    aRet=SchResId(STR_OBJECT_SECONDARY_X_AXIS);
                break;
            case 1://y-axis
                if( nAxisIndex == 0 )
                    aRet=SchResId(STR_OBJECT_AXIS_Y);
                else
                    aRet=SchResId(STR_OBJECT_SECONDARY_Y_AXIS);
                break;
            case 2://z-axis
                aRet=SchResId(STR_OBJECT_AXIS_Z);
                break;
            default://axis
                aRet=SchResId(STR_OBJECT_AXIS);
                break;
        }

        return aRet;
    }

    OUString ObjectNameProvider::getTitleNameByType( TitleHelper::eTitleType eType )
    {
        OUString aRet;

        switch(eType)
        {
            case TitleHelper::MAIN_TITLE:
                aRet=SchResId(STR_OBJECT_TITLE_MAIN);
                break;
            case TitleHelper::SUB_TITLE:
                aRet=SchResId(STR_OBJECT_TITLE_SUB);
                break;
            case TitleHelper::X_AXIS_TITLE:
                aRet=SchResId(STR_OBJECT_TITLE_X_AXIS);
                break;
            case TitleHelper::Y_AXIS_TITLE:
                aRet=SchResId(STR_OBJECT_TITLE_Y_AXIS);
                break;
            case TitleHelper::Z_AXIS_TITLE:
                aRet=SchResId(STR_OBJECT_TITLE_Z_AXIS);
                break;
            case TitleHelper::SECONDARY_X_AXIS_TITLE:
                aRet=SchResId(STR_OBJECT_TITLE_SECONDARY_X_AXIS);
                break;
            case TitleHelper::SECONDARY_Y_AXIS_TITLE:
                aRet=SchResId(STR_OBJECT_TITLE_SECONDARY_Y_AXIS);
                break;
            default:
                OSL_FAIL("unknown title type");
                break;
        }

        if( aRet.isEmpty() )
            aRet=SchResId(STR_OBJECT_TITLE);

        return aRet;
    }

    OUString ObjectNameProvider::getTitleName( const OUString& rObjectCID
                            , const Reference< frame::XModel >& xChartModel )
    {
        OUString aRet;

        Reference< XTitle > xTitle(
            ObjectIdentifier::getObjectPropertySet( rObjectCID , xChartModel ), uno::UNO_QUERY );
        if( xTitle.is() )
        {
            TitleHelper::eTitleType eType;
            if( TitleHelper::getTitleType( eType, xTitle, xChartModel ) )
                aRet = ObjectNameProvider::getTitleNameByType( eType );
        }
        if( aRet.isEmpty() )
            aRet=SchResId(STR_OBJECT_TITLE);

        return aRet;
    }

    OUString ObjectNameProvider::getGridName( const OUString& rObjectCID
                            , const uno::Reference< frame::XModel >& xChartModel )
    {
        OUString aRet;

        sal_Int32 nCooSysIndex = -1;
        sal_Int32 nDimensionIndex = -1;
        sal_Int32 nAxisIndex = -1;
        Reference< XAxis > xAxis( ObjectIdentifier::getAxisForCID( rObjectCID , xChartModel ) );
        AxisHelper::getIndicesForAxis( xAxis, ChartModelHelper::findDiagram( xChartModel )
                  , nCooSysIndex , nDimensionIndex, nAxisIndex );

        bool bMainGrid = (ObjectIdentifier::getObjectType( rObjectCID ) == OBJECTTYPE_GRID);

        if( bMainGrid )
        {
            switch(nDimensionIndex)
            {
                case 0://x-axis
                    aRet=SchResId(STR_OBJECT_GRID_MAJOR_X);
                    break;
                case 1://y-axis
                    aRet=SchResId(STR_OBJECT_GRID_MAJOR_Y);
                    break;
                case 2://z-axis
                    aRet=SchResId(STR_OBJECT_GRID_MAJOR_Z);
                    break;
                default://axis
                    aRet=SchResId(STR_OBJECT_GRID);
                    break;
            }
        }
        else
        {
            switch(nDimensionIndex)
            {
                case 0://x-axis
                    aRet=SchResId(STR_OBJECT_GRID_MINOR_X);
                    break;
                case 1://y-axis
                    aRet=SchResId(STR_OBJECT_GRID_MINOR_Y);
                    break;
                case 2://z-axis
                    aRet=SchResId(STR_OBJECT_GRID_MINOR_Z);
                    break;
                default://axis
                    aRet=SchResId(STR_OBJECT_GRID);
                    break;
            }
        }
        return aRet;
    }

    OUString ObjectNameProvider::getHelpText( const OUString& rObjectCID, const Reference< chart2::XChartDocument >& xChartDocument )
    {
        return getHelpText( rObjectCID, Reference< frame::XModel >( xChartDocument, uno::UNO_QUERY ) );
    }

    OUString ObjectNameProvider::getHelpText( const OUString& rObjectCID, const Reference< frame::XModel >& xChartModel, bool bVerbose )
    {
        OUString aRet;
        ObjectType eObjectType( ObjectIdentifier::getObjectType(rObjectCID) );
        if( eObjectType == OBJECTTYPE_AXIS )
        {
            aRet=ObjectNameProvider::getAxisName( rObjectCID, xChartModel );
        }
        else if( eObjectType == OBJECTTYPE_GRID
            || eObjectType == OBJECTTYPE_SUBGRID )
        {
            aRet=ObjectNameProvider::getGridName( rObjectCID, xChartModel );
        }
        else if( eObjectType == OBJECTTYPE_TITLE )
        {
            aRet=ObjectNameProvider::getTitleName( rObjectCID, xChartModel );
        }
        else if( eObjectType == OBJECTTYPE_DATA_SERIES )
        {
            aRet = lcl_getFullSeriesName( rObjectCID, xChartModel );
        }
        else if( eObjectType == OBJECTTYPE_DATA_POINT )
        {
            if( bVerbose )
            {
                aRet= SchResId(STR_TIP_DATAPOINT_INDEX) + "\n"
                    + SchResId(STR_TIP_DATASERIES) + "\n"
                    + SchResId(STR_TIP_DATAPOINT_VALUES);
            }
            else
                aRet=SchResId(STR_TIP_DATAPOINT);

            Reference< XDiagram > xDiagram( ChartModelHelper::findDiagram( xChartModel ) );
            Reference< XDataSeries > xSeries( ObjectIdentifier::getDataSeriesForCID( rObjectCID , xChartModel ), uno::UNO_QUERY );
            if( xDiagram.is() && xSeries.is() )
            {
                sal_Int32 nPointIndex( ObjectIdentifier::getParticleID(rObjectCID).toInt32() );

                //replace data point index
                OUString aWildcard(  "%POINTNUMBER" );
                sal_Int32 nIndex = aRet.indexOf( aWildcard );
                if( nIndex != -1 )
                {
                    aRet = aRet.replaceAt( nIndex, aWildcard.getLength(), OUString::number(nPointIndex+1) );
                }

                //replace data series index
                aWildcard =  "%SERIESNUMBER";
                nIndex = aRet.indexOf( aWildcard );
                if( nIndex != -1 )
                {
                    std::vector< Reference< chart2::XDataSeries > > aSeriesVector(
                        DiagramHelper::getDataSeriesFromDiagram( xDiagram ) );
                    sal_Int32 nSeriesIndex = -1;
                    for( nSeriesIndex=aSeriesVector.size();nSeriesIndex--;)
                    {
                        if( aSeriesVector[nSeriesIndex] == xSeries )
                        {
                            break;
                        }
                    }

                    OUString aReplacement( OUString::number(nSeriesIndex+1) );
                    aRet = aRet.replaceAt( nIndex, aWildcard.getLength(), aReplacement );
                }

                //replace point values
                aWildcard =  "%POINTVALUES";
                nIndex = aRet.indexOf( aWildcard );
                if( nIndex != -1 )
                    aRet = aRet.replaceAt( nIndex, aWildcard.getLength(), lcl_getDataPointValueText(
                    xSeries,nPointIndex, DataSeriesHelper::getCoordinateSystemOfSeries(xSeries, xDiagram), xChartModel ) );

                //replace series name
                aWildcard = "%SERIESNAME";
                nIndex = aRet.indexOf( aWildcard );
                if( nIndex != -1 )
                    aRet = aRet.replaceAt( nIndex, aWildcard.getLength(), lcl_getDataSeriesName( rObjectCID, xChartModel ) );
            }
        }
        else if( eObjectType == OBJECTTYPE_DATA_CURVE )
        {
            if( bVerbose )
            {
                aRet = SchResId( STR_OBJECT_CURVE_WITH_PARAMETERS );
                Reference< chart2::XDataSeries > xSeries( ObjectIdentifier::getDataSeriesForCID( rObjectCID , xChartModel ));
                Reference< chart2::XRegressionCurveContainer > xCurveCnt( xSeries, uno::UNO_QUERY );

                if( xCurveCnt.is())
                {
                    sal_Int32 nCurveIndex = ObjectIdentifier::getIndexFromParticleOrCID( rObjectCID );
                    Reference< chart2::XRegressionCurve > xCurve( RegressionCurveHelper::getRegressionCurveAtIndex(xCurveCnt, nCurveIndex) );
                    if( xCurve.is())
                    {
                        try
                        {
                            Reference< chart2::XRegressionCurveCalculator > xCalculator( xCurve->getCalculator(), uno::UNO_QUERY_THROW );
                            sal_Int32 aDegree = 2;
                            sal_Int32 aPeriod = 2;
                            bool bForceIntercept = false;
                            double aInterceptValue = 0.0;
                            OUString aXName ("x"), aYName ("f(x)");
                            const LocaleDataWrapper& rLocaleDataWrapper = Application::GetSettings().GetLocaleDataWrapper();
                            const OUString& aNumDecimalSep = rLocaleDataWrapper.getNumDecimalSep();
                            sal_Unicode cDecSeparator = aNumDecimalSep[0];

                            uno::Reference< beans::XPropertySet > xProperties( xCurve, uno::UNO_QUERY );
                            if ( xProperties.is())
                            {
                                    xProperties->getPropertyValue( "PolynomialDegree") >>= aDegree;
                                    xProperties->getPropertyValue( "MovingAveragePeriod") >>= aPeriod;
                                    xProperties->getPropertyValue( "ForceIntercept") >>= bForceIntercept;
                                    if (bForceIntercept)
                                            xProperties->getPropertyValue( "InterceptValue") >>= aInterceptValue;
                                    uno::Reference< beans::XPropertySet > xEqProp( xCurve->getEquationProperties());
                                    if( xEqProp.is())
                                    {
                                        if ( !(xEqProp->getPropertyValue( "XName") >>= aXName) )
                                            aXName = "x";
                                        if ( !(xEqProp->getPropertyValue( "YName") >>= aYName) )
                                            aYName = "f(x)";
                                    }
                            }
                            xCalculator->setRegressionProperties(aDegree, bForceIntercept, aInterceptValue, 2);
                            xCalculator->setXYNames ( aXName, aYName );
                            RegressionCurveHelper::initializeCurveCalculator( xCalculator, xSeries, xChartModel );

                            // change text for Moving Average
                            OUString aWildcard( "%PERIOD" );
                            sal_Int32 nIndex = xCalculator->getRepresentation().indexOf( aWildcard );
                            if( nIndex != -1 )
                            {  // replace period
                                    aRet = xCalculator->getRepresentation();
                                    aRet = aRet.replaceAt( nIndex, aWildcard.getLength(), OUString::number(aPeriod) );
                            }

                            // replace formula
                            aWildcard = "%FORMULA";
                            nIndex = aRet.indexOf( aWildcard );
                            if( nIndex != -1 )
                            {
                                OUString aFormula ( xCalculator->getRepresentation() );
                                if ( cDecSeparator != '.' )
                                {
                                    aFormula = aFormula.replace( '.', cDecSeparator );
                                }
                                aRet = aRet.replaceAt( nIndex, aWildcard.getLength(), aFormula );
                            }

                            // replace r^2
                            aWildcard = "%RSQUARED";
                            nIndex = aRet.indexOf( aWildcard );
                            if( nIndex != -1 )
                            {
                                double fR( xCalculator->getCorrelationCoefficient());
                                aRet = aRet.replaceAt(
                                    nIndex, aWildcard.getLength(),
                                    ::rtl::math::doubleToUString(
                                        fR*fR, rtl_math_StringFormat_G, 4, cDecSeparator, true ));
                            }
                        }
                        catch( const uno::Exception & )
                        {
                            DBG_UNHANDLED_EXCEPTION("chart2");
                        }
                    }
                }
            }
            else
            {
                Reference< chart2::XDataSeries > xSeries( ObjectIdentifier::getDataSeriesForCID(rObjectCID , xChartModel));
                Reference< chart2::XRegressionCurveContainer > xCurveCnt( xSeries, uno::UNO_QUERY );
                aRet += getName(eObjectType);

                if( xCurveCnt.is())
                {
                    sal_Int32 nCurveIndex = ObjectIdentifier::getIndexFromParticleOrCID( rObjectCID );
                    Reference< chart2::XRegressionCurve > xCurve( RegressionCurveHelper::getRegressionCurveAtIndex(xCurveCnt, nCurveIndex) );
                    if( xCurve.is())
                    {
                        aRet += " (" + RegressionCurveHelper::getRegressionCurveName(xCurve) + " )";
                    }
                }
            }
        }
        else if( eObjectType == OBJECTTYPE_DATA_AVERAGE_LINE )
        {
            if( bVerbose )
            {
                aRet = SchResId(STR_OBJECT_AVERAGE_LINE_WITH_PARAMETERS);
                Reference< chart2::XDataSeries > xSeries( ObjectIdentifier::getDataSeriesForCID( rObjectCID , xChartModel ));
                Reference< chart2::XRegressionCurveContainer > xCurveCnt( xSeries, uno::UNO_QUERY );
                if( xCurveCnt.is())
                {
                    Reference< chart2::XRegressionCurve > xCurve( RegressionCurveHelper::getMeanValueLine( xCurveCnt ));
                    if( xCurve.is())
                    {
                        try
                        {
                            Reference< chart2::XRegressionCurveCalculator > xCalculator( xCurve->getCalculator(), uno::UNO_QUERY_THROW );
                            RegressionCurveHelper::initializeCurveCalculator( xCalculator, xSeries, xChartModel );

                            const LocaleDataWrapper& rLocaleDataWrapper = Application::GetSettings().GetLocaleDataWrapper();
                            const OUString& aNumDecimalSep = rLocaleDataWrapper.getNumDecimalSep();
                            sal_Unicode cDecSeparator = aNumDecimalSep[0];

                            OUString aWildcard( "%AVERAGE_VALUE" );
                            sal_Int32 nIndex = aRet.indexOf( aWildcard );
                            // as the curve is constant, the value at any x-value is ok
                            if( nIndex != -1 )
                            {
                                const double fMeanValue( xCalculator->getCurveValue( 0.0 ));
                                aRet = aRet.replaceAt(
                                    nIndex, aWildcard.getLength(),
                                    ::rtl::math::doubleToUString(
                                        fMeanValue, rtl_math_StringFormat_G, 4, cDecSeparator, true ));
                            }

                            // replace standard deviation
                            aWildcard = "%STD_DEVIATION";
                            nIndex = aRet.indexOf( aWildcard );
                            if( nIndex != -1 )
                            {
                                const double fStdDev( xCalculator->getCorrelationCoefficient());
                                aRet = aRet.replaceAt(
                                    nIndex, aWildcard.getLength(),
                                    ::rtl::math::doubleToUString(
                                        fStdDev, rtl_math_StringFormat_G, 4, cDecSeparator, true ));
                            }
                        }
                        catch( const uno::Exception & )
                        {
                            DBG_UNHANDLED_EXCEPTION("chart2");
                        }
                    }
                }
            }
            else
            {
                // non-verbose
                aRet = ObjectNameProvider::getName( eObjectType );
            }
        }
        else
        {
            aRet = ObjectNameProvider::getName( eObjectType );
        }
        return aRet;
    }

    OUString ObjectNameProvider::getSelectedObjectText( const OUString & rObjectCID, const css::uno::Reference< css::chart2::XChartDocument >& xChartDocument )
    {
        OUString aRet;
        ObjectType eObjectType( ObjectIdentifier::getObjectType(rObjectCID) );
        Reference< frame::XModel > xChartModel( xChartDocument, uno::UNO_QUERY );

        if( eObjectType == OBJECTTYPE_DATA_POINT )
        {
            aRet = SchResId( STR_STATUS_DATAPOINT_MARKED );

            Reference< XDiagram > xDiagram( ChartModelHelper::findDiagram( xChartModel ) );
            Reference< XDataSeries > xSeries( ObjectIdentifier::getDataSeriesForCID( rObjectCID , xChartModel ), uno::UNO_QUERY );
            if( xDiagram.is() && xSeries.is() )
            {
                sal_Int32 nPointIndex( ObjectIdentifier::getParticleID(rObjectCID).toInt32() );

                // replace data point index
                replaceParamterInString( aRet, "%POINTNUMBER", OUString::number( nPointIndex + 1 ));

                // replace data series index
                {
                    std::vector< Reference< chart2::XDataSeries > > aSeriesVector(
                        DiagramHelper::getDataSeriesFromDiagram( xDiagram ) );
                    sal_Int32 nSeriesIndex = -1;
                    for( nSeriesIndex=aSeriesVector.size();nSeriesIndex--;)
                    {
                        if( aSeriesVector[nSeriesIndex] == xSeries )
                            break;
                    }
                    replaceParamterInString( aRet, "%SERIESNUMBER", OUString::number( nSeriesIndex + 1 ) );
                }

                // replace point value
                replaceParamterInString( aRet, "%POINTVALUES", lcl_getDataPointValueText(
                    xSeries, nPointIndex, DataSeriesHelper::getCoordinateSystemOfSeries(xSeries, xDiagram), xChartModel ) );
            }
        }
        else
        {
            // use the verbose text including the formula for trend lines
            const bool bVerbose( eObjectType == OBJECTTYPE_DATA_CURVE || eObjectType == OBJECTTYPE_DATA_AVERAGE_LINE );
            const OUString aHelpText( getHelpText( rObjectCID, xChartModel, bVerbose ));
            if( !aHelpText.isEmpty())
            {
                aRet = SchResId( STR_STATUS_OBJECT_MARKED );
                replaceParamterInString( aRet, "%OBJECTNAME", aHelpText );
            }
        }

        return aRet;
    }

    OUString ObjectNameProvider::getNameForCID(
        const OUString& rObjectCID,
        const uno::Reference< chart2::XChartDocument >& xChartDocument )
    {
        ObjectType eType( ObjectIdentifier::getObjectType( rObjectCID ));
        Reference< frame::XModel > xModel( xChartDocument, uno::UNO_QUERY );

        switch( eType )
        {
            case OBJECTTYPE_AXIS:
                return getAxisName( rObjectCID, xModel );
            case OBJECTTYPE_TITLE:
                return getTitleName( rObjectCID, xModel );
            case OBJECTTYPE_GRID:
            case OBJECTTYPE_SUBGRID:
                return getGridName( rObjectCID, xModel );
            case OBJECTTYPE_DATA_SERIES:
                return lcl_getFullSeriesName( rObjectCID, xModel );
            case OBJECTTYPE_DATA_POINT:
            case OBJECTTYPE_DATA_LABELS:
            case OBJECTTYPE_DATA_LABEL:
            case OBJECTTYPE_DATA_ERRORS_X:
            case OBJECTTYPE_DATA_ERRORS_Y:
            case OBJECTTYPE_DATA_ERRORS_Z:
            case OBJECTTYPE_DATA_AVERAGE_LINE:
            case OBJECTTYPE_DATA_CURVE:
            case OBJECTTYPE_DATA_CURVE_EQUATION:
                {
                    OUString aRet = lcl_getFullSeriesName( rObjectCID, xModel ) + " ";
                    if( eType == OBJECTTYPE_DATA_POINT || eType == OBJECTTYPE_DATA_LABEL )
                    {
                        aRet += getName( OBJECTTYPE_DATA_POINT  );
                        sal_Int32 nPointIndex = ObjectIdentifier::getIndexFromParticleOrCID( rObjectCID );
                        aRet += " " + OUString::number(nPointIndex+1);
                        if( eType == OBJECTTYPE_DATA_LABEL )
                        {
                            aRet += " " + getName( OBJECTTYPE_DATA_LABEL  );
                        }
                    }
                    else if (eType == OBJECTTYPE_DATA_CURVE || eType == OBJECTTYPE_DATA_CURVE_EQUATION)
                    {
                        Reference< chart2::XDataSeries > xSeries( ObjectIdentifier::getDataSeriesForCID( rObjectCID , xModel ));
                        Reference< chart2::XRegressionCurveContainer > xCurveCnt( xSeries, uno::UNO_QUERY );

                        aRet += " " + getName(eType);

                        if( xCurveCnt.is())
                        {
                            sal_Int32 nCurveIndex = ObjectIdentifier::getIndexFromParticleOrCID( rObjectCID );
                            Reference< chart2::XRegressionCurve > xCurve( RegressionCurveHelper::getRegressionCurveAtIndex(xCurveCnt, nCurveIndex) );
                            if( xCurve.is())
                            {
                               aRet += " (" + RegressionCurveHelper::getRegressionCurveName(xCurve) + ")";
                            }
                        }
                    }
                    else
                    {
                        aRet += getName( eType );
                    }
                    return aRet;
                }
            default:
                break;
        }

        return getName( eType );
    }

    OUString ObjectNameProvider::getName_ObjectForSeries(
            ObjectType eObjectType,
            const OUString& rSeriesCID,
            const uno::Reference< chart2::XChartDocument >& xChartDocument )
    {
        uno::Reference< frame::XModel> xChartModel( xChartDocument, uno::UNO_QUERY );
        Reference< XDataSeries > xSeries( ObjectIdentifier::getDataSeriesForCID( rSeriesCID , xChartModel ), uno::UNO_QUERY );
        if( xSeries.is() )
        {
            OUString aRet = SchResId(STR_OBJECT_FOR_SERIES);
            replaceParamterInString( aRet, "%OBJECTNAME", getName( eObjectType ) );
            replaceParamterInString( aRet, "%SERIESNAME", lcl_getDataSeriesName( rSeriesCID, xChartModel ) );
            return aRet;
        }
        else
            return ObjectNameProvider::getName_ObjectForAllSeries( eObjectType );
    }

    OUString ObjectNameProvider::getName_ObjectForAllSeries( ObjectType eObjectType )
    {
        OUString aRet = SchResId(STR_OBJECT_FOR_ALL_SERIES);
        replaceParamterInString( aRet, "%OBJECTNAME", getName( eObjectType, true /*bPlural*/ ) );
        return aRet;
    }

    } //namespace chart

    /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

↑ V547 Expression 'bForceIntercept' is always false.