Coverage Report

Created: 2025-11-16 09:57

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/libreoffice/oox/source/drawingml/chart/axiscontext.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 <drawingml/chart/axiscontext.hxx>
21
22
#include <drawingml/shapepropertiescontext.hxx>
23
#include <drawingml/textbodycontext.hxx>
24
#include <drawingml/chart/axismodel.hxx>
25
#include <drawingml/chart/titlecontext.hxx>
26
#include <oox/core/xmlfilterbase.hxx>
27
#include <oox/helper/attributelist.hxx>
28
#include <oox/token/namespaces.hxx>
29
#include <oox/token/tokens.hxx>
30
31
namespace oox::drawingml::chart {
32
33
using ::oox::core::ContextHandlerRef;
34
using ::oox::core::ContextHandler2Helper;
35
36
AxisDispUnitsContext::AxisDispUnitsContext( ContextHandler2Helper& rParent, AxisDispUnitsModel& rModel ) :
37
0
    ContextBase< AxisDispUnitsModel >( rParent, rModel )
38
0
{
39
0
}
40
41
AxisDispUnitsContext::~AxisDispUnitsContext()
42
0
{
43
0
}
44
45
ContextHandlerRef AxisDispUnitsContext::onCreateContext( sal_Int32 nElement, const AttributeList& rAttribs )
46
0
{
47
0
    switch( getCurrentElement() )
48
0
    {
49
0
        case C_TOKEN( dispUnits ):
50
0
            switch( nElement )
51
0
            {
52
0
                case C_TOKEN( builtInUnit ):
53
0
                    mrModel.mnBuiltInUnit = rAttribs.getString( XML_val, u"thousands"_ustr );
54
0
                    return nullptr;
55
0
                case C_TOKEN( custUnit ):
56
0
                    mrModel.mfCustomUnit = rAttribs.getDouble( XML_val, 0.0 );
57
0
                    return nullptr;
58
0
                case C_TOKEN( dispUnitsLbl ):
59
0
                    return this;
60
0
            }
61
0
        break;
62
63
0
        case C_TOKEN( dispUnitsLbl ):
64
0
            switch( nElement )
65
0
            {
66
0
                case C_TOKEN( layout ):
67
0
                    return new LayoutContext( *this, mrModel.mxLayout.create() );
68
0
                case C_TOKEN( spPr ):
69
0
                    return new ShapePropertiesContext( *this, mrModel.mxShapeProp.create() );
70
0
                case C_TOKEN( tx ):
71
0
                    return new TextContext( *this, mrModel.mxText.create() );
72
0
                case C_TOKEN( txPr ):
73
0
                    return new TextBodyContext( *this, mrModel.mxTextProp.create() );
74
0
            }
75
0
        break;
76
0
    }
77
0
    return nullptr;
78
0
}
79
80
AxisContextBase::AxisContextBase( ContextHandler2Helper& rParent, AxisModel& rModel ) :
81
0
    ContextBase< AxisModel >( rParent, rModel )
82
0
{
83
0
}
84
85
AxisContextBase::~AxisContextBase()
86
0
{
87
0
}
88
89
ContextHandlerRef AxisContextBase::onCreateContext( sal_Int32 nElement, const AttributeList& rAttribs )
90
0
{
91
0
    bool bMSO2007Doc = getFilter().isMSO2007Document();
92
0
    switch( getCurrentElement() )
93
0
    {
94
0
        case C_TOKEN( catAx ):
95
0
        case C_TOKEN( dateAx ):
96
0
        case C_TOKEN( serAx ):
97
0
        case C_TOKEN( valAx ):
98
0
            switch( nElement )
99
0
            {
100
0
                case C_TOKEN( axId ):
101
0
                    mrModel.mnAxisId = rAttribs.getInteger( XML_val, -1 );
102
0
                    return nullptr;
103
0
                case C_TOKEN( crossAx ):
104
0
                    mrModel.mnCrossAxisId = rAttribs.getInteger( XML_val, -1 );
105
0
                    return nullptr;
106
0
                case C_TOKEN( crosses ):
107
0
                    mrModel.mnCrossMode = rAttribs.getToken( XML_val, XML_autoZero );
108
0
                    return nullptr;
109
0
                case C_TOKEN( crossesAt ):
110
0
                    mrModel.mofCrossesAt = rAttribs.getDouble( XML_val, 0.0 );
111
0
                    return nullptr;
112
0
                case C_TOKEN( delete ):
113
0
                    mrModel.mbDeleted = rAttribs.getBool( XML_val, !bMSO2007Doc );
114
0
                    return nullptr;
115
0
                case C_TOKEN( majorGridlines ):
116
0
                    return new ShapePrWrapperContext( *this, mrModel.mxMajorGridLines.create() );
117
0
                case C_TOKEN( majorTickMark ):
118
0
                    mrModel.mnMajorTickMark = rAttribs.getToken( XML_val, bMSO2007Doc ? XML_out : XML_cross );
119
0
                    return nullptr;
120
0
                case C_TOKEN(axPos):
121
0
                    mrModel.mnAxisPos = rAttribs.getToken( XML_val, XML_TOKEN_INVALID );
122
0
                    return nullptr;
123
0
                case C_TOKEN( minorGridlines ):
124
0
                    return new ShapePrWrapperContext( *this, mrModel.mxMinorGridLines.create() );
125
0
                case C_TOKEN( minorTickMark ):
126
0
                    mrModel.mnMinorTickMark = rAttribs.getToken( XML_val, bMSO2007Doc ? XML_none : XML_cross );
127
0
                    return nullptr;
128
0
                case C_TOKEN( numFmt ):
129
0
                    mrModel.maNumberFormat.setAttributes( rAttribs );
130
0
                    return nullptr;
131
0
                case C_TOKEN( scaling ):
132
0
                    return this;
133
0
                case C_TOKEN( spPr ):
134
0
                    return new ShapePropertiesContext( *this, mrModel.mxShapeProp.create() );
135
0
                case C_TOKEN( tickLblPos ):
136
0
                    mrModel.mnTickLabelPos = rAttribs.getToken( XML_val, XML_nextTo );
137
0
                    return nullptr;
138
0
                case C_TOKEN( title ):
139
0
                {
140
0
                    bool bVerticalDefault = mrModel.mnAxisPos == XML_l || mrModel.mnAxisPos == XML_r;
141
0
                    sal_Int32 nDefaultRotation = bVerticalDefault ? -5400000 : 0;
142
0
                    return new TitleContext( *this, mrModel.mxTitle.create(nDefaultRotation) );
143
0
                }
144
0
                case C_TOKEN( txPr ):
145
0
                    return new TextBodyContext( *this, mrModel.mxTextProp.create() );
146
0
            }
147
0
        break;
148
149
0
        case C_TOKEN( scaling ):
150
0
            switch( nElement )
151
0
            {
152
0
                case C_TOKEN( logBase ):
153
0
                    mrModel.mofLogBase = rAttribs.getDouble( XML_val, 0.0 );
154
0
                    return nullptr;
155
0
                case C_TOKEN( max ):
156
0
                    mrModel.mofMax = rAttribs.getDouble( XML_val, 0.0 );
157
0
                    return nullptr;
158
0
                case C_TOKEN( min ):
159
0
                    mrModel.mofMin = rAttribs.getDouble( XML_val, 0.0 );
160
0
                    return nullptr;
161
0
                case C_TOKEN( orientation ):
162
0
                    mrModel.mnOrientation = rAttribs.getToken( XML_val, XML_minMax );
163
0
                    return nullptr;
164
0
            }
165
0
        break;
166
0
    }
167
0
    return nullptr;
168
0
}
169
170
CatAxisContext::CatAxisContext( ContextHandler2Helper& rParent, AxisModel& rModel ) :
171
0
    AxisContextBase( rParent, rModel )
172
0
{
173
0
}
174
175
CatAxisContext::~CatAxisContext()
176
{
177
}
178
179
ContextHandlerRef CatAxisContext::onCreateContext( sal_Int32 nElement, const AttributeList& rAttribs )
180
0
{
181
0
    bool bMSO2007Doc = getFilter().isMSO2007Document();
182
0
    if( isRootElement() ) switch( nElement )
183
0
    {
184
0
        case C_TOKEN( auto ):
185
0
            mrModel.mbAuto = rAttribs.getBool( XML_val, !bMSO2007Doc );
186
0
            return nullptr;
187
0
        case C_TOKEN( lblAlgn ):
188
0
            mrModel.mnLabelAlign = rAttribs.getToken( XML_val, XML_ctr );
189
0
            return nullptr;
190
0
        case C_TOKEN( lblOffset ):
191
0
            mrModel.mnLabelOffset = rAttribs.getInteger( XML_val, 100 );
192
0
            return nullptr;
193
0
        case C_TOKEN( noMultiLvlLbl ):
194
0
            mrModel.mbNoMultiLevel = rAttribs.getBool( XML_val, !bMSO2007Doc );
195
0
            return nullptr;
196
0
        case C_TOKEN( tickLblSkip ):
197
0
            mrModel.mnTickLabelSkip = rAttribs.getInteger( XML_val, 0 );
198
0
            return nullptr;
199
0
        case C_TOKEN( tickMarkSkip ):
200
0
            mrModel.mnTickMarkSkip = rAttribs.getInteger( XML_val, 0 );
201
0
            return nullptr;
202
0
    }
203
0
    return AxisContextBase::onCreateContext( nElement, rAttribs );
204
0
}
205
206
DateAxisContext::DateAxisContext( ContextHandler2Helper& rParent, AxisModel& rModel ) :
207
0
    AxisContextBase( rParent, rModel )
208
0
{
209
0
}
210
211
DateAxisContext::~DateAxisContext()
212
{
213
}
214
215
ContextHandlerRef DateAxisContext::onCreateContext( sal_Int32 nElement, const AttributeList& rAttribs )
216
0
{
217
0
    bool bMSO2007Doc = getFilter().isMSO2007Document();
218
0
    if( isRootElement() ) switch( nElement )
219
0
    {
220
0
        case C_TOKEN( auto ):
221
0
            mrModel.mbAuto = rAttribs.getBool( XML_val, !bMSO2007Doc );
222
0
            return nullptr;
223
0
        case C_TOKEN( baseTimeUnit ):
224
0
            mrModel.monBaseTimeUnit = rAttribs.getToken( XML_val, XML_days );
225
0
            return nullptr;
226
0
        case C_TOKEN( lblOffset ):
227
0
            mrModel.mnLabelOffset = rAttribs.getInteger( XML_val, 100 );
228
0
            return nullptr;
229
0
        case C_TOKEN( majorTimeUnit ):
230
0
            mrModel.mnMajorTimeUnit = rAttribs.getToken( XML_val, XML_days );
231
0
            return nullptr;
232
0
        case C_TOKEN( majorUnit ):
233
0
            mrModel.mofMajorUnit = rAttribs.getDouble( XML_val, 0.0 );
234
0
            return nullptr;
235
0
        case C_TOKEN( minorTimeUnit ):
236
0
            mrModel.mnMinorTimeUnit = rAttribs.getToken( XML_val, XML_days );
237
0
            return nullptr;
238
0
        case C_TOKEN( minorUnit ):
239
0
            mrModel.mofMinorUnit = rAttribs.getDouble( XML_val, 0.0 );
240
0
            return nullptr;
241
0
    }
242
0
    return AxisContextBase::onCreateContext( nElement, rAttribs );
243
0
}
244
245
SerAxisContext::SerAxisContext( ContextHandler2Helper& rParent, AxisModel& rModel ) :
246
0
    AxisContextBase( rParent, rModel )
247
0
{
248
0
}
249
250
SerAxisContext::~SerAxisContext()
251
{
252
}
253
254
ContextHandlerRef SerAxisContext::onCreateContext( sal_Int32 nElement, const AttributeList& rAttribs )
255
0
{
256
0
    if( isRootElement() ) switch( nElement )
257
0
    {
258
0
        case C_TOKEN( tickLblSkip ):
259
0
            mrModel.mnTickLabelSkip = rAttribs.getInteger( XML_val, 0 );
260
0
            return nullptr;
261
0
        case C_TOKEN( tickMarkSkip ):
262
0
            mrModel.mnTickMarkSkip = rAttribs.getInteger( XML_val, 0 );
263
0
            return nullptr;
264
0
    }
265
0
    return AxisContextBase::onCreateContext( nElement, rAttribs );
266
0
}
267
268
ValAxisContext::ValAxisContext( ContextHandler2Helper& rParent, AxisModel& rModel ) :
269
0
    AxisContextBase( rParent, rModel )
270
0
{
271
0
}
272
273
ValAxisContext::~ValAxisContext()
274
{
275
}
276
277
ContextHandlerRef ValAxisContext::onCreateContext( sal_Int32 nElement, const AttributeList& rAttribs )
278
0
{
279
0
    if( isRootElement() ) switch( nElement )
280
0
    {
281
0
        case C_TOKEN( crossBetween ):
282
0
            mrModel.mnCrossBetween = rAttribs.getToken( XML_val, -1 );
283
0
            return nullptr;
284
0
        case C_TOKEN( dispUnits ):
285
0
            return new AxisDispUnitsContext( *this, mrModel.mxDispUnits.create() );
286
0
        case C_TOKEN( majorUnit ):
287
0
            mrModel.mofMajorUnit = rAttribs.getDouble( XML_val, 0.0 );
288
0
            return nullptr;
289
0
        case C_TOKEN( minorUnit ):
290
0
            mrModel.mofMinorUnit = rAttribs.getDouble( XML_val, 0.0 );
291
0
            return nullptr;
292
0
    }
293
0
    return AxisContextBase::onCreateContext( nElement, rAttribs );
294
0
}
295
296
CxAxisContext::CxAxisContext( ContextHandler2Helper& rParent, AxisModel& rModel,
297
        sal_Int32 nId) :
298
0
    AxisContextBase( rParent, rModel )
299
0
{
300
0
    mrModel.mnAxisId = nId;
301
0
}
302
303
CxAxisContext::~CxAxisContext()
304
{
305
}
306
307
ContextHandlerRef CxAxisContext::onCreateContext( sal_Int32 nElement, const AttributeList& rAttribs )
308
0
{
309
0
    if( isRootElement() ) switch( nElement )
310
0
    {
311
0
        case CX_TOKEN(catScaling) :
312
            // TODO: figure out how to get gapWidth attribute to the right place
313
0
            return nullptr;
314
0
        case CX_TOKEN(valScaling) :
315
0
            if (rAttribs.hasAttribute(XML_max)) {
316
0
                mrModel.mofMax = rAttribs.getDouble(XML_max);
317
0
            }
318
0
            if (rAttribs.hasAttribute(XML_min)) {
319
0
                mrModel.mofMin = rAttribs.getDouble(XML_min);
320
0
            }
321
            /* TODO: need to implement AttributeList method
322
            if (rAttribs.hasAttribute(XML_majorUnit)) {
323
                mrModel.mofMajorUnit = rAttribs.getValAxisUnit(XML_majorUnit);
324
            }
325
            if (rAttribs.hasAttribute(XML_minorUnit)) {
326
                mrModel.mofMinorUnit = rAttribs.getValAxisUnit(XML_minorUnit);
327
            }
328
            */
329
0
            return nullptr;
330
0
        case CX_TOKEN(title):
331
0
        {
332
0
            bool bVerticalDefault = mrModel.mnAxisPos == XML_l || mrModel.mnAxisPos == XML_r;
333
0
            sal_Int32 nDefaultRotation = bVerticalDefault ? -5400000 : 0;
334
0
            return new TitleContext( *this, mrModel.mxTitle.create(nDefaultRotation) );
335
0
        }
336
0
        case CX_TOKEN(units) :
337
            // TODO
338
0
            return nullptr;
339
0
        case CX_TOKEN(majorGridlines):
340
0
            return new ShapePrWrapperContext( *this, mrModel.mxMajorGridLines.create() );
341
0
        case CX_TOKEN(minorGridlines):
342
0
            return new ShapePrWrapperContext( *this, mrModel.mxMinorGridLines.create() );
343
0
        case CX_TOKEN(majorTickMarks):
344
0
            mrModel.mnMajorTickMark = rAttribs.getToken( XML_type, XML_cross );
345
0
            return nullptr;
346
0
        case CX_TOKEN(minorTickMarks):
347
0
            mrModel.mnMinorTickMark = rAttribs.getToken( XML_type, XML_cross );
348
0
            return nullptr;
349
0
        case CX_TOKEN(tickLabels) :
350
            // TODO (contents is only an extLst)
351
0
            return nullptr;
352
0
        case CX_TOKEN(numFmt):
353
0
            mrModel.maNumberFormat.setAttributes( rAttribs );
354
0
            return nullptr;
355
0
        case CX_TOKEN(spPr):
356
0
            return new ShapePropertiesContext( *this, mrModel.mxShapeProp.create() );
357
0
        case CX_TOKEN(txPr):
358
0
            return new TextBodyContext( *this, mrModel.mxTextProp.create() );
359
0
        default:
360
0
            assert(false);
361
0
    }
362
0
    return nullptr;
363
0
}
364
365
} // namespace oox::drawingml::chart
366
367
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */