Coverage Report

Created: 2026-06-30 11:14

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/libreoffice/oox/source/shape/ShapeContextHandler.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/beans/XPropertySet.hpp>
21
#include <com/sun/star/drawing/XGluePointsSupplier.hpp>
22
#include <com/sun/star/container/XIdentifierContainer.hpp>
23
#include <com/sun/star/xml/dom/XDocument.hpp>
24
#include <com/sun/star/xml/sax/XFastSAXSerializable.hpp>
25
26
#include <oox/shape/ShapeContextHandler.hxx>
27
#include <oox/shape/ShapeDrawingFragmentHandler.hxx>
28
#include "LockedCanvasContext.hxx"
29
#include "WordprocessingCanvasContext.hxx"
30
#include "WpsContext.hxx"
31
#include "WpgContext.hxx"
32
#include <basegfx/matrix/b2dhommatrix.hxx>
33
#include <oox/vml/vmldrawing.hxx>
34
#include <oox/vml/vmldrawingfragment.hxx>
35
#include <oox/vml/vmlshape.hxx>
36
#include <oox/vml/vmlshapecontainer.hxx>
37
#include <oox/shape/ShapeFilterBase.hxx>
38
#include <oox/token/namespaces.hxx>
39
#include <oox/token/tokens.hxx>
40
#include <oox/drawingml/theme.hxx>
41
#include <oox/drawingml/themefragmenthandler.hxx>
42
#include <svx/svdogrp.hxx>
43
#include <svx/svdoedge.hxx>
44
#include <svx/svdobj.hxx>
45
46
#include <drawingml/connectorhelper.hxx>
47
48
#include <memory>
49
#include <utility>
50
51
using namespace ::com::sun::star;
52
53
namespace oox::shape {
54
using namespace core;
55
using namespace drawingml;
56
57
ShapeContextHandler::ShapeContextHandler(rtl::Reference<ShapeFilterBase> xFilterBase) :
58
2.20k
  m_bFullWPGSUpport(false),
59
2.20k
  mxShapeFilterBase(std::move(xFilterBase))
60
61
2.20k
{
62
2.20k
}
63
64
ShapeContextHandler::~ShapeContextHandler()
65
2.20k
{
66
2.20k
}
67
68
uno::Reference<xml::sax::XFastContextHandler> ShapeContextHandler::getLockedCanvasContext(sal_Int32 nElement)
69
320
{
70
320
    if (!mxLockedCanvasContext.is())
71
40
    {
72
40
        FragmentHandler2Ref rFragmentHandler(new ShapeFragmentHandler(*mxShapeFilterBase, msRelationFragmentPath));
73
74
40
        switch (nElement & 0xffff)
75
40
        {
76
40
            case XML_lockedCanvas:
77
40
                mxLockedCanvasContext.set(new LockedCanvasContext(*rFragmentHandler));
78
40
                break;
79
0
            default:
80
0
                break;
81
40
        }
82
40
    }
83
84
320
    return static_cast<ContextHandler *>(mxLockedCanvasContext.get());
85
320
}
86
87
/*
88
 * This method creates new ChartGraphicDataContext Object.
89
 */
90
uno::Reference<xml::sax::XFastContextHandler> ShapeContextHandler::getChartShapeContext(sal_Int32 nElement)
91
115
{
92
115
    if (!mxChartShapeContext.is())
93
23
    {
94
23
        switch (nElement & 0xffff)
95
23
        {
96
23
            case XML_chart:
97
23
            {
98
23
                std::unique_ptr<ContextHandler2Helper> pFragmentHandler(
99
23
                        new ShapeFragmentHandler(*mxShapeFilterBase, msRelationFragmentPath));
100
23
                mpShape = std::make_shared<Shape>("com.sun.star.drawing.OLE2Shape" );
101
23
                mxChartShapeContext.set(new ChartGraphicDataContext(*pFragmentHandler, mpShape, true));
102
23
                break;
103
0
            }
104
0
            default:
105
0
                break;
106
23
        }
107
23
    }
108
109
115
    return mxChartShapeContext;
110
115
}
111
112
uno::Reference<xml::sax::XFastContextHandler> ShapeContextHandler::getWpsContext(sal_Int32 nStartElement, sal_Int32 nElement)
113
4.85k
{
114
4.85k
    if (!mxWpsContext.is())
115
845
    {
116
845
        FragmentHandler2Ref rFragmentHandler(new ShapeFragmentHandler(*mxShapeFilterBase, msRelationFragmentPath));
117
118
845
        uno::Reference<drawing::XShape> xShape;
119
        // No element happens in case of pretty-printed XML, bodyPr is the case when we are called again after <wps:txbx>.
120
845
        if (!nElement || nElement == WPS_TOKEN(bodyPr))
121
            // Assume that this is just a continuation of the previous shape.
122
324
            xShape = mxSavedShape;
123
124
845
        switch (getBaseToken(nStartElement))
125
845
        {
126
845
            case XML_wsp:
127
845
                mxWpsContext.set(new WpsContext(
128
845
                                     *rFragmentHandler,
129
845
                                     xShape,
130
845
                                     nullptr,
131
845
                                     std::make_shared<oox::drawingml::Shape>(
132
845
                                             "com.sun.star.drawing.CustomShape")));
133
845
                break;
134
0
            default:
135
0
                break;
136
845
        }
137
845
    }
138
139
4.85k
    return mxWpsContext;
140
4.85k
}
141
142
uno::Reference<xml::sax::XFastContextHandler> ShapeContextHandler::getWpgContext(sal_Int32 nElement)
143
1.25k
{
144
1.25k
    if (!mxWpgContext.is())
145
139
    {
146
139
        FragmentHandler2Ref rFragmentHandler(new ShapeFragmentHandler(*mxShapeFilterBase, msRelationFragmentPath));
147
148
139
        switch (getBaseToken(nElement))
149
139
        {
150
139
            case XML_wgp:
151
139
            {
152
139
                mxWpgContext.set(new WpgContext(*rFragmentHandler, oox::drawingml::ShapePtr()));
153
139
                mxWpgContext->setFullWPGSupport(m_bFullWPGSUpport);
154
139
                break;
155
0
            }
156
0
            default:
157
0
                break;
158
139
        }
159
139
    }
160
161
1.25k
    return static_cast<ContextHandler *>(mxWpgContext.get());
162
1.25k
}
163
164
uno::Reference<xml::sax::XFastContextHandler> const &
165
ShapeContextHandler::getGraphicShapeContext(::sal_Int32 Element )
166
5.52k
{
167
5.52k
    if (! mxGraphicShapeContext.is())
168
668
    {
169
668
        auto pFragmentHandler = std::make_shared<ShapeFragmentHandler>(*mxShapeFilterBase, msRelationFragmentPath);
170
171
668
        switch (Element & 0xffff)
172
668
        {
173
0
            case XML_graphic:
174
0
                mpShape = std::make_shared<Shape>("com.sun.star.drawing.GraphicObjectShape" );
175
0
                mxGraphicShapeContext.set
176
0
                (new GraphicalObjectFrameContext(*pFragmentHandler, nullptr, mpShape, true));
177
0
                break;
178
668
            case XML_pic:
179
668
                mpShape = std::make_shared<Shape>("com.sun.star.drawing.GraphicObjectShape" );
180
668
                mxGraphicShapeContext.set
181
668
                (new GraphicShapeContext(*pFragmentHandler, nullptr, mpShape));
182
668
                break;
183
0
            default:
184
0
                break;
185
668
        }
186
668
    }
187
188
5.52k
    return mxGraphicShapeContext;
189
5.52k
}
190
191
uno::Reference<xml::sax::XFastContextHandler>
192
ShapeContextHandler::getDrawingShapeContext()
193
16.0k
{
194
16.0k
    if (!mxDrawingFragmentHandler.is())
195
2.08k
    {
196
2.08k
        mpDrawing = std::make_shared<oox::vml::Drawing>( *mxShapeFilterBase, mxDrawPage, oox::vml::VMLDRAWING_WORD );
197
2.08k
        mxDrawingFragmentHandler.set
198
2.08k
           (new oox::vml::DrawingFragment
199
2.08k
            ( *mxShapeFilterBase, msRelationFragmentPath, *mpDrawing ));
200
2.08k
    }
201
14.0k
    else
202
14.0k
    {
203
        // Reset the handler if fragment path has changed
204
14.0k
        OUString sHandlerFragmentPath = mxDrawingFragmentHandler->getFragmentPath();
205
14.0k
        if ( msRelationFragmentPath != sHandlerFragmentPath )
206
0
        {
207
0
            mxDrawingFragmentHandler.clear();
208
0
            mxDrawingFragmentHandler.set
209
0
               (new oox::vml::DrawingFragment
210
0
                ( *mxShapeFilterBase, msRelationFragmentPath, *mpDrawing ));
211
0
        }
212
14.0k
    }
213
16.0k
    return static_cast<ContextHandler *>(mxDrawingFragmentHandler.get());
214
16.0k
}
215
216
uno::Reference<xml::sax::XFastContextHandler>
217
ShapeContextHandler::getDiagramShapeContext()
218
323
{
219
323
    if (!mxDiagramShapeContext.is())
220
155
    {
221
155
        auto pFragmentHandler = std::make_shared<ShapeFragmentHandler>(*mxShapeFilterBase, msRelationFragmentPath);
222
155
        mpShape = std::make_shared<Shape>();
223
155
        mpShape->setSize(maSize);
224
155
        mxDiagramShapeContext.set(new DiagramGraphicDataContext(*pFragmentHandler, mpShape, EMPTY_OUSTRING));
225
155
    }
226
227
323
    return mxDiagramShapeContext;
228
323
}
229
230
uno::Reference<xml::sax::XFastContextHandler> ShapeContextHandler::getWordprocessingCanvasContext(sal_Int32 nElement)
231
0
{
232
0
    if (!mxWordprocessingCanvasContext.is())
233
0
    {
234
0
        FragmentHandler2Ref rFragmentHandler(new ShapeFragmentHandler(*mxShapeFilterBase, msRelationFragmentPath));
235
236
0
        switch (getBaseToken(nElement))
237
0
        {
238
0
            case XML_wpc:
239
0
                mxWordprocessingCanvasContext.set(new WordprocessingCanvasContext(*rFragmentHandler, maSize));
240
0
                break;
241
0
            default:
242
0
                break;
243
0
        }
244
0
    }
245
246
0
    return static_cast<ContextHandler *>(mxWordprocessingCanvasContext.get());
247
0
}
248
249
uno::Reference<xml::sax::XFastContextHandler>
250
ShapeContextHandler::getContextHandler(sal_Int32 nElement)
251
21.9k
{
252
21.9k
    uno::Reference<xml::sax::XFastContextHandler> xResult;
253
21.9k
    const sal_uInt32 nStartToken = getStartToken();
254
255
21.9k
    switch (getNamespace( nStartToken ))
256
21.9k
    {
257
9.60k
        case NMSP_doc:
258
9.60k
        case NMSP_vml:
259
9.60k
            xResult.set(getDrawingShapeContext());
260
9.60k
            break;
261
323
        case NMSP_dmlDiagram:
262
323
            xResult.set(getDiagramShapeContext());
263
323
            break;
264
320
        case NMSP_dmlLockedCanvas:
265
320
            xResult.set(getLockedCanvasContext(nStartToken));
266
320
            break;
267
115
        case NMSP_dmlChart:
268
115
            xResult.set(getChartShapeContext(nStartToken));
269
115
            break;
270
4.85k
        case NMSP_wps:
271
4.85k
            xResult.set(getWpsContext(nStartToken, nElement));
272
4.85k
            break;
273
1.25k
        case NMSP_wpg:
274
1.25k
            xResult.set(getWpgContext(nStartToken));
275
1.25k
            break;
276
0
        case NMSP_wpc:
277
0
            xResult.set(getWordprocessingCanvasContext(nStartToken));
278
0
            break;
279
5.52k
        default:
280
5.52k
            xResult.set(getGraphicShapeContext(nStartToken));
281
5.52k
            break;
282
21.9k
    }
283
284
21.9k
    return xResult;
285
21.9k
}
286
287
// css::xml::sax::XFastContextHandler:
288
void SAL_CALL ShapeContextHandler::startFastElement
289
(::sal_Int32 Element,
290
 const uno::Reference< xml::sax::XFastAttributeList > & Attribs)
291
3.37k
{
292
3.37k
    mxShapeFilterBase->filter(maMediaDescriptor);
293
294
3.37k
    if (Element == DGM_TOKEN(relIds) || Element == LC_TOKEN(lockedCanvas) || Element == C_TOKEN(chart) ||
295
3.37k
        Element == WPS_TOKEN(wsp) || Element == WPG_TOKEN(wgp) || Element == OOX_TOKEN(dmlPicture, pic)
296
1.82k
        || Element == WPC_TOKEN(wpc))
297
1.54k
    {
298
        // Parse the theme relation, if available; the diagram won't have colors without it.
299
1.54k
        if (!mpThemePtr && !msRelationFragmentPath.isEmpty())
300
1.08k
        {
301
            // Get Target for Type = "officeDocument" from _rels/.rels file
302
            // aOfficeDocumentFragmentPath is pointing to "word/document.xml" for docx & to "ppt/presentation.xml" for pptx
303
1.08k
            FragmentHandlerRef rFragmentHandlerRef(new ShapeFragmentHandler(*mxShapeFilterBase, u"/"_ustr));
304
1.08k
            OUString aOfficeDocumentFragmentPath = rFragmentHandlerRef->getFragmentPathFromFirstTypeFromOfficeDoc( u"officeDocument" );
305
306
            // Get the theme DO NOT  use msRelationFragmentPath for getting theme as for a document there is a single theme in document.xml.rels
307
            // and the same is used by header and footer as well.
308
1.08k
            FragmentHandlerRef rFragmentHandler(new ShapeFragmentHandler(*mxShapeFilterBase, aOfficeDocumentFragmentPath));
309
1.08k
            OUString aThemeFragmentPath = rFragmentHandler->getFragmentPathFromFirstTypeFromOfficeDoc( u"theme" );
310
311
1.08k
            if (!aThemeFragmentPath.isEmpty())
312
674
            {
313
674
                mpThemePtr = std::make_shared<Theme>();
314
674
                auto pTheme = std::make_shared<model::Theme>();
315
674
                mpThemePtr->setTheme(pTheme);
316
674
                mxShapeFilterBase->importFragment(new ThemeFragmentHandler(*mxShapeFilterBase, aThemeFragmentPath, *mpThemePtr, *pTheme));
317
674
                mxShapeFilterBase->setCurrentTheme(mpThemePtr);
318
674
            }
319
1.08k
        }
320
462
        else if (mpThemePtr && !mxShapeFilterBase->getCurrentTheme())
321
232
        {
322
232
            mxShapeFilterBase->setCurrentTheme(mpThemePtr);
323
232
        }
324
325
1.54k
        createFastChildContext(Element, Attribs);
326
1.54k
    }
327
328
    // Entering VML block (startFastElement() is called for the outermost tag),
329
    // handle possible recursion.
330
3.37k
    if ( getContextHandler() == getDrawingShapeContext() )
331
1.82k
        mpDrawing->getShapes().pushMark();
332
333
3.37k
    uno::Reference<XFastContextHandler> xContextHandler(getContextHandler());
334
335
3.37k
    if (xContextHandler.is())
336
3.26k
        xContextHandler->startFastElement(Element, Attribs);
337
3.37k
}
338
339
void SAL_CALL ShapeContextHandler::startUnknownElement
340
(const OUString & Namespace, const OUString & Name,
341
 const uno::Reference< xml::sax::XFastAttributeList > & Attribs)
342
0
{
343
0
    if ( getContextHandler() == getDrawingShapeContext() )
344
0
        mpDrawing->getShapes().pushMark();
345
346
0
    uno::Reference<XFastContextHandler> xContextHandler(getContextHandler());
347
348
0
    if (xContextHandler.is())
349
0
        xContextHandler->startUnknownElement(Namespace, Name, Attribs);
350
0
}
351
352
void SAL_CALL ShapeContextHandler::endFastElement(::sal_Int32 Element)
353
3.23k
{
354
3.23k
    uno::Reference<XFastContextHandler> xContextHandler(getContextHandler());
355
356
3.23k
    if (xContextHandler.is())
357
3.23k
        xContextHandler->endFastElement(Element);
358
    // In case a textbox is sent, and later we get additional properties for
359
    // the textbox, then the wps context is not cleared, so do that here.
360
3.23k
    if (Element != (NMSP_wps | XML_wsp))
361
2.71k
        return;
362
363
521
    uno::Reference<lang::XServiceInfo> xServiceInfo(mxSavedShape, uno::UNO_QUERY);
364
521
    bool bTextFrame = xServiceInfo.is() && xServiceInfo->supportsService(u"com.sun.star.text.TextFrame"_ustr);
365
521
    bool bTextBox = false;
366
521
    if (!bTextFrame)
367
521
    {
368
521
        uno::Reference<beans::XPropertySet> xPropertySet(mxSavedShape, uno::UNO_QUERY);
369
521
        if (xPropertySet.is())
370
324
            xPropertySet->getPropertyValue(u"TextBox"_ustr) >>= bTextBox;
371
521
    }
372
521
    if (bTextFrame || bTextBox)
373
324
        mxWpsContext.clear();
374
521
    mxSavedShape.clear();
375
521
}
376
377
void SAL_CALL ShapeContextHandler::endUnknownElement
378
(const OUString & Namespace,
379
 const OUString & Name)
380
0
{
381
0
    uno::Reference<XFastContextHandler> xContextHandler(getContextHandler());
382
383
0
    if (xContextHandler.is())
384
0
        xContextHandler->endUnknownElement(Namespace, Name);
385
0
}
386
387
uno::Reference< xml::sax::XFastContextHandler > SAL_CALL
388
ShapeContextHandler::createFastChildContext
389
(::sal_Int32 Element,
390
 const uno::Reference< xml::sax::XFastAttributeList > & Attribs)
391
8.67k
{
392
8.67k
    uno::Reference< xml::sax::XFastContextHandler > xResult;
393
8.67k
    uno::Reference< xml::sax::XFastContextHandler > xContextHandler(getContextHandler(Element));
394
395
8.67k
    if (xContextHandler.is())
396
8.67k
        xResult.set(xContextHandler->createFastChildContext
397
8.67k
                    (Element, Attribs));
398
399
8.67k
    return xResult;
400
8.67k
}
401
402
uno::Reference< xml::sax::XFastContextHandler > SAL_CALL
403
ShapeContextHandler::createUnknownChildContext
404
(const OUString & Namespace,
405
 const OUString & Name,
406
 const uno::Reference< xml::sax::XFastAttributeList > & Attribs)
407
0
{
408
0
    uno::Reference<XFastContextHandler> xContextHandler(getContextHandler());
409
410
0
    if (xContextHandler.is())
411
0
        return xContextHandler->createUnknownChildContext
412
0
            (Namespace, Name, Attribs);
413
414
0
    return uno::Reference< xml::sax::XFastContextHandler >();
415
0
}
416
417
void SAL_CALL ShapeContextHandler::characters(const OUString & aChars)
418
330
{
419
330
    uno::Reference<XFastContextHandler> xContextHandler(getContextHandler());
420
421
330
    if (xContextHandler.is())
422
330
        xContextHandler->characters(aChars);
423
330
}
424
425
namespace // helpers for case mxWordprocessingCanvasContext
426
{
427
    void lcl_createShapeMap(oox::drawingml::ShapePtr rShapePtr,
428
                            oox::drawingml::ShapeIdMap& rShapeMap)
429
0
{
430
0
    std::vector< ShapePtr >& rChildren = rShapePtr->getChildren();
431
0
    if (rChildren.empty())
432
0
        return;
433
0
    for (auto& pIt : rChildren)
434
0
    {
435
0
        rShapeMap[pIt->getId()] = pIt; // add child itself
436
0
        lcl_createShapeMap(pIt, rShapeMap); // and all its descendants
437
0
    }
438
0
}
439
440
} // end anonymous namespace
441
442
uno::Reference< drawing::XShape >
443
ShapeContextHandler::getShape()
444
3.23k
{
445
3.23k
    uno::Reference< drawing::XShape > xResult;
446
3.23k
    uno::Reference< drawing::XShapes > xShapes = mxDrawPage;
447
448
3.23k
    if (mxShapeFilterBase && xShapes.is())
449
3.23k
    {
450
3.23k
        if ( getContextHandler() == getDrawingShapeContext() )
451
1.79k
        {
452
1.79k
            mpDrawing->finalizeFragmentImport();
453
1.79k
            if( std::shared_ptr< vml::ShapeBase > pShape = mpDrawing->getShapes().takeLastShape() )
454
1.71k
                xResult = pShape->convertAndInsert( xShapes );
455
            // Only now remove the recursion mark, because getShape() is called in writerfilter
456
            // after endFastElement().
457
1.79k
            mpDrawing->getShapes().popMark();
458
1.79k
        }
459
1.43k
        else if (mxDiagramShapeContext.is())
460
42
        {
461
42
            basegfx::B2DHomMatrix aMatrix;
462
42
            static bool bIgnoreExtDrawings(nullptr != std::getenv("DIAGRAM_IGNORE_EXTDRAWINGS"));
463
464
42
            if (bIgnoreExtDrawings || mpShape->getExtDrawings().empty())
465
12
            {
466
12
                mpShape->addShape( *mxShapeFilterBase, mpThemePtr.get(), xShapes, aMatrix, mpShape->getFillProperties() );
467
12
                xResult = mpShape->getXShape();
468
12
            }
469
30
            else
470
30
            {
471
                // Prerendered diagram output is available, then use that, and throw away the original result.
472
30
                for (auto const& extDrawing : mpShape->getExtDrawings())
473
30
                {
474
30
                    OUString aFragmentPath(mxDiagramShapeContext->getFragmentPathFromRelId(extDrawing));
475
30
                    oox::drawingml::ShapePtr pShapePtr = std::make_shared<Shape>( "com.sun.star.drawing.GroupShape" );
476
30
                    pShapePtr->setDiagramType();
477
30
                    mxShapeFilterBase->importFragment(new ShapeDrawingFragmentHandler(*mxShapeFilterBase, aFragmentPath, pShapePtr));
478
479
30
                    if (mpShape->getFontRefColorForNodes().isUsed())
480
0
                        applyFontRefColor(pShapePtr, mpShape->getFontRefColorForNodes());
481
482
                    // migrate DiagramHelper_svx to new oox::Shape (from mpShape which was loaded
483
                    // to pShapePtr where the geometry is now constructed)
484
30
                    mpShape->migrateDiagramHelperToNewShape(pShapePtr);
485
486
                    // use now migrated DiagramHelper_oox
487
30
                    pShapePtr->keepDiagramDrawing(*mxShapeFilterBase, aFragmentPath);
488
489
30
                    if (!mpShape->getChildren().empty())
490
30
                    {
491
                        // first child is diagram background - we want to keep it, as drawingML fallback doesn't contain it
492
30
                        auto& aChildren = pShapePtr->getChildren();
493
30
                        ShapePtr pBackground = mpShape->getChildren().front();
494
30
                        aChildren.insert(aChildren.begin(), pBackground);
495
30
                    }
496
497
30
                    pShapePtr->addShape( *mxShapeFilterBase, mpThemePtr.get(), xShapes, aMatrix, pShapePtr->getFillProperties() );
498
30
                    xResult = pShapePtr->getXShape();
499
30
                }
500
30
                mpShape.reset();
501
30
            }
502
42
            mxDiagramShapeContext.clear();
503
42
        }
504
1.39k
        else if (mxLockedCanvasContext.is())
505
40
        {
506
40
            ShapePtr pShape = mxLockedCanvasContext->getShape();
507
40
            if (pShape)
508
40
            {
509
40
                basegfx::B2DHomMatrix aMatrix;
510
40
                pShape->addShape(*mxShapeFilterBase, mpThemePtr.get(), xShapes, aMatrix, pShape->getFillProperties());
511
40
                xResult = pShape->getXShape();
512
40
                mxLockedCanvasContext.clear();
513
40
            }
514
40
        }
515
1.35k
        else if (mxWordprocessingCanvasContext.is())
516
0
        {
517
             // group which represents the drawing canvas
518
0
            ShapePtr pShape = mxWordprocessingCanvasContext->getShape();
519
0
            if (pShape)
520
0
            {
521
0
                basegfx::B2DHomMatrix aMatrix;
522
0
                pShape->addShape(*mxShapeFilterBase, mpThemePtr.get(), xShapes, aMatrix, pShape->getFillProperties());
523
524
                // create a flat map of all shapes in the drawing canvas group.
525
0
                oox::drawingml::ShapeIdMap aShapeMap;
526
0
                lcl_createShapeMap(pShape, aShapeMap);
527
528
                // Traverse aShapeMap and generate edge related properties.
529
0
                for (auto& rIt : aShapeMap)
530
0
                {
531
0
                    if ((rIt.second)->getServiceName() == "com.sun.star.drawing.ConnectorShape")
532
0
                    {
533
0
                        ConnectorHelper::applyConnections(rIt.second, aShapeMap);
534
535
0
                        if (rIt.second->getConnectorName() == u"bentConnector3"_ustr
536
0
                           || rIt.second->getConnectorName() == u"bentConnector4"_ustr
537
0
                           || rIt.second->getConnectorName() == u"bentConnector5"_ustr)
538
0
                        {
539
0
                           ConnectorHelper::applyBentHandleAdjustments(rIt.second);
540
0
                        }
541
0
                        else if (rIt.second->getConnectorName() == u"curvedConnector3"_ustr
542
0
                           || rIt.second->getConnectorName() == u"curvedConnector4"_ustr
543
0
                           || rIt.second->getConnectorName() == u"curvedConnector5"_ustr)
544
0
                        {
545
0
                            ConnectorHelper::applyCurvedHandleAdjustments(rIt.second);
546
0
                        }
547
                        // else use the default path of LibreOffice.
548
                        // curveConnector2 and bentConnector2 do not have handles.
549
0
                    }
550
0
                }
551
0
                xResult = pShape->getXShape();
552
0
                mxWordprocessingCanvasContext.clear();
553
0
            }
554
0
        }
555
        //NMSP_dmlChart == getNamespace( mnStartToken ) check is introduced to make sure that
556
        //mnStartToken is set as NMSP_dmlChart in setStartToken.
557
        //Only in case it is set then only the below block of code for ChartShapeContext should be executed.
558
1.35k
        else if (mxChartShapeContext.is() && (NMSP_dmlChart == getNamespace( getStartToken() )))
559
23
        {
560
23
            basegfx::B2DHomMatrix aMatrix;
561
23
            oox::drawingml::ShapePtr xShapePtr( mxChartShapeContext->getShape());
562
            // See SwXTextDocument::createInstance(), ODF import uses the same hack.
563
23
            xShapePtr->setServiceName(u"com.sun.star.drawing.temporaryForXMLImportOLE2Shape"_ustr);
564
23
            xShapePtr->addShape( *mxShapeFilterBase, mpThemePtr.get(), xShapes, aMatrix, xShapePtr->getFillProperties() );
565
23
            xResult = xShapePtr->getXShape();
566
23
            mxChartShapeContext.clear();
567
23
        }
568
1.32k
        else if (mxWpsContext.is())
569
521
        {
570
521
            ShapePtr pShape = mxWpsContext->getShape();
571
521
            if (pShape)
572
521
            {
573
521
                basegfx::B2DHomMatrix aMatrix;
574
521
                pShape->setPosition(maPosition);
575
521
                pShape->addShape(*mxShapeFilterBase, mpThemePtr.get(), xShapes, aMatrix, pShape->getFillProperties());
576
521
                xResult = pShape->getXShape();
577
521
                mxSavedShape = xResult;
578
521
                mxWpsContext.clear();
579
521
            }
580
521
        }
581
807
        else if (mxWpgContext.is())
582
139
        {
583
139
            ShapePtr pShape = mxWpgContext->getShape();
584
139
            if (pShape)
585
139
            {
586
139
                basegfx::B2DHomMatrix aMatrix;
587
139
                pShape->setPosition(maPosition);
588
139
                pShape->addShape(*mxShapeFilterBase, mpThemePtr.get(), xShapes, aMatrix, pShape->getFillProperties());
589
139
                xResult = pShape->getXShape();
590
139
                mxSavedShape = xResult;
591
139
                mxWpgContext.clear();
592
139
            }
593
139
        }
594
668
        else if (mpShape)
595
668
        {
596
668
            basegfx::B2DHomMatrix aTransformation;
597
598
668
            if (maPosition.X != 0 || maPosition.Y != 0)
599
209
            {
600
                // We got a position from writerfilter/, store that in the shape, otherwise the
601
                // position won't be set.
602
209
                mpShape->setWps(true);
603
209
                mpShape->setPosition(maPosition);
604
209
            }
605
606
668
            mpShape->addShape(*mxShapeFilterBase, mpThemePtr.get(), xShapes, aTransformation, mpShape->getFillProperties() );
607
668
            xResult.set(mpShape->getXShape());
608
668
            mxGraphicShapeContext.clear( );
609
668
        }
610
3.23k
    }
611
612
3.23k
    if (xResult)
613
3.14k
        popStartToken();
614
3.23k
    return xResult;
615
3.23k
}
616
617
void ShapeContextHandler::setDrawPage(const css::uno::Reference< css::drawing::XDrawPage > & the_value)
618
3.37k
{
619
3.37k
    mxDrawPage = the_value;
620
3.37k
}
621
622
void ShapeContextHandler::setModel(const css::uno::Reference< css::frame::XModel > & the_value)
623
3.37k
{
624
3.37k
    if( !mxShapeFilterBase.is() )
625
0
        throw uno::RuntimeException();
626
3.37k
    uno::Reference<lang::XComponent> xComp(the_value, uno::UNO_QUERY_THROW);
627
3.37k
    mxShapeFilterBase->setTargetDocument(xComp);
628
3.37k
}
629
630
void ShapeContextHandler::setRelationFragmentPath(const OUString & the_value)
631
3.37k
{
632
3.37k
    msRelationFragmentPath = the_value;
633
3.37k
}
634
635
sal_Int32 ShapeContextHandler::getStartToken() const
636
22.5k
{
637
22.5k
    assert(mnStartTokenStack.size() && "This stack must not be empty!");
638
22.5k
    return mnStartTokenStack.top();
639
22.5k
}
640
641
void ShapeContextHandler::popStartToken()
642
3.14k
{
643
3.14k
    if (mnStartTokenStack.size() > 1)
644
1.14k
        mnStartTokenStack.pop();
645
3.14k
}
646
647
void ShapeContextHandler::pushStartToken( sal_Int32 _starttoken )
648
3.37k
{
649
3.37k
    mnStartTokenStack.push(_starttoken);
650
3.37k
}
651
652
void ShapeContextHandler::setPosition(const awt::Point& rPosition)
653
3.23k
{
654
3.23k
    maPosition = rPosition;
655
3.23k
}
656
657
void ShapeContextHandler::setSize(const awt::Size& rSize)
658
155
{
659
155
    maSize = rSize;
660
155
}
661
662
void ShapeContextHandler::setDocumentProperties(const uno::Reference<document::XDocumentProperties>& xDocProps)
663
3.37k
{
664
3.37k
    mxDocumentProperties = xDocProps;
665
3.37k
    mxShapeFilterBase->checkDocumentProperties(mxDocumentProperties);
666
3.37k
}
667
668
void ShapeContextHandler::setMediaDescriptor(const uno::Sequence<beans::PropertyValue>& rMediaDescriptor)
669
3.37k
{
670
3.37k
    maMediaDescriptor = rMediaDescriptor;
671
3.37k
}
672
673
void ShapeContextHandler::setGraphicMapper(css::uno::Reference<css::graphic::XGraphicMapper> const & rxGraphicMapper)
674
3.37k
{
675
3.37k
    mxShapeFilterBase->setGraphicMapper(rxGraphicMapper);
676
3.37k
}
677
678
void ShapeContextHandler::applyFontRefColor(const oox::drawingml::ShapePtr& pShape,
679
                                            const oox::drawingml::Color& rFontRefColor)
680
0
{
681
0
    pShape->getShapeStyleRefs()[XML_fontRef].maPhClr = rFontRefColor;
682
0
    std::vector<oox::drawingml::ShapePtr>& vChildren = pShape->getChildren();
683
0
    for (auto const& child : vChildren)
684
0
    {
685
0
        applyFontRefColor(child, rFontRefColor);
686
0
    }
687
0
}
688
}
689
690
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */