Quellcodebibliothek Statistik Leitseite products/Sources/formale Sprachen/C/LibreOffice/xmloff/source/chart/   (Office von Apache Version 25.8.3.2©)  Datei vom 5.10.2025 mit Größe 35 kB image not shown  

Quelle  SchXMLAxisContext.cxx   Sprache: C

 
/* -*- 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 <sax/tools/converter.hxx>

#include "SchXMLAxisContext.hxx"
#include "SchXMLChartContext.hxx"
#include "SchXMLTools.hxx"
#include <xmloff/xmlimp.hxx>
#include <xmloff/xmlnamespace.hxx>
#include <xmloff/xmlement.hxx>
#include <xmloff/xmlstyle.hxx>
#include <xmloff/prstylei.hxx>
#include <xmloff/xmluconv.hxx>

#include <rtl/math.hxx>
#include <tools/color.hxx>
#include <sal/log.hxx>

#include <com/sun/star/chart/ChartAxisLabelPosition.hpp>
#include <com/sun/star/chart/ChartAxisMarkPosition.hpp>
#include <com/sun/star/chart/ChartAxisPosition.hpp>
#include <com/sun/star/chart/ChartAxisType.hpp>
#include <com/sun/star/chart/TimeIncrement.hpp>
#include <com/sun/star/chart/TimeInterval.hpp>
#include <com/sun/star/chart/TimeUnit.hpp>
#include <com/sun/star/chart/XAxis.hpp>
#include <com/sun/star/chart/XAxisSupplier.hpp>
#include <com/sun/star/chart/XChartDocument.hpp>
#include <com/sun/star/chart2/AxisType.hpp>
#include <com/sun/star/chart2/XChartDocument.hpp>
#include <com/sun/star/chart2/XCoordinateSystemContainer.hpp>

#include <com/sun/star/drawing/LineStyle.hpp>

using namespace ::xmloff::token;
using namespace com::sun::star;

using com::sun::star::uno::Reference;

const SvXMLEnumMapEntry<SchXMLAxisDimension> aXMLAxisDimensionMap[] =
{
    { XML_X,  SCH_XML_AXIS_X  },
    { XML_Y,  SCH_XML_AXIS_Y  },
    { XML_Z,  SCH_XML_AXIS_Z  },
    { XML_TOKEN_INVALID, SchXMLAxisDimension(0) }
};

const SvXMLEnumMapEntry<sal_uInt16> aXMLAxisTypeMap[] =
{
    { XML_AUTO,  css::chart::ChartAxisType::AUTOMATIC },
    { XML_TEXT,  css::chart::ChartAxisType::CATEGORY },
    { XML_DATE,  css::chart::ChartAxisType::DATE },
    { XML_TOKEN_INVALID, 0 }
};

namespace {

class SchXMLCategoriesContext : public SvXMLImportContext
{
private:
    OUString& mrAddress;

public:
    SchXMLCategoriesContext( SvXMLImport& rImport,
                                   OUString& rAddress );
    virtual void SAL_CALL startFastElement( sal_Int32 nElement,
        const css::uno::Reference< css::xml::sax::XFastAttributeList >& xAttrList ) override;
};

class DateScaleContext : public SvXMLImportContext
{
public:
    DateScaleContext( SvXMLImport& rImport,
                        const Reference< beans::XPropertySet >& rAxisProps );

    virtual void SAL_CALL startFastElement( sal_Int32 nElement,
        const css::uno::Reference< css::xml::sax::XFastAttributeList >& xAttrList ) override;

private:
    Reference< beans::XPropertySet > m_xAxisProps;
};

}

SchXMLAxisContext::SchXMLAxisContext( SchXMLImportHelper& rImpHelper,
                                      SvXMLImport& rImport,
                                      Reference< chart::XDiagram > const & xDiagram,
                                      std::vector< SchXMLAxis >& rAxes,
                                      OUString & rCategoriesAddress,
                                      bool bAddMissingXAxisForNetCharts,
                                      bool bAdaptWrongPercentScaleValues,
                                      bool bAdaptXAxisOrientationForOld2DBarCharts,
                                      bool& rbAxisPositionAttributeImported ) :
        SvXMLImportContext( rImport ),
        m_rImportHelper( rImpHelper ),
        m_xDiagram( xDiagram ),
        m_rAxes( rAxes ),
        m_rCategoriesAddress( rCategoriesAddress ),
        m_nAxisType(chart::ChartAxisType::AUTOMATIC),
        m_bAxisTypeImported(false),
        m_bDateScaleImported(false),
        m_bAddMissingXAxisForNetCharts( bAddMissingXAxisForNetCharts ),
        m_bAdaptWrongPercentScaleValues( bAdaptWrongPercentScaleValues ),
        m_bAdaptXAxisOrientationForOld2DBarCharts( bAdaptXAxisOrientationForOld2DBarCharts ),
        m_rbAxisPositionAttributeImported( rbAxisPositionAttributeImported )
{
}

SchXMLAxisContext::~SchXMLAxisContext()
{}

static Reference< chart::XAxis > lcl_getChartAxis(const SchXMLAxis& rCurrentAxis, const Reference< chart::XDiagram >& rDiagram )
{
    Reference< chart::XAxis > xAxis;
    Reference< chart::XAxisSupplier > xAxisSuppl( rDiagram, uno::UNO_QUERY );
    if( !xAxisSuppl.is() )
        return xAxis;
    if( rCurrentAxis.nAxisIndex == 0 )
        xAxis = xAxisSuppl->getAxis(rCurrentAxis.eDimension);
    else
        xAxis = xAxisSuppl->getSecondaryAxis(rCurrentAxis.eDimension);
    return xAxis;
}

/* returns a shape for the current axis's title. The property
   "Has...AxisTitle" is set to "True" to get the shape
 */

Reference< drawing::XShape > SchXMLAxisContext::getTitleShape() const
{
    Reference< drawing::XShape > xResult;
    Reference< beans::XPropertySet > xDiaProp( m_rImportHelper.GetChartDocument()->getDiagram(), uno::UNO_QUERY );
    Reference< chart::XAxis > xAxis( lcl_getChartAxis( m_aCurrentAxis, m_xDiagram ) );
    if( !xDiaProp.is() || !xAxis.is() )
        return xResult;

    OUString aPropName;
    switch( m_aCurrentAxis.eDimension )
    {
        case SCH_XML_AXIS_X:
            if( m_aCurrentAxis.nAxisIndex == 0 )
                aPropName = "HasXAxisTitle";
            else
                aPropName = "HasSecondaryXAxisTitle";
            break;
        case SCH_XML_AXIS_Y:
            if( m_aCurrentAxis.nAxisIndex == 0 )
                aPropName = "HasYAxisTitle";
            else
                aPropName = "HasSecondaryYAxisTitle";
            break;
        case SCH_XML_AXIS_Z:
            aPropName = "HasZAxisTitle";
            break;
        case SCH_XML_AXIS_UNDEF:
            SAL_INFO("xmloff.chart""Invalid axis" );
            break;
    }
    xDiaProp->setPropertyValue( aPropName, uno::Any(true) );
    xResult.set( xAxis->getAxisTitle(), uno::UNO_QUERY );
    return xResult;
}

void SchXMLAxisContext::CreateGrid( const OUString& sAutoStyleName, bool bIsMajor )
{
    Reference< beans::XPropertySet > xDiaProp( m_rImportHelper.GetChartDocument()->getDiagram(), uno::UNO_QUERY );
    Reference< chart::XAxis > xAxis( lcl_getChartAxis( m_aCurrentAxis, m_xDiagram ) );
    if( !xDiaProp.is() || !xAxis.is() )
        return;

    OUString aPropName;
    switch( m_aCurrentAxis.eDimension )
    {
        case SCH_XML_AXIS_X:
            if( bIsMajor )
                aPropName = "HasXAxisGrid";
            else
                aPropName = "HasXAxisHelpGrid";
            break;
        case SCH_XML_AXIS_Y:
            if( bIsMajor )
                aPropName = "HasYAxisGrid";
            else
                aPropName = "HasYAxisHelpGrid";
            break;
        case SCH_XML_AXIS_Z:
            if( bIsMajor )
                aPropName = "HasZAxisGrid";
            else
                aPropName = "HasZAxisHelpGrid";
            break;
        case SCH_XML_AXIS_UNDEF:
            SAL_INFO("xmloff.chart""Invalid axis" );
            break;
    }
    xDiaProp->setPropertyValue( aPropName, uno::Any(true) );

    Reference< beans::XPropertySet > xGridProp;
    if( bIsMajor )
        xGridProp = xAxis->getMajorGrid();
    else
        xGridProp = xAxis->getMinorGrid();

    // set properties
    if( xGridProp.is())
    {
        // the line color is black as default, in the model it is a light gray
        xGridProp->setPropertyValue(u"LineColor"_ustr,
                                     uno::Any( COL_BLACK ));
        if (!sAutoStyleName.isEmpty())
            m_rImportHelper.FillAutoStyle(sAutoStyleName, xGridProp);
    }
}

void SchXMLAxisContext::startFastElement( sal_Int32 /*nElement*/,
    const css::uno::Reference< css::xml::sax::XFastAttributeList >& xAttrList )
{
    // parse attributes
    forauto& aIter : sax_fastparser::castToFastAttributeList(xAttrList) )
    {
        switch(aIter.getToken())
        {
            case XML_ELEMENT(CHART, XML_DIMENSION):
                {
                    SchXMLAxisDimension nEnumVal;
                    if( SvXMLUnitConverter::convertEnum( nEnumVal, aIter.toView(), aXMLAxisDimensionMap ))
                        m_aCurrentAxis.eDimension = nEnumVal;
                }
                break;
            case XML_ELEMENT(CHART, XML_NAME):
                m_aCurrentAxis.aName = aIter.toString();
                break;
            case XML_ELEMENT(CHART, XML_AXIS_TYPE):
            case XML_ELEMENT(CHART_EXT, XML_AXIS_TYPE):
                sal_uInt16 nEnumVal;
                if( SvXMLUnitConverter::convertEnum( nEnumVal, aIter.toView(), aXMLAxisTypeMap ))
                {
                    m_nAxisType = nEnumVal;
                    m_bAxisTypeImported = true;
                }
                break;
            case XML_ELEMENT(CHART, XML_STYLE_NAME):
                m_aAutoStyleName = aIter.toString();
                break;
            default:
                XMLOFF_WARN_UNKNOWN("xmloff", aIter);
        }
    }

    // check for number of axes with same dimension
    m_aCurrentAxis.nAxisIndex = 0;
    sal_Int32 nNumOfAxes = m_rAxes.size();
    for( sal_Int32 nCurrent = 0; nCurrent < nNumOfAxes; nCurrent++ )
    {
        if( m_rAxes[ nCurrent ].eDimension == m_aCurrentAxis.eDimension )
            m_aCurrentAxis.nAxisIndex++;
    }
    CreateAxis();
}
namespace
{

Reference< chart2::XAxis > lcl_getAxis( const Reference< frame::XModel >& xChartModel,
                                            sal_Int32 nDimensionIndex, sal_Int32 nAxisIndex )
{
    Reference< chart2::XAxis > xAxis;

    try
    {
        Reference< chart2::XChartDocument > xChart2Document( xChartModel, uno::UNO_QUERY );
        if( xChart2Document.is() )
        {
            Reference< chart2::XDiagram > xDiagram( xChart2Document->getFirstDiagram());
            Reference< chart2::XCoordinateSystemContainer > xCooSysCnt( xDiagram, uno::UNO_QUERY_THROW );
            uno::Sequence< Reference< chart2::XCoordinateSystem > >
                aCooSysSeq( xCooSysCnt->getCoordinateSystems());
            sal_Int32 nCooSysIndex = 0;
            if( nCooSysIndex < aCooSysSeq.getLength() )
            {
                const Reference< chart2::XCoordinateSystem >& xCooSys( aCooSysSeq[nCooSysIndex] );
                if( xCooSys.is() && nDimensionIndex < xCooSys->getDimension() )
                {
                    const sal_Int32 nMaxAxisIndex = xCooSys->getMaximumAxisIndexByDimension(nDimensionIndex);
                    if( nAxisIndex <= nMaxAxisIndex )
                        xAxis = xCooSys->getAxisByDimension( nDimensionIndex, nAxisIndex );
                }
            }
        }
    }
    catch( uno::Exception & )
    {
        SAL_INFO("xmloff.chart""Couldn't get axis" );
    }

    return xAxis;
}

bool lcl_divideBy100( uno::Any& rDoubleAny )
{
    bool bChanged = false;
    double fValue=0.0;
    if( (rDoubleAny>>=fValue) && (fValue!=0.0) )
    {
        fValue/=100.0;
        rDoubleAny <<= fValue;
        bChanged = true;
    }
    return bChanged;
}

bool lcl_AdaptWrongPercentScaleValues(chart2::ScaleData& rScaleData)
{
    bool bChanged = lcl_divideBy100( rScaleData.Minimum );
    bChanged = lcl_divideBy100( rScaleData.Maximum ) || bChanged;
    bChanged = lcl_divideBy100( rScaleData.Origin ) || bChanged;
    bChanged = lcl_divideBy100( rScaleData.IncrementData.Distance ) || bChanged;
    return bChanged;
}

}//end anonymous namespace

void SchXMLAxisContext::CreateAxis()
{
    m_rAxes.push_back( m_aCurrentAxis );

    Reference< beans::XPropertySet > xDiaProp( m_rImportHelper.GetChartDocument()->getDiagram(), uno::UNO_QUERY );
    if( !xDiaProp.is() )
        return;
    OUString aPropName;
    switch( m_aCurrentAxis.eDimension )
    {
        case SCH_XML_AXIS_X:
            if( m_aCurrentAxis.nAxisIndex == 0 )
                aPropName = "HasXAxis";
            else
                aPropName = "HasSecondaryXAxis";
            break;
        case SCH_XML_AXIS_Y:
            if( m_aCurrentAxis.nAxisIndex == 0 )
                aPropName = "HasYAxis";
            else
                aPropName = "HasSecondaryYAxis";
            break;
        case SCH_XML_AXIS_Z:
            if( m_aCurrentAxis.nAxisIndex == 0 )
                aPropName = "HasZAxis";
            break;
        case SCH_XML_AXIS_UNDEF:
            SAL_INFO("xmloff.chart""Invalid axis" );
            break;
    }
    try
    {
        xDiaProp->setPropertyValue( aPropName, uno::Any(true) );
    }
    catch( beans::UnknownPropertyException & )
    {
        SAL_INFO("xmloff.chart""Couldn't turn on axis" );
    }
    if( m_aCurrentAxis.eDimension==SCH_XML_AXIS_Z )
    {
        bool bSettingZAxisSucceeded = false;
        try
        {
            xDiaProp->getPropertyValue( aPropName ) >>= bSettingZAxisSucceeded;
        }
        catch( beans::UnknownPropertyException & )
        {
            SAL_INFO("xmloff.chart""Couldn't turn on z axis" );
        }
        if( !bSettingZAxisSucceeded )
            return;
    }

    m_xAxisProps.set( lcl_getChartAxis( m_aCurrentAxis, m_xDiagram ), uno::UNO_QUERY );

    if( m_bAddMissingXAxisForNetCharts && m_aCurrentAxis.eDimension==SCH_XML_AXIS_Y && m_aCurrentAxis.nAxisIndex==0 )
    {
        try
        {
            xDiaProp->setPropertyValue(u"HasXAxis"_ustr, uno::Any(true) );
        }
        catch( beans::UnknownPropertyException & )
        {
            SAL_INFO("xmloff.chart""Couldn't turn on x axis" );
        }
    }

    // set properties
    if( !m_xAxisProps.is())
        return;

    uno::Any aTrueBool( uno::Any( true ));
    uno::Any aFalseBool( uno::Any( false ));

    // #i109879# the line color is black as default, in the model it is a light gray
    m_xAxisProps->setPropertyValue(u"LineColor"_ustr,
                                 uno::Any( COL_BLACK ));

    m_xAxisProps->setPropertyValue(u"DisplayLabels"_ustr, aFalseBool );

    // Compatibility option: starting from LibreOffice 5.1 the rotated
    // layout is preferred to staggering for axis labels.
    // So the import default value for having compatibility with ODF
    // documents created with earlier LibreOffice versions is `true`.
    if( GetImport().getGeneratorVersion() != SvXMLImport::ProductVersionUnknown )
        m_xAxisProps->setPropertyValue(u"TryStaggeringFirst"_ustr, aTrueBool );

    // #88077# AutoOrigin 'on' is default
    m_xAxisProps->setPropertyValue(u"AutoOrigin"_ustr, aTrueBool );

    if( m_bAxisTypeImported )
        m_xAxisProps->setPropertyValue(u"AxisType"_ustr, uno::Any(m_nAxisType) );

    if( !m_aAutoStyleName.isEmpty())
    {
        const SvXMLStylesContext* pStylesCtxt = m_rImportHelper.GetAutoStylesContext();
        if (pStylesCtxt)
        {
            SvXMLStyleContext* pStyle = const_cast<SvXMLStyleContext*>(pStylesCtxt->FindStyleChildContext(SchXMLImportHelper::GetChartFamilyID(), m_aAutoStyleName));

            if (XMLPropStyleContext * pPropStyleContext = dynamic_cast<XMLPropStyleContext*>(pStyle))
            {
                pPropStyleContext->FillPropertySet(m_xAxisProps);

                if( m_bAdaptWrongPercentScaleValues && m_aCurrentAxis.eDimension==SCH_XML_AXIS_Y )
                {
                    //set scale data of added x axis back to default
                    Reference< chart2::XAxis > xAxis( lcl_getAxis( GetImport().GetModel(),
                                        m_aCurrentAxis.eDimension, m_aCurrentAxis.nAxisIndex ) );
                    if( xAxis.is() )
                    {
                        chart2::ScaleData aScaleData( xAxis->getScaleData());
                        if( lcl_AdaptWrongPercentScaleValues(aScaleData) )
                            xAxis->setScaleData( aScaleData );
                    }
                }

                if( m_bAddMissingXAxisForNetCharts )
                {
                    //copy style from y axis to added x axis:

                    Reference< chart::XAxisSupplier > xAxisSuppl( xDiaProp, uno::UNO_QUERY );
                    if( xAxisSuppl.is() )
                    {
                        Reference< beans::XPropertySet > xXAxisProp( xAxisSuppl->getAxis(0), uno::UNO_QUERY );
                        pPropStyleContext->FillPropertySet(xXAxisProp);
                    }

                    //set scale data of added x axis back to default
                    Reference< chart2::XAxis > xAxis( lcl_getAxis( GetImport().GetModel(),
                                        0 /*nDimensionIndex*/, 0 /*nAxisIndex*/ ) );
                    if( xAxis.is() )
                    {
                        chart2::ScaleData aScaleData;
                        aScaleData.AxisType = chart2::AxisType::CATEGORY;
                        aScaleData.Orientation = chart2::AxisOrientation_MATHEMATICAL;
                        xAxis->setScaleData( aScaleData );
                    }

                    //set line style of added x axis to invisible
                    Reference< beans::XPropertySet > xNewAxisProp( xAxis, uno::UNO_QUERY );
                    if( xNewAxisProp.is() )
                    {
                        xNewAxisProp->setPropertyValue(u"LineStyle"_ustr
                            , uno::Any(drawing::LineStyle_NONE));
                    }
                }

                if( m_bAdaptXAxisOrientationForOld2DBarCharts && m_aCurrentAxis.eDimension == SCH_XML_AXIS_X )
                {
                    bool bIs3DChart = false;
                    if( xDiaProp.is() && ( xDiaProp->getPropertyValue(u"Dim3D"_ustr) >>= bIs3DChart )
                        && !bIs3DChart )
                    {
                        Reference< chart2::XChartDocument > xChart2Document( GetImport().GetModel(), uno::UNO_QUERY );
                        if( xChart2Document.is() )
                        {
                            Reference< chart2::XCoordinateSystemContainer > xCooSysCnt( xChart2Document->getFirstDiagram(), uno::UNO_QUERY );
                            if( xCooSysCnt.is() )
                            {
                                uno::Sequence< Reference< chart2::XCoordinateSystem > > aCooSysSeq( xCooSysCnt->getCoordinateSystems() );
                                if( aCooSysSeq.hasElements() )
                                {
                                    bool bSwapXandYAxis = false;
                                    const Reference< chart2::XCoordinateSystem >& xCooSys( aCooSysSeq[0] );
                                    Reference< beans::XPropertySet > xCooSysProp( xCooSys, uno::UNO_QUERY );
                                    if( xCooSysProp.is() && ( xCooSysProp->getPropertyValue(u"SwapXAndYAxis"_ustr) >>= bSwapXandYAxis )
                                        && bSwapXandYAxis )
                                    {
                                        Reference< chart2::XAxis > xAxis = xCooSys->getAxisByDimension( 0, m_aCurrentAxis.nAxisIndex );
                                        if( xAxis.is() )
                                        {
                                            chart2::ScaleData aScaleData = xAxis->getScaleData();
                                            aScaleData.Orientation = chart2::AxisOrientation_REVERSE;
                                            xAxis->setScaleData( aScaleData );
                                        }
                                    }
                                }
                            }
                        }
                    }
                }

                m_rbAxisPositionAttributeImported = m_rbAxisPositionAttributeImported || SchXMLTools::getPropertyFromContext(
                    u"CrossoverPosition", pPropStyleContext, pStylesCtxt ).hasValue();
            }
        }
    }

    if (m_aCurrentAxis.eDimension != SCH_XML_AXIS_X)
        return;

    Reference<chart2::XAxis> xAxis(lcl_getAxis(GetImport().GetModel(), m_aCurrentAxis.eDimension, m_aCurrentAxis.nAxisIndex));
    if (!xAxis.is())
        return;

    chart2::ScaleData aScaleData(xAxis->getScaleData());
    bool bIs3DChart = false;
    double fMajorOrigin = -1;
    OUString sChartType = m_xDiagram->getDiagramType();
    if ((xDiaProp->getPropertyValue(u"Dim3D"_ustr) >>= bIs3DChart) && bIs3DChart
        && (sChartType == "com.sun.star.chart.BarDiagram" || sChartType == "com.sun.star.chart.StockDiagram"))
    {
        aScaleData.ShiftedCategoryPosition = true;
        xAxis->setScaleData(aScaleData);
    }
    else if ((m_xAxisProps->getPropertyValue(u"MajorOrigin"_ustr) >>= fMajorOrigin)
            && (rtl::math::approxEqual(fMajorOrigin, 0.0) || rtl::math::approxEqual(fMajorOrigin, 0.5)))
    {
        aScaleData.ShiftedCategoryPosition = rtl::math::approxEqual(fMajorOrigin, 0.5);
        xAxis->setScaleData(aScaleData);
        m_xAxisProps->setPropertyValue(u"MajorOrigin"_ustr, uno::Any());
    }
}

void SchXMLAxisContext::SetAxisTitle()
{
    if( m_aCurrentAxis.maTitle.empty() )
        return;

    Reference< chart::XAxis > xAxis( lcl_getChartAxis( m_aCurrentAxis, m_xDiagram ) );
    if( !xAxis.is() )
        return;

    if (m_aCurrentAxis.maTitle.back().first.isEmpty() &&
        m_aCurrentAxis.maTitle.back().second == OUStringChar(u'\x0D'))
        m_aCurrentAxis.maTitle.pop_back(); // remove last end of paragraph break

    SchXMLTools::importFormattedText(GetImport(), m_aCurrentAxis.maTitle, xAxis->getAxisTitle());
}

css::uno::Reference< css::xml::sax::XFastContextHandler > SchXMLAxisContext::createFastChildContext(
    sal_Int32 nElement,
    const css::uno::Reference< css::xml::sax::XFastAttributeList >& xAttrList )
{
    switch( nElement )
    {
        case XML_ELEMENT(CHART, XML_TITLE):
        {
            return new SchXMLTitleContext( m_rImportHelper, GetImport(),
                                               m_aCurrentAxis.maTitle,
                                               getTitleShape() );
        }
        break;

        case XML_ELEMENT(CHART, XML_CATEGORIES):
            m_aCurrentAxis.bHasCategories = true;
            return new SchXMLCategoriesContext( GetImport(),
                                                m_rCategoriesAddress );
            break;

        case  XML_ELEMENT(CHART, XML_DATE_SCALE):
        case  XML_ELEMENT(CHART_EXT, XML_DATE_SCALE):
            m_bDateScaleImported = true;
            return new DateScaleContext( GetImport(), m_xAxisProps );

        case XML_ELEMENT(CHART, XML_GRID):
        {
            bool bIsMajor = true;       // default value for class is "major"
            OUString sAutoStyleName;

            forauto& aIter : sax_fastparser::castToFastAttributeList(xAttrList) )
            {
                switch (aIter.getToken())
                {
                    case XML_ELEMENT(CHART, XML_CLASS):
                        if( IsXMLToken( aIter, XML_MINOR ) )
                            bIsMajor = false;
                        break;
                    case XML_ELEMENT(CHART, XML_STYLE_NAME):
                        sAutoStyleName = aIter.toString();
                        break;
                    default:
                        XMLOFF_WARN_UNKNOWN("xmloff", aIter);
                }
            }

            CreateGrid( sAutoStyleName, bIsMajor );

            // don't create a context => use default context. grid elements are empty
        }
        break;

        default:
            XMLOFF_WARN_UNKNOWN_ELEMENT("xmloff", nElement);
            break;
    }

    return nullptr;
}

void SchXMLAxisContext::endFastElement(sal_Int32 )
{
    if( !m_bDateScaleImported && m_nAxisType==chart::ChartAxisType::AUTOMATIC )
    {
        Reference< chart2::XAxis > xAxis( lcl_getAxis( GetImport().GetModel(), m_aCurrentAxis.eDimension, m_aCurrentAxis.nAxisIndex ) );
        if( xAxis.is() )
        {
            chart2::ScaleData aScaleData( xAxis->getScaleData());
            aScaleData.AutoDateAxis = false;//different default for older documents
            xAxis->setScaleData( aScaleData );
        }
    }

    SetAxisTitle();
}

namespace
{

Reference< chart2::XAxis > lcl_getAxis( const Reference< chart2::XCoordinateSystem >& rCooSys, sal_Int32 nDimensionIndex, sal_Int32 nAxisIndex )
{
    Reference< chart2::XAxis > xAxis;
    try
    {
        xAxis = rCooSys->getAxisByDimension( nDimensionIndex, nAxisIndex );
    }
    catch( uno::Exception & )
    {
    }
    return xAxis;
}

// anonymous namespace

void SchXMLAxisContext::CorrectAxisPositions( const Reference< chart2::XChartDocument >&&nbsp;xNewDoc,
                          std::u16string_view rChartTypeServiceName,
                          std::u16string_view rODFVersionOfFile,
                          bool bAxisPositionAttributeImported )
{
    if( !(rODFVersionOfFile.empty() || rODFVersionOfFile == u"1.0" || rODFVersionOfFile == u"1.1"
        || ( rODFVersionOfFile == u"1.2" && !bAxisPositionAttributeImported )) )
        return;

    try
    {
        Reference< chart2::XCoordinateSystemContainer > xCooSysCnt( xNewDoc->getFirstDiagram(), uno::UNO_QUERY_THROW );
        uno::Sequence< Reference< chart2::XCoordinateSystem > > aCooSysSeq( xCooSysCnt->getCoordinateSystems());
        if( aCooSysSeq.hasElements() )
        {
            const Reference< chart2::XCoordinateSystem >& xCooSys( aCooSysSeq[0] );
            if( xCooSys.is() )
            {
                Reference< chart2::XAxis > xMainXAxis = lcl_getAxis( xCooSys, 0, 0 );
                Reference< chart2::XAxis > xMainYAxis = lcl_getAxis( xCooSys, 1, 0 );
                //Reference< chart2::XAxis > xMajorZAxis = lcl_getAxis( xCooSys, 2, 0 );
                Reference< chart2::XAxis > xSecondaryXAxis = lcl_getAxis( xCooSys, 0, 1 );
                Reference< chart2::XAxis > xSecondaryYAxis = lcl_getAxis( xCooSys, 1, 1 );

                Reference< beans::XPropertySet > xMainXAxisProp( xMainXAxis, uno::UNO_QUERY );
                Reference< beans::XPropertySet > xMainYAxisProp( xMainYAxis, uno::UNO_QUERY );
                Reference< beans::XPropertySet > xSecondaryXAxisProp( xSecondaryXAxis, uno::UNO_QUERY );
                Reference< beans::XPropertySet > xSecondaryYAxisProp( xSecondaryYAxis, uno::UNO_QUERY );

                if( xMainXAxisProp.is() && xMainYAxisProp.is() )
                {
                    chart2::ScaleData aMainXScale = xMainXAxis->getScaleData();
                    if( rChartTypeServiceName == u"com.sun.star.chart2.ScatterChartType" )
                    {
                        xMainYAxisProp->setPropertyValue(u"CrossoverPosition"_ustr
                                , uno::Any( css::chart::ChartAxisPosition_VALUE) );
                        double fCrossoverValue = 0.0;
                        aMainXScale.Origin >>= fCrossoverValue;
                        xMainYAxisProp->setPropertyValue(u"CrossoverValue"_ustr
                                , uno::Any( fCrossoverValue ) );

                        if( aMainXScale.Orientation == chart2::AxisOrientation_REVERSE )
                        {
                            xMainYAxisProp->setPropertyValue(u"LabelPosition"_ustr
                                , uno::Any( css::chart::ChartAxisLabelPosition_OUTSIDE_END) );
                            xMainYAxisProp->setPropertyValue(u"MarkPosition"_ustr
                                , uno::Any( css::chart::ChartAxisMarkPosition_AT_LABELS) );
                            if( xSecondaryYAxisProp.is() )
                                xSecondaryYAxisProp->setPropertyValue(u"CrossoverPosition"_ustr
                                , uno::Any( css::chart::ChartAxisPosition_START) );
                        }
                        else
                        {
                            xMainYAxisProp->setPropertyValue(u"LabelPosition"_ustr
                                , uno::Any( css::chart::ChartAxisLabelPosition_OUTSIDE_START) );
                            xMainYAxisProp->setPropertyValue(u"MarkPosition"_ustr
                                , uno::Any( css::chart::ChartAxisMarkPosition_AT_LABELS) );
                            if( xSecondaryYAxisProp.is() )
                                xSecondaryYAxisProp->setPropertyValue(u"CrossoverPosition"_ustr
                                , uno::Any( css::chart::ChartAxisPosition_END) );
                        }
                    }
                    else
                    {
                        if( aMainXScale.Orientation == chart2::AxisOrientation_REVERSE )
                        {
                            xMainYAxisProp->setPropertyValue(u"CrossoverPosition"_ustr
                                , uno::Any( css::chart::ChartAxisPosition_END) );
                            if( xSecondaryYAxisProp.is() )
                                xSecondaryYAxisProp->setPropertyValue(u"CrossoverPosition"_ustr
                                    , uno::Any( css::chart::ChartAxisPosition_START) );
                        }
                        else
                        {
                            xMainYAxisProp->setPropertyValue(u"CrossoverPosition"_ustr
                                , uno::Any( css::chart::ChartAxisPosition_START) );
                            if( xSecondaryYAxisProp.is() )
                                xSecondaryYAxisProp->setPropertyValue(u"CrossoverPosition"_ustr
                                    , uno::Any( css::chart::ChartAxisPosition_END) );
                        }
                    }

                    chart2::ScaleData aMainYScale = xMainYAxis->getScaleData();
                    xMainXAxisProp->setPropertyValue(u"CrossoverPosition"_ustr
                            , uno::Any( css::chart::ChartAxisPosition_VALUE) );
                    double fCrossoverValue = 0.0;
                    aMainYScale.Origin >>= fCrossoverValue;
                    xMainXAxisProp->setPropertyValue(u"CrossoverValue"_ustr
                            , uno::Any( fCrossoverValue ) );

                    if( aMainYScale.Orientation == chart2::AxisOrientation_REVERSE )
                    {
                        xMainXAxisProp->setPropertyValue(u"LabelPosition"_ustr
                            , uno::Any( css::chart::ChartAxisLabelPosition_OUTSIDE_END) );
                        xMainXAxisProp->setPropertyValue(u"MarkPosition"_ustr
                            , uno::Any( css::chart::ChartAxisMarkPosition_AT_LABELS) );
                        if( xSecondaryXAxisProp.is() )
                            xSecondaryXAxisProp->setPropertyValue(u"CrossoverPosition"_ustr
                            , uno::Any( css::chart::ChartAxisPosition_START) );
                    }
                    else
                    {
                        xMainXAxisProp->setPropertyValue(u"LabelPosition"_ustr
                            , uno::Any( css::chart::ChartAxisLabelPosition_OUTSIDE_START) );
                        xMainXAxisProp->setPropertyValue(u"MarkPosition"_ustr
                            , uno::Any( css::chart::ChartAxisMarkPosition_AT_LABELS) );
                        if( xSecondaryXAxisProp.is() )
                            xSecondaryXAxisProp->setPropertyValue(u"CrossoverPosition"_ustr
                            , uno::Any( css::chart::ChartAxisPosition_END) );
                    }
                }
            }
        }
    }
    catch( uno::Exception & )
    {
    }
}

SchXMLCategoriesContext::SchXMLCategoriesContext(
    SvXMLImport& rImport,
    OUString& rAddress ) :
        SvXMLImportContext( rImport ),
        mrAddress( rAddress )
{
}

void SchXMLCategoriesContext::startFastElement( sal_Int32 /*nElement*/,
    const css::uno::Reference< css::xml::sax::XFastAttributeList >& xAttrList )
{
    forauto& aIter : sax_fastparser::castToFastAttributeList(xAttrList) )
    {
        if( aIter.getToken() == XML_ELEMENT(TABLE, XML_CELL_RANGE_ADDRESS) )
            mrAddress = aIter.toString();
        else
            XMLOFF_WARN_UNKNOWN("xmloff", aIter);
    }
}

DateScaleContext::DateScaleContext(
    SvXMLImport& rImport,
    const Reference< beans::XPropertySet >& rAxisProps ) :
        SvXMLImportContext( rImport ),
        m_xAxisProps( rAxisProps )
{
}

namespace
{
sal_Int32 lcl_getTimeUnit( const sax_fastparser::FastAttributeList::FastAttributeIter& rValue )
{
    sal_Int32 nTimeUnit = css::chart::TimeUnit::DAY;
    if( IsXMLToken( rValue, XML_DAYS ) )
        nTimeUnit = css::chart::TimeUnit::DAY;
    else if( IsXMLToken( rValue, XML_MONTHS ) )
        nTimeUnit = css::chart::TimeUnit::MONTH;
    else if( IsXMLToken( rValue, XML_YEARS ) )
        nTimeUnit = css::chart::TimeUnit::YEAR;
    return nTimeUnit;
}

}

void DateScaleContext::startFastElement( sal_Int32 /*nElement*/,
    const css::uno::Reference< css::xml::sax::XFastAttributeList >& xAttrList )
{
    if( !m_xAxisProps.is() )
        return;

    // parse attributes
    bool bSetNewIncrement=false;
    chart::TimeIncrement aIncrement;
    m_xAxisProps->getPropertyValue(u"TimeIncrement"_ustr) >>= aIncrement;

    forauto& aIter : sax_fastparser::castToFastAttributeList(xAttrList) )
    {
        switch( aIter.getToken() )
        {
            case  XML_ELEMENT(CHART, XML_BASE_TIME_UNIT):
                {
                    aIncrement.TimeResolution <<= lcl_getTimeUnit(aIter);
                    bSetNewIncrement = true;
                }
                break;
            case XML_ELEMENT(CHART, XML_MAJOR_INTERVAL_VALUE):
                {
                    chart::TimeInterval aInterval(1,0);
                    aIncrement.MajorTimeInterval >>= aInterval;
                    ::sax::Converter::convertNumber( aInterval.Number, aIter.toView() );
                    aIncrement.MajorTimeInterval <<= aInterval;
                    bSetNewIncrement = true;
                }
                break;
            case  XML_ELEMENT(CHART, XML_MAJOR_INTERVAL_UNIT):
                {
                    chart::TimeInterval aInterval(1,0);
                    aIncrement.MajorTimeInterval >>= aInterval;
                    aInterval.TimeUnit = lcl_getTimeUnit(aIter);
                    aIncrement.MajorTimeInterval <<= aInterval;
                    bSetNewIncrement = true;
                }
                break;
            case XML_ELEMENT(CHART, XML_MINOR_INTERVAL_VALUE):
                {
                    chart::TimeInterval aInterval(1,0);
                    aIncrement.MinorTimeInterval >>= aInterval;
                    ::sax::Converter::convertNumber( aInterval.Number, aIter.toView() );
                    aIncrement.MinorTimeInterval <<= aInterval;
                    bSetNewIncrement = true;
                }
                break;
            case  XML_ELEMENT(CHART, XML_MINOR_INTERVAL_UNIT):
                {
                    chart::TimeInterval aInterval(1,0);
                    aIncrement.MinorTimeInterval >>= aInterval;
                    aInterval.TimeUnit = lcl_getTimeUnit(aIter);
                    aIncrement.MinorTimeInterval <<= aInterval;
                    bSetNewIncrement = true;
                }
                break;
            default:
                XMLOFF_WARN_UNKNOWN("xmloff", aIter);
        }
    }

    if( bSetNewIncrement )
        m_xAxisProps->setPropertyValue(u"TimeIncrement"_ustr, uno::Any( aIncrement ) );
}

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

Messung V0.5
C=95 H=98 G=96

¤ Dauer der Verarbeitung: 0.16 Sekunden  (vorverarbeitet)  ¤

*© Formatika GbR, Deutschland






Wurzel

Suchen

Beweissystem der NASA

Beweissystem Isabelle

NIST Cobol Testsuite

Cephes Mathematical Library

Wiener Entwicklungsmethode

Haftungshinweis

Die Informationen auf dieser Webseite wurden nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit, noch Qualität der bereit gestellten Informationen zugesichert.

Bemerkung:

Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.