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/diagram/datamodelcontext.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 "datamodelcontext.hxx"
21
#include <oox/helper/attributelist.hxx>
22
#include <drawingml/misccontexts.hxx>
23
#include <drawingml/shapepropertiescontext.hxx>
24
#include <drawingml/textbodycontext.hxx>
25
#include <oox/token/namespaces.hxx>
26
#include <oox/token/tokens.hxx>
27
28
using namespace ::oox::core;
29
using namespace ::com::sun::star::uno;
30
31
namespace oox::drawingml {
32
33
namespace {
34
35
// CT_CxnList
36
class CxnListContext
37
    : public ContextHandler2
38
{
39
public:
40
    CxnListContext( ContextHandler2Helper const & rParent,
41
                    svx::diagram::Connections & aConnections )
42
626
        : ContextHandler2( rParent )
43
626
        , mrConnection( aConnections )
44
626
        {
45
626
        }
46
47
    virtual ContextHandlerRef
48
    onCreateContext( sal_Int32 aElementToken,
49
                     const AttributeList& rAttribs ) override
50
5.93k
        {
51
5.93k
            switch( aElementToken )
52
5.93k
            {
53
5.93k
                case DGM_TOKEN( cxn ):
54
5.93k
                {
55
5.93k
                    mrConnection.emplace_back( );
56
5.93k
                    svx::diagram::Connection& rConnection=mrConnection.back();
57
58
5.93k
                    rConnection.mnXMLType = static_cast<svx::diagram::TypeConstant>(rAttribs.getToken( XML_type, XML_parOf ));
59
5.93k
                    rConnection.msModelId = rAttribs.getStringDefaulted( XML_modelId );
60
5.93k
                    rConnection.msSourceId = rAttribs.getStringDefaulted( XML_srcId );
61
5.93k
                    rConnection.msDestId  = rAttribs.getStringDefaulted( XML_destId );
62
5.93k
                    rConnection.msPresId  = rAttribs.getStringDefaulted( XML_presId );
63
5.93k
                    rConnection.msSibTransId  = rAttribs.getStringDefaulted( XML_sibTransId );
64
5.93k
                    rConnection.msParTransId  = rAttribs.getStringDefaulted( XML_parTransId );
65
5.93k
                    rConnection.mnSourceOrder = rAttribs.getInteger( XML_srcOrd, 0 );
66
5.93k
                    rConnection.mnDestOrder = rAttribs.getInteger( XML_destOrd, 0 );
67
68
                    // skip CT_extLst
69
5.93k
                    return nullptr;
70
0
                }
71
0
                default:
72
0
                    break;
73
5.93k
            }
74
75
0
            return this;
76
5.93k
        }
77
private:
78
    svx::diagram::Connections& mrConnection;
79
};
80
81
// CT_presLayoutVars
82
class PresLayoutVarsContext
83
    : public ContextHandler2
84
{
85
public:
86
    PresLayoutVarsContext( ContextHandler2Helper const & rParent,
87
                           svx::diagram::Point & rPoint ) :
88
1.24k
        ContextHandler2( rParent ),
89
1.24k
        mrPoint( rPoint )
90
1.24k
    {
91
1.24k
    }
92
    virtual ContextHandlerRef
93
    onCreateContext( sal_Int32 aElementToken,
94
                     const AttributeList& rAttribs ) override
95
2.50k
    {
96
2.50k
        switch( aElementToken )
97
2.50k
        {
98
            // TODO
99
125
            case DGM_TOKEN( animLvl ):
100
133
            case DGM_TOKEN( animOne ):
101
133
                break;
102
888
            case DGM_TOKEN( bulletEnabled ):
103
888
                mrPoint.mbBulletEnabled = rAttribs.getBool( XML_val, false );
104
888
                break;
105
456
            case DGM_TOKEN( chMax ):
106
456
                mrPoint.mnMaxChildren = rAttribs.getInteger( XML_val, -1 );
107
456
                break;
108
412
            case DGM_TOKEN( chPref ):
109
412
                mrPoint.mnPreferredChildren = rAttribs.getInteger( XML_val, -1 );
110
412
                break;
111
302
            case DGM_TOKEN( dir ):
112
302
                mrPoint.mnDirection = rAttribs.getToken( XML_val, XML_norm );
113
302
                break;
114
0
            case DGM_TOKEN( hierBranch ):
115
0
            {
116
                // need to convert from oox::OptValue to std::optional since 1st is not available in svx
117
0
                const std::optional< sal_Int32 > aOptVal(rAttribs.getToken( XML_val ));
118
0
                if(aOptVal.has_value())
119
0
                    mrPoint.moHierarchyBranch = aOptVal.value();
120
0
                break;
121
125
            }
122
0
            case DGM_TOKEN( orgChart ):
123
0
                mrPoint.mbOrgChartEnabled = rAttribs.getBool( XML_val, false );
124
0
                break;
125
310
            case DGM_TOKEN( resizeHandles ):
126
310
                mrPoint.mnResizeHandles = rAttribs.getToken( XML_val, XML_rel );
127
310
                break;
128
0
            default:
129
0
                break;
130
2.50k
        }
131
132
2.50k
        return this;
133
2.50k
    }
134
135
private:
136
    svx::diagram::Point& mrPoint;
137
};
138
139
// CT_prSet
140
class PropertiesContext
141
    : public ContextHandler2
142
{
143
public:
144
    PropertiesContext( ContextHandler2Helper const & rParent,
145
                       svx::diagram::Point & rPoint,
146
                       const AttributeList& rAttribs ) :
147
6.05k
        ContextHandler2( rParent ),
148
6.05k
        mrPoint( rPoint )
149
6.05k
    {
150
6.05k
        mrPoint.msColorTransformCategoryId = rAttribs.getStringDefaulted( XML_csCatId);
151
6.05k
        mrPoint.msColorTransformTypeId = rAttribs.getStringDefaulted( XML_csTypeId);
152
6.05k
        mrPoint.msLayoutCategoryId = rAttribs.getStringDefaulted( XML_loCatId);
153
6.05k
        mrPoint.msLayoutTypeId = rAttribs.getStringDefaulted( XML_loTypeId);
154
6.05k
        mrPoint.msPlaceholderText = rAttribs.getStringDefaulted( XML_phldrT);
155
6.05k
        mrPoint.msPresentationAssociationId = rAttribs.getStringDefaulted( XML_presAssocID);
156
6.05k
        mrPoint.msPresentationLayoutName = rAttribs.getStringDefaulted( XML_presName);
157
6.05k
        mrPoint.msPresentationLayoutStyleLabel = rAttribs.getStringDefaulted( XML_presStyleLbl);
158
6.05k
        mrPoint.msQuickStyleCategoryId = rAttribs.getStringDefaulted( XML_qsCatId);
159
6.05k
        mrPoint.msQuickStyleTypeId = rAttribs.getStringDefaulted( XML_qsTypeId);
160
161
6.05k
        mrPoint.mnCustomAngle = rAttribs.getInteger( XML_custAng, -1 );
162
6.05k
        mrPoint.mnPercentageNeighbourWidth = rAttribs.getInteger( XML_custLinFactNeighborX, -1 );
163
6.05k
        mrPoint.mnPercentageNeighbourHeight = rAttribs.getInteger( XML_custLinFactNeighborY, -1 );
164
6.05k
        mrPoint.mnPercentageOwnWidth = rAttribs.getInteger( XML_custLinFactX, -1 );
165
6.05k
        mrPoint.mnPercentageOwnHeight = rAttribs.getInteger( XML_custLinFactY, -1 );
166
6.05k
        mrPoint.mnIncludeAngleScale = rAttribs.getInteger( XML_custRadScaleInc, -1 );
167
6.05k
        mrPoint.mnRadiusScale = rAttribs.getInteger( XML_custRadScaleRad, -1 );
168
6.05k
        mrPoint.mnWidthScale = rAttribs.getInteger( XML_custScaleX, -1 );
169
6.05k
        mrPoint.mnHeightScale = rAttribs.getInteger( XML_custScaleY, -1 );
170
6.05k
        mrPoint.mnWidthOverride = rAttribs.getInteger( XML_custSzX, -1 );
171
6.05k
        mrPoint.mnHeightOverride = rAttribs.getInteger( XML_custSzY, -1 );
172
6.05k
        mrPoint.mnLayoutStyleCount = rAttribs.getInteger( XML_presStyleCnt, -1 );
173
6.05k
        mrPoint.mnLayoutStyleIndex = rAttribs.getInteger( XML_presStyleIdx, -1 );
174
175
6.05k
        mrPoint.mbCoherent3DOffset = rAttribs.getBool( XML_coherent3DOff, false );
176
6.05k
        mrPoint.mbCustomHorizontalFlip = rAttribs.getBool( XML_custFlipHor, false );
177
6.05k
        mrPoint.mbCustomVerticalFlip = rAttribs.getBool( XML_custFlipVert, false );
178
6.05k
        mrPoint.mbCustomText = rAttribs.getBool( XML_custT, false );
179
6.05k
        mrPoint.mbIsPlaceholder = rAttribs.getBool( XML_phldr, false );
180
6.05k
    }
181
182
    virtual ContextHandlerRef
183
    onCreateContext( sal_Int32 aElementToken,
184
                     const AttributeList& ) override
185
1.24k
        {
186
1.24k
            switch( aElementToken )
187
1.24k
            {
188
1.24k
            case DGM_TOKEN( presLayoutVars ):
189
1.24k
                return new PresLayoutVarsContext( *this, mrPoint );
190
0
            case DGM_TOKEN( style ):
191
                // skip CT_shapeStyle
192
0
                return nullptr;
193
0
            default:
194
0
                break;
195
1.24k
            }
196
0
            return this;
197
1.24k
        }
198
199
private:
200
    svx::diagram::Point& mrPoint;
201
};
202
203
// CL_Pt
204
class PtContext
205
    : public ContextHandler2
206
{
207
public:
208
    PtContext( ContextHandler2Helper const& rParent,
209
               const AttributeList& rAttribs,
210
               svx::diagram::Point& rPoint,
211
               DiagramData& rDiagramData):
212
6.84k
        ContextHandler2( rParent ),
213
6.84k
        mrPoint( rPoint ),
214
6.84k
        mrDiagramData( rDiagramData )
215
6.84k
    {
216
6.84k
        mrPoint.msModelId = rAttribs.getStringDefaulted( XML_modelId );
217
218
        // the default type is XML_node
219
6.84k
        const sal_Int32 nType  = rAttribs.getToken( XML_type, XML_node );
220
6.84k
        mrPoint.mnXMLType = static_cast<svx::diagram::TypeConstant>(nType);
221
222
        // ignore the cxnId unless it is this type. See 5.15.3.1.3 in Primer
223
6.84k
        if( ( nType == XML_parTrans ) || ( nType == XML_sibTrans ) )
224
1.91k
            mrPoint.msCnxId = rAttribs.getStringDefaulted( XML_cxnId );
225
6.84k
    }
226
227
    virtual ContextHandlerRef
228
    onCreateContext( sal_Int32 aElementToken,
229
                     const AttributeList& rAttribs ) override
230
15.1k
        {
231
15.1k
            switch( aElementToken )
232
15.1k
            {
233
0
            case DGM_TOKEN( extLst ):
234
0
                return nullptr;
235
6.05k
            case DGM_TOKEN( prSet ):
236
6.05k
                return new PropertiesContext( *this, mrPoint, rAttribs );
237
5.56k
            case DGM_TOKEN( spPr ):
238
5.56k
            {
239
5.56k
                Shape* pShape(mrDiagramData.getOrCreateAssociatedShape(mrPoint, true));
240
5.56k
                return new ShapePropertiesContext( *this, *pShape );
241
0
            }
242
3.50k
            case DGM_TOKEN( t ):
243
3.50k
            {
244
3.50k
                Shape* pShape(mrDiagramData.getOrCreateAssociatedShape(mrPoint, true));
245
3.50k
                TextBodyPtr xTextBody = std::make_shared<TextBody>();
246
3.50k
                pShape->setTextBody( xTextBody );
247
3.50k
                return new TextBodyContext( *this, *xTextBody );
248
0
            }
249
0
            default:
250
0
                break;
251
15.1k
            }
252
0
            return this;
253
15.1k
        }
254
255
private:
256
    svx::diagram::Point& mrPoint;
257
    DiagramData& mrDiagramData;
258
};
259
260
// CT_PtList
261
class PtListContext
262
    : public ContextHandler2
263
{
264
public:
265
    PtListContext( ContextHandler2Helper const & rParent,  svx::diagram::Points& rPoints, DiagramData& rDiagramData) :
266
778
        ContextHandler2( rParent ),
267
778
        mrPoints( rPoints ),
268
778
        mrDiagramData( rDiagramData )
269
778
    {}
270
    virtual ContextHandlerRef
271
    onCreateContext( sal_Int32 aElementToken,
272
                     const AttributeList& rAttribs ) override
273
6.84k
        {
274
6.84k
            switch( aElementToken )
275
6.84k
            {
276
6.84k
            case DGM_TOKEN( pt ):
277
6.84k
            {
278
                // CT_Pt
279
6.84k
                mrPoints.emplace_back( );
280
6.84k
                return new PtContext( *this, rAttribs, mrPoints.back(), mrDiagramData );
281
0
            }
282
0
            default:
283
0
                break;
284
6.84k
            }
285
0
            return this;
286
6.84k
        }
287
288
private:
289
    svx::diagram::Points& mrPoints;
290
    DiagramData& mrDiagramData;
291
};
292
293
// CT_BackgroundFormatting
294
class BackgroundFormattingContext
295
    : public ContextHandler2
296
{
297
public:
298
    BackgroundFormattingContext( ContextHandler2Helper const & rParent, OoxDiagramDataPtr const& pModel )
299
783
        : ContextHandler2( rParent )
300
783
        , mpDataModel( pModel )
301
783
        {
302
783
            assert( pModel && "the data model MUST NOT be NULL" );
303
783
        }
304
305
    virtual ContextHandlerRef
306
    onCreateContext( sal_Int32 aElementToken,
307
                     const AttributeList& rAttribs ) override
308
0
        {
309
0
            switch( aElementToken )
310
0
            {
311
0
            case A_TOKEN( blipFill ):
312
0
            case A_TOKEN( gradFill ):
313
0
            case A_TOKEN( grpFill ):
314
0
            case A_TOKEN( noFill ):
315
0
            case A_TOKEN( pattFill ):
316
0
            case A_TOKEN( solidFill ):
317
                // EG_FillProperties
318
0
                return FillPropertiesContext::createFillContext(*this, aElementToken, rAttribs, *mpDataModel->getBackgroundShapeFillProperties(), nullptr);
319
0
            case A_TOKEN( effectDag ):
320
0
            case A_TOKEN( effectLst ):
321
                // TODO
322
                // EG_EffectProperties
323
0
                break;
324
0
            default:
325
0
                break;
326
0
            }
327
0
            return this;
328
0
        }
329
private:
330
    OoxDiagramDataPtr mpDataModel;
331
};
332
333
}
334
335
DataModelContext::DataModelContext( ContextHandler2Helper const& rParent,
336
                                    const OoxDiagramDataPtr& pDataModel )
337
817
    : ContextHandler2( rParent )
338
817
    , mpDataModel( pDataModel )
339
817
{
340
817
    assert( pDataModel && "Data Model must not be NULL" );
341
817
}
342
343
DataModelContext::~DataModelContext()
344
817
{
345
    // some debug
346
817
    mpDataModel->dump();
347
817
}
348
349
ContextHandlerRef
350
DataModelContext::onCreateContext( ::sal_Int32 aElement,
351
                                   const AttributeList& rAttribs )
352
4.35k
{
353
4.35k
    switch( aElement )
354
4.35k
    {
355
626
    case DGM_TOKEN( cxnLst ):
356
        // CT_CxnList
357
626
        return new CxnListContext( *this, mpDataModel->getConnections() );
358
778
    case DGM_TOKEN( ptLst ):
359
        // CT_PtList
360
778
        return new PtListContext( *this, mpDataModel->getPoints(), *mpDataModel );
361
783
    case DGM_TOKEN( bg ):
362
        // CT_BackgroundFormatting
363
783
        return new BackgroundFormattingContext( *this, mpDataModel );
364
783
    case DGM_TOKEN( whole ):
365
        // CT_WholeE2oFormatting
366
        // TODO
367
783
        return nullptr;
368
305
    case DGM_TOKEN( extLst ):
369
610
    case A_TOKEN( ext ):
370
610
        break;
371
305
    case DSP_TOKEN( dataModelExt ):
372
305
        mpDataModel->getExtDrawings().push_back( rAttribs.getStringDefaulted( XML_relId ) );
373
305
        break;
374
468
    default:
375
468
        break;
376
4.35k
    }
377
378
1.38k
    return this;
379
4.35k
}
380
381
}
382
383
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */