1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
3 * This file is part of the LibreOffice project.
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/.
9 * This file incorporates work covered by the following license notice:
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 .
20 #include <osl/diagnose.h>
21 #include <sal/log.hxx>
22 #include <tools/diagnose_ex.h>
23 #include <comphelper/base64.hxx>
24 #include <com/sun/star/frame/XModel.hpp>
25 #include <com/sun/star/lang/XMultiServiceFactory.hpp>
26 #include <com/sun/star/text/TextContentAnchorType.hpp>
27 #include <com/sun/star/beans/XPropertySet.hpp>
28 #include <com/sun/star/text/XTextFrame.hpp>
29 #include <com/sun/star/container/XNamed.hpp>
30 #include <com/sun/star/container/XNameContainer.hpp>
31 #include <com/sun/star/graphic/XGraphic.hpp>
32 #include <com/sun/star/text/SizeType.hpp>
33 #include <com/sun/star/drawing/XShape.hpp>
34 #include <com/sun/star/document/XEventsSupplier.hpp>
35 #include <com/sun/star/document/XEmbeddedObjectSupplier.hpp>
36 #include <com/sun/star/io/XOutputStream.hpp>
37 #include <com/sun/star/text/HoriOrientation.hpp>
38 #include <com/sun/star/text/VertOrientation.hpp>
39 #include <sax/tools/converter.hxx>
40 #include <xmloff/xmlimp.hxx>
41 #include <xmloff/xmltoken.hxx>
42 #include <xmloff/xmlnamespace.hxx>
43 #include <xmloff/namespacemap.hxx>
44 #include <xmloff/xmluconv.hxx>
45 #include "XMLAnchorTypePropHdl.hxx"
46 #include <XMLEmbeddedObjectImportContext.hxx>
47 #include <xmloff/XMLBase64ImportContext.hxx>
48 #include <XMLReplacementImageContext.hxx>
49 #include <xmloff/prstylei.hxx>
50 #include <xmloff/i18nmap.hxx>
51 #include <xexptran.hxx>
52 #include <xmloff/shapeimport.hxx>
53 #include <xmloff/XMLEventsImportContext.hxx>
54 #include <XMLImageMapContext.hxx>
55 #include "XMLTextFrameContext.hxx"
56 #include <xmloff/attrlist.hxx>
57 #include <basegfx/polygon/b2dpolygon.hxx>
58 #include <basegfx/polygon/b2dpolygontools.hxx>
59 #include <basegfx/polygon/b2dpolypolygon.hxx>
60 #include <basegfx/matrix/b2dhommatrixtools.hxx>
61 #include <basegfx/polygon/b2dpolypolygontools.hxx>
62 #include <basegfx/numeric/ftools.hxx>
64 #include <string_view>
66 using namespace ::com::sun::star
;
67 using namespace ::com::sun::star::uno
;
68 using namespace ::com::sun::star::text
;
69 using namespace ::com::sun::star::xml::sax
;
70 using namespace ::com::sun::star::beans
;
71 using namespace ::com::sun::star::lang
;
72 using namespace ::com::sun::star::container
;
73 using namespace ::com::sun::star::drawing
;
74 using namespace ::com::sun::star::document
;
75 using namespace ::xmloff::token
;
76 using ::com::sun::star::document::XEventsSupplier
;
78 #define XML_TEXT_FRAME_TEXTBOX 1
79 #define XML_TEXT_FRAME_GRAPHIC 2
80 #define XML_TEXT_FRAME_OBJECT 3
81 #define XML_TEXT_FRAME_OBJECT_OLE 4
82 #define XML_TEXT_FRAME_APPLET 5
83 #define XML_TEXT_FRAME_PLUGIN 6
84 #define XML_TEXT_FRAME_FLOATING_FRAME 7
86 typedef ::std::map
< const OUString
, OUString
> ParamMap
;
88 class XMLTextFrameContextHyperlink_Impl
92 OUString sTargetFrameName
;
97 inline XMLTextFrameContextHyperlink_Impl( const OUString
& rHRef
,
98 const OUString
& rName
,
99 const OUString
& rTargetFrameName
,
102 const OUString
& GetHRef() const { return sHRef
; }
103 const OUString
& GetName() const { return sName
; }
104 const OUString
& GetTargetFrameName() const { return sTargetFrameName
; }
105 bool GetMap() const { return bMap
; }
108 inline XMLTextFrameContextHyperlink_Impl::XMLTextFrameContextHyperlink_Impl(
109 const OUString
& rHRef
, const OUString
& rName
,
110 const OUString
& rTargetFrameName
, bool bM
) :
113 sTargetFrameName( rTargetFrameName
),
120 // Implement Title/Description Elements UI (#i73249#)
121 class XMLTextFrameTitleOrDescContext_Impl
: public SvXMLImportContext
123 OUString
& mrTitleOrDesc
;
128 XMLTextFrameTitleOrDescContext_Impl( SvXMLImport
& rImport
,
129 OUString
& rTitleOrDesc
);
131 virtual void SAL_CALL
characters( const OUString
& rText
) override
;
136 XMLTextFrameTitleOrDescContext_Impl::XMLTextFrameTitleOrDescContext_Impl(
137 SvXMLImport
& rImport
,
138 OUString
& rTitleOrDesc
)
139 : SvXMLImportContext( rImport
)
140 , mrTitleOrDesc( rTitleOrDesc
)
144 void XMLTextFrameTitleOrDescContext_Impl::characters( const OUString
& rText
)
146 mrTitleOrDesc
+= rText
;
151 class XMLTextFrameParam_Impl
: public SvXMLImportContext
154 XMLTextFrameParam_Impl( SvXMLImport
& rImport
,
155 const css::uno::Reference
< css::xml::sax::XFastAttributeList
> & xAttrList
,
156 ParamMap
&rParamMap
);
161 XMLTextFrameParam_Impl::XMLTextFrameParam_Impl(
162 SvXMLImport
& rImport
,
163 const css::uno::Reference
< css::xml::sax::XFastAttributeList
> & xAttrList
,
164 ParamMap
&rParamMap
):
165 SvXMLImportContext( rImport
)
167 OUString sName
, sValue
;
168 bool bFoundValue
= false; // to allow empty values
169 for (auto &aIter
: sax_fastparser::castToFastAttributeList( xAttrList
))
171 switch (aIter
.getToken())
173 case XML_ELEMENT(DRAW
, XML_VALUE
):
175 sValue
= aIter
.toString();
179 case XML_ELEMENT(DRAW
, XML_NAME
):
180 sName
= aIter
.toString();
183 XMLOFF_WARN_UNKNOWN("xmloff", aIter
);
186 if (!sName
.isEmpty() && bFoundValue
)
187 rParamMap
[sName
] = sValue
;
192 class XMLTextFrameContourContext_Impl
: public SvXMLImportContext
194 Reference
< XPropertySet
> xPropSet
;
199 XMLTextFrameContourContext_Impl( SvXMLImport
& rImport
, sal_Int32 nElement
,
200 const css::uno::Reference
< css::xml::sax::XFastAttributeList
> & xAttrList
,
201 const Reference
< XPropertySet
>& rPropSet
,
207 XMLTextFrameContourContext_Impl::XMLTextFrameContourContext_Impl(
208 SvXMLImport
& rImport
,
209 sal_Int32
/*nElement*/,
210 const Reference
< XFastAttributeList
> & xAttrList
,
211 const Reference
< XPropertySet
>& rPropSet
,
213 SvXMLImportContext( rImport
),
216 OUString sD
, sPoints
, sViewBox
;
217 bool bPixelWidth
= false, bPixelHeight
= false;
219 sal_Int32 nWidth
= 0;
220 sal_Int32 nHeight
= 0;
222 for( auto& aIter
: sax_fastparser::castToFastAttributeList(xAttrList
) )
224 switch( aIter
.getToken() )
226 case XML_ELEMENT(SVG
, XML_VIEWBOX
):
227 case XML_ELEMENT(SVG_COMPAT
, XML_VIEWBOX
):
228 sViewBox
= aIter
.toString();
230 case XML_ELEMENT(SVG
, XML_D
):
231 case XML_ELEMENT(SVG_COMPAT
, XML_D
):
233 sD
= aIter
.toString();
235 case XML_ELEMENT(DRAW
,XML_POINTS
):
237 sPoints
= aIter
.toString();
239 case XML_ELEMENT(SVG
, XML_WIDTH
):
240 case XML_ELEMENT(SVG_COMPAT
, XML_WIDTH
):
241 if (::sax::Converter::convertMeasurePx(nWidth
, aIter
.toView()))
244 GetImport().GetMM100UnitConverter().convertMeasureToCore(
245 nWidth
, aIter
.toView());
247 case XML_ELEMENT(SVG
, XML_HEIGHT
):
248 case XML_ELEMENT(SVG_COMPAT
, XML_HEIGHT
):
249 if (::sax::Converter::convertMeasurePx(nHeight
, aIter
.toView()))
252 GetImport().GetMM100UnitConverter().convertMeasureToCore(
253 nHeight
, aIter
.toView());
255 case XML_ELEMENT(DRAW
, XML_RECREATE_ON_EDIT
):
256 bAuto
= IsXMLToken(aIter
, XML_TRUE
);
261 OUString
sContourPolyPolygon("ContourPolyPolygon");
262 Reference
< XPropertySetInfo
> xPropSetInfo
= rPropSet
->getPropertySetInfo();
264 if(!xPropSetInfo
->hasPropertyByName(sContourPolyPolygon
) ||
265 nWidth
<= 0 || nHeight
<= 0 || bPixelWidth
!= bPixelHeight
||
266 !(bPath
? sD
: sPoints
).getLength())
269 const SdXMLImExViewBox
aViewBox( sViewBox
, GetImport().GetMM100UnitConverter());
270 basegfx::B2DPolyPolygon aPolyPolygon
;
274 basegfx::utils::importFromSvgD(aPolyPolygon
, sD
, GetImport().needFixPositionAfterZ(), nullptr);
278 basegfx::B2DPolygon aPolygon
;
280 if(basegfx::utils::importFromSvgPoints(aPolygon
, sPoints
))
282 aPolyPolygon
= basegfx::B2DPolyPolygon(aPolygon
);
286 if(aPolyPolygon
.count())
288 const basegfx::B2DRange
aSourceRange(
289 aViewBox
.GetX(), aViewBox
.GetY(),
290 aViewBox
.GetX() + aViewBox
.GetWidth(), aViewBox
.GetY() + aViewBox
.GetHeight());
291 const basegfx::B2DRange
aTargetRange(
295 if(!aSourceRange
.equal(aTargetRange
))
297 aPolyPolygon
.transform(
298 basegfx::utils::createSourceRangeTargetRangeTransform(
303 css::drawing::PointSequenceSequence aPointSequenceSequence
;
304 basegfx::utils::B2DPolyPolygonToUnoPointSequenceSequence(aPolyPolygon
, aPointSequenceSequence
);
305 xPropSet
->setPropertyValue( sContourPolyPolygon
, Any(aPointSequenceSequence
) );
308 static const OUStringLiteral
sIsPixelContour(u
"IsPixelContour");
310 if( xPropSetInfo
->hasPropertyByName( sIsPixelContour
) )
312 xPropSet
->setPropertyValue( sIsPixelContour
, Any(bPixelWidth
) );
315 static const OUStringLiteral
sIsAutomaticContour(u
"IsAutomaticContour");
317 if( xPropSetInfo
->hasPropertyByName( sIsAutomaticContour
) )
319 xPropSet
->setPropertyValue( sIsAutomaticContour
, Any(bAuto
) );
325 class XMLTextFrameContext_Impl
: public SvXMLImportContext
327 css::uno::Reference
< css::text::XTextCursor
> xOldTextCursor
;
328 css::uno::Reference
< css::beans::XPropertySet
> xPropSet
;
329 css::uno::Reference
< css::io::XOutputStream
> xBase64Stream
;
331 /// old list item and block (#89891#)
332 bool mbListContextPushed
;
334 OUString m_sOrigName
;
342 OUString sAppletName
;
343 OUString sFilterService
;
344 OUString sBase64CharsLeft
;
346 OUStringBuffer maUrlBuffer
;
358 sal_Int16 nRelHeight
;
361 css::text::TextContentAnchorType eAnchorType
;
367 bool bSyncHeight
: 1;
368 bool bCreateFailed
: 1;
369 bool bOwnBase64Stream
: 1;
370 bool mbMultipleContent
: 1; // This context is created based on a multiple content (image)
377 bool CreateIfNotThere();
378 const OUString
& GetHRef() const { return sHRef
; }
380 XMLTextFrameContext_Impl( SvXMLImport
& rImport
,
382 const css::uno::Reference
<css::xml::sax::XFastAttributeList
> & rAttrList
,
383 css::text::TextContentAnchorType eAnchorType
,
385 const css::uno::Reference
<css::xml::sax::XFastAttributeList
> & rFrameAttrList
,
386 bool bMultipleContent
= false );
388 virtual void SAL_CALL
endFastElement(sal_Int32 nElement
) override
;
390 virtual void SAL_CALL
characters( const OUString
& rChars
) override
;
392 virtual css::uno::Reference
< css::xml::sax::XFastContextHandler
> SAL_CALL
createFastChildContext(
393 sal_Int32 nElement
, const css::uno::Reference
< css::xml::sax::XFastAttributeList
>& AttrList
) override
;
395 void SetHyperlink( const OUString
& rHRef
,
396 const OUString
& rName
,
397 const OUString
& rTargetFrameName
,
400 // Implement Title/Description Elements UI (#i73249#)
401 void SetTitle( const OUString
& rTitle
);
403 void SetDesc( const OUString
& rDesc
);
407 const OUString
& GetOrigName() const { return m_sOrigName
; }
409 css::text::TextContentAnchorType
GetAnchorType() const { return eAnchorType
; }
411 const css::uno::Reference
< css::beans::XPropertySet
>& GetPropSet() const { return xPropSet
; }
416 void XMLTextFrameContext_Impl::Create()
418 rtl::Reference
< XMLTextImportHelper
> xTextImportHelper
=
419 GetImport().GetTextImport();
423 case XML_TEXT_FRAME_OBJECT
:
424 case XML_TEXT_FRAME_OBJECT_OLE
:
425 if( xBase64Stream
.is() )
427 OUString
sURL( GetImport().ResolveEmbeddedObjectURLFromBase64() );
428 if( !sURL
.isEmpty() )
429 xPropSet
= GetImport().GetTextImport()
430 ->createAndInsertOLEObject( GetImport(), sURL
,
435 else if( !sHRef
.isEmpty() )
437 OUString
sURL( GetImport().ResolveEmbeddedObjectURL( sHRef
,
438 std::u16string_view() ) );
440 if( GetImport().IsPackageURL( sHRef
) )
442 xPropSet
= GetImport().GetTextImport()
443 ->createAndInsertOLEObject( GetImport(), sURL
,
450 // it should be an own OOo link that has no storage persistence
451 xPropSet
= GetImport().GetTextImport()
452 ->createAndInsertOOoLink( GetImport(),
461 OUString sURL
= "vnd.sun.star.ServiceName:" + sFilterService
;
462 xPropSet
= GetImport().GetTextImport()
463 ->createAndInsertOLEObject( GetImport(), sURL
,
470 case XML_TEXT_FRAME_APPLET
:
472 xPropSet
= GetImport().GetTextImport()
473 ->createAndInsertApplet( sAppletName
, sCode
,
478 case XML_TEXT_FRAME_PLUGIN
:
481 GetImport().GetAbsoluteReference(sHRef
);
482 xPropSet
= GetImport().GetTextImport()
483 ->createAndInsertPlugin( sMimeType
, sHRef
,
488 case XML_TEXT_FRAME_FLOATING_FRAME
:
490 xPropSet
= GetImport().GetTextImport()
491 ->createAndInsertFloatingFrame( sFrameName
, sHRef
,
498 Reference
<XMultiServiceFactory
> xFactory( GetImport().GetModel(),
502 OUString sServiceName
;
505 case XML_TEXT_FRAME_TEXTBOX
: sServiceName
= "com.sun.star.text.TextFrame"; break;
506 case XML_TEXT_FRAME_GRAPHIC
: sServiceName
= "com.sun.star.text.GraphicObject"; break;
508 Reference
<XInterface
> xIfc
= xFactory
->createInstance( sServiceName
);
509 SAL_WARN_IF( !xIfc
.is(), "xmloff.text", "couldn't create frame" );
511 xPropSet
.set( xIfc
, UNO_QUERY
);
518 bCreateFailed
= true;
522 Reference
< XPropertySetInfo
> xPropSetInfo
= xPropSet
->getPropertySetInfo();
524 // Skip duplicated frames
525 if(!mbMultipleContent
&& // It's allowed to have multiple image for the same frame
527 xTextImportHelper
->IsDuplicateFrame(sName
, nX
, nY
, nWidth
, nHeight
))
529 bCreateFailed
= true;
534 Reference
< XNamed
> xNamed( xPropSet
, UNO_QUERY
);
537 OUString
sOrigName( xNamed
->getName() );
538 if( sOrigName
.isEmpty() ||
539 (!sName
.isEmpty() && sOrigName
!= sName
) )
541 OUString
sOldName( sName
);
544 while( xTextImportHelper
->HasFrameByName( sName
) )
546 sName
= sOldName
+ OUString::number( ++i
);
548 xNamed
->setName( sName
);
549 if( sName
!= sOldName
)
551 xTextImportHelper
->GetRenameMap().Add( XML_TEXT_RENAME_TYPE_FRAME
,
559 XMLPropStyleContext
*pStyle
= nullptr;
560 if( !sStyleName
.isEmpty() )
562 pStyle
= xTextImportHelper
->FindAutoFrameStyle( sStyleName
);
564 sStyleName
= pStyle
->GetParentName();
568 if( !sStyleName
.isEmpty() )
570 OUString
sDisplayStyleName( GetImport().GetStyleDisplayName(
571 XmlStyleFamily::SD_GRAPHICS_ID
, sStyleName
) );
572 const Reference
< XNameContainer
> & rStyles
=
573 xTextImportHelper
->GetFrameStyles();
575 rStyles
->hasByName( sDisplayStyleName
) )
577 xPropSet
->setPropertyValue( "FrameStyleName", Any(sDisplayStyleName
) );
581 // anchor type (must be set before any other properties, because
582 // otherwise some orientations cannot be set or will be changed
584 xPropSet
->setPropertyValue( "AnchorType", Any(eAnchorType
) );
588 pStyle
->FillPropertySet( xPropSet
);
591 sal_Int16 nHoriOrient
= HoriOrientation::NONE
;
592 aAny
= xPropSet
->getPropertyValue( "HoriOrient" );
593 aAny
>>= nHoriOrient
;
594 if( HoriOrientation::NONE
== nHoriOrient
)
596 xPropSet
->setPropertyValue( "HoriOrientPosition", Any(nX
) );
599 sal_Int16 nVertOrient
= VertOrientation::NONE
;
600 aAny
= xPropSet
->getPropertyValue( "VertOrient" );
601 aAny
>>= nVertOrient
;
602 if( VertOrientation::NONE
== nVertOrient
)
604 xPropSet
->setPropertyValue( "VertOrientPosition", Any(nY
) );
610 xPropSet
->setPropertyValue( "Width", Any(nWidth
) );
612 if( nRelWidth
> 0 || nWidth
> 0 )
614 xPropSet
->setPropertyValue( "RelativeWidth", Any(nRelWidth
) );
616 if( bSyncWidth
|| nWidth
> 0 )
618 xPropSet
->setPropertyValue( "IsSyncWidthToHeight", Any(bSyncWidth
) );
620 if( xPropSetInfo
->hasPropertyByName( "WidthType" ) &&
621 (bMinWidth
|| nWidth
> 0 || nRelWidth
> 0 ) )
623 sal_Int16 nSizeType
=
624 (bMinWidth
&& XML_TEXT_FRAME_TEXTBOX
== nType
) ? SizeType::MIN
626 xPropSet
->setPropertyValue( "WidthType", Any(nSizeType
) );
631 xPropSet
->setPropertyValue( "Height", Any(nHeight
) );
633 if( nRelHeight
> 0 || nHeight
> 0 )
635 xPropSet
->setPropertyValue( "RelativeHeight", Any(nRelHeight
) );
637 if( bSyncHeight
|| nHeight
> 0 )
639 xPropSet
->setPropertyValue( "IsSyncHeightToWidth", Any(bSyncHeight
) );
641 if( xPropSetInfo
->hasPropertyByName( "SizeType" ) &&
642 (bMinHeight
|| nHeight
> 0 || nRelHeight
> 0 ) )
644 sal_Int16 nSizeType
=
645 (bMinHeight
&& XML_TEXT_FRAME_TEXTBOX
== nType
) ? SizeType::MIN
647 xPropSet
->setPropertyValue( "SizeType", Any(nSizeType
) );
650 if( XML_TEXT_FRAME_GRAPHIC
== nType
)
653 OSL_ENSURE( !sHRef
.isEmpty() || xBase64Stream
.is(),
654 "neither URL nor base64 image data given" );
655 uno::Reference
<graphic::XGraphic
> xGraphic
;
656 if (!sHRef
.isEmpty())
658 xGraphic
= GetImport().loadGraphicByURL(sHRef
);
660 else if (xBase64Stream
.is())
662 xGraphic
= GetImport().loadGraphicFromBase64(xBase64Stream
);
663 xBase64Stream
= nullptr;
667 xPropSet
->setPropertyValue("Graphic", Any(xGraphic
));
670 xPropSet
->setPropertyValue( "GraphicFilter", Any(OUString()) );
673 xPropSet
->setPropertyValue( "GraphicRotation", Any(nRotation
) );
676 // page number (must be set after the frame is inserted, because it
677 // will be overwritten then inserting the frame.
678 if( TextContentAnchorType_AT_PAGE
== eAnchorType
&& nPage
> 0 )
680 xPropSet
->setPropertyValue( "AnchorPageNo", Any(nPage
) );
683 if( XML_TEXT_FRAME_OBJECT
!= nType
&&
684 XML_TEXT_FRAME_OBJECT_OLE
!= nType
&&
685 XML_TEXT_FRAME_APPLET
!= nType
&&
686 XML_TEXT_FRAME_PLUGIN
!= nType
&&
687 XML_TEXT_FRAME_FLOATING_FRAME
!= nType
)
689 Reference
< XTextContent
> xTxtCntnt( xPropSet
, UNO_QUERY
);
692 xTextImportHelper
->InsertTextContent(xTxtCntnt
);
694 catch (lang::IllegalArgumentException
const&)
696 TOOLS_WARN_EXCEPTION("xmloff.text", "Cannot import part of the text - probably an image in the text frame?");
701 // Make adding the shape to Z-Ordering dependent from if we are
702 // inside an inside_deleted_section (redlining). That is necessary
703 // since the shape will be removed again later. It would lead to
704 // errors if it would stay inside the Z-Ordering. Thus, the
705 // easiest way to solve that conflict is to not add it here.
706 if(!GetImport().HasTextImport()
707 || !GetImport().GetTextImport()->IsInsideDeleteContext())
709 Reference
< XShape
> xShape( xPropSet
, UNO_QUERY
);
711 GetImport().GetShapeImport()->shapeWithZIndexAdded( xShape
, nZIndex
);
714 if( XML_TEXT_FRAME_TEXTBOX
!= nType
)
717 xTextImportHelper
->ConnectFrameChains( sName
, sNextName
, xPropSet
);
718 Reference
< XTextFrame
> xTxtFrame( xPropSet
, UNO_QUERY
);
719 Reference
< XText
> xTxt
= xTxtFrame
->getText();
720 xOldTextCursor
= xTextImportHelper
->GetCursor();
721 xTextImportHelper
->SetCursor( xTxt
->createTextCursor() );
723 // remember old list item and block (#89892#) and reset them
724 // for the text frame
725 xTextImportHelper
->PushListContext();
726 mbListContextPushed
= true;
729 void XMLTextFrameContext::removeGraphicFromImportContext(const SvXMLImportContext
& rContext
)
731 const XMLTextFrameContext_Impl
* pXMLTextFrameContext_Impl
= dynamic_cast< const XMLTextFrameContext_Impl
* >(&rContext
);
733 if(!pXMLTextFrameContext_Impl
)
738 // just dispose to delete
739 uno::Reference
< lang::XComponent
> xComp(pXMLTextFrameContext_Impl
->GetPropSet(), UNO_QUERY
);
741 // Inform shape importer about the removal so it can adjust
743 uno::Reference
<drawing::XShape
> xShape(xComp
, uno::UNO_QUERY
);
744 GetImport().GetShapeImport()->shapeRemoved(xShape
);
751 catch( uno::Exception
& )
753 OSL_FAIL( "Error in cleanup of multiple graphic object import (!)" );
757 OUString
XMLTextFrameContext::getGraphicPackageURLFromImportContext(const SvXMLImportContext
& rContext
) const
759 const XMLTextFrameContext_Impl
* pXMLTextFrameContext_Impl
= dynamic_cast< const XMLTextFrameContext_Impl
* >(&rContext
);
761 if(pXMLTextFrameContext_Impl
)
763 return "vnd.sun.star.Package:" + pXMLTextFrameContext_Impl
->GetHRef();
769 css::uno::Reference
<css::graphic::XGraphic
> XMLTextFrameContext::getGraphicFromImportContext(const SvXMLImportContext
& rContext
) const
771 uno::Reference
<graphic::XGraphic
> xGraphic
;
773 const XMLTextFrameContext_Impl
* pXMLTextFrameContext_Impl
= dynamic_cast<const XMLTextFrameContext_Impl
*>(&rContext
);
775 if (pXMLTextFrameContext_Impl
)
779 const uno::Reference
<beans::XPropertySet
>& xPropertySet
= pXMLTextFrameContext_Impl
->GetPropSet();
781 if (xPropertySet
.is())
783 xPropertySet
->getPropertyValue("Graphic") >>= xGraphic
;
786 catch (uno::Exception
&)
792 bool XMLTextFrameContext_Impl::CreateIfNotThere()
794 if( !xPropSet
.is() &&
795 ( XML_TEXT_FRAME_OBJECT_OLE
== nType
||
796 XML_TEXT_FRAME_GRAPHIC
== nType
) &&
797 xBase64Stream
.is() && !bCreateFailed
)
799 if( bOwnBase64Stream
)
800 xBase64Stream
->closeOutput();
804 return xPropSet
.is();
807 XMLTextFrameContext_Impl::XMLTextFrameContext_Impl(
808 SvXMLImport
& rImport
,
809 sal_Int32
/*nElement*/,
810 const Reference
< XFastAttributeList
> & rAttrList
,
811 TextContentAnchorType eATyp
,
813 const Reference
< XFastAttributeList
> & rFrameAttrList
,
814 bool bMultipleContent
)
815 : SvXMLImportContext( rImport
)
816 , mbListContextPushed( false )
818 , eAnchorType( eATyp
)
835 bCreateFailed
= false;
836 bOwnBase64Stream
= false;
837 mbMultipleContent
= bMultipleContent
;
839 auto processAttr
= [&](sal_Int32 nElement
, const sax_fastparser::FastAttributeList::FastAttributeIter
& aIter
) -> void
843 case XML_ELEMENT(DRAW
, XML_STYLE_NAME
):
844 sStyleName
= aIter
.toString();
846 case XML_ELEMENT(DRAW
, XML_NAME
):
847 m_sOrigName
= aIter
.toString();
850 case XML_ELEMENT(DRAW
, XML_FRAME_NAME
):
851 sFrameName
= aIter
.toString();
853 case XML_ELEMENT(DRAW
, XML_APPLET_NAME
):
854 sAppletName
= aIter
.toString();
856 case XML_ELEMENT(TEXT
, XML_ANCHOR_TYPE
):
857 if( TextContentAnchorType_AT_PARAGRAPH
== eAnchorType
||
858 TextContentAnchorType_AT_CHARACTER
== eAnchorType
||
859 TextContentAnchorType_AS_CHARACTER
== eAnchorType
)
862 TextContentAnchorType eNew
;
863 if( XMLAnchorTypePropHdl::convert( aIter
.toView(), eNew
) &&
864 ( TextContentAnchorType_AT_PARAGRAPH
== eNew
||
865 TextContentAnchorType_AT_CHARACTER
== eNew
||
866 TextContentAnchorType_AS_CHARACTER
== eNew
||
867 TextContentAnchorType_AT_PAGE
== eNew
) )
871 case XML_ELEMENT(TEXT
, XML_ANCHOR_PAGE_NUMBER
):
874 if (::sax::Converter::convertNumber(nTmp
, aIter
.toView(), 1, SHRT_MAX
))
875 nPage
= static_cast<sal_Int16
>(nTmp
);
878 case XML_ELEMENT(SVG
, XML_X
):
879 case XML_ELEMENT(SVG_COMPAT
, XML_X
):
880 GetImport().GetMM100UnitConverter().convertMeasureToCore(
883 case XML_ELEMENT(SVG
, XML_Y
):
884 case XML_ELEMENT(SVG_COMPAT
, XML_Y
):
885 GetImport().GetMM100UnitConverter().convertMeasureToCore(
886 nY
, aIter
.toView() );
888 case XML_ELEMENT(SVG
, XML_WIDTH
):
889 case XML_ELEMENT(SVG_COMPAT
, XML_WIDTH
):
890 // relative widths are obsolete since SRC617. Remove them some day!
891 if( aIter
.toView().find( '%' ) != std::string_view::npos
)
894 if (::sax::Converter::convertPercent(nTmp
, aIter
.toView()))
895 nRelWidth
= static_cast<sal_Int16
>(nTmp
);
899 GetImport().GetMM100UnitConverter().convertMeasureToCore(
900 nWidth
, aIter
.toView(), 0 );
903 case XML_ELEMENT(STYLE
, XML_REL_WIDTH
):
904 if( IsXMLToken(aIter
, XML_SCALE
) )
911 if (::sax::Converter::convertPercent( nTmp
, aIter
.toView() ))
912 nRelWidth
= static_cast<sal_Int16
>(nTmp
);
915 case XML_ELEMENT(FO
, XML_MIN_WIDTH
):
916 case XML_ELEMENT(FO_COMPAT
, XML_MIN_WIDTH
):
917 if( aIter
.toView().find( '%' ) != std::string_view::npos
)
920 if (::sax::Converter::convertPercent(nTmp
, aIter
.toView()))
921 nRelWidth
= static_cast<sal_Int16
>(nTmp
);
925 GetImport().GetMM100UnitConverter().convertMeasureToCore(
926 nWidth
, aIter
.toView(), 0 );
930 case XML_ELEMENT(SVG
, XML_HEIGHT
):
931 case XML_ELEMENT(SVG_COMPAT
, XML_HEIGHT
):
932 // relative heights are obsolete since SRC617. Remove them some day!
933 if( aIter
.toView().find( '%' ) != std::string_view::npos
)
936 if (::sax::Converter::convertPercent(nTmp
, aIter
.toView()))
937 nRelHeight
= static_cast<sal_Int16
>(nTmp
);
941 GetImport().GetMM100UnitConverter().convertMeasureToCore(
942 nHeight
, aIter
.toView(), 0 );
945 case XML_ELEMENT(STYLE
, XML_REL_HEIGHT
):
946 if( IsXMLToken( aIter
, XML_SCALE
) )
950 else if( IsXMLToken( aIter
, XML_SCALE_MIN
) )
958 if (::sax::Converter::convertPercent( nTmp
, aIter
.toView() ))
959 nRelHeight
= static_cast<sal_Int16
>(nTmp
);
962 case XML_ELEMENT(FO
, XML_MIN_HEIGHT
):
963 case XML_ELEMENT(FO_COMPAT
, XML_MIN_HEIGHT
):
964 if( aIter
.toView().find( '%' ) != std::string_view::npos
)
967 if (::sax::Converter::convertPercent(nTmp
, aIter
.toView()))
968 nRelHeight
= static_cast<sal_Int16
>(nTmp
);
972 GetImport().GetMM100UnitConverter().convertMeasureToCore(
973 nHeight
, aIter
.toView(), 0 );
977 case XML_ELEMENT(DRAW
, XML_ZINDEX
):
978 ::sax::Converter::convertNumber( nZIndex
, aIter
.toView(), -1 );
980 case XML_ELEMENT(DRAW
, XML_CHAIN_NEXT_NAME
):
981 sNextName
= aIter
.toString();
983 case XML_ELEMENT(XLINK
, XML_HREF
):
984 sHRef
= aIter
.toString();
986 case XML_ELEMENT(DRAW
, XML_TRANSFORM
):
988 // RotateFlyFrameFix: im/export full 'draw:transform' using existing tooling
989 // Currently only rotation is used, but combinations with 'draw:transform'
990 // may be necessary in the future, so that svg:x/svg:y/svg:width/svg:height
991 // may be extended/replaced with 'draw:transform' (see draw objects)
992 SdXMLImExTransform2D aSdXMLImExTransform2D
;
993 basegfx::B2DHomMatrix aFullTransform
;
995 // Use SdXMLImExTransform2D to convert to transformation
996 // Note: using GetTwipUnitConverter instead of GetMM100UnitConverter may be needed,
997 // but is not generally available (as it should be, a 'current' UnitConverter should
998 // be available at GetExport() - and maybe was once). May have to be addressed as soon
999 // as translate transformations are used here.
1000 aSdXMLImExTransform2D
.SetString(aIter
.toString(), GetImport().GetMM100UnitConverter());
1001 aSdXMLImExTransform2D
.GetFullTransform(aFullTransform
);
1003 if(!aFullTransform
.isIdentity())
1005 const basegfx::utils::B2DHomMatrixBufferedDecompose
aDecomposedTransform(aFullTransform
);
1007 // currently we *only* use rotation (and translation indirectly), so warn if *any*
1008 // of the other transform parts is used
1009 SAL_WARN_IF(!basegfx::fTools::equal(1.0, aDecomposedTransform
.getScale().getX()), "xmloff.text", "draw:transform uses scaleX" );
1010 SAL_WARN_IF(!basegfx::fTools::equal(1.0, aDecomposedTransform
.getScale().getY()), "xmloff.text", "draw:transform uses scaleY" );
1011 SAL_WARN_IF(!basegfx::fTools::equalZero(aDecomposedTransform
.getShearX()), "xmloff.text", "draw:transform uses shearX" );
1013 // Translation comes from the translate to RotCenter, rot and BackTranslate.
1014 // This means that it represents the translation between unrotated TopLeft
1015 // and rotated TopLeft. This may be checked here now, but currently we only
1016 // use rotation around center and assume that this *was* a rotation around
1017 // center. The check would compare the object's center with the RotCenter
1018 // that can be extracted from the transformation in aFullTransform.
1019 // The definition contains implicitly the RotationCenter absolute
1020 // to the scaled and translated object, so this may be used if needed (see
1021 // _exportTextGraphic how the -trans/rot/trans is composed)
1023 if(!basegfx::fTools::equalZero(aDecomposedTransform
.getRotate()))
1025 // rotation is used, set it. Convert from deg to 10th degree integer
1026 // CAUTION: due to #i78696# (rotation mirrored using API) the rotate
1027 // value is already mirrored, so do not do it again here (to be in sync
1028 // with XMLTextParagraphExport::_exportTextGraphic normally it would need
1029 // to me mirrored using * -1.0, see conversion there)
1030 // CAUTION-II: due to tdf#115782 it is better for current ODF to indeed use it
1031 // with the wrong orientation as in all other cases - ARGH! We will need to
1032 // correct this in future ODF ASAP! For now, mirror the rotation here AGAIN
1033 const double fRotate(-basegfx::rad2deg
<10>(aDecomposedTransform
.getRotate()));
1034 nRotation
= static_cast< sal_Int16
>(basegfx::fround(fRotate
) % 3600);
1036 // tdf#115529 may be negative, with the above modulo maximal -3599, so
1037 // no loop needed here. nRotation is used in setPropertyValue("GraphicRotation")
1038 // and *has* to be in the range [0 .. 3600[
1047 case XML_ELEMENT(DRAW
, XML_CODE
):
1048 sCode
= aIter
.toString();
1050 case XML_ELEMENT(DRAW
, XML_OBJECT
):
1052 case XML_ELEMENT(DRAW
, XML_ARCHIVE
):
1054 case XML_ELEMENT(DRAW
, XML_MAY_SCRIPT
):
1055 bMayScript
= IsXMLToken( aIter
, XML_TRUE
);
1057 case XML_ELEMENT(DRAW
, XML_MIME_TYPE
):
1058 case XML_ELEMENT(LO_EXT
, XML_MIME_TYPE
):
1059 sMimeType
= aIter
.toString();
1061 case XML_ELEMENT(DRAW
, XML_NOTIFY_ON_UPDATE_OF_RANGES
):
1062 case XML_ELEMENT(DRAW
, XML_NOTIFY_ON_UPDATE_OF_TABLE
):
1063 sTblName
= aIter
.toString();
1066 XMLOFF_WARN_UNKNOWN("xmloff", aIter
);
1070 for( auto& aIter
: sax_fastparser::castToFastAttributeList(rAttrList
) )
1071 processAttr(aIter
.getToken(), aIter
);
1072 for( auto& aIter
: sax_fastparser::castToFastAttributeList(rFrameAttrList
) )
1073 processAttr(aIter
.getToken(), aIter
);
1075 if( ( (XML_TEXT_FRAME_GRAPHIC
== nType
||
1076 XML_TEXT_FRAME_OBJECT
== nType
||
1077 XML_TEXT_FRAME_OBJECT_OLE
== nType
) &&
1078 sHRef
.isEmpty() ) ||
1079 ( XML_TEXT_FRAME_APPLET
== nType
&& sCode
.isEmpty() ) ||
1080 ( XML_TEXT_FRAME_PLUGIN
== nType
&&
1081 sHRef
.isEmpty() && sMimeType
.isEmpty() ) )
1082 return; // no URL: no image or OLE object
1087 void XMLTextFrameContext_Impl::endFastElement(sal_Int32
)
1089 if( ( XML_TEXT_FRAME_OBJECT_OLE
== nType
||
1090 XML_TEXT_FRAME_GRAPHIC
== nType
) &&
1091 !xPropSet
.is() && !bCreateFailed
)
1093 OUString sTrimmedChars
= maUrlBuffer
.makeStringAndClear().trim();
1094 if( !sTrimmedChars
.isEmpty() )
1096 if( !xBase64Stream
.is() )
1098 if( XML_TEXT_FRAME_GRAPHIC
== nType
)
1101 GetImport().GetStreamForGraphicObjectURLFromBase64();
1106 GetImport().GetStreamForEmbeddedObjectURLFromBase64();
1108 if( xBase64Stream
.is() )
1109 bOwnBase64Stream
= true;
1111 if( bOwnBase64Stream
&& xBase64Stream
.is() )
1114 if( !sBase64CharsLeft
.isEmpty() )
1116 sChars
= sBase64CharsLeft
+ sTrimmedChars
;
1117 sBase64CharsLeft
.clear();
1121 sChars
= sTrimmedChars
;
1123 Sequence
< sal_Int8
> aBuffer( (sChars
.getLength() / 4) * 3 );
1124 sal_Int32 nCharsDecoded
=
1125 ::comphelper::Base64::decodeSomeChars( aBuffer
, sChars
);
1126 xBase64Stream
->writeBytes( aBuffer
);
1127 if( nCharsDecoded
!= sChars
.getLength() )
1128 sBase64CharsLeft
= sChars
.copy( nCharsDecoded
);
1135 if( xOldTextCursor
.is() )
1137 GetImport().GetTextImport()->DeleteParagraph();
1138 GetImport().GetTextImport()->SetCursor( xOldTextCursor
);
1141 // reinstall old list item (if necessary) #89892#
1142 if (mbListContextPushed
) {
1143 GetImport().GetTextImport()->PopListContext();
1146 if (( nType
== XML_TEXT_FRAME_APPLET
|| nType
== XML_TEXT_FRAME_PLUGIN
) && xPropSet
.is())
1147 GetImport().GetTextImport()->endAppletOrPlugin( xPropSet
, aParamMap
);
1150 css::uno::Reference
< css::xml::sax::XFastContextHandler
> XMLTextFrameContext_Impl::createFastChildContext(
1152 const css::uno::Reference
< css::xml::sax::XFastAttributeList
>& xAttrList
)
1154 if( nElement
== XML_ELEMENT(DRAW
, XML_PARAM
) )
1156 if ( nType
== XML_TEXT_FRAME_APPLET
|| nType
== XML_TEXT_FRAME_PLUGIN
)
1157 return new XMLTextFrameParam_Impl( GetImport(),
1158 xAttrList
, aParamMap
);
1160 else if( nElement
== XML_ELEMENT(OFFICE
, XML_BINARY_DATA
) )
1162 if( !xPropSet
.is() && !xBase64Stream
.is() && !bCreateFailed
)
1166 case XML_TEXT_FRAME_GRAPHIC
:
1168 GetImport().GetStreamForGraphicObjectURLFromBase64();
1170 case XML_TEXT_FRAME_OBJECT_OLE
:
1172 GetImport().GetStreamForEmbeddedObjectURLFromBase64();
1175 if( xBase64Stream
.is() )
1176 return new XMLBase64ImportContext( GetImport(), xBase64Stream
);
1179 // Correction of condition which also avoids warnings. (#i100480#)
1180 if( XML_TEXT_FRAME_OBJECT
== nType
&&
1181 ( nElement
== XML_ELEMENT(OFFICE
, XML_DOCUMENT
) ||
1182 nElement
== XML_ELEMENT(MATH
, XML_MATH
) ) )
1184 if( !xPropSet
.is() && !bCreateFailed
)
1186 XMLEmbeddedObjectImportContext
*pEContext
=
1187 new XMLEmbeddedObjectImportContext( GetImport(), nElement
, xAttrList
);
1188 sFilterService
= pEContext
->GetFilterServiceName();
1189 if( !sFilterService
.isEmpty() )
1194 Reference
< XEmbeddedObjectSupplier
> xEOS( xPropSet
,
1196 OSL_ENSURE( xEOS
.is(),
1197 "no embedded object supplier for own object" );
1198 Reference
<css::lang::XComponent
> aXComponent(xEOS
->getEmbeddedObject());
1199 pEContext
->SetComponent( aXComponent
);
1206 if( xOldTextCursor
.is() ) // text-box
1208 auto p
= GetImport().GetTextImport()->CreateTextChildContext(
1209 GetImport(), nElement
, xAttrList
,
1210 XMLTextType::TextBox
);
1215 XMLOFF_WARN_UNKNOWN_ELEMENT("xmloff", nElement
);
1220 void XMLTextFrameContext_Impl::characters( const OUString
& rChars
)
1222 maUrlBuffer
.append(rChars
);
1225 void XMLTextFrameContext_Impl::SetHyperlink( const OUString
& rHRef
,
1226 const OUString
& rName
,
1227 const OUString
& rTargetFrameName
,
1230 static constexpr OUStringLiteral s_HyperLinkURL
= u
"HyperLinkURL";
1231 static constexpr OUStringLiteral s_HyperLinkName
= u
"HyperLinkName";
1232 static constexpr OUStringLiteral s_HyperLinkTarget
= u
"HyperLinkTarget";
1233 static constexpr OUStringLiteral s_ServerMap
= u
"ServerMap";
1234 if( !xPropSet
.is() )
1237 Reference
< XPropertySetInfo
> xPropSetInfo
=
1238 xPropSet
->getPropertySetInfo();
1239 if( !xPropSetInfo
.is() ||
1240 !xPropSetInfo
->hasPropertyByName(s_HyperLinkURL
))
1243 xPropSet
->setPropertyValue( s_HyperLinkURL
, Any(rHRef
) );
1245 if (xPropSetInfo
->hasPropertyByName(s_HyperLinkName
))
1247 xPropSet
->setPropertyValue(s_HyperLinkName
, Any(rName
));
1250 if (xPropSetInfo
->hasPropertyByName(s_HyperLinkTarget
))
1252 xPropSet
->setPropertyValue( s_HyperLinkTarget
, Any(rTargetFrameName
) );
1255 if (xPropSetInfo
->hasPropertyByName(s_ServerMap
))
1257 xPropSet
->setPropertyValue(s_ServerMap
, Any(bMap
));
1261 void XMLTextFrameContext_Impl::SetName()
1263 Reference
<XNamed
> xNamed(xPropSet
, UNO_QUERY
);
1264 if (m_sOrigName
.isEmpty() || !xNamed
.is())
1267 OUString
const name(xNamed
->getName());
1268 if (name
!= m_sOrigName
)
1272 xNamed
->setName(m_sOrigName
);
1274 catch (uno::Exception
const&)
1275 { // fdo#71698 document contains 2 frames with same draw:name
1276 TOOLS_INFO_EXCEPTION("xmloff.text", "SetName(): exception setting \""
1277 << m_sOrigName
<< "\"");
1282 // Implement Title/Description Elements UI (#i73249#)
1283 void XMLTextFrameContext_Impl::SetTitle( const OUString
& rTitle
)
1285 if ( xPropSet
.is() )
1287 Reference
< XPropertySetInfo
> xPropSetInfo
= xPropSet
->getPropertySetInfo();
1288 if( xPropSetInfo
->hasPropertyByName( "Title" ) )
1290 xPropSet
->setPropertyValue( "Title", makeAny( rTitle
) );
1295 void XMLTextFrameContext_Impl::SetDesc( const OUString
& rDesc
)
1297 if ( xPropSet
.is() )
1299 Reference
< XPropertySetInfo
> xPropSetInfo
= xPropSet
->getPropertySetInfo();
1300 if( xPropSetInfo
->hasPropertyByName( "Description" ) )
1302 xPropSet
->setPropertyValue( "Description", makeAny( rDesc
) );
1308 bool XMLTextFrameContext::CreateIfNotThere( css::uno::Reference
< css::beans::XPropertySet
>& rPropSet
)
1310 SvXMLImportContext
*pContext
= m_xImplContext
.get();
1311 XMLTextFrameContext_Impl
*pImpl
= dynamic_cast< XMLTextFrameContext_Impl
*>( pContext
);
1312 if( pImpl
&& pImpl
->CreateIfNotThere() )
1313 rPropSet
= pImpl
->GetPropSet();
1315 return rPropSet
.is();
1318 XMLTextFrameContext::XMLTextFrameContext(
1319 SvXMLImport
& rImport
,
1320 const Reference
< XFastAttributeList
> & xAttrList
,
1321 TextContentAnchorType eATyp
)
1322 : SvXMLImportContext( rImport
)
1323 , m_xAttrList( new sax_fastparser::FastAttributeList( xAttrList
) )
1324 // Implement Title/Description Elements UI (#i73249#)
1325 , m_eDefaultAnchorType( eATyp
)
1326 // Shapes in Writer cannot be named via context menu (#i51726#)
1327 , m_HasAutomaticStyleWithoutParentStyle( false )
1328 , m_bSupportsReplacement( false )
1330 for( auto& aIter
: sax_fastparser::castToFastAttributeList(xAttrList
) )
1332 // New distinguish attribute between Writer objects and Draw objects is:
1333 // Draw objects have an automatic style without a parent style (#i51726#)
1334 switch (aIter
.getToken())
1336 case XML_ELEMENT(DRAW
, XML_STYLE_NAME
):
1338 OUString aStyleName
= aIter
.toString();
1339 if( !aStyleName
.isEmpty() )
1341 rtl::Reference
< XMLTextImportHelper
> xTxtImport
=
1342 GetImport().GetTextImport();
1343 XMLPropStyleContext
* pStyle
= xTxtImport
->FindAutoFrameStyle( aStyleName
);
1344 if ( pStyle
&& pStyle
->GetParentName().isEmpty() )
1346 m_HasAutomaticStyleWithoutParentStyle
= true;
1351 case XML_ELEMENT(TEXT
, XML_ANCHOR_TYPE
):
1353 TextContentAnchorType eNew
;
1354 if( XMLAnchorTypePropHdl::convert( aIter
.toView(), eNew
) &&
1355 ( TextContentAnchorType_AT_PARAGRAPH
== eNew
||
1356 TextContentAnchorType_AT_CHARACTER
== eNew
||
1357 TextContentAnchorType_AS_CHARACTER
== eNew
||
1358 TextContentAnchorType_AT_PAGE
== eNew
) )
1359 m_eDefaultAnchorType
= eNew
;
1366 void XMLTextFrameContext::endFastElement(sal_Int32
)
1368 /// solve if multiple image child contexts were imported
1369 SvXMLImportContextRef
const pMultiContext(solveMultipleImages());
1371 SvXMLImportContext
const*const pContext
=
1372 (pMultiContext
.is()) ? pMultiContext
.get() : m_xImplContext
.get();
1373 XMLTextFrameContext_Impl
*pImpl
= const_cast<XMLTextFrameContext_Impl
*>(dynamic_cast< const XMLTextFrameContext_Impl
*>( pContext
));
1374 assert(!pMultiContext
.is() || pImpl
);
1376 // When we are dealing with a textbox, pImpl will be null;
1377 // we need to set the hyperlink to the shape instead
1378 Reference
<XShape
> xShape
= GetShape();
1379 if (xShape
.is() && m_pHyperlink
)
1381 Reference
<XPropertySet
> xProps(xShape
, UNO_QUERY
);
1383 xProps
->setPropertyValue("Hyperlink", Any(m_pHyperlink
->GetHRef()));
1389 pImpl
->CreateIfNotThere();
1391 // fdo#68839: in case the surviving image was not the first one,
1392 // it will have a counter added to its name - set the original name
1393 if (pMultiContext
.is()) // do this only when necessary; esp. not for text
1394 { // frames that may have entries in GetRenameMap()!
1398 if( !m_sTitle
.isEmpty() )
1400 pImpl
->SetTitle( m_sTitle
);
1402 if( !m_sDesc
.isEmpty() )
1404 pImpl
->SetDesc( m_sDesc
);
1409 pImpl
->SetHyperlink( m_pHyperlink
->GetHRef(), m_pHyperlink
->GetName(),
1410 m_pHyperlink
->GetTargetFrameName(), m_pHyperlink
->GetMap() );
1411 m_pHyperlink
.reset();
1414 GetImport().GetTextImport()->StoreLastImportedFrameName(pImpl
->GetOrigName());
1417 css::uno::Reference
< css::xml::sax::XFastContextHandler
> XMLTextFrameContext::createFastChildContext(
1419 const uno::Reference
< xml::sax::XFastAttributeList
>& xAttrList
)
1421 SvXMLImportContextRef xContext
;
1423 if( !m_xImplContext
.is() )
1426 if( IsTokenInNamespace(nElement
, XML_NAMESPACE_DRAW
) )
1428 sal_uInt16 nFrameType
= USHRT_MAX
;
1429 switch (nElement
& TOKEN_MASK
)
1432 nFrameType
= XML_TEXT_FRAME_TEXTBOX
;
1435 nFrameType
= XML_TEXT_FRAME_GRAPHIC
;
1438 nFrameType
= XML_TEXT_FRAME_OBJECT
;
1440 case XML_OBJECT_OLE
:
1441 nFrameType
= XML_TEXT_FRAME_OBJECT_OLE
;
1444 nFrameType
= XML_TEXT_FRAME_APPLET
;
1447 nFrameType
= XML_TEXT_FRAME_PLUGIN
;
1449 case XML_FLOATING_FRAME
:
1450 nFrameType
= XML_TEXT_FRAME_FLOATING_FRAME
;
1454 if( USHRT_MAX
!= nFrameType
)
1456 // Shapes in Writer cannot be named via context menu (#i51726#)
1457 if ( ( XML_TEXT_FRAME_TEXTBOX
== nFrameType
||
1458 XML_TEXT_FRAME_GRAPHIC
== nFrameType
) &&
1459 m_HasAutomaticStyleWithoutParentStyle
)
1461 Reference
< XShapes
> xShapes
;
1462 xContext
= XMLShapeImportHelper::CreateFrameChildContext(
1463 GetImport(), nElement
, xAttrList
, xShapes
, m_xAttrList
);
1465 else if( XML_TEXT_FRAME_PLUGIN
== nFrameType
)
1467 bool bMedia
= false;
1469 // check, if we have a media object
1470 for( auto& aIter
: sax_fastparser::castToFastAttributeList(xAttrList
) )
1472 if( aIter
.getToken() == XML_ELEMENT(DRAW
, XML_MIME_TYPE
) )
1474 if( aIter
.toString() == "application/vnd.sun.star.media" )
1484 Reference
< XShapes
> xShapes
;
1485 xContext
= XMLShapeImportHelper::CreateFrameChildContext(
1486 GetImport(), nElement
, xAttrList
, xShapes
, m_xAttrList
);
1489 else if( XML_TEXT_FRAME_OBJECT
== nFrameType
||
1490 XML_TEXT_FRAME_OBJECT_OLE
== nFrameType
)
1492 m_bSupportsReplacement
= true;
1494 else if(XML_TEXT_FRAME_GRAPHIC
== nFrameType
)
1496 setSupportsMultipleContents( (nElement
& TOKEN_MASK
) == XML_IMAGE
);
1501 xContext
= new XMLTextFrameContext_Impl( GetImport(), nElement
,
1503 m_eDefaultAnchorType
,
1508 m_xImplContext
= xContext
;
1510 if(getSupportsMultipleContents() && XML_TEXT_FRAME_GRAPHIC
== nFrameType
)
1512 addContent(*m_xImplContext
);
1517 else if(getSupportsMultipleContents() && nElement
== XML_ELEMENT(DRAW
, XML_IMAGE
))
1519 // read another image
1520 xContext
= new XMLTextFrameContext_Impl(
1521 GetImport(), nElement
, xAttrList
,
1522 m_eDefaultAnchorType
, XML_TEXT_FRAME_GRAPHIC
, m_xAttrList
, true);
1524 m_xImplContext
= xContext
;
1525 addContent(*m_xImplContext
);
1527 else if( m_bSupportsReplacement
&& !m_xReplImplContext
.is() &&
1528 nElement
== XML_ELEMENT(DRAW
, XML_IMAGE
) )
1530 // read replacement image
1531 Reference
< XPropertySet
> xPropSet
;
1532 if( CreateIfNotThere( xPropSet
) )
1534 xContext
= new XMLReplacementImageContext( GetImport(),
1535 nElement
, xAttrList
, xPropSet
);
1536 m_xReplImplContext
= xContext
;
1539 else if( nullptr != dynamic_cast< const XMLTextFrameContext_Impl
*>( m_xImplContext
.get() ))
1541 // the child is a writer frame
1542 if( IsTokenInNamespace(nElement
, XML_NAMESPACE_SVG
) ||
1543 IsTokenInNamespace(nElement
, XML_NAMESPACE_SVG_COMPAT
) )
1545 // Implement Title/Description Elements UI (#i73249#)
1546 const bool bOld
= SvXMLImport::OOo_2x
>= GetImport().getGeneratorVersion();
1549 if ( (nElement
& TOKEN_MASK
) == XML_DESC
)
1551 xContext
= new XMLTextFrameTitleOrDescContext_Impl( GetImport(),
1557 if( (nElement
& TOKEN_MASK
) == XML_TITLE
)
1559 if (getSupportsMultipleContents())
1560 { // tdf#103567 ensure props are set on surviving shape
1561 m_xImplContext
= solveMultipleImages();
1563 xContext
= new XMLTextFrameTitleOrDescContext_Impl( GetImport(),
1566 else if ( (nElement
& TOKEN_MASK
) == XML_DESC
)
1568 if (getSupportsMultipleContents())
1569 { // tdf#103567 ensure props are set on surviving shape
1570 m_xImplContext
= solveMultipleImages();
1572 xContext
= new XMLTextFrameTitleOrDescContext_Impl( GetImport(),
1577 else if( IsTokenInNamespace(nElement
, XML_NAMESPACE_DRAW
) )
1579 Reference
< XPropertySet
> xPropSet
;
1580 if( (nElement
& TOKEN_MASK
) == XML_CONTOUR_POLYGON
)
1582 if (getSupportsMultipleContents())
1583 { // tdf#103567 ensure props are set on surviving shape
1584 m_xImplContext
= solveMultipleImages();
1586 if( CreateIfNotThere( xPropSet
) )
1587 xContext
= new XMLTextFrameContourContext_Impl( GetImport(), nElement
,
1588 xAttrList
, xPropSet
, false );
1590 else if( (nElement
& TOKEN_MASK
) == XML_CONTOUR_PATH
)
1592 if (getSupportsMultipleContents())
1593 { // tdf#103567 ensure props are set on surviving shape
1594 m_xImplContext
= solveMultipleImages();
1596 if( CreateIfNotThere( xPropSet
) )
1597 xContext
= new XMLTextFrameContourContext_Impl( GetImport(), nElement
,
1598 xAttrList
, xPropSet
, true );
1600 else if( (nElement
& TOKEN_MASK
) == XML_IMAGE_MAP
)
1602 if (getSupportsMultipleContents())
1603 { // tdf#103567 ensure props are set on surviving shape
1604 m_xImplContext
= solveMultipleImages();
1606 if( CreateIfNotThere( xPropSet
) )
1607 xContext
= new XMLImageMapContext( GetImport(), xPropSet
);
1610 else if( nElement
== XML_ELEMENT(OFFICE
, XML_EVENT_LISTENERS
) )
1612 if (getSupportsMultipleContents())
1613 { // tdf#103567 ensure props are set on surviving shape
1614 m_xImplContext
= solveMultipleImages();
1616 // do we still have the frame object?
1617 Reference
< XPropertySet
> xPropSet
;
1618 if( CreateIfNotThere( xPropSet
) )
1620 // is it an event supplier?
1621 Reference
<XEventsSupplier
> xEventsSupplier(xPropSet
, UNO_QUERY
);
1622 if (xEventsSupplier
.is())
1624 // OK, we have the events, so create the context
1625 xContext
= new XMLEventsImportContext(GetImport(), xEventsSupplier
);
1631 else if( nElement
== XML_ELEMENT(SVG
, XML_TITLE
) || nElement
== XML_ELEMENT(SVG
, XML_DESC
) ||
1632 nElement
== XML_ELEMENT(SVG_COMPAT
, XML_TITLE
) || nElement
== XML_ELEMENT(SVG_COMPAT
, XML_DESC
) )
1634 if (getSupportsMultipleContents())
1635 { // tdf#103567 ensure props are set on surviving shape
1636 // note: no more draw:image can be added once we get here
1637 m_xImplContext
= solveMultipleImages();
1639 xContext
= static_cast<SvXMLImportContext
*>(m_xImplContext
->createFastChildContext( nElement
, xAttrList
).get());
1641 else if (nElement
== XML_ELEMENT(LO_EXT
, XML_SIGNATURELINE
))
1643 if (getSupportsMultipleContents())
1644 { // tdf#103567 ensure props are set on surviving shape
1645 // note: no more draw:image can be added once we get here
1646 m_xImplContext
= solveMultipleImages();
1648 xContext
= static_cast<SvXMLImportContext
*>(m_xImplContext
->createFastChildContext(nElement
, xAttrList
).get());
1650 else if (nElement
== XML_ELEMENT(LO_EXT
, XML_QRCODE
))
1652 if (getSupportsMultipleContents())
1653 { // tdf#103567 ensure props are set on surviving shape
1654 // note: no more draw:image can be added once we get here
1655 m_xImplContext
= solveMultipleImages();
1657 xContext
= static_cast<SvXMLImportContext
*>(m_xImplContext
->createFastChildContext(nElement
, xAttrList
).get());
1659 else if (nElement
== XML_ELEMENT(DRAW
, XML_A
))
1661 xContext
= static_cast<SvXMLImportContext
*>(m_xImplContext
->createFastChildContext(nElement
, xAttrList
).get());
1665 // the child is a drawing shape
1666 return XMLShapeImportHelper::CreateFrameChildContext(
1667 m_xImplContext
.get(), nElement
, xAttrList
);
1673 void XMLTextFrameContext::SetHyperlink( const OUString
& rHRef
,
1674 const OUString
& rName
,
1675 const OUString
& rTargetFrameName
,
1678 OSL_ENSURE( !m_pHyperlink
, "recursive SetHyperlink call" );
1679 m_pHyperlink
= std::make_unique
<XMLTextFrameContextHyperlink_Impl
>(
1680 rHRef
, rName
, rTargetFrameName
, bMap
);
1683 TextContentAnchorType
XMLTextFrameContext::GetAnchorType() const
1685 SvXMLImportContext
*pContext
= m_xImplContext
.get();
1686 XMLTextFrameContext_Impl
*pImpl
= dynamic_cast< XMLTextFrameContext_Impl
*>( pContext
);
1688 return pImpl
->GetAnchorType();
1690 return m_eDefaultAnchorType
;
1693 Reference
< XTextContent
> XMLTextFrameContext::GetTextContent() const
1695 Reference
< XTextContent
> xTxtCntnt
;
1696 SvXMLImportContext
*pContext
= m_xImplContext
.get();
1697 XMLTextFrameContext_Impl
*pImpl
= dynamic_cast< XMLTextFrameContext_Impl
* >( pContext
);
1699 xTxtCntnt
.set( pImpl
->GetPropSet(), UNO_QUERY
);
1704 Reference
< XShape
> XMLTextFrameContext::GetShape() const
1706 Reference
< XShape
> xShape
;
1707 SvXMLImportContext
* pContext
= m_xImplContext
.get();
1708 SvXMLShapeContext
* pImpl
= dynamic_cast<SvXMLShapeContext
*>( pContext
);
1711 xShape
= pImpl
->getShape();
1717 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */