Coverage Report

Created: 2026-10-14 09:33

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