Coverage Report

Created: 2025-11-16 09:57

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/libreoffice/xmloff/source/text/XMLTextFrameContext.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 <o3tl/string_view.hxx>
21
#include <osl/diagnose.h>
22
#include <sal/log.hxx>
23
#include <comphelper/diagnose_ex.hxx>
24
#include <comphelper/base64.hxx>
25
#include <comphelper/configuration.hxx>
26
#include <comphelper/mediamimetype.hxx>
27
#include <com/sun/star/frame/XModel.hpp>
28
#include <com/sun/star/lang/XMultiServiceFactory.hpp>
29
#include <com/sun/star/text/TextContentAnchorType.hpp>
30
#include <com/sun/star/beans/XPropertySet.hpp>
31
#include <com/sun/star/text/XTextFrame.hpp>
32
#include <com/sun/star/container/XNamed.hpp>
33
#include <com/sun/star/container/XNameContainer.hpp>
34
#include <com/sun/star/graphic/XGraphic.hpp>
35
#include <com/sun/star/text/SizeType.hpp>
36
#include <com/sun/star/drawing/XShape.hpp>
37
#include <com/sun/star/document/XEventsSupplier.hpp>
38
#include <com/sun/star/document/XEmbeddedObjectSupplier.hpp>
39
#include <com/sun/star/io/XOutputStream.hpp>
40
#include <com/sun/star/text/HoriOrientation.hpp>
41
#include <com/sun/star/text/VertOrientation.hpp>
42
#include <sax/tools/converter.hxx>
43
#include <utility>
44
#include <xmloff/xmlimp.hxx>
45
#include <xmloff/xmltoken.hxx>
46
#include <xmloff/xmlnamespace.hxx>
47
#include <xmloff/xmluconv.hxx>
48
#include "XMLAnchorTypePropHdl.hxx"
49
#include <XMLEmbeddedObjectImportContext.hxx>
50
#include <xmloff/XMLBase64ImportContext.hxx>
51
#include <XMLReplacementImageContext.hxx>
52
#include <xmloff/prstylei.hxx>
53
#include <xmloff/i18nmap.hxx>
54
#include <xexptran.hxx>
55
#include <xmloff/shapeimport.hxx>
56
#include <xmloff/XMLEventsImportContext.hxx>
57
#include <XMLImageMapContext.hxx>
58
#include "XMLTextFrameContext.hxx"
59
#include <basegfx/polygon/b2dpolygon.hxx>
60
#include <basegfx/polygon/b2dpolygontools.hxx>
61
#include <basegfx/polygon/b2dpolypolygon.hxx>
62
#include <basegfx/matrix/b2dhommatrixtools.hxx>
63
#include <basegfx/polygon/b2dpolypolygontools.hxx>
64
#include <basegfx/numeric/ftools.hxx>
65
#include <map>
66
#include <string_view>
67
68
using namespace ::com::sun::star;
69
using namespace ::com::sun::star::uno;
70
using namespace ::com::sun::star::text;
71
using namespace ::com::sun::star::xml::sax;
72
using namespace ::com::sun::star::beans;
73
using namespace ::com::sun::star::lang;
74
using namespace ::com::sun::star::container;
75
using namespace ::com::sun::star::drawing;
76
using namespace ::com::sun::star::document;
77
using namespace ::xmloff::token;
78
using ::com::sun::star::document::XEventsSupplier;
79
80
133k
#define XML_TEXT_FRAME_TEXTBOX 1
81
316k
#define XML_TEXT_FRAME_GRAPHIC 2
82
129k
#define XML_TEXT_FRAME_OBJECT 3
83
182k
#define XML_TEXT_FRAME_OBJECT_OLE 4
84
264k
#define XML_TEXT_FRAME_APPLET 5
85
223k
#define XML_TEXT_FRAME_PLUGIN 6
86
65.7k
#define XML_TEXT_FRAME_FLOATING_FRAME 7
87
88
typedef ::std::map < const OUString, OUString > ParamMap;
89
90
class XMLTextFrameContextHyperlink_Impl
91
{
92
    OUString sHRef;
93
    OUString sName;
94
    OUString sTargetFrameName;
95
    bool bMap;
96
97
public:
98
99
    inline XMLTextFrameContextHyperlink_Impl( OUString aHRef,
100
                       OUString aName,
101
                       OUString aTargetFrameName,
102
                       bool bMap );
103
104
0
    const OUString& GetHRef() const { return sHRef; }
105
0
    const OUString& GetName() const { return sName; }
106
0
    const OUString& GetTargetFrameName() const { return sTargetFrameName; }
107
0
    bool GetMap() const { return bMap; }
108
};
109
110
inline XMLTextFrameContextHyperlink_Impl::XMLTextFrameContextHyperlink_Impl(
111
    OUString aHRef, OUString aName,
112
    OUString aTargetFrameName, bool bM ) :
113
0
    sHRef(std::move( aHRef )),
114
0
    sName(std::move( aName )),
115
0
    sTargetFrameName(std::move( aTargetFrameName )),
116
0
    bMap( bM )
117
0
{
118
0
}
119
120
namespace {
121
122
// Implement Title/Description Elements UI (#i73249#)
123
class XMLTextFrameTitleOrDescContext_Impl : public SvXMLImportContext
124
{
125
    OUString&   mrTitleOrDesc;
126
127
public:
128
129
130
    XMLTextFrameTitleOrDescContext_Impl( SvXMLImport& rImport,
131
                                         OUString& rTitleOrDesc );
132
133
    virtual void SAL_CALL characters( const OUString& rText ) override;
134
};
135
136
}
137
138
XMLTextFrameTitleOrDescContext_Impl::XMLTextFrameTitleOrDescContext_Impl(
139
        SvXMLImport& rImport,
140
        OUString& rTitleOrDesc )
141
0
    : SvXMLImportContext( rImport )
142
0
    , mrTitleOrDesc( rTitleOrDesc )
143
0
{
144
0
}
145
146
void XMLTextFrameTitleOrDescContext_Impl::characters( const OUString& rText )
147
0
{
148
0
    mrTitleOrDesc += rText;
149
0
}
150
151
namespace {
152
153
class XMLTextFrameParam_Impl : public SvXMLImportContext
154
{
155
public:
156
    XMLTextFrameParam_Impl( SvXMLImport& rImport,
157
            const css::uno::Reference< css::xml::sax::XFastAttributeList > & xAttrList,
158
            ParamMap &rParamMap);
159
};
160
161
}
162
163
XMLTextFrameParam_Impl::XMLTextFrameParam_Impl(
164
        SvXMLImport& rImport,
165
        const css::uno::Reference< css::xml::sax::XFastAttributeList > & xAttrList,
166
        ParamMap &rParamMap):
167
0
    SvXMLImportContext( rImport )
168
0
{
169
0
    OUString sName, sValue;
170
0
    bool bFoundValue = false; // to allow empty values
171
0
    for (auto &aIter : sax_fastparser::castToFastAttributeList( xAttrList ))
172
0
    {
173
0
        switch (aIter.getToken())
174
0
        {
175
0
            case XML_ELEMENT(DRAW, XML_VALUE):
176
0
            {
177
0
                sValue = aIter.toString();
178
0
                bFoundValue = true;
179
0
                break;
180
0
            }
181
0
            case XML_ELEMENT(DRAW, XML_NAME):
182
0
                sName = aIter.toString();
183
0
                break;
184
0
            default:
185
0
                XMLOFF_WARN_UNKNOWN("xmloff", aIter);
186
0
        }
187
0
    }
188
0
    if (!sName.isEmpty() && bFoundValue )
189
0
        rParamMap[sName] = sValue;
190
0
}
191
192
namespace {
193
194
class XMLTextFrameContourContext_Impl : public SvXMLImportContext
195
{
196
    Reference < XPropertySet > xPropSet;
197
198
public:
199
200
201
    XMLTextFrameContourContext_Impl( SvXMLImport& rImport, sal_Int32 nElement,
202
            const css::uno::Reference< css::xml::sax::XFastAttributeList > & xAttrList,
203
            const Reference < XPropertySet >& rPropSet,
204
            bool bPath );
205
};
206
207
}
208
209
XMLTextFrameContourContext_Impl::XMLTextFrameContourContext_Impl(
210
        SvXMLImport& rImport,
211
        sal_Int32 /*nElement*/,
212
        const Reference< XFastAttributeList > & xAttrList,
213
        const Reference < XPropertySet >& rPropSet,
214
        bool bPath ) :
215
0
    SvXMLImportContext( rImport ),
216
0
    xPropSet( rPropSet )
217
0
{
218
0
    OUString sD, sPoints, sViewBox;
219
0
    bool bPixelWidth = false, bPixelHeight = false;
220
0
    bool bAuto = false;
221
0
    sal_Int32 nWidth = 0;
222
0
    sal_Int32 nHeight = 0;
223
224
0
    for( auto& aIter : sax_fastparser::castToFastAttributeList(xAttrList) )
225
0
    {
226
0
        switch( aIter.getToken() )
227
0
        {
228
0
        case XML_ELEMENT(SVG, XML_VIEWBOX):
229
0
        case XML_ELEMENT(SVG_COMPAT, XML_VIEWBOX):
230
0
            sViewBox = aIter.toString();
231
0
            break;
232
0
        case XML_ELEMENT(SVG, XML_D):
233
0
        case XML_ELEMENT(SVG_COMPAT, XML_D):
234
0
            if( bPath )
235
0
                sD = aIter.toString();
236
0
            break;
237
0
        case XML_ELEMENT(DRAW,XML_POINTS):
238
0
            if( !bPath )
239
0
                sPoints = aIter.toString();
240
0
            break;
241
0
        case XML_ELEMENT(SVG, XML_WIDTH):
242
0
        case XML_ELEMENT(SVG_COMPAT, XML_WIDTH):
243
0
            if (::sax::Converter::convertMeasurePx(nWidth, aIter.toView()))
244
0
                bPixelWidth = true;
245
0
            else
246
0
                GetImport().GetMM100UnitConverter().convertMeasureToCore(
247
0
                        nWidth, aIter.toView());
248
0
            break;
249
0
        case XML_ELEMENT(SVG, XML_HEIGHT):
250
0
        case XML_ELEMENT(SVG_COMPAT, XML_HEIGHT):
251
0
            if (::sax::Converter::convertMeasurePx(nHeight, aIter.toView()))
252
0
                bPixelHeight = true;
253
0
            else
254
0
                GetImport().GetMM100UnitConverter().convertMeasureToCore(
255
0
                        nHeight, aIter.toView());
256
0
            break;
257
0
        case  XML_ELEMENT(DRAW, XML_RECREATE_ON_EDIT):
258
0
            bAuto = IsXMLToken(aIter, XML_TRUE);
259
0
            break;
260
0
        }
261
0
    }
262
263
0
    OUString sContourPolyPolygon(u"ContourPolyPolygon"_ustr);
264
0
    Reference < XPropertySetInfo > xPropSetInfo = rPropSet->getPropertySetInfo();
265
266
0
    if(!xPropSetInfo->hasPropertyByName(sContourPolyPolygon) ||
267
0
        nWidth <= 0 || nHeight <= 0 || bPixelWidth != bPixelHeight ||
268
0
        !(bPath ? sD : sPoints).getLength())
269
0
        return;
270
271
0
    const SdXMLImExViewBox aViewBox( sViewBox, GetImport().GetMM100UnitConverter());
272
0
    basegfx::B2DPolyPolygon aPolyPolygon;
273
274
    // Related tdf#161833: ignore saved polygon for "recreate on edit" contours
275
    // tdf#161833 would cause semi-transparent pixels to be treated as fully
276
    // transparent pixels when calculating the wrap contour for an image. To
277
    // force the correct contour when loading a document, force the contour
278
    // to be recalculated by ignoring the saved polygon if the contour is set
279
    // to "recreate on edit".
280
0
    if( !bAuto )
281
0
    {
282
0
        if( bPath )
283
0
        {
284
0
            basegfx::utils::importFromSvgD(aPolyPolygon, sD, GetImport().needFixPositionAfterZ(), nullptr);
285
0
        }
286
0
        else
287
0
        {
288
0
            basegfx::B2DPolygon aPolygon;
289
290
0
            if(basegfx::utils::importFromSvgPoints(aPolygon, sPoints))
291
0
            {
292
0
                aPolyPolygon = basegfx::B2DPolyPolygon(aPolygon);
293
0
            }
294
0
        }
295
0
    }
296
297
0
    if(aPolyPolygon.count())
298
0
    {
299
0
        const basegfx::B2DRange aSourceRange(
300
0
            aViewBox.GetX(), aViewBox.GetY(),
301
0
            aViewBox.GetX() + aViewBox.GetWidth(), aViewBox.GetY() + aViewBox.GetHeight());
302
0
        const basegfx::B2DRange aTargetRange(
303
0
            0.0, 0.0,
304
0
            nWidth, nHeight);
305
306
0
        if(!aSourceRange.equal(aTargetRange))
307
0
        {
308
0
            aPolyPolygon.transform(
309
0
                basegfx::utils::createSourceRangeTargetRangeTransform(
310
0
                    aSourceRange,
311
0
                    aTargetRange));
312
0
        }
313
314
0
        css::drawing::PointSequenceSequence aPointSequenceSequence;
315
0
        basegfx::utils::B2DPolyPolygonToUnoPointSequenceSequence(aPolyPolygon, aPointSequenceSequence);
316
0
        xPropSet->setPropertyValue( sContourPolyPolygon, Any(aPointSequenceSequence) );
317
0
    }
318
319
0
    static constexpr OUString sIsPixelContour(u"IsPixelContour"_ustr);
320
321
0
    if( xPropSetInfo->hasPropertyByName( sIsPixelContour ) )
322
0
    {
323
0
        xPropSet->setPropertyValue( sIsPixelContour, Any(bPixelWidth) );
324
0
    }
325
326
0
    static constexpr OUString sIsAutomaticContour(u"IsAutomaticContour"_ustr);
327
328
0
    if( xPropSetInfo->hasPropertyByName( sIsAutomaticContour ) )
329
0
    {
330
0
        xPropSet->setPropertyValue( sIsAutomaticContour, Any(bAuto) );
331
0
    }
332
0
}
333
334
namespace {
335
336
class XMLTextFrameContext_Impl : public SvXMLImportContext
337
{
338
    css::uno::Reference < css::text::XTextCursor > xOldTextCursor;
339
    css::uno::Reference < css::beans::XPropertySet > xPropSet;
340
    css::uno::Reference < css::io::XOutputStream > xBase64Stream;
341
342
    /// old list item and block (#89891#)
343
    bool mbListContextPushed;
344
345
    OUString m_sOrigName;
346
    OUString sName;
347
    OUString sStyleName;
348
    OUString sNextName;
349
    OUString sHRef;
350
    OUString sCode;
351
    OUString sMimeType;
352
    OUString sFrameName;
353
    OUString sAppletName;
354
    OUString sFilterService;
355
    OUString sBase64CharsLeft;
356
    OUString sTblName;
357
    OUStringBuffer maUrlBuffer;
358
359
    ParamMap aParamMap;
360
361
    sal_Int32   nX;
362
    sal_Int32   nY;
363
    sal_Int32   nWidth;
364
    sal_Int32   nHeight;
365
    sal_Int32   nZIndex;
366
    sal_Int16   nPage;
367
    sal_Int16   nRotation;
368
    sal_Int16   nRelWidth;
369
    sal_Int16   nRelHeight;
370
371
    sal_uInt16 nType;
372
    css::text::TextContentAnchorType   eAnchorType;
373
374
    bool    bMayScript : 1;
375
    bool    bMinWidth : 1;
376
    bool    bMinHeight : 1;
377
    bool    bSyncWidth : 1;
378
    bool    bSyncHeight : 1;
379
    bool    bCreateFailed : 1;
380
    bool    bOwnBase64Stream : 1;
381
    bool    mbMultipleContent : 1; // This context is created based on a multiple content (image)
382
    bool    m_isDecorative = false;
383
    bool    m_isSplitAllowed = false;
384
385
    void Create();
386
387
public:
388
389
390
    bool CreateIfNotThere();
391
11.4k
    const OUString& GetHRef() const { return sHRef; }
392
393
    XMLTextFrameContext_Impl( SvXMLImport& rImport,
394
            sal_Int32 nElement,
395
            const css::uno::Reference<css::xml::sax::XFastAttributeList > & rAttrList,
396
            css::text::TextContentAnchorType eAnchorType,
397
            sal_uInt16 nType,
398
            const css::uno::Reference<css::xml::sax::XFastAttributeList > & rFrameAttrList,
399
            bool bMultipleContent = false );
400
401
    virtual void SAL_CALL endFastElement(sal_Int32 nElement) override;
402
403
    virtual void SAL_CALL characters( const OUString& rChars ) override;
404
405
    virtual css::uno::Reference< css::xml::sax::XFastContextHandler > SAL_CALL createFastChildContext(
406
        sal_Int32 nElement, const css::uno::Reference< css::xml::sax::XFastAttributeList >& AttrList ) override;
407
408
    void SetHyperlink( const OUString& rHRef,
409
                       const OUString& rName,
410
                       const OUString& rTargetFrameName,
411
                       bool bMap );
412
413
    // Implement Title/Description Elements UI (#i73249#)
414
    void SetTitle( const OUString& rTitle );
415
416
    void SetDesc( const OUString& rDesc );
417
418
    void SetName();
419
420
23.6k
    const OUString& GetOrigName() const { return m_sOrigName; }
421
422
5
    css::text::TextContentAnchorType GetAnchorType() const { return eAnchorType; }
423
11.4k
    const OUString & GetMimeType() const { return sMimeType; }
424
425
11.2k
    const css::uno::Reference < css::beans::XPropertySet >& GetPropSet() const { return xPropSet; }
426
};
427
428
}
429
430
void XMLTextFrameContext_Impl::Create()
431
65.9k
{
432
65.9k
    rtl::Reference < XMLTextImportHelper > xTextImportHelper =
433
65.9k
        GetImport().GetTextImport();
434
435
65.9k
    switch ( nType)
436
65.9k
    {
437
45
        case XML_TEXT_FRAME_OBJECT:
438
83
        case XML_TEXT_FRAME_OBJECT_OLE:
439
83
            if( xBase64Stream.is() )
440
38
            {
441
38
                OUString sURL( GetImport().ResolveEmbeddedObjectURLFromBase64() );
442
38
                if( !sURL.isEmpty() )
443
38
                    xPropSet = GetImport().GetTextImport()
444
38
                            ->createAndInsertOLEObject( GetImport(), sURL,
445
38
                                                        sStyleName,
446
38
                                                        sTblName,
447
38
                                                        nWidth, nHeight );
448
38
            }
449
45
            else if( !sHRef.isEmpty() )
450
0
            {
451
0
                OUString sURL( GetImport().ResolveEmbeddedObjectURL( sHRef,
452
0
                                                                std::u16string_view() ) );
453
454
0
                if( GetImport().IsPackageURL( sHRef ) )
455
0
                {
456
0
                    xPropSet = GetImport().GetTextImport()
457
0
                            ->createAndInsertOLEObject( GetImport(), sURL,
458
0
                                                        sStyleName,
459
0
                                                        sTblName,
460
0
                                                        nWidth, nHeight );
461
0
                }
462
0
                else
463
0
                {
464
                    // it should be an own OOo link that has no storage persistence
465
0
                    xPropSet = GetImport().GetTextImport()
466
0
                            ->createAndInsertOOoLink( GetImport(),
467
0
                                                        sURL,
468
0
                                                        sStyleName,
469
0
                                                        sTblName,
470
0
                                                        nWidth, nHeight );
471
0
                }
472
0
            }
473
45
            else
474
45
            {
475
45
                OUString sURL = "vnd.sun.star.ServiceName:" + sFilterService;
476
45
                xPropSet = GetImport().GetTextImport()
477
45
                            ->createAndInsertOLEObject( GetImport(), sURL,
478
45
                                                        sStyleName,
479
45
                                                        sTblName,
480
45
                                                        nWidth, nHeight );
481
482
45
            }
483
83
            break;
484
0
        case XML_TEXT_FRAME_APPLET:
485
0
        {
486
0
            xPropSet = GetImport().GetTextImport()
487
0
                            ->createAndInsertApplet( sAppletName, sCode,
488
0
                                                     bMayScript, sHRef,
489
0
                                                     nWidth, nHeight);
490
0
            break;
491
45
        }
492
0
        case XML_TEXT_FRAME_PLUGIN:
493
0
        {
494
0
            if(!sHRef.isEmpty())
495
0
                GetImport().GetAbsoluteReference(sHRef);
496
0
            xPropSet = GetImport().GetTextImport()
497
0
                            ->createAndInsertPlugin( sMimeType, sHRef,
498
0
                                                         nWidth, nHeight);
499
500
0
            break;
501
45
        }
502
0
        case XML_TEXT_FRAME_FLOATING_FRAME:
503
0
        {
504
0
            xPropSet = GetImport().GetTextImport()
505
0
                            ->createAndInsertFloatingFrame( sFrameName, sHRef,
506
0
                                                            sStyleName,
507
0
                                                            nWidth, nHeight);
508
0
            break;
509
45
        }
510
65.8k
        default:
511
65.8k
        {
512
65.8k
            Reference<XMultiServiceFactory> xFactory( GetImport().GetModel(),
513
65.8k
                                                      UNO_QUERY );
514
65.8k
            if( xFactory.is() )
515
65.8k
            {
516
65.8k
                OUString sServiceName;
517
65.8k
                switch( nType )
518
65.8k
                {
519
23.0k
                    case XML_TEXT_FRAME_TEXTBOX: sServiceName = "com.sun.star.text.TextFrame"; break;
520
42.8k
                    case XML_TEXT_FRAME_GRAPHIC: sServiceName = "com.sun.star.text.GraphicObject"; break;
521
65.8k
                }
522
65.8k
                Reference<XInterface> xIfc = xFactory->createInstance( sServiceName );
523
65.8k
                SAL_WARN_IF( !xIfc.is(), "xmloff.text", "couldn't create frame" );
524
65.8k
                if( xIfc.is() )
525
65.7k
                    xPropSet.set( xIfc, UNO_QUERY );
526
65.8k
            }
527
65.8k
        }
528
65.9k
    }
529
530
65.8k
    if( !xPropSet.is() )
531
144
    {
532
144
        bCreateFailed = true;
533
144
        return;
534
144
    }
535
536
65.7k
    Reference< XPropertySetInfo > xPropSetInfo = xPropSet->getPropertySetInfo();
537
538
    // Skip duplicated frames
539
65.7k
    if(!mbMultipleContent && // It's allowed to have multiple image for the same frame
540
24.4k
       !sName.isEmpty() &&
541
9.82k
       xTextImportHelper->IsDuplicateFrame(sName, nX, nY, nWidth, nHeight))
542
1
    {
543
1
        bCreateFailed = true;
544
1
        return;
545
1
    }
546
547
    // set name
548
65.7k
    Reference < XNamed > xNamed( xPropSet, UNO_QUERY );
549
65.7k
    if( xNamed.is() )
550
65.7k
    {
551
65.7k
        OUString sOrigName( xNamed->getName() );
552
65.7k
        if( sOrigName.isEmpty() ||
553
38
            (!sName.isEmpty() && sOrigName != sName) )
554
65.7k
        {
555
65.7k
            OUString sOldName( sName );
556
557
65.7k
            sal_Int32 i = 0;
558
2.32M
            while( xTextImportHelper->HasFrameByName( sName ) )
559
2.25M
            {
560
2.25M
                sName = sOldName + OUString::number( ++i );
561
2.25M
            }
562
65.7k
            xNamed->setName( sName );
563
65.7k
            if( sName != sOldName )
564
39.0k
            {
565
39.0k
                xTextImportHelper->GetRenameMap().Add( XML_TEXT_RENAME_TYPE_FRAME,
566
39.0k
                                             sOldName, sName );
567
568
39.0k
            }
569
65.7k
        }
570
65.7k
    }
571
572
    // frame style
573
65.7k
    XMLPropStyleContext *pStyle = nullptr;
574
65.7k
    if( !sStyleName.isEmpty() )
575
41.0k
    {
576
41.0k
        pStyle = xTextImportHelper->FindAutoFrameStyle( sStyleName );
577
41.0k
        if( pStyle )
578
795
            sStyleName = pStyle->GetParentName();
579
41.0k
    }
580
581
65.7k
    Any aAny;
582
65.7k
    if( !sStyleName.isEmpty() )
583
41.0k
    {
584
41.0k
        OUString sDisplayStyleName( GetImport().GetStyleDisplayName(
585
41.0k
                            XmlStyleFamily::SD_GRAPHICS_ID, sStyleName ) );
586
41.0k
        const Reference < XNameContainer > & rStyles =
587
41.0k
            xTextImportHelper->GetFrameStyles();
588
41.0k
        if( rStyles.is() &&
589
41.0k
            rStyles->hasByName( sDisplayStyleName ) )
590
792
        {
591
792
            xPropSet->setPropertyValue( u"FrameStyleName"_ustr, Any(sDisplayStyleName) );
592
792
        }
593
41.0k
    }
594
595
    // anchor type (must be set before any other properties, because
596
    // otherwise some orientations cannot be set or will be changed
597
    // afterwards)
598
65.7k
    xPropSet->setPropertyValue( u"AnchorType"_ustr, Any(eAnchorType) );
599
600
    // hard properties
601
65.7k
    if( pStyle )
602
795
        pStyle->FillPropertySet( xPropSet );
603
604
    // x and y
605
65.7k
    sal_Int16 nHoriOrient =  HoriOrientation::NONE;
606
65.7k
    aAny = xPropSet->getPropertyValue( u"HoriOrient"_ustr );
607
65.7k
    aAny >>= nHoriOrient;
608
65.7k
    if( HoriOrientation::NONE == nHoriOrient )
609
244
    {
610
244
        xPropSet->setPropertyValue( u"HoriOrientPosition"_ustr, Any(nX) );
611
244
    }
612
613
65.7k
    sal_Int16 nVertOrient =  VertOrientation::NONE;
614
65.7k
    aAny = xPropSet->getPropertyValue( u"VertOrient"_ustr );
615
65.7k
    aAny >>= nVertOrient;
616
65.7k
    if( VertOrientation::NONE == nVertOrient )
617
30
    {
618
30
        xPropSet->setPropertyValue( u"VertOrientPosition"_ustr, Any(nY) );
619
30
    }
620
621
    // width
622
65.7k
    if( nWidth > 0 )
623
5.98k
    {
624
5.98k
        xPropSet->setPropertyValue( u"Width"_ustr, Any(nWidth) );
625
5.98k
    }
626
65.7k
    if( nRelWidth > 0 || nWidth > 0 )
627
6.54k
    {
628
6.54k
        xPropSet->setPropertyValue( u"RelativeWidth"_ustr, Any(nRelWidth) );
629
6.54k
    }
630
65.7k
    if( bSyncWidth || nWidth > 0 )
631
5.98k
    {
632
5.98k
        xPropSet->setPropertyValue( u"IsSyncWidthToHeight"_ustr, Any(bSyncWidth) );
633
5.98k
    }
634
65.7k
    if( xPropSetInfo->hasPropertyByName( u"WidthType"_ustr ) &&
635
22.8k
        (bMinWidth || nWidth > 0 || nRelWidth > 0 ) )
636
1.17k
    {
637
1.17k
        sal_Int16 nSizeType =
638
1.17k
            (bMinWidth && XML_TEXT_FRAME_TEXTBOX == nType) ? SizeType::MIN
639
1.17k
                                                           : SizeType::FIX;
640
1.17k
        xPropSet->setPropertyValue( u"WidthType"_ustr, Any(nSizeType) );
641
1.17k
    }
642
643
65.7k
    if( nHeight > 0 )
644
6.08k
    {
645
6.08k
        xPropSet->setPropertyValue( u"Height"_ustr, Any(nHeight) );
646
6.08k
    }
647
65.7k
    if( nRelHeight > 0 || nHeight > 0 )
648
6.08k
    {
649
6.08k
        xPropSet->setPropertyValue( u"RelativeHeight"_ustr, Any(nRelHeight) );
650
6.08k
    }
651
65.7k
    if( bSyncHeight || nHeight > 0 )
652
6.08k
    {
653
6.08k
        xPropSet->setPropertyValue( u"IsSyncHeightToWidth"_ustr, Any(bSyncHeight) );
654
6.08k
    }
655
65.7k
    if( xPropSetInfo->hasPropertyByName( u"SizeType"_ustr ) &&
656
22.8k
        (bMinHeight || nHeight > 0 || nRelHeight > 0 ) )
657
768
    {
658
768
        sal_Int16 nSizeType =
659
768
            (bMinHeight && XML_TEXT_FRAME_TEXTBOX == nType) ? SizeType::MIN
660
768
                                                            : SizeType::FIX;
661
768
        xPropSet->setPropertyValue( u"SizeType"_ustr, Any(nSizeType) );
662
768
    }
663
664
65.7k
    if( XML_TEXT_FRAME_GRAPHIC == nType )
665
42.8k
    {
666
        // URL
667
42.8k
        OSL_ENSURE( !sHRef.isEmpty() || xBase64Stream.is(),
668
42.8k
                    "neither URL nor base64 image data given" );
669
42.8k
        uno::Reference<graphic::XGraphic> xGraphic;
670
42.8k
        if (!sHRef.isEmpty())
671
42.8k
        {
672
42.8k
            xGraphic = GetImport().loadGraphicByURL(sHRef);
673
42.8k
        }
674
0
        else if (xBase64Stream.is())
675
0
        {
676
0
            xGraphic = GetImport().loadGraphicFromBase64(xBase64Stream);
677
0
            xBase64Stream = nullptr;
678
0
        }
679
680
42.8k
        if (xGraphic.is())
681
42.8k
            xPropSet->setPropertyValue(u"Graphic"_ustr, Any(xGraphic));
682
683
        // filter name
684
42.8k
        xPropSet->setPropertyValue( u"GraphicFilter"_ustr, Any(OUString()) );
685
686
        // rotation
687
42.8k
        xPropSet->setPropertyValue( u"GraphicRotation"_ustr, Any(nRotation) );
688
42.8k
    }
689
690
    // page number (must be set after the frame is inserted, because it
691
    // will be overwritten then inserting the frame.
692
65.7k
    if( TextContentAnchorType_AT_PAGE == eAnchorType && nPage > 0 )
693
159
    {
694
159
        xPropSet->setPropertyValue( u"AnchorPageNo"_ustr, Any(nPage) );
695
159
    }
696
697
65.7k
    if (m_isDecorative && xPropSetInfo->hasPropertyByName(u"Decorative"_ustr))
698
0
    {
699
0
        xPropSet->setPropertyValue(u"Decorative"_ustr, uno::Any(true));
700
0
    }
701
702
65.7k
    if (m_isSplitAllowed && xPropSetInfo->hasPropertyByName(u"IsSplitAllowed"_ustr))
703
0
    {
704
0
        xPropSet->setPropertyValue(u"IsSplitAllowed"_ustr, uno::Any(true));
705
0
    }
706
707
65.7k
    if( XML_TEXT_FRAME_OBJECT != nType  &&
708
65.7k
        XML_TEXT_FRAME_OBJECT_OLE != nType  &&
709
65.7k
        XML_TEXT_FRAME_APPLET != nType &&
710
65.7k
        XML_TEXT_FRAME_PLUGIN!= nType &&
711
65.7k
        XML_TEXT_FRAME_FLOATING_FRAME != nType)
712
65.7k
    {
713
65.7k
        Reference < XTextContent > xTxtCntnt( xPropSet, UNO_QUERY );
714
65.7k
        try
715
65.7k
        {
716
65.7k
            xTextImportHelper->InsertTextContent(xTxtCntnt);
717
65.7k
        }
718
65.7k
        catch (lang::IllegalArgumentException const&)
719
65.7k
        {
720
6.01k
            TOOLS_WARN_EXCEPTION("xmloff.text", "Cannot import part of the text - probably an image in the text frame?");
721
6.01k
            return;
722
6.01k
        }
723
65.7k
    }
724
725
    // Make adding the shape to Z-Ordering dependent from if we are
726
    // inside an inside_deleted_section (redlining). That is necessary
727
    // since the shape will be removed again later. It would lead to
728
    // errors if it would stay inside the Z-Ordering. Thus, the
729
    // easiest way to solve that conflict is to not add it here.
730
59.7k
    if(!GetImport().HasTextImport()
731
59.7k
        || !GetImport().GetTextImport()->IsInsideDeleteContext())
732
59.7k
    {
733
59.7k
        Reference < XShape > xShape( xPropSet, UNO_QUERY );
734
735
59.7k
        GetImport().GetShapeImport()->shapeWithZIndexAdded( xShape, nZIndex );
736
59.7k
    }
737
738
59.7k
    if( XML_TEXT_FRAME_TEXTBOX != nType )
739
36.8k
        return;
740
741
22.8k
    xTextImportHelper->ConnectFrameChains( sName, sNextName, xPropSet );
742
22.8k
    Reference < XTextFrame > xTxtFrame( xPropSet, UNO_QUERY );
743
22.8k
    Reference < XText > xTxt = xTxtFrame->getText();
744
22.8k
    xOldTextCursor = xTextImportHelper->GetCursor();
745
22.8k
    xTextImportHelper->SetCursor( xTxt->createTextCursor() );
746
747
    // remember old list item and block (#89892#) and reset them
748
    // for the text frame
749
22.8k
    xTextImportHelper->PushListContext();
750
22.8k
    mbListContextPushed = true;
751
22.8k
}
752
753
void XMLTextFrameContext::removeGraphicFromImportContext(const SvXMLImportContext& rContext)
754
11.2k
{
755
11.2k
    const XMLTextFrameContext_Impl* pXMLTextFrameContext_Impl = dynamic_cast< const XMLTextFrameContext_Impl* >(&rContext);
756
757
11.2k
    if(!pXMLTextFrameContext_Impl)
758
0
        return;
759
760
11.2k
    try
761
11.2k
    {
762
        // just dispose to delete
763
11.2k
        uno::Reference< lang::XComponent > xComp(pXMLTextFrameContext_Impl->GetPropSet(), UNO_QUERY);
764
765
        // Inform shape importer about the removal so it can adjust
766
        // z-indexes.
767
11.2k
        uno::Reference<drawing::XShape> xShape(xComp, uno::UNO_QUERY);
768
11.2k
        GetImport().GetShapeImport()->shapeRemoved(xShape);
769
770
11.2k
        if(xComp.is())
771
10.8k
        {
772
10.8k
            xComp->dispose();
773
10.8k
        }
774
11.2k
    }
775
11.2k
    catch( uno::Exception& )
776
11.2k
    {
777
0
        OSL_FAIL( "Error in cleanup of multiple graphic object import (!)" );
778
0
    }
779
11.2k
}
780
781
OUString XMLTextFrameContext::getMimeTypeFromImportContext(const SvXMLImportContext& rContext) const
782
11.4k
{
783
11.4k
    const XMLTextFrameContext_Impl* pXMLTextFrameContext_Impl = dynamic_cast<const XMLTextFrameContext_Impl*>(&rContext);
784
785
11.4k
    if (pXMLTextFrameContext_Impl)
786
11.4k
        return pXMLTextFrameContext_Impl->GetMimeType();
787
788
0
    return OUString();
789
11.4k
}
790
791
OUString XMLTextFrameContext::getGraphicPackageURLFromImportContext(const SvXMLImportContext& rContext) const
792
11.4k
{
793
11.4k
    const XMLTextFrameContext_Impl* pXMLTextFrameContext_Impl = dynamic_cast< const XMLTextFrameContext_Impl* >(&rContext);
794
795
11.4k
    if(pXMLTextFrameContext_Impl)
796
11.4k
    {
797
11.4k
        return "vnd.sun.star.Package:" + pXMLTextFrameContext_Impl->GetHRef();
798
11.4k
    }
799
800
0
    return OUString();
801
11.4k
}
802
803
css::uno::Reference<css::graphic::XGraphic> XMLTextFrameContext::getGraphicFromImportContext(const SvXMLImportContext& rContext) const
804
0
{
805
0
    uno::Reference<graphic::XGraphic> xGraphic;
806
807
0
    const XMLTextFrameContext_Impl* pXMLTextFrameContext_Impl = dynamic_cast<const XMLTextFrameContext_Impl*>(&rContext);
808
809
0
    if (pXMLTextFrameContext_Impl)
810
0
    {
811
0
        try
812
0
        {
813
0
            const uno::Reference<beans::XPropertySet>& xPropertySet = pXMLTextFrameContext_Impl->GetPropSet();
814
815
0
            if (xPropertySet.is())
816
0
            {
817
0
                xPropertySet->getPropertyValue(u"Graphic"_ustr) >>= xGraphic;
818
0
            }
819
0
        }
820
0
        catch (uno::Exception&)
821
0
        {}
822
0
    }
823
0
    return xGraphic;
824
0
}
825
826
bool XMLTextFrameContext_Impl::CreateIfNotThere()
827
90.2k
{
828
90.2k
    if( !xPropSet.is() &&
829
1.80k
        ( XML_TEXT_FRAME_OBJECT_OLE == nType ||
830
1.76k
          XML_TEXT_FRAME_GRAPHIC == nType ) &&
831
1.49k
        xBase64Stream.is() && !bCreateFailed )
832
38
    {
833
38
        if( bOwnBase64Stream )
834
0
            xBase64Stream->closeOutput();
835
38
        Create();
836
38
    }
837
838
90.2k
    return xPropSet.is();
839
90.2k
}
840
841
XMLTextFrameContext_Impl::XMLTextFrameContext_Impl(
842
        SvXMLImport& rImport,
843
        sal_Int32 /*nElement*/,
844
        const Reference< XFastAttributeList > & rAttrList,
845
        TextContentAnchorType eATyp,
846
        sal_uInt16 nNewType,
847
        const Reference< XFastAttributeList > & rFrameAttrList,
848
        bool bMultipleContent )
849
67.2k
:   SvXMLImportContext( rImport )
850
67.2k
,   mbListContextPushed( false )
851
67.2k
,   nType( nNewType )
852
67.2k
,   eAnchorType( eATyp )
853
67.2k
{
854
67.2k
    nX = 0;
855
67.2k
    nY = 0;
856
67.2k
    nWidth = 0;
857
67.2k
    nHeight = 0;
858
67.2k
    nZIndex = -1;
859
67.2k
    nPage = 0;
860
67.2k
    nRotation = 0;
861
67.2k
    nRelWidth = 0;
862
67.2k
    nRelHeight = 0;
863
67.2k
    bMayScript = false;
864
865
67.2k
    bMinHeight = false;
866
67.2k
    bMinWidth = false;
867
67.2k
    bSyncWidth = false;
868
67.2k
    bSyncHeight = false;
869
67.2k
    bCreateFailed = false;
870
67.2k
    bOwnBase64Stream = false;
871
67.2k
    mbMultipleContent = bMultipleContent;
872
873
67.2k
    auto processAttr = [&](sal_Int32 nElement, const sax_fastparser::FastAttributeList::FastAttributeIter& aIter) -> void
874
331k
    {
875
331k
        switch( nElement )
876
331k
        {
877
42.1k
        case XML_ELEMENT(DRAW, XML_STYLE_NAME):
878
42.1k
            sStyleName = aIter.toString();
879
42.1k
            break;
880
49.8k
        case XML_ELEMENT(DRAW, XML_NAME):
881
49.8k
            m_sOrigName = aIter.toString();
882
49.8k
            sName = m_sOrigName;
883
49.8k
            break;
884
0
        case XML_ELEMENT(DRAW, XML_FRAME_NAME):
885
0
            sFrameName = aIter.toString();
886
0
            break;
887
0
        case XML_ELEMENT(DRAW, XML_APPLET_NAME):
888
0
            sAppletName = aIter.toString();
889
0
            break;
890
47.5k
        case XML_ELEMENT(TEXT, XML_ANCHOR_TYPE):
891
47.5k
            if( TextContentAnchorType_AT_PARAGRAPH == eAnchorType ||
892
47.5k
                TextContentAnchorType_AT_CHARACTER == eAnchorType ||
893
47.4k
                TextContentAnchorType_AS_CHARACTER == eAnchorType )
894
46.9k
            {
895
896
46.9k
                TextContentAnchorType eNew;
897
46.9k
                if( XMLAnchorTypePropHdl::convert( aIter.toView(), eNew ) &&
898
39.5k
                    ( TextContentAnchorType_AT_PARAGRAPH == eNew ||
899
39.5k
                      TextContentAnchorType_AT_CHARACTER == eNew ||
900
39.5k
                      TextContentAnchorType_AS_CHARACTER == eNew ||
901
0
                      TextContentAnchorType_AT_PAGE == eNew) )
902
39.5k
                    eAnchorType = eNew;
903
46.9k
            }
904
47.5k
            break;
905
159
        case XML_ELEMENT(TEXT, XML_ANCHOR_PAGE_NUMBER):
906
159
            {
907
159
                sal_Int32 nTmp;
908
159
                sal_Int32 nMax = !comphelper::IsFuzzing() ? SHRT_MAX : 100;
909
159
                if (::sax::Converter::convertNumber(nTmp, aIter.toView(), 1, nMax))
910
159
                    nPage = static_cast<sal_Int16>(nTmp);
911
159
            }
912
159
            break;
913
0
        case XML_ELEMENT(SVG, XML_X):
914
30
        case XML_ELEMENT(SVG_COMPAT, XML_X):
915
30
            GetImport().GetMM100UnitConverter().convertMeasureToCore(
916
30
                    nX, aIter.toView());
917
30
            break;
918
0
        case XML_ELEMENT(SVG, XML_Y):
919
30
        case XML_ELEMENT(SVG_COMPAT, XML_Y):
920
30
            GetImport().GetMM100UnitConverter().convertMeasureToCore(
921
30
                    nY, aIter.toView() );
922
30
            break;
923
0
        case XML_ELEMENT(SVG, XML_WIDTH):
924
6.94k
        case XML_ELEMENT(SVG_COMPAT, XML_WIDTH):
925
            // relative widths are obsolete since SRC617. Remove them some day!
926
6.94k
            if( aIter.toView().find( '%' ) != std::string_view::npos )
927
574
            {
928
574
                sal_Int32 nTmp;
929
574
                if (::sax::Converter::convertPercent(nTmp, aIter.toView()))
930
572
                    nRelWidth = static_cast<sal_Int16>(nTmp);
931
574
            }
932
6.37k
            else
933
6.37k
            {
934
6.37k
                GetImport().GetMM100UnitConverter().convertMeasureToCore(
935
6.37k
                        nWidth, aIter.toView(), 0 );
936
6.37k
            }
937
6.94k
            break;
938
0
        case XML_ELEMENT(STYLE, XML_REL_WIDTH):
939
0
            if( IsXMLToken(aIter, XML_SCALE) )
940
0
            {
941
0
                bSyncWidth = true;
942
0
            }
943
0
            else
944
0
            {
945
0
                sal_Int32 nTmp;
946
0
                if (::sax::Converter::convertPercent( nTmp, aIter.toView() ))
947
0
                    nRelWidth = static_cast<sal_Int16>(nTmp);
948
0
            }
949
0
            break;
950
0
        case XML_ELEMENT(FO, XML_MIN_WIDTH):
951
0
        case XML_ELEMENT(FO_COMPAT, XML_MIN_WIDTH):
952
0
            if( aIter.toView().find( '%' ) != std::string_view::npos )
953
0
            {
954
0
                sal_Int32 nTmp;
955
0
                if (::sax::Converter::convertPercent(nTmp, aIter.toView()))
956
0
                    nRelWidth = static_cast<sal_Int16>(nTmp);
957
0
            }
958
0
            else
959
0
            {
960
0
                GetImport().GetMM100UnitConverter().convertMeasureToCore(
961
0
                        nWidth, aIter.toView(), 0 );
962
0
            }
963
0
            bMinWidth = true;
964
0
            break;
965
0
        case XML_ELEMENT(SVG, XML_HEIGHT):
966
6.31k
        case XML_ELEMENT(SVG_COMPAT, XML_HEIGHT):
967
            // relative heights are obsolete since SRC617. Remove them some day!
968
6.31k
            if( aIter.toView().find( '%' ) != std::string_view::npos )
969
0
            {
970
0
                sal_Int32 nTmp;
971
0
                if (::sax::Converter::convertPercent(nTmp, aIter.toView()))
972
0
                    nRelHeight = static_cast<sal_Int16>(nTmp);
973
0
            }
974
6.31k
            else
975
6.31k
            {
976
6.31k
                GetImport().GetMM100UnitConverter().convertMeasureToCore(
977
6.31k
                        nHeight, aIter.toView(), 0 );
978
6.31k
            }
979
6.31k
            break;
980
0
        case XML_ELEMENT(STYLE, XML_REL_HEIGHT):
981
0
            if( IsXMLToken( aIter, XML_SCALE ) )
982
0
            {
983
0
                bSyncHeight = true;
984
0
            }
985
0
            else if( IsXMLToken( aIter, XML_SCALE_MIN ) )
986
0
            {
987
0
                bSyncHeight = true;
988
0
                bMinHeight = true;
989
0
            }
990
0
            else
991
0
            {
992
0
                sal_Int32 nTmp;
993
0
                if (::sax::Converter::convertPercent( nTmp, aIter.toView() ))
994
0
                    nRelHeight = static_cast<sal_Int16>(nTmp);
995
0
            }
996
0
            break;
997
0
        case XML_ELEMENT(FO, XML_MIN_HEIGHT):
998
178
        case XML_ELEMENT(FO_COMPAT, XML_MIN_HEIGHT):
999
178
            if( aIter.toView().find( '%' ) != std::string_view::npos )
1000
0
            {
1001
0
                sal_Int32 nTmp;
1002
0
                if (::sax::Converter::convertPercent(nTmp, aIter.toView()))
1003
0
                    nRelHeight = static_cast<sal_Int16>(nTmp);
1004
0
            }
1005
178
            else
1006
178
            {
1007
178
                GetImport().GetMM100UnitConverter().convertMeasureToCore(
1008
178
                        nHeight, aIter.toView(), 0 );
1009
178
            }
1010
178
            bMinHeight = true;
1011
178
            break;
1012
54.1k
        case XML_ELEMENT(DRAW, XML_ZINDEX):
1013
54.1k
            ::sax::Converter::convertNumber( nZIndex, aIter.toView(), -1 );
1014
54.1k
            break;
1015
0
        case XML_ELEMENT(DRAW, XML_CHAIN_NEXT_NAME):
1016
0
            sNextName = aIter.toString();
1017
0
            break;
1018
42.8k
        case XML_ELEMENT(XLINK, XML_HREF):
1019
42.8k
            sHRef = aIter.toString();
1020
42.8k
            break;
1021
0
        case XML_ELEMENT(DRAW, XML_TRANSFORM):
1022
0
            {
1023
                // RotateFlyFrameFix: im/export full 'draw:transform' using existing tooling
1024
                // Currently only rotation is used, but combinations with 'draw:transform'
1025
                // may be necessary in the future, so that svg:x/svg:y/svg:width/svg:height
1026
                // may be extended/replaced with 'draw:transform' (see draw objects)
1027
0
                SdXMLImExTransform2D aSdXMLImExTransform2D;
1028
0
                basegfx::B2DHomMatrix aFullTransform;
1029
1030
                // Use SdXMLImExTransform2D to convert to transformation
1031
                // Note: using GetTwipUnitConverter instead of GetMM100UnitConverter may be needed,
1032
                // but is not generally available (as it should be, a 'current' UnitConverter should
1033
                // be available at GetExport() - and maybe was once). May have to be addressed as soon
1034
                // as translate transformations are used here.
1035
0
                aSdXMLImExTransform2D.SetString(aIter.toString(), GetImport().GetMM100UnitConverter());
1036
0
                aSdXMLImExTransform2D.GetFullTransform(aFullTransform);
1037
1038
0
                if(!aFullTransform.isIdentity())
1039
0
                {
1040
0
                    const basegfx::utils::B2DHomMatrixBufferedDecompose aDecomposedTransform(aFullTransform);
1041
1042
                    // currently we *only* use rotation (and translation indirectly), so warn if *any*
1043
                    // of the other transform parts is used
1044
0
                    SAL_WARN_IF(!basegfx::fTools::equal(1.0, aDecomposedTransform.getScale().getX()), "xmloff.text", "draw:transform uses scaleX" );
1045
0
                    SAL_WARN_IF(!basegfx::fTools::equal(1.0, aDecomposedTransform.getScale().getY()), "xmloff.text", "draw:transform uses scaleY" );
1046
0
                    SAL_WARN_IF(!basegfx::fTools::equalZero(aDecomposedTransform.getShearX()), "xmloff.text", "draw:transform uses shearX" );
1047
1048
                    // Translation comes from the translate to RotCenter, rot and BackTranslate.
1049
                    // This means that it represents the translation between unrotated TopLeft
1050
                    // and rotated TopLeft. This may be checked here now, but currently we only
1051
                    // use rotation around center and assume that this *was* a rotation around
1052
                    // center. The check would compare the object's center with the RotCenter
1053
                    // that can be extracted from the transformation in aFullTransform.
1054
                    // The definition contains implicitly the RotationCenter absolute
1055
                    // to the scaled and translated object, so this may be used if needed (see
1056
                    // _exportTextGraphic how the -trans/rot/trans is composed)
1057
1058
0
                    if(!basegfx::fTools::equalZero(aDecomposedTransform.getRotate()))
1059
0
                    {
1060
                        // rotation is used, set it. Convert from deg to 10th degree integer
1061
                        // CAUTION: due to #i78696# (rotation mirrored using API) the rotate
1062
                        // value is already mirrored, so do not do it again here (to be in sync
1063
                        // with XMLTextParagraphExport::_exportTextGraphic normally it would need
1064
                        // to me mirrored using * -1.0, see conversion there)
1065
                        // CAUTION-II: due to tdf#115782 it is better for current ODF to indeed use it
1066
                        // with the wrong orientation as in all other cases - ARGH! We will need to
1067
                        // correct this in future ODF ASAP! For now, mirror the rotation here AGAIN
1068
0
                        const double fRotate(-basegfx::rad2deg<10>(aDecomposedTransform.getRotate()));
1069
0
                        nRotation = static_cast< sal_Int16 >(basegfx::fround(fRotate) % 3600);
1070
1071
                        // tdf#115529 may be negative, with the above modulo maximal -3599, so
1072
                        // no loop needed here. nRotation is used in setPropertyValue("GraphicRotation")
1073
                        // and *has* to be in the range [0 .. 3600[
1074
0
                        if(nRotation < 0)
1075
0
                        {
1076
0
                            nRotation += 3600;
1077
0
                        }
1078
0
                    }
1079
0
                }
1080
0
            }
1081
0
            break;
1082
0
        case XML_ELEMENT(DRAW, XML_CODE):
1083
0
            sCode = aIter.toString();
1084
0
            break;
1085
0
        case XML_ELEMENT(DRAW, XML_OBJECT):
1086
0
            break;
1087
0
        case XML_ELEMENT(DRAW, XML_ARCHIVE):
1088
0
            break;
1089
0
        case XML_ELEMENT(DRAW, XML_MAY_SCRIPT):
1090
0
            bMayScript = IsXMLToken( aIter, XML_TRUE );
1091
0
            break;
1092
0
        case XML_ELEMENT(DRAW, XML_MIME_TYPE):
1093
0
        case XML_ELEMENT(LO_EXT, XML_MIME_TYPE):
1094
0
            sMimeType = aIter.toString();
1095
0
            break;
1096
0
        case XML_ELEMENT(DRAW, XML_NOTIFY_ON_UPDATE_OF_RANGES):
1097
0
        case XML_ELEMENT(DRAW, XML_NOTIFY_ON_UPDATE_OF_TABLE):
1098
0
            sTblName = aIter.toString();
1099
0
            break;
1100
0
        case XML_ELEMENT(LO_EXT, XML_DECORATIVE):
1101
0
        case XML_ELEMENT(DRAW, XML_DECORATIVE):
1102
0
            ::sax::Converter::convertBool(m_isDecorative, aIter.toString());
1103
0
            break;
1104
0
        case XML_ELEMENT(LO_EXT, XML_MAY_BREAK_BETWEEN_PAGES):
1105
0
        case XML_ELEMENT(DRAW, XML_MAY_BREAK_BETWEEN_PAGES):
1106
0
            sax::Converter::convertBool(m_isSplitAllowed, aIter.toString());
1107
0
            break;
1108
81.2k
        default:
1109
81.2k
            SAL_INFO("xmloff", "unknown attribute " << SvXMLImport::getPrefixAndNameFromToken(aIter.getToken()) << " value=" << aIter.toString());
1110
331k
        }
1111
331k
    };
1112
1113
67.2k
    for( auto& aIter : sax_fastparser::castToFastAttributeList(rAttrList) )
1114
124k
            processAttr(aIter.getToken(), aIter);
1115
67.2k
    for( auto& aIter : sax_fastparser::castToFastAttributeList(rFrameAttrList) )
1116
207k
            processAttr(aIter.getToken(), aIter);
1117
1118
67.2k
    if( ( (XML_TEXT_FRAME_GRAPHIC == nType ||
1119
23.1k
           XML_TEXT_FRAME_OBJECT == nType ||
1120
23.0k
           XML_TEXT_FRAME_OBJECT_OLE == nType) &&
1121
44.1k
          sHRef.isEmpty() ) ||
1122
65.8k
        ( XML_TEXT_FRAME_APPLET  == nType && sCode.isEmpty() ) ||
1123
65.8k
        ( XML_TEXT_FRAME_PLUGIN == nType &&
1124
0
          sHRef.isEmpty() && sMimeType.isEmpty() ) )
1125
1.32k
        return; // no URL: no image or OLE object
1126
1127
65.8k
    Create();
1128
65.8k
}
1129
1130
void XMLTextFrameContext_Impl::endFastElement(sal_Int32 )
1131
66.4k
{
1132
66.4k
    if( ( XML_TEXT_FRAME_OBJECT_OLE == nType ||
1133
66.4k
          XML_TEXT_FRAME_GRAPHIC == nType) &&
1134
44.0k
        !xPropSet.is() && !bCreateFailed )
1135
1.26k
    {
1136
1.26k
        std::u16string_view sTrimmedChars = o3tl::trim(maUrlBuffer);
1137
1.26k
        if( !sTrimmedChars.empty() )
1138
0
        {
1139
0
            if( !xBase64Stream.is() )
1140
0
            {
1141
0
                if( XML_TEXT_FRAME_GRAPHIC == nType )
1142
0
                {
1143
0
                    xBase64Stream =
1144
0
                        GetImport().GetStreamForGraphicObjectURLFromBase64();
1145
0
                }
1146
0
                else
1147
0
                {
1148
0
                    xBase64Stream =
1149
0
                        GetImport().GetStreamForEmbeddedObjectURLFromBase64();
1150
0
                }
1151
0
                if( xBase64Stream.is() )
1152
0
                    bOwnBase64Stream = true;
1153
0
            }
1154
0
            if( bOwnBase64Stream && xBase64Stream.is() )
1155
0
            {
1156
0
                OUString sChars;
1157
0
                if( !sBase64CharsLeft.isEmpty() )
1158
0
                {
1159
0
                    sChars = sBase64CharsLeft + sTrimmedChars;
1160
0
                    sBase64CharsLeft.clear();
1161
0
                }
1162
0
                else
1163
0
                {
1164
0
                    sChars = sTrimmedChars;
1165
0
                }
1166
0
                Sequence< sal_Int8 > aBuffer( (sChars.getLength() / 4) * 3 );
1167
0
                sal_Int32 nCharsDecoded =
1168
0
                    ::comphelper::Base64::decodeSomeChars( aBuffer, sChars );
1169
0
                xBase64Stream->writeBytes( aBuffer );
1170
0
                if( nCharsDecoded != sChars.getLength() )
1171
0
                    sBase64CharsLeft = sChars.copy( nCharsDecoded );
1172
0
            }
1173
0
        }
1174
1.26k
        maUrlBuffer.setLength(0);
1175
1.26k
    }
1176
1177
66.4k
    CreateIfNotThere();
1178
1179
66.4k
    if( xOldTextCursor.is() )
1180
22.2k
    {
1181
22.2k
        GetImport().GetTextImport()->DeleteParagraph();
1182
22.2k
        GetImport().GetTextImport()->SetCursor( xOldTextCursor );
1183
22.2k
    }
1184
1185
    // reinstall old list item (if necessary) #89892#
1186
66.4k
    if (mbListContextPushed) {
1187
22.2k
        GetImport().GetTextImport()->PopListContext();
1188
22.2k
    }
1189
1190
66.4k
    if (( nType == XML_TEXT_FRAME_APPLET || nType == XML_TEXT_FRAME_PLUGIN ) && xPropSet.is())
1191
0
        GetImport().GetTextImport()->endAppletOrPlugin( xPropSet, aParamMap);
1192
66.4k
}
1193
1194
css::uno::Reference< css::xml::sax::XFastContextHandler > XMLTextFrameContext_Impl::createFastChildContext(
1195
    sal_Int32 nElement,
1196
    const css::uno::Reference< css::xml::sax::XFastAttributeList >& xAttrList )
1197
15.6k
{
1198
15.6k
    if( nElement == XML_ELEMENT(DRAW, XML_PARAM) )
1199
0
    {
1200
0
        if ( nType == XML_TEXT_FRAME_APPLET || nType == XML_TEXT_FRAME_PLUGIN )
1201
0
            return new XMLTextFrameParam_Impl( GetImport(),
1202
0
                                               xAttrList, aParamMap );
1203
0
    }
1204
15.6k
    else if( nElement == XML_ELEMENT(OFFICE, XML_BINARY_DATA) )
1205
55
    {
1206
55
        if( !xPropSet.is() && !xBase64Stream.is() && !bCreateFailed )
1207
55
        {
1208
55
            switch( nType )
1209
55
            {
1210
0
            case XML_TEXT_FRAME_GRAPHIC:
1211
0
                xBase64Stream =
1212
0
                    GetImport().GetStreamForGraphicObjectURLFromBase64();
1213
0
                break;
1214
55
            case XML_TEXT_FRAME_OBJECT_OLE:
1215
55
                xBase64Stream =
1216
55
                    GetImport().GetStreamForEmbeddedObjectURLFromBase64();
1217
55
                break;
1218
55
            }
1219
55
            if( xBase64Stream.is() )
1220
55
                return new XMLBase64ImportContext( GetImport(), xBase64Stream );
1221
55
        }
1222
55
    }
1223
    // Correction of condition which also avoids warnings. (#i100480#)
1224
15.6k
    if( XML_TEXT_FRAME_OBJECT == nType &&
1225
45
        ( nElement == XML_ELEMENT(OFFICE, XML_DOCUMENT) ||
1226
45
          nElement == XML_ELEMENT(MATH, XML_MATH) ) )
1227
45
    {
1228
45
        if( !xPropSet.is() && !bCreateFailed )
1229
45
        {
1230
45
            XMLEmbeddedObjectImportContext *pEContext =
1231
45
                new XMLEmbeddedObjectImportContext( GetImport(), nElement, xAttrList );
1232
45
            sFilterService = pEContext->GetFilterServiceName();
1233
45
            if( !sFilterService.isEmpty() )
1234
45
            {
1235
45
                Create();
1236
45
                if( xPropSet.is() )
1237
0
                {
1238
0
                    Reference < XEmbeddedObjectSupplier > xEOS( xPropSet,
1239
0
                                                                UNO_QUERY );
1240
0
                    OSL_ENSURE( xEOS.is(),
1241
0
                            "no embedded object supplier for own object" );
1242
0
                    Reference<css::lang::XComponent> aXComponent(xEOS->getEmbeddedObject());
1243
0
                    pEContext->SetComponent( aXComponent );
1244
0
                }
1245
45
            }
1246
45
            return pEContext;
1247
45
        }
1248
45
    }
1249
1250
15.5k
    if( xOldTextCursor.is() )  // text-box
1251
15.0k
    {
1252
15.0k
        auto p = GetImport().GetTextImport()->CreateTextChildContext(
1253
15.0k
                            GetImport(), nElement, xAttrList,
1254
15.0k
                            XMLTextType::TextBox );
1255
15.0k
        if (p)
1256
15.0k
            return p;
1257
15.0k
    }
1258
1259
540
    XMLOFF_WARN_UNKNOWN_ELEMENT("xmloff", nElement);
1260
1261
540
    return nullptr;
1262
540
}
1263
1264
void XMLTextFrameContext_Impl::characters( const OUString& rChars )
1265
35.5k
{
1266
35.5k
    maUrlBuffer.append(rChars);
1267
35.5k
}
1268
1269
void XMLTextFrameContext_Impl::SetHyperlink( const OUString& rHRef,
1270
                       const OUString& rName,
1271
                       const OUString& rTargetFrameName,
1272
                       bool bMap )
1273
0
{
1274
0
    static constexpr OUString s_HyperLinkURL = u"HyperLinkURL"_ustr;
1275
0
    static constexpr OUString s_HyperLinkName = u"HyperLinkName"_ustr;
1276
0
    static constexpr OUString s_HyperLinkTarget = u"HyperLinkTarget"_ustr;
1277
0
    static constexpr OUString s_ServerMap = u"ServerMap"_ustr;
1278
0
    if( !xPropSet.is() )
1279
0
        return;
1280
1281
0
    Reference < XPropertySetInfo > xPropSetInfo =
1282
0
        xPropSet->getPropertySetInfo();
1283
0
    if( !xPropSetInfo.is() ||
1284
0
        !xPropSetInfo->hasPropertyByName(s_HyperLinkURL))
1285
0
        return;
1286
1287
0
    xPropSet->setPropertyValue( s_HyperLinkURL, Any(rHRef) );
1288
1289
0
    if (xPropSetInfo->hasPropertyByName(s_HyperLinkName))
1290
0
    {
1291
0
        xPropSet->setPropertyValue(s_HyperLinkName, Any(rName));
1292
0
    }
1293
1294
0
    if (xPropSetInfo->hasPropertyByName(s_HyperLinkTarget))
1295
0
    {
1296
0
        xPropSet->setPropertyValue( s_HyperLinkTarget, Any(rTargetFrameName) );
1297
0
    }
1298
1299
0
    if (xPropSetInfo->hasPropertyByName(s_ServerMap))
1300
0
    {
1301
0
        xPropSet->setPropertyValue(s_ServerMap, Any(bMap));
1302
0
    }
1303
0
}
1304
1305
void XMLTextFrameContext_Impl::SetName()
1306
1.30k
{
1307
1.30k
    Reference<XNamed> xNamed(xPropSet, UNO_QUERY);
1308
1.30k
    if (m_sOrigName.isEmpty() || !xNamed.is())
1309
924
        return;
1310
1311
379
    OUString const name(xNamed->getName());
1312
379
    if (name != m_sOrigName)
1313
135
    {
1314
135
        try
1315
135
        {
1316
135
            xNamed->setName(m_sOrigName);
1317
135
        }
1318
135
        catch (uno::Exception const&)
1319
135
        {   // fdo#71698 document contains 2 frames with same draw:name
1320
134
            TOOLS_INFO_EXCEPTION("xmloff.text", "SetName(): exception setting \""
1321
134
                    << m_sOrigName << "\"");
1322
134
        }
1323
135
    }
1324
379
}
1325
1326
// Implement Title/Description Elements UI (#i73249#)
1327
void XMLTextFrameContext_Impl::SetTitle( const OUString& rTitle )
1328
0
{
1329
0
    if ( xPropSet.is() )
1330
0
    {
1331
0
        Reference< XPropertySetInfo > xPropSetInfo = xPropSet->getPropertySetInfo();
1332
0
        if( xPropSetInfo->hasPropertyByName( u"Title"_ustr ) )
1333
0
        {
1334
0
            xPropSet->setPropertyValue( u"Title"_ustr, Any( rTitle ) );
1335
0
        }
1336
0
    }
1337
0
}
1338
1339
void XMLTextFrameContext_Impl::SetDesc( const OUString& rDesc )
1340
0
{
1341
0
    if ( xPropSet.is() )
1342
0
    {
1343
0
        Reference< XPropertySetInfo > xPropSetInfo = xPropSet->getPropertySetInfo();
1344
0
        if( xPropSetInfo->hasPropertyByName( u"Description"_ustr ) )
1345
0
        {
1346
0
            xPropSet->setPropertyValue( u"Description"_ustr, Any( rDesc ) );
1347
0
        }
1348
0
    }
1349
0
}
1350
1351
1352
bool XMLTextFrameContext::CreateIfNotThere( css::uno::Reference < css::beans::XPropertySet >& rPropSet )
1353
81
{
1354
81
    SvXMLImportContext *pContext = m_xImplContext.get();
1355
81
    XMLTextFrameContext_Impl *pImpl = dynamic_cast< XMLTextFrameContext_Impl*>( pContext );
1356
81
    if( pImpl && pImpl->CreateIfNotThere() )
1357
38
        rPropSet = pImpl->GetPropSet();
1358
1359
81
    return rPropSet.is();
1360
81
}
1361
1362
XMLTextFrameContext::XMLTextFrameContext(
1363
        SvXMLImport& rImport,
1364
        const Reference< XFastAttributeList > & xAttrList,
1365
        TextContentAnchorType eATyp )
1366
26.3k
:   SvXMLImportContext( rImport )
1367
26.3k
,   m_xAttrList( new sax_fastparser::FastAttributeList( xAttrList ) )
1368
    // Implement Title/Description Elements UI (#i73249#)
1369
26.3k
,   m_eDefaultAnchorType( eATyp )
1370
    // Shapes in Writer cannot be named via context menu (#i51726#)
1371
26.3k
,   m_HasAutomaticStyleWithoutParentStyle( false )
1372
26.3k
,   m_bSupportsReplacement( false )
1373
26.3k
{
1374
26.3k
    for( auto& aIter : sax_fastparser::castToFastAttributeList(xAttrList) )
1375
62.2k
    {
1376
        // New distinguish attribute between Writer objects and Draw objects is:
1377
        // Draw objects have an automatic style without a parent style (#i51726#)
1378
62.2k
        switch (aIter.getToken())
1379
62.2k
        {
1380
11.3k
            case XML_ELEMENT(DRAW, XML_STYLE_NAME):
1381
11.3k
            {
1382
11.3k
                OUString aStyleName = aIter.toString();
1383
11.3k
                if( !aStyleName.isEmpty() )
1384
11.3k
                {
1385
11.3k
                    rtl::Reference < XMLTextImportHelper > xTxtImport =
1386
11.3k
                                                        GetImport().GetTextImport();
1387
11.3k
                    XMLPropStyleContext* pStyle = xTxtImport->FindAutoFrameStyle( aStyleName );
1388
11.3k
                    if ( pStyle && pStyle->GetParentName().isEmpty() )
1389
1.25k
                    {
1390
1.25k
                        m_HasAutomaticStyleWithoutParentStyle = true;
1391
1.25k
                    }
1392
11.3k
                }
1393
11.3k
                break;
1394
0
            }
1395
12.9k
            case XML_ELEMENT(TEXT, XML_ANCHOR_TYPE):
1396
12.9k
            {
1397
12.9k
                TextContentAnchorType eNew;
1398
12.9k
                if( XMLAnchorTypePropHdl::convert( aIter.toView(), eNew ) &&
1399
12.2k
                    ( TextContentAnchorType_AT_PARAGRAPH == eNew ||
1400
12.2k
                      TextContentAnchorType_AT_CHARACTER == eNew ||
1401
12.2k
                      TextContentAnchorType_AS_CHARACTER == eNew ||
1402
172
                      TextContentAnchorType_AT_PAGE == eNew) )
1403
12.2k
                    m_eDefaultAnchorType = eNew;
1404
12.9k
                break;
1405
0
            }
1406
62.2k
        }
1407
62.2k
    }
1408
26.3k
}
1409
1410
void XMLTextFrameContext::endFastElement(sal_Int32 )
1411
24.7k
{
1412
    /// solve if multiple image child contexts were imported
1413
24.7k
    SvXMLImportContextRef const pMultiContext(solveMultipleImages());
1414
1415
24.7k
    SvXMLImportContext const*const pContext =
1416
24.7k
        (pMultiContext.is()) ? pMultiContext.get() : m_xImplContext.get();
1417
24.7k
    XMLTextFrameContext_Impl *pImpl = const_cast<XMLTextFrameContext_Impl*>(dynamic_cast< const XMLTextFrameContext_Impl*>( pContext ));
1418
24.7k
    assert(!pMultiContext.is() || pImpl);
1419
1420
    // When we are dealing with a textbox, pImpl will be null;
1421
    // we need to set the hyperlink to the shape instead
1422
24.7k
    Reference<XShape> xShape = GetShape();
1423
24.7k
    if (xShape.is() && m_pHyperlink)
1424
0
    {
1425
0
        Reference<XPropertySet> xProps(xShape, UNO_QUERY);
1426
0
        if (xProps.is())
1427
0
            xProps->setPropertyValue(u"Hyperlink"_ustr, Any(m_pHyperlink->GetHRef()));
1428
0
    }
1429
1430
24.7k
    if( !pImpl )
1431
1.12k
        return;
1432
1433
23.6k
    pImpl->CreateIfNotThere();
1434
1435
    // fdo#68839: in case the surviving image was not the first one,
1436
    // it will have a counter added to its name - set the original name
1437
23.6k
    if (pMultiContext.is()) // do this only when necessary; esp. not for text
1438
1.30k
    {                  // frames that may have entries in GetRenameMap()!
1439
1.30k
        pImpl->SetName();
1440
1.30k
    }
1441
1442
23.6k
    if( !m_sTitle.isEmpty() )
1443
0
    {
1444
0
        pImpl->SetTitle( m_sTitle );
1445
0
    }
1446
23.6k
    if( !m_sDesc.isEmpty() )
1447
0
    {
1448
0
        pImpl->SetDesc( m_sDesc );
1449
0
    }
1450
1451
23.6k
    if( m_pHyperlink )
1452
0
    {
1453
0
        pImpl->SetHyperlink( m_pHyperlink->GetHRef(), m_pHyperlink->GetName(),
1454
0
                      m_pHyperlink->GetTargetFrameName(), m_pHyperlink->GetMap() );
1455
0
        m_pHyperlink.reset();
1456
0
    }
1457
1458
23.6k
    GetImport().GetTextImport()->StoreLastImportedFrameName(pImpl->GetOrigName());
1459
23.6k
}
1460
1461
css::uno::Reference< css::xml::sax::XFastContextHandler > XMLTextFrameContext::createFastChildContext(
1462
    sal_Int32 nElement,
1463
    const uno::Reference< xml::sax::XFastAttributeList>& xAttrList )
1464
80.5k
{
1465
80.5k
    SvXMLImportContextRef xContext;
1466
1467
80.5k
    if( !m_xImplContext.is() )
1468
36.9k
    {
1469
        // no child exists
1470
36.9k
        if( IsTokenInNamespace(nElement, XML_NAMESPACE_DRAW) )
1471
26.2k
        {
1472
26.2k
            sal_uInt16 nFrameType = USHRT_MAX;
1473
26.2k
            switch (nElement & TOKEN_MASK)
1474
26.2k
            {
1475
24.0k
                case XML_TEXT_BOX:
1476
24.0k
                    nFrameType = XML_TEXT_FRAME_TEXTBOX;
1477
24.0k
                    break;
1478
1.97k
                case XML_IMAGE:
1479
1.97k
                    nFrameType = XML_TEXT_FRAME_GRAPHIC;
1480
1.97k
                    break;
1481
45
                case XML_OBJECT:
1482
45
                    nFrameType = XML_TEXT_FRAME_OBJECT;
1483
45
                    break;
1484
55
                case XML_OBJECT_OLE:
1485
55
                    nFrameType = XML_TEXT_FRAME_OBJECT_OLE;
1486
55
                    break;
1487
0
                case XML_APPLET:
1488
0
                    nFrameType = XML_TEXT_FRAME_APPLET;
1489
0
                    break;
1490
0
                case XML_PLUGIN:
1491
0
                    nFrameType = XML_TEXT_FRAME_PLUGIN;
1492
0
                    break;
1493
0
                case XML_FLOATING_FRAME:
1494
0
                    nFrameType = XML_TEXT_FRAME_FLOATING_FRAME;
1495
0
                    break;
1496
26.2k
            }
1497
1498
26.2k
            if( USHRT_MAX != nFrameType )
1499
26.1k
            {
1500
                // Shapes in Writer cannot be named via context menu (#i51726#)
1501
26.1k
                if ( ( XML_TEXT_FRAME_TEXTBOX == nFrameType ||
1502
2.07k
                       XML_TEXT_FRAME_GRAPHIC == nFrameType ) &&
1503
26.0k
                     m_HasAutomaticStyleWithoutParentStyle )
1504
1.19k
                {
1505
1.19k
                    Reference < XShapes > xShapes;
1506
1.19k
                    xContext = XMLShapeImportHelper::CreateFrameChildContext(
1507
1.19k
                                    GetImport(), nElement, xAttrList, xShapes, m_xAttrList );
1508
1.19k
                }
1509
24.9k
                else if( XML_TEXT_FRAME_PLUGIN == nFrameType )
1510
0
                {
1511
0
                    bool bMedia = false;
1512
1513
                    // check, if we have a media object
1514
0
                    for( auto& aIter : sax_fastparser::castToFastAttributeList(xAttrList) )
1515
0
                    {
1516
0
                        if( aIter.getToken() == XML_ELEMENT(DRAW, XML_MIME_TYPE) )
1517
0
                        {
1518
0
                            if (::comphelper::IsMediaMimeType(aIter.toView()))
1519
0
                                bMedia = true;
1520
1521
                            // leave this loop
1522
0
                            break;
1523
0
                        }
1524
0
                    }
1525
1526
0
                    if( bMedia )
1527
0
                    {
1528
0
                        Reference < XShapes > xShapes;
1529
0
                        xContext = XMLShapeImportHelper::CreateFrameChildContext(
1530
0
                                        GetImport(), nElement, xAttrList, xShapes, m_xAttrList );
1531
0
                    }
1532
0
                }
1533
24.9k
                else if( XML_TEXT_FRAME_OBJECT == nFrameType ||
1534
24.8k
                         XML_TEXT_FRAME_OBJECT_OLE == nFrameType )
1535
100
                {
1536
100
                    m_bSupportsReplacement = true;
1537
100
                }
1538
24.8k
                else if(XML_TEXT_FRAME_GRAPHIC == nFrameType)
1539
1.79k
                {
1540
1.79k
                    setSupportsMultipleContents( (nElement & TOKEN_MASK) == XML_IMAGE );
1541
1.79k
                }
1542
1543
26.1k
                if (!xContext)
1544
24.9k
                {
1545
24.9k
                    xContext = new XMLTextFrameContext_Impl( GetImport(), nElement,
1546
24.9k
                                                        xAttrList,
1547
24.9k
                                                        m_eDefaultAnchorType,
1548
24.9k
                                                        nFrameType,
1549
24.9k
                                                        m_xAttrList );
1550
24.9k
                }
1551
1552
26.1k
                m_xImplContext = xContext;
1553
1554
26.1k
                if(getSupportsMultipleContents() && XML_TEXT_FRAME_GRAPHIC == nFrameType)
1555
1.79k
                {
1556
1.79k
                    addContent(*m_xImplContext);
1557
1.79k
                }
1558
26.1k
            }
1559
26.2k
        }
1560
36.9k
    }
1561
43.5k
    else if(getSupportsMultipleContents() && nElement == XML_ELEMENT(DRAW, XML_IMAGE))
1562
42.2k
    {
1563
        // read another image
1564
42.2k
        xContext = new XMLTextFrameContext_Impl(
1565
42.2k
            GetImport(), nElement, xAttrList,
1566
42.2k
            m_eDefaultAnchorType, XML_TEXT_FRAME_GRAPHIC, m_xAttrList, true);
1567
1568
42.2k
        m_xImplContext = xContext;
1569
42.2k
        addContent(*m_xImplContext);
1570
42.2k
    }
1571
1.28k
    else if( m_bSupportsReplacement && !m_xReplImplContext.is() &&
1572
81
             nElement == XML_ELEMENT(DRAW, XML_IMAGE) )
1573
81
    {
1574
        // read replacement image
1575
81
        Reference < XPropertySet > xPropSet;
1576
81
        if( CreateIfNotThere( xPropSet ) )
1577
38
        {
1578
38
            xContext = new XMLReplacementImageContext( GetImport(),
1579
38
                                nElement, xAttrList, xPropSet );
1580
38
            m_xReplImplContext = xContext;
1581
38
        }
1582
81
    }
1583
1.20k
    else if( nullptr != dynamic_cast< const XMLTextFrameContext_Impl*>( m_xImplContext.get() ))
1584
1.11k
    {
1585
        // the child is a writer frame
1586
1.11k
        if( IsTokenInNamespace(nElement, XML_NAMESPACE_SVG) ||
1587
1.11k
            IsTokenInNamespace(nElement, XML_NAMESPACE_SVG_COMPAT) )
1588
0
        {
1589
            // Implement Title/Description Elements UI (#i73249#)
1590
0
            const bool bOld = SvXMLImport::OOo_2x >= GetImport().getGeneratorVersion();
1591
0
            if ( bOld )
1592
0
            {
1593
0
                if ( (nElement & TOKEN_MASK) == XML_DESC )
1594
0
                {
1595
0
                    xContext = new XMLTextFrameTitleOrDescContext_Impl( GetImport(),
1596
0
                                                                        m_sTitle );
1597
0
                }
1598
0
            }
1599
0
            else
1600
0
            {
1601
0
                if( (nElement & TOKEN_MASK) == XML_TITLE )
1602
0
                {
1603
0
                    if (getSupportsMultipleContents())
1604
0
                    {   // tdf#103567 ensure props are set on surviving shape
1605
0
                        m_xImplContext = solveMultipleImages();
1606
0
                    }
1607
0
                    xContext = new XMLTextFrameTitleOrDescContext_Impl( GetImport(),
1608
0
                                                                        m_sTitle );
1609
0
                }
1610
0
                else if ( (nElement & TOKEN_MASK) == XML_DESC )
1611
0
                {
1612
0
                    if (getSupportsMultipleContents())
1613
0
                    {   // tdf#103567 ensure props are set on surviving shape
1614
0
                        m_xImplContext = solveMultipleImages();
1615
0
                    }
1616
0
                    xContext = new XMLTextFrameTitleOrDescContext_Impl( GetImport(),
1617
0
                                                                        m_sDesc );
1618
0
                }
1619
0
            }
1620
0
        }
1621
1.11k
        else if( IsTokenInNamespace(nElement, XML_NAMESPACE_DRAW) )
1622
854
        {
1623
854
            Reference < XPropertySet > xPropSet;
1624
854
            if( (nElement & TOKEN_MASK) == XML_CONTOUR_POLYGON )
1625
0
            {
1626
0
                if (getSupportsMultipleContents())
1627
0
                {   // tdf#103567 ensure props are set on surviving shape
1628
0
                    m_xImplContext = solveMultipleImages();
1629
0
                }
1630
0
                if( CreateIfNotThere( xPropSet ) )
1631
0
                    xContext = new XMLTextFrameContourContext_Impl( GetImport(), nElement,
1632
0
                                                  xAttrList, xPropSet, false );
1633
0
            }
1634
854
            else if( (nElement & TOKEN_MASK) == XML_CONTOUR_PATH )
1635
0
            {
1636
0
                if (getSupportsMultipleContents())
1637
0
                {   // tdf#103567 ensure props are set on surviving shape
1638
0
                    m_xImplContext = solveMultipleImages();
1639
0
                }
1640
0
                if( CreateIfNotThere( xPropSet ) )
1641
0
                    xContext = new XMLTextFrameContourContext_Impl( GetImport(), nElement,
1642
0
                                                  xAttrList, xPropSet, true );
1643
0
            }
1644
854
            else if( (nElement & TOKEN_MASK) == XML_IMAGE_MAP )
1645
0
            {
1646
0
                if (getSupportsMultipleContents())
1647
0
                {   // tdf#103567 ensure props are set on surviving shape
1648
0
                    m_xImplContext = solveMultipleImages();
1649
0
                }
1650
0
                if( CreateIfNotThere( xPropSet ) )
1651
0
                    xContext = new XMLImageMapContext( GetImport(), xPropSet );
1652
0
            }
1653
854
        }
1654
264
        else if( nElement == XML_ELEMENT(OFFICE, XML_EVENT_LISTENERS) )
1655
0
        {
1656
0
            if (getSupportsMultipleContents())
1657
0
            {   // tdf#103567 ensure props are set on surviving shape
1658
0
                m_xImplContext = solveMultipleImages();
1659
0
            }
1660
            // do we still have the frame object?
1661
0
            Reference < XPropertySet > xPropSet;
1662
0
            if( CreateIfNotThere( xPropSet ) )
1663
0
            {
1664
                // is it an event supplier?
1665
0
                Reference<XEventsSupplier> xEventsSupplier(xPropSet, UNO_QUERY);
1666
0
                if (xEventsSupplier.is())
1667
0
                {
1668
                    // OK, we have the events, so create the context
1669
0
                    xContext = new XMLEventsImportContext(GetImport(), xEventsSupplier);
1670
0
                }
1671
0
            }
1672
0
        }
1673
1.11k
    }
1674
    // #i68101#
1675
90
    else if( nElement == XML_ELEMENT(SVG, XML_TITLE) || nElement == XML_ELEMENT(SVG, XML_DESC ) ||
1676
90
             nElement == XML_ELEMENT(SVG_COMPAT, XML_TITLE) || nElement == XML_ELEMENT(SVG_COMPAT, XML_DESC ) )
1677
0
    {
1678
0
        if (getSupportsMultipleContents())
1679
0
        {   // tdf#103567 ensure props are set on surviving shape
1680
            // note: no more draw:image can be added once we get here
1681
0
            m_xImplContext = solveMultipleImages();
1682
0
        }
1683
0
        xContext = static_cast<SvXMLImportContext*>(m_xImplContext->createFastChildContext( nElement, xAttrList ).get());
1684
0
    }
1685
90
    else if (nElement == XML_ELEMENT(LO_EXT, XML_SIGNATURELINE))
1686
0
    {
1687
0
        if (getSupportsMultipleContents())
1688
0
        {   // tdf#103567 ensure props are set on surviving shape
1689
            // note: no more draw:image can be added once we get here
1690
0
            m_xImplContext = solveMultipleImages();
1691
0
        }
1692
0
        xContext = static_cast<SvXMLImportContext*>(m_xImplContext->createFastChildContext(nElement, xAttrList).get());
1693
0
    }
1694
90
    else if (nElement == XML_ELEMENT(LO_EXT, XML_QRCODE))
1695
0
    {
1696
0
        if (getSupportsMultipleContents())
1697
0
        {   // tdf#103567 ensure props are set on surviving shape
1698
            // note: no more draw:image can be added once we get here
1699
0
            m_xImplContext = solveMultipleImages();
1700
0
        }
1701
0
        xContext = static_cast<SvXMLImportContext*>(m_xImplContext->createFastChildContext(nElement, xAttrList).get());
1702
0
    }
1703
90
    else if (nElement == XML_ELEMENT(DRAW, XML_A))
1704
0
    {
1705
0
        xContext = static_cast<SvXMLImportContext*>(m_xImplContext->createFastChildContext(nElement, xAttrList).get());
1706
0
    }
1707
90
    else
1708
90
    {
1709
        // the child is a drawing shape
1710
90
        return XMLShapeImportHelper::CreateFrameChildContext(
1711
90
                                    m_xImplContext.get(), nElement, xAttrList );
1712
90
    }
1713
1714
80.4k
    return xContext;
1715
80.5k
}
1716
1717
void XMLTextFrameContext::SetHyperlink( const OUString& rHRef,
1718
                       const OUString& rName,
1719
                       const OUString& rTargetFrameName,
1720
                       bool bMap )
1721
0
{
1722
0
    OSL_ENSURE( !m_pHyperlink, "recursive SetHyperlink call" );
1723
0
    m_pHyperlink = std::make_unique<XMLTextFrameContextHyperlink_Impl>(
1724
0
                rHRef, rName, rTargetFrameName, bMap );
1725
0
}
1726
1727
TextContentAnchorType XMLTextFrameContext::GetAnchorType() const
1728
17.6k
{
1729
17.6k
    SvXMLImportContext *pContext = m_xImplContext.get();
1730
17.6k
    XMLTextFrameContext_Impl *pImpl = dynamic_cast< XMLTextFrameContext_Impl*>( pContext );
1731
17.6k
    if( pImpl )
1732
5
        return pImpl->GetAnchorType();
1733
17.6k
    else
1734
17.6k
        return m_eDefaultAnchorType;
1735
17.6k
}
1736
1737
Reference < XTextContent > XMLTextFrameContext::GetTextContent() const
1738
5
{
1739
5
    Reference < XTextContent > xTxtCntnt;
1740
5
    SvXMLImportContext *pContext = m_xImplContext.get();
1741
5
    XMLTextFrameContext_Impl *pImpl = dynamic_cast< XMLTextFrameContext_Impl* >( pContext );
1742
5
    if( pImpl )
1743
5
        xTxtCntnt.set( pImpl->GetPropSet(), UNO_QUERY );
1744
1745
5
    return xTxtCntnt;
1746
5
}
1747
1748
Reference < XShape > XMLTextFrameContext::GetShape() const
1749
24.7k
{
1750
24.7k
    Reference < XShape > xShape;
1751
24.7k
    SvXMLImportContext* pContext = m_xImplContext.get();
1752
24.7k
    SvXMLShapeContext* pImpl = dynamic_cast<SvXMLShapeContext*>( pContext  );
1753
24.7k
    if ( pImpl )
1754
973
    {
1755
973
        xShape = pImpl->getShape();
1756
973
    }
1757
1758
24.7k
    return xShape;
1759
24.7k
}
1760
1761
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */