Coverage Report

Created: 2026-03-31 11:00

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/libreoffice/xmloff/source/draw/ximpshap.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 <config_wasm_strip.h>
21
22
#include <cassert>
23
24
#include <sal/log.hxx>
25
#include <com/sun/star/document/XEventsSupplier.hpp>
26
#include <com/sun/star/container/XNameReplace.hpp>
27
#include <com/sun/star/presentation/ClickAction.hpp>
28
#include <com/sun/star/drawing/FillStyle.hpp>
29
#include <com/sun/star/drawing/LineStyle.hpp>
30
#include <utility>
31
#include <xmloff/unointerfacetouniqueidentifiermapper.hxx>
32
#include <com/sun/star/drawing/XGluePointsSupplier.hpp>
33
#include <com/sun/star/drawing/GluePoint2.hpp>
34
#include <com/sun/star/media/ZoomLevel.hpp>
35
#include <com/sun/star/awt/Rectangle.hpp>
36
#include <com/sun/star/style/XStyleFamiliesSupplier.hpp>
37
#include <com/sun/star/container/XNameAccess.hpp>
38
#include "ximpshap.hxx"
39
#include <xmloff/XMLBase64ImportContext.hxx>
40
#include <xmloff/XMLShapeStyleContext.hxx>
41
#include <xmloff/xmluconv.hxx>
42
#include <com/sun/star/container/XNamed.hpp>
43
#include <com/sun/star/beans/XPropertySet.hpp>
44
#include <com/sun/star/awt/XControlModel.hpp>
45
#include <com/sun/star/drawing/XControlShape.hpp>
46
#include <com/sun/star/drawing/PointSequenceSequence.hpp>
47
#include <com/sun/star/drawing/PointSequence.hpp>
48
#include <com/sun/star/lang/XServiceInfo.hpp>
49
#include <com/sun/star/lang/XMultiServiceFactory.hpp>
50
#include <com/sun/star/util/XCloneable.hpp>
51
#include <com/sun/star/beans/XMultiPropertyStates.hpp>
52
#include <com/sun/star/beans/XPropertyState.hpp>
53
#include <xexptran.hxx>
54
#include <com/sun/star/drawing/PolyPolygonBezierCoords.hpp>
55
#include <com/sun/star/beans/XPropertySetInfo.hpp>
56
#include <com/sun/star/drawing/HomogenMatrix3.hpp>
57
#include <com/sun/star/graphic/XGraphic.hpp>
58
#include <com/sun/star/style/XStyle.hpp>
59
60
#include <sax/tools/converter.hxx>
61
#include <comphelper/sequence.hxx>
62
#include <comphelper/diagnose_ex.hxx>
63
#include <comphelper/mediamimetype.hxx>
64
65
#include <xmloff/families.hxx>
66
#include<xmloff/xmlnamespace.hxx>
67
#include <xmloff/xmltoken.hxx>
68
#include <EnhancedCustomShapeToken.hxx>
69
#include <XMLReplacementImageContext.hxx>
70
#include <XMLImageMapContext.hxx>
71
#include "sdpropls.hxx"
72
#include "sdxmlimp_impl.hxx"
73
#include "eventimp.hxx"
74
#include "descriptionimp.hxx"
75
#include "SignatureLineContext.hxx"
76
#include "QRCodeContext.hxx"
77
#include "ximpcustomshape.hxx"
78
#include <XMLEmbeddedObjectImportContext.hxx>
79
#include <xmloff/xmlerror.hxx>
80
#include <xmloff/table/XMLTableImport.hxx>
81
#include <xmloff/ProgressBarHelper.hxx>
82
#include <basegfx/matrix/b2dhommatrix.hxx>
83
#include <com/sun/star/drawing/XEnhancedCustomShapeDefaulter.hpp>
84
#include <com/sun/star/container/XChild.hpp>
85
#include <com/sun/star/table/XColumnRowRange.hpp>
86
#include <com/sun/star/text/XTextDocument.hpp>
87
#include <basegfx/matrix/b2dhommatrixtools.hxx>
88
#include <basegfx/point/b2dpoint.hxx>
89
#include <basegfx/polygon/b2dpolygon.hxx>
90
#include <basegfx/polygon/b2dpolygontools.hxx>
91
#include <basegfx/polygon/b2dpolypolygon.hxx>
92
#include <basegfx/polygon/b2dpolypolygontools.hxx>
93
#include <basegfx/vector/b2dvector.hxx>
94
#include <tools/urlobj.hxx>
95
#include <o3tl/any.hxx>
96
#include <o3tl/safeint.hxx>
97
98
using namespace ::com::sun::star;
99
using namespace ::com::sun::star::uno;
100
using namespace ::com::sun::star::drawing;
101
using namespace ::com::sun::star::style;
102
using namespace ::com::sun::star::container;
103
using namespace ::com::sun::star::document;
104
using namespace ::xmloff::token;
105
using namespace ::xmloff::EnhancedCustomShapeToken;
106
107
SvXMLEnumMapEntry<drawing::Alignment> const aXML_GlueAlignment_EnumMap[] =
108
{
109
    { XML_TOP_LEFT,     drawing::Alignment_TOP_LEFT },
110
    { XML_TOP,          drawing::Alignment_TOP },
111
    { XML_TOP_RIGHT,    drawing::Alignment_TOP_RIGHT },
112
    { XML_LEFT,         drawing::Alignment_LEFT },
113
    { XML_CENTER,       drawing::Alignment_CENTER },
114
    { XML_RIGHT,        drawing::Alignment_RIGHT },
115
    { XML_BOTTOM_LEFT,  drawing::Alignment_BOTTOM_LEFT },
116
    { XML_BOTTOM,       drawing::Alignment_BOTTOM },
117
    { XML_BOTTOM_RIGHT, drawing::Alignment_BOTTOM_RIGHT },
118
    { XML_TOKEN_INVALID, drawing::Alignment(0) }
119
};
120
121
SvXMLEnumMapEntry<drawing::EscapeDirection> const aXML_GlueEscapeDirection_EnumMap[] =
122
{
123
    { XML_AUTO,         drawing::EscapeDirection_SMART },
124
    { XML_LEFT,         drawing::EscapeDirection_LEFT },
125
    { XML_RIGHT,        drawing::EscapeDirection_RIGHT },
126
    { XML_UP,           drawing::EscapeDirection_UP },
127
    { XML_DOWN,         drawing::EscapeDirection_DOWN },
128
    { XML_HORIZONTAL,   drawing::EscapeDirection_HORIZONTAL },
129
    { XML_VERTICAL,     drawing::EscapeDirection_VERTICAL },
130
    { XML_TOKEN_INVALID, drawing::EscapeDirection(0) }
131
};
132
133
static bool ImpIsEmptyURL( std::u16string_view rURL )
134
0
{
135
0
    if( rURL.empty() )
136
0
        return true;
137
138
    // #i13140# Also compare against 'toplevel' URLs. which also
139
    // result in empty filename strings.
140
0
    if( rURL == u"#./" )
141
0
        return true;
142
143
0
    return false;
144
0
}
145
146
147
SdXMLShapeContext::SdXMLShapeContext(
148
    SvXMLImport& rImport,
149
    css::uno::Reference< css::xml::sax::XFastAttributeList> xAttrList,
150
    uno::Reference< drawing::XShapes > xShapes,
151
    bool bTemporaryShape)
152
27.7k
    : SvXMLShapeContext( rImport, bTemporaryShape )
153
27.7k
    , mxShapes(std::move( xShapes ))
154
27.7k
    , mxAttrList(std::move(xAttrList))
155
27.7k
    , mbListContextPushed( false )
156
27.7k
    , mnStyleFamily(XmlStyleFamily::SD_GRAPHICS_ID)
157
27.7k
    , mbIsPlaceholder(false)
158
27.7k
    , mbClearDefaultAttributes( true )
159
27.7k
    , mbIsUserTransformed(false)
160
27.7k
    , mnZOrder(-1)
161
27.7k
    , maSize(1, 1)
162
27.7k
    , mnRelWidth(0)
163
27.7k
    , mnRelHeight(0)
164
27.7k
    , maPosition(0, 0)
165
27.7k
    , mbVisible(true)
166
27.7k
    , mbPrintable(true)
167
27.7k
    , mbHaveXmlId(false)
168
27.7k
    , mbTextBox(false)
169
27.7k
{
170
27.7k
}
171
172
SdXMLShapeContext::~SdXMLShapeContext()
173
27.7k
{
174
27.7k
}
175
176
css::uno::Reference< css::xml::sax::XFastContextHandler > SdXMLShapeContext::createFastChildContext(
177
    sal_Int32 nElement,
178
    const css::uno::Reference< css::xml::sax::XFastAttributeList >& xAttrList )
179
111k
{
180
111k
    SvXMLImportContextRef xContext;
181
    // #i68101#
182
111k
    if( nElement == XML_ELEMENT(SVG, XML_TITLE) || nElement == XML_ELEMENT(SVG, XML_DESC)
183
111k
        || nElement == XML_ELEMENT(SVG_COMPAT, XML_TITLE) || nElement == XML_ELEMENT(SVG_COMPAT, XML_DESC) )
184
0
    {
185
0
        xContext = new SdXMLDescriptionContext( GetImport(), nElement, mxShape );
186
0
    }
187
111k
    else if( nElement == XML_ELEMENT(LO_EXT, XML_SIGNATURELINE) )
188
0
    {
189
0
        xContext = new SignatureLineContext( GetImport(), nElement, xAttrList, mxShape );
190
0
    }
191
111k
    else if( nElement == XML_ELEMENT(LO_EXT, XML_QRCODE) )
192
0
    {
193
0
        xContext = new QRCodeContext( GetImport(), nElement, xAttrList, mxShape );
194
0
    }
195
111k
    else if( nElement == XML_ELEMENT(OFFICE, XML_EVENT_LISTENERS) )
196
4
    {
197
4
        xContext = new SdXMLEventsContext( GetImport(), mxShape );
198
4
    }
199
111k
    else if( nElement == XML_ELEMENT(DRAW, XML_GLUE_POINT) )
200
0
    {
201
0
        addGluePoint( xAttrList );
202
0
    }
203
111k
    else if( nElement == XML_ELEMENT(DRAW, XML_THUMBNAIL) )
204
0
    {
205
        // search attributes for xlink:href
206
0
        maThumbnailURL = xAttrList->getOptionalValue(XML_ELEMENT(XLINK, XML_HREF));
207
0
    }
208
111k
    else
209
111k
    {
210
        // create text cursor on demand
211
111k
        if( !mxCursor.is() )
212
14.7k
        {
213
14.7k
            uno::Reference< text::XText > xText( mxShape, uno::UNO_QUERY );
214
14.7k
            if( xText.is() )
215
14.4k
            {
216
14.4k
                rtl::Reference < XMLTextImportHelper > xTxtImport =
217
14.4k
                    GetImport().GetTextImport();
218
14.4k
                mxOldCursor = xTxtImport->GetCursor();
219
14.4k
                mxCursor = xText->createTextCursor();
220
14.4k
                if( mxCursor.is() )
221
14.4k
                {
222
14.4k
                    xTxtImport->SetCursor( mxCursor );
223
14.4k
                }
224
225
                // remember old list item and block (#91964#) and reset them
226
                // for the text frame
227
14.4k
                xTxtImport->PushListContext();
228
14.4k
                mbListContextPushed = true;
229
14.4k
            }
230
14.7k
        }
231
232
        // if we have a text cursor, let's try to import some text
233
111k
        if( mxCursor.is() )
234
111k
        {
235
111k
            xContext = GetImport().GetTextImport()->CreateTextChildContext(
236
111k
                GetImport(), nElement, xAttrList,
237
111k
                ( mbTextBox ? XMLTextType::TextBox : XMLTextType::Shape ) );
238
111k
        }
239
111k
    }
240
241
111k
    if (!xContext)
242
111k
        XMLOFF_WARN_UNKNOWN_ELEMENT("xmloff", nElement);
243
244
111k
    return xContext;
245
111k
}
246
247
void SdXMLShapeContext::addGluePoint( const uno::Reference< xml::sax::XFastAttributeList>& xAttrList )
248
0
{
249
    // get the gluepoints container for this shape if it's not already there
250
0
    if( !mxGluePoints.is() )
251
0
    {
252
0
        uno::Reference< drawing::XGluePointsSupplier > xSupplier( mxShape, uno::UNO_QUERY );
253
0
        if( !xSupplier.is() )
254
0
            return;
255
256
0
        mxGluePoints.set( xSupplier->getGluePoints(), UNO_QUERY );
257
258
0
        if( !mxGluePoints.is() )
259
0
            return;
260
0
    }
261
262
0
    drawing::GluePoint2 aGluePoint;
263
0
    aGluePoint.IsUserDefined = true;
264
0
    aGluePoint.Position.X = 0;
265
0
    aGluePoint.Position.Y = 0;
266
0
    aGluePoint.Escape = drawing::EscapeDirection_SMART;
267
0
    aGluePoint.PositionAlignment = drawing::Alignment_CENTER;
268
0
    aGluePoint.IsRelative = true;
269
270
0
    sal_Int32 nId = -1;
271
272
    // read attributes for the 3DScene
273
0
    for( auto& aIter : sax_fastparser::castToFastAttributeList(xAttrList) )
274
0
    {
275
0
        switch(aIter.getToken())
276
0
        {
277
0
            case XML_ELEMENT(SVG, XML_X):
278
0
            case XML_ELEMENT(SVG_COMPAT, XML_X):
279
0
                GetImport().GetMM100UnitConverter().convertMeasureToCore(
280
0
                        aGluePoint.Position.X, aIter.toView());
281
0
                break;
282
0
            case XML_ELEMENT(SVG, XML_Y):
283
0
            case XML_ELEMENT(SVG_COMPAT, XML_Y):
284
0
                GetImport().GetMM100UnitConverter().convertMeasureToCore(
285
0
                        aGluePoint.Position.Y, aIter.toView());
286
0
                break;
287
0
            case XML_ELEMENT(DRAW, XML_ID):
288
0
                nId = aIter.toInt32();
289
0
                break;
290
0
            case XML_ELEMENT(DRAW, XML_ALIGN):
291
0
            {
292
0
                drawing::Alignment eKind;
293
0
                if( SvXMLUnitConverter::convertEnum( eKind, aIter.toView(), aXML_GlueAlignment_EnumMap ) )
294
0
                {
295
0
                    aGluePoint.PositionAlignment = eKind;
296
0
                    aGluePoint.IsRelative = false;
297
0
                }
298
0
                break;
299
0
            }
300
0
            case XML_ELEMENT(DRAW, XML_ESCAPE_DIRECTION):
301
0
            {
302
0
                SvXMLUnitConverter::convertEnum( aGluePoint.Escape, aIter.toView(), aXML_GlueEscapeDirection_EnumMap );
303
0
                break;
304
0
            }
305
0
            default:
306
0
                XMLOFF_WARN_UNKNOWN("xmloff", aIter);
307
0
        }
308
0
    }
309
310
0
    if( nId != -1 )
311
0
    {
312
0
        try
313
0
        {
314
0
            sal_Int32 nInternalId = mxGluePoints->insert( uno::Any( aGluePoint ) );
315
0
            GetImport().GetShapeImport()->addGluePointMapping( mxShape, nId, nInternalId );
316
0
        }
317
0
        catch(const uno::Exception&)
318
0
        {
319
0
            DBG_UNHANDLED_EXCEPTION( "xmloff", "during setting of gluepoints");
320
0
        }
321
0
    }
322
0
}
323
324
void SdXMLShapeContext::startFastElement (sal_Int32 /*nElement*/,
325
    const css::uno::Reference< css::xml::sax::XFastAttributeList >& /*xAttrList*/)
326
18.7k
{
327
18.7k
    GetImport().GetShapeImport()->finishShape( mxShape, mxAttrList, mxShapes );
328
18.7k
}
329
330
void SdXMLShapeContext::endFastElement(sal_Int32 )
331
17.9k
{
332
17.9k
    if(mxCursor.is())
333
7.89k
    {
334
        // tdf#72776 force UpdateData in the EditSource so we will not override text in SdrOutliner
335
7.89k
        if( mxLockable.is() )
336
7.87k
        {
337
7.87k
            mxLockable->removeActionLock();
338
7.87k
            mxLockable->addActionLock();
339
7.87k
        }
340
341
        // delete addition newline
342
7.89k
        mxCursor->gotoEnd( false );
343
7.89k
        mxCursor->goLeft( 1, true );
344
7.89k
        mxCursor->setString( u""_ustr );
345
346
        // reset cursor
347
7.89k
        GetImport().GetTextImport()->ResetCursor();
348
7.89k
    }
349
350
17.9k
    if(mxOldCursor.is())
351
2.51k
        GetImport().GetTextImport()->SetCursor( mxOldCursor );
352
353
    // reinstall old list item (if necessary) #91964#
354
17.9k
    if (mbListContextPushed) {
355
7.89k
        GetImport().GetTextImport()->PopListContext();
356
7.89k
    }
357
358
17.9k
    if( !msHyperlink.isEmpty() ) try
359
0
    {
360
0
        uno::Reference< beans::XPropertySet > xProp( mxShape, uno::UNO_QUERY );
361
362
0
        if ( xProp.is() && xProp->getPropertySetInfo()->hasPropertyByName( u"Hyperlink"_ustr ) )
363
0
            xProp->setPropertyValue( u"Hyperlink"_ustr, uno::Any( msHyperlink ) );
364
0
        Reference< XEventsSupplier > xEventsSupplier( mxShape, UNO_QUERY );
365
366
0
        if( xEventsSupplier.is() )
367
0
        {
368
0
            Reference< XNameReplace > xEvents( xEventsSupplier->getEvents(), UNO_SET_THROW );
369
370
0
            uno::Sequence< beans::PropertyValue > aProperties{
371
0
                { /* Name   */ u"EventType"_ustr,
372
0
                  /* Handle */ -1,
373
0
                  /* Value  */ uno::Any(u"Presentation"_ustr),
374
0
                  /* State  */ beans::PropertyState_DIRECT_VALUE },
375
376
0
                { /* Name   */ u"ClickAction"_ustr,
377
0
                  /* Handle */ -1,
378
0
                  /* Value  */ uno::Any(css::presentation::ClickAction_DOCUMENT),
379
0
                  /* State  */ beans::PropertyState_DIRECT_VALUE },
380
381
0
                { /* Name   */ u"Bookmark"_ustr,
382
0
                  /* Handle */ -1,
383
0
                  /* Value  */ uno::Any(msHyperlink),
384
0
                  /* State  */ beans::PropertyState_DIRECT_VALUE }
385
0
            };
386
387
0
            xEvents->replaceByName( u"OnClick"_ustr, Any( aProperties ) );
388
0
        }
389
0
        else
390
0
        {
391
            // in draw use the Bookmark property
392
0
            Reference< beans::XPropertySet > xSet( mxShape, UNO_QUERY_THROW );
393
0
            xSet->setPropertyValue( u"Bookmark"_ustr, Any( msHyperlink ) );
394
0
            xSet->setPropertyValue(u"OnClick"_ustr, Any( css::presentation::ClickAction_DOCUMENT ) );
395
0
        }
396
0
    }
397
0
    catch(const Exception&)
398
0
    {
399
0
        DBG_UNHANDLED_EXCEPTION("xmloff", "while setting hyperlink");
400
0
    }
401
402
17.9k
    if( mxLockable.is() )
403
11.9k
        mxLockable->removeActionLock();
404
17.9k
}
405
406
void SdXMLShapeContext::AddShape(uno::Reference< drawing::XShape >& xShape)
407
19.8k
{
408
19.8k
    if(xShape.is())
409
19.8k
    {
410
        // set shape local
411
19.8k
        mxShape = xShape;
412
413
19.8k
        if(!maShapeName.isEmpty())
414
969
        {
415
969
            uno::Reference< container::XNamed > xNamed( mxShape, uno::UNO_QUERY );
416
969
            if( xNamed.is() )
417
969
                xNamed->setName( maShapeName );
418
969
        }
419
420
19.8k
        rtl::Reference< XMLShapeImportHelper > xImp( GetImport().GetShapeImport() );
421
19.8k
        xImp->addShape( xShape, mxAttrList, mxShapes );
422
423
19.8k
        if( mbClearDefaultAttributes )
424
15.4k
        {
425
15.4k
            uno::Reference<beans::XMultiPropertyStates> xMultiPropertyStates(xShape, uno::UNO_QUERY );
426
15.4k
            if (xMultiPropertyStates.is())
427
15.4k
                xMultiPropertyStates->setAllPropertiesToDefault();
428
15.4k
        }
429
430
19.8k
        if( !mbVisible || !mbPrintable ) try
431
0
        {
432
0
            uno::Reference< beans::XPropertySet > xSet( xShape, uno::UNO_QUERY_THROW );
433
0
            if( !mbVisible )
434
0
                xSet->setPropertyValue(u"Visible"_ustr, uno::Any( false ) );
435
436
0
            if( !mbPrintable )
437
0
                xSet->setPropertyValue(u"Printable"_ustr, uno::Any( false ) );
438
0
        }
439
0
        catch(const Exception&)
440
0
        {
441
0
            DBG_UNHANDLED_EXCEPTION( "xmloff", "while setting visible or printable" );
442
0
        }
443
444
19.8k
        if(!mbTemporaryShape && (!GetImport().HasTextImport()
445
14.4k
            || !GetImport().GetTextImport()->IsInsideDeleteContext()))
446
16.6k
        {
447
16.6k
            xImp->shapeWithZIndexAdded( xShape, mnZOrder );
448
16.6k
        }
449
450
19.8k
        if (mnRelWidth || mnRelHeight)
451
1
        {
452
1
            uno::Reference<beans::XPropertySet> xPropertySet(xShape, uno::UNO_QUERY);
453
1
            uno::Reference<beans::XPropertySetInfo> xPropertySetInfo = xPropertySet->getPropertySetInfo();
454
1
            if (mnRelWidth && xPropertySetInfo->hasPropertyByName(u"RelativeWidth"_ustr))
455
1
                xPropertySet->setPropertyValue(u"RelativeWidth"_ustr, uno::Any(mnRelWidth));
456
1
            if (mnRelHeight && xPropertySetInfo->hasPropertyByName(u"RelativeHeight"_ustr))
457
0
                xPropertySet->setPropertyValue(u"RelativeHeight"_ustr, uno::Any(mnRelHeight));
458
1
        }
459
460
19.8k
        if( !maShapeId.isEmpty() )
461
0
        {
462
0
            uno::Reference< uno::XInterface > xRef( static_cast<uno::XInterface *>(xShape.get()) );
463
0
            GetImport().getInterfaceToIdentifierMapper().registerReference( maShapeId, xRef );
464
0
        }
465
466
        // #91065# count only if counting for shape import is enabled
467
19.8k
        if(GetImport().GetShapeImport()->IsHandleProgressBarEnabled())
468
9.45k
        {
469
            // #80365# increment progress bar at load once for each draw object
470
9.45k
            GetImport().GetProgressBarHelper()->Increment();
471
9.45k
        }
472
19.8k
    }
473
474
19.8k
    mxLockable.set( xShape, UNO_QUERY );
475
476
19.8k
    if( mxLockable.is() )
477
16.6k
        mxLockable->addActionLock();
478
479
19.8k
}
480
481
void SdXMLShapeContext::AddShape(OUString const & serviceName)
482
19.8k
{
483
19.8k
    uno::Reference< lang::XMultiServiceFactory > xServiceFact(GetImport().GetModel(), uno::UNO_QUERY);
484
19.8k
    if(!xServiceFact.is())
485
0
        return;
486
487
19.8k
    try
488
19.8k
    {
489
        /* Since fix for issue i33294 the Writer model doesn't support
490
           com.sun.star.drawing.OLE2Shape anymore.
491
           To handle Draw OLE objects it's decided to import these
492
           objects as com.sun.star.drawing.OLE2Shape and convert these
493
           objects after the import into com.sun.star.drawing.GraphicObjectShape.
494
        */
495
19.8k
        uno::Reference< drawing::XShape > xShape;
496
19.8k
        if ( serviceName == "com.sun.star.drawing.OLE2Shape" &&
497
16
             uno::Reference< text::XTextDocument >(GetImport().GetModel(), uno::UNO_QUERY).is() )
498
0
        {
499
0
            xShape.set(xServiceFact->createInstance(u"com.sun.star.drawing.temporaryForXMLImportOLE2Shape"_ustr), uno::UNO_QUERY);
500
0
        }
501
19.8k
        else if (serviceName == "com.sun.star.drawing.GraphicObjectShape"
502
19.7k
                 || serviceName == "com.sun.star.drawing.AppletShape"
503
19.7k
                 || serviceName == "com.sun.star.drawing.FrameShape"
504
19.7k
                 || serviceName == "com.sun.star.drawing.MediaShape"
505
19.7k
                 || serviceName == "com.sun.star.drawing.OLE2Shape"
506
19.6k
                 || serviceName == "com.sun.star.drawing.PluginShape"
507
19.6k
                 || serviceName == "com.sun.star.presentation.MediaShape")
508
204
        {
509
            // On adding another entry to this list of service names to pass an argument via the WithArguments variant
510
            // you may need to adjust the more obscure OReportDefinition::createInstanceWithArguments as well as the
511
            // more obvious SvxUnoDrawMSFactory::createInstanceWithArguments
512
204
            xShape.set( xServiceFact->createInstanceWithArguments(serviceName, { css::uno::Any(GetImport().GetDocumentBase()) }),
513
204
                        css::uno::UNO_QUERY);
514
204
        }
515
19.6k
        else
516
19.6k
        {
517
19.6k
            xShape.set(xServiceFact->createInstance(serviceName), uno::UNO_QUERY);
518
19.6k
        }
519
19.8k
        if( xShape.is() )
520
19.8k
            AddShape( xShape );
521
19.8k
    }
522
19.8k
    catch(const uno::Exception& e)
523
19.8k
    {
524
3.27k
        TOOLS_WARN_EXCEPTION("xmloff", "AddShape " << serviceName);
525
3.27k
        uno::Sequence<OUString> aSeq { serviceName };
526
3.27k
        GetImport().SetError( XMLERROR_FLAG_ERROR | XMLERROR_API,
527
3.27k
                              aSeq, e.Message, nullptr );
528
3.27k
    }
529
19.8k
}
530
531
void SdXMLShapeContext::SetTransformation()
532
18.8k
{
533
18.8k
    if(!mxShape.is())
534
0
        return;
535
536
18.8k
    uno::Reference< beans::XPropertySet > xPropSet(mxShape, uno::UNO_QUERY);
537
18.8k
    if(!xPropSet.is())
538
0
        return;
539
540
18.8k
    maUsedTransformation.identity();
541
542
18.8k
    if(maSize.Width != 1 || maSize.Height != 1)
543
6.18k
    {
544
        // take care there are no zeros used by error
545
6.18k
        if(0 == maSize.Width)
546
0
            maSize.Width = 1;
547
6.18k
        if(0 == maSize.Height)
548
801
            maSize.Height = 1;
549
550
        // set global size. This should always be used.
551
6.18k
        maUsedTransformation.scale(maSize.Width, maSize.Height);
552
6.18k
    }
553
554
18.8k
    if(maPosition.X != 0 || maPosition.Y != 0)
555
5.10k
    {
556
        // if global position is used, add it to transformation
557
5.10k
        maUsedTransformation.translate(maPosition.X, maPosition.Y);
558
5.10k
    }
559
560
18.8k
    if(mnTransform.NeedsAction())
561
249
    {
562
        // transformation is used, apply to object.
563
        // NOTICE: The transformation is applied AFTER evtl. used
564
        // global positioning and scaling is used, so any shear or
565
        // rotate used herein is applied around the (0,0) position
566
        // of the PAGE object !!!
567
249
        ::basegfx::B2DHomMatrix aMat;
568
249
        mnTransform.GetFullTransform(aMat);
569
570
        // now add to transformation
571
249
        maUsedTransformation *= aMat;
572
249
    }
573
574
    // now set transformation for this object
575
576
    // maUsedTransformtion contains the mathematical correct matrix, which if
577
    // applied to a unit square would generate the transformed shape. But the property
578
    // "Transformation" contains a matrix, which can be used in TRSetBaseGeometry
579
    // and would be created by TRGetBaseGeometry. And those use a mathematically wrong
580
    // sign for the shearing angle. So we need to adapt the matrix here.
581
18.8k
    basegfx::B2DTuple aScale;
582
18.8k
    basegfx::B2DTuple aTranslate;
583
18.8k
    double fRotate;
584
18.8k
    double fShearX;
585
18.8k
    maUsedTransformation.decompose(aScale, aTranslate, fRotate, fShearX);
586
18.8k
    basegfx::B2DHomMatrix aB2DHomMatrix;
587
18.8k
    aB2DHomMatrix = basegfx::utils::createScaleShearXRotateTranslateB2DHomMatrix(
588
18.8k
                                aScale,
589
18.8k
                                -fShearX,
590
18.8k
                                fRotate,
591
18.8k
                            aTranslate);
592
18.8k
    drawing::HomogenMatrix3 aUnoMatrix;
593
594
18.8k
    aUnoMatrix.Line1.Column1 = aB2DHomMatrix.get(0, 0);
595
18.8k
    aUnoMatrix.Line1.Column2 = aB2DHomMatrix.get(0, 1);
596
18.8k
    aUnoMatrix.Line1.Column3 = aB2DHomMatrix.get(0, 2);
597
598
18.8k
    aUnoMatrix.Line2.Column1 = aB2DHomMatrix.get(1, 0);
599
18.8k
    aUnoMatrix.Line2.Column2 = aB2DHomMatrix.get(1, 1);
600
18.8k
    aUnoMatrix.Line2.Column3 = aB2DHomMatrix.get(1, 2);
601
602
18.8k
    aUnoMatrix.Line3.Column1 = 0;
603
18.8k
    aUnoMatrix.Line3.Column2 = 0;
604
18.8k
    aUnoMatrix.Line3.Column3 = 1;
605
606
18.8k
    xPropSet->setPropertyValue(u"Transformation"_ustr, Any(aUnoMatrix));
607
18.8k
}
608
609
const SvXMLStyleContext* SdXMLShapeContext::FindAutoStyle()
610
14.2k
{
611
14.2k
    if (maDrawStyleName.isEmpty())
612
3.46k
        return nullptr;
613
10.7k
    if (const SvXMLStylesContext* pAutoStyles = GetImport().GetShapeImport()->GetAutoStylesContext())
614
6.83k
        return pAutoStyles->FindStyleChildContext(mnStyleFamily, maDrawStyleName);
615
3.93k
    return nullptr;
616
10.7k
}
617
618
void SdXMLShapeContext::SetStyle( bool bSupportsStyle /* = true */)
619
19.8k
{
620
19.8k
    try
621
19.8k
    {
622
19.8k
        uno::Reference< beans::XPropertySet > xPropSet(mxShape, uno::UNO_QUERY);
623
19.8k
        if( !xPropSet.is() )
624
0
            return;
625
626
19.8k
        do
627
19.8k
        {
628
            // set style on shape
629
19.8k
            if(maDrawStyleName.isEmpty())
630
9.12k
                break;
631
632
10.7k
            const SvXMLStyleContext* pStyle = FindAutoStyle();
633
10.7k
            bool bAutoStyle = pStyle != nullptr;
634
635
10.7k
            if(!pStyle && GetImport().GetShapeImport()->GetStylesContext())
636
1.99k
                pStyle = GetImport().GetShapeImport()->GetStylesContext()->FindStyleChildContext(mnStyleFamily, maDrawStyleName);
637
638
10.7k
            OUString aStyleName = maDrawStyleName;
639
10.7k
            uno::Reference< style::XStyle > xStyle;
640
641
10.7k
            XMLPropStyleContext* pDocStyle
642
10.7k
                = dynamic_cast<XMLShapeStyleContext*>(const_cast<SvXMLStyleContext*>(pStyle));
643
10.7k
            if (pDocStyle)
644
3.39k
            {
645
3.39k
                if( pDocStyle->GetStyle().is() )
646
491
                {
647
491
                    xStyle = pDocStyle->GetStyle();
648
491
                }
649
2.90k
                else
650
2.90k
                {
651
2.90k
                    aStyleName = pDocStyle->GetParentName();
652
2.90k
                }
653
3.39k
            }
654
655
10.7k
            if( !xStyle.is() && !aStyleName.isEmpty() )
656
8.15k
            {
657
8.15k
                try
658
8.15k
                {
659
660
8.15k
                    uno::Reference< style::XStyleFamiliesSupplier > xFamiliesSupplier( GetImport().GetModel(), uno::UNO_QUERY );
661
662
8.15k
                    if( xFamiliesSupplier.is() )
663
8.15k
                    {
664
8.15k
                        uno::Reference< container::XNameAccess > xFamilies( xFamiliesSupplier->getStyleFamilies() );
665
8.15k
                        if( xFamilies.is() )
666
8.15k
                        {
667
668
8.15k
                            uno::Reference< container::XNameAccess > xFamily;
669
670
8.15k
                            if( XmlStyleFamily::SD_PRESENTATION_ID == mnStyleFamily )
671
1.29k
                            {
672
1.29k
                                aStyleName = GetImport().GetStyleDisplayName(
673
1.29k
                                    XmlStyleFamily::SD_PRESENTATION_ID,
674
1.29k
                                    aStyleName );
675
1.29k
                                sal_Int32 nPos = aStyleName.lastIndexOf( '-' );
676
1.29k
                                if( -1 != nPos )
677
1.00k
                                {
678
1.00k
                                    OUString aFamily( aStyleName.copy( 0, nPos ) );
679
680
1.00k
                                    xFamilies->getByName( aFamily ) >>= xFamily;
681
1.00k
                                    aStyleName = aStyleName.copy( nPos + 1 );
682
1.00k
                                }
683
1.29k
                            }
684
6.85k
                            else
685
6.85k
                            {
686
                                // get graphics family
687
6.85k
                                if (xFamilies->hasByName(u"graphics"_ustr))
688
4.75k
                                    xFamilies->getByName(u"graphics"_ustr) >>= xFamily;
689
2.10k
                                else
690
2.10k
                                    xFamilies->getByName(u"GraphicStyles"_ustr) >>= xFamily;
691
692
6.85k
                                aStyleName = GetImport().GetStyleDisplayName(
693
6.85k
                                    XmlStyleFamily::SD_GRAPHICS_ID,
694
6.85k
                                    aStyleName );
695
6.85k
                            }
696
697
8.15k
                            if( xFamily.is() )
698
6.39k
                                xFamily->getByName( aStyleName ) >>= xStyle;
699
8.15k
                        }
700
8.15k
                    }
701
8.15k
                }
702
8.15k
                catch(const uno::Exception&)
703
8.15k
                {
704
4.33k
                    DBG_UNHANDLED_EXCEPTION( "xmloff", "finding style for shape" );
705
4.33k
                }
706
8.15k
            }
707
708
10.7k
            if( bSupportsStyle && xStyle.is() )
709
4.02k
            {
710
4.02k
                try
711
4.02k
                {
712
                    // set style on object
713
4.02k
                    xPropSet->setPropertyValue(u"Style"_ustr, Any(xStyle));
714
4.02k
                }
715
4.02k
                catch(const uno::Exception&)
716
4.02k
                {
717
0
                    DBG_UNHANDLED_EXCEPTION( "xmloff", "setting style for shape" );
718
0
                }
719
4.02k
            }
720
721
            // Writer shapes: if this one has a TextBox, set it here. We need to do it before
722
            // pDocStyle->FillPropertySet, because setting some properties depend on the format
723
            // having RES_CNTNT attribute (e.g., UNO_NAME_TEXT_(LEFT|RIGHT|UPPER|LOWER)DIST; see
724
            // SwTextBoxHelper::syncProperty, which indirectly calls SwTextBoxHelper::isTextBox)
725
10.7k
            uno::Reference<beans::XPropertySetInfo> xPropertySetInfo
726
10.7k
                = xPropSet->getPropertySetInfo();
727
10.7k
            static constexpr OUString sTextBox = u"TextBox"_ustr;
728
10.7k
            if (xPropertySetInfo->hasPropertyByName(sTextBox))
729
3.22k
                xPropSet->setPropertyValue(sTextBox, uno::Any(mbTextBox));
730
731
            // if this is an auto style, set its properties
732
10.7k
            if(bAutoStyle && pDocStyle)
733
3.21k
            {
734
                // set PropertySet on object
735
3.21k
                pDocStyle->FillPropertySet(xPropSet);
736
3.21k
            }
737
738
10.7k
        } while(false);
739
740
        // try to set text auto style
741
19.8k
        do
742
19.8k
        {
743
            // set style on shape
744
19.8k
            if( maTextStyleName.isEmpty() )
745
16.7k
                break;
746
747
3.17k
            if( nullptr == GetImport().GetShapeImport()->GetAutoStylesContext())
748
5
                break;
749
750
3.17k
            const SvXMLStyleContext* pTempStyle = GetImport().GetShapeImport()->GetAutoStylesContext()->FindStyleChildContext(XmlStyleFamily::TEXT_PARAGRAPH, maTextStyleName);
751
3.17k
            XMLPropStyleContext* pStyle = const_cast<XMLPropStyleContext*>(dynamic_cast<const XMLPropStyleContext*>( pTempStyle ) ); // use temp var, PTR_CAST is a bad macro, FindStyleChildContext will be called twice
752
3.17k
            if( pStyle == nullptr )
753
924
                break;
754
755
            // set PropertySet on object
756
2.24k
            pStyle->FillPropertySet(xPropSet);
757
758
2.24k
        } while(false);
759
19.8k
    }
760
19.8k
    catch(const uno::Exception&)
761
19.8k
    {
762
0
    }
763
19.8k
}
764
765
void SdXMLShapeContext::SetLayer()
766
19.5k
{
767
19.5k
    if( maLayerName.isEmpty() )
768
15.0k
        return;
769
770
4.44k
    try
771
4.44k
    {
772
4.44k
        uno::Reference< beans::XPropertySet > xPropSet(mxShape, uno::UNO_QUERY);
773
4.44k
        if(xPropSet.is() )
774
4.44k
        {
775
4.44k
            xPropSet->setPropertyValue(u"LayerName"_ustr, Any(maLayerName));
776
4.44k
            return;
777
4.44k
        }
778
4.44k
    }
779
4.44k
    catch(const uno::Exception&)
780
4.44k
    {
781
171
    }
782
4.44k
}
783
784
void SdXMLShapeContext::SetThumbnail()
785
0
{
786
0
    if( maThumbnailURL.isEmpty() )
787
0
        return;
788
789
0
    try
790
0
    {
791
0
        uno::Reference< beans::XPropertySet > xPropSet(mxShape, uno::UNO_QUERY);
792
0
        if( !xPropSet.is() )
793
0
            return;
794
795
0
        uno::Reference< beans::XPropertySetInfo > xPropSetInfo( xPropSet->getPropertySetInfo() );
796
0
        if( xPropSetInfo.is() && xPropSetInfo->hasPropertyByName( u"ThumbnailGraphic"_ustr ) )
797
0
        {
798
            // load the thumbnail graphic and export it to a wmf stream so we can set
799
            // it at the api
800
801
0
            uno::Reference<graphic::XGraphic> xGraphic = GetImport().loadGraphicByURL(maThumbnailURL);
802
0
            xPropSet->setPropertyValue(u"ThumbnailGraphic"_ustr, uno::Any(xGraphic));
803
0
        }
804
0
    }
805
0
    catch(const uno::Exception&)
806
0
    {
807
0
    }
808
0
}
809
810
// this is called from the parent group for each unparsed attribute in the attribute list
811
bool SdXMLShapeContext::processAttribute( const sax_fastparser::FastAttributeList::FastAttributeIter & aIter )
812
58.6k
{
813
58.6k
    sal_Int32 nTmp;
814
58.6k
    switch (aIter.getToken())
815
58.6k
    {
816
4.40k
        case XML_ELEMENT(DRAW, XML_ZINDEX):
817
4.40k
        case XML_ELEMENT(DRAW_EXT, XML_ZINDEX):
818
4.40k
            mnZOrder = aIter.toInt32();
819
4.40k
            break;
820
0
        case XML_ELEMENT(DRAW, XML_ID):
821
0
        case XML_ELEMENT(DRAW_EXT, XML_ID):
822
0
            if (!mbHaveXmlId) { maShapeId = aIter.toString(); }
823
0
            break;
824
969
        case XML_ELEMENT(DRAW, XML_NAME):
825
969
        case XML_ELEMENT(DRAW_EXT, XML_NAME):
826
969
            maShapeName = aIter.toString();
827
969
            break;
828
9.19k
        case XML_ELEMENT(DRAW, XML_STYLE_NAME):
829
9.19k
        case XML_ELEMENT(DRAW_EXT, XML_STYLE_NAME):
830
9.19k
            maDrawStyleName = aIter.toString();
831
9.19k
            break;
832
3.17k
        case XML_ELEMENT(DRAW, XML_TEXT_STYLE_NAME):
833
3.17k
        case XML_ELEMENT(DRAW_EXT, XML_TEXT_STYLE_NAME):
834
3.17k
            maTextStyleName = aIter.toString();
835
3.17k
            break;
836
4.44k
        case XML_ELEMENT(DRAW, XML_LAYER):
837
4.44k
        case XML_ELEMENT(DRAW_EXT, XML_LAYER):
838
4.44k
            maLayerName = aIter.toString();
839
4.44k
            break;
840
0
        case XML_ELEMENT(DRAW, XML_DISPLAY):
841
0
        case XML_ELEMENT(DRAW_EXT, XML_DISPLAY):
842
0
            mbVisible = IsXMLToken( aIter, XML_ALWAYS ) || IsXMLToken( aIter, XML_SCREEN );
843
0
            mbPrintable = IsXMLToken( aIter, XML_ALWAYS ) || IsXMLToken( aIter, XML_PRINTER );
844
0
            break;
845
0
        case XML_ELEMENT(PRESENTATION, XML_USER_TRANSFORMED):
846
0
            mbIsUserTransformed = IsXMLToken( aIter, XML_TRUE );
847
0
            break;
848
503
        case XML_ELEMENT(PRESENTATION, XML_PLACEHOLDER):
849
503
            mbIsPlaceholder = IsXMLToken( aIter, XML_TRUE );
850
503
            if( mbIsPlaceholder )
851
503
                mbClearDefaultAttributes = false;
852
503
            break;
853
2.36k
        case XML_ELEMENT(PRESENTATION, XML_CLASS):
854
2.36k
            maPresentationClass = aIter.toString();
855
2.36k
            break;
856
1.58k
        case XML_ELEMENT(PRESENTATION, XML_STYLE_NAME):
857
1.58k
            maDrawStyleName = aIter.toString();
858
1.58k
            mnStyleFamily = XmlStyleFamily::SD_PRESENTATION_ID;
859
1.58k
            break;
860
0
        case XML_ELEMENT(SVG, XML_X):
861
5.57k
        case XML_ELEMENT(SVG_COMPAT, XML_X):
862
5.57k
            GetImport().GetMM100UnitConverter().convertMeasureToCore(
863
5.57k
                    maPosition.X, aIter.toView());
864
5.57k
            break;
865
0
        case XML_ELEMENT(SVG, XML_Y):
866
5.15k
        case XML_ELEMENT(SVG_COMPAT, XML_Y):
867
5.15k
            GetImport().GetMM100UnitConverter().convertMeasureToCore(
868
5.15k
                    maPosition.Y, aIter.toView());
869
5.15k
            break;
870
0
        case XML_ELEMENT(SVG, XML_WIDTH):
871
6.43k
        case XML_ELEMENT(SVG_COMPAT, XML_WIDTH):
872
6.43k
            GetImport().GetMM100UnitConverter().convertMeasureToCore(
873
6.43k
                    maSize.Width, aIter.toView());
874
6.43k
            if (maSize.Width > 0)
875
6.36k
                maSize.Width = o3tl::saturating_add<sal_Int32>(maSize.Width, 1);
876
72
            else if (maSize.Width < 0)
877
72
                maSize.Width = o3tl::saturating_add<sal_Int32>(maSize.Width, -1);
878
6.43k
            break;
879
0
        case XML_ELEMENT(SVG, XML_HEIGHT):
880
6.10k
        case XML_ELEMENT(SVG_COMPAT, XML_HEIGHT):
881
6.10k
            GetImport().GetMM100UnitConverter().convertMeasureToCore(
882
6.10k
                    maSize.Height, aIter.toView());
883
6.10k
            if (maSize.Height > 0)
884
4.67k
                maSize.Height = o3tl::saturating_add<sal_Int32>(maSize.Height, 1);
885
1.43k
            else if (maSize.Height < 0)
886
631
                maSize.Height = o3tl::saturating_add<sal_Int32>(maSize.Height, -1);
887
6.10k
            break;
888
249
        case XML_ELEMENT(DRAW, XML_TRANSFORM):
889
249
        case XML_ELEMENT(DRAW_EXT, XML_TRANSFORM):
890
249
        case XML_ELEMENT(SVG, XML_TRANSFORM):
891
249
        case XML_ELEMENT(SVG_COMPAT, XML_TRANSFORM):
892
            // because of #85127# take svg:transform into account and handle like
893
            // draw:transform for compatibility
894
249
            mnTransform.SetString(aIter.toString(), GetImport().GetMM100UnitConverter());
895
249
            break;
896
1
        case XML_ELEMENT(STYLE, XML_REL_WIDTH):
897
1
            if (sax::Converter::convertPercent(nTmp, aIter.toView()))
898
1
                mnRelWidth = static_cast<sal_Int16>(nTmp);
899
1
            break;
900
0
        case XML_ELEMENT(STYLE, XML_REL_HEIGHT):
901
0
            if (sax::Converter::convertPercent(nTmp, aIter.toView()))
902
0
                mnRelHeight = static_cast<sal_Int16>(nTmp);
903
0
            break;
904
0
        case XML_ELEMENT(NONE, XML_ID):
905
2
        case XML_ELEMENT(XML, XML_ID):
906
2
            maShapeId = aIter.toString();
907
2
            mbHaveXmlId = true;
908
2
            break;
909
8.52k
        default:
910
8.52k
            return false;
911
58.6k
    }
912
50.1k
    return true;
913
58.6k
}
914
915
bool SdXMLShapeContext::isPresentationShape() const
916
7.96k
{
917
7.96k
    if( !maPresentationClass.isEmpty() && const_cast<SdXMLShapeContext*>(this)->GetImport().GetShapeImport()->IsPresentationShapesSupported() )
918
2.21k
    {
919
2.21k
        if(XmlStyleFamily::SD_PRESENTATION_ID == mnStyleFamily)
920
1.43k
        {
921
1.43k
            return true;
922
1.43k
        }
923
924
781
        if( IsXMLToken( maPresentationClass, XML_HEADER ) || IsXMLToken( maPresentationClass, XML_FOOTER ) ||
925
398
            IsXMLToken( maPresentationClass, XML_PAGE_NUMBER ) || IsXMLToken( maPresentationClass, XML_DATE_TIME ) )
926
747
        {
927
747
            return true;
928
747
        }
929
781
    }
930
931
5.78k
    return false;
932
7.96k
}
933
934
SdXMLRectShapeContext::SdXMLRectShapeContext(
935
    SvXMLImport& rImport,
936
    const css::uno::Reference< css::xml::sax::XFastAttributeList>& xAttrList,
937
    uno::Reference< drawing::XShapes > const & rShapes,
938
    bool bTemporaryShape)
939
3.44k
:   SdXMLShapeContext( rImport, xAttrList, rShapes, bTemporaryShape ),
940
3.44k
    mnRadius( 0 )
941
3.44k
{
942
3.44k
}
943
944
SdXMLRectShapeContext::~SdXMLRectShapeContext()
945
{
946
}
947
948
// this is called from the parent group for each unparsed attribute in the attribute list
949
bool SdXMLRectShapeContext::processAttribute( const sax_fastparser::FastAttributeList::FastAttributeIter & aIter )
950
15.6k
{
951
15.6k
    switch (aIter.getToken())
952
15.6k
    {
953
0
        case XML_ELEMENT(DRAW, XML_CORNER_RADIUS):
954
0
            GetImport().GetMM100UnitConverter().convertMeasureToCore(
955
0
                    mnRadius, aIter.toView());
956
0
            break;
957
15.6k
        default:
958
15.6k
            return SdXMLShapeContext::processAttribute( aIter );
959
15.6k
    }
960
0
    return true;
961
15.6k
}
962
963
void SdXMLRectShapeContext::startFastElement (sal_Int32 nElement,
964
    const css::uno::Reference< css::xml::sax::XFastAttributeList >& xAttrList)
965
3.44k
{
966
    // create rectangle shape
967
3.44k
    AddShape(u"com.sun.star.drawing.RectangleShape"_ustr);
968
3.44k
    if(!mxShape.is())
969
0
        return;
970
971
    // Add, set Style and properties from base shape
972
3.44k
    SetStyle();
973
3.44k
    SetLayer();
974
975
    // set pos, size, shear and rotate
976
3.44k
    SetTransformation();
977
978
3.44k
    if(mnRadius)
979
0
    {
980
0
        uno::Reference< beans::XPropertySet > xPropSet(mxShape, uno::UNO_QUERY);
981
0
        if(xPropSet.is())
982
0
        {
983
0
            try
984
0
            {
985
0
                xPropSet->setPropertyValue(u"CornerRadius"_ustr, uno::Any( mnRadius ) );
986
0
            }
987
0
            catch(const uno::Exception&)
988
0
            {
989
0
                DBG_UNHANDLED_EXCEPTION( "xmloff", "setting corner radius");
990
0
            }
991
0
        }
992
0
    }
993
3.44k
    SdXMLShapeContext::startFastElement(nElement, xAttrList);
994
3.44k
}
995
996
997
SdXMLLineShapeContext::SdXMLLineShapeContext(
998
    SvXMLImport& rImport,
999
    const css::uno::Reference< css::xml::sax::XFastAttributeList>& xAttrList,
1000
    uno::Reference< drawing::XShapes > const & rShapes,
1001
    bool bTemporaryShape)
1002
1.18k
:   SdXMLShapeContext( rImport, xAttrList, rShapes, bTemporaryShape ),
1003
1.18k
    mnX1( 0 ),
1004
1.18k
    mnY1( 0 ),
1005
1.18k
    mnX2( 1 ),
1006
1.18k
    mnY2( 1 )
1007
1.18k
{
1008
1.18k
}
1009
1010
SdXMLLineShapeContext::~SdXMLLineShapeContext()
1011
{
1012
}
1013
1014
// this is called from the parent group for each unparsed attribute in the attribute list
1015
bool SdXMLLineShapeContext::processAttribute( const sax_fastparser::FastAttributeList::FastAttributeIter & aIter )
1016
3.62k
{
1017
3.62k
    switch (aIter.getToken())
1018
3.62k
    {
1019
0
        case XML_ELEMENT(SVG, XML_X1):
1020
303
        case XML_ELEMENT(SVG_COMPAT, XML_X1):
1021
303
            GetImport().GetMM100UnitConverter().convertMeasureToCore(
1022
303
                    mnX1, aIter.toView());
1023
303
            break;
1024
0
        case XML_ELEMENT(SVG, XML_Y1):
1025
383
        case XML_ELEMENT(SVG_COMPAT, XML_Y1):
1026
383
            GetImport().GetMM100UnitConverter().convertMeasureToCore(
1027
383
                    mnY1, aIter.toView());
1028
383
            break;
1029
0
        case XML_ELEMENT(SVG, XML_X2):
1030
390
        case XML_ELEMENT(SVG_COMPAT, XML_X2):
1031
390
            GetImport().GetMM100UnitConverter().convertMeasureToCore(
1032
390
                    mnX2, aIter.toView());
1033
390
            break;
1034
0
        case XML_ELEMENT(SVG, XML_Y2):
1035
416
        case XML_ELEMENT(SVG_COMPAT, XML_Y2):
1036
416
            GetImport().GetMM100UnitConverter().convertMeasureToCore(
1037
416
                    mnY2, aIter.toView());
1038
416
            break;
1039
2.13k
        default:
1040
2.13k
            return SdXMLShapeContext::processAttribute( aIter );
1041
3.62k
    }
1042
1.49k
    return true;
1043
3.62k
}
1044
1045
void SdXMLLineShapeContext::startFastElement (sal_Int32 nElement,
1046
    const css::uno::Reference< css::xml::sax::XFastAttributeList >& xAttrList)
1047
1.18k
{
1048
    // #85920# use SetTransformation() to handle import of simple lines.
1049
    // This is necessary to take into account all anchor positions and
1050
    // other things. All shape imports use the same import schemata now.
1051
    // create necessary shape (Line Shape)
1052
1.18k
    AddShape(u"com.sun.star.drawing.PolyLineShape"_ustr);
1053
1054
1.18k
    if(!mxShape.is())
1055
0
        return;
1056
1057
    // Add, set Style and properties from base shape
1058
1.18k
    SetStyle();
1059
1.18k
    SetLayer();
1060
1061
    // get sizes and offsets
1062
1.18k
    awt::Point aTopLeft(mnX1, mnY1);
1063
1064
1.18k
    if(mnX1 > mnX2)
1065
134
    {
1066
134
        aTopLeft.X = mnX2;
1067
134
    }
1068
1069
1.18k
    if(mnY1 > mnY2)
1070
58
    {
1071
58
        aTopLeft.Y = mnY2;
1072
58
    }
1073
1074
    // set local parameters on shape
1075
1.18k
    uno::Reference< beans::XPropertySet > xPropSet(mxShape, uno::UNO_QUERY);
1076
1.18k
    if(xPropSet.is())
1077
1.18k
    {
1078
1.18k
        drawing::PointSequenceSequence aPolyPoly(1);
1079
1.18k
        drawing::PointSequence* pOuterSequence = aPolyPoly.getArray();
1080
1.18k
        pOuterSequence->realloc(2);
1081
1.18k
        awt::Point* pInnerSequence = pOuterSequence->getArray();
1082
1083
1.18k
        *pInnerSequence = awt::Point(o3tl::saturating_sub(mnX1, aTopLeft.X), o3tl::saturating_sub(mnY1, aTopLeft.Y));
1084
1.18k
        pInnerSequence++;
1085
1.18k
        *pInnerSequence = awt::Point(o3tl::saturating_sub(mnX2, aTopLeft.X), o3tl::saturating_sub(mnY2, aTopLeft.Y));
1086
1087
1.18k
        xPropSet->setPropertyValue(u"Geometry"_ustr, Any(aPolyPoly));
1088
1.18k
    }
1089
1090
    // Size is included in point coordinates
1091
1.18k
    maSize.Width = 1;
1092
1.18k
    maSize.Height = 1;
1093
1.18k
    maPosition.X = aTopLeft.X;
1094
1.18k
    maPosition.Y = aTopLeft.Y;
1095
1096
    // set pos, size, shear and rotate and get copy of matrix
1097
1.18k
    SetTransformation();
1098
1099
1.18k
    SdXMLShapeContext::startFastElement(nElement, xAttrList);
1100
1.18k
}
1101
1102
1103
SdXMLEllipseShapeContext::SdXMLEllipseShapeContext(
1104
    SvXMLImport& rImport,
1105
    const css::uno::Reference< css::xml::sax::XFastAttributeList>& xAttrList,
1106
    uno::Reference< drawing::XShapes > const & rShapes,
1107
    bool bTemporaryShape)
1108
5
:   SdXMLShapeContext( rImport, xAttrList, rShapes, bTemporaryShape ),
1109
5
    mnCX( 0 ),
1110
5
    mnCY( 0 ),
1111
5
    mnRX( 1 ),
1112
5
    mnRY( 1 ),
1113
5
    meKind( drawing::CircleKind_FULL ),
1114
5
    mnStartAngle( 0 ),
1115
5
    mnEndAngle( 0 )
1116
5
{
1117
5
}
1118
1119
SdXMLEllipseShapeContext::~SdXMLEllipseShapeContext()
1120
{
1121
}
1122
1123
// this is called from the parent group for each unparsed attribute in the attribute list
1124
bool SdXMLEllipseShapeContext::processAttribute( const sax_fastparser::FastAttributeList::FastAttributeIter & aIter )
1125
0
{
1126
0
    switch (aIter.getToken())
1127
0
    {
1128
0
        case XML_ELEMENT(SVG, XML_RX):
1129
0
        case XML_ELEMENT(SVG_COMPAT, XML_RX):
1130
0
            GetImport().GetMM100UnitConverter().convertMeasureToCore(
1131
0
                    mnRX, aIter.toView());
1132
0
            break;
1133
0
        case XML_ELEMENT(SVG, XML_RY):
1134
0
        case XML_ELEMENT(SVG_COMPAT, XML_RY):
1135
0
            GetImport().GetMM100UnitConverter().convertMeasureToCore(
1136
0
                    mnRY, aIter.toView());
1137
0
            break;
1138
0
        case XML_ELEMENT(SVG, XML_CX):
1139
0
        case XML_ELEMENT(SVG_COMPAT, XML_CX):
1140
0
            GetImport().GetMM100UnitConverter().convertMeasureToCore(
1141
0
                    mnCX, aIter.toView());
1142
0
            break;
1143
0
        case XML_ELEMENT(SVG, XML_CY):
1144
0
        case XML_ELEMENT(SVG_COMPAT, XML_CY):
1145
0
            GetImport().GetMM100UnitConverter().convertMeasureToCore(
1146
0
                    mnCY, aIter.toView());
1147
0
            break;
1148
0
        case XML_ELEMENT(SVG, XML_R):
1149
0
        case XML_ELEMENT(SVG_COMPAT, XML_R):
1150
            // single radius, it's a circle and both radii are the same
1151
0
            GetImport().GetMM100UnitConverter().convertMeasureToCore(
1152
0
                    mnRX, aIter.toView());
1153
0
            mnRY = mnRX;
1154
0
            break;
1155
0
        case XML_ELEMENT(DRAW, XML_KIND):
1156
0
            SvXMLUnitConverter::convertEnum( meKind, aIter.toView(), aXML_CircleKind_EnumMap );
1157
0
            break;
1158
0
        case XML_ELEMENT(DRAW, XML_START_ANGLE):
1159
0
        {
1160
0
            double dStartAngle;
1161
0
            if (::sax::Converter::convertAngle( dStartAngle, aIter.toView()))
1162
0
                mnStartAngle = static_cast<sal_Int32>(basegfx::fround(dStartAngle * 100));
1163
0
            break;
1164
0
        }
1165
0
        case XML_ELEMENT(DRAW, XML_END_ANGLE):
1166
0
        {
1167
0
            double dEndAngle;
1168
0
            if (::sax::Converter::convertAngle( dEndAngle, aIter.toView()))
1169
0
                mnEndAngle = static_cast<sal_Int32>(basegfx::fround(dEndAngle * 100));
1170
0
            break;
1171
0
        }
1172
0
        default:
1173
0
            return SdXMLShapeContext::processAttribute( aIter );
1174
0
    }
1175
0
    return true;
1176
0
}
1177
1178
void SdXMLEllipseShapeContext::startFastElement (sal_Int32 nElement,
1179
    const css::uno::Reference< css::xml::sax::XFastAttributeList >& xAttrList)
1180
5
{
1181
    // create rectangle shape
1182
5
    AddShape(u"com.sun.star.drawing.EllipseShape"_ustr);
1183
5
    if(!mxShape.is())
1184
0
        return;
1185
1186
    // Add, set Style and properties from base shape
1187
5
    SetStyle();
1188
5
    SetLayer();
1189
1190
5
    if(mnCX != 0 || mnCY != 0 || mnRX != 1 || mnRY != 1)
1191
0
    {
1192
        // #i121972# center/radius is used, put to pos and size
1193
0
        maSize.Width = 2 * mnRX;
1194
0
        maSize.Height = 2 * mnRY;
1195
0
        maPosition.X = mnCX - mnRX;
1196
0
        maPosition.Y = mnCY - mnRY;
1197
0
    }
1198
    // set pos, size, shear and rotate
1199
5
    SetTransformation();
1200
1201
5
    if( meKind != drawing::CircleKind_FULL )
1202
0
    {
1203
0
        uno::Reference< beans::XPropertySet > xPropSet( mxShape, uno::UNO_QUERY );
1204
0
        if( xPropSet.is() )
1205
0
        {
1206
            // calculate the correct start and end angle
1207
0
            sal_Int32 mnOldStartAngle = mnStartAngle;
1208
0
            sal_Int32 mnOldEndAngle = mnEndAngle;
1209
0
            basegfx::B2DTuple aScale;
1210
0
            basegfx::B2DTuple aTranslate;
1211
0
            double fRotate;
1212
0
            double fShearX;
1213
0
            maUsedTransformation.decompose(aScale, aTranslate, fRotate, fShearX);
1214
0
            if (aScale.getX() < 0 || aScale.getY() < 0)
1215
0
            {
1216
                // The angle for a horizontal flip is the same as the angle for a
1217
                // vertical flip because a vertical flip is treated as a horizontal
1218
                // flip plus a rotation.
1219
1220
                // To perform the flip, the start and end angle are switched and we
1221
                // use the fact performing a horizontal flip on a shape will change
1222
                // the angle that a radius makes with the origin to 180 degrees
1223
                // minus that angle (we use 54000 hundredths of a degree to get the
1224
                // modulus operation to give a value between 0 and 36000).
1225
1226
0
                mnStartAngle = (54000 - mnOldEndAngle) % 36000;
1227
0
                mnEndAngle = (54000 - mnOldStartAngle) % 36000;
1228
0
            }
1229
1230
0
            xPropSet->setPropertyValue(u"CircleKind"_ustr, Any( meKind) );
1231
0
            xPropSet->setPropertyValue(u"CircleStartAngle"_ustr, Any(mnStartAngle) );
1232
0
            xPropSet->setPropertyValue(u"CircleEndAngle"_ustr, Any(mnEndAngle) );
1233
0
        }
1234
0
    }
1235
1236
5
    SdXMLShapeContext::startFastElement(nElement, xAttrList);
1237
5
}
1238
1239
1240
SdXMLPolygonShapeContext::SdXMLPolygonShapeContext(
1241
    SvXMLImport& rImport,
1242
    const css::uno::Reference< css::xml::sax::XFastAttributeList>& xAttrList,
1243
    uno::Reference< drawing::XShapes > const & rShapes, bool bClosed, bool bTemporaryShape)
1244
250
:   SdXMLShapeContext( rImport, xAttrList, rShapes, bTemporaryShape ),
1245
250
    mbClosed( bClosed )
1246
250
{
1247
250
}
1248
1249
// this is called from the parent group for each unparsed attribute in the attribute list
1250
bool SdXMLPolygonShapeContext::processAttribute( const sax_fastparser::FastAttributeList::FastAttributeIter & aIter )
1251
2.33k
{
1252
2.33k
    switch (aIter.getToken())
1253
2.33k
    {
1254
0
        case XML_ELEMENT(SVG, XML_VIEWBOX):
1255
227
        case XML_ELEMENT(SVG_COMPAT, XML_VIEWBOX):
1256
227
            maViewBox = aIter.toString();
1257
227
            break;
1258
240
        case XML_ELEMENT(DRAW, XML_POINTS):
1259
240
            maPoints = aIter.toString();
1260
240
            break;
1261
1.87k
        default:
1262
1.87k
            return SdXMLShapeContext::processAttribute( aIter);
1263
2.33k
    }
1264
467
    return true;
1265
2.33k
}
1266
1267
SdXMLPolygonShapeContext::~SdXMLPolygonShapeContext()
1268
250
{
1269
250
}
1270
1271
void SdXMLPolygonShapeContext::startFastElement (sal_Int32 nElement,
1272
    const css::uno::Reference< css::xml::sax::XFastAttributeList >& xAttrList)
1273
250
{
1274
    // Add, set Style and properties from base shape
1275
250
    if(mbClosed)
1276
242
        AddShape(u"com.sun.star.drawing.PolyPolygonShape"_ustr);
1277
8
    else
1278
8
        AddShape(u"com.sun.star.drawing.PolyLineShape"_ustr);
1279
1280
250
    if( !mxShape.is() )
1281
0
        return;
1282
1283
250
    SetStyle();
1284
250
    SetLayer();
1285
1286
    // set local parameters on shape
1287
250
    uno::Reference< beans::XPropertySet > xPropSet(mxShape, uno::UNO_QUERY);
1288
250
    if(xPropSet.is())
1289
250
    {
1290
        // set polygon
1291
250
        if(!maPoints.isEmpty() && !maViewBox.isEmpty())
1292
226
        {
1293
226
            const SdXMLImExViewBox aViewBox(maViewBox, GetImport().GetMM100UnitConverter());
1294
226
            basegfx::B2DVector aSize(aViewBox.GetWidth(), aViewBox.GetHeight());
1295
1296
            // Is this correct? It overrides ViewBox stuff; OTOH it makes no
1297
            // sense to have the geometry content size different from object size
1298
226
            if(maSize.Width != 0 && maSize.Height != 0)
1299
226
            {
1300
226
                aSize = basegfx::B2DVector(maSize.Width, maSize.Height);
1301
226
            }
1302
1303
226
            basegfx::B2DPolygon aPolygon;
1304
1305
226
            if(basegfx::utils::importFromSvgPoints(aPolygon, maPoints))
1306
223
            {
1307
223
                if(aPolygon.count())
1308
223
                {
1309
223
                    const basegfx::B2DRange aSourceRange(
1310
223
                        aViewBox.GetX(), aViewBox.GetY(),
1311
223
                        aViewBox.GetX() + aViewBox.GetWidth(), aViewBox.GetY() + aViewBox.GetHeight());
1312
223
                    const basegfx::B2DRange aTargetRange(
1313
223
                        aViewBox.GetX(), aViewBox.GetY(),
1314
223
                        aViewBox.GetX() + aSize.getX(), aViewBox.GetY() + aSize.getY());
1315
1316
223
                    if(!aSourceRange.equal(aTargetRange))
1317
4
                    {
1318
4
                        aPolygon.transform(
1319
4
                            basegfx::utils::createSourceRangeTargetRangeTransform(
1320
4
                                aSourceRange,
1321
4
                                aTargetRange));
1322
4
                    }
1323
1324
223
                    css::drawing::PointSequenceSequence aPointSequenceSequence;
1325
223
                    basegfx::utils::B2DPolyPolygonToUnoPointSequenceSequence(basegfx::B2DPolyPolygon(aPolygon), aPointSequenceSequence);
1326
223
                    xPropSet->setPropertyValue(u"Geometry"_ustr, Any(aPointSequenceSequence));
1327
                    // Size is now contained in the point coordinates, adapt maSize for
1328
                    // to use the correct transformation matrix in SetTransformation()
1329
223
                    maSize.Width = 1;
1330
223
                    maSize.Height = 1;
1331
223
                }
1332
223
            }
1333
226
        }
1334
250
    }
1335
1336
    // set pos, size, shear and rotate and get copy of matrix
1337
250
    SetTransformation();
1338
1339
250
    SdXMLShapeContext::startFastElement(nElement, xAttrList);
1340
250
}
1341
1342
1343
SdXMLPathShapeContext::SdXMLPathShapeContext(
1344
    SvXMLImport& rImport,
1345
    const css::uno::Reference< css::xml::sax::XFastAttributeList>& xAttrList,
1346
    uno::Reference< drawing::XShapes > const & rShapes,
1347
    bool bTemporaryShape)
1348
0
:   SdXMLShapeContext( rImport, xAttrList, rShapes, bTemporaryShape )
1349
0
{
1350
0
}
1351
1352
SdXMLPathShapeContext::~SdXMLPathShapeContext()
1353
0
{
1354
0
}
1355
1356
// this is called from the parent group for each unparsed attribute in the attribute list
1357
bool SdXMLPathShapeContext::processAttribute( const sax_fastparser::FastAttributeList::FastAttributeIter & aIter )
1358
0
{
1359
0
    switch (aIter.getToken())
1360
0
    {
1361
0
        case XML_ELEMENT(SVG, XML_VIEWBOX):
1362
0
        case XML_ELEMENT(SVG_COMPAT, XML_VIEWBOX):
1363
0
            maViewBox = aIter.toString();
1364
0
            break;
1365
0
        case XML_ELEMENT(SVG, XML_D):
1366
0
        case XML_ELEMENT(SVG_COMPAT, XML_D):
1367
0
            maD = aIter.toString();
1368
0
            break;
1369
0
        default:
1370
0
            return SdXMLShapeContext::processAttribute( aIter );
1371
0
    }
1372
0
    return true;
1373
0
}
1374
1375
void SdXMLPathShapeContext::startFastElement (sal_Int32 nElement,
1376
    const css::uno::Reference< css::xml::sax::XFastAttributeList >& xAttrList)
1377
0
{
1378
    // create polygon shape
1379
0
    if(maD.isEmpty())
1380
0
        return;
1381
1382
0
    const SdXMLImExViewBox aViewBox(maViewBox, GetImport().GetMM100UnitConverter());
1383
0
    basegfx::B2DVector aSize(aViewBox.GetWidth(), aViewBox.GetHeight());
1384
1385
    // Is this correct? It overrides ViewBox stuff; OTOH it makes no
1386
    // sense to have the geometry content size different from object size
1387
0
    if(maSize.Width != 0 && maSize.Height != 0)
1388
0
    {
1389
0
        aSize = basegfx::B2DVector(maSize.Width, maSize.Height);
1390
0
    }
1391
1392
0
    basegfx::B2DPolyPolygon aPolyPolygon;
1393
1394
0
    if(!basegfx::utils::importFromSvgD(aPolyPolygon, maD, GetImport().needFixPositionAfterZ(), nullptr))
1395
0
        return;
1396
1397
0
    if(!aPolyPolygon.count())
1398
0
        return;
1399
1400
0
    const basegfx::B2DRange aSourceRange(
1401
0
        aViewBox.GetX(), aViewBox.GetY(),
1402
0
        aViewBox.GetX() + aViewBox.GetWidth(), aViewBox.GetY() + aViewBox.GetHeight());
1403
0
    const basegfx::B2DRange aTargetRange(
1404
0
        aViewBox.GetX(), aViewBox.GetY(),
1405
0
        aViewBox.GetX() + aSize.getX(), aViewBox.GetY() + aSize.getY());
1406
1407
0
    if(!aSourceRange.equal(aTargetRange))
1408
0
    {
1409
0
        aPolyPolygon.transform(
1410
0
            basegfx::utils::createSourceRangeTargetRangeTransform(
1411
0
                aSourceRange,
1412
0
                aTargetRange));
1413
0
    }
1414
1415
    // create shape
1416
0
    OUString service;
1417
1418
0
    if(aPolyPolygon.areControlPointsUsed())
1419
0
    {
1420
0
        if(aPolyPolygon.isClosed())
1421
0
        {
1422
0
            service = "com.sun.star.drawing.ClosedBezierShape";
1423
0
        }
1424
0
        else
1425
0
        {
1426
0
            service = "com.sun.star.drawing.OpenBezierShape";
1427
0
        }
1428
0
    }
1429
0
    else
1430
0
    {
1431
0
        if(aPolyPolygon.isClosed())
1432
0
        {
1433
0
            service = "com.sun.star.drawing.PolyPolygonShape";
1434
0
        }
1435
0
        else
1436
0
        {
1437
0
            service = "com.sun.star.drawing.PolyLineShape";
1438
0
        }
1439
0
    }
1440
1441
    // Add, set Style and properties from base shape
1442
0
    AddShape(service);
1443
1444
    // #89344# test for mxShape.is() and not for mxShapes.is() to support
1445
    // shape import helper classes WITHOUT XShapes (member mxShapes). This
1446
    // is used by the writer.
1447
0
    if( !mxShape.is() )
1448
0
        return;
1449
1450
0
    SetStyle();
1451
0
    SetLayer();
1452
1453
    // set local parameters on shape
1454
0
    uno::Reference< beans::XPropertySet > xPropSet(mxShape, uno::UNO_QUERY);
1455
1456
0
    if(xPropSet.is())
1457
0
    {
1458
0
        uno::Any aAny;
1459
1460
        // set polygon data
1461
0
        if(aPolyPolygon.areControlPointsUsed())
1462
0
        {
1463
0
            drawing::PolyPolygonBezierCoords aSourcePolyPolygon;
1464
1465
0
            basegfx::utils::B2DPolyPolygonToUnoPolyPolygonBezierCoords(
1466
0
                aPolyPolygon,
1467
0
                aSourcePolyPolygon);
1468
0
            aAny <<= aSourcePolyPolygon;
1469
0
        }
1470
0
        else
1471
0
        {
1472
0
            drawing::PointSequenceSequence aSourcePolyPolygon;
1473
1474
0
            basegfx::utils::B2DPolyPolygonToUnoPointSequenceSequence(
1475
0
                aPolyPolygon,
1476
0
                aSourcePolyPolygon);
1477
0
            aAny <<= aSourcePolyPolygon;
1478
0
        }
1479
1480
0
        xPropSet->setPropertyValue(u"Geometry"_ustr, aAny);
1481
        // Size is now contained in the point coordinates, adapt maSize for
1482
        // to use the correct transformation matrix in SetTransformation()
1483
0
        maSize.Width = 1;
1484
0
        maSize.Height = 1;
1485
0
    }
1486
1487
    // set pos, size, shear and rotate
1488
0
    SetTransformation();
1489
1490
0
    SdXMLShapeContext::startFastElement(nElement, xAttrList);
1491
0
}
1492
1493
1494
SdXMLTextBoxShapeContext::SdXMLTextBoxShapeContext(
1495
    SvXMLImport& rImport,
1496
    const css::uno::Reference< css::xml::sax::XFastAttributeList>& xAttrList,
1497
    uno::Reference< drawing::XShapes > const & rShapes)
1498
7.96k
:   SdXMLShapeContext( rImport, xAttrList, rShapes, false/*bTemporaryShape*/ ),
1499
7.96k
    mnRadius(0),
1500
7.96k
    maChainNextName(u""_ustr)
1501
7.96k
{
1502
7.96k
}
1503
1504
SdXMLTextBoxShapeContext::~SdXMLTextBoxShapeContext()
1505
7.96k
{
1506
7.96k
}
1507
1508
// this is called from the parent group for each unparsed attribute in the attribute list
1509
bool SdXMLTextBoxShapeContext::processAttribute( const sax_fastparser::FastAttributeList::FastAttributeIter & aIter )
1510
26.4k
{
1511
26.4k
    switch (aIter.getToken())
1512
26.4k
    {
1513
0
        case XML_ELEMENT(DRAW, XML_CORNER_RADIUS):
1514
0
            GetImport().GetMM100UnitConverter().convertMeasureToCore(
1515
0
                    mnRadius, aIter.toView());
1516
0
            break;
1517
0
        case XML_ELEMENT(DRAW, XML_CHAIN_NEXT_NAME):
1518
0
            maChainNextName = aIter.toString();
1519
0
            break;
1520
26.4k
        default:
1521
26.4k
            return SdXMLShapeContext::processAttribute( aIter );
1522
26.4k
    }
1523
0
    return true;
1524
26.4k
}
1525
1526
void SdXMLTextBoxShapeContext::startFastElement (sal_Int32 nElement,
1527
    const css::uno::Reference< css::xml::sax::XFastAttributeList >& xAttrList)
1528
7.96k
{
1529
    // create textbox shape
1530
7.96k
    bool bIsPresShape = false;
1531
7.96k
    bool bClearText = false;
1532
1533
7.96k
    OUString service;
1534
1535
7.96k
    if( isPresentationShape() )
1536
2.17k
    {
1537
        // check if the current document supports presentation shapes
1538
2.17k
        if( GetImport().GetShapeImport()->IsPresentationShapesSupported() )
1539
2.17k
        {
1540
2.17k
            if( IsXMLToken( maPresentationClass, XML_SUBTITLE ))
1541
0
            {
1542
                // XmlShapeType::PresSubtitleShape
1543
0
                service = "com.sun.star.presentation.SubtitleShape";
1544
0
            }
1545
2.17k
            else if( IsXMLToken( maPresentationClass, XML_PRESENTATION_OUTLINE ) )
1546
312
            {
1547
                // XmlShapeType::PresOutlinerShape
1548
312
                service = "com.sun.star.presentation.OutlinerShape";
1549
312
            }
1550
1.86k
            else if( IsXMLToken( maPresentationClass, XML_NOTES ) )
1551
137
            {
1552
                // XmlShapeType::PresNotesShape
1553
137
                service = "com.sun.star.presentation.NotesShape";
1554
137
            }
1555
1.73k
            else if( IsXMLToken( maPresentationClass, XML_HEADER ) )
1556
289
            {
1557
                // XmlShapeType::PresHeaderShape
1558
289
                service = "com.sun.star.presentation.HeaderShape";
1559
289
                bClearText = true;
1560
289
            }
1561
1.44k
            else if( IsXMLToken( maPresentationClass, XML_FOOTER ) )
1562
400
            {
1563
                // XmlShapeType::PresFooterShape
1564
400
                service = "com.sun.star.presentation.FooterShape";
1565
400
                bClearText = true;
1566
400
            }
1567
1.04k
            else if( IsXMLToken( maPresentationClass, XML_PAGE_NUMBER ) )
1568
369
            {
1569
                // XmlShapeType::PresSlideNumberShape
1570
369
                service = "com.sun.star.presentation.SlideNumberShape";
1571
369
                bClearText = true;
1572
369
            }
1573
672
            else if( IsXMLToken( maPresentationClass, XML_DATE_TIME ) )
1574
427
            {
1575
                // XmlShapeType::PresDateTimeShape
1576
427
                service = "com.sun.star.presentation.DateTimeShape";
1577
427
                bClearText = true;
1578
427
            }
1579
245
            else //  IsXMLToken( maPresentationClass, XML_TITLE ) )
1580
245
            {
1581
                // XmlShapeType::PresTitleTextShape
1582
245
                service = "com.sun.star.presentation.TitleTextShape";
1583
245
            }
1584
2.17k
            bIsPresShape = true;
1585
2.17k
        }
1586
2.17k
    }
1587
1588
7.96k
    if( service.isEmpty() )
1589
5.78k
    {
1590
        // normal text shape
1591
5.78k
        service = "com.sun.star.drawing.TextShape";
1592
5.78k
    }
1593
1594
    // Add, set Style and properties from base shape
1595
7.96k
    AddShape(service);
1596
1597
7.96k
    if( !mxShape.is() )
1598
0
        return;
1599
1600
7.96k
    SetStyle();
1601
7.96k
    SetLayer();
1602
1603
7.96k
    if(bIsPresShape)
1604
2.17k
    {
1605
2.17k
        uno::Reference< beans::XPropertySet > xProps(mxShape, uno::UNO_QUERY);
1606
2.17k
        if(xProps.is())
1607
2.17k
        {
1608
2.17k
            uno::Reference< beans::XPropertySetInfo > xPropsInfo( xProps->getPropertySetInfo() );
1609
2.17k
            if( xPropsInfo.is() )
1610
2.17k
            {
1611
2.17k
                if( !mbIsPlaceholder && xPropsInfo->hasPropertyByName(u"IsEmptyPresentationObject"_ustr))
1612
1.69k
                    xProps->setPropertyValue(u"IsEmptyPresentationObject"_ustr, css::uno::Any(false) );
1613
1614
2.17k
                if( mbIsUserTransformed && xPropsInfo->hasPropertyByName(u"IsPlaceholderDependent"_ustr))
1615
0
                    xProps->setPropertyValue(u"IsPlaceholderDependent"_ustr, css::uno::Any(false) );
1616
2.17k
            }
1617
2.17k
        }
1618
2.17k
    }
1619
1620
7.96k
    if( bClearText )
1621
1.48k
    {
1622
1.48k
        uno::Reference< text::XText > xText( mxShape, uno::UNO_QUERY );
1623
1.48k
        xText->setString( u""_ustr );
1624
1.48k
    }
1625
1626
    // set parameters on shape
1627
//A AW->CL: Eventually You need to strip scale and translate from the transformation
1628
//A to reach the same goal again.
1629
//A     if(!bIsPresShape || mbIsUserTransformed)
1630
//A     {
1631
//A         // set pos and size on shape, this should remove binding
1632
//A         // to presentation object on masterpage
1633
//A         SetSizeAndPosition();
1634
//A     }
1635
1636
    // set pos, size, shear and rotate
1637
7.96k
    SetTransformation();
1638
1639
7.96k
    if(mnRadius)
1640
0
    {
1641
0
        uno::Reference< beans::XPropertySet > xPropSet(mxShape, uno::UNO_QUERY);
1642
0
        if(xPropSet.is())
1643
0
        {
1644
0
            try
1645
0
            {
1646
0
                xPropSet->setPropertyValue(u"CornerRadius"_ustr, uno::Any( mnRadius ) );
1647
0
            }
1648
0
            catch(const uno::Exception&)
1649
0
            {
1650
0
                DBG_UNHANDLED_EXCEPTION( "xmloff", "setting corner radius");
1651
0
            }
1652
0
        }
1653
0
    }
1654
1655
7.96k
    if(!maChainNextName.isEmpty())
1656
0
    {
1657
0
        uno::Reference< beans::XPropertySet > xPropSet(mxShape, uno::UNO_QUERY);
1658
0
        if(xPropSet.is())
1659
0
        {
1660
0
            try
1661
0
            {
1662
0
                xPropSet->setPropertyValue(u"TextChainNextName"_ustr,
1663
0
                                           uno::Any( maChainNextName ) );
1664
0
            }
1665
0
            catch(const uno::Exception&)
1666
0
            {
1667
0
                DBG_UNHANDLED_EXCEPTION( "xmloff", "setting name of next chain link");
1668
0
            }
1669
0
        }
1670
0
    }
1671
1672
7.96k
    SdXMLShapeContext::startFastElement(nElement, xAttrList);
1673
7.96k
}
1674
1675
1676
SdXMLControlShapeContext::SdXMLControlShapeContext(
1677
    SvXMLImport& rImport,
1678
    const css::uno::Reference< css::xml::sax::XFastAttributeList>& xAttrList,
1679
    uno::Reference< drawing::XShapes > const & rShapes,
1680
    bool bTemporaryShape)
1681
3.46k
:   SdXMLShapeContext( rImport, xAttrList, rShapes, bTemporaryShape )
1682
3.46k
{
1683
3.46k
}
1684
1685
SdXMLControlShapeContext::~SdXMLControlShapeContext()
1686
3.46k
{
1687
3.46k
}
1688
1689
// this is called from the parent group for each unparsed attribute in the attribute list
1690
bool SdXMLControlShapeContext::processAttribute( const sax_fastparser::FastAttributeList::FastAttributeIter & aIter )
1691
0
{
1692
0
    switch (aIter.getToken())
1693
0
    {
1694
0
        case XML_ELEMENT(DRAW, XML_CONTROL):
1695
0
            maFormId = aIter.toString();
1696
0
            break;
1697
0
        default:
1698
0
            return SdXMLShapeContext::processAttribute( aIter );
1699
0
    }
1700
0
    return true;
1701
0
}
1702
1703
void SdXMLControlShapeContext::startFastElement (sal_Int32 nElement,
1704
    const css::uno::Reference< css::xml::sax::XFastAttributeList >& xAttrList)
1705
3.46k
{
1706
    // create Control shape
1707
    // add, set style and properties from base shape
1708
3.46k
    AddShape(u"com.sun.star.drawing.ControlShape"_ustr);
1709
3.46k
    if( !mxShape.is() )
1710
0
        return;
1711
1712
3.46k
    SAL_WARN_IF( !!maFormId.isEmpty(), "xmloff", "draw:control without a form:id attribute!" );
1713
3.46k
    if( !maFormId.isEmpty() )
1714
0
    {
1715
0
        if( GetImport().IsFormsSupported() )
1716
0
        {
1717
0
            uno::Reference< awt::XControlModel > xControlModel( GetImport().GetFormImport()->lookupControl( maFormId ), uno::UNO_QUERY );
1718
0
            if( xControlModel.is() )
1719
0
            {
1720
0
                uno::Reference< drawing::XControlShape > xControl( mxShape, uno::UNO_QUERY );
1721
0
                if( xControl.is() )
1722
0
                    xControl->setControl(  xControlModel );
1723
1724
0
            }
1725
0
        }
1726
0
    }
1727
1728
3.46k
    SetStyle();
1729
1730
    // tdf#156707 if fo:border was not in the auto style, apply the control
1731
    // model's own default (which varies per control type) to the shape
1732
3.46k
    if (const XMLPropStyleContext* pDocStyle = dynamic_cast<const XMLPropStyleContext*>(FindAutoStyle()))
1733
0
    {
1734
0
        SvXMLImportPropertyMapper* pImpMapper = GetImport().GetShapeImport()->GetPropertySetMapper();
1735
0
        const rtl::Reference<XMLPropertySetMapper>& rMapper = pImpMapper->getPropertySetMapper();
1736
1737
0
        bool bHasBorder = false;
1738
0
        for (const auto& rProp : pDocStyle->GetProperties())
1739
0
        {
1740
0
            if (rProp.mnIndex < 0)
1741
0
                continue;
1742
0
            if (rMapper->GetEntryAPIName(rProp.mnIndex) == "ControlBorder")
1743
0
            {
1744
0
                bHasBorder = true;
1745
0
                break;
1746
0
            }
1747
0
        }
1748
1749
0
        if (!bHasBorder)
1750
0
        {
1751
0
            uno::Reference<drawing::XControlShape> xControl(mxShape, uno::UNO_QUERY);
1752
0
            if (xControl.is())
1753
0
            {
1754
0
                uno::Reference<beans::XPropertySet> xControlModel(xControl->getControl(), uno::UNO_QUERY);
1755
0
                if (xControlModel.is())
1756
0
                {
1757
0
                    uno::Reference<beans::XPropertySetInfo> xInfo(xControlModel->getPropertySetInfo());
1758
0
                    if (xInfo.is() && xInfo->hasPropertyByName(u"Border"_ustr))
1759
0
                    {
1760
0
                        uno::Reference<beans::XPropertyState> xPropState(xControlModel, uno::UNO_QUERY);
1761
0
                        if (xPropState.is())
1762
0
                        {
1763
0
                            uno::Any aDefault = xPropState->getPropertyDefault(u"Border"_ustr);
1764
0
                            uno::Reference<beans::XPropertySet> xShapePropSet(mxShape, uno::UNO_QUERY);
1765
0
                            if (xShapePropSet.is())
1766
0
                                xShapePropSet->setPropertyValue(u"ControlBorder"_ustr, aDefault);
1767
0
                        }
1768
0
                    }
1769
0
                }
1770
0
            }
1771
0
        }
1772
0
    }
1773
1774
3.46k
    SetLayer();
1775
1776
    // set pos, size, shear and rotate
1777
3.46k
    SetTransformation();
1778
1779
3.46k
    SdXMLShapeContext::startFastElement(nElement, xAttrList);
1780
3.46k
}
1781
1782
1783
SdXMLConnectorShapeContext::SdXMLConnectorShapeContext(
1784
    SvXMLImport& rImport,
1785
    const css::uno::Reference< css::xml::sax::XFastAttributeList>& xAttrList,
1786
    uno::Reference< drawing::XShapes > const & rShapes,
1787
    bool bTemporaryShape)
1788
0
:   SdXMLShapeContext( rImport, xAttrList, rShapes, bTemporaryShape ),
1789
0
    maStart(0,0),
1790
0
    maEnd(1,1),
1791
0
    mnType( drawing::ConnectorType_STANDARD ),
1792
0
    mnStartGlueId(-1),
1793
0
    mnEndGlueId(-1),
1794
0
    mnDelta1(0),
1795
0
    mnDelta2(0),
1796
0
    mnDelta3(0),
1797
0
    mbLikelyOOXMLCurve(true)
1798
0
{
1799
0
}
1800
1801
SdXMLConnectorShapeContext::~SdXMLConnectorShapeContext()
1802
0
{
1803
0
}
1804
1805
bool SvXMLImport::needFixPositionAfterZ() const
1806
17.3k
{
1807
17.3k
    bool bWrongPositionAfterZ( false );
1808
17.3k
    sal_Int32 nUPD( 0 );
1809
17.3k
    sal_Int32 nBuildId( 0 );
1810
17.3k
    if ( getBuildIds( nUPD, nBuildId ) && // test OOo and old versions of LibO and AOO
1811
28
       ( ( ( nUPD == 641 ) || ( nUPD == 645 ) || ( nUPD == 680 ) || ( nUPD == 300 ) ||
1812
28
           ( nUPD == 310 ) || ( nUPD == 320 ) || ( nUPD == 330 ) || ( nUPD == 340 ) ||
1813
0
           ( nUPD == 350 && nBuildId < 202 ) )
1814
0
       || (getGeneratorVersion() == SvXMLImport::AOO_40x))) // test if AOO 4.0.x
1815
           // apparently bug was fixed in AOO by i#123433 f15874d8f976f3874bdbcb53429eeefa65c28841
1816
28
    {
1817
28
        bWrongPositionAfterZ = true;
1818
28
    }
1819
17.3k
    return bWrongPositionAfterZ;
1820
17.3k
}
1821
1822
namespace
1823
{
1824
bool lcl_IsLikelyOOXMLCurve(const basegfx::B2DPolygon& rPolygon)
1825
0
{
1826
0
    sal_uInt32 nCount = rPolygon.count();
1827
0
    if (!rPolygon.areControlPointsUsed() or nCount < 2)
1828
0
        return false; // no curve at all
1829
1830
0
    basegfx::B2DVector aStartVec(rPolygon.getNextControlPoint(0) - rPolygon.getB2DPoint(0));
1831
0
    basegfx::B2DVector aEndVec(rPolygon.getPrevControlPoint(nCount-1) - rPolygon.getB2DPoint(nCount - 1));
1832
    // LibreOffice uses one point less than OOXML for the same underlying bentConnector or
1833
    // STANDARD connector, respectively. A deeper inspection is only needed in case of 2 resulting
1834
    // points. Those connector paths look like a quarter ellipse.
1835
0
    switch (nCount)
1836
0
    {
1837
0
        case 2:
1838
0
        {
1839
            // In case start and end direction are parallel, it cannot be OOXML because that case
1840
            // introduces a handle on the path and the curve has three points then.
1841
0
            if (basegfx::areParallel(aStartVec, aEndVec))
1842
0
                return false;
1843
            // OOXML sets the control point at 1/2, LibreOffice at 2/3 of width or height.
1844
            // A tolerance is used because +-1 deviations due to integer arithmetic in many places.
1845
0
            basegfx::B2DRange aRect(rPolygon.getB2DPoint(0), rPolygon.getB2DPoint(1));
1846
0
            if ((basegfx::fTools::equalZero(aStartVec.getX())
1847
0
                     && basegfx::fTools::equal(aStartVec.getLength() * 2.0, aRect.getHeight(), 2.0))
1848
0
                || (basegfx::fTools::equalZero(aStartVec.getY())
1849
0
                     && basegfx::fTools::equal(aStartVec.getLength() * 2.0, aRect.getWidth(), 2.0)))
1850
0
                return true;
1851
0
        }
1852
0
        break;
1853
0
        case 3:
1854
0
        case 5:
1855
0
            return basegfx::areParallel(aStartVec, aEndVec);
1856
0
        break;
1857
0
        case 4: // start and end direction are orthogonal
1858
0
            return basegfx::fTools::equalZero(aStartVec.scalar( aEndVec));
1859
0
        break;
1860
0
        default:
1861
0
            return false;
1862
0
    }
1863
0
    return false;
1864
0
}
1865
} // end namespace
1866
1867
// this is called from the parent group for each unparsed attribute in the attribute list
1868
bool SdXMLConnectorShapeContext::processAttribute( const sax_fastparser::FastAttributeList::FastAttributeIter & aIter )
1869
0
{
1870
0
    switch( aIter.getToken() )
1871
0
    {
1872
0
        case XML_ELEMENT(DRAW, XML_START_SHAPE):
1873
0
            maStartShapeId = aIter.toString();
1874
0
            break;
1875
0
        case XML_ELEMENT(DRAW, XML_START_GLUE_POINT):
1876
0
            mnStartGlueId = aIter.toInt32();
1877
0
            break;
1878
0
        case XML_ELEMENT(DRAW, XML_END_SHAPE):
1879
0
            maEndShapeId = aIter.toString();
1880
0
            break;
1881
0
        case XML_ELEMENT(DRAW, XML_END_GLUE_POINT):
1882
0
            mnEndGlueId = aIter.toInt32();
1883
0
            break;
1884
0
        case XML_ELEMENT(DRAW, XML_LINE_SKEW):
1885
0
        {
1886
0
            OUString sValue = aIter.toString();
1887
0
            SvXMLTokenEnumerator aTokenEnum( sValue );
1888
0
            std::u16string_view aToken;
1889
0
            if( aTokenEnum.getNextToken( aToken ) )
1890
0
            {
1891
0
                GetImport().GetMM100UnitConverter().convertMeasureToCore(
1892
0
                        mnDelta1, aToken);
1893
0
                if( aTokenEnum.getNextToken( aToken ) )
1894
0
                {
1895
0
                    GetImport().GetMM100UnitConverter().convertMeasureToCore(
1896
0
                            mnDelta2, aToken);
1897
0
                    if( aTokenEnum.getNextToken( aToken ) )
1898
0
                    {
1899
0
                        GetImport().GetMM100UnitConverter().convertMeasureToCore(
1900
0
                                mnDelta3, aToken);
1901
0
                    }
1902
0
                }
1903
0
            }
1904
0
            break;
1905
0
        }
1906
0
        case XML_ELEMENT(DRAW, XML_TYPE):
1907
0
        {
1908
0
            (void)SvXMLUnitConverter::convertEnum( mnType, aIter.toView(), aXML_ConnectionKind_EnumMap );
1909
0
            break;
1910
0
        }
1911
        // #121965# draw:transform may be used in ODF1.2, e.g. exports from MS seem to use these
1912
0
        case XML_ELEMENT(DRAW, XML_TRANSFORM):
1913
0
            mnTransform.SetString(aIter.toString(), GetImport().GetMM100UnitConverter());
1914
0
            break;
1915
1916
0
        case XML_ELEMENT(SVG, XML_X1):
1917
0
        case XML_ELEMENT(SVG_COMPAT, XML_X1):
1918
0
            GetImport().GetMM100UnitConverter().convertMeasureToCore(
1919
0
                    maStart.X, aIter.toView());
1920
0
            break;
1921
0
        case XML_ELEMENT(SVG, XML_Y1):
1922
0
        case XML_ELEMENT(SVG_COMPAT, XML_Y1):
1923
0
            GetImport().GetMM100UnitConverter().convertMeasureToCore(
1924
0
                    maStart.Y, aIter.toView());
1925
0
            break;
1926
0
        case XML_ELEMENT(SVG, XML_X2):
1927
0
        case XML_ELEMENT(SVG_COMPAT, XML_X2):
1928
0
            GetImport().GetMM100UnitConverter().convertMeasureToCore(
1929
0
                    maEnd.X, aIter.toView());
1930
0
            break;
1931
0
        case XML_ELEMENT(SVG, XML_Y2):
1932
0
        case XML_ELEMENT(SVG_COMPAT, XML_Y2):
1933
0
            GetImport().GetMM100UnitConverter().convertMeasureToCore(
1934
0
                    maEnd.Y, aIter.toView());
1935
0
            break;
1936
0
        case XML_ELEMENT(SVG, XML_D):
1937
0
        case XML_ELEMENT(SVG_COMPAT, XML_D):
1938
0
        {
1939
0
            basegfx::B2DPolyPolygon aPolyPolygon;
1940
1941
0
            if(basegfx::utils::importFromSvgD(aPolyPolygon, aIter.toString(), GetImport().needFixPositionAfterZ(), nullptr))
1942
0
            {
1943
0
                if(aPolyPolygon.count())
1944
0
                {
1945
0
                    drawing::PolyPolygonBezierCoords aSourcePolyPolygon;
1946
1947
0
                    basegfx::utils::B2DPolyPolygonToUnoPolyPolygonBezierCoords(
1948
0
                        aPolyPolygon,
1949
0
                        aSourcePolyPolygon);
1950
0
                    maPath <<= aSourcePolyPolygon;
1951
1952
0
                    mbLikelyOOXMLCurve = lcl_IsLikelyOOXMLCurve(aPolyPolygon.getB2DPolygon(0));
1953
0
                }
1954
0
            }
1955
0
            break;
1956
0
        }
1957
0
        default:
1958
0
            return SdXMLShapeContext::processAttribute( aIter );
1959
0
    }
1960
0
    return true;
1961
0
}
1962
1963
void SdXMLConnectorShapeContext::startFastElement (sal_Int32 nElement,
1964
    const css::uno::Reference< css::xml::sax::XFastAttributeList >& xAttrList)
1965
0
{
1966
    // For security reasons, do not add empty connectors. There may have been an error in EA2
1967
    // that created empty, far set off connectors (e.g. 63 meters below top of document). This
1968
    // is not guaranteed, but it's definitely safe to not add empty connectors.
1969
0
    bool bDoAdd(true);
1970
1971
0
    if(    maStartShapeId.isEmpty()
1972
0
        && maEndShapeId.isEmpty()
1973
0
        && maStart.X == maEnd.X
1974
0
        && maStart.Y == maEnd.Y
1975
0
        && 0 == mnDelta1
1976
0
        && 0 == mnDelta2
1977
0
        && 0 == mnDelta3
1978
0
        )
1979
0
    {
1980
0
        bDoAdd = false;
1981
0
    }
1982
1983
0
    if(!bDoAdd)
1984
0
        return;
1985
1986
    // create Connector shape
1987
    // add, set style and properties from base shape
1988
0
    AddShape(u"com.sun.star.drawing.ConnectorShape"_ustr);
1989
0
    if(!mxShape.is())
1990
0
        return;
1991
1992
    // #121965# if draw:transform is used, apply directly to the start
1993
    // and end positions before using these
1994
0
    if(mnTransform.NeedsAction())
1995
0
    {
1996
        // transformation is used, apply to object.
1997
0
        ::basegfx::B2DHomMatrix aMat;
1998
0
        mnTransform.GetFullTransform(aMat);
1999
2000
0
        if(!aMat.isIdentity())
2001
0
        {
2002
0
            basegfx::B2DPoint aStart(maStart.X, maStart.Y);
2003
0
            basegfx::B2DPoint aEnd(maEnd.X, maEnd.Y);
2004
2005
0
            aStart = aMat * aStart;
2006
0
            aEnd = aMat * aEnd;
2007
2008
0
            maStart.X = basegfx::fround(aStart.getX());
2009
0
            maStart.Y = basegfx::fround(aStart.getY());
2010
0
            maEnd.X = basegfx::fround(aEnd.getX());
2011
0
            maEnd.Y = basegfx::fround(aEnd.getY());
2012
0
        }
2013
0
    }
2014
2015
0
    uno::Reference< beans::XPropertySet > xProps( mxShape, uno::UNO_QUERY );
2016
0
    if (xProps.is())
2017
0
        xProps->setPropertyValue(u"EdgeOOXMLCurve"_ustr, Any(mbLikelyOOXMLCurve));
2018
2019
    // add connection ids
2020
0
    if( !maStartShapeId.isEmpty() )
2021
0
        GetImport().GetShapeImport()->addShapeConnection( mxShape, true, maStartShapeId, mnStartGlueId );
2022
0
    if( !maEndShapeId.isEmpty() )
2023
0
        GetImport().GetShapeImport()->addShapeConnection( mxShape, false, maEndShapeId, mnEndGlueId );
2024
2025
0
    if( xProps.is() )
2026
0
    {
2027
0
        xProps->setPropertyValue(u"StartPosition"_ustr, Any(maStart));
2028
0
        xProps->setPropertyValue(u"EndPosition"_ustr, Any(maEnd) );
2029
0
        xProps->setPropertyValue(u"EdgeKind"_ustr, Any(mnType) );
2030
0
        xProps->setPropertyValue(u"EdgeLine1Delta"_ustr, Any(mnDelta1) );
2031
0
        xProps->setPropertyValue(u"EdgeLine2Delta"_ustr, Any(mnDelta2) );
2032
0
        xProps->setPropertyValue(u"EdgeLine3Delta"_ustr, Any(mnDelta3) );
2033
0
    }
2034
0
    SetStyle();
2035
0
    SetLayer();
2036
2037
0
    if ( maPath.hasValue() )
2038
0
    {
2039
        // #i115492#
2040
        // Ignore svg:d attribute for text documents created by OpenOffice.org
2041
        // versions before OOo 3.3, because these OOo versions are storing
2042
        // svg:d values not using the correct unit.
2043
0
        bool bApplySVGD( true );
2044
0
        if ( uno::Reference< text::XTextDocument >(GetImport().GetModel(), uno::UNO_QUERY).is() )
2045
0
        {
2046
0
            sal_Int32 nUPD( 0 );
2047
0
            sal_Int32 nBuild( 0 );
2048
0
            const bool bBuildIdFound = GetImport().getBuildIds( nUPD, nBuild );
2049
0
            if ( GetImport().IsTextDocInOOoFileFormat() ||
2050
0
                 ( bBuildIdFound &&
2051
0
                   ( ( nUPD == 641 ) || ( nUPD == 645 ) ||  // prior OOo 2.0
2052
0
                     ( nUPD == 680 ) ||                     // OOo 2.x
2053
0
                     ( nUPD == 300 ) ||                     // OOo 3.0 - OOo 3.0.1
2054
0
                     ( nUPD == 310 ) ||                     // OOo 3.1 - OOo 3.1.1
2055
0
                     ( nUPD == 320 ) ) ) )                  // OOo 3.2 - OOo 3.2.1
2056
0
            {
2057
0
                bApplySVGD = false;
2058
0
            }
2059
0
        }
2060
2061
0
        if ( bApplySVGD )
2062
0
        {
2063
            // tdf#83360 use path data only when redundant data of start and end point coordinates of
2064
            // path start/end and connector start/end is equal. This is to avoid using erroneous
2065
            // or inconsistent path data at import of foreign formats. Office itself always
2066
            // writes out a consistent data set. Not using it when there is inconsistency
2067
            // is okay since the path data is redundant, buffered data just to avoid recalculation
2068
            // of the connector's layout at load time, no real information would be lost.
2069
            // A 'connected' end has prio to direct coordinate data in Start/EndPosition
2070
            // to the path data (which should have the start/end redundant in the path)
2071
0
            const drawing::PolyPolygonBezierCoords* pSource = static_cast< const drawing::PolyPolygonBezierCoords* >(maPath.getValue());
2072
0
            const sal_uInt32 nSequenceCount(pSource->Coordinates.getLength());
2073
0
            bool bStartEqual(false);
2074
0
            bool bEndEqual(false);
2075
2076
0
            if(nSequenceCount)
2077
0
            {
2078
0
                const drawing::PointSequence& rStartSeq = pSource->Coordinates[0];
2079
0
                const sal_uInt32 nStartCount = rStartSeq.getLength();
2080
2081
0
                if(nStartCount)
2082
0
                {
2083
0
                    const awt::Point& rStartPoint = rStartSeq.getConstArray()[0];
2084
2085
0
                    if(rStartPoint.X == maStart.X && rStartPoint.Y == maStart.Y)
2086
0
                    {
2087
0
                        bStartEqual = true;
2088
0
                    }
2089
0
                }
2090
2091
0
                const drawing::PointSequence& rEndSeq = pSource->Coordinates[nSequenceCount - 1];
2092
0
                const sal_uInt32 nEndCount = rEndSeq.getLength();
2093
2094
0
                if(nEndCount)
2095
0
                {
2096
0
                    const awt::Point& rEndPoint = rEndSeq.getConstArray()[nEndCount - 1];
2097
2098
0
                    if(rEndPoint.X == maEnd.X && rEndPoint.Y == maEnd.Y)
2099
0
                    {
2100
0
                        bEndEqual = true;
2101
0
                    }
2102
0
                }
2103
0
            }
2104
2105
0
            if(!bStartEqual || !bEndEqual)
2106
0
            {
2107
0
                bApplySVGD = false;
2108
0
            }
2109
0
        }
2110
2111
0
        if ( bApplySVGD )
2112
0
        {
2113
0
            assert(maPath.getValueType() == cppu::UnoType<drawing::PolyPolygonBezierCoords>::get());
2114
0
            xProps->setPropertyValue(u"PolyPolygonBezier"_ustr, maPath);
2115
0
        }
2116
0
    }
2117
2118
0
    SdXMLShapeContext::startFastElement(nElement, xAttrList);
2119
0
}
2120
2121
2122
SdXMLMeasureShapeContext::SdXMLMeasureShapeContext(
2123
    SvXMLImport& rImport,
2124
    const css::uno::Reference< css::xml::sax::XFastAttributeList>& xAttrList,
2125
    uno::Reference< drawing::XShapes > const & rShapes,
2126
    bool bTemporaryShape)
2127
0
:   SdXMLShapeContext( rImport, xAttrList, rShapes, bTemporaryShape ),
2128
0
    maStart(0,0),
2129
0
    maEnd(1,1)
2130
0
{
2131
0
}
2132
2133
SdXMLMeasureShapeContext::~SdXMLMeasureShapeContext()
2134
{
2135
}
2136
2137
// this is called from the parent group for each unparsed attribute in the attribute list
2138
bool SdXMLMeasureShapeContext::processAttribute( const sax_fastparser::FastAttributeList::FastAttributeIter & aIter )
2139
0
{
2140
0
    switch( aIter.getToken() )
2141
0
    {
2142
0
        case XML_ELEMENT(SVG, XML_X1):
2143
0
        case XML_ELEMENT(SVG_COMPAT, XML_X1):
2144
0
        {
2145
0
            GetImport().GetMM100UnitConverter().convertMeasureToCore(
2146
0
                    maStart.X, aIter.toView());
2147
0
            break;
2148
0
        }
2149
0
        case XML_ELEMENT(SVG, XML_Y1):
2150
0
        case XML_ELEMENT(SVG_COMPAT, XML_Y1):
2151
0
        {
2152
0
            GetImport().GetMM100UnitConverter().convertMeasureToCore(
2153
0
                    maStart.Y, aIter.toView());
2154
0
            break;
2155
0
        }
2156
0
        case XML_ELEMENT(SVG, XML_X2):
2157
0
        case XML_ELEMENT(SVG_COMPAT, XML_X2):
2158
0
        {
2159
0
            GetImport().GetMM100UnitConverter().convertMeasureToCore(
2160
0
                    maEnd.X, aIter.toView());
2161
0
            break;
2162
0
        }
2163
0
        case XML_ELEMENT(SVG, XML_Y2):
2164
0
        case XML_ELEMENT(SVG_COMPAT, XML_Y2):
2165
0
        {
2166
0
            GetImport().GetMM100UnitConverter().convertMeasureToCore(
2167
0
                    maEnd.Y, aIter.toView());
2168
0
            break;
2169
0
        }
2170
0
        default:
2171
0
            return SdXMLShapeContext::processAttribute( aIter );
2172
0
    }
2173
0
    return true;
2174
0
}
2175
2176
void SdXMLMeasureShapeContext::startFastElement (sal_Int32 nElement,
2177
    const css::uno::Reference< css::xml::sax::XFastAttributeList >& xAttrList)
2178
0
{
2179
    // create Measure shape
2180
    // add, set style and properties from base shape
2181
0
    AddShape(u"com.sun.star.drawing.MeasureShape"_ustr);
2182
0
    if(!mxShape.is())
2183
0
        return;
2184
2185
0
    SetStyle();
2186
0
    SetLayer();
2187
2188
0
    uno::Reference< beans::XPropertySet > xProps( mxShape, uno::UNO_QUERY );
2189
0
    if( xProps.is() )
2190
0
    {
2191
0
        xProps->setPropertyValue(u"StartPosition"_ustr, Any(maStart));
2192
0
        xProps->setPropertyValue(u"EndPosition"_ustr, Any(maEnd) );
2193
0
    }
2194
2195
    // delete pre created fields
2196
0
    uno::Reference< text::XText > xText( mxShape, uno::UNO_QUERY );
2197
0
    if( xText.is() )
2198
0
    {
2199
0
        xText->setString( u" "_ustr );
2200
0
    }
2201
2202
0
    SdXMLShapeContext::startFastElement(nElement, xAttrList);
2203
0
}
2204
2205
void SdXMLMeasureShapeContext::endFastElement(sal_Int32 nElement)
2206
0
{
2207
0
    do
2208
0
    {
2209
        // delete pre created fields
2210
0
        uno::Reference< text::XText > xText( mxShape, uno::UNO_QUERY );
2211
0
        if( !xText.is() )
2212
0
            break;
2213
2214
0
        uno::Reference< text::XTextCursor > xCursor( xText->createTextCursor() );
2215
0
        if( !xCursor.is() )
2216
0
            break;
2217
2218
0
        xCursor->collapseToStart();
2219
0
        xCursor->goRight( 1, true );
2220
0
        xCursor->setString( u""_ustr );
2221
0
    }
2222
0
    while(false);
2223
2224
0
    SdXMLShapeContext::endFastElement(nElement);
2225
0
}
2226
2227
2228
SdXMLPageShapeContext::SdXMLPageShapeContext(
2229
    SvXMLImport& rImport,
2230
    const css::uno::Reference< css::xml::sax::XFastAttributeList>& xAttrList,
2231
    uno::Reference< drawing::XShapes > const & rShapes,
2232
    bool bTemporaryShape)
2233
2.25k
:   SdXMLShapeContext( rImport, xAttrList, rShapes, bTemporaryShape ), mnPageNumber(0)
2234
2.25k
{
2235
2.25k
    mbClearDefaultAttributes = false;
2236
2.25k
}
2237
2238
SdXMLPageShapeContext::~SdXMLPageShapeContext()
2239
{
2240
}
2241
2242
// this is called from the parent group for each unparsed attribute in the attribute list
2243
bool SdXMLPageShapeContext::processAttribute( const sax_fastparser::FastAttributeList::FastAttributeIter & aIter )
2244
7.49k
{
2245
7.49k
    if( aIter.getToken() == XML_ELEMENT(DRAW, XML_PAGE_NUMBER) )
2246
45
        mnPageNumber = aIter.toInt32();
2247
7.45k
    else
2248
7.45k
        return SdXMLShapeContext::processAttribute( aIter );
2249
45
    return true;
2250
7.49k
}
2251
2252
void SdXMLPageShapeContext::startFastElement (sal_Int32 nElement,
2253
    const css::uno::Reference< css::xml::sax::XFastAttributeList >& xAttrList)
2254
2.25k
{
2255
    // create Page shape
2256
    // add, set style and properties from base shape
2257
2258
    // #86163# take into account which type of PageShape needs to
2259
    // be constructed. It's a presentation shape if presentation:XML_CLASS == XML_PAGE.
2260
2.25k
    bool bIsPresentation = !maPresentationClass.isEmpty() &&
2261
152
           GetImport().GetShapeImport()->IsPresentationShapesSupported();
2262
2263
2.25k
    uno::Reference< lang::XServiceInfo > xInfo( mxShapes, uno::UNO_QUERY );
2264
2.25k
    const bool bIsOnHandoutPage = xInfo.is() && xInfo->supportsService(u"com.sun.star.presentation.HandoutMasterPage"_ustr);
2265
2266
2.25k
    if( bIsOnHandoutPage )
2267
1.43k
    {
2268
1.43k
        AddShape(u"com.sun.star.presentation.HandoutShape"_ustr);
2269
1.43k
    }
2270
826
    else
2271
826
    {
2272
826
        if(bIsPresentation && !IsXMLToken( maPresentationClass, XML_PAGE ) )
2273
1
        {
2274
1
            bIsPresentation = false;
2275
1
        }
2276
2277
826
        if(bIsPresentation)
2278
151
        {
2279
151
            AddShape(u"com.sun.star.presentation.PageShape"_ustr);
2280
151
        }
2281
675
        else
2282
675
        {
2283
675
            AddShape(u"com.sun.star.drawing.PageShape"_ustr);
2284
675
        }
2285
826
    }
2286
2287
2.25k
    if(!mxShape.is())
2288
0
        return;
2289
2290
2.25k
    SetStyle();
2291
2.25k
    SetLayer();
2292
2293
    // set pos, size, shear and rotate
2294
2.25k
    SetTransformation();
2295
2296
2.25k
    uno::Reference< beans::XPropertySet > xPropSet(mxShape, uno::UNO_QUERY);
2297
2.25k
    if (xPropSet.is() && mnPageNumber >= 0) // mnPageNumber < 0 means "ignore"
2298
2.21k
    {
2299
2.21k
        uno::Reference< beans::XPropertySetInfo > xPropSetInfo( xPropSet->getPropertySetInfo() );
2300
2.21k
        static constexpr OUString aPageNumberStr(u"PageNumber"_ustr);
2301
2.21k
        if( xPropSetInfo.is() && xPropSetInfo->hasPropertyByName(aPageNumberStr))
2302
2.21k
            xPropSet->setPropertyValue(aPageNumberStr, uno::Any( mnPageNumber ));
2303
2.21k
    }
2304
2305
    // For later resolution of page shape references, in case the target page does not
2306
    // exist during import. This will be resolved in SdXMLImport::endDocument()
2307
2.25k
    if (mnPageNumber > 0)
2308
7
    {
2309
7
        if (SdXMLImport* pSdImport = dynamic_cast<SdXMLImport*>(&GetImport()))
2310
7
            pSdImport->AddPageShapePageNum(mxShape, mnPageNumber);
2311
7
    }
2312
2313
2.25k
    SdXMLShapeContext::startFastElement(nElement, xAttrList);
2314
2.25k
}
2315
2316
2317
SdXMLCaptionShapeContext::SdXMLCaptionShapeContext(
2318
    SvXMLImport& rImport,
2319
    const css::uno::Reference< css::xml::sax::XFastAttributeList>& xAttrList,
2320
    uno::Reference< drawing::XShapes > const & rShapes,
2321
    bool bTemporaryShape)
2322
1
:   SdXMLShapeContext( rImport, xAttrList, rShapes, bTemporaryShape ),
2323
    // #86616# for correct edge rounding import mnRadius needs to be initialized
2324
1
    mnRadius( 0 )
2325
1
{
2326
1
}
2327
2328
SdXMLCaptionShapeContext::~SdXMLCaptionShapeContext()
2329
{
2330
}
2331
2332
void SdXMLCaptionShapeContext::startFastElement (sal_Int32 nElement,
2333
    const css::uno::Reference< css::xml::sax::XFastAttributeList >& xAttrList)
2334
1
{
2335
    // create Caption shape
2336
    // add, set style and properties from base shape
2337
1
    AddShape(u"com.sun.star.drawing.CaptionShape"_ustr);
2338
1
    if( !mxShape.is() )
2339
0
        return;
2340
2341
1
    SetStyle();
2342
1
    SetLayer();
2343
2344
1
    uno::Reference< beans::XPropertySet > xProps( mxShape, uno::UNO_QUERY );
2345
2346
    // SJ: If AutoGrowWidthItem is set, SetTransformation will lead to the wrong SnapRect
2347
    // because NbcAdjustTextFrameWidthAndHeight() is called (text is set later and center alignment
2348
    // is the default setting, so the top left reference point that is used by the caption point is
2349
    // no longer correct) There are two ways to solve this problem, temporarily disabling the
2350
    // autogrowwidth as we are doing here or to apply the CaptionPoint after setting text
2351
1
    bool bIsAutoGrowWidth = false;
2352
1
    if ( xProps.is() )
2353
1
    {
2354
1
        uno::Any aAny( xProps->getPropertyValue(u"TextAutoGrowWidth"_ustr) );
2355
1
        aAny >>= bIsAutoGrowWidth;
2356
2357
1
        if ( bIsAutoGrowWidth )
2358
0
            xProps->setPropertyValue(u"TextAutoGrowWidth"_ustr, uno::Any( false ) );
2359
1
    }
2360
2361
    // set pos, size, shear and rotate
2362
1
    SetTransformation();
2363
1
    if( xProps.is() )
2364
1
        xProps->setPropertyValue(u"CaptionPoint"_ustr, uno::Any( maCaptionPoint ) );
2365
2366
1
    if ( bIsAutoGrowWidth )
2367
0
        xProps->setPropertyValue(u"TextAutoGrowWidth"_ustr, uno::Any( true ) );
2368
2369
1
    if(mnRadius)
2370
0
    {
2371
0
        uno::Reference< beans::XPropertySet > xPropSet(mxShape, uno::UNO_QUERY);
2372
0
        if(xPropSet.is())
2373
0
        {
2374
0
            try
2375
0
            {
2376
0
                xPropSet->setPropertyValue(u"CornerRadius"_ustr, uno::Any( mnRadius ) );
2377
0
            }
2378
0
            catch(const uno::Exception&)
2379
0
            {
2380
0
                DBG_UNHANDLED_EXCEPTION( "xmloff", "setting corner radius");
2381
0
            }
2382
0
        }
2383
0
    }
2384
2385
1
    SdXMLShapeContext::startFastElement(nElement, xAttrList);
2386
1
}
2387
2388
// this is called from the parent group for each unparsed attribute in the attribute list
2389
bool SdXMLCaptionShapeContext::processAttribute( const sax_fastparser::FastAttributeList::FastAttributeIter & aIter )
2390
0
{
2391
0
    switch (aIter.getToken())
2392
0
    {
2393
0
        case XML_ELEMENT(DRAW, XML_CAPTION_POINT_X):
2394
0
            GetImport().GetMM100UnitConverter().convertMeasureToCore(
2395
0
                    maCaptionPoint.X, aIter.toView());
2396
0
            break;
2397
0
        case XML_ELEMENT(DRAW, XML_CAPTION_POINT_Y):
2398
0
            GetImport().GetMM100UnitConverter().convertMeasureToCore(
2399
0
                    maCaptionPoint.Y, aIter.toView());
2400
0
            break;
2401
0
        case XML_ELEMENT(DRAW, XML_CORNER_RADIUS):
2402
0
            GetImport().GetMM100UnitConverter().convertMeasureToCore(
2403
0
                    mnRadius, aIter.toView());
2404
0
            break;
2405
0
        default:
2406
0
            return SdXMLShapeContext::processAttribute( aIter );
2407
0
    }
2408
0
    return true;
2409
0
}
2410
2411
2412
SdXMLGraphicObjectShapeContext::SdXMLGraphicObjectShapeContext(
2413
    SvXMLImport& rImport, const css::uno::Reference<css::xml::sax::XFastAttributeList>& xAttrList,
2414
    uno::Reference<drawing::XShapes> const& rShapes)
2415
188
    : SdXMLShapeContext(rImport, xAttrList, rShapes, false /*bTemporaryShape*/)
2416
188
    , mnPage(-1)
2417
188
{
2418
188
}
2419
2420
// this is called from the parent group for each unparsed attribute in the attribute list
2421
bool SdXMLGraphicObjectShapeContext::processAttribute( const sax_fastparser::FastAttributeList::FastAttributeIter & aIter )
2422
1.19k
{
2423
1.19k
    switch (aIter.getToken())
2424
1.19k
    {
2425
35
    case XML_ELEMENT(XLINK, XML_HREF):
2426
35
        maURL = aIter.toString();
2427
35
        break;
2428
0
    case XML_ELEMENT(DRAW, XML_MIME_TYPE):
2429
0
    case XML_ELEMENT(LO_EXT, XML_MIME_TYPE):
2430
0
        msMimeType = aIter.toString();
2431
0
        break;
2432
0
    case XML_ELEMENT(LO_EXT, XML_PAGE_NUMBER):
2433
0
        mnPage = aIter.toInt32();
2434
0
        break;
2435
1.16k
    default:
2436
1.16k
        return SdXMLShapeContext::processAttribute(aIter);
2437
1.19k
    }
2438
35
    return true;
2439
1.19k
}
2440
2441
void SdXMLGraphicObjectShapeContext::startFastElement (sal_Int32 nElement,
2442
    const css::uno::Reference< css::xml::sax::XFastAttributeList >& xAttrList)
2443
188
{
2444
    // create graphic object shape
2445
188
    OUString service;
2446
2447
188
    if( IsXMLToken( maPresentationClass, XML_GRAPHIC ) && GetImport().GetShapeImport()->IsPresentationShapesSupported() )
2448
0
    {
2449
0
        service = "com.sun.star.presentation.GraphicObjectShape";
2450
0
    }
2451
188
    else
2452
188
    {
2453
188
        service = "com.sun.star.drawing.GraphicObjectShape";
2454
188
    }
2455
2456
188
    AddShape(service);
2457
2458
188
    if(!mxShape.is())
2459
0
        return;
2460
2461
188
    SetStyle();
2462
188
    SetLayer();
2463
2464
188
    uno::Reference< beans::XPropertySet > xPropset(mxShape, uno::UNO_QUERY);
2465
188
    if(xPropset.is())
2466
188
    {
2467
        // since OOo 1.x had no line or fill style for graphics, but may create
2468
        // documents with them, we have to override them here
2469
188
        sal_Int32 nUPD, nBuildId;
2470
188
        if( GetImport().getBuildIds( nUPD, nBuildId ) && (nUPD == 645) ) try
2471
0
        {
2472
0
            xPropset->setPropertyValue(u"FillStyle"_ustr, Any( FillStyle_NONE ) );
2473
0
            xPropset->setPropertyValue(u"LineStyle"_ustr, Any( LineStyle_NONE ) );
2474
0
        }
2475
0
        catch(const Exception&)
2476
0
        {
2477
0
        }
2478
2479
188
        uno::Reference< beans::XPropertySetInfo > xPropsInfo( xPropset->getPropertySetInfo() );
2480
188
        if( xPropsInfo.is() && xPropsInfo->hasPropertyByName(u"IsEmptyPresentationObject"_ustr))
2481
188
            xPropset->setPropertyValue(u"IsEmptyPresentationObject"_ustr, css::uno::Any( mbIsPlaceholder ) );
2482
2483
188
        if( !mbIsPlaceholder )
2484
188
        {
2485
188
            if( !maURL.isEmpty() )
2486
35
            {
2487
35
                uno::Reference<graphic::XGraphic> xGraphic
2488
35
                    = GetImport().loadGraphicByURL(maURL, mnPage);
2489
35
                if (xGraphic.is())
2490
35
                {
2491
35
                    xPropset->setPropertyValue(u"Graphic"_ustr, uno::Any(xGraphic));
2492
35
                }
2493
35
            }
2494
188
        }
2495
188
    }
2496
2497
188
    if(mbIsUserTransformed)
2498
0
    {
2499
0
        uno::Reference< beans::XPropertySet > xProps(mxShape, uno::UNO_QUERY);
2500
0
        if(xProps.is())
2501
0
        {
2502
0
            uno::Reference< beans::XPropertySetInfo > xPropsInfo( xProps->getPropertySetInfo() );
2503
0
            if( xPropsInfo.is() )
2504
0
            {
2505
0
                if( xPropsInfo->hasPropertyByName(u"IsPlaceholderDependent"_ustr))
2506
0
                    xProps->setPropertyValue(u"IsPlaceholderDependent"_ustr, css::uno::Any(false) );
2507
0
            }
2508
0
        }
2509
0
    }
2510
2511
    // set pos, size, shear and rotate
2512
188
    SetTransformation();
2513
2514
188
    SdXMLShapeContext::startFastElement(nElement, xAttrList);
2515
188
}
2516
2517
void SdXMLGraphicObjectShapeContext::endFastElement(sal_Int32 nElement)
2518
185
{
2519
185
    if (mxBase64Stream.is())
2520
0
    {
2521
0
        uno::Reference<graphic::XGraphic> xGraphic(GetImport().loadGraphicFromBase64(mxBase64Stream, mnPage));
2522
0
        if (xGraphic.is())
2523
0
        {
2524
0
            uno::Reference<beans::XPropertySet> xProperties(mxShape, uno::UNO_QUERY);
2525
0
            if (xProperties.is())
2526
0
            {
2527
0
                xProperties->setPropertyValue(u"Graphic"_ustr, uno::Any(xGraphic));
2528
0
            }
2529
0
        }
2530
0
    }
2531
2532
185
    SdXMLShapeContext::endFastElement(nElement);
2533
185
}
2534
2535
css::uno::Reference< css::xml::sax::XFastContextHandler > SdXMLGraphicObjectShapeContext::createFastChildContext(
2536
    sal_Int32 nElement,
2537
    const css::uno::Reference< css::xml::sax::XFastAttributeList >& xAttrList )
2538
11
{
2539
11
    css::uno::Reference< css::xml::sax::XFastContextHandler > xContext;
2540
2541
11
    if( nElement == XML_ELEMENT(OFFICE, XML_BINARY_DATA) )
2542
0
    {
2543
0
        if( maURL.isEmpty() && !mxBase64Stream.is() )
2544
0
        {
2545
0
            mxBase64Stream = GetImport().GetStreamForGraphicObjectURLFromBase64();
2546
0
            if( mxBase64Stream.is() )
2547
0
                xContext = new XMLBase64ImportContext( GetImport(),
2548
0
                                                    mxBase64Stream );
2549
0
        }
2550
0
    }
2551
2552
    // delegate to parent class if no context could be created
2553
11
    if (!xContext)
2554
11
        xContext = SdXMLShapeContext::createFastChildContext(nElement,
2555
11
                                                         xAttrList);
2556
2557
11
    if (!xContext)
2558
11
        XMLOFF_WARN_UNKNOWN_ELEMENT("xmloff", nElement);
2559
2560
11
    return xContext;
2561
11
}
2562
2563
SdXMLGraphicObjectShapeContext::~SdXMLGraphicObjectShapeContext()
2564
188
{
2565
2566
188
}
2567
2568
2569
SdXMLChartShapeContext::SdXMLChartShapeContext(
2570
    SvXMLImport& rImport,
2571
    const css::uno::Reference< css::xml::sax::XFastAttributeList>& xAttrList,
2572
    uno::Reference< drawing::XShapes > const & rShapes,
2573
    bool bTemporaryShape)
2574
0
:   SdXMLShapeContext( rImport, xAttrList, rShapes, bTemporaryShape )
2575
0
{
2576
0
}
2577
2578
void SdXMLChartShapeContext::startFastElement (sal_Int32 nElement,
2579
    const css::uno::Reference< css::xml::sax::XFastAttributeList >& xAttrList)
2580
0
{
2581
0
    const bool bIsPresentation = isPresentationShape();
2582
2583
0
    AddShape(
2584
0
        bIsPresentation
2585
0
        ? u"com.sun.star.presentation.ChartShape"_ustr
2586
0
        : u"com.sun.star.drawing.OLE2Shape"_ustr);
2587
2588
0
    if(!mxShape.is())
2589
0
        return;
2590
2591
0
    SetStyle();
2592
0
    SetLayer();
2593
2594
0
    if( !mbIsPlaceholder )
2595
0
    {
2596
0
        uno::Reference< beans::XPropertySet > xProps(mxShape, uno::UNO_QUERY);
2597
0
        if(xProps.is())
2598
0
        {
2599
0
            uno::Reference< beans::XPropertySetInfo > xPropsInfo( xProps->getPropertySetInfo() );
2600
0
            if( xPropsInfo.is() && xPropsInfo->hasPropertyByName(u"IsEmptyPresentationObject"_ustr))
2601
0
                xProps->setPropertyValue(u"IsEmptyPresentationObject"_ustr, css::uno::Any(false) );
2602
2603
0
            uno::Any aAny;
2604
2605
0
            xProps->setPropertyValue(u"CLSID"_ustr, Any(u"12DCAE26-281F-416F-a234-c3086127382e"_ustr) );
2606
2607
0
            aAny = xProps->getPropertyValue(u"Model"_ustr);
2608
0
            uno::Reference< frame::XModel > xChartModel;
2609
0
            if( aAny >>= xChartModel )
2610
0
            {
2611
0
#if !ENABLE_WASM_STRIP_CHART
2612
                // WASM_CHART change
2613
                // TODO: Maybe use SdXMLGraphicObjectShapeContext completely instead
2614
                // or try to create as mbIsPlaceholder object adding a Chart visualization
2615
                // that should be available somehow
2616
0
                mxChartContext.set( GetImport().GetChartImport()->CreateChartContext( GetImport(), xChartModel ) );
2617
0
#endif
2618
0
            }
2619
0
        }
2620
0
    }
2621
2622
0
    if(mbIsUserTransformed)
2623
0
    {
2624
0
        uno::Reference< beans::XPropertySet > xProps(mxShape, uno::UNO_QUERY);
2625
0
        if(xProps.is())
2626
0
        {
2627
0
            uno::Reference< beans::XPropertySetInfo > xPropsInfo( xProps->getPropertySetInfo() );
2628
0
            if( xPropsInfo.is() )
2629
0
            {
2630
0
                if( xPropsInfo->hasPropertyByName(u"IsPlaceholderDependent"_ustr))
2631
0
                    xProps->setPropertyValue(u"IsPlaceholderDependent"_ustr, css::uno::Any(false) );
2632
0
            }
2633
0
        }
2634
0
    }
2635
2636
    // set pos, size, shear and rotate
2637
0
    SetTransformation();
2638
2639
0
    SdXMLShapeContext::startFastElement(nElement, xAttrList);
2640
2641
0
    if( mxChartContext.is() )
2642
0
        mxChartContext->startFastElement( nElement, xAttrList );
2643
0
}
2644
2645
void SdXMLChartShapeContext::endFastElement(sal_Int32 nElement)
2646
0
{
2647
0
    if( mxChartContext.is() )
2648
0
        mxChartContext->endFastElement(nElement);
2649
2650
0
    SdXMLShapeContext::endFastElement(nElement);
2651
0
}
2652
2653
void SdXMLChartShapeContext::characters( const OUString& rChars )
2654
0
{
2655
0
    if( mxChartContext.is() )
2656
0
        mxChartContext->characters( rChars );
2657
0
}
2658
2659
css::uno::Reference< css::xml::sax::XFastContextHandler > SdXMLChartShapeContext::createFastChildContext(
2660
    sal_Int32 nElement,
2661
    const css::uno::Reference< css::xml::sax::XFastAttributeList >& xAttrList )
2662
0
{
2663
0
    if( mxChartContext.is() )
2664
0
        return mxChartContext->createFastChildContext( nElement, xAttrList );
2665
2666
0
    return nullptr;
2667
0
}
2668
2669
2670
SdXMLObjectShapeContext::SdXMLObjectShapeContext( SvXMLImport& rImport,
2671
        const css::uno::Reference< css::xml::sax::XFastAttributeList>& xAttrList,
2672
        css::uno::Reference< css::drawing::XShapes > const & rShapes)
2673
16
: SdXMLShapeContext( rImport, xAttrList, rShapes, false/*bTemporaryShape*/ )
2674
16
{
2675
16
}
2676
2677
SdXMLObjectShapeContext::~SdXMLObjectShapeContext()
2678
16
{
2679
16
}
2680
2681
void SdXMLObjectShapeContext::startFastElement (sal_Int32 /*nElement*/,
2682
    const css::uno::Reference< css::xml::sax::XFastAttributeList >& /*xAttrList*/)
2683
16
{
2684
    // #96717# in theorie, if we don't have a URL we shouldn't even
2685
    // export this OLE shape. But practically it's too risky right now
2686
    // to change this so we better dispose this on load
2687
    //if( !mbIsPlaceholder && ImpIsEmptyURL(maHref) )
2688
    //  return;
2689
2690
    // #100592# this BugFix prevents that a shape is created. CL
2691
    // is thinking about an alternative.
2692
    // #i13140# Check for more than empty string in maHref, there are
2693
    // other possibilities that maHref results in empty container
2694
    // storage names
2695
16
    if( !(GetImport().getImportFlags() & SvXMLImportFlags::EMBEDDED) && !mbIsPlaceholder && ImpIsEmptyURL(maHref) )
2696
0
        return;
2697
2698
16
    OUString service(u"com.sun.star.drawing.OLE2Shape"_ustr);
2699
2700
16
    bool bIsPresShape = !maPresentationClass.isEmpty() && GetImport().GetShapeImport()->IsPresentationShapesSupported();
2701
2702
16
    if( bIsPresShape )
2703
0
    {
2704
0
        if( IsXMLToken( maPresentationClass, XML_CHART ) )
2705
0
        {
2706
0
            service = "com.sun.star.presentation.ChartShape";
2707
0
        }
2708
0
        else if( IsXMLToken( maPresentationClass, XML_TABLE ) )
2709
0
        {
2710
0
            service = "com.sun.star.presentation.CalcShape";
2711
0
        }
2712
0
        else if( IsXMLToken( maPresentationClass, XML_OBJECT ) )
2713
0
        {
2714
0
            service = "com.sun.star.presentation.OLE2Shape";
2715
0
        }
2716
0
    }
2717
2718
16
    AddShape(service);
2719
2720
16
    if( !mxShape.is() )
2721
0
        return;
2722
2723
16
    SetLayer();
2724
2725
16
    if(bIsPresShape)
2726
0
    {
2727
0
        uno::Reference< beans::XPropertySet > xProps(mxShape, uno::UNO_QUERY);
2728
0
        if(xProps.is())
2729
0
        {
2730
0
            uno::Reference< beans::XPropertySetInfo > xPropsInfo( xProps->getPropertySetInfo() );
2731
0
            if( xPropsInfo.is() )
2732
0
            {
2733
0
                if( !mbIsPlaceholder && xPropsInfo->hasPropertyByName(u"IsEmptyPresentationObject"_ustr))
2734
0
                    xProps->setPropertyValue(u"IsEmptyPresentationObject"_ustr, css::uno::Any(false) );
2735
2736
0
                if( mbIsUserTransformed && xPropsInfo->hasPropertyByName(u"IsPlaceholderDependent"_ustr))
2737
0
                    xProps->setPropertyValue(u"IsPlaceholderDependent"_ustr, css::uno::Any(false) );
2738
0
            }
2739
0
        }
2740
0
    }
2741
2742
16
    if( !mbIsPlaceholder && !maHref.isEmpty() )
2743
0
    {
2744
0
        uno::Reference< beans::XPropertySet > xProps( mxShape, uno::UNO_QUERY );
2745
2746
0
        if( xProps.is() )
2747
0
        {
2748
0
            OUString aPersistName = GetImport().ResolveEmbeddedObjectURL( maHref, maCLSID );
2749
2750
0
            if ( GetImport().IsPackageURL( maHref ) )
2751
0
            {
2752
0
                static constexpr OUString  sURL( u"vnd.sun.star.EmbeddedObject:"_ustr );
2753
2754
0
                if ( aPersistName.startsWith( sURL ) )
2755
0
                    aPersistName = aPersistName.copy( sURL.getLength() );
2756
2757
0
                xProps->setPropertyValue(u"PersistName"_ustr,
2758
0
                                          uno::Any( aPersistName ) );
2759
0
            }
2760
0
            else
2761
0
            {
2762
                // this is OOo link object
2763
0
                xProps->setPropertyValue(u"LinkURL"_ustr,
2764
0
                                          uno::Any( aPersistName ) );
2765
0
            }
2766
0
        }
2767
0
    }
2768
2769
    // set pos, size, shear and rotate
2770
16
    SetTransformation();
2771
2772
16
    SetStyle();
2773
2774
16
    GetImport().GetShapeImport()->finishShape( mxShape, mxAttrList, mxShapes );
2775
16
}
2776
2777
void SdXMLObjectShapeContext::endFastElement(sal_Int32 nElement)
2778
0
{
2779
0
    if (GetImport().isGeneratorVersionOlderThan(
2780
0
                SvXMLImport::OOo_34x, SvXMLImport::LO_41x)) // < LO 4.0
2781
0
    {
2782
        // #i118485#
2783
        // If it's an old file from us written before OOo3.4, we need to correct
2784
        // FillStyle and LineStyle for OLE2 objects. The error was that the old paint
2785
        // implementations just ignored added fill/linestyles completely, thus
2786
        // those objects need to be corrected to not show blue and hairline which
2787
        // always was the default, but would be shown now
2788
0
        uno::Reference< beans::XPropertySet > xProps(mxShape, uno::UNO_QUERY);
2789
2790
0
        if( xProps.is() )
2791
0
        {
2792
0
            xProps->setPropertyValue(u"FillStyle"_ustr, uno::Any(drawing::FillStyle_NONE));
2793
0
            xProps->setPropertyValue(u"LineStyle"_ustr, uno::Any(drawing::LineStyle_NONE));
2794
0
        }
2795
0
    }
2796
2797
0
    if( mxBase64Stream.is() )
2798
0
    {
2799
0
        OUString aPersistName( GetImport().ResolveEmbeddedObjectURLFromBase64() );
2800
0
        static constexpr OUStringLiteral  sURL( u"vnd.sun.star.EmbeddedObject:" );
2801
2802
0
        aPersistName = aPersistName.copy( sURL.getLength() );
2803
2804
0
        uno::Reference< beans::XPropertySet > xProps(mxShape, uno::UNO_QUERY);
2805
0
        if( xProps.is() )
2806
0
            xProps->setPropertyValue(u"PersistName"_ustr, uno::Any( aPersistName ) );
2807
0
    }
2808
2809
0
    SdXMLShapeContext::endFastElement(nElement);
2810
0
}
2811
2812
// this is called from the parent group for each unparsed attribute in the attribute list
2813
bool SdXMLObjectShapeContext::processAttribute( const sax_fastparser::FastAttributeList::FastAttributeIter & aIter )
2814
121
{
2815
121
    switch( aIter.getToken() )
2816
121
    {
2817
0
        case XML_ELEMENT(DRAW, XML_CLASS_ID):
2818
0
            maCLSID = aIter.toString();
2819
0
            break;
2820
0
        case XML_ELEMENT(XLINK, XML_HREF):
2821
0
            maHref = aIter.toString();
2822
0
            break;
2823
121
        default:
2824
121
            return SdXMLShapeContext::processAttribute( aIter );
2825
121
    }
2826
0
    return true;
2827
121
}
2828
2829
css::uno::Reference< css::xml::sax::XFastContextHandler > SdXMLObjectShapeContext::createFastChildContext(
2830
    sal_Int32 nElement,
2831
    const css::uno::Reference< css::xml::sax::XFastAttributeList >& xAttrList )
2832
14
{
2833
14
    if(nElement == XML_ELEMENT(OFFICE, XML_BINARY_DATA))
2834
0
    {
2835
0
        mxBase64Stream = GetImport().GetStreamForEmbeddedObjectURLFromBase64();
2836
0
        if( mxBase64Stream.is() )
2837
0
            return new XMLBase64ImportContext( GetImport(), mxBase64Stream );
2838
0
    }
2839
14
    else if( nElement == XML_ELEMENT(OFFICE, XML_DOCUMENT) ||
2840
0
             nElement == XML_ELEMENT(MATH, XML_MATH) )
2841
14
    {
2842
14
        rtl::Reference<XMLEmbeddedObjectImportContext> xEContext(
2843
14
            new XMLEmbeddedObjectImportContext(GetImport(), nElement, xAttrList));
2844
14
        maCLSID = xEContext->GetFilterCLSID();
2845
14
        if( !maCLSID.isEmpty() )
2846
14
        {
2847
14
            uno::Reference< beans::XPropertySet > xPropSet(mxShape, uno::UNO_QUERY);
2848
14
            if( xPropSet.is() )
2849
14
            {
2850
14
                xPropSet->setPropertyValue(u"CLSID"_ustr, uno::Any( maCLSID ) );
2851
2852
                // A hack: getting the model of newly created OLE object will eventually call
2853
                // SdrOle2Obj::AddOwnLightClient, which will try to update scaling, using the
2854
                // incomplete object data. Avoid that by setting the special property.
2855
14
                xPropSet->setPropertyValue(u"IgnoreOLEObjectScale"_ustr, uno::Any(true));
2856
2857
14
                uno::Reference< lang::XComponent > xComp;
2858
14
                xPropSet->getPropertyValue(u"Model"_ustr) >>= xComp;
2859
2860
14
                xPropSet->setPropertyValue(u"IgnoreOLEObjectScale"_ustr, uno::Any(false));
2861
2862
14
                SAL_WARN_IF( !xComp.is(), "xmloff", "no xModel for own OLE format" );
2863
14
                xEContext->SetComponent(xComp);
2864
14
            }
2865
14
        }
2866
14
        return xEContext;
2867
14
    }
2868
2869
    // delegate to parent class if no context could be created
2870
0
    return SdXMLShapeContext::createFastChildContext(nElement, xAttrList);
2871
14
}
2872
2873
SdXMLAppletShapeContext::SdXMLAppletShapeContext( SvXMLImport& rImport,
2874
        const css::uno::Reference< css::xml::sax::XFastAttributeList>& xAttrList,
2875
        css::uno::Reference< css::drawing::XShapes > const & rShapes)
2876
0
: SdXMLShapeContext( rImport, xAttrList, rShapes, false/*bTemporaryShape*/ ),
2877
0
  mbIsScript( false )
2878
0
{
2879
0
}
2880
2881
SdXMLAppletShapeContext::~SdXMLAppletShapeContext()
2882
0
{
2883
0
}
2884
2885
void SdXMLAppletShapeContext::startFastElement (sal_Int32 /*nElement*/,
2886
    const css::uno::Reference< css::xml::sax::XFastAttributeList >& /*xAttrList*/)
2887
0
{
2888
0
    AddShape(u"com.sun.star.drawing.AppletShape"_ustr);
2889
2890
0
    if( mxShape.is() )
2891
0
    {
2892
0
        SetLayer();
2893
2894
        // set pos, size, shear and rotate
2895
0
        SetTransformation();
2896
0
        GetImport().GetShapeImport()->finishShape( mxShape, mxAttrList, mxShapes );
2897
0
    }
2898
0
}
2899
2900
// this is called from the parent group for each unparsed attribute in the attribute list
2901
bool SdXMLAppletShapeContext::processAttribute( const sax_fastparser::FastAttributeList::FastAttributeIter & aIter )
2902
0
{
2903
0
    switch( aIter.getToken() )
2904
0
    {
2905
0
        case XML_ELEMENT(DRAW, XML_APPLET_NAME):
2906
0
            maAppletName = aIter.toString();
2907
0
            break;
2908
0
        case XML_ELEMENT(DRAW, XML_CODE):
2909
0
            maAppletCode = aIter.toString();
2910
0
            break;
2911
0
        case XML_ELEMENT(DRAW, XML_MAY_SCRIPT):
2912
0
            mbIsScript = IsXMLToken( aIter, XML_TRUE );
2913
0
            break;
2914
0
        case XML_ELEMENT(XLINK, XML_HREF):
2915
0
            maHref = GetImport().GetAbsoluteReference(aIter.toString());
2916
0
            break;
2917
0
        default:
2918
0
            return SdXMLShapeContext::processAttribute( aIter );
2919
0
    }
2920
0
    return true;
2921
0
}
2922
2923
void SdXMLAppletShapeContext::endFastElement(sal_Int32 nElement)
2924
0
{
2925
0
    uno::Reference< beans::XPropertySet > xProps( mxShape, uno::UNO_QUERY );
2926
0
    if( xProps.is() )
2927
0
    {
2928
0
        if ( maSize.Width && maSize.Height )
2929
0
        {
2930
            // the visual area for applet must be set on loading
2931
0
            awt::Rectangle aRect( 0, 0, maSize.Width, maSize.Height );
2932
0
            xProps->setPropertyValue(u"VisibleArea"_ustr, Any(aRect) );
2933
0
        }
2934
2935
0
        if( maParams.hasElements() )
2936
0
        {
2937
0
            xProps->setPropertyValue(u"AppletCommands"_ustr, Any(maParams) );
2938
0
        }
2939
2940
0
        if( !maHref.isEmpty() )
2941
0
        {
2942
0
            xProps->setPropertyValue(u"AppletCodeBase"_ustr, Any(maHref) );
2943
0
        }
2944
2945
0
        if( !maAppletName.isEmpty() )
2946
0
        {
2947
0
            xProps->setPropertyValue(u"AppletName"_ustr, Any(maAppletName) );
2948
0
        }
2949
2950
0
        if( mbIsScript )
2951
0
        {
2952
0
            xProps->setPropertyValue(u"AppletIsScript"_ustr, Any(mbIsScript) );
2953
2954
0
        }
2955
2956
0
        if( !maAppletCode.isEmpty() )
2957
0
        {
2958
0
            xProps->setPropertyValue(u"AppletCode"_ustr, Any(maAppletCode) );
2959
0
        }
2960
2961
0
        xProps->setPropertyValue(u"AppletDocBase"_ustr, Any(GetImport().GetDocumentBase()) );
2962
2963
0
        SetThumbnail();
2964
0
    }
2965
2966
0
    SdXMLShapeContext::endFastElement(nElement);
2967
0
}
2968
2969
css::uno::Reference< css::xml::sax::XFastContextHandler > SdXMLAppletShapeContext::createFastChildContext(
2970
    sal_Int32 nElement,
2971
    const css::uno::Reference< css::xml::sax::XFastAttributeList >& xAttrList )
2972
0
{
2973
0
    if( nElement == XML_ELEMENT(DRAW, XML_PARAM) )
2974
0
    {
2975
0
        OUString aParamName, aParamValue;
2976
        // now parse the attribute list and look for draw:name and draw:value
2977
0
        for( auto& aIter : sax_fastparser::castToFastAttributeList(xAttrList) )
2978
0
        {
2979
0
            if( aIter.getToken() == XML_ELEMENT(DRAW, XML_NAME) )
2980
0
                aParamName = aIter.toString();
2981
0
            if( aIter.getToken() == XML_ELEMENT(DRAW, XML_VALUE) )
2982
0
                aParamValue = aIter.toString();
2983
0
        }
2984
2985
0
        if( !aParamName.isEmpty() )
2986
0
        {
2987
0
            sal_Int32 nIndex = maParams.getLength();
2988
0
            maParams.realloc( nIndex + 1 );
2989
0
            auto pParams = maParams.getArray();
2990
0
            pParams[nIndex].Name = aParamName;
2991
0
            pParams[nIndex].Handle = -1;
2992
0
            pParams[nIndex].Value <<= aParamValue;
2993
0
            pParams[nIndex].State = beans::PropertyState_DIRECT_VALUE;
2994
0
        }
2995
2996
0
        return new SvXMLImportContext( GetImport() );
2997
0
    }
2998
2999
0
    return SdXMLShapeContext::createFastChildContext( nElement, xAttrList );
3000
0
}
3001
3002
3003
SdXMLPluginShapeContext::SdXMLPluginShapeContext( SvXMLImport& rImport,
3004
        const css::uno::Reference< css::xml::sax::XFastAttributeList>& xAttrList,
3005
        css::uno::Reference< css::drawing::XShapes > const & rShapes) :
3006
0
SdXMLShapeContext( rImport, xAttrList, rShapes, false/*bTemporaryShape*/ ),
3007
0
mbMedia( false )
3008
0
{
3009
0
}
3010
3011
SdXMLPluginShapeContext::~SdXMLPluginShapeContext()
3012
0
{
3013
0
}
3014
3015
void SdXMLPluginShapeContext::startFastElement (sal_Int32 /*nElement*/,
3016
    const css::uno::Reference< css::xml::sax::XFastAttributeList >& xAttrList)
3017
0
{
3018
3019
    // watch for MimeType attribute to see if we have a media object
3020
0
    for( auto& aIter : sax_fastparser::castToFastAttributeList(xAttrList) )
3021
0
    {
3022
0
        if( aIter.getToken() == XML_ELEMENT(DRAW, XML_MIME_TYPE) )
3023
0
        {
3024
0
            if (::comphelper::IsMediaMimeType(aIter.toView()))
3025
0
                mbMedia = true;
3026
            // leave this loop
3027
0
            break;
3028
0
        }
3029
0
    }
3030
3031
0
    OUString service;
3032
3033
0
    bool bIsPresShape = false;
3034
3035
0
    if( mbMedia )
3036
0
    {
3037
0
        service = "com.sun.star.drawing.MediaShape";
3038
3039
0
        bIsPresShape = !maPresentationClass.isEmpty() && GetImport().GetShapeImport()->IsPresentationShapesSupported();
3040
0
        if( bIsPresShape )
3041
0
        {
3042
0
            if( IsXMLToken( maPresentationClass, XML_OBJECT ) )
3043
0
            {
3044
0
                service = "com.sun.star.presentation.MediaShape";
3045
0
            }
3046
0
        }
3047
0
    }
3048
0
    else
3049
0
        service = "com.sun.star.drawing.PluginShape";
3050
3051
0
    AddShape(service);
3052
3053
0
    if( !mxShape.is() )
3054
0
        return;
3055
3056
0
    if (mbMedia)
3057
0
    {
3058
        // The media may have a crop, apply it.
3059
0
        SetStyle(/*bSupportsStyle=*/false);
3060
0
    }
3061
3062
0
    SetLayer();
3063
3064
0
    if(bIsPresShape)
3065
0
    {
3066
0
        uno::Reference< beans::XPropertySet > xProps( mxShape, uno::UNO_QUERY );
3067
0
        if(xProps.is())
3068
0
        {
3069
0
            uno::Reference< beans::XPropertySetInfo > xPropsInfo( xProps->getPropertySetInfo() );
3070
0
            if( xPropsInfo.is() )
3071
0
            {
3072
0
                if( !mbIsPlaceholder && xPropsInfo->hasPropertyByName(u"IsEmptyPresentationObject"_ustr))
3073
0
                    xProps->setPropertyValue(u"IsEmptyPresentationObject"_ustr, css::uno::Any(false) );
3074
3075
0
                if( mbIsUserTransformed && xPropsInfo->hasPropertyByName(u"IsPlaceholderDependent"_ustr))
3076
0
                    xProps->setPropertyValue(u"IsPlaceholderDependent"_ustr, css::uno::Any(false) );
3077
0
            }
3078
0
        }
3079
0
    }
3080
3081
    // set pos, size, shear and rotate
3082
0
    SetTransformation();
3083
0
    GetImport().GetShapeImport()->finishShape( mxShape, mxAttrList, mxShapes );
3084
0
}
3085
3086
static OUString
3087
lcl_GetMediaReference(SvXMLImport const& rImport, OUString const& rURL)
3088
0
{
3089
0
    if (rImport.IsPackageURL(rURL))
3090
0
    {
3091
0
        return "vnd.sun.star.Package:" + rURL;
3092
0
    }
3093
0
    else
3094
0
    {
3095
0
        return rImport.GetAbsoluteReference(rURL);
3096
0
    }
3097
0
}
3098
3099
// this is called from the parent group for each unparsed attribute in the attribute list
3100
bool SdXMLPluginShapeContext::processAttribute( const sax_fastparser::FastAttributeList::FastAttributeIter & aIter )
3101
0
{
3102
0
    switch( aIter.getToken() )
3103
0
    {
3104
0
        case XML_ELEMENT(DRAW, XML_MIME_TYPE):
3105
0
            maMimeType = aIter.toString();
3106
0
            break;
3107
0
        case XML_ELEMENT(XLINK, XML_HREF):
3108
0
            maHref = lcl_GetMediaReference(GetImport(), aIter.toString());
3109
0
            break;
3110
0
        default:
3111
0
            return SdXMLShapeContext::processAttribute( aIter );
3112
0
    }
3113
0
    return true;
3114
0
}
3115
3116
void SdXMLPluginShapeContext::endFastElement(sal_Int32 nElement)
3117
0
{
3118
0
    uno::Reference< beans::XPropertySet > xProps( mxShape, uno::UNO_QUERY );
3119
3120
0
    if( xProps.is() )
3121
0
    {
3122
0
        if ( maSize.Width && maSize.Height )
3123
0
        {
3124
0
            static constexpr OUString sVisibleArea(  u"VisibleArea"_ustr  );
3125
0
            uno::Reference< beans::XPropertySetInfo > aXPropSetInfo( xProps->getPropertySetInfo() );
3126
0
            if ( !aXPropSetInfo.is() || aXPropSetInfo->hasPropertyByName( sVisibleArea ) )
3127
0
            {
3128
                // the visual area for a plugin must be set on loading
3129
0
                awt::Rectangle aRect( 0, 0, maSize.Width, maSize.Height );
3130
0
                xProps->setPropertyValue( sVisibleArea, Any(aRect) );
3131
0
            }
3132
0
        }
3133
3134
0
        if( !mbMedia )
3135
0
        {
3136
            // in case we have a plugin object
3137
0
            if( maParams.hasElements() )
3138
0
            {
3139
0
                xProps->setPropertyValue(u"PluginCommands"_ustr, Any(maParams) );
3140
0
            }
3141
3142
0
            if( !maMimeType.isEmpty() )
3143
0
            {
3144
0
                xProps->setPropertyValue(u"PluginMimeType"_ustr, Any(maMimeType) );
3145
0
            }
3146
3147
0
            if( !maHref.isEmpty() )
3148
0
            {
3149
0
                xProps->setPropertyValue(u"PluginURL"_ustr, Any(maHref) );
3150
0
            }
3151
0
        }
3152
0
        else
3153
0
        {
3154
            // in case we have a media object
3155
0
            xProps->setPropertyValue( u"MediaURL"_ustr, uno::Any(maHref));
3156
            // could be from old times when a format was unsupported
3157
            // likely already guessed a possibly more accurate MIME type from MediaURL, don't override
3158
0
            bool bUpdateMimeType = false;
3159
0
            if (maMimeType != AVMEDIA_MIMETYPE_COMMON)
3160
0
                bUpdateMimeType = true;
3161
0
            else
3162
0
            {
3163
0
                OUString aExistingMimeType;
3164
0
                xProps->getPropertyValue(u"MediaMimeType"_ustr) >>= aExistingMimeType;
3165
0
                if (aExistingMimeType.isEmpty())
3166
0
                    bUpdateMimeType = true;
3167
0
            }
3168
0
            if (bUpdateMimeType)
3169
0
                xProps->setPropertyValue(u"MediaMimeType"_ustr, uno::Any(maMimeType) );
3170
3171
0
            for (const auto& rParam : maParams)
3172
0
            {
3173
0
                const OUString& rName = rParam.Name;
3174
3175
0
                if( rName == "Loop" )
3176
0
                {
3177
0
                    OUString aValueStr;
3178
0
                    rParam.Value >>= aValueStr;
3179
0
                    xProps->setPropertyValue(u"Loop"_ustr,
3180
0
                        uno::Any( aValueStr == "true" ) );
3181
0
                }
3182
0
                else if( rName == "Mute" )
3183
0
                {
3184
0
                    OUString aValueStr;
3185
0
                    rParam.Value >>= aValueStr;
3186
0
                    xProps->setPropertyValue(u"Mute"_ustr,
3187
0
                        uno::Any( aValueStr == "true" ) );
3188
0
                }
3189
0
                else if( rName == "VolumeDB" )
3190
0
                {
3191
0
                    OUString aValueStr;
3192
0
                    rParam.Value >>= aValueStr;
3193
0
                    xProps->setPropertyValue(u"VolumeDB"_ustr,
3194
0
                                                uno::Any( static_cast< sal_Int16 >( aValueStr.toInt32() ) ) );
3195
0
                }
3196
0
                else if( rName == "Zoom" )
3197
0
                {
3198
0
                    OUString            aZoomStr;
3199
0
                    media::ZoomLevel    eZoomLevel;
3200
3201
0
                    rParam.Value >>= aZoomStr;
3202
3203
0
                    if( aZoomStr == "25%" )
3204
0
                        eZoomLevel = media::ZoomLevel_ZOOM_1_TO_4;
3205
0
                    else if( aZoomStr == "50%" )
3206
0
                        eZoomLevel = media::ZoomLevel_ZOOM_1_TO_2;
3207
0
                    else if( aZoomStr == "100%" )
3208
0
                        eZoomLevel = media::ZoomLevel_ORIGINAL;
3209
0
                    else if( aZoomStr == "200%" )
3210
0
                        eZoomLevel = media::ZoomLevel_ZOOM_2_TO_1;
3211
0
                    else if( aZoomStr == "400%" )
3212
0
                        eZoomLevel = media::ZoomLevel_ZOOM_4_TO_1;
3213
0
                    else if( aZoomStr == "fit" )
3214
0
                        eZoomLevel = media::ZoomLevel_FIT_TO_WINDOW;
3215
0
                    else if( aZoomStr == "fixedfit" )
3216
0
                        eZoomLevel = media::ZoomLevel_FIT_TO_WINDOW_FIXED_ASPECT;
3217
0
                    else if( aZoomStr == "fullscreen" )
3218
0
                        eZoomLevel = media::ZoomLevel_FULLSCREEN;
3219
0
                    else
3220
0
                        eZoomLevel = media::ZoomLevel_NOT_AVAILABLE;
3221
3222
0
                    xProps->setPropertyValue(u"Zoom"_ustr, uno::Any( eZoomLevel ) );
3223
0
                }
3224
0
            }
3225
0
        }
3226
3227
0
        SetThumbnail();
3228
0
    }
3229
3230
0
    SdXMLShapeContext::endFastElement(nElement);
3231
0
}
3232
3233
css::uno::Reference< css::xml::sax::XFastContextHandler > SdXMLPluginShapeContext::createFastChildContext(
3234
    sal_Int32 nElement,
3235
    const css::uno::Reference< css::xml::sax::XFastAttributeList >& xAttrList )
3236
0
{
3237
0
    if( nElement == XML_ELEMENT(DRAW, XML_PARAM) )
3238
0
    {
3239
0
        OUString aParamName, aParamValue;
3240
        // now parse the attribute list and look for draw:name and draw:value
3241
0
        for( auto& aIter : sax_fastparser::castToFastAttributeList(xAttrList) )
3242
0
        {
3243
0
            if( aIter.getToken() == XML_ELEMENT(DRAW, XML_NAME) )
3244
0
                aParamName = aIter.toString();
3245
0
            else if( aIter.getToken() == XML_ELEMENT(DRAW, XML_VALUE) )
3246
0
                aParamValue = aIter.toString();
3247
0
        }
3248
3249
0
        if( !aParamName.isEmpty() )
3250
0
        {
3251
0
            sal_Int32 nIndex = maParams.getLength();
3252
0
            maParams.realloc( nIndex + 1 );
3253
0
            auto pParams = maParams.getArray();
3254
0
            pParams[nIndex].Name = aParamName;
3255
0
            pParams[nIndex].Handle = -1;
3256
0
            pParams[nIndex].Value <<= aParamValue;
3257
0
            pParams[nIndex].State = beans::PropertyState_DIRECT_VALUE;
3258
0
        }
3259
3260
0
        return new SvXMLImportContext( GetImport() );
3261
0
    }
3262
3263
0
    return SdXMLShapeContext::createFastChildContext( nElement, xAttrList );
3264
0
}
3265
3266
3267
SdXMLFloatingFrameShapeContext::SdXMLFloatingFrameShapeContext( SvXMLImport& rImport,
3268
        const css::uno::Reference< css::xml::sax::XFastAttributeList>& xAttrList,
3269
        css::uno::Reference< css::drawing::XShapes > const & rShapes)
3270
0
: SdXMLShapeContext( rImport, xAttrList, rShapes, false/*bTemporaryShape*/ )
3271
0
{
3272
0
}
3273
3274
SdXMLFloatingFrameShapeContext::~SdXMLFloatingFrameShapeContext()
3275
0
{
3276
0
}
3277
3278
uno::Reference<drawing::XShape> SdXMLFloatingFrameShapeContext::CreateFloatingFrameShape() const
3279
0
{
3280
0
    uno::Reference<lang::XMultiServiceFactory> xServiceFact(GetImport().GetModel(), uno::UNO_QUERY);
3281
0
    if (!xServiceFact.is())
3282
0
        return nullptr;
3283
0
    uno::Reference<drawing::XShape> xShape(
3284
0
            xServiceFact->createInstance(u"com.sun.star.drawing.FrameShape"_ustr), uno::UNO_QUERY);
3285
0
    return xShape;
3286
0
}
3287
3288
void SdXMLFloatingFrameShapeContext::startFastElement (sal_Int32 /*nElement*/,
3289
    const css::uno::Reference< css::xml::sax::XFastAttributeList >& /*xAttrList*/)
3290
0
{
3291
0
    uno::Reference<drawing::XShape> xShape(SdXMLFloatingFrameShapeContext::CreateFloatingFrameShape());
3292
3293
0
    uno::Reference< beans::XPropertySet > xProps(xShape, uno::UNO_QUERY);
3294
    // set FrameURL before AddShape, we have to do it again later because it
3295
    // gets cleared when the SdrOle2Obj is attached to the XShape.  But we want
3296
    // FrameURL to exist when AddShape triggers SetPersistName which itself
3297
    // triggers SdrOle2Obj::CheckFileLink_Impl and at that point we want to
3298
    // know what URL will end up being used. So bodge this by setting FrameURL
3299
    // to the temp pre-SdrOle2Obj attached properties and we can smuggle it
3300
    // eventually into SdrOle2Obj::SetPersistName at the right point after
3301
    // PersistName is set but before SdrOle2Obj::CheckFileLink_Impl is called
3302
    // in order to inform the link manager that this is an IFrame that links to
3303
    // a URL
3304
0
    if (xProps && !maHref.isEmpty())
3305
0
        xProps->setPropertyValue(u"FrameURL"_ustr, Any(maHref));
3306
3307
0
    AddShape(xShape);
3308
3309
0
    if( !mxShape.is() )
3310
0
        return;
3311
3312
0
    SetLayer();
3313
3314
    // set pos, size, shear and rotate
3315
0
    SetTransformation();
3316
3317
0
    if( xProps.is() )
3318
0
    {
3319
0
        if( !maFrameName.isEmpty() )
3320
0
        {
3321
0
            xProps->setPropertyValue(u"FrameName"_ustr, Any(maFrameName) );
3322
0
        }
3323
3324
0
        if( !maHref.isEmpty() )
3325
0
        {
3326
0
            if (INetURLObject(maHref).IsExoticProtocol())
3327
0
                GetImport().NotifyMacroEventRead();
3328
3329
0
            xProps->setPropertyValue(u"FrameURL"_ustr, Any(maHref) );
3330
0
        }
3331
0
    }
3332
3333
0
    SetStyle();
3334
3335
0
    GetImport().GetShapeImport()->finishShape( mxShape, mxAttrList, mxShapes );
3336
0
}
3337
3338
// this is called from the parent group for each unparsed attribute in the attribute list
3339
bool SdXMLFloatingFrameShapeContext::processAttribute( const sax_fastparser::FastAttributeList::FastAttributeIter & aIter )
3340
0
{
3341
0
    switch( aIter.getToken() )
3342
0
    {
3343
0
        case XML_ELEMENT(DRAW, XML_FRAME_NAME):
3344
0
            maFrameName = aIter.toString();
3345
0
            break;
3346
0
        case XML_ELEMENT(XLINK, XML_HREF):
3347
0
            maHref = GetImport().GetAbsoluteReference(aIter.toString());
3348
0
            break;
3349
0
        default:
3350
0
            return SdXMLShapeContext::processAttribute( aIter );
3351
0
    }
3352
0
    return true;
3353
0
}
3354
3355
void SdXMLFloatingFrameShapeContext::endFastElement(sal_Int32 nElement)
3356
0
{
3357
0
    uno::Reference< beans::XPropertySet > xProps( mxShape, uno::UNO_QUERY );
3358
3359
0
    if( xProps.is() )
3360
0
    {
3361
0
        if ( maSize.Width && maSize.Height )
3362
0
        {
3363
            // the visual area for a floating frame must be set on loading
3364
0
            awt::Rectangle aRect( 0, 0, maSize.Width, maSize.Height );
3365
0
            xProps->setPropertyValue(u"VisibleArea"_ustr, Any(aRect) );
3366
0
        }
3367
0
    }
3368
3369
0
    SetThumbnail();
3370
0
    SdXMLShapeContext::endFastElement(nElement);
3371
0
}
3372
3373
3374
SdXMLFrameShapeContext::SdXMLFrameShapeContext( SvXMLImport& rImport,
3375
        const css::uno::Reference< css::xml::sax::XFastAttributeList>& xAttrList,
3376
        css::uno::Reference< css::drawing::XShapes > const & rShapes,
3377
        bool bTemporaryShape)
3378
7.88k
: SdXMLShapeContext( rImport, xAttrList, rShapes, bTemporaryShape ),
3379
7.88k
    mbSupportsReplacement( false )
3380
7.88k
{
3381
7.88k
    uno::Reference < util::XCloneable > xClone( xAttrList, uno::UNO_QUERY );
3382
7.88k
    if( xClone.is() )
3383
7.88k
        mxAttrList.set( xClone->createClone(), uno::UNO_QUERY );
3384
0
    else
3385
0
        mxAttrList = new sax_fastparser::FastAttributeList(xAttrList);
3386
7.88k
}
3387
3388
SdXMLFrameShapeContext::~SdXMLFrameShapeContext()
3389
7.88k
{
3390
7.88k
}
3391
3392
void SdXMLFrameShapeContext::removeGraphicFromImportContext(const SvXMLImportContext& rContext)
3393
0
{
3394
0
    const SdXMLGraphicObjectShapeContext* pSdXMLGraphicObjectShapeContext = dynamic_cast< const SdXMLGraphicObjectShapeContext* >(&rContext);
3395
3396
0
    if(!pSdXMLGraphicObjectShapeContext)
3397
0
        return;
3398
3399
0
    try
3400
0
    {
3401
0
        uno::Reference< container::XChild > xChild(pSdXMLGraphicObjectShapeContext->getShape(), uno::UNO_QUERY_THROW);
3402
3403
0
        uno::Reference< drawing::XShapes > xParent(xChild->getParent(), uno::UNO_QUERY_THROW);
3404
3405
        // remove from parent
3406
0
        xParent->remove(pSdXMLGraphicObjectShapeContext->getShape());
3407
3408
        // dispose
3409
0
        uno::Reference< lang::XComponent > xComp(pSdXMLGraphicObjectShapeContext->getShape(), UNO_QUERY);
3410
3411
0
        if(xComp.is())
3412
0
        {
3413
0
            xComp->dispose();
3414
0
        }
3415
0
    }
3416
0
    catch( uno::Exception& )
3417
0
    {
3418
0
        DBG_UNHANDLED_EXCEPTION( "xmloff", "Error in cleanup of multiple graphic object import." );
3419
0
    }
3420
0
}
3421
3422
namespace
3423
{
3424
uno::Reference<beans::XPropertySet> getGraphicPropertySetFromImportContext(const SvXMLImportContext& rContext)
3425
0
{
3426
0
    uno::Reference<beans::XPropertySet> aPropertySet;
3427
0
    const SdXMLGraphicObjectShapeContext* pSdXMLGraphicObjectShapeContext = dynamic_cast<const SdXMLGraphicObjectShapeContext*>(&rContext);
3428
3429
0
    if (pSdXMLGraphicObjectShapeContext)
3430
0
        aPropertySet.set(pSdXMLGraphicObjectShapeContext->getShape(), uno::UNO_QUERY);
3431
3432
0
    return aPropertySet;
3433
0
}
3434
3435
} // end anonymous namespace
3436
3437
uno::Reference<graphic::XGraphic> SdXMLFrameShapeContext::getGraphicFromImportContext(const SvXMLImportContext& rContext) const
3438
0
{
3439
0
    uno::Reference<graphic::XGraphic> xGraphic;
3440
0
    try
3441
0
    {
3442
0
        const uno::Reference<beans::XPropertySet> xPropertySet = getGraphicPropertySetFromImportContext(rContext);
3443
3444
0
        if (xPropertySet.is())
3445
0
        {
3446
0
            xPropertySet->getPropertyValue(u"Graphic"_ustr) >>= xGraphic;
3447
0
        }
3448
0
    }
3449
0
    catch( uno::Exception& )
3450
0
    {
3451
0
        DBG_UNHANDLED_EXCEPTION("xmloff", "Error in cleanup of multiple graphic object import.");
3452
0
    }
3453
3454
0
    return xGraphic;
3455
0
}
3456
3457
OUString SdXMLFrameShapeContext::getMimeTypeFromImportContext(const SvXMLImportContext& rContext) const
3458
0
{
3459
0
    OUString aMimeType;
3460
0
    const SdXMLGraphicObjectShapeContext* pSdXMLGraphicObjectShapeContext = dynamic_cast<const SdXMLGraphicObjectShapeContext*>(&rContext);
3461
3462
0
    if (pSdXMLGraphicObjectShapeContext)
3463
0
        aMimeType = pSdXMLGraphicObjectShapeContext->getMimeType();
3464
0
    return aMimeType;
3465
0
}
3466
3467
OUString SdXMLFrameShapeContext::getGraphicPackageURLFromImportContext(const SvXMLImportContext& rContext) const
3468
0
{
3469
0
    OUString aRetval;
3470
0
    const SdXMLGraphicObjectShapeContext* pSdXMLGraphicObjectShapeContext = dynamic_cast< const SdXMLGraphicObjectShapeContext* >(&rContext);
3471
3472
0
    if(pSdXMLGraphicObjectShapeContext)
3473
0
    {
3474
0
        try
3475
0
        {
3476
0
            const uno::Reference< beans::XPropertySet > xPropSet(pSdXMLGraphicObjectShapeContext->getShape(), uno::UNO_QUERY_THROW);
3477
3478
0
            xPropSet->getPropertyValue(u"GraphicStreamURL"_ustr) >>= aRetval;
3479
0
        }
3480
0
        catch( uno::Exception& )
3481
0
        {
3482
0
            DBG_UNHANDLED_EXCEPTION( "xmloff", "Error in cleanup of multiple graphic object import." );
3483
0
        }
3484
0
    }
3485
3486
0
    return aRetval;
3487
0
}
3488
3489
css::uno::Reference< css::xml::sax::XFastContextHandler > SdXMLFrameShapeContext::createFastChildContext(
3490
    sal_Int32 nElement,
3491
    const uno::Reference< xml::sax::XFastAttributeList>& xAttrList )
3492
8.80k
{
3493
8.80k
    SvXMLImportContextRef xContext;
3494
8.80k
    if( !mxImplContext.is() )
3495
8.69k
    {
3496
8.69k
        SvXMLShapeContext* pShapeContext = XMLShapeImportHelper::CreateFrameChildContext(
3497
8.69k
                        GetImport(), nElement, xAttrList, mxShapes, mxAttrList );
3498
3499
8.69k
        xContext = pShapeContext;
3500
3501
        // propagate the hyperlink to child context
3502
8.69k
        if ( !msHyperlink.isEmpty() )
3503
0
            pShapeContext->setHyperlink( msHyperlink );
3504
3505
8.69k
        auto nToken = nElement & TOKEN_MASK;
3506
8.69k
        bool bMedia = false;
3507
        // Ignore gltf model if necessary and so the fallback image will be imported
3508
8.69k
        if( nToken == XML_PLUGIN )
3509
0
        {
3510
0
            SdXMLPluginShapeContext* pPluginContext = dynamic_cast<SdXMLPluginShapeContext*>(pShapeContext);
3511
0
            if( pPluginContext && pPluginContext->getMimeType() == "model/vnd.gltf+json" )
3512
0
            {
3513
0
                mxImplContext = nullptr;
3514
0
                return new SvXMLImportContext(GetImport());
3515
0
            }
3516
0
            else if (pPluginContext && ::comphelper::IsMediaMimeType(pPluginContext->getMimeType()))
3517
0
            {
3518
                // The media may have a preview, import it.
3519
0
                bMedia = true;
3520
0
            }
3521
0
        }
3522
3523
8.69k
        mxImplContext = xContext;
3524
8.69k
        mbSupportsReplacement = (nToken == XML_OBJECT ) || (nToken == XML_OBJECT_OLE) || bMedia;
3525
8.69k
        setSupportsMultipleContents(nToken == XML_IMAGE);
3526
3527
8.69k
        if(getSupportsMultipleContents() && dynamic_cast< SdXMLGraphicObjectShapeContext* >(xContext.get()))
3528
0
        {
3529
0
            if ( !maShapeId.isEmpty() )
3530
0
                GetImport().getInterfaceToIdentifierMapper().reserveIdentifier( maShapeId );
3531
3532
0
            addContent(*mxImplContext);
3533
0
        }
3534
8.69k
    }
3535
106
    else if(getSupportsMultipleContents() && nElement == XML_ELEMENT(DRAW, XML_IMAGE))
3536
0
    {
3537
        // read another image
3538
0
        xContext = XMLShapeImportHelper::CreateFrameChildContext(
3539
0
            GetImport(), nElement, xAttrList, mxShapes, mxAttrList);
3540
0
        mxImplContext = xContext;
3541
3542
0
        if(dynamic_cast< SdXMLGraphicObjectShapeContext* >(xContext.get()))
3543
0
        {
3544
0
            addContent(*mxImplContext);
3545
0
        }
3546
0
    }
3547
106
    else if( mbSupportsReplacement && !mxReplImplContext.is() &&
3548
0
             nElement == XML_ELEMENT(DRAW, XML_IMAGE) )
3549
0
    {
3550
        // read replacement image
3551
0
        SvXMLImportContext *pImplContext = mxImplContext.get();
3552
0
        SdXMLShapeContext *pSContext =
3553
0
            dynamic_cast<SdXMLShapeContext*>( pImplContext  );
3554
0
        if( pSContext )
3555
0
        {
3556
0
            uno::Reference < beans::XPropertySet > xPropSet(
3557
0
                    pSContext->getShape(), uno::UNO_QUERY );
3558
0
            if( xPropSet.is() )
3559
0
            {
3560
0
                xContext = new XMLReplacementImageContext( GetImport(),
3561
0
                                    nElement, xAttrList, xPropSet );
3562
0
                mxReplImplContext = xContext;
3563
0
            }
3564
0
        }
3565
0
    }
3566
106
    else if( nElement == XML_ELEMENT(SVG, XML_TITLE) || // #i68101#
3567
106
             nElement == XML_ELEMENT(SVG_COMPAT, XML_TITLE) ||
3568
106
             nElement == XML_ELEMENT(SVG, XML_DESC) ||
3569
106
             nElement == XML_ELEMENT(SVG_COMPAT, XML_DESC) ||
3570
106
             nElement == XML_ELEMENT(OFFICE, XML_EVENT_LISTENERS) ||
3571
106
             nElement == XML_ELEMENT(DRAW, XML_GLUE_POINT) ||
3572
106
             nElement == XML_ELEMENT(DRAW, XML_THUMBNAIL) )
3573
0
    {
3574
0
        if (getSupportsMultipleContents())
3575
0
        {   // tdf#103567 ensure props are set on surviving shape
3576
            // note: no more draw:image can be added once we get here
3577
0
            mxImplContext = solveMultipleImages();
3578
0
        }
3579
0
        SvXMLImportContext *pImplContext = mxImplContext.get();
3580
0
        xContext = static_cast<SvXMLImportContext*>(dynamic_cast<SdXMLShapeContext&>(*pImplContext).createFastChildContext( nElement,
3581
0
                                                                        xAttrList ).get());
3582
0
    }
3583
106
    else if ( nElement == XML_ELEMENT(DRAW, XML_IMAGE_MAP) )
3584
0
    {
3585
0
        if (getSupportsMultipleContents())
3586
0
        {   // tdf#103567 ensure props are set on surviving shape
3587
            // note: no more draw:image can be added once we get here
3588
0
            mxImplContext = solveMultipleImages();
3589
0
        }
3590
0
        SdXMLShapeContext *pSContext = dynamic_cast< SdXMLShapeContext* >( mxImplContext.get() );
3591
0
        if( pSContext )
3592
0
        {
3593
0
            uno::Reference < beans::XPropertySet > xPropSet( pSContext->getShape(), uno::UNO_QUERY );
3594
0
            if (xPropSet.is())
3595
0
            {
3596
0
                xContext = new XMLImageMapContext(GetImport(), xPropSet);
3597
0
            }
3598
0
        }
3599
0
    }
3600
106
    else if ( nElement == XML_ELEMENT(LO_EXT, XML_SIGNATURELINE) )
3601
0
    {
3602
0
        SdXMLShapeContext* pSContext = dynamic_cast<SdXMLShapeContext*>(mxImplContext.get());
3603
0
        if (pSContext)
3604
0
        {
3605
0
            uno::Reference<beans::XPropertySet> xPropSet(pSContext->getShape(), uno::UNO_QUERY);
3606
0
            if (xPropSet.is())
3607
0
            {
3608
0
                xContext = new SignatureLineContext(GetImport(), nElement, xAttrList,
3609
0
                                                    pSContext->getShape());
3610
0
            }
3611
0
        }
3612
0
    }
3613
106
    else if ( nElement == XML_ELEMENT(LO_EXT, XML_QRCODE))
3614
0
    {
3615
0
        SdXMLShapeContext* pSContext = dynamic_cast<SdXMLShapeContext*>(mxImplContext.get());
3616
0
        if (pSContext)
3617
0
        {
3618
0
            uno::Reference<beans::XPropertySet> xPropSet(pSContext->getShape(), uno::UNO_QUERY);
3619
0
            if (xPropSet.is())
3620
0
            {
3621
0
                xContext = new QRCodeContext(GetImport(), nElement, xAttrList,
3622
0
                                                    pSContext->getShape());
3623
0
            }
3624
0
        }
3625
0
    }
3626
3627
8.80k
    return xContext;
3628
8.80k
}
3629
3630
void SdXMLFrameShapeContext::startFastElement (sal_Int32 /*nElement*/,
3631
    const css::uno::Reference< css::xml::sax::XFastAttributeList >& /*xAttrList*/)
3632
7.88k
{
3633
    // ignore
3634
7.88k
}
3635
3636
void SdXMLFrameShapeContext::endFastElement(sal_Int32 nElement)
3637
5.49k
{
3638
    // solve if multiple image child contexts were imported
3639
5.49k
    SvXMLImportContextRef const pSelectedContext(solveMultipleImages());
3640
5.49k
    const SdXMLGraphicObjectShapeContext* pShapeContext(
3641
5.49k
        dynamic_cast<const SdXMLGraphicObjectShapeContext*>(pSelectedContext.get()));
3642
5.49k
    if ( pShapeContext )
3643
0
    {
3644
0
        assert( mxImplContext.is() );
3645
0
        const uno::Reference< uno::XInterface > xShape( pShapeContext->getShape() );
3646
0
        GetImport().getInterfaceToIdentifierMapper().registerReservedReference( maShapeId, xShape );
3647
0
    }
3648
3649
5.49k
    if( !mxImplContext.is() )
3650
53
    {
3651
        // now check if this is an empty presentation object
3652
53
        for( auto& aIter : sax_fastparser::castToFastAttributeList(mxAttrList) )
3653
298
        {
3654
298
            switch (aIter.getToken())
3655
298
            {
3656
28
                case XML_ELEMENT(PRESENTATION, XML_PLACEHOLDER):
3657
28
                    mbIsPlaceholder = IsXMLToken( aIter, XML_TRUE );
3658
28
                    break;
3659
35
                case XML_ELEMENT(PRESENTATION, XML_CLASS):
3660
35
                    maPresentationClass = aIter.toString();
3661
35
                    break;
3662
235
                default:;
3663
298
            }
3664
298
        }
3665
3666
53
        if( (!maPresentationClass.isEmpty()) && mbIsPlaceholder )
3667
26
        {
3668
26
            uno::Reference< xml::sax::XFastAttributeList> xEmpty;
3669
3670
26
            enum XMLTokenEnum eToken = XML_TEXT_BOX;
3671
3672
26
            if( IsXMLToken( maPresentationClass, XML_GRAPHIC ) )
3673
0
            {
3674
0
                eToken = XML_IMAGE;
3675
3676
0
            }
3677
26
            else if( IsXMLToken( maPresentationClass, XML_PAGE ) )
3678
0
            {
3679
0
                eToken = XML_PAGE_THUMBNAIL;
3680
0
            }
3681
26
            else if( IsXMLToken( maPresentationClass, XML_CHART ) ||
3682
26
                     IsXMLToken( maPresentationClass, XML_TABLE ) ||
3683
26
                     IsXMLToken( maPresentationClass, XML_OBJECT ) )
3684
0
            {
3685
0
                eToken = XML_OBJECT;
3686
0
            }
3687
3688
26
            auto x = XML_ELEMENT(DRAW, eToken);
3689
26
            mxImplContext = XMLShapeImportHelper::CreateFrameChildContext(
3690
26
                    GetImport(), x, mxAttrList, mxShapes, xEmpty );
3691
3692
26
            if( mxImplContext.is() )
3693
26
            {
3694
26
                mxImplContext->startFastElement( x, mxAttrList );
3695
26
                mxImplContext->endFastElement(x);
3696
26
            }
3697
26
        }
3698
53
    }
3699
3700
5.49k
    mxImplContext = nullptr;
3701
5.49k
    SdXMLShapeContext::endFastElement(nElement);
3702
5.49k
}
3703
3704
bool SdXMLFrameShapeContext::processAttribute( const sax_fastparser::FastAttributeList::FastAttributeIter & aIter )
3705
25.1k
{
3706
25.1k
    bool bId( false );
3707
3708
25.1k
    switch ( aIter.getToken() )
3709
25.1k
    {
3710
0
        case XML_ELEMENT(DRAW, XML_ID):
3711
0
        case XML_ELEMENT(DRAW_EXT, XML_ID):
3712
0
        case XML_ELEMENT(NONE, XML_ID):
3713
0
        case XML_ELEMENT(XML, XML_ID) :
3714
0
            bId = true;
3715
0
            break;
3716
25.1k
        default:;
3717
25.1k
    }
3718
3719
25.1k
    if ( bId )
3720
0
        return SdXMLShapeContext::processAttribute( aIter );
3721
25.1k
    return true; // deliberately ignoring other attributes
3722
25.1k
}
3723
3724
3725
SdXMLCustomShapeContext::SdXMLCustomShapeContext(
3726
    SvXMLImport& rImport,
3727
    const css::uno::Reference< css::xml::sax::XFastAttributeList>& xAttrList,
3728
    uno::Reference< drawing::XShapes > const & rShapes)
3729
4
:   SdXMLShapeContext( rImport, xAttrList, rShapes, false/*bTemporaryShape*/ )
3730
4
{
3731
    // See the XMLTextFrameContext ctor, a frame has Writer content (and not
3732
    // editeng) if its autostyle has a parent style. Do the same for shapes as well.
3733
4
    for( auto& aIter : sax_fastparser::castToFastAttributeList(xAttrList) )
3734
0
    {
3735
0
        if (aIter.getToken() == XML_ELEMENT(DRAW, XML_STYLE_NAME))
3736
0
        {
3737
0
            OUString aStyleName = aIter.toString();
3738
0
            if(!aStyleName.isEmpty())
3739
0
            {
3740
0
                rtl::Reference<XMLTextImportHelper> xTxtImport = GetImport().GetTextImport();
3741
0
                XMLPropStyleContext* pStyle = xTxtImport->FindAutoFrameStyle(aStyleName);
3742
                // Note that this an API name, so intentionally not localized.
3743
                // Also allow other Frame styles with the same prefix, we just want to reject
3744
                // Graphics after all.
3745
0
                if (pStyle && pStyle->GetParentName().startsWith("Frame"))
3746
0
                {
3747
0
                    mbTextBox = true;
3748
0
                    break;
3749
0
                }
3750
0
            }
3751
0
        }
3752
0
    }
3753
4
}
3754
3755
SdXMLCustomShapeContext::~SdXMLCustomShapeContext()
3756
4
{
3757
4
}
3758
3759
// this is called from the parent group for each unparsed attribute in the attribute list
3760
bool SdXMLCustomShapeContext::processAttribute( const sax_fastparser::FastAttributeList::FastAttributeIter & aIter )
3761
0
{
3762
0
    if( aIter.getToken() == XML_ELEMENT(DRAW, XML_ENGINE) )
3763
0
    {
3764
0
        maCustomShapeEngine = aIter.toString();
3765
0
    }
3766
0
    else if (aIter.getToken() == XML_ELEMENT(DRAW, XML_DATA) )
3767
0
    {
3768
0
        maCustomShapeData = aIter.toString();
3769
0
    }
3770
0
    else
3771
0
        return SdXMLShapeContext::processAttribute( aIter );
3772
0
    return true;
3773
0
}
3774
3775
void SdXMLCustomShapeContext::startFastElement (sal_Int32 nElement,
3776
    const css::uno::Reference< css::xml::sax::XFastAttributeList >& xAttrList)
3777
4
{
3778
    // create rectangle shape
3779
4
    AddShape(u"com.sun.star.drawing.CustomShape"_ustr);
3780
4
    if ( !mxShape.is() )
3781
0
        return;
3782
3783
    // Add, set Style and properties from base shape
3784
4
    SetStyle();
3785
4
    SetLayer();
3786
3787
    // set pos, size, shear and rotate
3788
4
    SetTransformation();
3789
3790
4
    try
3791
4
    {
3792
4
        uno::Reference< beans::XPropertySet > xPropSet( mxShape, uno::UNO_QUERY );
3793
4
        if( xPropSet.is() )
3794
4
        {
3795
4
            if ( !maCustomShapeEngine.isEmpty() )
3796
0
            {
3797
0
                xPropSet->setPropertyValue( EASGet( EAS_CustomShapeEngine ), Any(maCustomShapeEngine) );
3798
0
            }
3799
4
            if ( !maCustomShapeData.isEmpty() )
3800
0
            {
3801
0
                xPropSet->setPropertyValue( EASGet( EAS_CustomShapeData ), Any(maCustomShapeData) );
3802
0
            }
3803
4
        }
3804
4
    }
3805
4
    catch(const uno::Exception&)
3806
4
    {
3807
0
        DBG_UNHANDLED_EXCEPTION( "xmloff", "setting enhanced customshape geometry" );
3808
0
    }
3809
4
    SdXMLShapeContext::startFastElement(nElement, xAttrList);
3810
4
}
3811
3812
void SdXMLCustomShapeContext::endFastElement(sal_Int32 nElement)
3813
1
{
3814
    // Customshapes remember mirror state in its enhanced geometry.
3815
    // SetTransformation() in StartElement() may have applied mirroring, but that is not yet
3816
    // contained. Merge that information here before writing the property.
3817
1
    if(!maUsedTransformation.isIdentity())
3818
0
    {
3819
0
        basegfx::B2DVector aScale, aTranslate;
3820
0
        double fRotate, fShearX;
3821
3822
0
        maUsedTransformation.decompose(aScale, aTranslate, fRotate, fShearX);
3823
3824
0
        if (aScale.getX() < 0.0)
3825
0
        {
3826
0
            static constexpr OUString sName(u"MirroredX"_ustr);
3827
            //fdo#84043 Merge, if property exists, otherwise append it
3828
0
            auto aI = std::find_if(maCustomShapeGeometry.begin(), maCustomShapeGeometry.end(),
3829
0
                [](beans::PropertyValue& rValue) { return rValue.Name == sName; });
3830
0
            if (aI != maCustomShapeGeometry.end())
3831
0
            {
3832
0
                beans::PropertyValue& rItem = *aI;
3833
0
                bool bMirroredX = *o3tl::doAccess<bool>(rItem.Value);
3834
0
                rItem.Value <<= !bMirroredX;
3835
0
                rItem.Handle = -1;
3836
0
                rItem.State = beans::PropertyState_DIRECT_VALUE;
3837
0
            }
3838
0
            else
3839
0
            {
3840
0
                beans::PropertyValue* pItem;
3841
0
                maCustomShapeGeometry.emplace_back();
3842
0
                pItem = &maCustomShapeGeometry.back();
3843
0
                pItem->Name = sName;
3844
0
                pItem->Handle = -1;
3845
0
                pItem->Value <<= true;
3846
0
                pItem->State = beans::PropertyState_DIRECT_VALUE;
3847
0
            }
3848
0
        }
3849
3850
0
        if (aScale.getY() < 0.0)
3851
0
        {
3852
0
            static constexpr OUString sName(u"MirroredY"_ustr);
3853
            //fdo#84043 Merge, if property exists, otherwise append it
3854
0
            auto aI = std::find_if(maCustomShapeGeometry.begin(), maCustomShapeGeometry.end(),
3855
0
                [](beans::PropertyValue& rValue) { return rValue.Name == sName; });
3856
0
            if (aI != maCustomShapeGeometry.end())
3857
0
            {
3858
0
                beans::PropertyValue& rItem = *aI;
3859
0
                bool bMirroredY = *o3tl::doAccess<bool>(rItem.Value);
3860
0
                rItem.Value <<= !bMirroredY;
3861
0
                rItem.Handle = -1;
3862
0
                rItem.State = beans::PropertyState_DIRECT_VALUE;
3863
0
            }
3864
0
            else
3865
0
            {
3866
0
                beans::PropertyValue* pItem;
3867
0
                maCustomShapeGeometry.emplace_back();
3868
0
                pItem = &maCustomShapeGeometry.back();
3869
0
                pItem->Name = sName;
3870
0
                pItem->Handle = -1;
3871
0
                pItem->Value <<= true;
3872
0
                pItem->State = beans::PropertyState_DIRECT_VALUE;
3873
0
            }
3874
0
        }
3875
0
    }
3876
3877
1
    if ( !maCustomShapeGeometry.empty() )
3878
0
    {
3879
        // converting the vector to a sequence
3880
0
        uno::Sequence< beans::PropertyValue > aSeq( comphelper::containerToSequence(maCustomShapeGeometry) );
3881
3882
0
        try
3883
0
        {
3884
0
            uno::Reference< beans::XPropertySet > xPropSet( mxShape, uno::UNO_QUERY );
3885
0
            if( xPropSet.is() )
3886
0
            {
3887
0
                xPropSet->setPropertyValue( u"CustomShapeGeometry"_ustr, Any(aSeq) );
3888
0
            }
3889
0
        }
3890
0
        catch(const uno::Exception&)
3891
0
        {
3892
0
            DBG_UNHANDLED_EXCEPTION( "xmloff", "setting enhanced customshape geometry" );
3893
0
        }
3894
3895
0
        sal_Int32 nUPD;
3896
0
        sal_Int32 nBuild;
3897
0
        if (GetImport().getBuildIds(nUPD, nBuild))
3898
0
        {
3899
0
            if( ((nUPD >= 640 && nUPD <= 645) || (nUPD == 680)) && (nBuild <= 9221) )
3900
0
            {
3901
0
                Reference< drawing::XEnhancedCustomShapeDefaulter > xDefaulter( mxShape, UNO_QUERY );
3902
0
                if( xDefaulter.is() )
3903
0
                {
3904
0
                    xDefaulter->createCustomShapeDefaults( u""_ustr );
3905
0
                }
3906
0
            }
3907
0
        }
3908
0
    }
3909
3910
1
    SdXMLShapeContext::endFastElement(nElement);
3911
3912
    // tdf#98163 call a custom slot to be able to reset the UNO API
3913
    // implementations held on the SdrObjects of type
3914
    // SdrObjCustomShape - those tend to linger until the entire file
3915
    // is loaded. For large files with a lot of these, 32bit systems
3916
    // may crash due to being out of resources after ca. 4200
3917
    // Outliners and VirtualDevices used there as RefDevice
3918
1
    try
3919
1
    {
3920
1
        uno::Reference< beans::XPropertySet > xPropSet(mxShape, uno::UNO_QUERY);
3921
3922
1
        if(xPropSet.is())
3923
1
        {
3924
1
            xPropSet->setPropertyValue(
3925
1
                u"FlushCustomShapeUnoApiObjects"_ustr, css::uno::Any(true));
3926
1
        }
3927
1
    }
3928
1
    catch(const uno::Exception&)
3929
1
    {
3930
0
        DBG_UNHANDLED_EXCEPTION("xmloff", "flushing after load");
3931
0
    }
3932
1
}
3933
3934
css::uno::Reference< css::xml::sax::XFastContextHandler > SdXMLCustomShapeContext::createFastChildContext(
3935
    sal_Int32 nElement,
3936
    const uno::Reference< xml::sax::XFastAttributeList>& xAttrList )
3937
3
{
3938
3
    css::uno::Reference< css::xml::sax::XFastContextHandler > xContext;
3939
3
    if ( nElement == XML_ELEMENT(DRAW, XML_ENHANCED_GEOMETRY) )
3940
0
    {
3941
0
        uno::Reference< beans::XPropertySet > xPropSet( mxShape,uno::UNO_QUERY );
3942
0
        if ( xPropSet.is() )
3943
0
            xContext = new XMLEnhancedCustomShapeContext( GetImport(), mxShape, maCustomShapeGeometry );
3944
0
    }
3945
    // delegate to parent class if no context could be created
3946
3
    if (!xContext)
3947
3
        xContext = SdXMLShapeContext::createFastChildContext( nElement,
3948
3
                                                         xAttrList);
3949
3
    return xContext;
3950
3
}
3951
3952
SdXMLTableShapeContext::SdXMLTableShapeContext( SvXMLImport& rImport, const css::uno::Reference< css::xml::sax::XFastAttributeList>& xAttrList, css::uno::Reference< css::drawing::XShapes > const & rShapes )
3953
744
: SdXMLShapeContext( rImport, xAttrList, rShapes, false )
3954
744
{
3955
744
}
3956
3957
SdXMLTableShapeContext::~SdXMLTableShapeContext()
3958
744
{
3959
744
}
3960
3961
void SdXMLTableShapeContext::startFastElement (sal_Int32 nElement,
3962
    const css::uno::Reference< css::xml::sax::XFastAttributeList >& xAttrList)
3963
744
{
3964
744
    OUString service(u"com.sun.star.drawing.TableShape"_ustr);
3965
3966
744
    bool bIsPresShape = !maPresentationClass.isEmpty() && GetImport().GetShapeImport()->IsPresentationShapesSupported();
3967
744
    if( bIsPresShape )
3968
0
    {
3969
0
        if( IsXMLToken( maPresentationClass, XML_TABLE ) )
3970
0
        {
3971
0
            service = "com.sun.star.presentation.TableShape";
3972
0
        }
3973
0
    }
3974
3975
744
    AddShape(service);
3976
3977
744
    if( !mxShape.is() )
3978
0
        return;
3979
3980
744
    SetLayer();
3981
3982
744
    uno::Reference< beans::XPropertySet > xProps(mxShape, uno::UNO_QUERY);
3983
3984
744
    if(bIsPresShape && xProps.is())
3985
0
    {
3986
0
        uno::Reference< beans::XPropertySetInfo > xPropsInfo( xProps->getPropertySetInfo() );
3987
0
        if( xPropsInfo.is() )
3988
0
        {
3989
0
            if( !mbIsPlaceholder && xPropsInfo->hasPropertyByName(u"IsEmptyPresentationObject"_ustr))
3990
0
                xProps->setPropertyValue(u"IsEmptyPresentationObject"_ustr, css::uno::Any(false) );
3991
3992
0
            if( mbIsUserTransformed && xPropsInfo->hasPropertyByName(u"IsPlaceholderDependent"_ustr))
3993
0
                xProps->setPropertyValue(u"IsPlaceholderDependent"_ustr, css::uno::Any(false) );
3994
0
        }
3995
0
    }
3996
3997
744
    SetStyle();
3998
3999
744
    if( xProps.is() )
4000
744
    {
4001
744
        if( !msTemplateStyleName.isEmpty() ) try
4002
0
        {
4003
0
            Reference< XStyleFamiliesSupplier > xFamiliesSupp( GetImport().GetModel(), UNO_QUERY_THROW );
4004
0
            Reference< XNameAccess > xFamilies( xFamiliesSupp->getStyleFamilies() );
4005
0
            Reference< XNameAccess > xTableFamily( xFamilies->getByName( u"table"_ustr ), UNO_QUERY_THROW );
4006
0
            Reference< XStyle > xTableStyle( xTableFamily->getByName( msTemplateStyleName ), UNO_QUERY_THROW );
4007
0
            xProps->setPropertyValue(u"TableTemplate"_ustr, Any( xTableStyle ) );
4008
0
        }
4009
0
        catch(const Exception&)
4010
0
        {
4011
0
            DBG_UNHANDLED_EXCEPTION("xmloff.draw");
4012
0
        }
4013
4014
744
        const XMLPropertyMapEntry* pEntry = &aXMLTableShapeAttributes[0];
4015
5.20k
        for( int i = 0; !pEntry->IsEnd() && (i < 6); i++, pEntry++ )
4016
4.46k
        {
4017
4.46k
            try
4018
4.46k
            {
4019
4.46k
                xProps->setPropertyValue( pEntry->getApiName(), Any( maTemplateStylesUsed[i] ) );
4020
4.46k
            }
4021
4.46k
            catch(const Exception&)
4022
4.46k
            {
4023
0
                DBG_UNHANDLED_EXCEPTION("xmloff.draw");
4024
0
            }
4025
4.46k
        }
4026
744
    }
4027
4028
744
    GetImport().GetShapeImport()->finishShape( mxShape, mxAttrList, mxShapes );
4029
4030
744
    const rtl::Reference< XMLTableImport >& xTableImport( GetImport().GetShapeImport()->GetShapeTableImport() );
4031
744
    if( xTableImport.is() && xProps.is() )
4032
744
    {
4033
744
        uno::Reference< table::XColumnRowRange > xColumnRowRange(
4034
744
            xProps->getPropertyValue(u"Model"_ustr), uno::UNO_QUERY );
4035
4036
744
        if( xColumnRowRange.is() )
4037
744
            mxTableImportContext = xTableImport->CreateTableContext( xColumnRowRange );
4038
4039
744
        if( mxTableImportContext.is() )
4040
744
            mxTableImportContext->startFastElement( nElement, xAttrList );
4041
744
    }
4042
744
}
4043
4044
void SdXMLTableShapeContext::endFastElement(sal_Int32 nElement)
4045
31
{
4046
31
    if( mxTableImportContext.is() )
4047
31
        mxTableImportContext->endFastElement(nElement);
4048
4049
31
    SdXMLShapeContext::endFastElement(nElement);
4050
4051
31
    if( mxShape.is() )
4052
31
    {
4053
        // set pos, size, shear and rotate
4054
31
        SetTransformation();
4055
31
    }
4056
31
}
4057
4058
// this is called from the parent group for each unparsed attribute in the attribute list
4059
bool SdXMLTableShapeContext::processAttribute( const sax_fastparser::FastAttributeList::FastAttributeIter & aIter )
4060
2.95k
{
4061
2.95k
    auto nElement = aIter.getToken();
4062
2.95k
    if( IsTokenInNamespace(nElement, XML_NAMESPACE_TABLE) )
4063
1.42k
    {
4064
1.42k
        if( (nElement & TOKEN_MASK) == XML_TEMPLATE_NAME )
4065
0
        {
4066
0
            msTemplateStyleName = aIter.toString();
4067
0
        }
4068
1.42k
        else
4069
1.42k
        {
4070
1.42k
            int i = 0;
4071
1.42k
            const XMLPropertyMapEntry* pEntry = &aXMLTableShapeAttributes[0];
4072
10.0k
            while( !pEntry->IsEnd() && (i < 6) )
4073
8.57k
            {
4074
8.57k
                if( (nElement & TOKEN_MASK) == pEntry->meXMLName )
4075
0
                {
4076
0
                    if( IsXMLToken( aIter, XML_TRUE ) )
4077
0
                        maTemplateStylesUsed[i] = true;
4078
0
                    break;
4079
0
                }
4080
8.57k
                pEntry++;
4081
8.57k
                i++;
4082
8.57k
            }
4083
1.42k
        }
4084
1.42k
    }
4085
2.95k
    return SdXMLShapeContext::processAttribute( aIter );
4086
2.95k
}
4087
4088
css::uno::Reference< css::xml::sax::XFastContextHandler > SdXMLTableShapeContext::createFastChildContext(
4089
    sal_Int32 nElement,
4090
    const css::uno::Reference< css::xml::sax::XFastAttributeList >& xAttrList )
4091
5.41k
{
4092
5.41k
    if( mxTableImportContext.is() && IsTokenInNamespace(nElement, XML_NAMESPACE_TABLE) )
4093
5.13k
        return mxTableImportContext->createFastChildContext(nElement, xAttrList);
4094
287
    return SdXMLShapeContext::createFastChildContext(nElement, xAttrList);
4095
5.41k
}
4096
4097
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */