Coverage Report

Created: 2026-11-06 11:29

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/libreoffice/oox/source/drawingml/chart/chartconverter.cxx
Line
Count
Source
1
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2
/*
3
 * This file is part of the LibreOffice project.
4
 *
5
 * This Source Code Form is subject to the terms of the Mozilla Public
6
 * License, v. 2.0. If a copy of the MPL was not distributed with this
7
 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
8
 *
9
 * This file incorporates work covered by the following license notice:
10
 *
11
 *   Licensed to the Apache Software Foundation (ASF) under one or more
12
 *   contributor license agreements. See the NOTICE file distributed
13
 *   with this work for additional information regarding copyright
14
 *   ownership. The ASF licenses this file to you under the Apache
15
 *   License, Version 2.0 (the "License"); you may not use this file
16
 *   except in compliance with the License. You may obtain a copy of
17
 *   the License at http://www.apache.org/licenses/LICENSE-2.0 .
18
 */
19
20
#include <com/sun/star/chart2/XChartDocument.hpp>
21
#include <com/sun/star/chart2/data/XDataReceiver.hpp>
22
#include <com/sun/star/util/XNumberFormatsSupplier.hpp>
23
#include <drawingml/chart/chartspaceconverter.hxx>
24
#include <drawingml/chart/chartspacemodel.hxx>
25
#include <drawingml/chart/stylemodel.hxx>
26
#include <drawingml/chart/colorsmodel.hxx>
27
#include <docmodel/uno/UnoChartStyle.hxx>
28
#include <docmodel/uno/UnoChartColorStyle.hxx>
29
#include <docmodel/styles/ChartStyle.hxx>
30
#include <docmodel/styles/ChartColorStyle.hxx>
31
#include <oox/helper/containerhelper.hxx>
32
#include <oox/core/xmlfilterbase.hxx>
33
#include <osl/diagnose.h>
34
35
#include <oox/drawingml/chart/chartconverter.hxx>
36
37
using ::oox::drawingml::chart::DataSequenceModel;
38
using ::com::sun::star::uno::Any;
39
namespace oox::drawingml::chart {
40
41
using namespace ::com::sun::star;
42
using namespace ::com::sun::star::chart2;
43
using namespace ::com::sun::star::chart2::data;
44
using namespace ::com::sun::star::drawing;
45
using namespace ::com::sun::star::uno;
46
47
using ::oox::core::XmlFilterBase;
48
49
const sal_Unicode API_TOKEN_ARRAY_OPEN      = '{';
50
const sal_Unicode API_TOKEN_ARRAY_CLOSE     = '}';
51
const sal_Unicode API_TOKEN_ARRAY_COLSEP    = ';';
52
53
static OUString lclGenerateApiArray(const std::vector<Any>& rRow, sal_Int32 nStart, sal_Int32 nCount)
54
0
{
55
0
    OSL_ENSURE( !rRow.empty(), "ChartConverter::lclGenerateApiArray - missing matrix values" );
56
0
    OUStringBuffer aBuffer(( OUStringChar(API_TOKEN_ARRAY_OPEN) ));
57
0
    for (auto aBeg = rRow.begin() + nStart, aIt = aBeg, aEnd = aBeg + nCount; aIt != aEnd; ++aIt)
58
0
    {
59
0
        double fValue = 0.0;
60
0
        OUString aString;
61
0
        if( aIt != aBeg )
62
0
            aBuffer.append( API_TOKEN_ARRAY_COLSEP );
63
0
        if( *aIt >>= fValue )
64
0
            aBuffer.append( fValue );
65
0
        else if( *aIt >>= aString )
66
0
        {
67
            // Code similar to sc/source/filter/oox/formulabase.cxx
68
0
            aBuffer.append( "\"" + aString.replaceAll(u"\"", u"\"\"") + "\"" );
69
0
        }
70
0
        else
71
0
            aBuffer.append( "\"\"" );
72
0
    }
73
0
    aBuffer.append( API_TOKEN_ARRAY_CLOSE );
74
0
    return aBuffer.makeStringAndClear();
75
0
}
76
77
ChartConverter::ChartConverter()
78
11.2k
{
79
11.2k
}
80
81
ChartConverter::~ChartConverter()
82
11.2k
{
83
11.2k
}
84
85
void ChartConverter::convertFromModel( XmlFilterBase& rFilter,
86
        ChartSpaceModel& rChartModel, const Reference< XChartDocument >& rxChartDoc,
87
        const Reference< XShapes >& rxExternalPage, const awt::Point& rChartPos,
88
        const awt::Size& rChartSize ) const
89
0
{
90
0
    OSL_ENSURE( rxChartDoc.is(), "ChartConverter::convertFromModel - missing chart document" );
91
0
    if( rxChartDoc.is() )
92
0
    {
93
0
        Reference< data::XDataReceiver > xDataReceiver( rxChartDoc, uno::UNO_QUERY_THROW );
94
0
        Reference< util::XNumberFormatsSupplier > xNumberFormatsSupplier( rFilter.getModel(), uno::UNO_QUERY );
95
0
        if (xNumberFormatsSupplier.is())
96
0
            xDataReceiver->attachNumberFormatsSupplier( xNumberFormatsSupplier );
97
98
0
        ConverterRoot aConvBase( rFilter, *this, rChartModel, rxChartDoc, rChartSize );
99
0
        ChartSpaceConverter aSpaceConv( aConvBase, rChartModel );
100
0
        aSpaceConv.convertFromModel( rxExternalPage, rChartPos );
101
0
    }
102
0
}
103
104
void ChartConverter::createDataProvider( const Reference< XChartDocument >&
105
        rxChartDoc ) const
106
0
{
107
0
    try
108
0
    {
109
0
        if( !rxChartDoc->hasInternalDataProvider() )
110
0
            rxChartDoc->createInternalDataProvider( false );
111
0
    }
112
0
    catch( Exception& )
113
0
    {
114
0
    }
115
0
}
116
117
Reference< XDataSequence > ChartConverter::createDataSequence(
118
    const Reference< XDataProvider >& rxDataProvider, const DataSequenceModel& rDataSeq,
119
    const OUString& rRole, const OUString& rRoleQualifier ) const
120
0
{
121
0
    Reference< XDataSequence > xDataSeq;
122
0
    if( rxDataProvider.is() )
123
0
    {
124
0
        OUString aRangeRep;
125
0
        if( !rDataSeq.maData.empty() || (rRole == "values-y" && rDataSeq.mnPointCount > 0) ) try
126
0
        {
127
            // create a single-row array from constant source data
128
            // (multiple levels in the case of complex categories)
129
0
            assert( rDataSeq.mnPointCount > 0);
130
0
            std::vector<Any> aRow(rDataSeq.mnLevelCount * rDataSeq.mnPointCount);
131
0
            for (auto const& elem : rDataSeq.maData)
132
0
                aRow.at(elem.first) = elem.second;
133
134
0
            for (sal_Int32 i = rDataSeq.mnLevelCount-1; i >= 0; i--)
135
0
            {
136
0
                aRangeRep = lclGenerateApiArray( aRow, i * rDataSeq.mnPointCount, rDataSeq.mnPointCount);
137
138
0
                if (!aRangeRep.isEmpty())
139
0
                {
140
                    // create or add a new level to the data sequence
141
0
                    xDataSeq = rxDataProvider->createDataSequenceByValueArray(rRole, aRangeRep, rRoleQualifier);
142
0
                    if (i == 0)
143
0
                        return xDataSeq;
144
0
                }
145
0
            }
146
0
        }
147
0
        catch( Exception& )
148
0
        {
149
0
            OSL_FAIL( "ChartConverter::createDataSequence - cannot create data sequence" );
150
0
        }
151
0
    }
152
153
0
    return nullptr;
154
0
}
155
156
// ===========
157
// ChartStyleConverter
158
// ===========
159
void ChartStyleConverter::convertFromModel(const XmlFilterBase& rFilter,
160
        const StyleModel& rChartStyleModel,
161
        const Reference< XChartStyle >& rxChartStyle)
162
0
{
163
0
    OSL_ENSURE( rxChartStyle.is(), "ChartStyleConverter::convertFromModel - missing chart style" );
164
0
    if (!rxChartStyle.is()) return;
165
166
0
    UnoChartStyle *pUnoCS = static_cast<UnoChartStyle*>(rxChartStyle.get());
167
0
    assert(pUnoCS);
168
169
0
    model::StyleSet& aStyles = pUnoCS->getChartStyle();
170
171
0
    if (rChartStyleModel.mxAxisTitle) {
172
0
        aStyles.addEntry(model::StyleSet::StyleEntryType::AXISTITLE,
173
0
                rChartStyleModel.mxAxisTitle->toStyleEntry(rFilter));
174
0
    }
175
    // etc.
176
    // TODO: fill in all the stuff
177
178
0
    aStyles.mnId = rChartStyleModel.mnId;
179
0
}
180
181
// ===========
182
// ChartColorStyleConverter
183
// ===========
184
void ChartColorStyleConverter::convertFromModel([[maybe_unused]] XmlFilterBase& rFilter,
185
        ColorStyleModel& rChartColorStyleModel,
186
        const Reference< XChartColorStyle >& rxChartColorStyle)
187
0
{
188
0
    OSL_ENSURE( rxChartColorStyle.is(), "ChartColorStyleConverter::convertFromModel - missing chart colorstyle" );
189
0
    if (!rxChartColorStyle.is()) return;
190
191
0
    UnoChartColorStyle *pUnoCS = static_cast<UnoChartColorStyle*>(rxChartColorStyle.get());
192
0
    assert(pUnoCS);
193
194
0
    model::ColorStyleSet& aColorStyles = pUnoCS->getChartColorStyle();
195
196
0
    if (!rChartColorStyleModel.maComplexColors.empty()) {
197
0
        aColorStyles.addEntry(rChartColorStyleModel.maComplexColors,
198
0
                rChartColorStyleModel.meMethod, rChartColorStyleModel.mnId);
199
0
    }
200
0
}
201
202
203
} // namespace oox::drawingml::chart
204
205
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */