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 <config_wasm_strip.h>
24 #include <sal/log.hxx>
25 #include <com/sun/star/document/XEventsSupplier.hpp>
26 #include <com/sun/star/container/XNameReplace.hpp>
27 #include <com/sun/star/presentation/ClickAction.hpp>
28 #include <com/sun/star/drawing/FillStyle.hpp>
29 #include <com/sun/star/drawing/LineStyle.hpp>
31 #include <xmloff/unointerfacetouniqueidentifiermapper.hxx>
32 #include <com/sun/star/drawing/XGluePointsSupplier.hpp>
33 #include <com/sun/star/drawing/GluePoint2.hpp>
34 #include <com/sun/star/drawing/Alignment.hpp>
35 #include <com/sun/star/drawing/EscapeDirection.hpp>
36 #include <com/sun/star/media/ZoomLevel.hpp>
37 #include <com/sun/star/awt/Rectangle.hpp>
38 #include <com/sun/star/style/XStyleFamiliesSupplier.hpp>
39 #include <com/sun/star/container/XNameAccess.hpp>
40 #include "ximpshap.hxx"
41 #include <xmloff/XMLBase64ImportContext.hxx>
42 #include <xmloff/XMLShapeStyleContext.hxx>
43 #include <xmloff/xmluconv.hxx>
44 #include <com/sun/star/container/XNamed.hpp>
45 #include <com/sun/star/beans/XPropertySet.hpp>
46 #include <com/sun/star/awt/XControlModel.hpp>
47 #include <com/sun/star/drawing/XControlShape.hpp>
48 #include <com/sun/star/drawing/PointSequenceSequence.hpp>
49 #include <com/sun/star/drawing/PointSequence.hpp>
50 #include <com/sun/star/lang/XServiceInfo.hpp>
51 #include <com/sun/star/lang/XMultiServiceFactory.hpp>
52 #include <com/sun/star/util/XCloneable.hpp>
53 #include <com/sun/star/beans/XMultiPropertyStates.hpp>
54 #include <xexptran.hxx>
55 #include <com/sun/star/drawing/PolyPolygonBezierCoords.hpp>
56 #include <com/sun/star/beans/XPropertySetInfo.hpp>
57 #include <com/sun/star/drawing/HomogenMatrix3.hpp>
58 #include <com/sun/star/graphic/XGraphic.hpp>
59 #include <com/sun/star/style/XStyle.hpp>
61 #include <sax/tools/converter.hxx>
62 #include <comphelper/sequence.hxx>
63 #include <comphelper/diagnose_ex.hxx>
64 #include <comphelper/mediamimetype.hxx>
66 #include <xmloff/families.hxx>
67 #include<xmloff/xmlnamespace.hxx>
68 #include <xmloff/xmltoken.hxx>
69 #include <EnhancedCustomShapeToken.hxx>
70 #include <XMLReplacementImageContext.hxx>
71 #include <XMLImageMapContext.hxx>
72 #include "sdpropls.hxx"
73 #include "eventimp.hxx"
74 #include "descriptionimp.hxx"
75 #include "SignatureLineContext.hxx"
76 #include "QRCodeContext.hxx"
77 #include "ximpcustomshape.hxx"
78 #include <XMLEmbeddedObjectImportContext.hxx>
79 #include <xmloff/xmlerror.hxx>
80 #include <xmloff/table/XMLTableImport.hxx>
81 #include <xmloff/ProgressBarHelper.hxx>
82 #include <basegfx/matrix/b2dhommatrix.hxx>
83 #include <com/sun/star/drawing/XEnhancedCustomShapeDefaulter.hpp>
84 #include <com/sun/star/container/XChild.hpp>
85 #include <com/sun/star/text/XTextDocument.hpp>
86 #include <basegfx/matrix/b2dhommatrixtools.hxx>
87 #include <basegfx/point/b2dpoint.hxx>
88 #include <basegfx/polygon/b2dpolygon.hxx>
89 #include <basegfx/polygon/b2dpolygontools.hxx>
90 #include <basegfx/polygon/b2dpolypolygon.hxx>
91 #include <basegfx/polygon/b2dpolypolygontools.hxx>
92 #include <basegfx/vector/b2dvector.hxx>
93 #include <tools/urlobj.hxx>
94 #include <o3tl/any.hxx>
95 #include <o3tl/safeint.hxx>
97 using namespace ::com::sun::star
;
98 using namespace ::com::sun::star::uno
;
99 using namespace ::com::sun::star::drawing
;
100 using namespace ::com::sun::star::style
;
101 using namespace ::com::sun::star::container
;
102 using namespace ::com::sun::star::document
;
103 using namespace ::xmloff::token
;
104 using namespace ::xmloff::EnhancedCustomShapeToken
;
106 SvXMLEnumMapEntry
<drawing::Alignment
> const aXML_GlueAlignment_EnumMap
[] =
108 { XML_TOP_LEFT
, drawing::Alignment_TOP_LEFT
},
109 { XML_TOP
, drawing::Alignment_TOP
},
110 { XML_TOP_RIGHT
, drawing::Alignment_TOP_RIGHT
},
111 { XML_LEFT
, drawing::Alignment_LEFT
},
112 { XML_CENTER
, drawing::Alignment_CENTER
},
113 { XML_RIGHT
, drawing::Alignment_RIGHT
},
114 { XML_BOTTOM_LEFT
, drawing::Alignment_BOTTOM_LEFT
},
115 { XML_BOTTOM
, drawing::Alignment_BOTTOM
},
116 { XML_BOTTOM_RIGHT
, drawing::Alignment_BOTTOM_RIGHT
},
117 { XML_TOKEN_INVALID
, drawing::Alignment(0) }
120 SvXMLEnumMapEntry
<drawing::EscapeDirection
> const aXML_GlueEscapeDirection_EnumMap
[] =
122 { XML_AUTO
, drawing::EscapeDirection_SMART
},
123 { XML_LEFT
, drawing::EscapeDirection_LEFT
},
124 { XML_RIGHT
, drawing::EscapeDirection_RIGHT
},
125 { XML_UP
, drawing::EscapeDirection_UP
},
126 { XML_DOWN
, drawing::EscapeDirection_DOWN
},
127 { XML_HORIZONTAL
, drawing::EscapeDirection_HORIZONTAL
},
128 { XML_VERTICAL
, drawing::EscapeDirection_VERTICAL
},
129 { XML_TOKEN_INVALID
, drawing::EscapeDirection(0) }
132 static bool ImpIsEmptyURL( std::u16string_view rURL
)
137 // #i13140# Also compare against 'toplevel' URLs. which also
138 // result in empty filename strings.
146 SdXMLShapeContext::SdXMLShapeContext(
147 SvXMLImport
& rImport
,
148 css::uno::Reference
< css::xml::sax::XFastAttributeList
> xAttrList
,
149 uno::Reference
< drawing::XShapes
> xShapes
,
150 bool bTemporaryShape
)
151 : SvXMLShapeContext( rImport
, bTemporaryShape
)
152 , mxShapes(std::move( xShapes
))
153 , mxAttrList(std::move(xAttrList
))
154 , mbListContextPushed( false )
155 , mnStyleFamily(XmlStyleFamily::SD_GRAPHICS_ID
)
156 , mbIsPlaceholder(false)
157 , mbClearDefaultAttributes( true )
158 , mbIsUserTransformed(false)
171 SdXMLShapeContext::~SdXMLShapeContext()
175 css::uno::Reference
< css::xml::sax::XFastContextHandler
> SdXMLShapeContext::createFastChildContext(
177 const css::uno::Reference
< css::xml::sax::XFastAttributeList
>& xAttrList
)
179 SvXMLImportContextRef xContext
;
181 if( nElement
== XML_ELEMENT(SVG
, XML_TITLE
) || nElement
== XML_ELEMENT(SVG
, XML_DESC
)
182 || nElement
== XML_ELEMENT(SVG_COMPAT
, XML_TITLE
) || nElement
== XML_ELEMENT(SVG_COMPAT
, XML_DESC
) )
184 xContext
= new SdXMLDescriptionContext( GetImport(), nElement
, mxShape
);
186 else if( nElement
== XML_ELEMENT(LO_EXT
, XML_SIGNATURELINE
) )
188 xContext
= new SignatureLineContext( GetImport(), nElement
, xAttrList
, mxShape
);
190 else if( nElement
== XML_ELEMENT(LO_EXT
, XML_QRCODE
) )
192 xContext
= new QRCodeContext( GetImport(), nElement
, xAttrList
, mxShape
);
194 else if( nElement
== XML_ELEMENT(OFFICE
, XML_EVENT_LISTENERS
) )
196 xContext
= new SdXMLEventsContext( GetImport(), mxShape
);
198 else if( nElement
== XML_ELEMENT(DRAW
, XML_GLUE_POINT
) )
200 addGluePoint( xAttrList
);
202 else if( nElement
== XML_ELEMENT(DRAW
, XML_THUMBNAIL
) )
204 // search attributes for xlink:href
205 maThumbnailURL
= xAttrList
->getOptionalValue(XML_ELEMENT(XLINK
, XML_HREF
));
209 // create text cursor on demand
212 uno::Reference
< text::XText
> xText( mxShape
, uno::UNO_QUERY
);
215 rtl::Reference
< XMLTextImportHelper
> xTxtImport
=
216 GetImport().GetTextImport();
217 mxOldCursor
= xTxtImport
->GetCursor();
218 mxCursor
= xText
->createTextCursor();
221 xTxtImport
->SetCursor( mxCursor
);
224 // remember old list item and block (#91964#) and reset them
225 // for the text frame
226 xTxtImport
->PushListContext();
227 mbListContextPushed
= true;
231 // if we have a text cursor, lets try to import some text
234 xContext
= GetImport().GetTextImport()->CreateTextChildContext(
235 GetImport(), nElement
, xAttrList
,
236 ( mbTextBox
? XMLTextType::TextBox
: XMLTextType::Shape
) );
241 XMLOFF_WARN_UNKNOWN_ELEMENT("xmloff", nElement
);
246 void SdXMLShapeContext::addGluePoint( const uno::Reference
< xml::sax::XFastAttributeList
>& xAttrList
)
248 // get the gluepoints container for this shape if it's not already there
249 if( !mxGluePoints
.is() )
251 uno::Reference
< drawing::XGluePointsSupplier
> xSupplier( mxShape
, uno::UNO_QUERY
);
252 if( !xSupplier
.is() )
255 mxGluePoints
.set( xSupplier
->getGluePoints(), UNO_QUERY
);
257 if( !mxGluePoints
.is() )
261 drawing::GluePoint2 aGluePoint
;
262 aGluePoint
.IsUserDefined
= true;
263 aGluePoint
.Position
.X
= 0;
264 aGluePoint
.Position
.Y
= 0;
265 aGluePoint
.Escape
= drawing::EscapeDirection_SMART
;
266 aGluePoint
.PositionAlignment
= drawing::Alignment_CENTER
;
267 aGluePoint
.IsRelative
= true;
271 // read attributes for the 3DScene
272 for( auto& aIter
: sax_fastparser::castToFastAttributeList(xAttrList
) )
274 switch(aIter
.getToken())
276 case XML_ELEMENT(SVG
, XML_X
):
277 case XML_ELEMENT(SVG_COMPAT
, XML_X
):
278 GetImport().GetMM100UnitConverter().convertMeasureToCore(
279 aGluePoint
.Position
.X
, aIter
.toView());
281 case XML_ELEMENT(SVG
, XML_Y
):
282 case XML_ELEMENT(SVG_COMPAT
, XML_Y
):
283 GetImport().GetMM100UnitConverter().convertMeasureToCore(
284 aGluePoint
.Position
.Y
, aIter
.toView());
286 case XML_ELEMENT(DRAW
, XML_ID
):
287 nId
= aIter
.toInt32();
289 case XML_ELEMENT(DRAW
, XML_ALIGN
):
291 drawing::Alignment eKind
;
292 if( SvXMLUnitConverter::convertEnum( eKind
, aIter
.toView(), aXML_GlueAlignment_EnumMap
) )
294 aGluePoint
.PositionAlignment
= eKind
;
295 aGluePoint
.IsRelative
= false;
299 case XML_ELEMENT(DRAW
, XML_ESCAPE_DIRECTION
):
301 SvXMLUnitConverter::convertEnum( aGluePoint
.Escape
, aIter
.toView(), aXML_GlueEscapeDirection_EnumMap
);
305 XMLOFF_WARN_UNKNOWN("xmloff", aIter
);
313 sal_Int32 nInternalId
= mxGluePoints
->insert( uno::Any( aGluePoint
) );
314 GetImport().GetShapeImport()->addGluePointMapping( mxShape
, nId
, nInternalId
);
316 catch(const uno::Exception
&)
318 DBG_UNHANDLED_EXCEPTION( "xmloff", "during setting of gluepoints");
323 void SdXMLShapeContext::startFastElement (sal_Int32
/*nElement*/,
324 const css::uno::Reference
< css::xml::sax::XFastAttributeList
>& /*xAttrList*/)
326 GetImport().GetShapeImport()->finishShape( mxShape
, mxAttrList
, mxShapes
);
329 void SdXMLShapeContext::endFastElement(sal_Int32
)
333 // tdf#72776 force UpdateData in the EditSource so we will not override text in SdrOutliner
334 if( mxLockable
.is() )
336 mxLockable
->removeActionLock();
337 mxLockable
->addActionLock();
340 // delete addition newline
341 mxCursor
->gotoEnd( false );
342 mxCursor
->goLeft( 1, true );
343 mxCursor
->setString( "" );
346 GetImport().GetTextImport()->ResetCursor();
350 GetImport().GetTextImport()->SetCursor( mxOldCursor
);
352 // reinstall old list item (if necessary) #91964#
353 if (mbListContextPushed
) {
354 GetImport().GetTextImport()->PopListContext();
357 if( !msHyperlink
.isEmpty() ) try
359 uno::Reference
< beans::XPropertySet
> xProp( mxShape
, uno::UNO_QUERY
);
361 if ( xProp
.is() && xProp
->getPropertySetInfo()->hasPropertyByName( "Hyperlink" ) )
362 xProp
->setPropertyValue( "Hyperlink", uno::Any( msHyperlink
) );
363 Reference
< XEventsSupplier
> xEventsSupplier( mxShape
, UNO_QUERY
);
365 if( xEventsSupplier
.is() )
367 Reference
< XNameReplace
> xEvents( xEventsSupplier
->getEvents(), UNO_SET_THROW
);
369 uno::Sequence
< beans::PropertyValue
> aProperties
{
370 { /* Name */ "EventType",
372 /* Value */ uno::Any(OUString( "Presentation" )),
373 /* State */ beans::PropertyState_DIRECT_VALUE
},
375 { /* Name */ "ClickAction",
377 /* Value */ uno::Any(css::presentation::ClickAction_DOCUMENT
),
378 /* State */ beans::PropertyState_DIRECT_VALUE
},
380 { /* Name */ "Bookmark",
382 /* Value */ uno::Any(msHyperlink
),
383 /* State */ beans::PropertyState_DIRECT_VALUE
}
386 xEvents
->replaceByName( "OnClick", Any( aProperties
) );
390 // in draw use the Bookmark property
391 Reference
< beans::XPropertySet
> xSet( mxShape
, UNO_QUERY_THROW
);
392 xSet
->setPropertyValue( "Bookmark", Any( msHyperlink
) );
393 xSet
->setPropertyValue("OnClick", Any( css::presentation::ClickAction_DOCUMENT
) );
396 catch(const Exception
&)
398 DBG_UNHANDLED_EXCEPTION("xmloff", "while setting hyperlink");
401 if( mxLockable
.is() )
402 mxLockable
->removeActionLock();
405 void SdXMLShapeContext::AddShape(uno::Reference
< drawing::XShape
>& xShape
)
412 if(!maShapeName
.isEmpty())
414 uno::Reference
< container::XNamed
> xNamed( mxShape
, uno::UNO_QUERY
);
416 xNamed
->setName( maShapeName
);
419 rtl::Reference
< XMLShapeImportHelper
> xImp( GetImport().GetShapeImport() );
420 xImp
->addShape( xShape
, mxAttrList
, mxShapes
);
422 if( mbClearDefaultAttributes
)
424 uno::Reference
<beans::XMultiPropertyStates
> xMultiPropertyStates(xShape
, uno::UNO_QUERY
);
425 if (xMultiPropertyStates
.is())
426 xMultiPropertyStates
->setAllPropertiesToDefault();
429 if( !mbVisible
|| !mbPrintable
) try
431 uno::Reference
< beans::XPropertySet
> xSet( xShape
, uno::UNO_QUERY_THROW
);
433 xSet
->setPropertyValue("Visible", uno::Any( false ) );
436 xSet
->setPropertyValue("Printable", uno::Any( false ) );
438 catch(const Exception
&)
440 DBG_UNHANDLED_EXCEPTION( "xmloff", "while setting visible or printable" );
443 if(!mbTemporaryShape
&& (!GetImport().HasTextImport()
444 || !GetImport().GetTextImport()->IsInsideDeleteContext()))
446 xImp
->shapeWithZIndexAdded( xShape
, mnZOrder
);
449 if (mnRelWidth
|| mnRelHeight
)
451 uno::Reference
<beans::XPropertySet
> xPropertySet(xShape
, uno::UNO_QUERY
);
452 uno::Reference
<beans::XPropertySetInfo
> xPropertySetInfo
= xPropertySet
->getPropertySetInfo();
453 if (mnRelWidth
&& xPropertySetInfo
->hasPropertyByName("RelativeWidth"))
454 xPropertySet
->setPropertyValue("RelativeWidth", uno::Any(mnRelWidth
));
455 if (mnRelHeight
&& xPropertySetInfo
->hasPropertyByName("RelativeHeight"))
456 xPropertySet
->setPropertyValue("RelativeHeight", uno::Any(mnRelHeight
));
459 if( !maShapeId
.isEmpty() )
461 uno::Reference
< uno::XInterface
> xRef( static_cast<uno::XInterface
*>(xShape
.get()) );
462 GetImport().getInterfaceToIdentifierMapper().registerReference( maShapeId
, xRef
);
465 // #91065# count only if counting for shape import is enabled
466 if(GetImport().GetShapeImport()->IsHandleProgressBarEnabled())
468 // #80365# increment progress bar at load once for each draw object
469 GetImport().GetProgressBarHelper()->Increment();
473 mxLockable
.set( xShape
, UNO_QUERY
);
475 if( mxLockable
.is() )
476 mxLockable
->addActionLock();
480 void SdXMLShapeContext::AddShape(OUString
const & serviceName
)
482 uno::Reference
< lang::XMultiServiceFactory
> xServiceFact(GetImport().GetModel(), uno::UNO_QUERY
);
483 if(!xServiceFact
.is())
488 /* Since fix for issue i33294 the Writer model doesn't support
489 com.sun.star.drawing.OLE2Shape anymore.
490 To handle Draw OLE objects it's decided to import these
491 objects as com.sun.star.drawing.OLE2Shape and convert these
492 objects after the import into com.sun.star.drawing.GraphicObjectShape.
494 uno::Reference
< drawing::XShape
> xShape
;
495 if ( serviceName
== "com.sun.star.drawing.OLE2Shape" &&
496 uno::Reference
< text::XTextDocument
>(GetImport().GetModel(), uno::UNO_QUERY
).is() )
498 xShape
.set(xServiceFact
->createInstance("com.sun.star.drawing.temporaryForXMLImportOLE2Shape"), uno::UNO_QUERY
);
500 else if (serviceName
== "com.sun.star.drawing.GraphicObjectShape"
501 || serviceName
== "com.sun.star.drawing.AppletShape"
502 || serviceName
== "com.sun.star.drawing.FrameShape"
503 || serviceName
== "com.sun.star.drawing.MediaShape"
504 || serviceName
== "com.sun.star.drawing.OLE2Shape"
505 || serviceName
== "com.sun.star.drawing.PluginShape"
506 || serviceName
== "com.sun.star.presentation.MediaShape")
508 // On adding another entry to this list of service names to pass an argument via the WithArguments variant
509 // you may need to adjust the more obscure OReportDefinition::createInstanceWithArguments as well as the
510 // more obvious SvxUnoDrawMSFactory::createInstanceWithArguments
511 xShape
.set( xServiceFact
->createInstanceWithArguments(serviceName
, { css::uno::Any(GetImport().GetDocumentBase()) }),
512 css::uno::UNO_QUERY
);
516 xShape
.set(xServiceFact
->createInstance(serviceName
), uno::UNO_QUERY
);
521 catch(const uno::Exception
& e
)
523 TOOLS_WARN_EXCEPTION("xmloff", "AddShape " << serviceName
);
524 uno::Sequence
<OUString
> aSeq
{ serviceName
};
525 GetImport().SetError( XMLERROR_FLAG_ERROR
| XMLERROR_API
,
526 aSeq
, e
.Message
, nullptr );
530 void SdXMLShapeContext::SetTransformation()
535 uno::Reference
< beans::XPropertySet
> xPropSet(mxShape
, uno::UNO_QUERY
);
539 maUsedTransformation
.identity();
541 if(maSize
.Width
!= 1 || maSize
.Height
!= 1)
543 // take care there are no zeros used by error
544 if(0 == maSize
.Width
)
546 if(0 == maSize
.Height
)
549 // set global size. This should always be used.
550 maUsedTransformation
.scale(maSize
.Width
, maSize
.Height
);
553 if(maPosition
.X
!= 0 || maPosition
.Y
!= 0)
555 // if global position is used, add it to transformation
556 maUsedTransformation
.translate(maPosition
.X
, maPosition
.Y
);
559 if(mnTransform
.NeedsAction())
561 // transformation is used, apply to object.
562 // NOTICE: The transformation is applied AFTER evtl. used
563 // global positioning and scaling is used, so any shear or
564 // rotate used herein is applied around the (0,0) position
565 // of the PAGE object !!!
566 ::basegfx::B2DHomMatrix aMat
;
567 mnTransform
.GetFullTransform(aMat
);
569 // now add to transformation
570 maUsedTransformation
*= aMat
;
573 // now set transformation for this object
575 // maUsedTransformtion contains the mathematical correct matrix, which if
576 // applied to a unit square would generate the transformed shape. But the property
577 // "Transformation" contains a matrix, which can be used in TRSetBaseGeometry
578 // and would be created by TRGetBaseGeometry. And those use a mathematically wrong
579 // sign for the shearing angle. So we need to adapt the matrix here.
580 basegfx::B2DTuple aScale
;
581 basegfx::B2DTuple aTranslate
;
584 maUsedTransformation
.decompose(aScale
, aTranslate
, fRotate
, fShearX
);
585 basegfx::B2DHomMatrix aB2DHomMatrix
;
586 aB2DHomMatrix
= basegfx::utils::createScaleShearXRotateTranslateB2DHomMatrix(
588 basegfx::fTools::equalZero(fShearX
) ? 0.0 : -fShearX
,
589 basegfx::fTools::equalZero(fRotate
) ? 0.0 : fRotate
,
591 drawing::HomogenMatrix3 aUnoMatrix
;
593 aUnoMatrix
.Line1
.Column1
= aB2DHomMatrix
.get(0, 0);
594 aUnoMatrix
.Line1
.Column2
= aB2DHomMatrix
.get(0, 1);
595 aUnoMatrix
.Line1
.Column3
= aB2DHomMatrix
.get(0, 2);
597 aUnoMatrix
.Line2
.Column1
= aB2DHomMatrix
.get(1, 0);
598 aUnoMatrix
.Line2
.Column2
= aB2DHomMatrix
.get(1, 1);
599 aUnoMatrix
.Line2
.Column3
= aB2DHomMatrix
.get(1, 2);
601 aUnoMatrix
.Line3
.Column1
= 0;
602 aUnoMatrix
.Line3
.Column2
= 0;
603 aUnoMatrix
.Line3
.Column3
= 1;
605 xPropSet
->setPropertyValue("Transformation", Any(aUnoMatrix
));
608 void SdXMLShapeContext::SetStyle( bool bSupportsStyle
/* = true */)
612 uno::Reference
< beans::XPropertySet
> xPropSet(mxShape
, uno::UNO_QUERY
);
618 // set style on shape
619 if(maDrawStyleName
.isEmpty())
622 const SvXMLStyleContext
* pStyle
= nullptr;
623 bool bAutoStyle(false);
625 if(GetImport().GetShapeImport()->GetAutoStylesContext())
626 pStyle
= GetImport().GetShapeImport()->GetAutoStylesContext()->FindStyleChildContext(mnStyleFamily
, maDrawStyleName
);
631 if(!pStyle
&& GetImport().GetShapeImport()->GetStylesContext())
632 pStyle
= GetImport().GetShapeImport()->GetStylesContext()->FindStyleChildContext(mnStyleFamily
, maDrawStyleName
);
634 OUString aStyleName
= maDrawStyleName
;
635 uno::Reference
< style::XStyle
> xStyle
;
637 XMLPropStyleContext
* pDocStyle
638 = dynamic_cast<XMLShapeStyleContext
*>(const_cast<SvXMLStyleContext
*>(pStyle
));
641 if( pDocStyle
->GetStyle().is() )
643 xStyle
= pDocStyle
->GetStyle();
647 aStyleName
= pDocStyle
->GetParentName();
651 if( !xStyle
.is() && !aStyleName
.isEmpty() )
656 uno::Reference
< style::XStyleFamiliesSupplier
> xFamiliesSupplier( GetImport().GetModel(), uno::UNO_QUERY
);
658 if( xFamiliesSupplier
.is() )
660 uno::Reference
< container::XNameAccess
> xFamilies( xFamiliesSupplier
->getStyleFamilies() );
664 uno::Reference
< container::XNameAccess
> xFamily
;
666 if( XmlStyleFamily::SD_PRESENTATION_ID
== mnStyleFamily
)
668 aStyleName
= GetImport().GetStyleDisplayName(
669 XmlStyleFamily::SD_PRESENTATION_ID
,
671 sal_Int32 nPos
= aStyleName
.lastIndexOf( '-' );
674 OUString
aFamily( aStyleName
.copy( 0, nPos
) );
676 xFamilies
->getByName( aFamily
) >>= xFamily
;
677 aStyleName
= aStyleName
.copy( nPos
+ 1 );
682 // get graphics family
683 if (xFamilies
->hasByName("graphics"))
684 xFamilies
->getByName("graphics") >>= xFamily
;
686 xFamilies
->getByName("GraphicStyles") >>= xFamily
;
688 aStyleName
= GetImport().GetStyleDisplayName(
689 XmlStyleFamily::SD_GRAPHICS_ID
,
694 xFamily
->getByName( aStyleName
) >>= xStyle
;
698 catch(const uno::Exception
&)
700 DBG_UNHANDLED_EXCEPTION( "xmloff", "finding style for shape" );
704 if( bSupportsStyle
&& xStyle
.is() )
708 // set style on object
709 xPropSet
->setPropertyValue("Style", Any(xStyle
));
711 catch(const uno::Exception
&)
713 DBG_UNHANDLED_EXCEPTION( "xmloff", "setting style for shape" );
717 // Writer shapes: if this one has a TextBox, set it here. We need to do it before
718 // pDocStyle->FillPropertySet, because setting some properties depend on the format
719 // having RES_CNTNT attribute (e.g., UNO_NAME_TEXT_(LEFT|RIGHT|UPPER|LOWER)DIST; see
720 // SwTextBoxHelper::syncProperty, which indirectly calls SwTextBoxHelper::isTextBox)
721 uno::Reference
<beans::XPropertySetInfo
> xPropertySetInfo
722 = xPropSet
->getPropertySetInfo();
723 static constexpr OUString sTextBox
= u
"TextBox"_ustr
;
724 if (xPropertySetInfo
->hasPropertyByName(sTextBox
))
725 xPropSet
->setPropertyValue(sTextBox
, uno::Any(mbTextBox
));
727 // if this is an auto style, set its properties
728 if(bAutoStyle
&& pDocStyle
)
730 // set PropertySet on object
731 pDocStyle
->FillPropertySet(xPropSet
);
736 // try to set text auto style
739 // set style on shape
740 if( maTextStyleName
.isEmpty() )
743 if( nullptr == GetImport().GetShapeImport()->GetAutoStylesContext())
746 const SvXMLStyleContext
* pTempStyle
= GetImport().GetShapeImport()->GetAutoStylesContext()->FindStyleChildContext(XmlStyleFamily::TEXT_PARAGRAPH
, maTextStyleName
);
747 XMLPropStyleContext
* pStyle
= const_cast<XMLPropStyleContext
*>(dynamic_cast<const XMLPropStyleContext
*>( pTempStyle
) ); // use temp var, PTR_CAST is a bad macro, FindStyleChildContext will be called twice
748 if( pStyle
== nullptr )
751 // set PropertySet on object
752 pStyle
->FillPropertySet(xPropSet
);
756 catch(const uno::Exception
&)
761 void SdXMLShapeContext::SetLayer()
763 if( maLayerName
.isEmpty() )
768 uno::Reference
< beans::XPropertySet
> xPropSet(mxShape
, uno::UNO_QUERY
);
771 xPropSet
->setPropertyValue("LayerName", Any(maLayerName
));
775 catch(const uno::Exception
&)
780 void SdXMLShapeContext::SetThumbnail()
782 if( maThumbnailURL
.isEmpty() )
787 uno::Reference
< beans::XPropertySet
> xPropSet(mxShape
, uno::UNO_QUERY
);
791 uno::Reference
< beans::XPropertySetInfo
> xPropSetInfo( xPropSet
->getPropertySetInfo() );
792 if( xPropSetInfo
.is() && xPropSetInfo
->hasPropertyByName( "ThumbnailGraphic" ) )
794 // load the thumbnail graphic and export it to a wmf stream so we can set
797 uno::Reference
<graphic::XGraphic
> xGraphic
= GetImport().loadGraphicByURL(maThumbnailURL
);
798 xPropSet
->setPropertyValue("ThumbnailGraphic", uno::Any(xGraphic
));
801 catch(const uno::Exception
&)
806 // this is called from the parent group for each unparsed attribute in the attribute list
807 bool SdXMLShapeContext::processAttribute( const sax_fastparser::FastAttributeList::FastAttributeIter
& aIter
)
810 switch (aIter
.getToken())
812 case XML_ELEMENT(DRAW
, XML_ZINDEX
):
813 case XML_ELEMENT(DRAW_EXT
, XML_ZINDEX
):
814 mnZOrder
= aIter
.toInt32();
816 case XML_ELEMENT(DRAW
, XML_ID
):
817 case XML_ELEMENT(DRAW_EXT
, XML_ID
):
818 if (!mbHaveXmlId
) { maShapeId
= aIter
.toString(); }
820 case XML_ELEMENT(DRAW
, XML_NAME
):
821 case XML_ELEMENT(DRAW_EXT
, XML_NAME
):
822 maShapeName
= aIter
.toString();
824 case XML_ELEMENT(DRAW
, XML_STYLE_NAME
):
825 case XML_ELEMENT(DRAW_EXT
, XML_STYLE_NAME
):
826 maDrawStyleName
= aIter
.toString();
828 case XML_ELEMENT(DRAW
, XML_TEXT_STYLE_NAME
):
829 case XML_ELEMENT(DRAW_EXT
, XML_TEXT_STYLE_NAME
):
830 maTextStyleName
= aIter
.toString();
832 case XML_ELEMENT(DRAW
, XML_LAYER
):
833 case XML_ELEMENT(DRAW_EXT
, XML_LAYER
):
834 maLayerName
= aIter
.toString();
836 case XML_ELEMENT(DRAW
, XML_TRANSFORM
):
837 case XML_ELEMENT(DRAW_EXT
, XML_TRANSFORM
):
838 mnTransform
.SetString(aIter
.toString(), GetImport().GetMM100UnitConverter());
840 case XML_ELEMENT(DRAW
, XML_DISPLAY
):
841 case XML_ELEMENT(DRAW_EXT
, XML_DISPLAY
):
842 mbVisible
= IsXMLToken( aIter
, XML_ALWAYS
) || IsXMLToken( aIter
, XML_SCREEN
);
843 mbPrintable
= IsXMLToken( aIter
, XML_ALWAYS
) || IsXMLToken( aIter
, XML_PRINTER
);
845 case XML_ELEMENT(PRESENTATION
, XML_USER_TRANSFORMED
):
846 mbIsUserTransformed
= IsXMLToken( aIter
, XML_TRUE
);
848 case XML_ELEMENT(PRESENTATION
, XML_PLACEHOLDER
):
849 mbIsPlaceholder
= IsXMLToken( aIter
, XML_TRUE
);
850 if( mbIsPlaceholder
)
851 mbClearDefaultAttributes
= false;
853 case XML_ELEMENT(PRESENTATION
, XML_CLASS
):
854 maPresentationClass
= aIter
.toString();
856 case XML_ELEMENT(PRESENTATION
, XML_STYLE_NAME
):
857 maDrawStyleName
= aIter
.toString();
858 mnStyleFamily
= XmlStyleFamily::SD_PRESENTATION_ID
;
860 case XML_ELEMENT(SVG
, XML_X
):
861 case XML_ELEMENT(SVG_COMPAT
, XML_X
):
862 GetImport().GetMM100UnitConverter().convertMeasureToCore(
863 maPosition
.X
, aIter
.toView());
865 case XML_ELEMENT(SVG
, XML_Y
):
866 case XML_ELEMENT(SVG_COMPAT
, XML_Y
):
867 GetImport().GetMM100UnitConverter().convertMeasureToCore(
868 maPosition
.Y
, aIter
.toView());
870 case XML_ELEMENT(SVG
, XML_WIDTH
):
871 case XML_ELEMENT(SVG_COMPAT
, XML_WIDTH
):
872 GetImport().GetMM100UnitConverter().convertMeasureToCore(
873 maSize
.Width
, aIter
.toView());
874 if (maSize
.Width
> 0)
875 maSize
.Width
= o3tl::saturating_add
<sal_Int32
>(maSize
.Width
, 1);
876 else if (maSize
.Width
< 0)
877 maSize
.Width
= o3tl::saturating_add
<sal_Int32
>(maSize
.Width
, -1);
879 case XML_ELEMENT(SVG
, XML_HEIGHT
):
880 case XML_ELEMENT(SVG_COMPAT
, XML_HEIGHT
):
881 GetImport().GetMM100UnitConverter().convertMeasureToCore(
882 maSize
.Height
, aIter
.toView());
883 if (maSize
.Height
> 0)
884 maSize
.Height
= o3tl::saturating_add
<sal_Int32
>(maSize
.Height
, 1);
885 else if (maSize
.Height
< 0)
886 maSize
.Height
= o3tl::saturating_add
<sal_Int32
>(maSize
.Height
, -1);
888 case XML_ELEMENT(SVG
, XML_TRANSFORM
):
889 case XML_ELEMENT(SVG_COMPAT
, XML_TRANSFORM
):
890 // because of #85127# take svg:transform into account and handle like
891 // draw:transform for compatibility
892 mnTransform
.SetString(aIter
.toString(), GetImport().GetMM100UnitConverter());
894 case XML_ELEMENT(STYLE
, XML_REL_WIDTH
):
895 if (sax::Converter::convertPercent(nTmp
, aIter
.toView()))
896 mnRelWidth
= static_cast<sal_Int16
>(nTmp
);
898 case XML_ELEMENT(STYLE
, XML_REL_HEIGHT
):
899 if (sax::Converter::convertPercent(nTmp
, aIter
.toView()))
900 mnRelHeight
= static_cast<sal_Int16
>(nTmp
);
902 case XML_ELEMENT(NONE
, XML_ID
):
903 case XML_ELEMENT(XML
, XML_ID
):
904 maShapeId
= aIter
.toString();
913 bool SdXMLShapeContext::isPresentationShape() const
915 if( !maPresentationClass
.isEmpty() && const_cast<SdXMLShapeContext
*>(this)->GetImport().GetShapeImport()->IsPresentationShapesSupported() )
917 if(XmlStyleFamily::SD_PRESENTATION_ID
== mnStyleFamily
)
922 if( IsXMLToken( maPresentationClass
, XML_HEADER
) || IsXMLToken( maPresentationClass
, XML_FOOTER
) ||
923 IsXMLToken( maPresentationClass
, XML_PAGE_NUMBER
) || IsXMLToken( maPresentationClass
, XML_DATE_TIME
) )
932 SdXMLRectShapeContext::SdXMLRectShapeContext(
933 SvXMLImport
& rImport
,
934 const css::uno::Reference
< css::xml::sax::XFastAttributeList
>& xAttrList
,
935 uno::Reference
< drawing::XShapes
> const & rShapes
,
936 bool bTemporaryShape
)
937 : SdXMLShapeContext( rImport
, xAttrList
, rShapes
, bTemporaryShape
),
942 SdXMLRectShapeContext::~SdXMLRectShapeContext()
946 // this is called from the parent group for each unparsed attribute in the attribute list
947 bool SdXMLRectShapeContext::processAttribute( const sax_fastparser::FastAttributeList::FastAttributeIter
& aIter
)
949 switch (aIter
.getToken())
951 case XML_ELEMENT(DRAW
, XML_CORNER_RADIUS
):
952 GetImport().GetMM100UnitConverter().convertMeasureToCore(
953 mnRadius
, aIter
.toView());
956 return SdXMLShapeContext::processAttribute( aIter
);
961 void SdXMLRectShapeContext::startFastElement (sal_Int32 nElement
,
962 const css::uno::Reference
< css::xml::sax::XFastAttributeList
>& xAttrList
)
964 // create rectangle shape
965 AddShape("com.sun.star.drawing.RectangleShape");
969 // Add, set Style and properties from base shape
973 // set pos, size, shear and rotate
978 uno::Reference
< beans::XPropertySet
> xPropSet(mxShape
, uno::UNO_QUERY
);
983 xPropSet
->setPropertyValue("CornerRadius", uno::Any( mnRadius
) );
985 catch(const uno::Exception
&)
987 DBG_UNHANDLED_EXCEPTION( "xmloff", "setting corner radius");
991 SdXMLShapeContext::startFastElement(nElement
, xAttrList
);
995 SdXMLLineShapeContext::SdXMLLineShapeContext(
996 SvXMLImport
& rImport
,
997 const css::uno::Reference
< css::xml::sax::XFastAttributeList
>& xAttrList
,
998 uno::Reference
< drawing::XShapes
> const & rShapes
,
999 bool bTemporaryShape
)
1000 : SdXMLShapeContext( rImport
, xAttrList
, rShapes
, bTemporaryShape
),
1008 SdXMLLineShapeContext::~SdXMLLineShapeContext()
1012 // this is called from the parent group for each unparsed attribute in the attribute list
1013 bool SdXMLLineShapeContext::processAttribute( const sax_fastparser::FastAttributeList::FastAttributeIter
& aIter
)
1015 switch (aIter
.getToken())
1017 case XML_ELEMENT(SVG
, XML_X1
):
1018 case XML_ELEMENT(SVG_COMPAT
, XML_X1
):
1019 GetImport().GetMM100UnitConverter().convertMeasureToCore(
1020 mnX1
, aIter
.toView());
1022 case XML_ELEMENT(SVG
, XML_Y1
):
1023 case XML_ELEMENT(SVG_COMPAT
, XML_Y1
):
1024 GetImport().GetMM100UnitConverter().convertMeasureToCore(
1025 mnY1
, aIter
.toView());
1027 case XML_ELEMENT(SVG
, XML_X2
):
1028 case XML_ELEMENT(SVG_COMPAT
, XML_X2
):
1029 GetImport().GetMM100UnitConverter().convertMeasureToCore(
1030 mnX2
, aIter
.toView());
1032 case XML_ELEMENT(SVG
, XML_Y2
):
1033 case XML_ELEMENT(SVG_COMPAT
, XML_Y2
):
1034 GetImport().GetMM100UnitConverter().convertMeasureToCore(
1035 mnY2
, aIter
.toView());
1038 return SdXMLShapeContext::processAttribute( aIter
);
1043 void SdXMLLineShapeContext::startFastElement (sal_Int32 nElement
,
1044 const css::uno::Reference
< css::xml::sax::XFastAttributeList
>& xAttrList
)
1046 // #85920# use SetTransformation() to handle import of simple lines.
1047 // This is necessary to take into account all anchor positions and
1048 // other things. All shape imports use the same import schemata now.
1049 // create necessary shape (Line Shape)
1050 AddShape("com.sun.star.drawing.PolyLineShape");
1055 // Add, set Style and properties from base shape
1059 // get sizes and offsets
1060 awt::Point
aTopLeft(mnX1
, mnY1
);
1061 awt::Point
aBottomRight(mnX2
, mnY2
);
1066 aBottomRight
.X
= mnX1
;
1072 aBottomRight
.Y
= mnY1
;
1075 // set local parameters on shape
1076 uno::Reference
< beans::XPropertySet
> xPropSet(mxShape
, uno::UNO_QUERY
);
1079 drawing::PointSequenceSequence
aPolyPoly(1);
1080 drawing::PointSequence
* pOuterSequence
= aPolyPoly
.getArray();
1081 pOuterSequence
->realloc(2);
1082 awt::Point
* pInnerSequence
= pOuterSequence
->getArray();
1084 *pInnerSequence
= awt::Point(o3tl::saturating_sub(mnX1
, aTopLeft
.X
), o3tl::saturating_sub(mnY1
, aTopLeft
.Y
));
1086 *pInnerSequence
= awt::Point(o3tl::saturating_sub(mnX2
, aTopLeft
.X
), o3tl::saturating_sub(mnY2
, aTopLeft
.Y
));
1088 xPropSet
->setPropertyValue("Geometry", Any(aPolyPoly
));
1091 // Size is included in point coordinates
1094 maPosition
.X
= aTopLeft
.X
;
1095 maPosition
.Y
= aTopLeft
.Y
;
1097 // set pos, size, shear and rotate and get copy of matrix
1098 SetTransformation();
1100 SdXMLShapeContext::startFastElement(nElement
, xAttrList
);
1104 SdXMLEllipseShapeContext::SdXMLEllipseShapeContext(
1105 SvXMLImport
& rImport
,
1106 const css::uno::Reference
< css::xml::sax::XFastAttributeList
>& xAttrList
,
1107 uno::Reference
< drawing::XShapes
> const & rShapes
,
1108 bool bTemporaryShape
)
1109 : SdXMLShapeContext( rImport
, xAttrList
, rShapes
, bTemporaryShape
),
1114 meKind( drawing::CircleKind_FULL
),
1120 SdXMLEllipseShapeContext::~SdXMLEllipseShapeContext()
1124 // this is called from the parent group for each unparsed attribute in the attribute list
1125 bool SdXMLEllipseShapeContext::processAttribute( const sax_fastparser::FastAttributeList::FastAttributeIter
& aIter
)
1127 switch (aIter
.getToken())
1129 case XML_ELEMENT(SVG
, XML_RX
):
1130 case XML_ELEMENT(SVG_COMPAT
, XML_RX
):
1131 GetImport().GetMM100UnitConverter().convertMeasureToCore(
1132 mnRX
, aIter
.toView());
1134 case XML_ELEMENT(SVG
, XML_RY
):
1135 case XML_ELEMENT(SVG_COMPAT
, XML_RY
):
1136 GetImport().GetMM100UnitConverter().convertMeasureToCore(
1137 mnRY
, aIter
.toView());
1139 case XML_ELEMENT(SVG
, XML_CX
):
1140 case XML_ELEMENT(SVG_COMPAT
, XML_CX
):
1141 GetImport().GetMM100UnitConverter().convertMeasureToCore(
1142 mnCX
, aIter
.toView());
1144 case XML_ELEMENT(SVG
, XML_CY
):
1145 case XML_ELEMENT(SVG_COMPAT
, XML_CY
):
1146 GetImport().GetMM100UnitConverter().convertMeasureToCore(
1147 mnCY
, aIter
.toView());
1149 case XML_ELEMENT(SVG
, XML_R
):
1150 case XML_ELEMENT(SVG_COMPAT
, XML_R
):
1151 // single radius, it's a circle and both radii are the same
1152 GetImport().GetMM100UnitConverter().convertMeasureToCore(
1153 mnRX
, aIter
.toView());
1156 case XML_ELEMENT(DRAW
, XML_KIND
):
1157 SvXMLUnitConverter::convertEnum( meKind
, aIter
.toView(), aXML_CircleKind_EnumMap
);
1159 case XML_ELEMENT(DRAW
, XML_START_ANGLE
):
1162 if (::sax::Converter::convertDouble( dStartAngle
, aIter
.toView() ))
1163 mnStartAngle
= static_cast<sal_Int32
>(dStartAngle
* 100.0);
1166 case XML_ELEMENT(DRAW
, XML_END_ANGLE
):
1169 if (::sax::Converter::convertDouble( dEndAngle
, aIter
.toView() ))
1170 mnEndAngle
= static_cast<sal_Int32
>(dEndAngle
* 100.0);
1174 return SdXMLShapeContext::processAttribute( aIter
);
1179 void SdXMLEllipseShapeContext::startFastElement (sal_Int32 nElement
,
1180 const css::uno::Reference
< css::xml::sax::XFastAttributeList
>& xAttrList
)
1182 // create rectangle shape
1183 AddShape("com.sun.star.drawing.EllipseShape");
1187 // Add, set Style and properties from base shape
1191 if(mnCX
!= 0 || mnCY
!= 0 || mnRX
!= 1 || mnRY
!= 1)
1193 // #i121972# center/radius is used, put to pos and size
1194 maSize
.Width
= 2 * mnRX
;
1195 maSize
.Height
= 2 * mnRY
;
1196 maPosition
.X
= mnCX
- mnRX
;
1197 maPosition
.Y
= mnCY
- mnRY
;
1199 // set pos, size, shear and rotate
1200 SetTransformation();
1202 if( meKind
!= drawing::CircleKind_FULL
)
1204 uno::Reference
< beans::XPropertySet
> xPropSet( mxShape
, uno::UNO_QUERY
);
1207 // calculate the correct start and end angle
1208 sal_Int32 mnOldStartAngle
= mnStartAngle
;
1209 sal_Int32 mnOldEndAngle
= mnEndAngle
;
1210 basegfx::B2DTuple aScale
;
1211 basegfx::B2DTuple aTranslate
;
1214 maUsedTransformation
.decompose(aScale
, aTranslate
, fRotate
, fShearX
);
1215 if (aScale
.getX() < 0 || aScale
.getY() < 0)
1217 // The angle for a horizontal flip is the same as the angle for a
1218 // vertical flip because a vertical flip is treated as a horizontal
1219 // flip plus a rotation.
1221 // To perform the flip, the start and end angle are switched and we
1222 // use the fact performing a horizontal flip on a shape will change
1223 // the angle that a radius makes with the origin to 180 degrees
1224 // minus that angle (we use 54000 hundredths of a degree to get the
1225 // modulus operation to give a value between 0 and 36000).
1227 mnStartAngle
= (54000 - mnOldEndAngle
) % 36000;
1228 mnEndAngle
= (54000 - mnOldStartAngle
) % 36000;
1231 xPropSet
->setPropertyValue("CircleKind", Any( meKind
) );
1232 xPropSet
->setPropertyValue("CircleStartAngle", Any(mnStartAngle
) );
1233 xPropSet
->setPropertyValue("CircleEndAngle", Any(mnEndAngle
) );
1237 SdXMLShapeContext::startFastElement(nElement
, xAttrList
);
1241 SdXMLPolygonShapeContext::SdXMLPolygonShapeContext(
1242 SvXMLImport
& rImport
,
1243 const css::uno::Reference
< css::xml::sax::XFastAttributeList
>& xAttrList
,
1244 uno::Reference
< drawing::XShapes
> const & rShapes
, bool bClosed
, bool bTemporaryShape
)
1245 : SdXMLShapeContext( rImport
, xAttrList
, rShapes
, bTemporaryShape
),
1250 // this is called from the parent group for each unparsed attribute in the attribute list
1251 bool SdXMLPolygonShapeContext::processAttribute( const sax_fastparser::FastAttributeList::FastAttributeIter
& aIter
)
1253 switch (aIter
.getToken())
1255 case XML_ELEMENT(SVG
, XML_VIEWBOX
):
1256 case XML_ELEMENT(SVG_COMPAT
, XML_VIEWBOX
):
1257 maViewBox
= aIter
.toString();
1259 case XML_ELEMENT(DRAW
, XML_POINTS
):
1260 maPoints
= aIter
.toString();
1263 return SdXMLShapeContext::processAttribute( aIter
);
1268 SdXMLPolygonShapeContext::~SdXMLPolygonShapeContext()
1272 void SdXMLPolygonShapeContext::startFastElement (sal_Int32 nElement
,
1273 const css::uno::Reference
< css::xml::sax::XFastAttributeList
>& xAttrList
)
1275 // Add, set Style and properties from base shape
1277 AddShape("com.sun.star.drawing.PolyPolygonShape");
1279 AddShape("com.sun.star.drawing.PolyLineShape");
1287 // set local parameters on shape
1288 uno::Reference
< beans::XPropertySet
> xPropSet(mxShape
, uno::UNO_QUERY
);
1292 if(!maPoints
.isEmpty() && !maViewBox
.isEmpty())
1294 const SdXMLImExViewBox
aViewBox(maViewBox
, GetImport().GetMM100UnitConverter());
1295 basegfx::B2DVector
aSize(aViewBox
.GetWidth(), aViewBox
.GetHeight());
1297 // Is this correct? It overrides ViewBox stuff; OTOH it makes no
1298 // sense to have the geometry content size different from object size
1299 if(maSize
.Width
!= 0 && maSize
.Height
!= 0)
1301 aSize
= basegfx::B2DVector(maSize
.Width
, maSize
.Height
);
1304 basegfx::B2DPolygon aPolygon
;
1306 if(basegfx::utils::importFromSvgPoints(aPolygon
, maPoints
))
1308 if(aPolygon
.count())
1310 const basegfx::B2DRange
aSourceRange(
1311 aViewBox
.GetX(), aViewBox
.GetY(),
1312 aViewBox
.GetX() + aViewBox
.GetWidth(), aViewBox
.GetY() + aViewBox
.GetHeight());
1313 const basegfx::B2DRange
aTargetRange(
1314 aViewBox
.GetX(), aViewBox
.GetY(),
1315 aViewBox
.GetX() + aSize
.getX(), aViewBox
.GetY() + aSize
.getY());
1317 if(!aSourceRange
.equal(aTargetRange
))
1320 basegfx::utils::createSourceRangeTargetRangeTransform(
1325 css::drawing::PointSequenceSequence aPointSequenceSequence
;
1326 basegfx::utils::B2DPolyPolygonToUnoPointSequenceSequence(basegfx::B2DPolyPolygon(aPolygon
), aPointSequenceSequence
);
1327 xPropSet
->setPropertyValue("Geometry", Any(aPointSequenceSequence
));
1328 // Size is now contained in the point coordinates, adapt maSize for
1329 // to use the correct transformation matrix in SetTransformation()
1337 // set pos, size, shear and rotate and get copy of matrix
1338 SetTransformation();
1340 SdXMLShapeContext::startFastElement(nElement
, xAttrList
);
1344 SdXMLPathShapeContext::SdXMLPathShapeContext(
1345 SvXMLImport
& rImport
,
1346 const css::uno::Reference
< css::xml::sax::XFastAttributeList
>& xAttrList
,
1347 uno::Reference
< drawing::XShapes
> const & rShapes
,
1348 bool bTemporaryShape
)
1349 : SdXMLShapeContext( rImport
, xAttrList
, rShapes
, bTemporaryShape
)
1353 SdXMLPathShapeContext::~SdXMLPathShapeContext()
1357 // this is called from the parent group for each unparsed attribute in the attribute list
1358 bool SdXMLPathShapeContext::processAttribute( const sax_fastparser::FastAttributeList::FastAttributeIter
& aIter
)
1360 switch (aIter
.getToken())
1362 case XML_ELEMENT(SVG
, XML_VIEWBOX
):
1363 case XML_ELEMENT(SVG_COMPAT
, XML_VIEWBOX
):
1364 maViewBox
= aIter
.toString();
1366 case XML_ELEMENT(SVG
, XML_D
):
1367 case XML_ELEMENT(SVG_COMPAT
, XML_D
):
1368 maD
= aIter
.toString();
1371 return SdXMLShapeContext::processAttribute( aIter
);
1376 void SdXMLPathShapeContext::startFastElement (sal_Int32 nElement
,
1377 const css::uno::Reference
< css::xml::sax::XFastAttributeList
>& xAttrList
)
1379 // create polygon shape
1383 const SdXMLImExViewBox
aViewBox(maViewBox
, GetImport().GetMM100UnitConverter());
1384 basegfx::B2DVector
aSize(aViewBox
.GetWidth(), aViewBox
.GetHeight());
1386 // Is this correct? It overrides ViewBox stuff; OTOH it makes no
1387 // sense to have the geometry content size different from object size
1388 if(maSize
.Width
!= 0 && maSize
.Height
!= 0)
1390 aSize
= basegfx::B2DVector(maSize
.Width
, maSize
.Height
);
1393 basegfx::B2DPolyPolygon aPolyPolygon
;
1395 if(!basegfx::utils::importFromSvgD(aPolyPolygon
, maD
, GetImport().needFixPositionAfterZ(), nullptr))
1398 if(!aPolyPolygon
.count())
1401 const basegfx::B2DRange
aSourceRange(
1402 aViewBox
.GetX(), aViewBox
.GetY(),
1403 aViewBox
.GetX() + aViewBox
.GetWidth(), aViewBox
.GetY() + aViewBox
.GetHeight());
1404 const basegfx::B2DRange
aTargetRange(
1405 aViewBox
.GetX(), aViewBox
.GetY(),
1406 aViewBox
.GetX() + aSize
.getX(), aViewBox
.GetY() + aSize
.getY());
1408 if(!aSourceRange
.equal(aTargetRange
))
1410 aPolyPolygon
.transform(
1411 basegfx::utils::createSourceRangeTargetRangeTransform(
1419 if(aPolyPolygon
.areControlPointsUsed())
1421 if(aPolyPolygon
.isClosed())
1423 service
= "com.sun.star.drawing.ClosedBezierShape";
1427 service
= "com.sun.star.drawing.OpenBezierShape";
1432 if(aPolyPolygon
.isClosed())
1434 service
= "com.sun.star.drawing.PolyPolygonShape";
1438 service
= "com.sun.star.drawing.PolyLineShape";
1442 // Add, set Style and properties from base shape
1445 // #89344# test for mxShape.is() and not for mxShapes.is() to support
1446 // shape import helper classes WITHOUT XShapes (member mxShapes). This
1447 // is used by the writer.
1454 // set local parameters on shape
1455 uno::Reference
< beans::XPropertySet
> xPropSet(mxShape
, uno::UNO_QUERY
);
1462 if(aPolyPolygon
.areControlPointsUsed())
1464 drawing::PolyPolygonBezierCoords aSourcePolyPolygon
;
1466 basegfx::utils::B2DPolyPolygonToUnoPolyPolygonBezierCoords(
1468 aSourcePolyPolygon
);
1469 aAny
<<= aSourcePolyPolygon
;
1473 drawing::PointSequenceSequence aSourcePolyPolygon
;
1475 basegfx::utils::B2DPolyPolygonToUnoPointSequenceSequence(
1477 aSourcePolyPolygon
);
1478 aAny
<<= aSourcePolyPolygon
;
1481 xPropSet
->setPropertyValue("Geometry", aAny
);
1482 // Size is now contained in the point coordinates, adapt maSize for
1483 // to use the correct transformation matrix in SetTransformation()
1488 // set pos, size, shear and rotate
1489 SetTransformation();
1491 SdXMLShapeContext::startFastElement(nElement
, xAttrList
);
1495 SdXMLTextBoxShapeContext::SdXMLTextBoxShapeContext(
1496 SvXMLImport
& rImport
,
1497 const css::uno::Reference
< css::xml::sax::XFastAttributeList
>& xAttrList
,
1498 uno::Reference
< drawing::XShapes
> const & rShapes
)
1499 : SdXMLShapeContext( rImport
, xAttrList
, rShapes
, false/*bTemporaryShape*/ ),
1505 SdXMLTextBoxShapeContext::~SdXMLTextBoxShapeContext()
1509 // this is called from the parent group for each unparsed attribute in the attribute list
1510 bool SdXMLTextBoxShapeContext::processAttribute( const sax_fastparser::FastAttributeList::FastAttributeIter
& aIter
)
1512 switch (aIter
.getToken())
1514 case XML_ELEMENT(DRAW
, XML_CORNER_RADIUS
):
1515 GetImport().GetMM100UnitConverter().convertMeasureToCore(
1516 mnRadius
, aIter
.toView());
1518 case XML_ELEMENT(DRAW
, XML_CHAIN_NEXT_NAME
):
1519 maChainNextName
= aIter
.toString();
1522 return SdXMLShapeContext::processAttribute( aIter
);
1527 void SdXMLTextBoxShapeContext::startFastElement (sal_Int32 nElement
,
1528 const css::uno::Reference
< css::xml::sax::XFastAttributeList
>& xAttrList
)
1530 // create textbox shape
1531 bool bIsPresShape
= false;
1532 bool bClearText
= false;
1536 if( isPresentationShape() )
1538 // check if the current document supports presentation shapes
1539 if( GetImport().GetShapeImport()->IsPresentationShapesSupported() )
1541 if( IsXMLToken( maPresentationClass
, XML_SUBTITLE
))
1543 // XmlShapeType::PresSubtitleShape
1544 service
= "com.sun.star.presentation.SubtitleShape";
1546 else if( IsXMLToken( maPresentationClass
, XML_PRESENTATION_OUTLINE
) )
1548 // XmlShapeType::PresOutlinerShape
1549 service
= "com.sun.star.presentation.OutlinerShape";
1551 else if( IsXMLToken( maPresentationClass
, XML_NOTES
) )
1553 // XmlShapeType::PresNotesShape
1554 service
= "com.sun.star.presentation.NotesShape";
1556 else if( IsXMLToken( maPresentationClass
, XML_HEADER
) )
1558 // XmlShapeType::PresHeaderShape
1559 service
= "com.sun.star.presentation.HeaderShape";
1562 else if( IsXMLToken( maPresentationClass
, XML_FOOTER
) )
1564 // XmlShapeType::PresFooterShape
1565 service
= "com.sun.star.presentation.FooterShape";
1568 else if( IsXMLToken( maPresentationClass
, XML_PAGE_NUMBER
) )
1570 // XmlShapeType::PresSlideNumberShape
1571 service
= "com.sun.star.presentation.SlideNumberShape";
1574 else if( IsXMLToken( maPresentationClass
, XML_DATE_TIME
) )
1576 // XmlShapeType::PresDateTimeShape
1577 service
= "com.sun.star.presentation.DateTimeShape";
1580 else // IsXMLToken( maPresentationClass, XML_TITLE ) )
1582 // XmlShapeType::PresTitleTextShape
1583 service
= "com.sun.star.presentation.TitleTextShape";
1585 bIsPresShape
= true;
1589 if( service
.isEmpty() )
1591 // normal text shape
1592 service
= "com.sun.star.drawing.TextShape";
1595 // Add, set Style and properties from base shape
1606 uno::Reference
< beans::XPropertySet
> xProps(mxShape
, uno::UNO_QUERY
);
1609 uno::Reference
< beans::XPropertySetInfo
> xPropsInfo( xProps
->getPropertySetInfo() );
1610 if( xPropsInfo
.is() )
1612 if( !mbIsPlaceholder
&& xPropsInfo
->hasPropertyByName("IsEmptyPresentationObject"))
1613 xProps
->setPropertyValue("IsEmptyPresentationObject", css::uno::Any(false) );
1615 if( mbIsUserTransformed
&& xPropsInfo
->hasPropertyByName("IsPlaceholderDependent"))
1616 xProps
->setPropertyValue("IsPlaceholderDependent", css::uno::Any(false) );
1623 uno::Reference
< text::XText
> xText( mxShape
, uno::UNO_QUERY
);
1624 xText
->setString( "" );
1627 // set parameters on shape
1628 //A AW->CL: Eventually You need to strip scale and translate from the transformation
1629 //A to reach the same goal again.
1630 //A if(!bIsPresShape || mbIsUserTransformed)
1632 //A // set pos and size on shape, this should remove binding
1633 //A // to presentation object on masterpage
1634 //A SetSizeAndPosition();
1637 // set pos, size, shear and rotate
1638 SetTransformation();
1642 uno::Reference
< beans::XPropertySet
> xPropSet(mxShape
, uno::UNO_QUERY
);
1647 xPropSet
->setPropertyValue("CornerRadius", uno::Any( mnRadius
) );
1649 catch(const uno::Exception
&)
1651 DBG_UNHANDLED_EXCEPTION( "xmloff", "setting corner radius");
1656 if(!maChainNextName
.isEmpty())
1658 uno::Reference
< beans::XPropertySet
> xPropSet(mxShape
, uno::UNO_QUERY
);
1663 xPropSet
->setPropertyValue("TextChainNextName",
1664 uno::Any( maChainNextName
) );
1666 catch(const uno::Exception
&)
1668 DBG_UNHANDLED_EXCEPTION( "xmloff", "setting name of next chain link");
1673 SdXMLShapeContext::startFastElement(nElement
, xAttrList
);
1677 SdXMLControlShapeContext::SdXMLControlShapeContext(
1678 SvXMLImport
& rImport
,
1679 const css::uno::Reference
< css::xml::sax::XFastAttributeList
>& xAttrList
,
1680 uno::Reference
< drawing::XShapes
> const & rShapes
,
1681 bool bTemporaryShape
)
1682 : SdXMLShapeContext( rImport
, xAttrList
, rShapes
, bTemporaryShape
)
1686 SdXMLControlShapeContext::~SdXMLControlShapeContext()
1690 // this is called from the parent group for each unparsed attribute in the attribute list
1691 bool SdXMLControlShapeContext::processAttribute( const sax_fastparser::FastAttributeList::FastAttributeIter
& aIter
)
1693 switch (aIter
.getToken())
1695 case XML_ELEMENT(DRAW
, XML_CONTROL
):
1696 maFormId
= aIter
.toString();
1699 return SdXMLShapeContext::processAttribute( aIter
);
1704 void SdXMLControlShapeContext::startFastElement (sal_Int32 nElement
,
1705 const css::uno::Reference
< css::xml::sax::XFastAttributeList
>& xAttrList
)
1707 // create Control shape
1708 // add, set style and properties from base shape
1709 AddShape("com.sun.star.drawing.ControlShape");
1713 SAL_WARN_IF( !!maFormId
.isEmpty(), "xmloff", "draw:control without a form:id attribute!" );
1714 if( !maFormId
.isEmpty() )
1716 if( GetImport().IsFormsSupported() )
1718 uno::Reference
< awt::XControlModel
> xControlModel( GetImport().GetFormImport()->lookupControl( maFormId
), uno::UNO_QUERY
);
1719 if( xControlModel
.is() )
1721 uno::Reference
< drawing::XControlShape
> xControl( mxShape
, uno::UNO_QUERY
);
1723 xControl
->setControl( xControlModel
);
1732 // set pos, size, shear and rotate
1733 SetTransformation();
1735 SdXMLShapeContext::startFastElement(nElement
, xAttrList
);
1739 SdXMLConnectorShapeContext::SdXMLConnectorShapeContext(
1740 SvXMLImport
& rImport
,
1741 const css::uno::Reference
< css::xml::sax::XFastAttributeList
>& xAttrList
,
1742 uno::Reference
< drawing::XShapes
> const & rShapes
,
1743 bool bTemporaryShape
)
1744 : SdXMLShapeContext( rImport
, xAttrList
, rShapes
, bTemporaryShape
),
1747 mnType( drawing::ConnectorType_STANDARD
),
1753 mbLikelyOOXMLCurve(true)
1757 SdXMLConnectorShapeContext::~SdXMLConnectorShapeContext()
1761 bool SvXMLImport::needFixPositionAfterZ() const
1763 bool bWrongPositionAfterZ( false );
1764 sal_Int32
nUPD( 0 );
1765 sal_Int32
nBuildId( 0 );
1766 if ( getBuildIds( nUPD
, nBuildId
) && // test OOo and old versions of LibO and AOO
1767 ( ( ( nUPD
== 641 ) || ( nUPD
== 645 ) || ( nUPD
== 680 ) || ( nUPD
== 300 ) ||
1768 ( nUPD
== 310 ) || ( nUPD
== 320 ) || ( nUPD
== 330 ) || ( nUPD
== 340 ) ||
1769 ( nUPD
== 350 && nBuildId
< 202 ) )
1770 || (getGeneratorVersion() == SvXMLImport::AOO_40x
))) // test if AOO 4.0.x
1771 // apparently bug was fixed in AOO by i#123433 f15874d8f976f3874bdbcb53429eeefa65c28841
1773 bWrongPositionAfterZ
= true;
1775 return bWrongPositionAfterZ
;
1780 bool lcl_IsLikelyOOXMLCurve(const basegfx::B2DPolygon
& rPolygon
)
1782 sal_uInt32 nCount
= rPolygon
.count();
1783 if (!rPolygon
.areControlPointsUsed() or nCount
< 2)
1784 return false; // no curve at all
1786 basegfx::B2DVector
aStartVec(rPolygon
.getNextControlPoint(0) - rPolygon
.getB2DPoint(0));
1787 basegfx::B2DVector
aEndVec(rPolygon
.getPrevControlPoint(nCount
-1) - rPolygon
.getB2DPoint(nCount
- 1));
1788 // LibreOffice uses one point less than OOXML for the same underlying bentConnector or
1789 // STANDARD connector, respectively. A deeper inspection is only needed in case of 2 resulting
1790 // points. Those connector paths look like a quarter ellipse.
1795 // In case start and end direction are parallel, it cannot be OOXML because that case
1796 // introduces a handle on the path and the curve has three points then.
1797 if (basegfx::areParallel(aStartVec
, aEndVec
))
1799 // OOXML sets the control point at 1/2, LibreOffice at 2/3 of width or height.
1800 // A tolerance is used because +-1 deviations due to integer arithmetic in many places.
1801 basegfx::B2DRange
aRect(rPolygon
.getB2DPoint(0), rPolygon
.getB2DPoint(1));
1802 if ((basegfx::fTools::equalZero(aStartVec
.getX())
1803 && basegfx::fTools::equal(aStartVec
.getLength() * 2.0, aRect
.getHeight(), 2.0))
1804 || (basegfx::fTools::equalZero(aStartVec
.getY())
1805 && basegfx::fTools::equal(aStartVec
.getLength() * 2.0, aRect
.getWidth(), 2.0)))
1811 return basegfx::areParallel(aStartVec
, aEndVec
);
1813 case 4: // start and end direction are orthogonal
1814 return basegfx::fTools::equalZero(aStartVec
.scalar( aEndVec
));
1823 // this is called from the parent group for each unparsed attribute in the attribute list
1824 bool SdXMLConnectorShapeContext::processAttribute( const sax_fastparser::FastAttributeList::FastAttributeIter
& aIter
)
1826 switch( aIter
.getToken() )
1828 case XML_ELEMENT(DRAW
, XML_START_SHAPE
):
1829 maStartShapeId
= aIter
.toString();
1831 case XML_ELEMENT(DRAW
, XML_START_GLUE_POINT
):
1832 mnStartGlueId
= aIter
.toInt32();
1834 case XML_ELEMENT(DRAW
, XML_END_SHAPE
):
1835 maEndShapeId
= aIter
.toString();
1837 case XML_ELEMENT(DRAW
, XML_END_GLUE_POINT
):
1838 mnEndGlueId
= aIter
.toInt32();
1840 case XML_ELEMENT(DRAW
, XML_LINE_SKEW
):
1842 OUString sValue
= aIter
.toString();
1843 SvXMLTokenEnumerator
aTokenEnum( sValue
);
1844 std::u16string_view aToken
;
1845 if( aTokenEnum
.getNextToken( aToken
) )
1847 GetImport().GetMM100UnitConverter().convertMeasureToCore(
1849 if( aTokenEnum
.getNextToken( aToken
) )
1851 GetImport().GetMM100UnitConverter().convertMeasureToCore(
1853 if( aTokenEnum
.getNextToken( aToken
) )
1855 GetImport().GetMM100UnitConverter().convertMeasureToCore(
1862 case XML_ELEMENT(DRAW
, XML_TYPE
):
1864 (void)SvXMLUnitConverter::convertEnum( mnType
, aIter
.toView(), aXML_ConnectionKind_EnumMap
);
1867 // #121965# draw:transform may be used in ODF1.2, e.g. exports from MS seem to use these
1868 case XML_ELEMENT(DRAW
, XML_TRANSFORM
):
1869 mnTransform
.SetString(aIter
.toString(), GetImport().GetMM100UnitConverter());
1872 case XML_ELEMENT(SVG
, XML_X1
):
1873 case XML_ELEMENT(SVG_COMPAT
, XML_X1
):
1874 GetImport().GetMM100UnitConverter().convertMeasureToCore(
1875 maStart
.X
, aIter
.toView());
1877 case XML_ELEMENT(SVG
, XML_Y1
):
1878 case XML_ELEMENT(SVG_COMPAT
, XML_Y1
):
1879 GetImport().GetMM100UnitConverter().convertMeasureToCore(
1880 maStart
.Y
, aIter
.toView());
1882 case XML_ELEMENT(SVG
, XML_X2
):
1883 case XML_ELEMENT(SVG_COMPAT
, XML_X2
):
1884 GetImport().GetMM100UnitConverter().convertMeasureToCore(
1885 maEnd
.X
, aIter
.toView());
1887 case XML_ELEMENT(SVG
, XML_Y2
):
1888 case XML_ELEMENT(SVG_COMPAT
, XML_Y2
):
1889 GetImport().GetMM100UnitConverter().convertMeasureToCore(
1890 maEnd
.Y
, aIter
.toView());
1892 case XML_ELEMENT(SVG
, XML_D
):
1893 case XML_ELEMENT(SVG_COMPAT
, XML_D
):
1895 basegfx::B2DPolyPolygon aPolyPolygon
;
1897 if(basegfx::utils::importFromSvgD(aPolyPolygon
, aIter
.toString(), GetImport().needFixPositionAfterZ(), nullptr))
1899 if(aPolyPolygon
.count())
1901 drawing::PolyPolygonBezierCoords aSourcePolyPolygon
;
1903 basegfx::utils::B2DPolyPolygonToUnoPolyPolygonBezierCoords(
1905 aSourcePolyPolygon
);
1906 maPath
<<= aSourcePolyPolygon
;
1908 mbLikelyOOXMLCurve
= lcl_IsLikelyOOXMLCurve(aPolyPolygon
.getB2DPolygon(0));
1914 return SdXMLShapeContext::processAttribute( aIter
);
1919 void SdXMLConnectorShapeContext::startFastElement (sal_Int32 nElement
,
1920 const css::uno::Reference
< css::xml::sax::XFastAttributeList
>& xAttrList
)
1922 // For security reasons, do not add empty connectors. There may have been an error in EA2
1923 // that created empty, far set off connectors (e.g. 63 meters below top of document). This
1924 // is not guaranteed, but it's definitely safe to not add empty connectors.
1927 if( maStartShapeId
.isEmpty()
1928 && maEndShapeId
.isEmpty()
1929 && maStart
.X
== maEnd
.X
1930 && maStart
.Y
== maEnd
.Y
1942 // create Connector shape
1943 // add, set style and properties from base shape
1944 AddShape("com.sun.star.drawing.ConnectorShape");
1948 // #121965# if draw:transform is used, apply directly to the start
1949 // and end positions before using these
1950 if(mnTransform
.NeedsAction())
1952 // transformation is used, apply to object.
1953 ::basegfx::B2DHomMatrix aMat
;
1954 mnTransform
.GetFullTransform(aMat
);
1956 if(!aMat
.isIdentity())
1958 basegfx::B2DPoint
aStart(maStart
.X
, maStart
.Y
);
1959 basegfx::B2DPoint
aEnd(maEnd
.X
, maEnd
.Y
);
1961 aStart
= aMat
* aStart
;
1964 maStart
.X
= basegfx::fround(aStart
.getX());
1965 maStart
.Y
= basegfx::fround(aStart
.getY());
1966 maEnd
.X
= basegfx::fround(aEnd
.getX());
1967 maEnd
.Y
= basegfx::fround(aEnd
.getY());
1971 uno::Reference
< beans::XPropertySet
> xProps( mxShape
, uno::UNO_QUERY
);
1973 xProps
->setPropertyValue("EdgeOOXMLCurve", Any(mbLikelyOOXMLCurve
));
1975 // add connection ids
1976 if( !maStartShapeId
.isEmpty() )
1977 GetImport().GetShapeImport()->addShapeConnection( mxShape
, true, maStartShapeId
, mnStartGlueId
);
1978 if( !maEndShapeId
.isEmpty() )
1979 GetImport().GetShapeImport()->addShapeConnection( mxShape
, false, maEndShapeId
, mnEndGlueId
);
1983 xProps
->setPropertyValue("StartPosition", Any(maStart
));
1984 xProps
->setPropertyValue("EndPosition", Any(maEnd
) );
1985 xProps
->setPropertyValue("EdgeKind", Any(mnType
) );
1986 xProps
->setPropertyValue("EdgeLine1Delta", Any(mnDelta1
) );
1987 xProps
->setPropertyValue("EdgeLine2Delta", Any(mnDelta2
) );
1988 xProps
->setPropertyValue("EdgeLine3Delta", Any(mnDelta3
) );
1993 if ( maPath
.hasValue() )
1996 // Ignore svg:d attribute for text documents created by OpenOffice.org
1997 // versions before OOo 3.3, because these OOo versions are storing
1998 // svg:d values not using the correct unit.
1999 bool bApplySVGD( true );
2000 if ( uno::Reference
< text::XTextDocument
>(GetImport().GetModel(), uno::UNO_QUERY
).is() )
2002 sal_Int32
nUPD( 0 );
2003 sal_Int32
nBuild( 0 );
2004 const bool bBuildIdFound
= GetImport().getBuildIds( nUPD
, nBuild
);
2005 if ( GetImport().IsTextDocInOOoFileFormat() ||
2007 ( ( nUPD
== 641 ) || ( nUPD
== 645 ) || // prior OOo 2.0
2008 ( nUPD
== 680 ) || // OOo 2.x
2009 ( nUPD
== 300 ) || // OOo 3.0 - OOo 3.0.1
2010 ( nUPD
== 310 ) || // OOo 3.1 - OOo 3.1.1
2011 ( nUPD
== 320 ) ) ) ) // OOo 3.2 - OOo 3.2.1
2019 // tdf#83360 use path data only when redundant data of start and end point coordinates of
2020 // path start/end and connector start/end is equal. This is to avoid using erroneous
2021 // or inconsistent path data at import of foreign formats. Office itself always
2022 // writes out a consistent data set. Not using it when there is inconsistency
2023 // is okay since the path data is redundant, buffered data just to avoid recalculation
2024 // of the connector's layout at load time, no real information would be lost.
2025 // A 'connected' end has prio to direct coordinate data in Start/EndPosition
2026 // to the path data (which should have the start/end redundant in the path)
2027 const drawing::PolyPolygonBezierCoords
* pSource
= static_cast< const drawing::PolyPolygonBezierCoords
* >(maPath
.getValue());
2028 const sal_uInt32
nSequenceCount(pSource
->Coordinates
.getLength());
2029 bool bStartEqual(false);
2030 bool bEndEqual(false);
2034 const drawing::PointSequence
& rStartSeq
= pSource
->Coordinates
[0];
2035 const sal_uInt32 nStartCount
= rStartSeq
.getLength();
2039 const awt::Point
& rStartPoint
= rStartSeq
.getConstArray()[0];
2041 if(rStartPoint
.X
== maStart
.X
&& rStartPoint
.Y
== maStart
.Y
)
2047 const drawing::PointSequence
& rEndSeq
= pSource
->Coordinates
[nSequenceCount
- 1];
2048 const sal_uInt32 nEndCount
= rEndSeq
.getLength();
2052 const awt::Point
& rEndPoint
= rEndSeq
.getConstArray()[nEndCount
- 1];
2054 if(rEndPoint
.X
== maEnd
.X
&& rEndPoint
.Y
== maEnd
.Y
)
2061 if(!bStartEqual
|| !bEndEqual
)
2069 assert(maPath
.getValueType() == cppu::UnoType
<drawing::PolyPolygonBezierCoords
>::get());
2070 xProps
->setPropertyValue("PolyPolygonBezier", maPath
);
2074 SdXMLShapeContext::startFastElement(nElement
, xAttrList
);
2078 SdXMLMeasureShapeContext::SdXMLMeasureShapeContext(
2079 SvXMLImport
& rImport
,
2080 const css::uno::Reference
< css::xml::sax::XFastAttributeList
>& xAttrList
,
2081 uno::Reference
< drawing::XShapes
> const & rShapes
,
2082 bool bTemporaryShape
)
2083 : SdXMLShapeContext( rImport
, xAttrList
, rShapes
, bTemporaryShape
),
2089 SdXMLMeasureShapeContext::~SdXMLMeasureShapeContext()
2093 // this is called from the parent group for each unparsed attribute in the attribute list
2094 bool SdXMLMeasureShapeContext::processAttribute( const sax_fastparser::FastAttributeList::FastAttributeIter
& aIter
)
2096 switch( aIter
.getToken() )
2098 case XML_ELEMENT(SVG
, XML_X1
):
2099 case XML_ELEMENT(SVG_COMPAT
, XML_X1
):
2101 GetImport().GetMM100UnitConverter().convertMeasureToCore(
2102 maStart
.X
, aIter
.toView());
2105 case XML_ELEMENT(SVG
, XML_Y1
):
2106 case XML_ELEMENT(SVG_COMPAT
, XML_Y1
):
2108 GetImport().GetMM100UnitConverter().convertMeasureToCore(
2109 maStart
.Y
, aIter
.toView());
2112 case XML_ELEMENT(SVG
, XML_X2
):
2113 case XML_ELEMENT(SVG_COMPAT
, XML_X2
):
2115 GetImport().GetMM100UnitConverter().convertMeasureToCore(
2116 maEnd
.X
, aIter
.toView());
2119 case XML_ELEMENT(SVG
, XML_Y2
):
2120 case XML_ELEMENT(SVG_COMPAT
, XML_Y2
):
2122 GetImport().GetMM100UnitConverter().convertMeasureToCore(
2123 maEnd
.Y
, aIter
.toView());
2127 return SdXMLShapeContext::processAttribute( aIter
);
2132 void SdXMLMeasureShapeContext::startFastElement (sal_Int32 nElement
,
2133 const css::uno::Reference
< css::xml::sax::XFastAttributeList
>& xAttrList
)
2135 // create Measure shape
2136 // add, set style and properties from base shape
2137 AddShape("com.sun.star.drawing.MeasureShape");
2144 uno::Reference
< beans::XPropertySet
> xProps( mxShape
, uno::UNO_QUERY
);
2147 xProps
->setPropertyValue("StartPosition", Any(maStart
));
2148 xProps
->setPropertyValue("EndPosition", Any(maEnd
) );
2151 // delete pre created fields
2152 uno::Reference
< text::XText
> xText( mxShape
, uno::UNO_QUERY
);
2155 xText
->setString( " " );
2158 SdXMLShapeContext::startFastElement(nElement
, xAttrList
);
2161 void SdXMLMeasureShapeContext::endFastElement(sal_Int32 nElement
)
2165 // delete pre created fields
2166 uno::Reference
< text::XText
> xText( mxShape
, uno::UNO_QUERY
);
2170 uno::Reference
< text::XTextCursor
> xCursor( xText
->createTextCursor() );
2174 xCursor
->collapseToStart();
2175 xCursor
->goRight( 1, true );
2176 xCursor
->setString( "" );
2180 SdXMLShapeContext::endFastElement(nElement
);
2184 SdXMLPageShapeContext::SdXMLPageShapeContext(
2185 SvXMLImport
& rImport
,
2186 const css::uno::Reference
< css::xml::sax::XFastAttributeList
>& xAttrList
,
2187 uno::Reference
< drawing::XShapes
> const & rShapes
,
2188 bool bTemporaryShape
)
2189 : SdXMLShapeContext( rImport
, xAttrList
, rShapes
, bTemporaryShape
), mnPageNumber(0)
2191 mbClearDefaultAttributes
= false;
2194 SdXMLPageShapeContext::~SdXMLPageShapeContext()
2198 // this is called from the parent group for each unparsed attribute in the attribute list
2199 bool SdXMLPageShapeContext::processAttribute( const sax_fastparser::FastAttributeList::FastAttributeIter
& aIter
)
2201 if( aIter
.getToken() == XML_ELEMENT(DRAW
, XML_PAGE_NUMBER
) )
2202 mnPageNumber
= aIter
.toInt32();
2204 return SdXMLShapeContext::processAttribute( aIter
);
2208 void SdXMLPageShapeContext::startFastElement (sal_Int32 nElement
,
2209 const css::uno::Reference
< css::xml::sax::XFastAttributeList
>& xAttrList
)
2211 // create Page shape
2212 // add, set style and properties from base shape
2214 // #86163# take into account which type of PageShape needs to
2215 // be constructed. It's a presentation shape if presentation:XML_CLASS == XML_PAGE.
2216 bool bIsPresentation
= !maPresentationClass
.isEmpty() &&
2217 GetImport().GetShapeImport()->IsPresentationShapesSupported();
2219 uno::Reference
< lang::XServiceInfo
> xInfo( mxShapes
, uno::UNO_QUERY
);
2220 const bool bIsOnHandoutPage
= xInfo
.is() && xInfo
->supportsService("com.sun.star.presentation.HandoutMasterPage");
2222 if( bIsOnHandoutPage
)
2224 AddShape("com.sun.star.presentation.HandoutShape");
2228 if(bIsPresentation
&& !IsXMLToken( maPresentationClass
, XML_PAGE
) )
2230 bIsPresentation
= false;
2235 AddShape("com.sun.star.presentation.PageShape");
2239 AddShape("com.sun.star.drawing.PageShape");
2249 // set pos, size, shear and rotate
2250 SetTransformation();
2252 uno::Reference
< beans::XPropertySet
> xPropSet(mxShape
, uno::UNO_QUERY
);
2255 uno::Reference
< beans::XPropertySetInfo
> xPropSetInfo( xPropSet
->getPropertySetInfo() );
2256 static constexpr OUString
aPageNumberStr(u
"PageNumber"_ustr
);
2257 if( xPropSetInfo
.is() && xPropSetInfo
->hasPropertyByName(aPageNumberStr
))
2258 xPropSet
->setPropertyValue(aPageNumberStr
, uno::Any( mnPageNumber
));
2261 SdXMLShapeContext::startFastElement(nElement
, xAttrList
);
2265 SdXMLCaptionShapeContext::SdXMLCaptionShapeContext(
2266 SvXMLImport
& rImport
,
2267 const css::uno::Reference
< css::xml::sax::XFastAttributeList
>& xAttrList
,
2268 uno::Reference
< drawing::XShapes
> const & rShapes
,
2269 bool bTemporaryShape
)
2270 : SdXMLShapeContext( rImport
, xAttrList
, rShapes
, bTemporaryShape
),
2271 // #86616# for correct edge rounding import mnRadius needs to be initialized
2276 SdXMLCaptionShapeContext::~SdXMLCaptionShapeContext()
2280 void SdXMLCaptionShapeContext::startFastElement (sal_Int32 nElement
,
2281 const css::uno::Reference
< css::xml::sax::XFastAttributeList
>& xAttrList
)
2283 // create Caption shape
2284 // add, set style and properties from base shape
2285 AddShape("com.sun.star.drawing.CaptionShape");
2292 uno::Reference
< beans::XPropertySet
> xProps( mxShape
, uno::UNO_QUERY
);
2294 // SJ: If AutoGrowWidthItem is set, SetTransformation will lead to the wrong SnapRect
2295 // because NbcAdjustTextFrameWidthAndHeight() is called (text is set later and center alignment
2296 // is the default setting, so the top left reference point that is used by the caption point is
2297 // no longer correct) There are two ways to solve this problem, temporarily disabling the
2298 // autogrowwidth as we are doing here or to apply the CaptionPoint after setting text
2299 bool bIsAutoGrowWidth
= false;
2302 uno::Any
aAny( xProps
->getPropertyValue("TextAutoGrowWidth") );
2303 aAny
>>= bIsAutoGrowWidth
;
2305 if ( bIsAutoGrowWidth
)
2306 xProps
->setPropertyValue("TextAutoGrowWidth", uno::Any( false ) );
2309 // set pos, size, shear and rotate
2310 SetTransformation();
2312 xProps
->setPropertyValue("CaptionPoint", uno::Any( maCaptionPoint
) );
2314 if ( bIsAutoGrowWidth
)
2315 xProps
->setPropertyValue("TextAutoGrowWidth", uno::Any( true ) );
2319 uno::Reference
< beans::XPropertySet
> xPropSet(mxShape
, uno::UNO_QUERY
);
2324 xPropSet
->setPropertyValue("CornerRadius", uno::Any( mnRadius
) );
2326 catch(const uno::Exception
&)
2328 DBG_UNHANDLED_EXCEPTION( "xmloff", "setting corner radius");
2333 SdXMLShapeContext::startFastElement(nElement
, xAttrList
);
2336 // this is called from the parent group for each unparsed attribute in the attribute list
2337 bool SdXMLCaptionShapeContext::processAttribute( const sax_fastparser::FastAttributeList::FastAttributeIter
& aIter
)
2339 switch (aIter
.getToken())
2341 case XML_ELEMENT(DRAW
, XML_CAPTION_POINT_X
):
2342 GetImport().GetMM100UnitConverter().convertMeasureToCore(
2343 maCaptionPoint
.X
, aIter
.toView());
2345 case XML_ELEMENT(DRAW
, XML_CAPTION_POINT_Y
):
2346 GetImport().GetMM100UnitConverter().convertMeasureToCore(
2347 maCaptionPoint
.Y
, aIter
.toView());
2349 case XML_ELEMENT(DRAW
, XML_CORNER_RADIUS
):
2350 GetImport().GetMM100UnitConverter().convertMeasureToCore(
2351 mnRadius
, aIter
.toView());
2354 return SdXMLShapeContext::processAttribute( aIter
);
2360 SdXMLGraphicObjectShapeContext::SdXMLGraphicObjectShapeContext(
2361 SvXMLImport
& rImport
,
2362 const css::uno::Reference
< css::xml::sax::XFastAttributeList
>& xAttrList
,
2363 uno::Reference
< drawing::XShapes
> const & rShapes
)
2364 : SdXMLShapeContext( rImport
, xAttrList
, rShapes
, false/*bTemporaryShape*/ )
2368 // this is called from the parent group for each unparsed attribute in the attribute list
2369 bool SdXMLGraphicObjectShapeContext::processAttribute( const sax_fastparser::FastAttributeList::FastAttributeIter
& aIter
)
2371 switch (aIter
.getToken())
2373 case XML_ELEMENT(XLINK
, XML_HREF
):
2374 maURL
= aIter
.toString();
2376 case XML_ELEMENT(DRAW
, XML_MIME_TYPE
):
2377 case XML_ELEMENT(LO_EXT
, XML_MIME_TYPE
):
2378 msMimeType
= aIter
.toString();
2381 return SdXMLShapeContext::processAttribute(aIter
);
2386 void SdXMLGraphicObjectShapeContext::startFastElement (sal_Int32 nElement
,
2387 const css::uno::Reference
< css::xml::sax::XFastAttributeList
>& xAttrList
)
2389 // create graphic object shape
2392 if( IsXMLToken( maPresentationClass
, XML_GRAPHIC
) && GetImport().GetShapeImport()->IsPresentationShapesSupported() )
2394 service
= "com.sun.star.presentation.GraphicObjectShape";
2398 service
= "com.sun.star.drawing.GraphicObjectShape";
2409 uno::Reference
< beans::XPropertySet
> xPropset(mxShape
, uno::UNO_QUERY
);
2412 // since OOo 1.x had no line or fill style for graphics, but may create
2413 // documents with them, we have to override them here
2414 sal_Int32 nUPD
, nBuildId
;
2415 if( GetImport().getBuildIds( nUPD
, nBuildId
) && (nUPD
== 645) ) try
2417 xPropset
->setPropertyValue("FillStyle", Any( FillStyle_NONE
) );
2418 xPropset
->setPropertyValue("LineStyle", Any( LineStyle_NONE
) );
2420 catch(const Exception
&)
2424 uno::Reference
< beans::XPropertySetInfo
> xPropsInfo( xPropset
->getPropertySetInfo() );
2425 if( xPropsInfo
.is() && xPropsInfo
->hasPropertyByName("IsEmptyPresentationObject"))
2426 xPropset
->setPropertyValue("IsEmptyPresentationObject", css::uno::Any( mbIsPlaceholder
) );
2428 if( !mbIsPlaceholder
)
2430 if( !maURL
.isEmpty() )
2432 uno::Reference
<graphic::XGraphic
> xGraphic
= GetImport().loadGraphicByURL(maURL
);
2435 xPropset
->setPropertyValue("Graphic", uno::Any(xGraphic
));
2441 if(mbIsUserTransformed
)
2443 uno::Reference
< beans::XPropertySet
> xProps(mxShape
, uno::UNO_QUERY
);
2446 uno::Reference
< beans::XPropertySetInfo
> xPropsInfo( xProps
->getPropertySetInfo() );
2447 if( xPropsInfo
.is() )
2449 if( xPropsInfo
->hasPropertyByName("IsPlaceholderDependent"))
2450 xProps
->setPropertyValue("IsPlaceholderDependent", css::uno::Any(false) );
2455 // set pos, size, shear and rotate
2456 SetTransformation();
2458 SdXMLShapeContext::startFastElement(nElement
, xAttrList
);
2461 void SdXMLGraphicObjectShapeContext::endFastElement(sal_Int32 nElement
)
2463 if (mxBase64Stream
.is())
2465 uno::Reference
<graphic::XGraphic
> xGraphic(GetImport().loadGraphicFromBase64(mxBase64Stream
));
2468 uno::Reference
<beans::XPropertySet
> xProperties(mxShape
, uno::UNO_QUERY
);
2469 if (xProperties
.is())
2471 xProperties
->setPropertyValue("Graphic", uno::Any(xGraphic
));
2476 SdXMLShapeContext::endFastElement(nElement
);
2479 css::uno::Reference
< css::xml::sax::XFastContextHandler
> SdXMLGraphicObjectShapeContext::createFastChildContext(
2481 const css::uno::Reference
< css::xml::sax::XFastAttributeList
>& xAttrList
)
2483 css::uno::Reference
< css::xml::sax::XFastContextHandler
> xContext
;
2485 if( nElement
== XML_ELEMENT(OFFICE
, XML_BINARY_DATA
) )
2487 if( maURL
.isEmpty() && !mxBase64Stream
.is() )
2489 mxBase64Stream
= GetImport().GetStreamForGraphicObjectURLFromBase64();
2490 if( mxBase64Stream
.is() )
2491 xContext
= new XMLBase64ImportContext( GetImport(),
2496 // delegate to parent class if no context could be created
2498 xContext
= SdXMLShapeContext::createFastChildContext(nElement
,
2502 XMLOFF_WARN_UNKNOWN_ELEMENT("xmloff", nElement
);
2507 SdXMLGraphicObjectShapeContext::~SdXMLGraphicObjectShapeContext()
2513 SdXMLChartShapeContext::SdXMLChartShapeContext(
2514 SvXMLImport
& rImport
,
2515 const css::uno::Reference
< css::xml::sax::XFastAttributeList
>& xAttrList
,
2516 uno::Reference
< drawing::XShapes
> const & rShapes
,
2517 bool bTemporaryShape
)
2518 : SdXMLShapeContext( rImport
, xAttrList
, rShapes
, bTemporaryShape
)
2522 void SdXMLChartShapeContext::startFastElement (sal_Int32 nElement
,
2523 const css::uno::Reference
< css::xml::sax::XFastAttributeList
>& xAttrList
)
2525 const bool bIsPresentation
= isPresentationShape();
2529 ? OUString("com.sun.star.presentation.ChartShape")
2530 : OUString("com.sun.star.drawing.OLE2Shape"));
2538 if( !mbIsPlaceholder
)
2540 uno::Reference
< beans::XPropertySet
> xProps(mxShape
, uno::UNO_QUERY
);
2543 uno::Reference
< beans::XPropertySetInfo
> xPropsInfo( xProps
->getPropertySetInfo() );
2544 if( xPropsInfo
.is() && xPropsInfo
->hasPropertyByName("IsEmptyPresentationObject"))
2545 xProps
->setPropertyValue("IsEmptyPresentationObject", css::uno::Any(false) );
2549 xProps
->setPropertyValue("CLSID", Any(OUString("12DCAE26-281F-416F-a234-c3086127382e")) );
2551 aAny
= xProps
->getPropertyValue("Model");
2552 uno::Reference
< frame::XModel
> xChartModel
;
2553 if( aAny
>>= xChartModel
)
2555 #if !ENABLE_WASM_STRIP_CHART
2556 // WASM_CHART change
2557 // TODO: Maybe use SdXMLGraphicObjectShapeContext completely instead
2558 // or try to create as mbIsPlaceholder object adding a Chart visualization
2559 // that should be available somehow
2560 mxChartContext
.set( GetImport().GetChartImport()->CreateChartContext( GetImport(), xChartModel
) );
2566 if(mbIsUserTransformed
)
2568 uno::Reference
< beans::XPropertySet
> xProps(mxShape
, uno::UNO_QUERY
);
2571 uno::Reference
< beans::XPropertySetInfo
> xPropsInfo( xProps
->getPropertySetInfo() );
2572 if( xPropsInfo
.is() )
2574 if( xPropsInfo
->hasPropertyByName("IsPlaceholderDependent"))
2575 xProps
->setPropertyValue("IsPlaceholderDependent", css::uno::Any(false) );
2580 // set pos, size, shear and rotate
2581 SetTransformation();
2583 SdXMLShapeContext::startFastElement(nElement
, xAttrList
);
2585 if( mxChartContext
.is() )
2586 mxChartContext
->startFastElement( nElement
, xAttrList
);
2589 void SdXMLChartShapeContext::endFastElement(sal_Int32 nElement
)
2591 if( mxChartContext
.is() )
2592 mxChartContext
->endFastElement(nElement
);
2594 SdXMLShapeContext::endFastElement(nElement
);
2597 void SdXMLChartShapeContext::characters( const OUString
& rChars
)
2599 if( mxChartContext
.is() )
2600 mxChartContext
->characters( rChars
);
2603 css::uno::Reference
< css::xml::sax::XFastContextHandler
> SdXMLChartShapeContext::createFastChildContext(
2605 const css::uno::Reference
< css::xml::sax::XFastAttributeList
>& xAttrList
)
2607 if( mxChartContext
.is() )
2608 return mxChartContext
->createFastChildContext( nElement
, xAttrList
);
2614 SdXMLObjectShapeContext::SdXMLObjectShapeContext( SvXMLImport
& rImport
,
2615 const css::uno::Reference
< css::xml::sax::XFastAttributeList
>& xAttrList
,
2616 css::uno::Reference
< css::drawing::XShapes
> const & rShapes
)
2617 : SdXMLShapeContext( rImport
, xAttrList
, rShapes
, false/*bTemporaryShape*/ )
2621 SdXMLObjectShapeContext::~SdXMLObjectShapeContext()
2625 void SdXMLObjectShapeContext::startFastElement (sal_Int32
/*nElement*/,
2626 const css::uno::Reference
< css::xml::sax::XFastAttributeList
>& /*xAttrList*/)
2628 // #96717# in theorie, if we don't have a URL we shouldn't even
2629 // export this OLE shape. But practically it's too risky right now
2630 // to change this so we better dispose this on load
2631 //if( !mbIsPlaceholder && ImpIsEmptyURL(maHref) )
2634 // #100592# this BugFix prevents that a shape is created. CL
2635 // is thinking about an alternative.
2636 // #i13140# Check for more than empty string in maHref, there are
2637 // other possibilities that maHref results in empty container
2639 if( !(GetImport().getImportFlags() & SvXMLImportFlags::EMBEDDED
) && !mbIsPlaceholder
&& ImpIsEmptyURL(maHref
) )
2642 OUString
service("com.sun.star.drawing.OLE2Shape");
2644 bool bIsPresShape
= !maPresentationClass
.isEmpty() && GetImport().GetShapeImport()->IsPresentationShapesSupported();
2648 if( IsXMLToken( maPresentationClass
, XML_CHART
) )
2650 service
= "com.sun.star.presentation.ChartShape";
2652 else if( IsXMLToken( maPresentationClass
, XML_TABLE
) )
2654 service
= "com.sun.star.presentation.CalcShape";
2656 else if( IsXMLToken( maPresentationClass
, XML_OBJECT
) )
2658 service
= "com.sun.star.presentation.OLE2Shape";
2671 uno::Reference
< beans::XPropertySet
> xProps(mxShape
, uno::UNO_QUERY
);
2674 uno::Reference
< beans::XPropertySetInfo
> xPropsInfo( xProps
->getPropertySetInfo() );
2675 if( xPropsInfo
.is() )
2677 if( !mbIsPlaceholder
&& xPropsInfo
->hasPropertyByName("IsEmptyPresentationObject"))
2678 xProps
->setPropertyValue("IsEmptyPresentationObject", css::uno::Any(false) );
2680 if( mbIsUserTransformed
&& xPropsInfo
->hasPropertyByName("IsPlaceholderDependent"))
2681 xProps
->setPropertyValue("IsPlaceholderDependent", css::uno::Any(false) );
2686 if( !mbIsPlaceholder
&& !maHref
.isEmpty() )
2688 uno::Reference
< beans::XPropertySet
> xProps( mxShape
, uno::UNO_QUERY
);
2692 OUString aPersistName
= GetImport().ResolveEmbeddedObjectURL( maHref
, maCLSID
);
2694 if ( GetImport().IsPackageURL( maHref
) )
2696 static constexpr OUString
sURL( u
"vnd.sun.star.EmbeddedObject:"_ustr
);
2698 if ( aPersistName
.startsWith( sURL
) )
2699 aPersistName
= aPersistName
.copy( sURL
.getLength() );
2701 xProps
->setPropertyValue("PersistName",
2702 uno::Any( aPersistName
) );
2706 // this is OOo link object
2707 xProps
->setPropertyValue("LinkURL",
2708 uno::Any( aPersistName
) );
2713 // set pos, size, shear and rotate
2714 SetTransformation();
2718 GetImport().GetShapeImport()->finishShape( mxShape
, mxAttrList
, mxShapes
);
2721 void SdXMLObjectShapeContext::endFastElement(sal_Int32 nElement
)
2723 if (GetImport().isGeneratorVersionOlderThan(
2724 SvXMLImport::OOo_34x
, SvXMLImport::LO_41x
)) // < LO 4.0
2727 // If it's an old file from us written before OOo3.4, we need to correct
2728 // FillStyle and LineStyle for OLE2 objects. The error was that the old paint
2729 // implementations just ignored added fill/linestyles completely, thus
2730 // those objects need to be corrected to not show blue and hairline which
2731 // always was the default, but would be shown now
2732 uno::Reference
< beans::XPropertySet
> xProps(mxShape
, uno::UNO_QUERY
);
2736 xProps
->setPropertyValue("FillStyle", uno::Any(drawing::FillStyle_NONE
));
2737 xProps
->setPropertyValue("LineStyle", uno::Any(drawing::LineStyle_NONE
));
2741 if( mxBase64Stream
.is() )
2743 OUString
aPersistName( GetImport().ResolveEmbeddedObjectURLFromBase64() );
2744 static constexpr OUStringLiteral
sURL( u
"vnd.sun.star.EmbeddedObject:" );
2746 aPersistName
= aPersistName
.copy( sURL
.getLength() );
2748 uno::Reference
< beans::XPropertySet
> xProps(mxShape
, uno::UNO_QUERY
);
2750 xProps
->setPropertyValue("PersistName", uno::Any( aPersistName
) );
2753 SdXMLShapeContext::endFastElement(nElement
);
2756 // this is called from the parent group for each unparsed attribute in the attribute list
2757 bool SdXMLObjectShapeContext::processAttribute( const sax_fastparser::FastAttributeList::FastAttributeIter
& aIter
)
2759 switch( aIter
.getToken() )
2761 case XML_ELEMENT(DRAW
, XML_CLASS_ID
):
2762 maCLSID
= aIter
.toString();
2764 case XML_ELEMENT(XLINK
, XML_HREF
):
2765 maHref
= aIter
.toString();
2768 return SdXMLShapeContext::processAttribute( aIter
);
2773 css::uno::Reference
< css::xml::sax::XFastContextHandler
> SdXMLObjectShapeContext::createFastChildContext(
2775 const css::uno::Reference
< css::xml::sax::XFastAttributeList
>& xAttrList
)
2777 if(nElement
== XML_ELEMENT(OFFICE
, XML_BINARY_DATA
))
2779 mxBase64Stream
= GetImport().GetStreamForEmbeddedObjectURLFromBase64();
2780 if( mxBase64Stream
.is() )
2781 return new XMLBase64ImportContext( GetImport(), mxBase64Stream
);
2783 else if( nElement
== XML_ELEMENT(OFFICE
, XML_DOCUMENT
) ||
2784 nElement
== XML_ELEMENT(MATH
, XML_MATH
) )
2786 rtl::Reference
<XMLEmbeddedObjectImportContext
> xEContext(
2787 new XMLEmbeddedObjectImportContext(GetImport(), nElement
, xAttrList
));
2788 maCLSID
= xEContext
->GetFilterCLSID();
2789 if( !maCLSID
.isEmpty() )
2791 uno::Reference
< beans::XPropertySet
> xPropSet(mxShape
, uno::UNO_QUERY
);
2794 xPropSet
->setPropertyValue("CLSID", uno::Any( maCLSID
) );
2796 uno::Reference
< lang::XComponent
> xComp
;
2797 xPropSet
->getPropertyValue("Model") >>= xComp
;
2798 SAL_WARN_IF( !xComp
.is(), "xmloff", "no xModel for own OLE format" );
2799 xEContext
->SetComponent(xComp
);
2805 // delegate to parent class if no context could be created
2806 return SdXMLShapeContext::createFastChildContext(nElement
, xAttrList
);
2809 SdXMLAppletShapeContext::SdXMLAppletShapeContext( SvXMLImport
& rImport
,
2810 const css::uno::Reference
< css::xml::sax::XFastAttributeList
>& xAttrList
,
2811 css::uno::Reference
< css::drawing::XShapes
> const & rShapes
)
2812 : SdXMLShapeContext( rImport
, xAttrList
, rShapes
, false/*bTemporaryShape*/ ),
2817 SdXMLAppletShapeContext::~SdXMLAppletShapeContext()
2821 void SdXMLAppletShapeContext::startFastElement (sal_Int32
/*nElement*/,
2822 const css::uno::Reference
< css::xml::sax::XFastAttributeList
>& /*xAttrList*/)
2824 AddShape("com.sun.star.drawing.AppletShape");
2830 // set pos, size, shear and rotate
2831 SetTransformation();
2832 GetImport().GetShapeImport()->finishShape( mxShape
, mxAttrList
, mxShapes
);
2836 // this is called from the parent group for each unparsed attribute in the attribute list
2837 bool SdXMLAppletShapeContext::processAttribute( const sax_fastparser::FastAttributeList::FastAttributeIter
& aIter
)
2839 switch( aIter
.getToken() )
2841 case XML_ELEMENT(DRAW
, XML_APPLET_NAME
):
2842 maAppletName
= aIter
.toString();
2844 case XML_ELEMENT(DRAW
, XML_CODE
):
2845 maAppletCode
= aIter
.toString();
2847 case XML_ELEMENT(DRAW
, XML_MAY_SCRIPT
):
2848 mbIsScript
= IsXMLToken( aIter
, XML_TRUE
);
2850 case XML_ELEMENT(XLINK
, XML_HREF
):
2851 maHref
= GetImport().GetAbsoluteReference(aIter
.toString());
2854 return SdXMLShapeContext::processAttribute( aIter
);
2859 void SdXMLAppletShapeContext::endFastElement(sal_Int32 nElement
)
2861 uno::Reference
< beans::XPropertySet
> xProps( mxShape
, uno::UNO_QUERY
);
2864 if ( maSize
.Width
&& maSize
.Height
)
2866 // the visual area for applet must be set on loading
2867 awt::Rectangle
aRect( 0, 0, maSize
.Width
, maSize
.Height
);
2868 xProps
->setPropertyValue("VisibleArea", Any(aRect
) );
2871 if( maParams
.hasElements() )
2873 xProps
->setPropertyValue("AppletCommands", Any(maParams
) );
2876 if( !maHref
.isEmpty() )
2878 xProps
->setPropertyValue("AppletCodeBase", Any(maHref
) );
2881 if( !maAppletName
.isEmpty() )
2883 xProps
->setPropertyValue("AppletName", Any(maAppletName
) );
2888 xProps
->setPropertyValue("AppletIsScript", Any(mbIsScript
) );
2892 if( !maAppletCode
.isEmpty() )
2894 xProps
->setPropertyValue("AppletCode", Any(maAppletCode
) );
2897 xProps
->setPropertyValue("AppletDocBase", Any(GetImport().GetDocumentBase()) );
2902 SdXMLShapeContext::endFastElement(nElement
);
2905 css::uno::Reference
< css::xml::sax::XFastContextHandler
> SdXMLAppletShapeContext::createFastChildContext(
2907 const css::uno::Reference
< css::xml::sax::XFastAttributeList
>& xAttrList
)
2909 if( nElement
== XML_ELEMENT(DRAW
, XML_PARAM
) )
2911 OUString aParamName
, aParamValue
;
2912 // now parse the attribute list and look for draw:name and draw:value
2913 for( auto& aIter
: sax_fastparser::castToFastAttributeList(xAttrList
) )
2915 if( aIter
.getToken() == XML_ELEMENT(DRAW
, XML_NAME
) )
2916 aParamName
= aIter
.toString();
2917 if( aIter
.getToken() == XML_ELEMENT(DRAW
, XML_VALUE
) )
2918 aParamValue
= aIter
.toString();
2921 if( !aParamName
.isEmpty() )
2923 sal_Int32 nIndex
= maParams
.getLength();
2924 maParams
.realloc( nIndex
+ 1 );
2925 auto pParams
= maParams
.getArray();
2926 pParams
[nIndex
].Name
= aParamName
;
2927 pParams
[nIndex
].Handle
= -1;
2928 pParams
[nIndex
].Value
<<= aParamValue
;
2929 pParams
[nIndex
].State
= beans::PropertyState_DIRECT_VALUE
;
2932 return new SvXMLImportContext( GetImport() );
2935 return SdXMLShapeContext::createFastChildContext( nElement
, xAttrList
);
2939 SdXMLPluginShapeContext::SdXMLPluginShapeContext( SvXMLImport
& rImport
,
2940 const css::uno::Reference
< css::xml::sax::XFastAttributeList
>& xAttrList
,
2941 css::uno::Reference
< css::drawing::XShapes
> const & rShapes
) :
2942 SdXMLShapeContext( rImport
, xAttrList
, rShapes
, false/*bTemporaryShape*/ ),
2947 SdXMLPluginShapeContext::~SdXMLPluginShapeContext()
2951 void SdXMLPluginShapeContext::startFastElement (sal_Int32
/*nElement*/,
2952 const css::uno::Reference
< css::xml::sax::XFastAttributeList
>& xAttrList
)
2955 // watch for MimeType attribute to see if we have a media object
2956 for( auto& aIter
: sax_fastparser::castToFastAttributeList(xAttrList
) )
2958 if( aIter
.getToken() == XML_ELEMENT(DRAW
, XML_MIME_TYPE
) )
2960 if (::comphelper::IsMediaMimeType(aIter
.toView()))
2969 bool bIsPresShape
= false;
2973 service
= "com.sun.star.drawing.MediaShape";
2975 bIsPresShape
= !maPresentationClass
.isEmpty() && GetImport().GetShapeImport()->IsPresentationShapesSupported();
2978 if( IsXMLToken( maPresentationClass
, XML_OBJECT
) )
2980 service
= "com.sun.star.presentation.MediaShape";
2985 service
= "com.sun.star.drawing.PluginShape";
2994 // The media may have a crop, apply it.
2995 SetStyle(/*bSupportsStyle=*/false);
3002 uno::Reference
< beans::XPropertySet
> xProps( mxShape
, uno::UNO_QUERY
);
3005 uno::Reference
< beans::XPropertySetInfo
> xPropsInfo( xProps
->getPropertySetInfo() );
3006 if( xPropsInfo
.is() )
3008 if( !mbIsPlaceholder
&& xPropsInfo
->hasPropertyByName("IsEmptyPresentationObject"))
3009 xProps
->setPropertyValue("IsEmptyPresentationObject", css::uno::Any(false) );
3011 if( mbIsUserTransformed
&& xPropsInfo
->hasPropertyByName("IsPlaceholderDependent"))
3012 xProps
->setPropertyValue("IsPlaceholderDependent", css::uno::Any(false) );
3017 // set pos, size, shear and rotate
3018 SetTransformation();
3019 GetImport().GetShapeImport()->finishShape( mxShape
, mxAttrList
, mxShapes
);
3023 lcl_GetMediaReference(SvXMLImport
const& rImport
, OUString
const& rURL
)
3025 if (rImport
.IsPackageURL(rURL
))
3027 return "vnd.sun.star.Package:" + rURL
;
3031 return rImport
.GetAbsoluteReference(rURL
);
3035 // this is called from the parent group for each unparsed attribute in the attribute list
3036 bool SdXMLPluginShapeContext::processAttribute( const sax_fastparser::FastAttributeList::FastAttributeIter
& aIter
)
3038 switch( aIter
.getToken() )
3040 case XML_ELEMENT(DRAW
, XML_MIME_TYPE
):
3041 maMimeType
= aIter
.toString();
3043 case XML_ELEMENT(XLINK
, XML_HREF
):
3044 maHref
= lcl_GetMediaReference(GetImport(), aIter
.toString());
3047 return SdXMLShapeContext::processAttribute( aIter
);
3052 void SdXMLPluginShapeContext::endFastElement(sal_Int32 nElement
)
3054 uno::Reference
< beans::XPropertySet
> xProps( mxShape
, uno::UNO_QUERY
);
3058 if ( maSize
.Width
&& maSize
.Height
)
3060 static constexpr OUString
sVisibleArea( u
"VisibleArea"_ustr
);
3061 uno::Reference
< beans::XPropertySetInfo
> aXPropSetInfo( xProps
->getPropertySetInfo() );
3062 if ( !aXPropSetInfo
.is() || aXPropSetInfo
->hasPropertyByName( sVisibleArea
) )
3064 // the visual area for a plugin must be set on loading
3065 awt::Rectangle
aRect( 0, 0, maSize
.Width
, maSize
.Height
);
3066 xProps
->setPropertyValue( sVisibleArea
, Any(aRect
) );
3072 // in case we have a plugin object
3073 if( maParams
.hasElements() )
3075 xProps
->setPropertyValue("PluginCommands", Any(maParams
) );
3078 if( !maMimeType
.isEmpty() )
3080 xProps
->setPropertyValue("PluginMimeType", Any(maMimeType
) );
3083 if( !maHref
.isEmpty() )
3085 xProps
->setPropertyValue("PluginURL", Any(maHref
) );
3090 // in case we have a media object
3091 xProps
->setPropertyValue( "MediaURL", uno::Any(maHref
));
3093 xProps
->setPropertyValue("MediaMimeType", uno::Any(maMimeType
) );
3095 for( const auto& rParam
: std::as_const(maParams
) )
3097 const OUString
& rName
= rParam
.Name
;
3099 if( rName
== "Loop" )
3102 rParam
.Value
>>= aValueStr
;
3103 xProps
->setPropertyValue("Loop",
3104 uno::Any( aValueStr
== "true" ) );
3106 else if( rName
== "Mute" )
3109 rParam
.Value
>>= aValueStr
;
3110 xProps
->setPropertyValue("Mute",
3111 uno::Any( aValueStr
== "true" ) );
3113 else if( rName
== "VolumeDB" )
3116 rParam
.Value
>>= aValueStr
;
3117 xProps
->setPropertyValue("VolumeDB",
3118 uno::Any( static_cast< sal_Int16
>( aValueStr
.toInt32() ) ) );
3120 else if( rName
== "Zoom" )
3123 media::ZoomLevel eZoomLevel
;
3125 rParam
.Value
>>= aZoomStr
;
3127 if( aZoomStr
== "25%" )
3128 eZoomLevel
= media::ZoomLevel_ZOOM_1_TO_4
;
3129 else if( aZoomStr
== "50%" )
3130 eZoomLevel
= media::ZoomLevel_ZOOM_1_TO_2
;
3131 else if( aZoomStr
== "100%" )
3132 eZoomLevel
= media::ZoomLevel_ORIGINAL
;
3133 else if( aZoomStr
== "200%" )
3134 eZoomLevel
= media::ZoomLevel_ZOOM_2_TO_1
;
3135 else if( aZoomStr
== "400%" )
3136 eZoomLevel
= media::ZoomLevel_ZOOM_4_TO_1
;
3137 else if( aZoomStr
== "fit" )
3138 eZoomLevel
= media::ZoomLevel_FIT_TO_WINDOW
;
3139 else if( aZoomStr
== "fixedfit" )
3140 eZoomLevel
= media::ZoomLevel_FIT_TO_WINDOW_FIXED_ASPECT
;
3141 else if( aZoomStr
== "fullscreen" )
3142 eZoomLevel
= media::ZoomLevel_FULLSCREEN
;
3144 eZoomLevel
= media::ZoomLevel_NOT_AVAILABLE
;
3146 xProps
->setPropertyValue("Zoom", uno::Any( eZoomLevel
) );
3154 SdXMLShapeContext::endFastElement(nElement
);
3157 css::uno::Reference
< css::xml::sax::XFastContextHandler
> SdXMLPluginShapeContext::createFastChildContext(
3159 const css::uno::Reference
< css::xml::sax::XFastAttributeList
>& xAttrList
)
3161 if( nElement
== XML_ELEMENT(DRAW
, XML_PARAM
) )
3163 OUString aParamName
, aParamValue
;
3164 // now parse the attribute list and look for draw:name and draw:value
3165 for( auto& aIter
: sax_fastparser::castToFastAttributeList(xAttrList
) )
3167 if( aIter
.getToken() == XML_ELEMENT(DRAW
, XML_NAME
) )
3168 aParamName
= aIter
.toString();
3169 else if( aIter
.getToken() == XML_ELEMENT(DRAW
, XML_VALUE
) )
3170 aParamValue
= aIter
.toString();
3173 if( !aParamName
.isEmpty() )
3175 sal_Int32 nIndex
= maParams
.getLength();
3176 maParams
.realloc( nIndex
+ 1 );
3177 auto pParams
= maParams
.getArray();
3178 pParams
[nIndex
].Name
= aParamName
;
3179 pParams
[nIndex
].Handle
= -1;
3180 pParams
[nIndex
].Value
<<= aParamValue
;
3181 pParams
[nIndex
].State
= beans::PropertyState_DIRECT_VALUE
;
3184 return new SvXMLImportContext( GetImport() );
3187 return SdXMLShapeContext::createFastChildContext( nElement
, xAttrList
);
3191 SdXMLFloatingFrameShapeContext::SdXMLFloatingFrameShapeContext( SvXMLImport
& rImport
,
3192 const css::uno::Reference
< css::xml::sax::XFastAttributeList
>& xAttrList
,
3193 css::uno::Reference
< css::drawing::XShapes
> const & rShapes
)
3194 : SdXMLShapeContext( rImport
, xAttrList
, rShapes
, false/*bTemporaryShape*/ )
3198 SdXMLFloatingFrameShapeContext::~SdXMLFloatingFrameShapeContext()
3202 uno::Reference
<drawing::XShape
> SdXMLFloatingFrameShapeContext::CreateFloatingFrameShape() const
3204 uno::Reference
<lang::XMultiServiceFactory
> xServiceFact(GetImport().GetModel(), uno::UNO_QUERY
);
3205 if (!xServiceFact
.is())
3207 uno::Reference
<drawing::XShape
> xShape(
3208 xServiceFact
->createInstance("com.sun.star.drawing.FrameShape"), uno::UNO_QUERY
);
3212 void SdXMLFloatingFrameShapeContext::startFastElement (sal_Int32
/*nElement*/,
3213 const css::uno::Reference
< css::xml::sax::XFastAttributeList
>& /*xAttrList*/)
3215 uno::Reference
<drawing::XShape
> xShape(SdXMLFloatingFrameShapeContext::CreateFloatingFrameShape());
3217 uno::Reference
< beans::XPropertySet
> xProps(xShape
, uno::UNO_QUERY
);
3218 // set FrameURL before AddShape, we have to do it again later because it
3219 // gets cleared when the SdrOle2Obj is attached to the XShape. But we want
3220 // FrameURL to exist when AddShape triggers SetPersistName which itself
3221 // triggers SdrOle2Obj::CheckFileLink_Impl and at that point we want to
3222 // know what URL will end up being used. So bodge this by setting FrameURL
3223 // to the temp pre-SdrOle2Obj attached properties and we can smuggle it
3224 // eventually into SdrOle2Obj::SetPersistName at the right point after
3225 // PersistName is set but before SdrOle2Obj::CheckFileLink_Impl is called
3226 // in order to inform the link manager that this is an IFrame that links to
3228 if (xProps
&& !maHref
.isEmpty())
3229 xProps
->setPropertyValue("FrameURL", Any(maHref
));
3238 // set pos, size, shear and rotate
3239 SetTransformation();
3243 if( !maFrameName
.isEmpty() )
3245 xProps
->setPropertyValue("FrameName", Any(maFrameName
) );
3248 if( !maHref
.isEmpty() )
3250 if (INetURLObject(maHref
).IsExoticProtocol())
3251 GetImport().NotifyMacroEventRead();
3253 xProps
->setPropertyValue("FrameURL", Any(maHref
) );
3259 GetImport().GetShapeImport()->finishShape( mxShape
, mxAttrList
, mxShapes
);
3262 // this is called from the parent group for each unparsed attribute in the attribute list
3263 bool SdXMLFloatingFrameShapeContext::processAttribute( const sax_fastparser::FastAttributeList::FastAttributeIter
& aIter
)
3265 switch( aIter
.getToken() )
3267 case XML_ELEMENT(DRAW
, XML_FRAME_NAME
):
3268 maFrameName
= aIter
.toString();
3270 case XML_ELEMENT(XLINK
, XML_HREF
):
3271 maHref
= GetImport().GetAbsoluteReference(aIter
.toString());
3274 return SdXMLShapeContext::processAttribute( aIter
);
3279 void SdXMLFloatingFrameShapeContext::endFastElement(sal_Int32 nElement
)
3281 uno::Reference
< beans::XPropertySet
> xProps( mxShape
, uno::UNO_QUERY
);
3285 if ( maSize
.Width
&& maSize
.Height
)
3287 // the visual area for a floating frame must be set on loading
3288 awt::Rectangle
aRect( 0, 0, maSize
.Width
, maSize
.Height
);
3289 xProps
->setPropertyValue("VisibleArea", Any(aRect
) );
3294 SdXMLShapeContext::endFastElement(nElement
);
3298 SdXMLFrameShapeContext::SdXMLFrameShapeContext( SvXMLImport
& rImport
,
3299 const css::uno::Reference
< css::xml::sax::XFastAttributeList
>& xAttrList
,
3300 css::uno::Reference
< css::drawing::XShapes
> const & rShapes
,
3301 bool bTemporaryShape
)
3302 : SdXMLShapeContext( rImport
, xAttrList
, rShapes
, bTemporaryShape
),
3303 mbSupportsReplacement( false )
3305 uno::Reference
< util::XCloneable
> xClone( xAttrList
, uno::UNO_QUERY
);
3307 mxAttrList
.set( xClone
->createClone(), uno::UNO_QUERY
);
3309 mxAttrList
= new sax_fastparser::FastAttributeList(xAttrList
);
3312 SdXMLFrameShapeContext::~SdXMLFrameShapeContext()
3316 void SdXMLFrameShapeContext::removeGraphicFromImportContext(const SvXMLImportContext
& rContext
)
3318 const SdXMLGraphicObjectShapeContext
* pSdXMLGraphicObjectShapeContext
= dynamic_cast< const SdXMLGraphicObjectShapeContext
* >(&rContext
);
3320 if(!pSdXMLGraphicObjectShapeContext
)
3325 uno::Reference
< container::XChild
> xChild(pSdXMLGraphicObjectShapeContext
->getShape(), uno::UNO_QUERY_THROW
);
3327 uno::Reference
< drawing::XShapes
> xParent(xChild
->getParent(), uno::UNO_QUERY_THROW
);
3329 // remove from parent
3330 xParent
->remove(pSdXMLGraphicObjectShapeContext
->getShape());
3333 uno::Reference
< lang::XComponent
> xComp(pSdXMLGraphicObjectShapeContext
->getShape(), UNO_QUERY
);
3340 catch( uno::Exception
& )
3342 DBG_UNHANDLED_EXCEPTION( "xmloff", "Error in cleanup of multiple graphic object import." );
3348 uno::Reference
<beans::XPropertySet
> getGraphicPropertySetFromImportContext(const SvXMLImportContext
& rContext
)
3350 uno::Reference
<beans::XPropertySet
> aPropertySet
;
3351 const SdXMLGraphicObjectShapeContext
* pSdXMLGraphicObjectShapeContext
= dynamic_cast<const SdXMLGraphicObjectShapeContext
*>(&rContext
);
3353 if (pSdXMLGraphicObjectShapeContext
)
3354 aPropertySet
.set(pSdXMLGraphicObjectShapeContext
->getShape(), uno::UNO_QUERY
);
3356 return aPropertySet
;
3359 } // end anonymous namespace
3361 uno::Reference
<graphic::XGraphic
> SdXMLFrameShapeContext::getGraphicFromImportContext(const SvXMLImportContext
& rContext
) const
3363 uno::Reference
<graphic::XGraphic
> xGraphic
;
3366 const uno::Reference
<beans::XPropertySet
> xPropertySet
= getGraphicPropertySetFromImportContext(rContext
);
3368 if (xPropertySet
.is())
3370 xPropertySet
->getPropertyValue("Graphic") >>= xGraphic
;
3373 catch( uno::Exception
& )
3375 DBG_UNHANDLED_EXCEPTION("xmloff", "Error in cleanup of multiple graphic object import.");
3381 OUString
SdXMLFrameShapeContext::getMimeTypeFromImportContext(const SvXMLImportContext
& rContext
) const
3384 const SdXMLGraphicObjectShapeContext
* pSdXMLGraphicObjectShapeContext
= dynamic_cast<const SdXMLGraphicObjectShapeContext
*>(&rContext
);
3386 if (pSdXMLGraphicObjectShapeContext
)
3387 aMimeType
= pSdXMLGraphicObjectShapeContext
->getMimeType();
3391 OUString
SdXMLFrameShapeContext::getGraphicPackageURLFromImportContext(const SvXMLImportContext
& rContext
) const
3394 const SdXMLGraphicObjectShapeContext
* pSdXMLGraphicObjectShapeContext
= dynamic_cast< const SdXMLGraphicObjectShapeContext
* >(&rContext
);
3396 if(pSdXMLGraphicObjectShapeContext
)
3400 const uno::Reference
< beans::XPropertySet
> xPropSet(pSdXMLGraphicObjectShapeContext
->getShape(), uno::UNO_QUERY_THROW
);
3402 xPropSet
->getPropertyValue("GraphicStreamURL") >>= aRetval
;
3404 catch( uno::Exception
& )
3406 DBG_UNHANDLED_EXCEPTION( "xmloff", "Error in cleanup of multiple graphic object import." );
3413 css::uno::Reference
< css::xml::sax::XFastContextHandler
> SdXMLFrameShapeContext::createFastChildContext(
3415 const uno::Reference
< xml::sax::XFastAttributeList
>& xAttrList
)
3417 SvXMLImportContextRef xContext
;
3418 if( !mxImplContext
.is() )
3420 SvXMLShapeContext
* pShapeContext
= XMLShapeImportHelper::CreateFrameChildContext(
3421 GetImport(), nElement
, xAttrList
, mxShapes
, mxAttrList
);
3423 xContext
= pShapeContext
;
3425 // propagate the hyperlink to child context
3426 if ( !msHyperlink
.isEmpty() )
3427 pShapeContext
->setHyperlink( msHyperlink
);
3429 auto nToken
= nElement
& TOKEN_MASK
;
3430 bool bMedia
= false;
3431 // Ignore gltf model if necessary and so the fallback image will be imported
3432 if( nToken
== XML_PLUGIN
)
3434 SdXMLPluginShapeContext
* pPluginContext
= dynamic_cast<SdXMLPluginShapeContext
*>(pShapeContext
);
3435 if( pPluginContext
&& pPluginContext
->getMimeType() == "model/vnd.gltf+json" )
3437 mxImplContext
= nullptr;
3438 return new SvXMLImportContext(GetImport());
3440 else if (pPluginContext
&& ::comphelper::IsMediaMimeType(pPluginContext
->getMimeType()))
3442 // The media may have a preview, import it.
3447 mxImplContext
= xContext
;
3448 mbSupportsReplacement
= (nToken
== XML_OBJECT
) || (nToken
== XML_OBJECT_OLE
) || bMedia
;
3449 setSupportsMultipleContents(nToken
== XML_IMAGE
);
3451 if(getSupportsMultipleContents() && dynamic_cast< SdXMLGraphicObjectShapeContext
* >(xContext
.get()))
3453 if ( !maShapeId
.isEmpty() )
3454 GetImport().getInterfaceToIdentifierMapper().reserveIdentifier( maShapeId
);
3456 addContent(*mxImplContext
);
3459 else if(getSupportsMultipleContents() && nElement
== XML_ELEMENT(DRAW
, XML_IMAGE
))
3461 // read another image
3462 xContext
= XMLShapeImportHelper::CreateFrameChildContext(
3463 GetImport(), nElement
, xAttrList
, mxShapes
, mxAttrList
);
3464 mxImplContext
= xContext
;
3466 if(dynamic_cast< SdXMLGraphicObjectShapeContext
* >(xContext
.get()))
3468 addContent(*mxImplContext
);
3471 else if( mbSupportsReplacement
&& !mxReplImplContext
.is() &&
3472 nElement
== XML_ELEMENT(DRAW
, XML_IMAGE
) )
3474 // read replacement image
3475 SvXMLImportContext
*pImplContext
= mxImplContext
.get();
3476 SdXMLShapeContext
*pSContext
=
3477 dynamic_cast<SdXMLShapeContext
*>( pImplContext
);
3480 uno::Reference
< beans::XPropertySet
> xPropSet(
3481 pSContext
->getShape(), uno::UNO_QUERY
);
3484 xContext
= new XMLReplacementImageContext( GetImport(),
3485 nElement
, xAttrList
, xPropSet
);
3486 mxReplImplContext
= xContext
;
3490 else if( nElement
== XML_ELEMENT(SVG
, XML_TITLE
) || // #i68101#
3491 nElement
== XML_ELEMENT(SVG_COMPAT
, XML_TITLE
) ||
3492 nElement
== XML_ELEMENT(SVG
, XML_DESC
) ||
3493 nElement
== XML_ELEMENT(SVG_COMPAT
, XML_DESC
) ||
3494 nElement
== XML_ELEMENT(OFFICE
, XML_EVENT_LISTENERS
) ||
3495 nElement
== XML_ELEMENT(DRAW
, XML_GLUE_POINT
) ||
3496 nElement
== XML_ELEMENT(DRAW
, XML_THUMBNAIL
) )
3498 if (getSupportsMultipleContents())
3499 { // tdf#103567 ensure props are set on surviving shape
3500 // note: no more draw:image can be added once we get here
3501 mxImplContext
= solveMultipleImages();
3503 SvXMLImportContext
*pImplContext
= mxImplContext
.get();
3504 xContext
= static_cast<SvXMLImportContext
*>(dynamic_cast<SdXMLShapeContext
&>(*pImplContext
).createFastChildContext( nElement
,
3507 else if ( nElement
== XML_ELEMENT(DRAW
, XML_IMAGE_MAP
) )
3509 if (getSupportsMultipleContents())
3510 { // tdf#103567 ensure props are set on surviving shape
3511 // note: no more draw:image can be added once we get here
3512 mxImplContext
= solveMultipleImages();
3514 SdXMLShapeContext
*pSContext
= dynamic_cast< SdXMLShapeContext
* >( mxImplContext
.get() );
3517 uno::Reference
< beans::XPropertySet
> xPropSet( pSContext
->getShape(), uno::UNO_QUERY
);
3520 xContext
= new XMLImageMapContext(GetImport(), xPropSet
);
3524 else if ( nElement
== XML_ELEMENT(LO_EXT
, XML_SIGNATURELINE
) )
3526 SdXMLShapeContext
* pSContext
= dynamic_cast<SdXMLShapeContext
*>(mxImplContext
.get());
3529 uno::Reference
<beans::XPropertySet
> xPropSet(pSContext
->getShape(), uno::UNO_QUERY
);
3532 xContext
= new SignatureLineContext(GetImport(), nElement
, xAttrList
,
3533 pSContext
->getShape());
3537 else if ( nElement
== XML_ELEMENT(LO_EXT
, XML_QRCODE
))
3539 SdXMLShapeContext
* pSContext
= dynamic_cast<SdXMLShapeContext
*>(mxImplContext
.get());
3542 uno::Reference
<beans::XPropertySet
> xPropSet(pSContext
->getShape(), uno::UNO_QUERY
);
3545 xContext
= new QRCodeContext(GetImport(), nElement
, xAttrList
,
3546 pSContext
->getShape());
3554 void SdXMLFrameShapeContext::startFastElement (sal_Int32
/*nElement*/,
3555 const css::uno::Reference
< css::xml::sax::XFastAttributeList
>& /*xAttrList*/)
3560 void SdXMLFrameShapeContext::endFastElement(sal_Int32 nElement
)
3562 // solve if multiple image child contexts were imported
3563 SvXMLImportContextRef
const pSelectedContext(solveMultipleImages());
3564 const SdXMLGraphicObjectShapeContext
* pShapeContext(
3565 dynamic_cast<const SdXMLGraphicObjectShapeContext
*>(pSelectedContext
.get()));
3566 if ( pShapeContext
)
3568 assert( mxImplContext
.is() );
3569 const uno::Reference
< uno::XInterface
> xShape( pShapeContext
->getShape() );
3570 GetImport().getInterfaceToIdentifierMapper().registerReservedReference( maShapeId
, xShape
);
3573 if( !mxImplContext
.is() )
3575 // now check if this is an empty presentation object
3576 for( auto& aIter
: sax_fastparser::castToFastAttributeList(mxAttrList
) )
3578 switch (aIter
.getToken())
3580 case XML_ELEMENT(PRESENTATION
, XML_PLACEHOLDER
):
3581 mbIsPlaceholder
= IsXMLToken( aIter
, XML_TRUE
);
3583 case XML_ELEMENT(PRESENTATION
, XML_CLASS
):
3584 maPresentationClass
= aIter
.toString();
3590 if( (!maPresentationClass
.isEmpty()) && mbIsPlaceholder
)
3592 uno::Reference
< xml::sax::XFastAttributeList
> xEmpty
;
3594 enum XMLTokenEnum eToken
= XML_TEXT_BOX
;
3596 if( IsXMLToken( maPresentationClass
, XML_GRAPHIC
) )
3601 else if( IsXMLToken( maPresentationClass
, XML_PAGE
) )
3603 eToken
= XML_PAGE_THUMBNAIL
;
3605 else if( IsXMLToken( maPresentationClass
, XML_CHART
) ||
3606 IsXMLToken( maPresentationClass
, XML_TABLE
) ||
3607 IsXMLToken( maPresentationClass
, XML_OBJECT
) )
3609 eToken
= XML_OBJECT
;
3612 auto x
= XML_ELEMENT(DRAW
, eToken
);
3613 mxImplContext
= XMLShapeImportHelper::CreateFrameChildContext(
3614 GetImport(), x
, mxAttrList
, mxShapes
, xEmpty
);
3616 if( mxImplContext
.is() )
3618 mxImplContext
->startFastElement( x
, mxAttrList
);
3619 mxImplContext
->endFastElement(x
);
3624 mxImplContext
= nullptr;
3625 SdXMLShapeContext::endFastElement(nElement
);
3628 bool SdXMLFrameShapeContext::processAttribute( const sax_fastparser::FastAttributeList::FastAttributeIter
& aIter
)
3632 switch ( aIter
.getToken() )
3634 case XML_ELEMENT(DRAW
, XML_ID
):
3635 case XML_ELEMENT(DRAW_EXT
, XML_ID
):
3636 case XML_ELEMENT(NONE
, XML_ID
):
3637 case XML_ELEMENT(XML
, XML_ID
) :
3644 return SdXMLShapeContext::processAttribute( aIter
);
3645 return true; // deliberately ignoring other attributes
3649 SdXMLCustomShapeContext::SdXMLCustomShapeContext(
3650 SvXMLImport
& rImport
,
3651 const css::uno::Reference
< css::xml::sax::XFastAttributeList
>& xAttrList
,
3652 uno::Reference
< drawing::XShapes
> const & rShapes
)
3653 : SdXMLShapeContext( rImport
, xAttrList
, rShapes
, false/*bTemporaryShape*/ )
3655 // See the XMLTextFrameContext ctor, a frame has Writer content (and not
3656 // editeng) if its autostyle has a parent style. Do the same for shapes as well.
3657 for( auto& aIter
: sax_fastparser::castToFastAttributeList(xAttrList
) )
3659 if (aIter
.getToken() == XML_ELEMENT(DRAW
, XML_STYLE_NAME
))
3661 OUString aStyleName
= aIter
.toString();
3662 if(!aStyleName
.isEmpty())
3664 rtl::Reference
<XMLTextImportHelper
> xTxtImport
= GetImport().GetTextImport();
3665 XMLPropStyleContext
* pStyle
= xTxtImport
->FindAutoFrameStyle(aStyleName
);
3666 // Note that this an API name, so intentionally not localized.
3667 // Also allow other Frame styles with the same prefix, we just want to reject
3668 // Graphics after all.
3669 if (pStyle
&& pStyle
->GetParentName().startsWith("Frame"))
3679 SdXMLCustomShapeContext::~SdXMLCustomShapeContext()
3683 // this is called from the parent group for each unparsed attribute in the attribute list
3684 bool SdXMLCustomShapeContext::processAttribute( const sax_fastparser::FastAttributeList::FastAttributeIter
& aIter
)
3686 if( aIter
.getToken() == XML_ELEMENT(DRAW
, XML_ENGINE
) )
3688 maCustomShapeEngine
= aIter
.toString();
3690 else if (aIter
.getToken() == XML_ELEMENT(DRAW
, XML_DATA
) )
3692 maCustomShapeData
= aIter
.toString();
3695 return SdXMLShapeContext::processAttribute( aIter
);
3699 void SdXMLCustomShapeContext::startFastElement (sal_Int32 nElement
,
3700 const css::uno::Reference
< css::xml::sax::XFastAttributeList
>& xAttrList
)
3702 // create rectangle shape
3703 AddShape("com.sun.star.drawing.CustomShape");
3704 if ( !mxShape
.is() )
3707 // Add, set Style and properties from base shape
3711 // set pos, size, shear and rotate
3712 SetTransformation();
3716 uno::Reference
< beans::XPropertySet
> xPropSet( mxShape
, uno::UNO_QUERY
);
3719 if ( !maCustomShapeEngine
.isEmpty() )
3721 xPropSet
->setPropertyValue( EASGet( EAS_CustomShapeEngine
), Any(maCustomShapeEngine
) );
3723 if ( !maCustomShapeData
.isEmpty() )
3725 xPropSet
->setPropertyValue( EASGet( EAS_CustomShapeData
), Any(maCustomShapeData
) );
3729 catch(const uno::Exception
&)
3731 DBG_UNHANDLED_EXCEPTION( "xmloff", "setting enhanced customshape geometry" );
3733 SdXMLShapeContext::startFastElement(nElement
, xAttrList
);
3736 void SdXMLCustomShapeContext::endFastElement(sal_Int32 nElement
)
3738 // Customshapes remember mirror state in its enhanced geometry.
3739 // SetTransformation() in StartElement() may have applied mirroring, but that is not yet
3740 // contained. Merge that information here before writing the property.
3741 if(!maUsedTransformation
.isIdentity())
3743 basegfx::B2DVector aScale
, aTranslate
;
3744 double fRotate
, fShearX
;
3746 maUsedTransformation
.decompose(aScale
, aTranslate
, fRotate
, fShearX
);
3748 if (aScale
.getX() < 0.0)
3750 static constexpr OUString
sName(u
"MirroredX"_ustr
);
3751 //fdo#84043 Merge, if property exists, otherwise append it
3752 auto aI
= std::find_if(maCustomShapeGeometry
.begin(), maCustomShapeGeometry
.end(),
3753 [](beans::PropertyValue
& rValue
) { return rValue
.Name
== sName
; });
3754 if (aI
!= maCustomShapeGeometry
.end())
3756 beans::PropertyValue
& rItem
= *aI
;
3757 bool bMirroredX
= *o3tl::doAccess
<bool>(rItem
.Value
);
3758 rItem
.Value
<<= !bMirroredX
;
3760 rItem
.State
= beans::PropertyState_DIRECT_VALUE
;
3764 beans::PropertyValue
* pItem
;
3765 maCustomShapeGeometry
.emplace_back();
3766 pItem
= &maCustomShapeGeometry
.back();
3767 pItem
->Name
= sName
;
3769 pItem
->Value
<<= true;
3770 pItem
->State
= beans::PropertyState_DIRECT_VALUE
;
3774 if (aScale
.getY() < 0.0)
3776 static constexpr OUString
sName(u
"MirroredY"_ustr
);
3777 //fdo#84043 Merge, if property exists, otherwise append it
3778 auto aI
= std::find_if(maCustomShapeGeometry
.begin(), maCustomShapeGeometry
.end(),
3779 [](beans::PropertyValue
& rValue
) { return rValue
.Name
== sName
; });
3780 if (aI
!= maCustomShapeGeometry
.end())
3782 beans::PropertyValue
& rItem
= *aI
;
3783 bool bMirroredY
= *o3tl::doAccess
<bool>(rItem
.Value
);
3784 rItem
.Value
<<= !bMirroredY
;
3786 rItem
.State
= beans::PropertyState_DIRECT_VALUE
;
3790 beans::PropertyValue
* pItem
;
3791 maCustomShapeGeometry
.emplace_back();
3792 pItem
= &maCustomShapeGeometry
.back();
3793 pItem
->Name
= sName
;
3795 pItem
->Value
<<= true;
3796 pItem
->State
= beans::PropertyState_DIRECT_VALUE
;
3801 if ( !maCustomShapeGeometry
.empty() )
3803 // converting the vector to a sequence
3804 uno::Sequence
< beans::PropertyValue
> aSeq( comphelper::containerToSequence(maCustomShapeGeometry
) );
3808 uno::Reference
< beans::XPropertySet
> xPropSet( mxShape
, uno::UNO_QUERY
);
3811 xPropSet
->setPropertyValue( "CustomShapeGeometry", Any(aSeq
) );
3814 catch(const uno::Exception
&)
3816 DBG_UNHANDLED_EXCEPTION( "xmloff", "setting enhanced customshape geometry" );
3821 if (GetImport().getBuildIds(nUPD
, nBuild
))
3823 if( ((nUPD
>= 640 && nUPD
<= 645) || (nUPD
== 680)) && (nBuild
<= 9221) )
3825 Reference
< drawing::XEnhancedCustomShapeDefaulter
> xDefaulter( mxShape
, UNO_QUERY
);
3826 if( xDefaulter
.is() )
3828 xDefaulter
->createCustomShapeDefaults( "" );
3834 SdXMLShapeContext::endFastElement(nElement
);
3836 // tdf#98163 call a custom slot to be able to reset the UNO API
3837 // implementations held on the SdrObjects of type
3838 // SdrObjCustomShape - those tend to linger until the entire file
3839 // is loaded. For large files with a lot of these, 32bit systems
3840 // may crash due to being out of resources after ca. 4200
3841 // Outliners and VirtualDevices used there as RefDevice
3844 uno::Reference
< beans::XPropertySet
> xPropSet(mxShape
, uno::UNO_QUERY
);
3848 xPropSet
->setPropertyValue(
3849 "FlushCustomShapeUnoApiObjects", css::uno::Any(true));
3852 catch(const uno::Exception
&)
3854 DBG_UNHANDLED_EXCEPTION("xmloff", "flushing after load");
3858 css::uno::Reference
< css::xml::sax::XFastContextHandler
> SdXMLCustomShapeContext::createFastChildContext(
3860 const uno::Reference
< xml::sax::XFastAttributeList
>& xAttrList
)
3862 css::uno::Reference
< css::xml::sax::XFastContextHandler
> xContext
;
3863 if ( nElement
== XML_ELEMENT(DRAW
, XML_ENHANCED_GEOMETRY
) )
3865 uno::Reference
< beans::XPropertySet
> xPropSet( mxShape
,uno::UNO_QUERY
);
3866 if ( xPropSet
.is() )
3867 xContext
= new XMLEnhancedCustomShapeContext( GetImport(), mxShape
, maCustomShapeGeometry
);
3869 // delegate to parent class if no context could be created
3871 xContext
= SdXMLShapeContext::createFastChildContext( nElement
,
3876 SdXMLTableShapeContext::SdXMLTableShapeContext( SvXMLImport
& rImport
, const css::uno::Reference
< css::xml::sax::XFastAttributeList
>& xAttrList
, css::uno::Reference
< css::drawing::XShapes
> const & rShapes
)
3877 : SdXMLShapeContext( rImport
, xAttrList
, rShapes
, false )
3881 SdXMLTableShapeContext::~SdXMLTableShapeContext()
3885 void SdXMLTableShapeContext::startFastElement (sal_Int32 nElement
,
3886 const css::uno::Reference
< css::xml::sax::XFastAttributeList
>& xAttrList
)
3888 OUString
service("com.sun.star.drawing.TableShape");
3890 bool bIsPresShape
= !maPresentationClass
.isEmpty() && GetImport().GetShapeImport()->IsPresentationShapesSupported();
3893 if( IsXMLToken( maPresentationClass
, XML_TABLE
) )
3895 service
= "com.sun.star.presentation.TableShape";
3906 uno::Reference
< beans::XPropertySet
> xProps(mxShape
, uno::UNO_QUERY
);
3908 if(bIsPresShape
&& xProps
.is())
3910 uno::Reference
< beans::XPropertySetInfo
> xPropsInfo( xProps
->getPropertySetInfo() );
3911 if( xPropsInfo
.is() )
3913 if( !mbIsPlaceholder
&& xPropsInfo
->hasPropertyByName("IsEmptyPresentationObject"))
3914 xProps
->setPropertyValue("IsEmptyPresentationObject", css::uno::Any(false) );
3916 if( mbIsUserTransformed
&& xPropsInfo
->hasPropertyByName("IsPlaceholderDependent"))
3917 xProps
->setPropertyValue("IsPlaceholderDependent", css::uno::Any(false) );
3925 if( !msTemplateStyleName
.isEmpty() ) try
3927 Reference
< XStyleFamiliesSupplier
> xFamiliesSupp( GetImport().GetModel(), UNO_QUERY_THROW
);
3928 Reference
< XNameAccess
> xFamilies( xFamiliesSupp
->getStyleFamilies() );
3929 Reference
< XNameAccess
> xTableFamily( xFamilies
->getByName( "table" ), UNO_QUERY_THROW
);
3930 Reference
< XStyle
> xTableStyle( xTableFamily
->getByName( msTemplateStyleName
), UNO_QUERY_THROW
);
3931 xProps
->setPropertyValue("TableTemplate", Any( xTableStyle
) );
3933 catch(const Exception
&)
3935 DBG_UNHANDLED_EXCEPTION("xmloff.draw");
3938 const XMLPropertyMapEntry
* pEntry
= &aXMLTableShapeAttributes
[0];
3939 for( int i
= 0; !pEntry
->IsEnd() && (i
< 6); i
++, pEntry
++ )
3943 xProps
->setPropertyValue( pEntry
->getApiName(), Any( maTemplateStylesUsed
[i
] ) );
3945 catch(const Exception
&)
3947 DBG_UNHANDLED_EXCEPTION("xmloff.draw");
3952 GetImport().GetShapeImport()->finishShape( mxShape
, mxAttrList
, mxShapes
);
3954 const rtl::Reference
< XMLTableImport
>& xTableImport( GetImport().GetShapeImport()->GetShapeTableImport() );
3955 if( xTableImport
.is() && xProps
.is() )
3957 uno::Reference
< table::XColumnRowRange
> xColumnRowRange(
3958 xProps
->getPropertyValue("Model"), uno::UNO_QUERY
);
3960 if( xColumnRowRange
.is() )
3961 mxTableImportContext
= xTableImport
->CreateTableContext( xColumnRowRange
);
3963 if( mxTableImportContext
.is() )
3964 mxTableImportContext
->startFastElement( nElement
, xAttrList
);
3968 void SdXMLTableShapeContext::endFastElement(sal_Int32 nElement
)
3970 if( mxTableImportContext
.is() )
3971 mxTableImportContext
->endFastElement(nElement
);
3973 SdXMLShapeContext::endFastElement(nElement
);
3977 // set pos, size, shear and rotate
3978 SetTransformation();
3982 // this is called from the parent group for each unparsed attribute in the attribute list
3983 bool SdXMLTableShapeContext::processAttribute( const sax_fastparser::FastAttributeList::FastAttributeIter
& aIter
)
3985 auto nElement
= aIter
.getToken();
3986 if( IsTokenInNamespace(nElement
, XML_NAMESPACE_TABLE
) )
3988 if( (nElement
& TOKEN_MASK
) == XML_TEMPLATE_NAME
)
3990 msTemplateStyleName
= aIter
.toString();
3995 const XMLPropertyMapEntry
* pEntry
= &aXMLTableShapeAttributes
[0];
3996 while( !pEntry
->IsEnd() && (i
< 6) )
3998 if( (nElement
& TOKEN_MASK
) == pEntry
->meXMLName
)
4000 if( IsXMLToken( aIter
, XML_TRUE
) )
4001 maTemplateStylesUsed
[i
] = true;
4009 return SdXMLShapeContext::processAttribute( aIter
);
4012 css::uno::Reference
< css::xml::sax::XFastContextHandler
> SdXMLTableShapeContext::createFastChildContext(
4014 const css::uno::Reference
< css::xml::sax::XFastAttributeList
>& xAttrList
)
4016 if( mxTableImportContext
.is() && IsTokenInNamespace(nElement
, XML_NAMESPACE_TABLE
) )
4017 return mxTableImportContext
->createFastChildContext(nElement
, xAttrList
);
4018 return SdXMLShapeContext::createFastChildContext(nElement
, xAttrList
);
4021 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */