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

Quelle  titleconverter.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 <drawingml/chart/titleconverter.hxx>

#include <com/sun/star/chart/ChartLegendExpansion.hpp>
#include <com/sun/star/chart2/FormattedString.hpp>
#include <com/sun/star/chart2/LegendPosition.hpp>
#include <com/sun/star/chart2/XDiagram.hpp>
#include <com/sun/star/chart2/XLegend.hpp>
#include <com/sun/star/chart2/XTitle.hpp>
#include <com/sun/star/chart2/XTitled.hpp>
#include <com/sun/star/chart2/XChartTypeContainer.hpp>
#include <com/sun/star/chart2/XCoordinateSystemContainer.hpp>
#include <com/sun/star/chart2/XDataSeriesContainer.hpp>

#include <comphelper/sequence.hxx>
#include <osl/diagnose.h>
#include <drawingml/textbody.hxx>
#include <drawingml/textparagraph.hxx>
#include <drawingml/chart/datasourceconverter.hxx>
#include <drawingml/chart/titlemodel.hxx>
#include <oox/token/properties.hxx>
#include <oox/token/tokens.hxx>
#include <com/sun/star/chart2/RelativePosition.hpp>
#include <com/sun/star/drawing/Alignment.hpp>

#include <oox/drawingml/chart/modelbase.hxx>
namespace oox::drawingml::chart {

using namespace ::com::sun::star::chart2;
using namespace ::com::sun::star::chart2::data;
using namespace ::com::sun::star::drawing;
using namespace ::com::sun::star::uno;


TextConverter::TextConverter( const ConverterRoot& rParent, TextModel& rModel ) :
    ConverterBase< TextModel >( rParent, rModel )
{
}

TextConverter::~TextConverter()
{
}

Reference< XDataSequence > TextConverter::createDataSequence( const OUString& rRole )
{
    Reference< XDataSequence > xDataSeq;
    if( mrModel.mxDataSeq.is() )
    {
        DataSequenceConverter aDataSeqConv( *this, *mrModel.mxDataSeq );
        xDataSeq = aDataSeqConv.createDataSequence( rRole );
    }
    return xDataSeq;
}

Sequence< Reference< XFormattedString > > TextConverter::createStringSequence(
        const OUString& rDefaultText, const ModelRef< TextBody >& rxTextProp, ObjectType eObjType )
{
    OSL_ENSURE( !mrModel.mxDataSeq || !mrModel.mxTextBody, "TextConverter::createStringSequence - linked string and rich text found" );
    ::std::vector< Reference< XFormattedString > > aStringVec;
    bool bTextFound = false;
    if( mrModel.mxTextBody.is() )
    {
        // rich-formatted text objects can be created, but currently Chart2 is not able to show them
        const TextParagraphVector& rTextParas = mrModel.mxTextBody->getParagraphs();
        for( TextParagraphVector::const_iterator aPIt = rTextParas.begin(), aPEnd = rTextParas.end(); aPIt != aPEnd; ++aPIt )
        {
            const TextParagraph& rTextPara = **aPIt;
            const TextCharacterProperties& rParaProps = rTextPara.getProperties().getTextCharacterProperties();
            for( TextRunVector::const_iterator aRIt = rTextPara.getRuns().begin(), aREnd = rTextPara.getRuns().end(); aRIt != aREnd; ++aRIt )
            {
                const TextRun& rTextRun = **aRIt;
                bool bAddNewLine = ((aRIt + 1 == aREnd) && (aPIt + 1 != aPEnd)) || rTextRun.isLineBreak();
                Reference< XFormattedString > xFmtStr = appendFormattedString( aStringVec, rTextRun.getText(), bAddNewLine );
                PropertySet aPropSet( xFmtStr );
                TextCharacterProperties aRunProps;
                if (rParaProps.mbHasEmptyParaProperties && rxTextProp.is() && rxTextProp->hasParagraphProperties())
                {
                    const TextParagraphVector rDefTextParas = rxTextProp->getParagraphs();
                    TextParagraphVector::const_iterator aDefPIt = rDefTextParas.begin();
                    const TextParagraph& rDefTextPara = **aDefPIt;
                    aRunProps = rDefTextPara.getProperties().getTextCharacterProperties();
                }
                else
                    aRunProps = rParaProps;
                aRunProps.assignUsed( rTextRun.getTextCharacterProperties() );
                getFormatter().convertTextFormatting( aPropSet, aRunProps, eObjType );

                bTextFound = true;
            }
        }
    }
    else if (rxTextProp.is() && !rxTextProp->getParagraphs().empty()) {
        // <c:txPr> or <cx:txPr> can contain <a:p>. Which seems odd, but handle
        // it here.
        const TextParagraphVector& rTextParas = rxTextProp->getParagraphs();
        for( TextParagraphVector::const_iterator aPIt = rTextParas.begin(), aPEnd = rTextParas.end(); aPIt != aPEnd; ++aPIt )
        {
            const TextParagraph& rTextPara = **aPIt;
            const TextCharacterProperties& rParaProps = rTextPara.getProperties().getTextCharacterProperties();
            for( TextRunVector::const_iterator aRIt = rTextPara.getRuns().begin(), aREnd = rTextPara.getRuns().end(); aRIt != aREnd; ++aRIt )
            {
                const TextRun& rTextRun = **aRIt;
                bool bAddNewLine = ((aRIt + 1 == aREnd) && (aPIt + 1 != aPEnd)) || rTextRun.isLineBreak();
                Reference< XFormattedString > xFmtStr = appendFormattedString( aStringVec, rTextRun.getText(), bAddNewLine );
                PropertySet aPropSet( xFmtStr );
                TextCharacterProperties aRunProps;
                if (rParaProps.mbHasEmptyParaProperties && rxTextProp->hasParagraphProperties())
                {
                    const TextParagraphVector rDefTextParas = rxTextProp->getParagraphs();
                    TextParagraphVector::const_iterator aDefPIt = rDefTextParas.begin();
                    const TextParagraph& rDefTextPara = **aDefPIt;
                    aRunProps = rDefTextPara.getProperties().getTextCharacterProperties();
                }
                else
                    aRunProps = rParaProps;
                aRunProps.assignUsed( rTextRun.getTextCharacterProperties() );
                getFormatter().convertTextFormatting( aPropSet, aRunProps, eObjType );

                bTextFound = true;
            }
        }
    }

    if (!bTextFound)
    {
        OUString aString;
        // try to create string from linked data
        if( mrModel.mxDataSeq.is() && !mrModel.mxDataSeq->maData.empty() )
            mrModel.mxDataSeq->maData.begin()->second >>= aString;
        // no linked string -> fall back to default string
        if( aString.isEmpty() )
            aString = rDefaultText;

        // create formatted string object
        if( !aString.isEmpty() )
        {
            Reference< XFormattedString > xFmtStr = appendFormattedString( aStringVec, aString, false );
            PropertySet aPropSet( xFmtStr );
            getFormatter().convertTextFormatting( aPropSet, rxTextProp, eObjType );
        }
    }

    return comphelper::containerToSequence( aStringVec );
}

Reference< XFormattedString > TextConverter::appendFormattedString(
        ::std::vector< Reference< XFormattedString > >& orStringVec, const OUString& rStringbool bAddNewLine ) const
{
    Reference< XFormattedString2 > xFmtStr;
    try
    {
        xFmtStr = FormattedString::create( ConverterRoot::getComponentContext() );
        xFmtStr->setString( bAddNewLine ? (rString + "\n") : rString );
        orStringVec.emplace_back(xFmtStr );
    }
    catch( Exception& )
    {
    }
    return xFmtStr;
}

TitleConverter::TitleConverter( const ConverterRoot& rParent, TitleModel& rModel ) :
    ConverterBase< TitleModel >( rParent, rModel )
{
}

TitleConverter::~TitleConverter()
{
}

void TitleConverter::convertFromModel( const Reference< XTitled >& rxTitled, const OUString& rAutoTitle, ObjectType eObjType, sal_Int32 nMainIdx, sal_Int32 nSubIdx )
{
    if( !rxTitled.is() )
        return;

    // create the formatted strings
    TextModel& rText = mrModel.mxText.getOrCreate();
    TextConverter aTextConv( *this, rText );
    Sequence< Reference< XFormattedString > > aStringSeq = aTextConv.createStringSequence( rAutoTitle, mrModel.mxTextProp, eObjType );
    if( !aStringSeq.hasElements() )
        return;

    try
    {
        // create the title object and set the string data
        Reference< XTitle > xTitle( createInstance( u"com.sun.star.chart2.Title"_ustr ), UNO_QUERY_THROW );
        xTitle->setText( aStringSeq );
        rxTitled->setTitleObject( xTitle );

        // frame formatting (text formatting already done in TextConverter::createStringSequence())
        PropertySet aPropSet( xTitle );
        getFormatter().convertFrameFormatting( aPropSet, mrModel.mxShapeProp, eObjType );

        // frame rotation
        OSL_ENSURE( !mrModel.mxTextProp || !rText.mxTextBody, "TitleConverter::convertFromModel - multiple text properties" );
        ModelRef< TextBody > xTextProp = mrModel.mxTextProp.is() ? mrModel.mxTextProp : rText.mxTextBody;
        ObjectFormatter::convertTextRotation( aPropSet, xTextProp, true, mrModel.mnDefaultRotation );

        // register the title and layout data for conversion of position
        registerTitleLayout( xTitle, mrModel.mxLayout, eObjType, nMainIdx, nSubIdx );
    }
    catch( Exception& )
    {
    }
}

LegendConverter::LegendConverter( const ConverterRoot& rParent, LegendModel& rModel ) :
    ConverterBase< LegendModel >( rParent, rModel )
{
}

LegendConverter::~LegendConverter()
{
}

void LegendConverter::convertFromModel( const Reference< XDiagram >& rxDiagram )
{
    if( !rxDiagram.is() )
        return;

    try
    {
        namespace cssc = css::chart;
        namespace cssc2 = css::chart2;

        // create the legend
        Reference< XLegend > xLegend( createInstance( u"com.sun.star.chart2.Legend"_ustr ), UNO_QUERY_THROW );
        rxDiagram->setLegend( xLegend );
        PropertySet aPropSet( xLegend );
        aPropSet.setProperty( PROP_Show, true );

        // legend formatting
        getFormatter().convertFormatting( aPropSet, mrModel.mxShapeProp, mrModel.mxTextProp, OBJECTTYPE_LEGEND );

        // predefined legend position and expansion
        cssc2::LegendPosition eLegendPos = cssc2::LegendPosition_LINE_END;
        cssc::ChartLegendExpansion eLegendExpand = cssc::ChartLegendExpansion_CUSTOM;
        RelativePosition eRelPos;
        bool bTopRight=false;
        switch( mrModel.mnPosition )
        {
            case XML_l:
                eLegendPos = cssc2::LegendPosition_LINE_START;
                eLegendExpand = cssc::ChartLegendExpansion_HIGH;
            break;
            case XML_r:
                eLegendPos = cssc2::LegendPosition_LINE_END;
                eLegendExpand = cssc::ChartLegendExpansion_HIGH;
            break;
            case XML_tr:    // top-right not supported
                eRelPos.Primary = 1;
                eRelPos.Secondary =0;
                eRelPos.Anchor = Alignment_TOP_RIGHT;
                bTopRight=true;
            break;
            case XML_t:
                eLegendPos = cssc2::LegendPosition_PAGE_START;
                eLegendExpand = cssc::ChartLegendExpansion_WIDE;
            break;
            case XML_b:
                eLegendPos = cssc2::LegendPosition_PAGE_END;
                eLegendExpand = cssc::ChartLegendExpansion_WIDE;
            break;
        }
        bool bManualLayout=false;
        // manual positioning and size
        if( mrModel.mxLayout )
        {
            LayoutConverter aLayoutConv( *this, *mrModel.mxLayout );
            // manual size needs ChartLegendExpansion_CUSTOM
            if( aLayoutConv.convertFromModel( aPropSet ) )
            {
                eLegendExpand = cssc::ChartLegendExpansion_CUSTOM;
            }
            bManualLayout = !aLayoutConv.getAutoLayout();
        }

        // set position and expansion properties
        aPropSet.setProperty( PROP_AnchorPosition, eLegendPos );
        aPropSet.setProperty( PROP_Expansion, eLegendExpand );

        if (bTopRight && !bManualLayout)
            aPropSet.setProperty( PROP_RelativePosition , Any(eRelPos));

        aPropSet.setProperty(PROP_Overlay, mrModel.mbOverlay);

        if (mrModel.maLegendEntries.size() > 0)
            legendEntriesFormatting(rxDiagram);
    }
    catch( Exception& )
    {
    }
}

void LegendConverter::legendEntriesFormatting(const Reference<XDiagram>& rxDiagram)
{
    Reference<XCoordinateSystemContainer> xCooSysContainer(rxDiagram, UNO_QUERY_THROW);
    const Sequence<Reference<XCoordinateSystem>> xCooSysSequence(xCooSysContainer->getCoordinateSystems());
    if (!xCooSysSequence.hasElements())
        return;

    sal_Int32 nIndex = 0;
    for (const auto& rCooSys : xCooSysSequence)
    {
        PropertySet aCooSysProp(rCooSys);
        bool bSwapXAndY = aCooSysProp.getBoolProperty(PROP_SwapXAndYAxis);

        Reference<XChartTypeContainer> xChartTypeContainer(rCooSys, UNO_QUERY_THROW);
        const Sequence<Reference<XChartType>> xChartTypeSequence(xChartTypeContainer->getChartTypes());
        if (!xChartTypeSequence.hasElements())
            continue;

        for (const auto& rCT : xChartTypeSequence)
        {
            Reference<XDataSeriesContainer> xDSCont(rCT, UNO_QUERY);
            if (!xDSCont.is())
                continue;

            bool bIsPie
                = rCT->getChartType().equalsIgnoreAsciiCase("com.sun.star.chart2.PieChartType");
            if (bIsPie)
            {
                PropertySet xChartTypeProp(rCT);
                bIsPie = !xChartTypeProp.getBoolProperty(PROP_UseRings);
            }
            const Sequence<Reference<XDataSeries>> aDataSeriesSeq = xDSCont->getDataSeries();
            if (bSwapXAndY)
                nIndex += aDataSeriesSeq.getLength() - 1;
            for (const auto& rDataSeries : aDataSeriesSeq)
            {
                PropertySet aSeriesProp(rDataSeries);
                bool bVaryColorsByPoint = aSeriesProp.getBoolProperty(PROP_VaryColorsByPoint);

                if (bVaryColorsByPoint || bIsPie)
                {
                    Reference<XDataSource> xDSrc(rDataSeries, UNO_QUERY);
                    if (!xDSrc.is())
                        continue;

                    const Sequence<Reference<XLabeledDataSequence> > aDataSeqs = xDSrc->getDataSequences();
                    std::vector<sal_Int32> deletedLegendEntries;
                    sal_Int32 j = 0;
                    for (const auto& rDataSeq : aDataSeqs)
                    {
                        Reference<XDataSequence> xValues = rDataSeq->getValues();
                        if (!xValues.is())
                            continue;

                        sal_Int32 nDataSeqSize = xValues->getData().getLength();
                        for (sal_Int32 i = 0; i < nDataSeqSize; ++i)
                        {
                            for (const auto& rLegendEntry : mrModel.maLegendEntries)
                            {
                                if (nIndex == rLegendEntry->mnLegendEntryIdx && rLegendEntry->mbLabelDeleted)
                                {
                                    deletedLegendEntries.push_back(j + i);
                                    break;
                                }
                            }
                            nIndex++;
                        }
                        j += nDataSeqSize;
                    }
                    if (deletedLegendEntries.size() > 0)
                        aSeriesProp.setProperty(PROP_DeletedLegendEntries, comphelper::containerToSequence(deletedLegendEntries));
                }
                else
                {
                    for (const auto& rLegendEntry : mrModel.maLegendEntries)
                    {
                        if (nIndex == rLegendEntry->mnLegendEntryIdx)
                        {
                            aSeriesProp.setProperty(PROP_ShowLegendEntry, !rLegendEntry->mbLabelDeleted);
                            break;
                        }
                    }
                    bSwapXAndY ? nIndex-- : nIndex++;
                }
            }
            if (bSwapXAndY)
                nIndex += aDataSeriesSeq.getLength() + 1;
        }
    }
}

// namespace oox::drawingml::chart

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

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

¤ Dauer der Verarbeitung: 0.13 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.