Coverage Report

Created: 2026-10-14 09:33

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/libreoffice/oox/source/drawingml/diagram/layoutnodecontext.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 "layoutnodecontext.hxx"
21
22
#include <oox/helper/attributelist.hxx>
23
#include <oox/drawingml/shapecontext.hxx>
24
#include <drawingml/customshapeproperties.hxx>
25
#include "constraintlistcontext.hxx"
26
#include "rulelistcontext.hxx"
27
#include <oox/token/namespaces.hxx>
28
#include <oox/token/tokens.hxx>
29
#include <sal/log.hxx>
30
#include <sax/fastattribs.hxx>
31
#include <utility>
32
33
using namespace ::oox::core;
34
35
namespace oox::drawingml {
36
37
namespace {
38
39
class IfContext
40
    : public LayoutNodeContext
41
{
42
public:
43
    IfContext( SmartArtDiagram& rDgm, ContextHandler2Helper const & rParent,
44
               const AttributeList& rAttribs,
45
               const ConditionAtomPtr& pAtom )
46
3.55k
        : LayoutNodeContext( rDgm, rParent, rAttribs, pAtom )
47
3.55k
    {}
48
};
49
50
class AlgorithmContext
51
    : public ContextHandler2
52
{
53
public:
54
    AlgorithmContext( ContextHandler2Helper const & rParent, const AttributeList& rAttribs, const AlgAtomPtr & pNode )
55
2.07k
        : ContextHandler2( rParent )
56
2.07k
        , mnRevision( 0 )
57
2.07k
        , mpNode( pNode )
58
2.07k
        {
59
2.07k
            mnRevision = rAttribs.getInteger( XML_rev, 0 );
60
2.07k
            pNode->setType(rAttribs.getToken(XML_type, 0));
61
2.07k
        }
62
63
    virtual ContextHandlerRef
64
    onCreateContext( ::sal_Int32 aElement,
65
                     const AttributeList& rAttribs ) override
66
1.63k
        {
67
1.63k
            switch( aElement )
68
1.63k
            {
69
1.63k
                case DGM_TOKEN( param ):
70
1.63k
                {
71
1.63k
                    sal_Int32 nType = rAttribs.getToken(XML_type, 0);
72
1.63k
                    switch (nType)
73
1.63k
                    {
74
58
                        case XML_ar:
75
58
                            mpNode->setAspectRatio(rAttribs.getDouble(XML_val, 0));
76
58
                            break;
77
1.57k
                        default:
78
1.57k
                            const sal_Int32 nValTok = rAttribs.getToken(XML_val, 0);
79
1.57k
                            mpNode->addParam(nType, nValTok > 0 ? nValTok
80
1.57k
                                                                : rAttribs.getInteger(XML_val, 0));
81
1.57k
                            break;
82
1.63k
                    }
83
1.63k
                    break;
84
1.63k
                }
85
1.63k
                default:
86
0
                    break;
87
1.63k
            }
88
89
1.63k
            return this;
90
1.63k
        }
91
92
private:
93
    sal_Int32  mnRevision;
94
    AlgAtomPtr mpNode;
95
};
96
97
class ChooseContext
98
    : public ContextHandler2
99
{
100
public:
101
    ChooseContext( SmartArtDiagram& rDgm, ContextHandler2Helper const & rParent, const AttributeList& rAttribs, LayoutAtomPtr pNode )
102
1.64k
        : ContextHandler2( rParent )
103
1.64k
        , mpNode(std::move( pNode ))
104
1.64k
        , mrDgm(rDgm)
105
1.64k
        {
106
1.64k
            msName = rAttribs.getStringDefaulted( XML_name );
107
1.64k
        }
108
109
    virtual ContextHandlerRef
110
    onCreateContext( ::sal_Int32 aElement,
111
                     const AttributeList& rAttribs ) override
112
3.55k
        {
113
3.55k
            switch( aElement )
114
3.55k
            {
115
1.91k
            case DGM_TOKEN( if ):
116
1.91k
            {
117
                // CT_When
118
1.91k
                ConditionAtomPtr pNode = std::make_shared<ConditionAtom>(mpNode->getLayoutNode(), false, rAttribs.getFastAttributeList());
119
1.91k
                LayoutAtom::connect(mpNode, pNode);
120
1.91k
                return new IfContext( mrDgm, *this, rAttribs, pNode );
121
0
            }
122
1.64k
            case DGM_TOKEN( else ):
123
1.64k
            {
124
                // CT_Otherwise
125
1.64k
                ConditionAtomPtr pNode = std::make_shared<ConditionAtom>(mpNode->getLayoutNode(), true, rAttribs.getFastAttributeList());
126
1.64k
                LayoutAtom::connect(mpNode, pNode);
127
1.64k
                return new IfContext( mrDgm, *this, rAttribs, pNode );
128
0
            }
129
0
            default:
130
0
                break;
131
3.55k
            }
132
133
0
            return this;
134
3.55k
        }
135
private:
136
    OUString msName;
137
    LayoutAtomPtr mpNode;
138
    SmartArtDiagram& mrDgm;
139
};
140
141
class ForEachContext
142
    : public LayoutNodeContext
143
{
144
public:
145
    ForEachContext( SmartArtDiagram& rDgm, ContextHandler2Helper const & rParent, const AttributeList& rAttribs, const ForEachAtomPtr& pAtom )
146
899
        : LayoutNodeContext( rDgm, rParent, rAttribs, pAtom )
147
899
        {
148
899
            pAtom->setRef(rAttribs.getStringDefaulted(XML_ref));
149
899
            pAtom->iterator().loadFromXAttr( rAttribs.getFastAttributeList() );
150
151
899
            LayoutAtomMap& rLayoutAtomMap = getDiagram().getLayout()->getLayoutAtomMap();
152
899
            rLayoutAtomMap[pAtom->getName()] = pAtom;
153
899
        }
154
};
155
156
// CT_LayoutVariablePropertySet
157
class LayoutVariablePropertySetContext
158
    : public ContextHandler2
159
{
160
public:
161
    LayoutVariablePropertySetContext( ContextHandler2Helper const & rParent, LayoutNode::VarMap & aVar )
162
930
        : ContextHandler2( rParent )
163
930
        , mVariables( aVar )
164
930
        {
165
930
        }
166
167
    virtual ContextHandlerRef onCreateContext( ::sal_Int32 aElement, const AttributeList& rAttribs ) override
168
2.18k
        {
169
2.18k
            mVariables[ getBaseToken(aElement) ] = rAttribs.getStringDefaulted( XML_val );
170
2.18k
            return this;
171
2.18k
        }
172
private:
173
    LayoutNode::VarMap & mVariables;
174
};
175
176
}
177
178
// CT_LayoutNode
179
LayoutNodeContext::LayoutNodeContext( SmartArtDiagram& rDgm, ContextHandler2Helper const & rParent,
180
                                      const AttributeList& rAttribs,
181
                                      const LayoutAtomPtr& pAtom )
182
6.16k
    : ContextHandler2( rParent )
183
6.16k
    , mpNode( pAtom )
184
6.16k
    , mrDgm(rDgm)
185
6.16k
{
186
6.16k
    assert( pAtom && "Node must NOT be NULL" );
187
6.16k
    mpNode->setName( rAttribs.getStringDefaulted( XML_name ) );
188
6.16k
}
189
190
LayoutNodeContext::~LayoutNodeContext()
191
6.16k
{
192
6.16k
}
193
194
ContextHandlerRef
195
LayoutNodeContext::onCreateContext( ::sal_Int32 aElement,
196
                                    const AttributeList& rAttribs )
197
15.4k
{
198
15.4k
    switch( aElement )
199
15.4k
    {
200
1.44k
    case DGM_TOKEN( layoutNode ):
201
1.44k
    {
202
1.44k
        LayoutNodePtr pNode = std::make_shared<LayoutNode>();
203
1.44k
        LayoutAtom::connect(mpNode, pNode);
204
205
1.44k
        if (rAttribs.hasAttribute(XML_chOrder))
206
0
        {
207
0
            pNode->setChildOrder(rAttribs.getToken(XML_chOrder, XML_b));
208
0
        }
209
1.44k
        else
210
1.44k
        {
211
4.22k
            for (LayoutAtomPtr pAtom = mpNode; pAtom; pAtom = pAtom->getParent())
212
4.22k
            {
213
4.22k
                auto pLayoutNode = dynamic_cast<LayoutNode*>(pAtom.get());
214
4.22k
                if (pLayoutNode)
215
1.44k
                {
216
1.44k
                    pNode->setChildOrder(pLayoutNode->getChildOrder());
217
1.44k
                    break;
218
1.44k
                }
219
4.22k
            }
220
1.44k
        }
221
222
1.44k
        pNode->setMoveWith( rAttribs.getStringDefaulted( XML_moveWith ) );
223
1.44k
        pNode->setStyleLabel( rAttribs.getStringDefaulted( XML_styleLbl ) );
224
1.44k
        return new LayoutNodeContext( getDiagram(), *this, rAttribs, pNode );
225
0
    }
226
2.19k
    case DGM_TOKEN( shape ):
227
2.19k
    {
228
2.19k
        ShapePtr pShape;
229
230
2.19k
        if( rAttribs.hasAttribute( XML_type ) )
231
1.36k
        {
232
1.36k
            pShape = std::make_shared<Shape>("com.sun.star.drawing.CustomShape");
233
1.36k
            if (!rAttribs.getBool(XML_hideGeom, false))
234
1.13k
            {
235
1.13k
                const sal_Int32 nType(rAttribs.getToken( XML_type, XML_obj ));
236
1.13k
                pShape->setSubType( nType );
237
1.13k
                pShape->getCustomShapeProperties()->setShapePresetType( nType );
238
1.13k
            }
239
1.36k
        }
240
829
        else
241
829
        {
242
829
            pShape = std::make_shared<Shape>("com.sun.star.drawing.GroupShape");
243
829
        }
244
245
2.19k
        pShape->setDiagramRotation(rAttribs.getInteger(XML_rot, 0) * PER_DEGREE);
246
247
2.19k
        pShape->setZOrderOff(rAttribs.getInteger(XML_zOrderOff, 0));
248
249
2.19k
        ShapeAtomPtr pAtom = std::make_shared<ShapeAtom>(mpNode->getLayoutNode(), pShape);
250
2.19k
        LayoutAtom::connect(mpNode, pAtom);
251
2.19k
        return new ShapeContext( *this, ShapePtr(), std::move(pShape) );
252
0
    }
253
0
    case DGM_TOKEN( extLst ):
254
0
        return nullptr;
255
2.07k
    case DGM_TOKEN( alg ):
256
2.07k
    {
257
        // CT_Algorithm
258
2.07k
        AlgAtomPtr pAtom = std::make_shared<AlgAtom>(mpNode->getLayoutNode());
259
2.07k
        LayoutAtom::connect(mpNode, pAtom);
260
2.07k
        return new AlgorithmContext( *this, rAttribs, pAtom );
261
0
    }
262
1.64k
    case DGM_TOKEN( choose ):
263
1.64k
    {
264
        // CT_Choose
265
1.64k
        LayoutAtomPtr pAtom = std::make_shared<ChooseAtom>(mpNode->getLayoutNode());
266
1.64k
        LayoutAtom::connect(mpNode, pAtom);
267
1.64k
        return new ChooseContext( getDiagram(), *this, rAttribs, std::move(pAtom) );
268
0
    }
269
899
    case DGM_TOKEN( forEach ):
270
899
    {
271
        // CT_ForEach
272
899
        ForEachAtomPtr pAtom = std::make_shared<ForEachAtom>(mpNode->getLayoutNode(), rAttribs.getFastAttributeList());
273
899
        LayoutAtom::connect(mpNode, pAtom);
274
899
        return new ForEachContext( getDiagram(), *this, rAttribs, pAtom );
275
0
    }
276
2.35k
    case DGM_TOKEN( constrLst ):
277
        // CT_Constraints
278
2.35k
        return new ConstraintListContext( *this, mpNode );
279
2.09k
    case DGM_TOKEN( presOf ):
280
2.09k
    {
281
        // CT_PresentationOf
282
        // TODO
283
2.09k
        IteratorAttr aIterator;
284
2.09k
        aIterator.loadFromXAttr(rAttribs.getFastAttributeList());
285
2.09k
        break;
286
0
    }
287
1.85k
    case DGM_TOKEN( ruleLst ):
288
        // CT_Rules
289
1.85k
        return new RuleListContext( *this, mpNode );
290
930
    case DGM_TOKEN( varLst ):
291
930
    {
292
930
        LayoutNodePtr pNode(std::dynamic_pointer_cast<LayoutNode>(mpNode));
293
930
        if( pNode )
294
930
        {
295
930
            return new LayoutVariablePropertySetContext( *this, pNode->variables() );
296
930
        }
297
0
        else
298
0
        {
299
0
            SAL_WARN("oox",  "OOX: encountered a varLst in a non layoutNode context" );
300
0
        }
301
0
        break;
302
930
    }
303
0
    default:
304
0
        break;
305
15.4k
    }
306
307
2.09k
    return this;
308
15.4k
}
309
310
}
311
312
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */