Update git submodules
[LibreOffice.git] / xmloff / source / draw / ximpshap.cxx
blobdbaefd30b95c3967455f9c23cf6ede129cb13cb1
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
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>
22 #include <cassert>
24 #include <sal/log.hxx>
25 #include <com/sun/star/document/XEventsSupplier.hpp>
26 #include <com/sun/star/container/XNameReplace.hpp>
27 #include <com/sun/star/presentation/ClickAction.hpp>
28 #include <com/sun/star/drawing/FillStyle.hpp>
29 #include <com/sun/star/drawing/LineStyle.hpp>
30 #include <utility>
31 #include <xmloff/unointerfacetouniqueidentifiermapper.hxx>
32 #include <com/sun/star/drawing/XGluePointsSupplier.hpp>
33 #include <com/sun/star/drawing/GluePoint2.hpp>
34 #include <com/sun/star/media/ZoomLevel.hpp>
35 #include <com/sun/star/awt/Rectangle.hpp>
36 #include <com/sun/star/style/XStyleFamiliesSupplier.hpp>
37 #include <com/sun/star/container/XNameAccess.hpp>
38 #include "ximpshap.hxx"
39 #include <xmloff/XMLBase64ImportContext.hxx>
40 #include <xmloff/XMLShapeStyleContext.hxx>
41 #include <xmloff/xmluconv.hxx>
42 #include <com/sun/star/container/XNamed.hpp>
43 #include <com/sun/star/beans/XPropertySet.hpp>
44 #include <com/sun/star/awt/XControlModel.hpp>
45 #include <com/sun/star/drawing/XControlShape.hpp>
46 #include <com/sun/star/drawing/PointSequenceSequence.hpp>
47 #include <com/sun/star/drawing/PointSequence.hpp>
48 #include <com/sun/star/lang/XServiceInfo.hpp>
49 #include <com/sun/star/lang/XMultiServiceFactory.hpp>
50 #include <com/sun/star/util/XCloneable.hpp>
51 #include <com/sun/star/beans/XMultiPropertyStates.hpp>
52 #include <xexptran.hxx>
53 #include <com/sun/star/drawing/PolyPolygonBezierCoords.hpp>
54 #include <com/sun/star/beans/XPropertySetInfo.hpp>
55 #include <com/sun/star/drawing/HomogenMatrix3.hpp>
56 #include <com/sun/star/graphic/XGraphic.hpp>
57 #include <com/sun/star/style/XStyle.hpp>
59 #include <sax/tools/converter.hxx>
60 #include <comphelper/sequence.hxx>
61 #include <comphelper/diagnose_ex.hxx>
62 #include <comphelper/mediamimetype.hxx>
64 #include <xmloff/families.hxx>
65 #include<xmloff/xmlnamespace.hxx>
66 #include <xmloff/xmltoken.hxx>
67 #include <EnhancedCustomShapeToken.hxx>
68 #include <XMLReplacementImageContext.hxx>
69 #include <XMLImageMapContext.hxx>
70 #include "sdpropls.hxx"
71 #include "eventimp.hxx"
72 #include "descriptionimp.hxx"
73 #include "SignatureLineContext.hxx"
74 #include "QRCodeContext.hxx"
75 #include "ximpcustomshape.hxx"
76 #include <XMLEmbeddedObjectImportContext.hxx>
77 #include <xmloff/xmlerror.hxx>
78 #include <xmloff/table/XMLTableImport.hxx>
79 #include <xmloff/ProgressBarHelper.hxx>
80 #include <basegfx/matrix/b2dhommatrix.hxx>
81 #include <com/sun/star/drawing/XEnhancedCustomShapeDefaulter.hpp>
82 #include <com/sun/star/container/XChild.hpp>
83 #include <com/sun/star/text/XTextDocument.hpp>
84 #include <basegfx/matrix/b2dhommatrixtools.hxx>
85 #include <basegfx/point/b2dpoint.hxx>
86 #include <basegfx/polygon/b2dpolygon.hxx>
87 #include <basegfx/polygon/b2dpolygontools.hxx>
88 #include <basegfx/polygon/b2dpolypolygon.hxx>
89 #include <basegfx/polygon/b2dpolypolygontools.hxx>
90 #include <basegfx/vector/b2dvector.hxx>
91 #include <tools/urlobj.hxx>
92 #include <o3tl/any.hxx>
93 #include <o3tl/safeint.hxx>
95 using namespace ::com::sun::star;
96 using namespace ::com::sun::star::uno;
97 using namespace ::com::sun::star::drawing;
98 using namespace ::com::sun::star::style;
99 using namespace ::com::sun::star::container;
100 using namespace ::com::sun::star::document;
101 using namespace ::xmloff::token;
102 using namespace ::xmloff::EnhancedCustomShapeToken;
104 SvXMLEnumMapEntry<drawing::Alignment> const aXML_GlueAlignment_EnumMap[] =
106 { XML_TOP_LEFT, drawing::Alignment_TOP_LEFT },
107 { XML_TOP, drawing::Alignment_TOP },
108 { XML_TOP_RIGHT, drawing::Alignment_TOP_RIGHT },
109 { XML_LEFT, drawing::Alignment_LEFT },
110 { XML_CENTER, drawing::Alignment_CENTER },
111 { XML_RIGHT, drawing::Alignment_RIGHT },
112 { XML_BOTTOM_LEFT, drawing::Alignment_BOTTOM_LEFT },
113 { XML_BOTTOM, drawing::Alignment_BOTTOM },
114 { XML_BOTTOM_RIGHT, drawing::Alignment_BOTTOM_RIGHT },
115 { XML_TOKEN_INVALID, drawing::Alignment(0) }
118 SvXMLEnumMapEntry<drawing::EscapeDirection> const aXML_GlueEscapeDirection_EnumMap[] =
120 { XML_AUTO, drawing::EscapeDirection_SMART },
121 { XML_LEFT, drawing::EscapeDirection_LEFT },
122 { XML_RIGHT, drawing::EscapeDirection_RIGHT },
123 { XML_UP, drawing::EscapeDirection_UP },
124 { XML_DOWN, drawing::EscapeDirection_DOWN },
125 { XML_HORIZONTAL, drawing::EscapeDirection_HORIZONTAL },
126 { XML_VERTICAL, drawing::EscapeDirection_VERTICAL },
127 { XML_TOKEN_INVALID, drawing::EscapeDirection(0) }
130 static bool ImpIsEmptyURL( std::u16string_view rURL )
132 if( rURL.empty() )
133 return true;
135 // #i13140# Also compare against 'toplevel' URLs. which also
136 // result in empty filename strings.
137 if( rURL == u"#./" )
138 return true;
140 return false;
144 SdXMLShapeContext::SdXMLShapeContext(
145 SvXMLImport& rImport,
146 css::uno::Reference< css::xml::sax::XFastAttributeList> xAttrList,
147 uno::Reference< drawing::XShapes > xShapes,
148 bool bTemporaryShape)
149 : SvXMLShapeContext( rImport, bTemporaryShape )
150 , mxShapes(std::move( xShapes ))
151 , mxAttrList(std::move(xAttrList))
152 , mbListContextPushed( false )
153 , mnStyleFamily(XmlStyleFamily::SD_GRAPHICS_ID)
154 , mbIsPlaceholder(false)
155 , mbClearDefaultAttributes( true )
156 , mbIsUserTransformed(false)
157 , mnZOrder(-1)
158 , maSize(1, 1)
159 , mnRelWidth(0)
160 , mnRelHeight(0)
161 , maPosition(0, 0)
162 , mbVisible(true)
163 , mbPrintable(true)
164 , mbHaveXmlId(false)
165 , mbTextBox(false)
169 SdXMLShapeContext::~SdXMLShapeContext()
173 css::uno::Reference< css::xml::sax::XFastContextHandler > SdXMLShapeContext::createFastChildContext(
174 sal_Int32 nElement,
175 const css::uno::Reference< css::xml::sax::XFastAttributeList >& xAttrList )
177 SvXMLImportContextRef xContext;
178 // #i68101#
179 if( nElement == XML_ELEMENT(SVG, XML_TITLE) || nElement == XML_ELEMENT(SVG, XML_DESC)
180 || nElement == XML_ELEMENT(SVG_COMPAT, XML_TITLE) || nElement == XML_ELEMENT(SVG_COMPAT, XML_DESC) )
182 xContext = new SdXMLDescriptionContext( GetImport(), nElement, mxShape );
184 else if( nElement == XML_ELEMENT(LO_EXT, XML_SIGNATURELINE) )
186 xContext = new SignatureLineContext( GetImport(), nElement, xAttrList, mxShape );
188 else if( nElement == XML_ELEMENT(LO_EXT, XML_QRCODE) )
190 xContext = new QRCodeContext( GetImport(), nElement, xAttrList, mxShape );
192 else if( nElement == XML_ELEMENT(OFFICE, XML_EVENT_LISTENERS) )
194 xContext = new SdXMLEventsContext( GetImport(), mxShape );
196 else if( nElement == XML_ELEMENT(DRAW, XML_GLUE_POINT) )
198 addGluePoint( xAttrList );
200 else if( nElement == XML_ELEMENT(DRAW, XML_THUMBNAIL) )
202 // search attributes for xlink:href
203 maThumbnailURL = xAttrList->getOptionalValue(XML_ELEMENT(XLINK, XML_HREF));
205 else
207 // create text cursor on demand
208 if( !mxCursor.is() )
210 uno::Reference< text::XText > xText( mxShape, uno::UNO_QUERY );
211 if( xText.is() )
213 rtl::Reference < XMLTextImportHelper > xTxtImport =
214 GetImport().GetTextImport();
215 mxOldCursor = xTxtImport->GetCursor();
216 mxCursor = xText->createTextCursor();
217 if( mxCursor.is() )
219 xTxtImport->SetCursor( mxCursor );
222 // remember old list item and block (#91964#) and reset them
223 // for the text frame
224 xTxtImport->PushListContext();
225 mbListContextPushed = true;
229 // if we have a text cursor, let's try to import some text
230 if( mxCursor.is() )
232 xContext = GetImport().GetTextImport()->CreateTextChildContext(
233 GetImport(), nElement, xAttrList,
234 ( mbTextBox ? XMLTextType::TextBox : XMLTextType::Shape ) );
238 if (!xContext)
239 XMLOFF_WARN_UNKNOWN_ELEMENT("xmloff", nElement);
241 return xContext;
244 void SdXMLShapeContext::addGluePoint( const uno::Reference< xml::sax::XFastAttributeList>& xAttrList )
246 // get the gluepoints container for this shape if it's not already there
247 if( !mxGluePoints.is() )
249 uno::Reference< drawing::XGluePointsSupplier > xSupplier( mxShape, uno::UNO_QUERY );
250 if( !xSupplier.is() )
251 return;
253 mxGluePoints.set( xSupplier->getGluePoints(), UNO_QUERY );
255 if( !mxGluePoints.is() )
256 return;
259 drawing::GluePoint2 aGluePoint;
260 aGluePoint.IsUserDefined = true;
261 aGluePoint.Position.X = 0;
262 aGluePoint.Position.Y = 0;
263 aGluePoint.Escape = drawing::EscapeDirection_SMART;
264 aGluePoint.PositionAlignment = drawing::Alignment_CENTER;
265 aGluePoint.IsRelative = true;
267 sal_Int32 nId = -1;
269 // read attributes for the 3DScene
270 for( auto& aIter : sax_fastparser::castToFastAttributeList(xAttrList) )
272 switch(aIter.getToken())
274 case XML_ELEMENT(SVG, XML_X):
275 case XML_ELEMENT(SVG_COMPAT, XML_X):
276 GetImport().GetMM100UnitConverter().convertMeasureToCore(
277 aGluePoint.Position.X, aIter.toView());
278 break;
279 case XML_ELEMENT(SVG, XML_Y):
280 case XML_ELEMENT(SVG_COMPAT, XML_Y):
281 GetImport().GetMM100UnitConverter().convertMeasureToCore(
282 aGluePoint.Position.Y, aIter.toView());
283 break;
284 case XML_ELEMENT(DRAW, XML_ID):
285 nId = aIter.toInt32();
286 break;
287 case XML_ELEMENT(DRAW, XML_ALIGN):
289 drawing::Alignment eKind;
290 if( SvXMLUnitConverter::convertEnum( eKind, aIter.toView(), aXML_GlueAlignment_EnumMap ) )
292 aGluePoint.PositionAlignment = eKind;
293 aGluePoint.IsRelative = false;
295 break;
297 case XML_ELEMENT(DRAW, XML_ESCAPE_DIRECTION):
299 SvXMLUnitConverter::convertEnum( aGluePoint.Escape, aIter.toView(), aXML_GlueEscapeDirection_EnumMap );
300 break;
302 default:
303 XMLOFF_WARN_UNKNOWN("xmloff", aIter);
307 if( nId != -1 )
311 sal_Int32 nInternalId = mxGluePoints->insert( uno::Any( aGluePoint ) );
312 GetImport().GetShapeImport()->addGluePointMapping( mxShape, nId, nInternalId );
314 catch(const uno::Exception&)
316 DBG_UNHANDLED_EXCEPTION( "xmloff", "during setting of gluepoints");
321 void SdXMLShapeContext::startFastElement (sal_Int32 /*nElement*/,
322 const css::uno::Reference< css::xml::sax::XFastAttributeList >& /*xAttrList*/)
324 GetImport().GetShapeImport()->finishShape( mxShape, mxAttrList, mxShapes );
327 void SdXMLShapeContext::endFastElement(sal_Int32 )
329 if(mxCursor.is())
331 // tdf#72776 force UpdateData in the EditSource so we will not override text in SdrOutliner
332 if( mxLockable.is() )
334 mxLockable->removeActionLock();
335 mxLockable->addActionLock();
338 // delete addition newline
339 mxCursor->gotoEnd( false );
340 mxCursor->goLeft( 1, true );
341 mxCursor->setString( u""_ustr );
343 // reset cursor
344 GetImport().GetTextImport()->ResetCursor();
347 if(mxOldCursor.is())
348 GetImport().GetTextImport()->SetCursor( mxOldCursor );
350 // reinstall old list item (if necessary) #91964#
351 if (mbListContextPushed) {
352 GetImport().GetTextImport()->PopListContext();
355 if( !msHyperlink.isEmpty() ) try
357 uno::Reference< beans::XPropertySet > xProp( mxShape, uno::UNO_QUERY );
359 if ( xProp.is() && xProp->getPropertySetInfo()->hasPropertyByName( u"Hyperlink"_ustr ) )
360 xProp->setPropertyValue( u"Hyperlink"_ustr, uno::Any( msHyperlink ) );
361 Reference< XEventsSupplier > xEventsSupplier( mxShape, UNO_QUERY );
363 if( xEventsSupplier.is() )
365 Reference< XNameReplace > xEvents( xEventsSupplier->getEvents(), UNO_SET_THROW );
367 uno::Sequence< beans::PropertyValue > aProperties{
368 { /* Name */ u"EventType"_ustr,
369 /* Handle */ -1,
370 /* Value */ uno::Any(u"Presentation"_ustr),
371 /* State */ beans::PropertyState_DIRECT_VALUE },
373 { /* Name */ u"ClickAction"_ustr,
374 /* Handle */ -1,
375 /* Value */ uno::Any(css::presentation::ClickAction_DOCUMENT),
376 /* State */ beans::PropertyState_DIRECT_VALUE },
378 { /* Name */ u"Bookmark"_ustr,
379 /* Handle */ -1,
380 /* Value */ uno::Any(msHyperlink),
381 /* State */ beans::PropertyState_DIRECT_VALUE }
384 xEvents->replaceByName( u"OnClick"_ustr, Any( aProperties ) );
386 else
388 // in draw use the Bookmark property
389 Reference< beans::XPropertySet > xSet( mxShape, UNO_QUERY_THROW );
390 xSet->setPropertyValue( u"Bookmark"_ustr, Any( msHyperlink ) );
391 xSet->setPropertyValue(u"OnClick"_ustr, Any( css::presentation::ClickAction_DOCUMENT ) );
394 catch(const Exception&)
396 DBG_UNHANDLED_EXCEPTION("xmloff", "while setting hyperlink");
399 if( mxLockable.is() )
400 mxLockable->removeActionLock();
403 void SdXMLShapeContext::AddShape(uno::Reference< drawing::XShape >& xShape)
405 if(xShape.is())
407 // set shape local
408 mxShape = xShape;
410 if(!maShapeName.isEmpty())
412 uno::Reference< container::XNamed > xNamed( mxShape, uno::UNO_QUERY );
413 if( xNamed.is() )
414 xNamed->setName( maShapeName );
417 rtl::Reference< XMLShapeImportHelper > xImp( GetImport().GetShapeImport() );
418 xImp->addShape( xShape, mxAttrList, mxShapes );
420 if( mbClearDefaultAttributes )
422 uno::Reference<beans::XMultiPropertyStates> xMultiPropertyStates(xShape, uno::UNO_QUERY );
423 if (xMultiPropertyStates.is())
424 xMultiPropertyStates->setAllPropertiesToDefault();
427 if( !mbVisible || !mbPrintable ) try
429 uno::Reference< beans::XPropertySet > xSet( xShape, uno::UNO_QUERY_THROW );
430 if( !mbVisible )
431 xSet->setPropertyValue(u"Visible"_ustr, uno::Any( false ) );
433 if( !mbPrintable )
434 xSet->setPropertyValue(u"Printable"_ustr, uno::Any( false ) );
436 catch(const Exception&)
438 DBG_UNHANDLED_EXCEPTION( "xmloff", "while setting visible or printable" );
441 if(!mbTemporaryShape && (!GetImport().HasTextImport()
442 || !GetImport().GetTextImport()->IsInsideDeleteContext()))
444 xImp->shapeWithZIndexAdded( xShape, mnZOrder );
447 if (mnRelWidth || mnRelHeight)
449 uno::Reference<beans::XPropertySet> xPropertySet(xShape, uno::UNO_QUERY);
450 uno::Reference<beans::XPropertySetInfo> xPropertySetInfo = xPropertySet->getPropertySetInfo();
451 if (mnRelWidth && xPropertySetInfo->hasPropertyByName(u"RelativeWidth"_ustr))
452 xPropertySet->setPropertyValue(u"RelativeWidth"_ustr, uno::Any(mnRelWidth));
453 if (mnRelHeight && xPropertySetInfo->hasPropertyByName(u"RelativeHeight"_ustr))
454 xPropertySet->setPropertyValue(u"RelativeHeight"_ustr, uno::Any(mnRelHeight));
457 if( !maShapeId.isEmpty() )
459 uno::Reference< uno::XInterface > xRef( static_cast<uno::XInterface *>(xShape.get()) );
460 GetImport().getInterfaceToIdentifierMapper().registerReference( maShapeId, xRef );
463 // #91065# count only if counting for shape import is enabled
464 if(GetImport().GetShapeImport()->IsHandleProgressBarEnabled())
466 // #80365# increment progress bar at load once for each draw object
467 GetImport().GetProgressBarHelper()->Increment();
471 mxLockable.set( xShape, UNO_QUERY );
473 if( mxLockable.is() )
474 mxLockable->addActionLock();
478 void SdXMLShapeContext::AddShape(OUString const & serviceName)
480 uno::Reference< lang::XMultiServiceFactory > xServiceFact(GetImport().GetModel(), uno::UNO_QUERY);
481 if(!xServiceFact.is())
482 return;
486 /* Since fix for issue i33294 the Writer model doesn't support
487 com.sun.star.drawing.OLE2Shape anymore.
488 To handle Draw OLE objects it's decided to import these
489 objects as com.sun.star.drawing.OLE2Shape and convert these
490 objects after the import into com.sun.star.drawing.GraphicObjectShape.
492 uno::Reference< drawing::XShape > xShape;
493 if ( serviceName == "com.sun.star.drawing.OLE2Shape" &&
494 uno::Reference< text::XTextDocument >(GetImport().GetModel(), uno::UNO_QUERY).is() )
496 xShape.set(xServiceFact->createInstance(u"com.sun.star.drawing.temporaryForXMLImportOLE2Shape"_ustr), uno::UNO_QUERY);
498 else if (serviceName == "com.sun.star.drawing.GraphicObjectShape"
499 || serviceName == "com.sun.star.drawing.AppletShape"
500 || serviceName == "com.sun.star.drawing.FrameShape"
501 || serviceName == "com.sun.star.drawing.MediaShape"
502 || serviceName == "com.sun.star.drawing.OLE2Shape"
503 || serviceName == "com.sun.star.drawing.PluginShape"
504 || serviceName == "com.sun.star.presentation.MediaShape")
506 // On adding another entry to this list of service names to pass an argument via the WithArguments variant
507 // you may need to adjust the more obscure OReportDefinition::createInstanceWithArguments as well as the
508 // more obvious SvxUnoDrawMSFactory::createInstanceWithArguments
509 xShape.set( xServiceFact->createInstanceWithArguments(serviceName, { css::uno::Any(GetImport().GetDocumentBase()) }),
510 css::uno::UNO_QUERY);
512 else
514 xShape.set(xServiceFact->createInstance(serviceName), uno::UNO_QUERY);
516 if( xShape.is() )
517 AddShape( xShape );
519 catch(const uno::Exception& e)
521 TOOLS_WARN_EXCEPTION("xmloff", "AddShape " << serviceName);
522 uno::Sequence<OUString> aSeq { serviceName };
523 GetImport().SetError( XMLERROR_FLAG_ERROR | XMLERROR_API,
524 aSeq, e.Message, nullptr );
528 void SdXMLShapeContext::SetTransformation()
530 if(!mxShape.is())
531 return;
533 uno::Reference< beans::XPropertySet > xPropSet(mxShape, uno::UNO_QUERY);
534 if(!xPropSet.is())
535 return;
537 maUsedTransformation.identity();
539 if(maSize.Width != 1 || maSize.Height != 1)
541 // take care there are no zeros used by error
542 if(0 == maSize.Width)
543 maSize.Width = 1;
544 if(0 == maSize.Height)
545 maSize.Height = 1;
547 // set global size. This should always be used.
548 maUsedTransformation.scale(maSize.Width, maSize.Height);
551 if(maPosition.X != 0 || maPosition.Y != 0)
553 // if global position is used, add it to transformation
554 maUsedTransformation.translate(maPosition.X, maPosition.Y);
557 if(mnTransform.NeedsAction())
559 // transformation is used, apply to object.
560 // NOTICE: The transformation is applied AFTER evtl. used
561 // global positioning and scaling is used, so any shear or
562 // rotate used herein is applied around the (0,0) position
563 // of the PAGE object !!!
564 ::basegfx::B2DHomMatrix aMat;
565 mnTransform.GetFullTransform(aMat);
567 // now add to transformation
568 maUsedTransformation *= aMat;
571 // now set transformation for this object
573 // maUsedTransformtion contains the mathematical correct matrix, which if
574 // applied to a unit square would generate the transformed shape. But the property
575 // "Transformation" contains a matrix, which can be used in TRSetBaseGeometry
576 // and would be created by TRGetBaseGeometry. And those use a mathematically wrong
577 // sign for the shearing angle. So we need to adapt the matrix here.
578 basegfx::B2DTuple aScale;
579 basegfx::B2DTuple aTranslate;
580 double fRotate;
581 double fShearX;
582 maUsedTransformation.decompose(aScale, aTranslate, fRotate, fShearX);
583 basegfx::B2DHomMatrix aB2DHomMatrix;
584 aB2DHomMatrix = basegfx::utils::createScaleShearXRotateTranslateB2DHomMatrix(
585 aScale,
586 basegfx::fTools::equalZero(fShearX) ? 0.0 : -fShearX,
587 basegfx::fTools::equalZero(fRotate) ? 0.0 : fRotate,
588 aTranslate);
589 drawing::HomogenMatrix3 aUnoMatrix;
591 aUnoMatrix.Line1.Column1 = aB2DHomMatrix.get(0, 0);
592 aUnoMatrix.Line1.Column2 = aB2DHomMatrix.get(0, 1);
593 aUnoMatrix.Line1.Column3 = aB2DHomMatrix.get(0, 2);
595 aUnoMatrix.Line2.Column1 = aB2DHomMatrix.get(1, 0);
596 aUnoMatrix.Line2.Column2 = aB2DHomMatrix.get(1, 1);
597 aUnoMatrix.Line2.Column3 = aB2DHomMatrix.get(1, 2);
599 aUnoMatrix.Line3.Column1 = 0;
600 aUnoMatrix.Line3.Column2 = 0;
601 aUnoMatrix.Line3.Column3 = 1;
603 xPropSet->setPropertyValue(u"Transformation"_ustr, Any(aUnoMatrix));
606 void SdXMLShapeContext::SetStyle( bool bSupportsStyle /* = true */)
610 uno::Reference< beans::XPropertySet > xPropSet(mxShape, uno::UNO_QUERY);
611 if( !xPropSet.is() )
612 return;
616 // set style on shape
617 if(maDrawStyleName.isEmpty())
618 break;
620 const SvXMLStyleContext* pStyle = nullptr;
621 bool bAutoStyle(false);
623 if(GetImport().GetShapeImport()->GetAutoStylesContext())
624 pStyle = GetImport().GetShapeImport()->GetAutoStylesContext()->FindStyleChildContext(mnStyleFamily, maDrawStyleName);
626 if(pStyle)
627 bAutoStyle = true;
629 if(!pStyle && GetImport().GetShapeImport()->GetStylesContext())
630 pStyle = GetImport().GetShapeImport()->GetStylesContext()->FindStyleChildContext(mnStyleFamily, maDrawStyleName);
632 OUString aStyleName = maDrawStyleName;
633 uno::Reference< style::XStyle > xStyle;
635 XMLPropStyleContext* pDocStyle
636 = dynamic_cast<XMLShapeStyleContext*>(const_cast<SvXMLStyleContext*>(pStyle));
637 if (pDocStyle)
639 if( pDocStyle->GetStyle().is() )
641 xStyle = pDocStyle->GetStyle();
643 else
645 aStyleName = pDocStyle->GetParentName();
649 if( !xStyle.is() && !aStyleName.isEmpty() )
654 uno::Reference< style::XStyleFamiliesSupplier > xFamiliesSupplier( GetImport().GetModel(), uno::UNO_QUERY );
656 if( xFamiliesSupplier.is() )
658 uno::Reference< container::XNameAccess > xFamilies( xFamiliesSupplier->getStyleFamilies() );
659 if( xFamilies.is() )
662 uno::Reference< container::XNameAccess > xFamily;
664 if( XmlStyleFamily::SD_PRESENTATION_ID == mnStyleFamily )
666 aStyleName = GetImport().GetStyleDisplayName(
667 XmlStyleFamily::SD_PRESENTATION_ID,
668 aStyleName );
669 sal_Int32 nPos = aStyleName.lastIndexOf( '-' );
670 if( -1 != nPos )
672 OUString aFamily( aStyleName.copy( 0, nPos ) );
674 xFamilies->getByName( aFamily ) >>= xFamily;
675 aStyleName = aStyleName.copy( nPos + 1 );
678 else
680 // get graphics family
681 if (xFamilies->hasByName(u"graphics"_ustr))
682 xFamilies->getByName(u"graphics"_ustr) >>= xFamily;
683 else
684 xFamilies->getByName(u"GraphicStyles"_ustr) >>= xFamily;
686 aStyleName = GetImport().GetStyleDisplayName(
687 XmlStyleFamily::SD_GRAPHICS_ID,
688 aStyleName );
691 if( xFamily.is() )
692 xFamily->getByName( aStyleName ) >>= xStyle;
696 catch(const uno::Exception&)
698 DBG_UNHANDLED_EXCEPTION( "xmloff", "finding style for shape" );
702 if( bSupportsStyle && xStyle.is() )
706 // set style on object
707 xPropSet->setPropertyValue(u"Style"_ustr, Any(xStyle));
709 catch(const uno::Exception&)
711 DBG_UNHANDLED_EXCEPTION( "xmloff", "setting style for shape" );
715 // Writer shapes: if this one has a TextBox, set it here. We need to do it before
716 // pDocStyle->FillPropertySet, because setting some properties depend on the format
717 // having RES_CNTNT attribute (e.g., UNO_NAME_TEXT_(LEFT|RIGHT|UPPER|LOWER)DIST; see
718 // SwTextBoxHelper::syncProperty, which indirectly calls SwTextBoxHelper::isTextBox)
719 uno::Reference<beans::XPropertySetInfo> xPropertySetInfo
720 = xPropSet->getPropertySetInfo();
721 static constexpr OUString sTextBox = u"TextBox"_ustr;
722 if (xPropertySetInfo->hasPropertyByName(sTextBox))
723 xPropSet->setPropertyValue(sTextBox, uno::Any(mbTextBox));
725 // if this is an auto style, set its properties
726 if(bAutoStyle && pDocStyle)
728 // set PropertySet on object
729 pDocStyle->FillPropertySet(xPropSet);
732 } while(false);
734 // try to set text auto style
737 // set style on shape
738 if( maTextStyleName.isEmpty() )
739 break;
741 if( nullptr == GetImport().GetShapeImport()->GetAutoStylesContext())
742 break;
744 const SvXMLStyleContext* pTempStyle = GetImport().GetShapeImport()->GetAutoStylesContext()->FindStyleChildContext(XmlStyleFamily::TEXT_PARAGRAPH, maTextStyleName);
745 XMLPropStyleContext* pStyle = const_cast<XMLPropStyleContext*>(dynamic_cast<const XMLPropStyleContext*>( pTempStyle ) ); // use temp var, PTR_CAST is a bad macro, FindStyleChildContext will be called twice
746 if( pStyle == nullptr )
747 break;
749 // set PropertySet on object
750 pStyle->FillPropertySet(xPropSet);
752 } while(false);
754 catch(const uno::Exception&)
759 void SdXMLShapeContext::SetLayer()
761 if( maLayerName.isEmpty() )
762 return;
766 uno::Reference< beans::XPropertySet > xPropSet(mxShape, uno::UNO_QUERY);
767 if(xPropSet.is() )
769 xPropSet->setPropertyValue(u"LayerName"_ustr, Any(maLayerName));
770 return;
773 catch(const uno::Exception&)
778 void SdXMLShapeContext::SetThumbnail()
780 if( maThumbnailURL.isEmpty() )
781 return;
785 uno::Reference< beans::XPropertySet > xPropSet(mxShape, uno::UNO_QUERY);
786 if( !xPropSet.is() )
787 return;
789 uno::Reference< beans::XPropertySetInfo > xPropSetInfo( xPropSet->getPropertySetInfo() );
790 if( xPropSetInfo.is() && xPropSetInfo->hasPropertyByName( u"ThumbnailGraphic"_ustr ) )
792 // load the thumbnail graphic and export it to a wmf stream so we can set
793 // it at the api
795 uno::Reference<graphic::XGraphic> xGraphic = GetImport().loadGraphicByURL(maThumbnailURL);
796 xPropSet->setPropertyValue(u"ThumbnailGraphic"_ustr, uno::Any(xGraphic));
799 catch(const uno::Exception&)
804 // this is called from the parent group for each unparsed attribute in the attribute list
805 bool SdXMLShapeContext::processAttribute( const sax_fastparser::FastAttributeList::FastAttributeIter & aIter )
807 sal_Int32 nTmp;
808 switch (aIter.getToken())
810 case XML_ELEMENT(DRAW, XML_ZINDEX):
811 case XML_ELEMENT(DRAW_EXT, XML_ZINDEX):
812 mnZOrder = aIter.toInt32();
813 break;
814 case XML_ELEMENT(DRAW, XML_ID):
815 case XML_ELEMENT(DRAW_EXT, XML_ID):
816 if (!mbHaveXmlId) { maShapeId = aIter.toString(); }
817 break;
818 case XML_ELEMENT(DRAW, XML_NAME):
819 case XML_ELEMENT(DRAW_EXT, XML_NAME):
820 maShapeName = aIter.toString();
821 break;
822 case XML_ELEMENT(DRAW, XML_STYLE_NAME):
823 case XML_ELEMENT(DRAW_EXT, XML_STYLE_NAME):
824 maDrawStyleName = aIter.toString();
825 break;
826 case XML_ELEMENT(DRAW, XML_TEXT_STYLE_NAME):
827 case XML_ELEMENT(DRAW_EXT, XML_TEXT_STYLE_NAME):
828 maTextStyleName = aIter.toString();
829 break;
830 case XML_ELEMENT(DRAW, XML_LAYER):
831 case XML_ELEMENT(DRAW_EXT, XML_LAYER):
832 maLayerName = aIter.toString();
833 break;
834 case XML_ELEMENT(DRAW, XML_DISPLAY):
835 case XML_ELEMENT(DRAW_EXT, XML_DISPLAY):
836 mbVisible = IsXMLToken( aIter, XML_ALWAYS ) || IsXMLToken( aIter, XML_SCREEN );
837 mbPrintable = IsXMLToken( aIter, XML_ALWAYS ) || IsXMLToken( aIter, XML_PRINTER );
838 break;
839 case XML_ELEMENT(PRESENTATION, XML_USER_TRANSFORMED):
840 mbIsUserTransformed = IsXMLToken( aIter, XML_TRUE );
841 break;
842 case XML_ELEMENT(PRESENTATION, XML_PLACEHOLDER):
843 mbIsPlaceholder = IsXMLToken( aIter, XML_TRUE );
844 if( mbIsPlaceholder )
845 mbClearDefaultAttributes = false;
846 break;
847 case XML_ELEMENT(PRESENTATION, XML_CLASS):
848 maPresentationClass = aIter.toString();
849 break;
850 case XML_ELEMENT(PRESENTATION, XML_STYLE_NAME):
851 maDrawStyleName = aIter.toString();
852 mnStyleFamily = XmlStyleFamily::SD_PRESENTATION_ID;
853 break;
854 case XML_ELEMENT(SVG, XML_X):
855 case XML_ELEMENT(SVG_COMPAT, XML_X):
856 GetImport().GetMM100UnitConverter().convertMeasureToCore(
857 maPosition.X, aIter.toView());
858 break;
859 case XML_ELEMENT(SVG, XML_Y):
860 case XML_ELEMENT(SVG_COMPAT, XML_Y):
861 GetImport().GetMM100UnitConverter().convertMeasureToCore(
862 maPosition.Y, aIter.toView());
863 break;
864 case XML_ELEMENT(SVG, XML_WIDTH):
865 case XML_ELEMENT(SVG_COMPAT, XML_WIDTH):
866 GetImport().GetMM100UnitConverter().convertMeasureToCore(
867 maSize.Width, aIter.toView());
868 if (maSize.Width > 0)
869 maSize.Width = o3tl::saturating_add<sal_Int32>(maSize.Width, 1);
870 else if (maSize.Width < 0)
871 maSize.Width = o3tl::saturating_add<sal_Int32>(maSize.Width, -1);
872 break;
873 case XML_ELEMENT(SVG, XML_HEIGHT):
874 case XML_ELEMENT(SVG_COMPAT, XML_HEIGHT):
875 GetImport().GetMM100UnitConverter().convertMeasureToCore(
876 maSize.Height, aIter.toView());
877 if (maSize.Height > 0)
878 maSize.Height = o3tl::saturating_add<sal_Int32>(maSize.Height, 1);
879 else if (maSize.Height < 0)
880 maSize.Height = o3tl::saturating_add<sal_Int32>(maSize.Height, -1);
881 break;
882 case XML_ELEMENT(DRAW, XML_TRANSFORM):
883 case XML_ELEMENT(DRAW_EXT, XML_TRANSFORM):
884 case XML_ELEMENT(SVG, XML_TRANSFORM):
885 case XML_ELEMENT(SVG_COMPAT, XML_TRANSFORM):
886 // because of #85127# take svg:transform into account and handle like
887 // draw:transform for compatibility
888 mnTransform.SetString(aIter.toString(), GetImport().GetMM100UnitConverter());
889 break;
890 case XML_ELEMENT(STYLE, XML_REL_WIDTH):
891 if (sax::Converter::convertPercent(nTmp, aIter.toView()))
892 mnRelWidth = static_cast<sal_Int16>(nTmp);
893 break;
894 case XML_ELEMENT(STYLE, XML_REL_HEIGHT):
895 if (sax::Converter::convertPercent(nTmp, aIter.toView()))
896 mnRelHeight = static_cast<sal_Int16>(nTmp);
897 break;
898 case XML_ELEMENT(NONE, XML_ID):
899 case XML_ELEMENT(XML, XML_ID):
900 maShapeId = aIter.toString();
901 mbHaveXmlId = true;
902 break;
903 default:
904 return false;
906 return true;
909 bool SdXMLShapeContext::isPresentationShape() const
911 if( !maPresentationClass.isEmpty() && const_cast<SdXMLShapeContext*>(this)->GetImport().GetShapeImport()->IsPresentationShapesSupported() )
913 if(XmlStyleFamily::SD_PRESENTATION_ID == mnStyleFamily)
915 return true;
918 if( IsXMLToken( maPresentationClass, XML_HEADER ) || IsXMLToken( maPresentationClass, XML_FOOTER ) ||
919 IsXMLToken( maPresentationClass, XML_PAGE_NUMBER ) || IsXMLToken( maPresentationClass, XML_DATE_TIME ) )
921 return true;
925 return false;
928 SdXMLRectShapeContext::SdXMLRectShapeContext(
929 SvXMLImport& rImport,
930 const css::uno::Reference< css::xml::sax::XFastAttributeList>& xAttrList,
931 uno::Reference< drawing::XShapes > const & rShapes,
932 bool bTemporaryShape)
933 : SdXMLShapeContext( rImport, xAttrList, rShapes, bTemporaryShape ),
934 mnRadius( 0 )
938 SdXMLRectShapeContext::~SdXMLRectShapeContext()
942 // this is called from the parent group for each unparsed attribute in the attribute list
943 bool SdXMLRectShapeContext::processAttribute( const sax_fastparser::FastAttributeList::FastAttributeIter & aIter )
945 switch (aIter.getToken())
947 case XML_ELEMENT(DRAW, XML_CORNER_RADIUS):
948 GetImport().GetMM100UnitConverter().convertMeasureToCore(
949 mnRadius, aIter.toView());
950 break;
951 default:
952 return SdXMLShapeContext::processAttribute( aIter );
954 return true;
957 void SdXMLRectShapeContext::startFastElement (sal_Int32 nElement,
958 const css::uno::Reference< css::xml::sax::XFastAttributeList >& xAttrList)
960 // create rectangle shape
961 AddShape(u"com.sun.star.drawing.RectangleShape"_ustr);
962 if(!mxShape.is())
963 return;
965 // Add, set Style and properties from base shape
966 SetStyle();
967 SetLayer();
969 // set pos, size, shear and rotate
970 SetTransformation();
972 if(mnRadius)
974 uno::Reference< beans::XPropertySet > xPropSet(mxShape, uno::UNO_QUERY);
975 if(xPropSet.is())
979 xPropSet->setPropertyValue(u"CornerRadius"_ustr, uno::Any( mnRadius ) );
981 catch(const uno::Exception&)
983 DBG_UNHANDLED_EXCEPTION( "xmloff", "setting corner radius");
987 SdXMLShapeContext::startFastElement(nElement, xAttrList);
991 SdXMLLineShapeContext::SdXMLLineShapeContext(
992 SvXMLImport& rImport,
993 const css::uno::Reference< css::xml::sax::XFastAttributeList>& xAttrList,
994 uno::Reference< drawing::XShapes > const & rShapes,
995 bool bTemporaryShape)
996 : SdXMLShapeContext( rImport, xAttrList, rShapes, bTemporaryShape ),
997 mnX1( 0 ),
998 mnY1( 0 ),
999 mnX2( 1 ),
1000 mnY2( 1 )
1004 SdXMLLineShapeContext::~SdXMLLineShapeContext()
1008 // this is called from the parent group for each unparsed attribute in the attribute list
1009 bool SdXMLLineShapeContext::processAttribute( const sax_fastparser::FastAttributeList::FastAttributeIter & aIter )
1011 switch (aIter.getToken())
1013 case XML_ELEMENT(SVG, XML_X1):
1014 case XML_ELEMENT(SVG_COMPAT, XML_X1):
1015 GetImport().GetMM100UnitConverter().convertMeasureToCore(
1016 mnX1, aIter.toView());
1017 break;
1018 case XML_ELEMENT(SVG, XML_Y1):
1019 case XML_ELEMENT(SVG_COMPAT, XML_Y1):
1020 GetImport().GetMM100UnitConverter().convertMeasureToCore(
1021 mnY1, aIter.toView());
1022 break;
1023 case XML_ELEMENT(SVG, XML_X2):
1024 case XML_ELEMENT(SVG_COMPAT, XML_X2):
1025 GetImport().GetMM100UnitConverter().convertMeasureToCore(
1026 mnX2, aIter.toView());
1027 break;
1028 case XML_ELEMENT(SVG, XML_Y2):
1029 case XML_ELEMENT(SVG_COMPAT, XML_Y2):
1030 GetImport().GetMM100UnitConverter().convertMeasureToCore(
1031 mnY2, aIter.toView());
1032 break;
1033 default:
1034 return SdXMLShapeContext::processAttribute( aIter );
1036 return true;
1039 void SdXMLLineShapeContext::startFastElement (sal_Int32 nElement,
1040 const css::uno::Reference< css::xml::sax::XFastAttributeList >& xAttrList)
1042 // #85920# use SetTransformation() to handle import of simple lines.
1043 // This is necessary to take into account all anchor positions and
1044 // other things. All shape imports use the same import schemata now.
1045 // create necessary shape (Line Shape)
1046 AddShape(u"com.sun.star.drawing.PolyLineShape"_ustr);
1048 if(!mxShape.is())
1049 return;
1051 // Add, set Style and properties from base shape
1052 SetStyle();
1053 SetLayer();
1055 // get sizes and offsets
1056 awt::Point aTopLeft(mnX1, mnY1);
1057 awt::Point aBottomRight(mnX2, mnY2);
1059 if(mnX1 > mnX2)
1061 aTopLeft.X = mnX2;
1062 aBottomRight.X = mnX1;
1065 if(mnY1 > mnY2)
1067 aTopLeft.Y = mnY2;
1068 aBottomRight.Y = mnY1;
1071 // set local parameters on shape
1072 uno::Reference< beans::XPropertySet > xPropSet(mxShape, uno::UNO_QUERY);
1073 if(xPropSet.is())
1075 drawing::PointSequenceSequence aPolyPoly(1);
1076 drawing::PointSequence* pOuterSequence = aPolyPoly.getArray();
1077 pOuterSequence->realloc(2);
1078 awt::Point* pInnerSequence = pOuterSequence->getArray();
1080 *pInnerSequence = awt::Point(o3tl::saturating_sub(mnX1, aTopLeft.X), o3tl::saturating_sub(mnY1, aTopLeft.Y));
1081 pInnerSequence++;
1082 *pInnerSequence = awt::Point(o3tl::saturating_sub(mnX2, aTopLeft.X), o3tl::saturating_sub(mnY2, aTopLeft.Y));
1084 xPropSet->setPropertyValue(u"Geometry"_ustr, Any(aPolyPoly));
1087 // Size is included in point coordinates
1088 maSize.Width = 1;
1089 maSize.Height = 1;
1090 maPosition.X = aTopLeft.X;
1091 maPosition.Y = aTopLeft.Y;
1093 // set pos, size, shear and rotate and get copy of matrix
1094 SetTransformation();
1096 SdXMLShapeContext::startFastElement(nElement, xAttrList);
1100 SdXMLEllipseShapeContext::SdXMLEllipseShapeContext(
1101 SvXMLImport& rImport,
1102 const css::uno::Reference< css::xml::sax::XFastAttributeList>& xAttrList,
1103 uno::Reference< drawing::XShapes > const & rShapes,
1104 bool bTemporaryShape)
1105 : SdXMLShapeContext( rImport, xAttrList, rShapes, bTemporaryShape ),
1106 mnCX( 0 ),
1107 mnCY( 0 ),
1108 mnRX( 1 ),
1109 mnRY( 1 ),
1110 meKind( drawing::CircleKind_FULL ),
1111 mnStartAngle( 0 ),
1112 mnEndAngle( 0 )
1116 SdXMLEllipseShapeContext::~SdXMLEllipseShapeContext()
1120 // this is called from the parent group for each unparsed attribute in the attribute list
1121 bool SdXMLEllipseShapeContext::processAttribute( const sax_fastparser::FastAttributeList::FastAttributeIter & aIter )
1123 switch (aIter.getToken())
1125 case XML_ELEMENT(SVG, XML_RX):
1126 case XML_ELEMENT(SVG_COMPAT, XML_RX):
1127 GetImport().GetMM100UnitConverter().convertMeasureToCore(
1128 mnRX, aIter.toView());
1129 break;
1130 case XML_ELEMENT(SVG, XML_RY):
1131 case XML_ELEMENT(SVG_COMPAT, XML_RY):
1132 GetImport().GetMM100UnitConverter().convertMeasureToCore(
1133 mnRY, aIter.toView());
1134 break;
1135 case XML_ELEMENT(SVG, XML_CX):
1136 case XML_ELEMENT(SVG_COMPAT, XML_CX):
1137 GetImport().GetMM100UnitConverter().convertMeasureToCore(
1138 mnCX, aIter.toView());
1139 break;
1140 case XML_ELEMENT(SVG, XML_CY):
1141 case XML_ELEMENT(SVG_COMPAT, XML_CY):
1142 GetImport().GetMM100UnitConverter().convertMeasureToCore(
1143 mnCY, aIter.toView());
1144 break;
1145 case XML_ELEMENT(SVG, XML_R):
1146 case XML_ELEMENT(SVG_COMPAT, XML_R):
1147 // single radius, it's a circle and both radii are the same
1148 GetImport().GetMM100UnitConverter().convertMeasureToCore(
1149 mnRX, aIter.toView());
1150 mnRY = mnRX;
1151 break;
1152 case XML_ELEMENT(DRAW, XML_KIND):
1153 SvXMLUnitConverter::convertEnum( meKind, aIter.toView(), aXML_CircleKind_EnumMap );
1154 break;
1155 case XML_ELEMENT(DRAW, XML_START_ANGLE):
1157 double dStartAngle;
1158 if (::sax::Converter::convertAngle( dStartAngle, aIter.toView()))
1159 mnStartAngle = static_cast<sal_Int32>(basegfx::fround(dStartAngle * 100));
1160 break;
1162 case XML_ELEMENT(DRAW, XML_END_ANGLE):
1164 double dEndAngle;
1165 if (::sax::Converter::convertAngle( dEndAngle, aIter.toView()))
1166 mnEndAngle = static_cast<sal_Int32>(basegfx::fround(dEndAngle * 100));
1167 break;
1169 default:
1170 return SdXMLShapeContext::processAttribute( aIter );
1172 return true;
1175 void SdXMLEllipseShapeContext::startFastElement (sal_Int32 nElement,
1176 const css::uno::Reference< css::xml::sax::XFastAttributeList >& xAttrList)
1178 // create rectangle shape
1179 AddShape(u"com.sun.star.drawing.EllipseShape"_ustr);
1180 if(!mxShape.is())
1181 return;
1183 // Add, set Style and properties from base shape
1184 SetStyle();
1185 SetLayer();
1187 if(mnCX != 0 || mnCY != 0 || mnRX != 1 || mnRY != 1)
1189 // #i121972# center/radius is used, put to pos and size
1190 maSize.Width = 2 * mnRX;
1191 maSize.Height = 2 * mnRY;
1192 maPosition.X = mnCX - mnRX;
1193 maPosition.Y = mnCY - mnRY;
1195 // set pos, size, shear and rotate
1196 SetTransformation();
1198 if( meKind != drawing::CircleKind_FULL )
1200 uno::Reference< beans::XPropertySet > xPropSet( mxShape, uno::UNO_QUERY );
1201 if( xPropSet.is() )
1203 // calculate the correct start and end angle
1204 sal_Int32 mnOldStartAngle = mnStartAngle;
1205 sal_Int32 mnOldEndAngle = mnEndAngle;
1206 basegfx::B2DTuple aScale;
1207 basegfx::B2DTuple aTranslate;
1208 double fRotate;
1209 double fShearX;
1210 maUsedTransformation.decompose(aScale, aTranslate, fRotate, fShearX);
1211 if (aScale.getX() < 0 || aScale.getY() < 0)
1213 // The angle for a horizontal flip is the same as the angle for a
1214 // vertical flip because a vertical flip is treated as a horizontal
1215 // flip plus a rotation.
1217 // To perform the flip, the start and end angle are switched and we
1218 // use the fact performing a horizontal flip on a shape will change
1219 // the angle that a radius makes with the origin to 180 degrees
1220 // minus that angle (we use 54000 hundredths of a degree to get the
1221 // modulus operation to give a value between 0 and 36000).
1223 mnStartAngle = (54000 - mnOldEndAngle) % 36000;
1224 mnEndAngle = (54000 - mnOldStartAngle) % 36000;
1227 xPropSet->setPropertyValue(u"CircleKind"_ustr, Any( meKind) );
1228 xPropSet->setPropertyValue(u"CircleStartAngle"_ustr, Any(mnStartAngle) );
1229 xPropSet->setPropertyValue(u"CircleEndAngle"_ustr, Any(mnEndAngle) );
1233 SdXMLShapeContext::startFastElement(nElement, xAttrList);
1237 SdXMLPolygonShapeContext::SdXMLPolygonShapeContext(
1238 SvXMLImport& rImport,
1239 const css::uno::Reference< css::xml::sax::XFastAttributeList>& xAttrList,
1240 uno::Reference< drawing::XShapes > const & rShapes, bool bClosed, bool bTemporaryShape)
1241 : SdXMLShapeContext( rImport, xAttrList, rShapes, bTemporaryShape ),
1242 mbClosed( bClosed )
1246 // this is called from the parent group for each unparsed attribute in the attribute list
1247 bool SdXMLPolygonShapeContext::processAttribute( const sax_fastparser::FastAttributeList::FastAttributeIter & aIter )
1249 switch (aIter.getToken())
1251 case XML_ELEMENT(SVG, XML_VIEWBOX):
1252 case XML_ELEMENT(SVG_COMPAT, XML_VIEWBOX):
1253 maViewBox = aIter.toString();
1254 break;
1255 case XML_ELEMENT(DRAW, XML_POINTS):
1256 maPoints = aIter.toString();
1257 break;
1258 default:
1259 return SdXMLShapeContext::processAttribute( aIter);
1261 return true;
1264 SdXMLPolygonShapeContext::~SdXMLPolygonShapeContext()
1268 void SdXMLPolygonShapeContext::startFastElement (sal_Int32 nElement,
1269 const css::uno::Reference< css::xml::sax::XFastAttributeList >& xAttrList)
1271 // Add, set Style and properties from base shape
1272 if(mbClosed)
1273 AddShape(u"com.sun.star.drawing.PolyPolygonShape"_ustr);
1274 else
1275 AddShape(u"com.sun.star.drawing.PolyLineShape"_ustr);
1277 if( !mxShape.is() )
1278 return;
1280 SetStyle();
1281 SetLayer();
1283 // set local parameters on shape
1284 uno::Reference< beans::XPropertySet > xPropSet(mxShape, uno::UNO_QUERY);
1285 if(xPropSet.is())
1287 // set polygon
1288 if(!maPoints.isEmpty() && !maViewBox.isEmpty())
1290 const SdXMLImExViewBox aViewBox(maViewBox, GetImport().GetMM100UnitConverter());
1291 basegfx::B2DVector aSize(aViewBox.GetWidth(), aViewBox.GetHeight());
1293 // Is this correct? It overrides ViewBox stuff; OTOH it makes no
1294 // sense to have the geometry content size different from object size
1295 if(maSize.Width != 0 && maSize.Height != 0)
1297 aSize = basegfx::B2DVector(maSize.Width, maSize.Height);
1300 basegfx::B2DPolygon aPolygon;
1302 if(basegfx::utils::importFromSvgPoints(aPolygon, maPoints))
1304 if(aPolygon.count())
1306 const basegfx::B2DRange aSourceRange(
1307 aViewBox.GetX(), aViewBox.GetY(),
1308 aViewBox.GetX() + aViewBox.GetWidth(), aViewBox.GetY() + aViewBox.GetHeight());
1309 const basegfx::B2DRange aTargetRange(
1310 aViewBox.GetX(), aViewBox.GetY(),
1311 aViewBox.GetX() + aSize.getX(), aViewBox.GetY() + aSize.getY());
1313 if(!aSourceRange.equal(aTargetRange))
1315 aPolygon.transform(
1316 basegfx::utils::createSourceRangeTargetRangeTransform(
1317 aSourceRange,
1318 aTargetRange));
1321 css::drawing::PointSequenceSequence aPointSequenceSequence;
1322 basegfx::utils::B2DPolyPolygonToUnoPointSequenceSequence(basegfx::B2DPolyPolygon(aPolygon), aPointSequenceSequence);
1323 xPropSet->setPropertyValue(u"Geometry"_ustr, Any(aPointSequenceSequence));
1324 // Size is now contained in the point coordinates, adapt maSize for
1325 // to use the correct transformation matrix in SetTransformation()
1326 maSize.Width = 1;
1327 maSize.Height = 1;
1333 // set pos, size, shear and rotate and get copy of matrix
1334 SetTransformation();
1336 SdXMLShapeContext::startFastElement(nElement, xAttrList);
1340 SdXMLPathShapeContext::SdXMLPathShapeContext(
1341 SvXMLImport& rImport,
1342 const css::uno::Reference< css::xml::sax::XFastAttributeList>& xAttrList,
1343 uno::Reference< drawing::XShapes > const & rShapes,
1344 bool bTemporaryShape)
1345 : SdXMLShapeContext( rImport, xAttrList, rShapes, bTemporaryShape )
1349 SdXMLPathShapeContext::~SdXMLPathShapeContext()
1353 // this is called from the parent group for each unparsed attribute in the attribute list
1354 bool SdXMLPathShapeContext::processAttribute( const sax_fastparser::FastAttributeList::FastAttributeIter & aIter )
1356 switch (aIter.getToken())
1358 case XML_ELEMENT(SVG, XML_VIEWBOX):
1359 case XML_ELEMENT(SVG_COMPAT, XML_VIEWBOX):
1360 maViewBox = aIter.toString();
1361 break;
1362 case XML_ELEMENT(SVG, XML_D):
1363 case XML_ELEMENT(SVG_COMPAT, XML_D):
1364 maD = aIter.toString();
1365 break;
1366 default:
1367 return SdXMLShapeContext::processAttribute( aIter );
1369 return true;
1372 void SdXMLPathShapeContext::startFastElement (sal_Int32 nElement,
1373 const css::uno::Reference< css::xml::sax::XFastAttributeList >& xAttrList)
1375 // create polygon shape
1376 if(maD.isEmpty())
1377 return;
1379 const SdXMLImExViewBox aViewBox(maViewBox, GetImport().GetMM100UnitConverter());
1380 basegfx::B2DVector aSize(aViewBox.GetWidth(), aViewBox.GetHeight());
1382 // Is this correct? It overrides ViewBox stuff; OTOH it makes no
1383 // sense to have the geometry content size different from object size
1384 if(maSize.Width != 0 && maSize.Height != 0)
1386 aSize = basegfx::B2DVector(maSize.Width, maSize.Height);
1389 basegfx::B2DPolyPolygon aPolyPolygon;
1391 if(!basegfx::utils::importFromSvgD(aPolyPolygon, maD, GetImport().needFixPositionAfterZ(), nullptr))
1392 return;
1394 if(!aPolyPolygon.count())
1395 return;
1397 const basegfx::B2DRange aSourceRange(
1398 aViewBox.GetX(), aViewBox.GetY(),
1399 aViewBox.GetX() + aViewBox.GetWidth(), aViewBox.GetY() + aViewBox.GetHeight());
1400 const basegfx::B2DRange aTargetRange(
1401 aViewBox.GetX(), aViewBox.GetY(),
1402 aViewBox.GetX() + aSize.getX(), aViewBox.GetY() + aSize.getY());
1404 if(!aSourceRange.equal(aTargetRange))
1406 aPolyPolygon.transform(
1407 basegfx::utils::createSourceRangeTargetRangeTransform(
1408 aSourceRange,
1409 aTargetRange));
1412 // create shape
1413 OUString service;
1415 if(aPolyPolygon.areControlPointsUsed())
1417 if(aPolyPolygon.isClosed())
1419 service = "com.sun.star.drawing.ClosedBezierShape";
1421 else
1423 service = "com.sun.star.drawing.OpenBezierShape";
1426 else
1428 if(aPolyPolygon.isClosed())
1430 service = "com.sun.star.drawing.PolyPolygonShape";
1432 else
1434 service = "com.sun.star.drawing.PolyLineShape";
1438 // Add, set Style and properties from base shape
1439 AddShape(service);
1441 // #89344# test for mxShape.is() and not for mxShapes.is() to support
1442 // shape import helper classes WITHOUT XShapes (member mxShapes). This
1443 // is used by the writer.
1444 if( !mxShape.is() )
1445 return;
1447 SetStyle();
1448 SetLayer();
1450 // set local parameters on shape
1451 uno::Reference< beans::XPropertySet > xPropSet(mxShape, uno::UNO_QUERY);
1453 if(xPropSet.is())
1455 uno::Any aAny;
1457 // set polygon data
1458 if(aPolyPolygon.areControlPointsUsed())
1460 drawing::PolyPolygonBezierCoords aSourcePolyPolygon;
1462 basegfx::utils::B2DPolyPolygonToUnoPolyPolygonBezierCoords(
1463 aPolyPolygon,
1464 aSourcePolyPolygon);
1465 aAny <<= aSourcePolyPolygon;
1467 else
1469 drawing::PointSequenceSequence aSourcePolyPolygon;
1471 basegfx::utils::B2DPolyPolygonToUnoPointSequenceSequence(
1472 aPolyPolygon,
1473 aSourcePolyPolygon);
1474 aAny <<= aSourcePolyPolygon;
1477 xPropSet->setPropertyValue(u"Geometry"_ustr, aAny);
1478 // Size is now contained in the point coordinates, adapt maSize for
1479 // to use the correct transformation matrix in SetTransformation()
1480 maSize.Width = 1;
1481 maSize.Height = 1;
1484 // set pos, size, shear and rotate
1485 SetTransformation();
1487 SdXMLShapeContext::startFastElement(nElement, xAttrList);
1491 SdXMLTextBoxShapeContext::SdXMLTextBoxShapeContext(
1492 SvXMLImport& rImport,
1493 const css::uno::Reference< css::xml::sax::XFastAttributeList>& xAttrList,
1494 uno::Reference< drawing::XShapes > const & rShapes)
1495 : SdXMLShapeContext( rImport, xAttrList, rShapes, false/*bTemporaryShape*/ ),
1496 mnRadius(0),
1497 maChainNextName(u""_ustr)
1501 SdXMLTextBoxShapeContext::~SdXMLTextBoxShapeContext()
1505 // this is called from the parent group for each unparsed attribute in the attribute list
1506 bool SdXMLTextBoxShapeContext::processAttribute( const sax_fastparser::FastAttributeList::FastAttributeIter & aIter )
1508 switch (aIter.getToken())
1510 case XML_ELEMENT(DRAW, XML_CORNER_RADIUS):
1511 GetImport().GetMM100UnitConverter().convertMeasureToCore(
1512 mnRadius, aIter.toView());
1513 break;
1514 case XML_ELEMENT(DRAW, XML_CHAIN_NEXT_NAME):
1515 maChainNextName = aIter.toString();
1516 break;
1517 default:
1518 return SdXMLShapeContext::processAttribute( aIter );
1520 return true;
1523 void SdXMLTextBoxShapeContext::startFastElement (sal_Int32 nElement,
1524 const css::uno::Reference< css::xml::sax::XFastAttributeList >& xAttrList)
1526 // create textbox shape
1527 bool bIsPresShape = false;
1528 bool bClearText = false;
1530 OUString service;
1532 if( isPresentationShape() )
1534 // check if the current document supports presentation shapes
1535 if( GetImport().GetShapeImport()->IsPresentationShapesSupported() )
1537 if( IsXMLToken( maPresentationClass, XML_SUBTITLE ))
1539 // XmlShapeType::PresSubtitleShape
1540 service = "com.sun.star.presentation.SubtitleShape";
1542 else if( IsXMLToken( maPresentationClass, XML_PRESENTATION_OUTLINE ) )
1544 // XmlShapeType::PresOutlinerShape
1545 service = "com.sun.star.presentation.OutlinerShape";
1547 else if( IsXMLToken( maPresentationClass, XML_NOTES ) )
1549 // XmlShapeType::PresNotesShape
1550 service = "com.sun.star.presentation.NotesShape";
1552 else if( IsXMLToken( maPresentationClass, XML_HEADER ) )
1554 // XmlShapeType::PresHeaderShape
1555 service = "com.sun.star.presentation.HeaderShape";
1556 bClearText = true;
1558 else if( IsXMLToken( maPresentationClass, XML_FOOTER ) )
1560 // XmlShapeType::PresFooterShape
1561 service = "com.sun.star.presentation.FooterShape";
1562 bClearText = true;
1564 else if( IsXMLToken( maPresentationClass, XML_PAGE_NUMBER ) )
1566 // XmlShapeType::PresSlideNumberShape
1567 service = "com.sun.star.presentation.SlideNumberShape";
1568 bClearText = true;
1570 else if( IsXMLToken( maPresentationClass, XML_DATE_TIME ) )
1572 // XmlShapeType::PresDateTimeShape
1573 service = "com.sun.star.presentation.DateTimeShape";
1574 bClearText = true;
1576 else // IsXMLToken( maPresentationClass, XML_TITLE ) )
1578 // XmlShapeType::PresTitleTextShape
1579 service = "com.sun.star.presentation.TitleTextShape";
1581 bIsPresShape = true;
1585 if( service.isEmpty() )
1587 // normal text shape
1588 service = "com.sun.star.drawing.TextShape";
1591 // Add, set Style and properties from base shape
1592 AddShape(service);
1594 if( !mxShape.is() )
1595 return;
1597 SetStyle();
1598 SetLayer();
1600 if(bIsPresShape)
1602 uno::Reference< beans::XPropertySet > xProps(mxShape, uno::UNO_QUERY);
1603 if(xProps.is())
1605 uno::Reference< beans::XPropertySetInfo > xPropsInfo( xProps->getPropertySetInfo() );
1606 if( xPropsInfo.is() )
1608 if( !mbIsPlaceholder && xPropsInfo->hasPropertyByName(u"IsEmptyPresentationObject"_ustr))
1609 xProps->setPropertyValue(u"IsEmptyPresentationObject"_ustr, css::uno::Any(false) );
1611 if( mbIsUserTransformed && xPropsInfo->hasPropertyByName(u"IsPlaceholderDependent"_ustr))
1612 xProps->setPropertyValue(u"IsPlaceholderDependent"_ustr, css::uno::Any(false) );
1617 if( bClearText )
1619 uno::Reference< text::XText > xText( mxShape, uno::UNO_QUERY );
1620 xText->setString( u""_ustr );
1623 // set parameters on shape
1624 //A AW->CL: Eventually You need to strip scale and translate from the transformation
1625 //A to reach the same goal again.
1626 //A if(!bIsPresShape || mbIsUserTransformed)
1627 //A {
1628 //A // set pos and size on shape, this should remove binding
1629 //A // to presentation object on masterpage
1630 //A SetSizeAndPosition();
1631 //A }
1633 // set pos, size, shear and rotate
1634 SetTransformation();
1636 if(mnRadius)
1638 uno::Reference< beans::XPropertySet > xPropSet(mxShape, uno::UNO_QUERY);
1639 if(xPropSet.is())
1643 xPropSet->setPropertyValue(u"CornerRadius"_ustr, uno::Any( mnRadius ) );
1645 catch(const uno::Exception&)
1647 DBG_UNHANDLED_EXCEPTION( "xmloff", "setting corner radius");
1652 if(!maChainNextName.isEmpty())
1654 uno::Reference< beans::XPropertySet > xPropSet(mxShape, uno::UNO_QUERY);
1655 if(xPropSet.is())
1659 xPropSet->setPropertyValue(u"TextChainNextName"_ustr,
1660 uno::Any( maChainNextName ) );
1662 catch(const uno::Exception&)
1664 DBG_UNHANDLED_EXCEPTION( "xmloff", "setting name of next chain link");
1669 SdXMLShapeContext::startFastElement(nElement, xAttrList);
1673 SdXMLControlShapeContext::SdXMLControlShapeContext(
1674 SvXMLImport& rImport,
1675 const css::uno::Reference< css::xml::sax::XFastAttributeList>& xAttrList,
1676 uno::Reference< drawing::XShapes > const & rShapes,
1677 bool bTemporaryShape)
1678 : SdXMLShapeContext( rImport, xAttrList, rShapes, bTemporaryShape )
1682 SdXMLControlShapeContext::~SdXMLControlShapeContext()
1686 // this is called from the parent group for each unparsed attribute in the attribute list
1687 bool SdXMLControlShapeContext::processAttribute( const sax_fastparser::FastAttributeList::FastAttributeIter & aIter )
1689 switch (aIter.getToken())
1691 case XML_ELEMENT(DRAW, XML_CONTROL):
1692 maFormId = aIter.toString();
1693 break;
1694 default:
1695 return SdXMLShapeContext::processAttribute( aIter );
1697 return true;
1700 void SdXMLControlShapeContext::startFastElement (sal_Int32 nElement,
1701 const css::uno::Reference< css::xml::sax::XFastAttributeList >& xAttrList)
1703 // create Control shape
1704 // add, set style and properties from base shape
1705 AddShape(u"com.sun.star.drawing.ControlShape"_ustr);
1706 if( !mxShape.is() )
1707 return;
1709 SAL_WARN_IF( !!maFormId.isEmpty(), "xmloff", "draw:control without a form:id attribute!" );
1710 if( !maFormId.isEmpty() )
1712 if( GetImport().IsFormsSupported() )
1714 uno::Reference< awt::XControlModel > xControlModel( GetImport().GetFormImport()->lookupControl( maFormId ), uno::UNO_QUERY );
1715 if( xControlModel.is() )
1717 uno::Reference< drawing::XControlShape > xControl( mxShape, uno::UNO_QUERY );
1718 if( xControl.is() )
1719 xControl->setControl( xControlModel );
1725 SetStyle();
1726 SetLayer();
1728 // set pos, size, shear and rotate
1729 SetTransformation();
1731 SdXMLShapeContext::startFastElement(nElement, xAttrList);
1735 SdXMLConnectorShapeContext::SdXMLConnectorShapeContext(
1736 SvXMLImport& rImport,
1737 const css::uno::Reference< css::xml::sax::XFastAttributeList>& xAttrList,
1738 uno::Reference< drawing::XShapes > const & rShapes,
1739 bool bTemporaryShape)
1740 : SdXMLShapeContext( rImport, xAttrList, rShapes, bTemporaryShape ),
1741 maStart(0,0),
1742 maEnd(1,1),
1743 mnType( drawing::ConnectorType_STANDARD ),
1744 mnStartGlueId(-1),
1745 mnEndGlueId(-1),
1746 mnDelta1(0),
1747 mnDelta2(0),
1748 mnDelta3(0),
1749 mbLikelyOOXMLCurve(true)
1753 SdXMLConnectorShapeContext::~SdXMLConnectorShapeContext()
1757 bool SvXMLImport::needFixPositionAfterZ() const
1759 bool bWrongPositionAfterZ( false );
1760 sal_Int32 nUPD( 0 );
1761 sal_Int32 nBuildId( 0 );
1762 if ( getBuildIds( nUPD, nBuildId ) && // test OOo and old versions of LibO and AOO
1763 ( ( ( nUPD == 641 ) || ( nUPD == 645 ) || ( nUPD == 680 ) || ( nUPD == 300 ) ||
1764 ( nUPD == 310 ) || ( nUPD == 320 ) || ( nUPD == 330 ) || ( nUPD == 340 ) ||
1765 ( nUPD == 350 && nBuildId < 202 ) )
1766 || (getGeneratorVersion() == SvXMLImport::AOO_40x))) // test if AOO 4.0.x
1767 // apparently bug was fixed in AOO by i#123433 f15874d8f976f3874bdbcb53429eeefa65c28841
1769 bWrongPositionAfterZ = true;
1771 return bWrongPositionAfterZ;
1774 namespace
1776 bool lcl_IsLikelyOOXMLCurve(const basegfx::B2DPolygon& rPolygon)
1778 sal_uInt32 nCount = rPolygon.count();
1779 if (!rPolygon.areControlPointsUsed() or nCount < 2)
1780 return false; // no curve at all
1782 basegfx::B2DVector aStartVec(rPolygon.getNextControlPoint(0) - rPolygon.getB2DPoint(0));
1783 basegfx::B2DVector aEndVec(rPolygon.getPrevControlPoint(nCount-1) - rPolygon.getB2DPoint(nCount - 1));
1784 // LibreOffice uses one point less than OOXML for the same underlying bentConnector or
1785 // STANDARD connector, respectively. A deeper inspection is only needed in case of 2 resulting
1786 // points. Those connector paths look like a quarter ellipse.
1787 switch (nCount)
1789 case 2:
1791 // In case start and end direction are parallel, it cannot be OOXML because that case
1792 // introduces a handle on the path and the curve has three points then.
1793 if (basegfx::areParallel(aStartVec, aEndVec))
1794 return false;
1795 // OOXML sets the control point at 1/2, LibreOffice at 2/3 of width or height.
1796 // A tolerance is used because +-1 deviations due to integer arithmetic in many places.
1797 basegfx::B2DRange aRect(rPolygon.getB2DPoint(0), rPolygon.getB2DPoint(1));
1798 if ((basegfx::fTools::equalZero(aStartVec.getX())
1799 && basegfx::fTools::equal(aStartVec.getLength() * 2.0, aRect.getHeight(), 2.0))
1800 || (basegfx::fTools::equalZero(aStartVec.getY())
1801 && basegfx::fTools::equal(aStartVec.getLength() * 2.0, aRect.getWidth(), 2.0)))
1802 return true;
1804 break;
1805 case 3:
1806 case 5:
1807 return basegfx::areParallel(aStartVec, aEndVec);
1808 break;
1809 case 4: // start and end direction are orthogonal
1810 return basegfx::fTools::equalZero(aStartVec.scalar( aEndVec));
1811 break;
1812 default:
1813 return false;
1815 return false;
1817 } // end namespace
1819 // this is called from the parent group for each unparsed attribute in the attribute list
1820 bool SdXMLConnectorShapeContext::processAttribute( const sax_fastparser::FastAttributeList::FastAttributeIter & aIter )
1822 switch( aIter.getToken() )
1824 case XML_ELEMENT(DRAW, XML_START_SHAPE):
1825 maStartShapeId = aIter.toString();
1826 break;
1827 case XML_ELEMENT(DRAW, XML_START_GLUE_POINT):
1828 mnStartGlueId = aIter.toInt32();
1829 break;
1830 case XML_ELEMENT(DRAW, XML_END_SHAPE):
1831 maEndShapeId = aIter.toString();
1832 break;
1833 case XML_ELEMENT(DRAW, XML_END_GLUE_POINT):
1834 mnEndGlueId = aIter.toInt32();
1835 break;
1836 case XML_ELEMENT(DRAW, XML_LINE_SKEW):
1838 OUString sValue = aIter.toString();
1839 SvXMLTokenEnumerator aTokenEnum( sValue );
1840 std::u16string_view aToken;
1841 if( aTokenEnum.getNextToken( aToken ) )
1843 GetImport().GetMM100UnitConverter().convertMeasureToCore(
1844 mnDelta1, aToken);
1845 if( aTokenEnum.getNextToken( aToken ) )
1847 GetImport().GetMM100UnitConverter().convertMeasureToCore(
1848 mnDelta2, aToken);
1849 if( aTokenEnum.getNextToken( aToken ) )
1851 GetImport().GetMM100UnitConverter().convertMeasureToCore(
1852 mnDelta3, aToken);
1856 break;
1858 case XML_ELEMENT(DRAW, XML_TYPE):
1860 (void)SvXMLUnitConverter::convertEnum( mnType, aIter.toView(), aXML_ConnectionKind_EnumMap );
1861 break;
1863 // #121965# draw:transform may be used in ODF1.2, e.g. exports from MS seem to use these
1864 case XML_ELEMENT(DRAW, XML_TRANSFORM):
1865 mnTransform.SetString(aIter.toString(), GetImport().GetMM100UnitConverter());
1866 break;
1868 case XML_ELEMENT(SVG, XML_X1):
1869 case XML_ELEMENT(SVG_COMPAT, XML_X1):
1870 GetImport().GetMM100UnitConverter().convertMeasureToCore(
1871 maStart.X, aIter.toView());
1872 break;
1873 case XML_ELEMENT(SVG, XML_Y1):
1874 case XML_ELEMENT(SVG_COMPAT, XML_Y1):
1875 GetImport().GetMM100UnitConverter().convertMeasureToCore(
1876 maStart.Y, aIter.toView());
1877 break;
1878 case XML_ELEMENT(SVG, XML_X2):
1879 case XML_ELEMENT(SVG_COMPAT, XML_X2):
1880 GetImport().GetMM100UnitConverter().convertMeasureToCore(
1881 maEnd.X, aIter.toView());
1882 break;
1883 case XML_ELEMENT(SVG, XML_Y2):
1884 case XML_ELEMENT(SVG_COMPAT, XML_Y2):
1885 GetImport().GetMM100UnitConverter().convertMeasureToCore(
1886 maEnd.Y, aIter.toView());
1887 break;
1888 case XML_ELEMENT(SVG, XML_D):
1889 case XML_ELEMENT(SVG_COMPAT, XML_D):
1891 basegfx::B2DPolyPolygon aPolyPolygon;
1893 if(basegfx::utils::importFromSvgD(aPolyPolygon, aIter.toString(), GetImport().needFixPositionAfterZ(), nullptr))
1895 if(aPolyPolygon.count())
1897 drawing::PolyPolygonBezierCoords aSourcePolyPolygon;
1899 basegfx::utils::B2DPolyPolygonToUnoPolyPolygonBezierCoords(
1900 aPolyPolygon,
1901 aSourcePolyPolygon);
1902 maPath <<= aSourcePolyPolygon;
1904 mbLikelyOOXMLCurve = lcl_IsLikelyOOXMLCurve(aPolyPolygon.getB2DPolygon(0));
1907 break;
1909 default:
1910 return SdXMLShapeContext::processAttribute( aIter );
1912 return true;
1915 void SdXMLConnectorShapeContext::startFastElement (sal_Int32 nElement,
1916 const css::uno::Reference< css::xml::sax::XFastAttributeList >& xAttrList)
1918 // For security reasons, do not add empty connectors. There may have been an error in EA2
1919 // that created empty, far set off connectors (e.g. 63 meters below top of document). This
1920 // is not guaranteed, but it's definitely safe to not add empty connectors.
1921 bool bDoAdd(true);
1923 if( maStartShapeId.isEmpty()
1924 && maEndShapeId.isEmpty()
1925 && maStart.X == maEnd.X
1926 && maStart.Y == maEnd.Y
1927 && 0 == mnDelta1
1928 && 0 == mnDelta2
1929 && 0 == mnDelta3
1932 bDoAdd = false;
1935 if(!bDoAdd)
1936 return;
1938 // create Connector shape
1939 // add, set style and properties from base shape
1940 AddShape(u"com.sun.star.drawing.ConnectorShape"_ustr);
1941 if(!mxShape.is())
1942 return;
1944 // #121965# if draw:transform is used, apply directly to the start
1945 // and end positions before using these
1946 if(mnTransform.NeedsAction())
1948 // transformation is used, apply to object.
1949 ::basegfx::B2DHomMatrix aMat;
1950 mnTransform.GetFullTransform(aMat);
1952 if(!aMat.isIdentity())
1954 basegfx::B2DPoint aStart(maStart.X, maStart.Y);
1955 basegfx::B2DPoint aEnd(maEnd.X, maEnd.Y);
1957 aStart = aMat * aStart;
1958 aEnd = aMat * aEnd;
1960 maStart.X = basegfx::fround(aStart.getX());
1961 maStart.Y = basegfx::fround(aStart.getY());
1962 maEnd.X = basegfx::fround(aEnd.getX());
1963 maEnd.Y = basegfx::fround(aEnd.getY());
1967 uno::Reference< beans::XPropertySet > xProps( mxShape, uno::UNO_QUERY );
1968 if (xProps.is())
1969 xProps->setPropertyValue(u"EdgeOOXMLCurve"_ustr, Any(mbLikelyOOXMLCurve));
1971 // add connection ids
1972 if( !maStartShapeId.isEmpty() )
1973 GetImport().GetShapeImport()->addShapeConnection( mxShape, true, maStartShapeId, mnStartGlueId );
1974 if( !maEndShapeId.isEmpty() )
1975 GetImport().GetShapeImport()->addShapeConnection( mxShape, false, maEndShapeId, mnEndGlueId );
1977 if( xProps.is() )
1979 xProps->setPropertyValue(u"StartPosition"_ustr, Any(maStart));
1980 xProps->setPropertyValue(u"EndPosition"_ustr, Any(maEnd) );
1981 xProps->setPropertyValue(u"EdgeKind"_ustr, Any(mnType) );
1982 xProps->setPropertyValue(u"EdgeLine1Delta"_ustr, Any(mnDelta1) );
1983 xProps->setPropertyValue(u"EdgeLine2Delta"_ustr, Any(mnDelta2) );
1984 xProps->setPropertyValue(u"EdgeLine3Delta"_ustr, Any(mnDelta3) );
1986 SetStyle();
1987 SetLayer();
1989 if ( maPath.hasValue() )
1991 // #i115492#
1992 // Ignore svg:d attribute for text documents created by OpenOffice.org
1993 // versions before OOo 3.3, because these OOo versions are storing
1994 // svg:d values not using the correct unit.
1995 bool bApplySVGD( true );
1996 if ( uno::Reference< text::XTextDocument >(GetImport().GetModel(), uno::UNO_QUERY).is() )
1998 sal_Int32 nUPD( 0 );
1999 sal_Int32 nBuild( 0 );
2000 const bool bBuildIdFound = GetImport().getBuildIds( nUPD, nBuild );
2001 if ( GetImport().IsTextDocInOOoFileFormat() ||
2002 ( bBuildIdFound &&
2003 ( ( nUPD == 641 ) || ( nUPD == 645 ) || // prior OOo 2.0
2004 ( nUPD == 680 ) || // OOo 2.x
2005 ( nUPD == 300 ) || // OOo 3.0 - OOo 3.0.1
2006 ( nUPD == 310 ) || // OOo 3.1 - OOo 3.1.1
2007 ( nUPD == 320 ) ) ) ) // OOo 3.2 - OOo 3.2.1
2009 bApplySVGD = false;
2013 if ( bApplySVGD )
2015 // tdf#83360 use path data only when redundant data of start and end point coordinates of
2016 // path start/end and connector start/end is equal. This is to avoid using erroneous
2017 // or inconsistent path data at import of foreign formats. Office itself always
2018 // writes out a consistent data set. Not using it when there is inconsistency
2019 // is okay since the path data is redundant, buffered data just to avoid recalculation
2020 // of the connector's layout at load time, no real information would be lost.
2021 // A 'connected' end has prio to direct coordinate data in Start/EndPosition
2022 // to the path data (which should have the start/end redundant in the path)
2023 const drawing::PolyPolygonBezierCoords* pSource = static_cast< const drawing::PolyPolygonBezierCoords* >(maPath.getValue());
2024 const sal_uInt32 nSequenceCount(pSource->Coordinates.getLength());
2025 bool bStartEqual(false);
2026 bool bEndEqual(false);
2028 if(nSequenceCount)
2030 const drawing::PointSequence& rStartSeq = pSource->Coordinates[0];
2031 const sal_uInt32 nStartCount = rStartSeq.getLength();
2033 if(nStartCount)
2035 const awt::Point& rStartPoint = rStartSeq.getConstArray()[0];
2037 if(rStartPoint.X == maStart.X && rStartPoint.Y == maStart.Y)
2039 bStartEqual = true;
2043 const drawing::PointSequence& rEndSeq = pSource->Coordinates[nSequenceCount - 1];
2044 const sal_uInt32 nEndCount = rEndSeq.getLength();
2046 if(nEndCount)
2048 const awt::Point& rEndPoint = rEndSeq.getConstArray()[nEndCount - 1];
2050 if(rEndPoint.X == maEnd.X && rEndPoint.Y == maEnd.Y)
2052 bEndEqual = true;
2057 if(!bStartEqual || !bEndEqual)
2059 bApplySVGD = false;
2063 if ( bApplySVGD )
2065 assert(maPath.getValueType() == cppu::UnoType<drawing::PolyPolygonBezierCoords>::get());
2066 xProps->setPropertyValue(u"PolyPolygonBezier"_ustr, maPath);
2070 SdXMLShapeContext::startFastElement(nElement, xAttrList);
2074 SdXMLMeasureShapeContext::SdXMLMeasureShapeContext(
2075 SvXMLImport& rImport,
2076 const css::uno::Reference< css::xml::sax::XFastAttributeList>& xAttrList,
2077 uno::Reference< drawing::XShapes > const & rShapes,
2078 bool bTemporaryShape)
2079 : SdXMLShapeContext( rImport, xAttrList, rShapes, bTemporaryShape ),
2080 maStart(0,0),
2081 maEnd(1,1)
2085 SdXMLMeasureShapeContext::~SdXMLMeasureShapeContext()
2089 // this is called from the parent group for each unparsed attribute in the attribute list
2090 bool SdXMLMeasureShapeContext::processAttribute( const sax_fastparser::FastAttributeList::FastAttributeIter & aIter )
2092 switch( aIter.getToken() )
2094 case XML_ELEMENT(SVG, XML_X1):
2095 case XML_ELEMENT(SVG_COMPAT, XML_X1):
2097 GetImport().GetMM100UnitConverter().convertMeasureToCore(
2098 maStart.X, aIter.toView());
2099 break;
2101 case XML_ELEMENT(SVG, XML_Y1):
2102 case XML_ELEMENT(SVG_COMPAT, XML_Y1):
2104 GetImport().GetMM100UnitConverter().convertMeasureToCore(
2105 maStart.Y, aIter.toView());
2106 break;
2108 case XML_ELEMENT(SVG, XML_X2):
2109 case XML_ELEMENT(SVG_COMPAT, XML_X2):
2111 GetImport().GetMM100UnitConverter().convertMeasureToCore(
2112 maEnd.X, aIter.toView());
2113 break;
2115 case XML_ELEMENT(SVG, XML_Y2):
2116 case XML_ELEMENT(SVG_COMPAT, XML_Y2):
2118 GetImport().GetMM100UnitConverter().convertMeasureToCore(
2119 maEnd.Y, aIter.toView());
2120 break;
2122 default:
2123 return SdXMLShapeContext::processAttribute( aIter );
2125 return true;
2128 void SdXMLMeasureShapeContext::startFastElement (sal_Int32 nElement,
2129 const css::uno::Reference< css::xml::sax::XFastAttributeList >& xAttrList)
2131 // create Measure shape
2132 // add, set style and properties from base shape
2133 AddShape(u"com.sun.star.drawing.MeasureShape"_ustr);
2134 if(!mxShape.is())
2135 return;
2137 SetStyle();
2138 SetLayer();
2140 uno::Reference< beans::XPropertySet > xProps( mxShape, uno::UNO_QUERY );
2141 if( xProps.is() )
2143 xProps->setPropertyValue(u"StartPosition"_ustr, Any(maStart));
2144 xProps->setPropertyValue(u"EndPosition"_ustr, Any(maEnd) );
2147 // delete pre created fields
2148 uno::Reference< text::XText > xText( mxShape, uno::UNO_QUERY );
2149 if( xText.is() )
2151 xText->setString( u" "_ustr );
2154 SdXMLShapeContext::startFastElement(nElement, xAttrList);
2157 void SdXMLMeasureShapeContext::endFastElement(sal_Int32 nElement)
2161 // delete pre created fields
2162 uno::Reference< text::XText > xText( mxShape, uno::UNO_QUERY );
2163 if( !xText.is() )
2164 break;
2166 uno::Reference< text::XTextCursor > xCursor( xText->createTextCursor() );
2167 if( !xCursor.is() )
2168 break;
2170 xCursor->collapseToStart();
2171 xCursor->goRight( 1, true );
2172 xCursor->setString( u""_ustr );
2174 while(false);
2176 SdXMLShapeContext::endFastElement(nElement);
2180 SdXMLPageShapeContext::SdXMLPageShapeContext(
2181 SvXMLImport& rImport,
2182 const css::uno::Reference< css::xml::sax::XFastAttributeList>& xAttrList,
2183 uno::Reference< drawing::XShapes > const & rShapes,
2184 bool bTemporaryShape)
2185 : SdXMLShapeContext( rImport, xAttrList, rShapes, bTemporaryShape ), mnPageNumber(0)
2187 mbClearDefaultAttributes = false;
2190 SdXMLPageShapeContext::~SdXMLPageShapeContext()
2194 // this is called from the parent group for each unparsed attribute in the attribute list
2195 bool SdXMLPageShapeContext::processAttribute( const sax_fastparser::FastAttributeList::FastAttributeIter & aIter )
2197 if( aIter.getToken() == XML_ELEMENT(DRAW, XML_PAGE_NUMBER) )
2198 mnPageNumber = aIter.toInt32();
2199 else
2200 return SdXMLShapeContext::processAttribute( aIter );
2201 return true;
2204 void SdXMLPageShapeContext::startFastElement (sal_Int32 nElement,
2205 const css::uno::Reference< css::xml::sax::XFastAttributeList >& xAttrList)
2207 // create Page shape
2208 // add, set style and properties from base shape
2210 // #86163# take into account which type of PageShape needs to
2211 // be constructed. It's a presentation shape if presentation:XML_CLASS == XML_PAGE.
2212 bool bIsPresentation = !maPresentationClass.isEmpty() &&
2213 GetImport().GetShapeImport()->IsPresentationShapesSupported();
2215 uno::Reference< lang::XServiceInfo > xInfo( mxShapes, uno::UNO_QUERY );
2216 const bool bIsOnHandoutPage = xInfo.is() && xInfo->supportsService(u"com.sun.star.presentation.HandoutMasterPage"_ustr);
2218 if( bIsOnHandoutPage )
2220 AddShape(u"com.sun.star.presentation.HandoutShape"_ustr);
2222 else
2224 if(bIsPresentation && !IsXMLToken( maPresentationClass, XML_PAGE ) )
2226 bIsPresentation = false;
2229 if(bIsPresentation)
2231 AddShape(u"com.sun.star.presentation.PageShape"_ustr);
2233 else
2235 AddShape(u"com.sun.star.drawing.PageShape"_ustr);
2239 if(!mxShape.is())
2240 return;
2242 SetStyle();
2243 SetLayer();
2245 // set pos, size, shear and rotate
2246 SetTransformation();
2248 uno::Reference< beans::XPropertySet > xPropSet(mxShape, uno::UNO_QUERY);
2249 if(xPropSet.is())
2251 uno::Reference< beans::XPropertySetInfo > xPropSetInfo( xPropSet->getPropertySetInfo() );
2252 static constexpr OUString aPageNumberStr(u"PageNumber"_ustr);
2253 if( xPropSetInfo.is() && xPropSetInfo->hasPropertyByName(aPageNumberStr))
2254 xPropSet->setPropertyValue(aPageNumberStr, uno::Any( mnPageNumber ));
2257 SdXMLShapeContext::startFastElement(nElement, xAttrList);
2261 SdXMLCaptionShapeContext::SdXMLCaptionShapeContext(
2262 SvXMLImport& rImport,
2263 const css::uno::Reference< css::xml::sax::XFastAttributeList>& xAttrList,
2264 uno::Reference< drawing::XShapes > const & rShapes,
2265 bool bTemporaryShape)
2266 : SdXMLShapeContext( rImport, xAttrList, rShapes, bTemporaryShape ),
2267 // #86616# for correct edge rounding import mnRadius needs to be initialized
2268 mnRadius( 0 )
2272 SdXMLCaptionShapeContext::~SdXMLCaptionShapeContext()
2276 void SdXMLCaptionShapeContext::startFastElement (sal_Int32 nElement,
2277 const css::uno::Reference< css::xml::sax::XFastAttributeList >& xAttrList)
2279 // create Caption shape
2280 // add, set style and properties from base shape
2281 AddShape(u"com.sun.star.drawing.CaptionShape"_ustr);
2282 if( !mxShape.is() )
2283 return;
2285 SetStyle();
2286 SetLayer();
2288 uno::Reference< beans::XPropertySet > xProps( mxShape, uno::UNO_QUERY );
2290 // SJ: If AutoGrowWidthItem is set, SetTransformation will lead to the wrong SnapRect
2291 // because NbcAdjustTextFrameWidthAndHeight() is called (text is set later and center alignment
2292 // is the default setting, so the top left reference point that is used by the caption point is
2293 // no longer correct) There are two ways to solve this problem, temporarily disabling the
2294 // autogrowwidth as we are doing here or to apply the CaptionPoint after setting text
2295 bool bIsAutoGrowWidth = false;
2296 if ( xProps.is() )
2298 uno::Any aAny( xProps->getPropertyValue(u"TextAutoGrowWidth"_ustr) );
2299 aAny >>= bIsAutoGrowWidth;
2301 if ( bIsAutoGrowWidth )
2302 xProps->setPropertyValue(u"TextAutoGrowWidth"_ustr, uno::Any( false ) );
2305 // set pos, size, shear and rotate
2306 SetTransformation();
2307 if( xProps.is() )
2308 xProps->setPropertyValue(u"CaptionPoint"_ustr, uno::Any( maCaptionPoint ) );
2310 if ( bIsAutoGrowWidth )
2311 xProps->setPropertyValue(u"TextAutoGrowWidth"_ustr, uno::Any( true ) );
2313 if(mnRadius)
2315 uno::Reference< beans::XPropertySet > xPropSet(mxShape, uno::UNO_QUERY);
2316 if(xPropSet.is())
2320 xPropSet->setPropertyValue(u"CornerRadius"_ustr, uno::Any( mnRadius ) );
2322 catch(const uno::Exception&)
2324 DBG_UNHANDLED_EXCEPTION( "xmloff", "setting corner radius");
2329 SdXMLShapeContext::startFastElement(nElement, xAttrList);
2332 // this is called from the parent group for each unparsed attribute in the attribute list
2333 bool SdXMLCaptionShapeContext::processAttribute( const sax_fastparser::FastAttributeList::FastAttributeIter & aIter )
2335 switch (aIter.getToken())
2337 case XML_ELEMENT(DRAW, XML_CAPTION_POINT_X):
2338 GetImport().GetMM100UnitConverter().convertMeasureToCore(
2339 maCaptionPoint.X, aIter.toView());
2340 break;
2341 case XML_ELEMENT(DRAW, XML_CAPTION_POINT_Y):
2342 GetImport().GetMM100UnitConverter().convertMeasureToCore(
2343 maCaptionPoint.Y, aIter.toView());
2344 break;
2345 case XML_ELEMENT(DRAW, XML_CORNER_RADIUS):
2346 GetImport().GetMM100UnitConverter().convertMeasureToCore(
2347 mnRadius, aIter.toView());
2348 break;
2349 default:
2350 return SdXMLShapeContext::processAttribute( aIter );
2352 return true;
2356 SdXMLGraphicObjectShapeContext::SdXMLGraphicObjectShapeContext(
2357 SvXMLImport& rImport,
2358 const css::uno::Reference< css::xml::sax::XFastAttributeList>& xAttrList,
2359 uno::Reference< drawing::XShapes > const & rShapes)
2360 : SdXMLShapeContext( rImport, xAttrList, rShapes, false/*bTemporaryShape*/ )
2364 // this is called from the parent group for each unparsed attribute in the attribute list
2365 bool SdXMLGraphicObjectShapeContext::processAttribute( const sax_fastparser::FastAttributeList::FastAttributeIter & aIter )
2367 switch (aIter.getToken())
2369 case XML_ELEMENT(XLINK, XML_HREF):
2370 maURL = aIter.toString();
2371 break;
2372 case XML_ELEMENT(DRAW, XML_MIME_TYPE):
2373 case XML_ELEMENT(LO_EXT, XML_MIME_TYPE):
2374 msMimeType = aIter.toString();
2375 break;
2376 default:
2377 return SdXMLShapeContext::processAttribute(aIter);
2379 return true;
2382 void SdXMLGraphicObjectShapeContext::startFastElement (sal_Int32 nElement,
2383 const css::uno::Reference< css::xml::sax::XFastAttributeList >& xAttrList)
2385 // create graphic object shape
2386 OUString service;
2388 if( IsXMLToken( maPresentationClass, XML_GRAPHIC ) && GetImport().GetShapeImport()->IsPresentationShapesSupported() )
2390 service = "com.sun.star.presentation.GraphicObjectShape";
2392 else
2394 service = "com.sun.star.drawing.GraphicObjectShape";
2397 AddShape(service);
2399 if(!mxShape.is())
2400 return;
2402 SetStyle();
2403 SetLayer();
2405 uno::Reference< beans::XPropertySet > xPropset(mxShape, uno::UNO_QUERY);
2406 if(xPropset.is())
2408 // since OOo 1.x had no line or fill style for graphics, but may create
2409 // documents with them, we have to override them here
2410 sal_Int32 nUPD, nBuildId;
2411 if( GetImport().getBuildIds( nUPD, nBuildId ) && (nUPD == 645) ) try
2413 xPropset->setPropertyValue(u"FillStyle"_ustr, Any( FillStyle_NONE ) );
2414 xPropset->setPropertyValue(u"LineStyle"_ustr, Any( LineStyle_NONE ) );
2416 catch(const Exception&)
2420 uno::Reference< beans::XPropertySetInfo > xPropsInfo( xPropset->getPropertySetInfo() );
2421 if( xPropsInfo.is() && xPropsInfo->hasPropertyByName(u"IsEmptyPresentationObject"_ustr))
2422 xPropset->setPropertyValue(u"IsEmptyPresentationObject"_ustr, css::uno::Any( mbIsPlaceholder ) );
2424 if( !mbIsPlaceholder )
2426 if( !maURL.isEmpty() )
2428 uno::Reference<graphic::XGraphic> xGraphic = GetImport().loadGraphicByURL(maURL);
2429 if (xGraphic.is())
2431 xPropset->setPropertyValue(u"Graphic"_ustr, uno::Any(xGraphic));
2437 if(mbIsUserTransformed)
2439 uno::Reference< beans::XPropertySet > xProps(mxShape, uno::UNO_QUERY);
2440 if(xProps.is())
2442 uno::Reference< beans::XPropertySetInfo > xPropsInfo( xProps->getPropertySetInfo() );
2443 if( xPropsInfo.is() )
2445 if( xPropsInfo->hasPropertyByName(u"IsPlaceholderDependent"_ustr))
2446 xProps->setPropertyValue(u"IsPlaceholderDependent"_ustr, css::uno::Any(false) );
2451 // set pos, size, shear and rotate
2452 SetTransformation();
2454 SdXMLShapeContext::startFastElement(nElement, xAttrList);
2457 void SdXMLGraphicObjectShapeContext::endFastElement(sal_Int32 nElement)
2459 if (mxBase64Stream.is())
2461 uno::Reference<graphic::XGraphic> xGraphic(GetImport().loadGraphicFromBase64(mxBase64Stream));
2462 if (xGraphic.is())
2464 uno::Reference<beans::XPropertySet> xProperties(mxShape, uno::UNO_QUERY);
2465 if (xProperties.is())
2467 xProperties->setPropertyValue(u"Graphic"_ustr, uno::Any(xGraphic));
2472 SdXMLShapeContext::endFastElement(nElement);
2475 css::uno::Reference< css::xml::sax::XFastContextHandler > SdXMLGraphicObjectShapeContext::createFastChildContext(
2476 sal_Int32 nElement,
2477 const css::uno::Reference< css::xml::sax::XFastAttributeList >& xAttrList )
2479 css::uno::Reference< css::xml::sax::XFastContextHandler > xContext;
2481 if( nElement == XML_ELEMENT(OFFICE, XML_BINARY_DATA) )
2483 if( maURL.isEmpty() && !mxBase64Stream.is() )
2485 mxBase64Stream = GetImport().GetStreamForGraphicObjectURLFromBase64();
2486 if( mxBase64Stream.is() )
2487 xContext = new XMLBase64ImportContext( GetImport(),
2488 mxBase64Stream );
2492 // delegate to parent class if no context could be created
2493 if (!xContext)
2494 xContext = SdXMLShapeContext::createFastChildContext(nElement,
2495 xAttrList);
2497 if (!xContext)
2498 XMLOFF_WARN_UNKNOWN_ELEMENT("xmloff", nElement);
2500 return xContext;
2503 SdXMLGraphicObjectShapeContext::~SdXMLGraphicObjectShapeContext()
2509 SdXMLChartShapeContext::SdXMLChartShapeContext(
2510 SvXMLImport& rImport,
2511 const css::uno::Reference< css::xml::sax::XFastAttributeList>& xAttrList,
2512 uno::Reference< drawing::XShapes > const & rShapes,
2513 bool bTemporaryShape)
2514 : SdXMLShapeContext( rImport, xAttrList, rShapes, bTemporaryShape )
2518 void SdXMLChartShapeContext::startFastElement (sal_Int32 nElement,
2519 const css::uno::Reference< css::xml::sax::XFastAttributeList >& xAttrList)
2521 const bool bIsPresentation = isPresentationShape();
2523 AddShape(
2524 bIsPresentation
2525 ? u"com.sun.star.presentation.ChartShape"_ustr
2526 : u"com.sun.star.drawing.OLE2Shape"_ustr);
2528 if(!mxShape.is())
2529 return;
2531 SetStyle();
2532 SetLayer();
2534 if( !mbIsPlaceholder )
2536 uno::Reference< beans::XPropertySet > xProps(mxShape, uno::UNO_QUERY);
2537 if(xProps.is())
2539 uno::Reference< beans::XPropertySetInfo > xPropsInfo( xProps->getPropertySetInfo() );
2540 if( xPropsInfo.is() && xPropsInfo->hasPropertyByName(u"IsEmptyPresentationObject"_ustr))
2541 xProps->setPropertyValue(u"IsEmptyPresentationObject"_ustr, css::uno::Any(false) );
2543 uno::Any aAny;
2545 xProps->setPropertyValue(u"CLSID"_ustr, Any(u"12DCAE26-281F-416F-a234-c3086127382e"_ustr) );
2547 aAny = xProps->getPropertyValue(u"Model"_ustr);
2548 uno::Reference< frame::XModel > xChartModel;
2549 if( aAny >>= xChartModel )
2551 #if !ENABLE_WASM_STRIP_CHART
2552 // WASM_CHART change
2553 // TODO: Maybe use SdXMLGraphicObjectShapeContext completely instead
2554 // or try to create as mbIsPlaceholder object adding a Chart visualization
2555 // that should be available somehow
2556 mxChartContext.set( GetImport().GetChartImport()->CreateChartContext( GetImport(), xChartModel ) );
2557 #endif
2562 if(mbIsUserTransformed)
2564 uno::Reference< beans::XPropertySet > xProps(mxShape, uno::UNO_QUERY);
2565 if(xProps.is())
2567 uno::Reference< beans::XPropertySetInfo > xPropsInfo( xProps->getPropertySetInfo() );
2568 if( xPropsInfo.is() )
2570 if( xPropsInfo->hasPropertyByName(u"IsPlaceholderDependent"_ustr))
2571 xProps->setPropertyValue(u"IsPlaceholderDependent"_ustr, css::uno::Any(false) );
2576 // set pos, size, shear and rotate
2577 SetTransformation();
2579 SdXMLShapeContext::startFastElement(nElement, xAttrList);
2581 if( mxChartContext.is() )
2582 mxChartContext->startFastElement( nElement, xAttrList );
2585 void SdXMLChartShapeContext::endFastElement(sal_Int32 nElement)
2587 if( mxChartContext.is() )
2588 mxChartContext->endFastElement(nElement);
2590 SdXMLShapeContext::endFastElement(nElement);
2593 void SdXMLChartShapeContext::characters( const OUString& rChars )
2595 if( mxChartContext.is() )
2596 mxChartContext->characters( rChars );
2599 css::uno::Reference< css::xml::sax::XFastContextHandler > SdXMLChartShapeContext::createFastChildContext(
2600 sal_Int32 nElement,
2601 const css::uno::Reference< css::xml::sax::XFastAttributeList >& xAttrList )
2603 if( mxChartContext.is() )
2604 return mxChartContext->createFastChildContext( nElement, xAttrList );
2606 return nullptr;
2610 SdXMLObjectShapeContext::SdXMLObjectShapeContext( SvXMLImport& rImport,
2611 const css::uno::Reference< css::xml::sax::XFastAttributeList>& xAttrList,
2612 css::uno::Reference< css::drawing::XShapes > const & rShapes)
2613 : SdXMLShapeContext( rImport, xAttrList, rShapes, false/*bTemporaryShape*/ )
2617 SdXMLObjectShapeContext::~SdXMLObjectShapeContext()
2621 void SdXMLObjectShapeContext::startFastElement (sal_Int32 /*nElement*/,
2622 const css::uno::Reference< css::xml::sax::XFastAttributeList >& /*xAttrList*/)
2624 // #96717# in theorie, if we don't have a URL we shouldn't even
2625 // export this OLE shape. But practically it's too risky right now
2626 // to change this so we better dispose this on load
2627 //if( !mbIsPlaceholder && ImpIsEmptyURL(maHref) )
2628 // return;
2630 // #100592# this BugFix prevents that a shape is created. CL
2631 // is thinking about an alternative.
2632 // #i13140# Check for more than empty string in maHref, there are
2633 // other possibilities that maHref results in empty container
2634 // storage names
2635 if( !(GetImport().getImportFlags() & SvXMLImportFlags::EMBEDDED) && !mbIsPlaceholder && ImpIsEmptyURL(maHref) )
2636 return;
2638 OUString service(u"com.sun.star.drawing.OLE2Shape"_ustr);
2640 bool bIsPresShape = !maPresentationClass.isEmpty() && GetImport().GetShapeImport()->IsPresentationShapesSupported();
2642 if( bIsPresShape )
2644 if( IsXMLToken( maPresentationClass, XML_CHART ) )
2646 service = "com.sun.star.presentation.ChartShape";
2648 else if( IsXMLToken( maPresentationClass, XML_TABLE ) )
2650 service = "com.sun.star.presentation.CalcShape";
2652 else if( IsXMLToken( maPresentationClass, XML_OBJECT ) )
2654 service = "com.sun.star.presentation.OLE2Shape";
2658 AddShape(service);
2660 if( !mxShape.is() )
2661 return;
2663 SetLayer();
2665 if(bIsPresShape)
2667 uno::Reference< beans::XPropertySet > xProps(mxShape, uno::UNO_QUERY);
2668 if(xProps.is())
2670 uno::Reference< beans::XPropertySetInfo > xPropsInfo( xProps->getPropertySetInfo() );
2671 if( xPropsInfo.is() )
2673 if( !mbIsPlaceholder && xPropsInfo->hasPropertyByName(u"IsEmptyPresentationObject"_ustr))
2674 xProps->setPropertyValue(u"IsEmptyPresentationObject"_ustr, css::uno::Any(false) );
2676 if( mbIsUserTransformed && xPropsInfo->hasPropertyByName(u"IsPlaceholderDependent"_ustr))
2677 xProps->setPropertyValue(u"IsPlaceholderDependent"_ustr, css::uno::Any(false) );
2682 if( !mbIsPlaceholder && !maHref.isEmpty() )
2684 uno::Reference< beans::XPropertySet > xProps( mxShape, uno::UNO_QUERY );
2686 if( xProps.is() )
2688 OUString aPersistName = GetImport().ResolveEmbeddedObjectURL( maHref, maCLSID );
2690 if ( GetImport().IsPackageURL( maHref ) )
2692 static constexpr OUString sURL( u"vnd.sun.star.EmbeddedObject:"_ustr );
2694 if ( aPersistName.startsWith( sURL ) )
2695 aPersistName = aPersistName.copy( sURL.getLength() );
2697 xProps->setPropertyValue(u"PersistName"_ustr,
2698 uno::Any( aPersistName ) );
2700 else
2702 // this is OOo link object
2703 xProps->setPropertyValue(u"LinkURL"_ustr,
2704 uno::Any( aPersistName ) );
2709 // set pos, size, shear and rotate
2710 SetTransformation();
2712 SetStyle();
2714 GetImport().GetShapeImport()->finishShape( mxShape, mxAttrList, mxShapes );
2717 void SdXMLObjectShapeContext::endFastElement(sal_Int32 nElement)
2719 if (GetImport().isGeneratorVersionOlderThan(
2720 SvXMLImport::OOo_34x, SvXMLImport::LO_41x)) // < LO 4.0
2722 // #i118485#
2723 // If it's an old file from us written before OOo3.4, we need to correct
2724 // FillStyle and LineStyle for OLE2 objects. The error was that the old paint
2725 // implementations just ignored added fill/linestyles completely, thus
2726 // those objects need to be corrected to not show blue and hairline which
2727 // always was the default, but would be shown now
2728 uno::Reference< beans::XPropertySet > xProps(mxShape, uno::UNO_QUERY);
2730 if( xProps.is() )
2732 xProps->setPropertyValue(u"FillStyle"_ustr, uno::Any(drawing::FillStyle_NONE));
2733 xProps->setPropertyValue(u"LineStyle"_ustr, uno::Any(drawing::LineStyle_NONE));
2737 if( mxBase64Stream.is() )
2739 OUString aPersistName( GetImport().ResolveEmbeddedObjectURLFromBase64() );
2740 static constexpr OUStringLiteral sURL( u"vnd.sun.star.EmbeddedObject:" );
2742 aPersistName = aPersistName.copy( sURL.getLength() );
2744 uno::Reference< beans::XPropertySet > xProps(mxShape, uno::UNO_QUERY);
2745 if( xProps.is() )
2746 xProps->setPropertyValue(u"PersistName"_ustr, uno::Any( aPersistName ) );
2749 SdXMLShapeContext::endFastElement(nElement);
2752 // this is called from the parent group for each unparsed attribute in the attribute list
2753 bool SdXMLObjectShapeContext::processAttribute( const sax_fastparser::FastAttributeList::FastAttributeIter & aIter )
2755 switch( aIter.getToken() )
2757 case XML_ELEMENT(DRAW, XML_CLASS_ID):
2758 maCLSID = aIter.toString();
2759 break;
2760 case XML_ELEMENT(XLINK, XML_HREF):
2761 maHref = aIter.toString();
2762 break;
2763 default:
2764 return SdXMLShapeContext::processAttribute( aIter );
2766 return true;
2769 css::uno::Reference< css::xml::sax::XFastContextHandler > SdXMLObjectShapeContext::createFastChildContext(
2770 sal_Int32 nElement,
2771 const css::uno::Reference< css::xml::sax::XFastAttributeList >& xAttrList )
2773 if(nElement == XML_ELEMENT(OFFICE, XML_BINARY_DATA))
2775 mxBase64Stream = GetImport().GetStreamForEmbeddedObjectURLFromBase64();
2776 if( mxBase64Stream.is() )
2777 return new XMLBase64ImportContext( GetImport(), mxBase64Stream );
2779 else if( nElement == XML_ELEMENT(OFFICE, XML_DOCUMENT) ||
2780 nElement == XML_ELEMENT(MATH, XML_MATH) )
2782 rtl::Reference<XMLEmbeddedObjectImportContext> xEContext(
2783 new XMLEmbeddedObjectImportContext(GetImport(), nElement, xAttrList));
2784 maCLSID = xEContext->GetFilterCLSID();
2785 if( !maCLSID.isEmpty() )
2787 uno::Reference< beans::XPropertySet > xPropSet(mxShape, uno::UNO_QUERY);
2788 if( xPropSet.is() )
2790 xPropSet->setPropertyValue(u"CLSID"_ustr, uno::Any( maCLSID ) );
2792 // A hack: getting the model of newly created OLE object will eventually call
2793 // SdrOle2Obj::AddOwnLightClient, which will try to update scaling, using the
2794 // incomplete object data. Avoid that by setting the special property.
2795 xPropSet->setPropertyValue(u"IgnoreOLEObjectScale"_ustr, uno::Any(true));
2797 uno::Reference< lang::XComponent > xComp;
2798 xPropSet->getPropertyValue(u"Model"_ustr) >>= xComp;
2800 xPropSet->setPropertyValue(u"IgnoreOLEObjectScale"_ustr, uno::Any(false));
2802 SAL_WARN_IF( !xComp.is(), "xmloff", "no xModel for own OLE format" );
2803 xEContext->SetComponent(xComp);
2806 return xEContext;
2809 // delegate to parent class if no context could be created
2810 return SdXMLShapeContext::createFastChildContext(nElement, xAttrList);
2813 SdXMLAppletShapeContext::SdXMLAppletShapeContext( SvXMLImport& rImport,
2814 const css::uno::Reference< css::xml::sax::XFastAttributeList>& xAttrList,
2815 css::uno::Reference< css::drawing::XShapes > const & rShapes)
2816 : SdXMLShapeContext( rImport, xAttrList, rShapes, false/*bTemporaryShape*/ ),
2817 mbIsScript( false )
2821 SdXMLAppletShapeContext::~SdXMLAppletShapeContext()
2825 void SdXMLAppletShapeContext::startFastElement (sal_Int32 /*nElement*/,
2826 const css::uno::Reference< css::xml::sax::XFastAttributeList >& /*xAttrList*/)
2828 AddShape(u"com.sun.star.drawing.AppletShape"_ustr);
2830 if( mxShape.is() )
2832 SetLayer();
2834 // set pos, size, shear and rotate
2835 SetTransformation();
2836 GetImport().GetShapeImport()->finishShape( mxShape, mxAttrList, mxShapes );
2840 // this is called from the parent group for each unparsed attribute in the attribute list
2841 bool SdXMLAppletShapeContext::processAttribute( const sax_fastparser::FastAttributeList::FastAttributeIter & aIter )
2843 switch( aIter.getToken() )
2845 case XML_ELEMENT(DRAW, XML_APPLET_NAME):
2846 maAppletName = aIter.toString();
2847 break;
2848 case XML_ELEMENT(DRAW, XML_CODE):
2849 maAppletCode = aIter.toString();
2850 break;
2851 case XML_ELEMENT(DRAW, XML_MAY_SCRIPT):
2852 mbIsScript = IsXMLToken( aIter, XML_TRUE );
2853 break;
2854 case XML_ELEMENT(XLINK, XML_HREF):
2855 maHref = GetImport().GetAbsoluteReference(aIter.toString());
2856 break;
2857 default:
2858 return SdXMLShapeContext::processAttribute( aIter );
2860 return true;
2863 void SdXMLAppletShapeContext::endFastElement(sal_Int32 nElement)
2865 uno::Reference< beans::XPropertySet > xProps( mxShape, uno::UNO_QUERY );
2866 if( xProps.is() )
2868 if ( maSize.Width && maSize.Height )
2870 // the visual area for applet must be set on loading
2871 awt::Rectangle aRect( 0, 0, maSize.Width, maSize.Height );
2872 xProps->setPropertyValue(u"VisibleArea"_ustr, Any(aRect) );
2875 if( maParams.hasElements() )
2877 xProps->setPropertyValue(u"AppletCommands"_ustr, Any(maParams) );
2880 if( !maHref.isEmpty() )
2882 xProps->setPropertyValue(u"AppletCodeBase"_ustr, Any(maHref) );
2885 if( !maAppletName.isEmpty() )
2887 xProps->setPropertyValue(u"AppletName"_ustr, Any(maAppletName) );
2890 if( mbIsScript )
2892 xProps->setPropertyValue(u"AppletIsScript"_ustr, Any(mbIsScript) );
2896 if( !maAppletCode.isEmpty() )
2898 xProps->setPropertyValue(u"AppletCode"_ustr, Any(maAppletCode) );
2901 xProps->setPropertyValue(u"AppletDocBase"_ustr, Any(GetImport().GetDocumentBase()) );
2903 SetThumbnail();
2906 SdXMLShapeContext::endFastElement(nElement);
2909 css::uno::Reference< css::xml::sax::XFastContextHandler > SdXMLAppletShapeContext::createFastChildContext(
2910 sal_Int32 nElement,
2911 const css::uno::Reference< css::xml::sax::XFastAttributeList >& xAttrList )
2913 if( nElement == XML_ELEMENT(DRAW, XML_PARAM) )
2915 OUString aParamName, aParamValue;
2916 // now parse the attribute list and look for draw:name and draw:value
2917 for( auto& aIter : sax_fastparser::castToFastAttributeList(xAttrList) )
2919 if( aIter.getToken() == XML_ELEMENT(DRAW, XML_NAME) )
2920 aParamName = aIter.toString();
2921 if( aIter.getToken() == XML_ELEMENT(DRAW, XML_VALUE) )
2922 aParamValue = aIter.toString();
2925 if( !aParamName.isEmpty() )
2927 sal_Int32 nIndex = maParams.getLength();
2928 maParams.realloc( nIndex + 1 );
2929 auto pParams = maParams.getArray();
2930 pParams[nIndex].Name = aParamName;
2931 pParams[nIndex].Handle = -1;
2932 pParams[nIndex].Value <<= aParamValue;
2933 pParams[nIndex].State = beans::PropertyState_DIRECT_VALUE;
2936 return new SvXMLImportContext( GetImport() );
2939 return SdXMLShapeContext::createFastChildContext( nElement, xAttrList );
2943 SdXMLPluginShapeContext::SdXMLPluginShapeContext( SvXMLImport& rImport,
2944 const css::uno::Reference< css::xml::sax::XFastAttributeList>& xAttrList,
2945 css::uno::Reference< css::drawing::XShapes > const & rShapes) :
2946 SdXMLShapeContext( rImport, xAttrList, rShapes, false/*bTemporaryShape*/ ),
2947 mbMedia( false )
2951 SdXMLPluginShapeContext::~SdXMLPluginShapeContext()
2955 void SdXMLPluginShapeContext::startFastElement (sal_Int32 /*nElement*/,
2956 const css::uno::Reference< css::xml::sax::XFastAttributeList >& xAttrList)
2959 // watch for MimeType attribute to see if we have a media object
2960 for( auto& aIter : sax_fastparser::castToFastAttributeList(xAttrList) )
2962 if( aIter.getToken() == XML_ELEMENT(DRAW, XML_MIME_TYPE) )
2964 if (::comphelper::IsMediaMimeType(aIter.toView()))
2965 mbMedia = true;
2966 // leave this loop
2967 break;
2971 OUString service;
2973 bool bIsPresShape = false;
2975 if( mbMedia )
2977 service = "com.sun.star.drawing.MediaShape";
2979 bIsPresShape = !maPresentationClass.isEmpty() && GetImport().GetShapeImport()->IsPresentationShapesSupported();
2980 if( bIsPresShape )
2982 if( IsXMLToken( maPresentationClass, XML_OBJECT ) )
2984 service = "com.sun.star.presentation.MediaShape";
2988 else
2989 service = "com.sun.star.drawing.PluginShape";
2991 AddShape(service);
2993 if( !mxShape.is() )
2994 return;
2996 if (mbMedia)
2998 // The media may have a crop, apply it.
2999 SetStyle(/*bSupportsStyle=*/false);
3002 SetLayer();
3004 if(bIsPresShape)
3006 uno::Reference< beans::XPropertySet > xProps( mxShape, uno::UNO_QUERY );
3007 if(xProps.is())
3009 uno::Reference< beans::XPropertySetInfo > xPropsInfo( xProps->getPropertySetInfo() );
3010 if( xPropsInfo.is() )
3012 if( !mbIsPlaceholder && xPropsInfo->hasPropertyByName(u"IsEmptyPresentationObject"_ustr))
3013 xProps->setPropertyValue(u"IsEmptyPresentationObject"_ustr, css::uno::Any(false) );
3015 if( mbIsUserTransformed && xPropsInfo->hasPropertyByName(u"IsPlaceholderDependent"_ustr))
3016 xProps->setPropertyValue(u"IsPlaceholderDependent"_ustr, css::uno::Any(false) );
3021 // set pos, size, shear and rotate
3022 SetTransformation();
3023 GetImport().GetShapeImport()->finishShape( mxShape, mxAttrList, mxShapes );
3026 static OUString
3027 lcl_GetMediaReference(SvXMLImport const& rImport, OUString const& rURL)
3029 if (rImport.IsPackageURL(rURL))
3031 return "vnd.sun.star.Package:" + rURL;
3033 else
3035 return rImport.GetAbsoluteReference(rURL);
3039 // this is called from the parent group for each unparsed attribute in the attribute list
3040 bool SdXMLPluginShapeContext::processAttribute( const sax_fastparser::FastAttributeList::FastAttributeIter & aIter )
3042 switch( aIter.getToken() )
3044 case XML_ELEMENT(DRAW, XML_MIME_TYPE):
3045 maMimeType = aIter.toString();
3046 break;
3047 case XML_ELEMENT(XLINK, XML_HREF):
3048 maHref = lcl_GetMediaReference(GetImport(), aIter.toString());
3049 break;
3050 default:
3051 return SdXMLShapeContext::processAttribute( aIter );
3053 return true;
3056 void SdXMLPluginShapeContext::endFastElement(sal_Int32 nElement)
3058 uno::Reference< beans::XPropertySet > xProps( mxShape, uno::UNO_QUERY );
3060 if( xProps.is() )
3062 if ( maSize.Width && maSize.Height )
3064 static constexpr OUString sVisibleArea( u"VisibleArea"_ustr );
3065 uno::Reference< beans::XPropertySetInfo > aXPropSetInfo( xProps->getPropertySetInfo() );
3066 if ( !aXPropSetInfo.is() || aXPropSetInfo->hasPropertyByName( sVisibleArea ) )
3068 // the visual area for a plugin must be set on loading
3069 awt::Rectangle aRect( 0, 0, maSize.Width, maSize.Height );
3070 xProps->setPropertyValue( sVisibleArea, Any(aRect) );
3074 if( !mbMedia )
3076 // in case we have a plugin object
3077 if( maParams.hasElements() )
3079 xProps->setPropertyValue(u"PluginCommands"_ustr, Any(maParams) );
3082 if( !maMimeType.isEmpty() )
3084 xProps->setPropertyValue(u"PluginMimeType"_ustr, Any(maMimeType) );
3087 if( !maHref.isEmpty() )
3089 xProps->setPropertyValue(u"PluginURL"_ustr, Any(maHref) );
3092 else
3094 // in case we have a media object
3095 xProps->setPropertyValue( u"MediaURL"_ustr, uno::Any(maHref));
3097 xProps->setPropertyValue(u"MediaMimeType"_ustr, uno::Any(maMimeType) );
3099 for (const auto& rParam : maParams)
3101 const OUString& rName = rParam.Name;
3103 if( rName == "Loop" )
3105 OUString aValueStr;
3106 rParam.Value >>= aValueStr;
3107 xProps->setPropertyValue(u"Loop"_ustr,
3108 uno::Any( aValueStr == "true" ) );
3110 else if( rName == "Mute" )
3112 OUString aValueStr;
3113 rParam.Value >>= aValueStr;
3114 xProps->setPropertyValue(u"Mute"_ustr,
3115 uno::Any( aValueStr == "true" ) );
3117 else if( rName == "VolumeDB" )
3119 OUString aValueStr;
3120 rParam.Value >>= aValueStr;
3121 xProps->setPropertyValue(u"VolumeDB"_ustr,
3122 uno::Any( static_cast< sal_Int16 >( aValueStr.toInt32() ) ) );
3124 else if( rName == "Zoom" )
3126 OUString aZoomStr;
3127 media::ZoomLevel eZoomLevel;
3129 rParam.Value >>= aZoomStr;
3131 if( aZoomStr == "25%" )
3132 eZoomLevel = media::ZoomLevel_ZOOM_1_TO_4;
3133 else if( aZoomStr == "50%" )
3134 eZoomLevel = media::ZoomLevel_ZOOM_1_TO_2;
3135 else if( aZoomStr == "100%" )
3136 eZoomLevel = media::ZoomLevel_ORIGINAL;
3137 else if( aZoomStr == "200%" )
3138 eZoomLevel = media::ZoomLevel_ZOOM_2_TO_1;
3139 else if( aZoomStr == "400%" )
3140 eZoomLevel = media::ZoomLevel_ZOOM_4_TO_1;
3141 else if( aZoomStr == "fit" )
3142 eZoomLevel = media::ZoomLevel_FIT_TO_WINDOW;
3143 else if( aZoomStr == "fixedfit" )
3144 eZoomLevel = media::ZoomLevel_FIT_TO_WINDOW_FIXED_ASPECT;
3145 else if( aZoomStr == "fullscreen" )
3146 eZoomLevel = media::ZoomLevel_FULLSCREEN;
3147 else
3148 eZoomLevel = media::ZoomLevel_NOT_AVAILABLE;
3150 xProps->setPropertyValue(u"Zoom"_ustr, uno::Any( eZoomLevel ) );
3155 SetThumbnail();
3158 SdXMLShapeContext::endFastElement(nElement);
3161 css::uno::Reference< css::xml::sax::XFastContextHandler > SdXMLPluginShapeContext::createFastChildContext(
3162 sal_Int32 nElement,
3163 const css::uno::Reference< css::xml::sax::XFastAttributeList >& xAttrList )
3165 if( nElement == XML_ELEMENT(DRAW, XML_PARAM) )
3167 OUString aParamName, aParamValue;
3168 // now parse the attribute list and look for draw:name and draw:value
3169 for( auto& aIter : sax_fastparser::castToFastAttributeList(xAttrList) )
3171 if( aIter.getToken() == XML_ELEMENT(DRAW, XML_NAME) )
3172 aParamName = aIter.toString();
3173 else if( aIter.getToken() == XML_ELEMENT(DRAW, XML_VALUE) )
3174 aParamValue = aIter.toString();
3177 if( !aParamName.isEmpty() )
3179 sal_Int32 nIndex = maParams.getLength();
3180 maParams.realloc( nIndex + 1 );
3181 auto pParams = maParams.getArray();
3182 pParams[nIndex].Name = aParamName;
3183 pParams[nIndex].Handle = -1;
3184 pParams[nIndex].Value <<= aParamValue;
3185 pParams[nIndex].State = beans::PropertyState_DIRECT_VALUE;
3188 return new SvXMLImportContext( GetImport() );
3191 return SdXMLShapeContext::createFastChildContext( nElement, xAttrList );
3195 SdXMLFloatingFrameShapeContext::SdXMLFloatingFrameShapeContext( SvXMLImport& rImport,
3196 const css::uno::Reference< css::xml::sax::XFastAttributeList>& xAttrList,
3197 css::uno::Reference< css::drawing::XShapes > const & rShapes)
3198 : SdXMLShapeContext( rImport, xAttrList, rShapes, false/*bTemporaryShape*/ )
3202 SdXMLFloatingFrameShapeContext::~SdXMLFloatingFrameShapeContext()
3206 uno::Reference<drawing::XShape> SdXMLFloatingFrameShapeContext::CreateFloatingFrameShape() const
3208 uno::Reference<lang::XMultiServiceFactory> xServiceFact(GetImport().GetModel(), uno::UNO_QUERY);
3209 if (!xServiceFact.is())
3210 return nullptr;
3211 uno::Reference<drawing::XShape> xShape(
3212 xServiceFact->createInstance(u"com.sun.star.drawing.FrameShape"_ustr), uno::UNO_QUERY);
3213 return xShape;
3216 void SdXMLFloatingFrameShapeContext::startFastElement (sal_Int32 /*nElement*/,
3217 const css::uno::Reference< css::xml::sax::XFastAttributeList >& /*xAttrList*/)
3219 uno::Reference<drawing::XShape> xShape(SdXMLFloatingFrameShapeContext::CreateFloatingFrameShape());
3221 uno::Reference< beans::XPropertySet > xProps(xShape, uno::UNO_QUERY);
3222 // set FrameURL before AddShape, we have to do it again later because it
3223 // gets cleared when the SdrOle2Obj is attached to the XShape. But we want
3224 // FrameURL to exist when AddShape triggers SetPersistName which itself
3225 // triggers SdrOle2Obj::CheckFileLink_Impl and at that point we want to
3226 // know what URL will end up being used. So bodge this by setting FrameURL
3227 // to the temp pre-SdrOle2Obj attached properties and we can smuggle it
3228 // eventually into SdrOle2Obj::SetPersistName at the right point after
3229 // PersistName is set but before SdrOle2Obj::CheckFileLink_Impl is called
3230 // in order to inform the link manager that this is an IFrame that links to
3231 // a URL
3232 if (xProps && !maHref.isEmpty())
3233 xProps->setPropertyValue(u"FrameURL"_ustr, Any(maHref));
3235 AddShape(xShape);
3237 if( !mxShape.is() )
3238 return;
3240 SetLayer();
3242 // set pos, size, shear and rotate
3243 SetTransformation();
3245 if( xProps.is() )
3247 if( !maFrameName.isEmpty() )
3249 xProps->setPropertyValue(u"FrameName"_ustr, Any(maFrameName) );
3252 if( !maHref.isEmpty() )
3254 if (INetURLObject(maHref).IsExoticProtocol())
3255 GetImport().NotifyMacroEventRead();
3257 xProps->setPropertyValue(u"FrameURL"_ustr, Any(maHref) );
3261 SetStyle();
3263 GetImport().GetShapeImport()->finishShape( mxShape, mxAttrList, mxShapes );
3266 // this is called from the parent group for each unparsed attribute in the attribute list
3267 bool SdXMLFloatingFrameShapeContext::processAttribute( const sax_fastparser::FastAttributeList::FastAttributeIter & aIter )
3269 switch( aIter.getToken() )
3271 case XML_ELEMENT(DRAW, XML_FRAME_NAME):
3272 maFrameName = aIter.toString();
3273 break;
3274 case XML_ELEMENT(XLINK, XML_HREF):
3275 maHref = GetImport().GetAbsoluteReference(aIter.toString());
3276 break;
3277 default:
3278 return SdXMLShapeContext::processAttribute( aIter );
3280 return true;
3283 void SdXMLFloatingFrameShapeContext::endFastElement(sal_Int32 nElement)
3285 uno::Reference< beans::XPropertySet > xProps( mxShape, uno::UNO_QUERY );
3287 if( xProps.is() )
3289 if ( maSize.Width && maSize.Height )
3291 // the visual area for a floating frame must be set on loading
3292 awt::Rectangle aRect( 0, 0, maSize.Width, maSize.Height );
3293 xProps->setPropertyValue(u"VisibleArea"_ustr, Any(aRect) );
3297 SetThumbnail();
3298 SdXMLShapeContext::endFastElement(nElement);
3302 SdXMLFrameShapeContext::SdXMLFrameShapeContext( SvXMLImport& rImport,
3303 const css::uno::Reference< css::xml::sax::XFastAttributeList>& xAttrList,
3304 css::uno::Reference< css::drawing::XShapes > const & rShapes,
3305 bool bTemporaryShape)
3306 : SdXMLShapeContext( rImport, xAttrList, rShapes, bTemporaryShape ),
3307 mbSupportsReplacement( false )
3309 uno::Reference < util::XCloneable > xClone( xAttrList, uno::UNO_QUERY );
3310 if( xClone.is() )
3311 mxAttrList.set( xClone->createClone(), uno::UNO_QUERY );
3312 else
3313 mxAttrList = new sax_fastparser::FastAttributeList(xAttrList);
3316 SdXMLFrameShapeContext::~SdXMLFrameShapeContext()
3320 void SdXMLFrameShapeContext::removeGraphicFromImportContext(const SvXMLImportContext& rContext)
3322 const SdXMLGraphicObjectShapeContext* pSdXMLGraphicObjectShapeContext = dynamic_cast< const SdXMLGraphicObjectShapeContext* >(&rContext);
3324 if(!pSdXMLGraphicObjectShapeContext)
3325 return;
3329 uno::Reference< container::XChild > xChild(pSdXMLGraphicObjectShapeContext->getShape(), uno::UNO_QUERY_THROW);
3331 uno::Reference< drawing::XShapes > xParent(xChild->getParent(), uno::UNO_QUERY_THROW);
3333 // remove from parent
3334 xParent->remove(pSdXMLGraphicObjectShapeContext->getShape());
3336 // dispose
3337 uno::Reference< lang::XComponent > xComp(pSdXMLGraphicObjectShapeContext->getShape(), UNO_QUERY);
3339 if(xComp.is())
3341 xComp->dispose();
3344 catch( uno::Exception& )
3346 DBG_UNHANDLED_EXCEPTION( "xmloff", "Error in cleanup of multiple graphic object import." );
3350 namespace
3352 uno::Reference<beans::XPropertySet> getGraphicPropertySetFromImportContext(const SvXMLImportContext& rContext)
3354 uno::Reference<beans::XPropertySet> aPropertySet;
3355 const SdXMLGraphicObjectShapeContext* pSdXMLGraphicObjectShapeContext = dynamic_cast<const SdXMLGraphicObjectShapeContext*>(&rContext);
3357 if (pSdXMLGraphicObjectShapeContext)
3358 aPropertySet.set(pSdXMLGraphicObjectShapeContext->getShape(), uno::UNO_QUERY);
3360 return aPropertySet;
3363 } // end anonymous namespace
3365 uno::Reference<graphic::XGraphic> SdXMLFrameShapeContext::getGraphicFromImportContext(const SvXMLImportContext& rContext) const
3367 uno::Reference<graphic::XGraphic> xGraphic;
3370 const uno::Reference<beans::XPropertySet> xPropertySet = getGraphicPropertySetFromImportContext(rContext);
3372 if (xPropertySet.is())
3374 xPropertySet->getPropertyValue(u"Graphic"_ustr) >>= xGraphic;
3377 catch( uno::Exception& )
3379 DBG_UNHANDLED_EXCEPTION("xmloff", "Error in cleanup of multiple graphic object import.");
3382 return xGraphic;
3385 OUString SdXMLFrameShapeContext::getMimeTypeFromImportContext(const SvXMLImportContext& rContext) const
3387 OUString aMimeType;
3388 const SdXMLGraphicObjectShapeContext* pSdXMLGraphicObjectShapeContext = dynamic_cast<const SdXMLGraphicObjectShapeContext*>(&rContext);
3390 if (pSdXMLGraphicObjectShapeContext)
3391 aMimeType = pSdXMLGraphicObjectShapeContext->getMimeType();
3392 return aMimeType;
3395 OUString SdXMLFrameShapeContext::getGraphicPackageURLFromImportContext(const SvXMLImportContext& rContext) const
3397 OUString aRetval;
3398 const SdXMLGraphicObjectShapeContext* pSdXMLGraphicObjectShapeContext = dynamic_cast< const SdXMLGraphicObjectShapeContext* >(&rContext);
3400 if(pSdXMLGraphicObjectShapeContext)
3404 const uno::Reference< beans::XPropertySet > xPropSet(pSdXMLGraphicObjectShapeContext->getShape(), uno::UNO_QUERY_THROW);
3406 xPropSet->getPropertyValue(u"GraphicStreamURL"_ustr) >>= aRetval;
3408 catch( uno::Exception& )
3410 DBG_UNHANDLED_EXCEPTION( "xmloff", "Error in cleanup of multiple graphic object import." );
3414 return aRetval;
3417 css::uno::Reference< css::xml::sax::XFastContextHandler > SdXMLFrameShapeContext::createFastChildContext(
3418 sal_Int32 nElement,
3419 const uno::Reference< xml::sax::XFastAttributeList>& xAttrList )
3421 SvXMLImportContextRef xContext;
3422 if( !mxImplContext.is() )
3424 SvXMLShapeContext* pShapeContext = XMLShapeImportHelper::CreateFrameChildContext(
3425 GetImport(), nElement, xAttrList, mxShapes, mxAttrList );
3427 xContext = pShapeContext;
3429 // propagate the hyperlink to child context
3430 if ( !msHyperlink.isEmpty() )
3431 pShapeContext->setHyperlink( msHyperlink );
3433 auto nToken = nElement & TOKEN_MASK;
3434 bool bMedia = false;
3435 // Ignore gltf model if necessary and so the fallback image will be imported
3436 if( nToken == XML_PLUGIN )
3438 SdXMLPluginShapeContext* pPluginContext = dynamic_cast<SdXMLPluginShapeContext*>(pShapeContext);
3439 if( pPluginContext && pPluginContext->getMimeType() == "model/vnd.gltf+json" )
3441 mxImplContext = nullptr;
3442 return new SvXMLImportContext(GetImport());
3444 else if (pPluginContext && ::comphelper::IsMediaMimeType(pPluginContext->getMimeType()))
3446 // The media may have a preview, import it.
3447 bMedia = true;
3451 mxImplContext = xContext;
3452 mbSupportsReplacement = (nToken == XML_OBJECT ) || (nToken == XML_OBJECT_OLE) || bMedia;
3453 setSupportsMultipleContents(nToken == XML_IMAGE);
3455 if(getSupportsMultipleContents() && dynamic_cast< SdXMLGraphicObjectShapeContext* >(xContext.get()))
3457 if ( !maShapeId.isEmpty() )
3458 GetImport().getInterfaceToIdentifierMapper().reserveIdentifier( maShapeId );
3460 addContent(*mxImplContext);
3463 else if(getSupportsMultipleContents() && nElement == XML_ELEMENT(DRAW, XML_IMAGE))
3465 // read another image
3466 xContext = XMLShapeImportHelper::CreateFrameChildContext(
3467 GetImport(), nElement, xAttrList, mxShapes, mxAttrList);
3468 mxImplContext = xContext;
3470 if(dynamic_cast< SdXMLGraphicObjectShapeContext* >(xContext.get()))
3472 addContent(*mxImplContext);
3475 else if( mbSupportsReplacement && !mxReplImplContext.is() &&
3476 nElement == XML_ELEMENT(DRAW, XML_IMAGE) )
3478 // read replacement image
3479 SvXMLImportContext *pImplContext = mxImplContext.get();
3480 SdXMLShapeContext *pSContext =
3481 dynamic_cast<SdXMLShapeContext*>( pImplContext );
3482 if( pSContext )
3484 uno::Reference < beans::XPropertySet > xPropSet(
3485 pSContext->getShape(), uno::UNO_QUERY );
3486 if( xPropSet.is() )
3488 xContext = new XMLReplacementImageContext( GetImport(),
3489 nElement, xAttrList, xPropSet );
3490 mxReplImplContext = xContext;
3494 else if( nElement == XML_ELEMENT(SVG, XML_TITLE) || // #i68101#
3495 nElement == XML_ELEMENT(SVG_COMPAT, XML_TITLE) ||
3496 nElement == XML_ELEMENT(SVG, XML_DESC) ||
3497 nElement == XML_ELEMENT(SVG_COMPAT, XML_DESC) ||
3498 nElement == XML_ELEMENT(OFFICE, XML_EVENT_LISTENERS) ||
3499 nElement == XML_ELEMENT(DRAW, XML_GLUE_POINT) ||
3500 nElement == XML_ELEMENT(DRAW, XML_THUMBNAIL) )
3502 if (getSupportsMultipleContents())
3503 { // tdf#103567 ensure props are set on surviving shape
3504 // note: no more draw:image can be added once we get here
3505 mxImplContext = solveMultipleImages();
3507 SvXMLImportContext *pImplContext = mxImplContext.get();
3508 xContext = static_cast<SvXMLImportContext*>(dynamic_cast<SdXMLShapeContext&>(*pImplContext).createFastChildContext( nElement,
3509 xAttrList ).get());
3511 else if ( nElement == XML_ELEMENT(DRAW, XML_IMAGE_MAP) )
3513 if (getSupportsMultipleContents())
3514 { // tdf#103567 ensure props are set on surviving shape
3515 // note: no more draw:image can be added once we get here
3516 mxImplContext = solveMultipleImages();
3518 SdXMLShapeContext *pSContext = dynamic_cast< SdXMLShapeContext* >( mxImplContext.get() );
3519 if( pSContext )
3521 uno::Reference < beans::XPropertySet > xPropSet( pSContext->getShape(), uno::UNO_QUERY );
3522 if (xPropSet.is())
3524 xContext = new XMLImageMapContext(GetImport(), xPropSet);
3528 else if ( nElement == XML_ELEMENT(LO_EXT, XML_SIGNATURELINE) )
3530 SdXMLShapeContext* pSContext = dynamic_cast<SdXMLShapeContext*>(mxImplContext.get());
3531 if (pSContext)
3533 uno::Reference<beans::XPropertySet> xPropSet(pSContext->getShape(), uno::UNO_QUERY);
3534 if (xPropSet.is())
3536 xContext = new SignatureLineContext(GetImport(), nElement, xAttrList,
3537 pSContext->getShape());
3541 else if ( nElement == XML_ELEMENT(LO_EXT, XML_QRCODE))
3543 SdXMLShapeContext* pSContext = dynamic_cast<SdXMLShapeContext*>(mxImplContext.get());
3544 if (pSContext)
3546 uno::Reference<beans::XPropertySet> xPropSet(pSContext->getShape(), uno::UNO_QUERY);
3547 if (xPropSet.is())
3549 xContext = new QRCodeContext(GetImport(), nElement, xAttrList,
3550 pSContext->getShape());
3555 return xContext;
3558 void SdXMLFrameShapeContext::startFastElement (sal_Int32 /*nElement*/,
3559 const css::uno::Reference< css::xml::sax::XFastAttributeList >& /*xAttrList*/)
3561 // ignore
3564 void SdXMLFrameShapeContext::endFastElement(sal_Int32 nElement)
3566 // solve if multiple image child contexts were imported
3567 SvXMLImportContextRef const pSelectedContext(solveMultipleImages());
3568 const SdXMLGraphicObjectShapeContext* pShapeContext(
3569 dynamic_cast<const SdXMLGraphicObjectShapeContext*>(pSelectedContext.get()));
3570 if ( pShapeContext )
3572 assert( mxImplContext.is() );
3573 const uno::Reference< uno::XInterface > xShape( pShapeContext->getShape() );
3574 GetImport().getInterfaceToIdentifierMapper().registerReservedReference( maShapeId, xShape );
3577 if( !mxImplContext.is() )
3579 // now check if this is an empty presentation object
3580 for( auto& aIter : sax_fastparser::castToFastAttributeList(mxAttrList) )
3582 switch (aIter.getToken())
3584 case XML_ELEMENT(PRESENTATION, XML_PLACEHOLDER):
3585 mbIsPlaceholder = IsXMLToken( aIter, XML_TRUE );
3586 break;
3587 case XML_ELEMENT(PRESENTATION, XML_CLASS):
3588 maPresentationClass = aIter.toString();
3589 break;
3590 default:;
3594 if( (!maPresentationClass.isEmpty()) && mbIsPlaceholder )
3596 uno::Reference< xml::sax::XFastAttributeList> xEmpty;
3598 enum XMLTokenEnum eToken = XML_TEXT_BOX;
3600 if( IsXMLToken( maPresentationClass, XML_GRAPHIC ) )
3602 eToken = XML_IMAGE;
3605 else if( IsXMLToken( maPresentationClass, XML_PAGE ) )
3607 eToken = XML_PAGE_THUMBNAIL;
3609 else if( IsXMLToken( maPresentationClass, XML_CHART ) ||
3610 IsXMLToken( maPresentationClass, XML_TABLE ) ||
3611 IsXMLToken( maPresentationClass, XML_OBJECT ) )
3613 eToken = XML_OBJECT;
3616 auto x = XML_ELEMENT(DRAW, eToken);
3617 mxImplContext = XMLShapeImportHelper::CreateFrameChildContext(
3618 GetImport(), x, mxAttrList, mxShapes, xEmpty );
3620 if( mxImplContext.is() )
3622 mxImplContext->startFastElement( x, mxAttrList );
3623 mxImplContext->endFastElement(x);
3628 mxImplContext = nullptr;
3629 SdXMLShapeContext::endFastElement(nElement);
3632 bool SdXMLFrameShapeContext::processAttribute( const sax_fastparser::FastAttributeList::FastAttributeIter & aIter )
3634 bool bId( false );
3636 switch ( aIter.getToken() )
3638 case XML_ELEMENT(DRAW, XML_ID):
3639 case XML_ELEMENT(DRAW_EXT, XML_ID):
3640 case XML_ELEMENT(NONE, XML_ID):
3641 case XML_ELEMENT(XML, XML_ID) :
3642 bId = true;
3643 break;
3644 default:;
3647 if ( bId )
3648 return SdXMLShapeContext::processAttribute( aIter );
3649 return true; // deliberately ignoring other attributes
3653 SdXMLCustomShapeContext::SdXMLCustomShapeContext(
3654 SvXMLImport& rImport,
3655 const css::uno::Reference< css::xml::sax::XFastAttributeList>& xAttrList,
3656 uno::Reference< drawing::XShapes > const & rShapes)
3657 : SdXMLShapeContext( rImport, xAttrList, rShapes, false/*bTemporaryShape*/ )
3659 // See the XMLTextFrameContext ctor, a frame has Writer content (and not
3660 // editeng) if its autostyle has a parent style. Do the same for shapes as well.
3661 for( auto& aIter : sax_fastparser::castToFastAttributeList(xAttrList) )
3663 if (aIter.getToken() == XML_ELEMENT(DRAW, XML_STYLE_NAME))
3665 OUString aStyleName = aIter.toString();
3666 if(!aStyleName.isEmpty())
3668 rtl::Reference<XMLTextImportHelper> xTxtImport = GetImport().GetTextImport();
3669 XMLPropStyleContext* pStyle = xTxtImport->FindAutoFrameStyle(aStyleName);
3670 // Note that this an API name, so intentionally not localized.
3671 // Also allow other Frame styles with the same prefix, we just want to reject
3672 // Graphics after all.
3673 if (pStyle && pStyle->GetParentName().startsWith("Frame"))
3675 mbTextBox = true;
3676 break;
3683 SdXMLCustomShapeContext::~SdXMLCustomShapeContext()
3687 // this is called from the parent group for each unparsed attribute in the attribute list
3688 bool SdXMLCustomShapeContext::processAttribute( const sax_fastparser::FastAttributeList::FastAttributeIter & aIter )
3690 if( aIter.getToken() == XML_ELEMENT(DRAW, XML_ENGINE) )
3692 maCustomShapeEngine = aIter.toString();
3694 else if (aIter.getToken() == XML_ELEMENT(DRAW, XML_DATA) )
3696 maCustomShapeData = aIter.toString();
3698 else
3699 return SdXMLShapeContext::processAttribute( aIter );
3700 return true;
3703 void SdXMLCustomShapeContext::startFastElement (sal_Int32 nElement,
3704 const css::uno::Reference< css::xml::sax::XFastAttributeList >& xAttrList)
3706 // create rectangle shape
3707 AddShape(u"com.sun.star.drawing.CustomShape"_ustr);
3708 if ( !mxShape.is() )
3709 return;
3711 // Add, set Style and properties from base shape
3712 SetStyle();
3713 SetLayer();
3715 // set pos, size, shear and rotate
3716 SetTransformation();
3720 uno::Reference< beans::XPropertySet > xPropSet( mxShape, uno::UNO_QUERY );
3721 if( xPropSet.is() )
3723 if ( !maCustomShapeEngine.isEmpty() )
3725 xPropSet->setPropertyValue( EASGet( EAS_CustomShapeEngine ), Any(maCustomShapeEngine) );
3727 if ( !maCustomShapeData.isEmpty() )
3729 xPropSet->setPropertyValue( EASGet( EAS_CustomShapeData ), Any(maCustomShapeData) );
3733 catch(const uno::Exception&)
3735 DBG_UNHANDLED_EXCEPTION( "xmloff", "setting enhanced customshape geometry" );
3737 SdXMLShapeContext::startFastElement(nElement, xAttrList);
3740 void SdXMLCustomShapeContext::endFastElement(sal_Int32 nElement)
3742 // Customshapes remember mirror state in its enhanced geometry.
3743 // SetTransformation() in StartElement() may have applied mirroring, but that is not yet
3744 // contained. Merge that information here before writing the property.
3745 if(!maUsedTransformation.isIdentity())
3747 basegfx::B2DVector aScale, aTranslate;
3748 double fRotate, fShearX;
3750 maUsedTransformation.decompose(aScale, aTranslate, fRotate, fShearX);
3752 if (aScale.getX() < 0.0)
3754 static constexpr OUString sName(u"MirroredX"_ustr);
3755 //fdo#84043 Merge, if property exists, otherwise append it
3756 auto aI = std::find_if(maCustomShapeGeometry.begin(), maCustomShapeGeometry.end(),
3757 [](beans::PropertyValue& rValue) { return rValue.Name == sName; });
3758 if (aI != maCustomShapeGeometry.end())
3760 beans::PropertyValue& rItem = *aI;
3761 bool bMirroredX = *o3tl::doAccess<bool>(rItem.Value);
3762 rItem.Value <<= !bMirroredX;
3763 rItem.Handle = -1;
3764 rItem.State = beans::PropertyState_DIRECT_VALUE;
3766 else
3768 beans::PropertyValue* pItem;
3769 maCustomShapeGeometry.emplace_back();
3770 pItem = &maCustomShapeGeometry.back();
3771 pItem->Name = sName;
3772 pItem->Handle = -1;
3773 pItem->Value <<= true;
3774 pItem->State = beans::PropertyState_DIRECT_VALUE;
3778 if (aScale.getY() < 0.0)
3780 static constexpr OUString sName(u"MirroredY"_ustr);
3781 //fdo#84043 Merge, if property exists, otherwise append it
3782 auto aI = std::find_if(maCustomShapeGeometry.begin(), maCustomShapeGeometry.end(),
3783 [](beans::PropertyValue& rValue) { return rValue.Name == sName; });
3784 if (aI != maCustomShapeGeometry.end())
3786 beans::PropertyValue& rItem = *aI;
3787 bool bMirroredY = *o3tl::doAccess<bool>(rItem.Value);
3788 rItem.Value <<= !bMirroredY;
3789 rItem.Handle = -1;
3790 rItem.State = beans::PropertyState_DIRECT_VALUE;
3792 else
3794 beans::PropertyValue* pItem;
3795 maCustomShapeGeometry.emplace_back();
3796 pItem = &maCustomShapeGeometry.back();
3797 pItem->Name = sName;
3798 pItem->Handle = -1;
3799 pItem->Value <<= true;
3800 pItem->State = beans::PropertyState_DIRECT_VALUE;
3805 if ( !maCustomShapeGeometry.empty() )
3807 // converting the vector to a sequence
3808 uno::Sequence< beans::PropertyValue > aSeq( comphelper::containerToSequence(maCustomShapeGeometry) );
3812 uno::Reference< beans::XPropertySet > xPropSet( mxShape, uno::UNO_QUERY );
3813 if( xPropSet.is() )
3815 xPropSet->setPropertyValue( u"CustomShapeGeometry"_ustr, Any(aSeq) );
3818 catch(const uno::Exception&)
3820 DBG_UNHANDLED_EXCEPTION( "xmloff", "setting enhanced customshape geometry" );
3823 sal_Int32 nUPD;
3824 sal_Int32 nBuild;
3825 if (GetImport().getBuildIds(nUPD, nBuild))
3827 if( ((nUPD >= 640 && nUPD <= 645) || (nUPD == 680)) && (nBuild <= 9221) )
3829 Reference< drawing::XEnhancedCustomShapeDefaulter > xDefaulter( mxShape, UNO_QUERY );
3830 if( xDefaulter.is() )
3832 xDefaulter->createCustomShapeDefaults( u""_ustr );
3838 SdXMLShapeContext::endFastElement(nElement);
3840 // tdf#98163 call a custom slot to be able to reset the UNO API
3841 // implementations held on the SdrObjects of type
3842 // SdrObjCustomShape - those tend to linger until the entire file
3843 // is loaded. For large files with a lot of these, 32bit systems
3844 // may crash due to being out of resources after ca. 4200
3845 // Outliners and VirtualDevices used there as RefDevice
3848 uno::Reference< beans::XPropertySet > xPropSet(mxShape, uno::UNO_QUERY);
3850 if(xPropSet.is())
3852 xPropSet->setPropertyValue(
3853 u"FlushCustomShapeUnoApiObjects"_ustr, css::uno::Any(true));
3856 catch(const uno::Exception&)
3858 DBG_UNHANDLED_EXCEPTION("xmloff", "flushing after load");
3862 css::uno::Reference< css::xml::sax::XFastContextHandler > SdXMLCustomShapeContext::createFastChildContext(
3863 sal_Int32 nElement,
3864 const uno::Reference< xml::sax::XFastAttributeList>& xAttrList )
3866 css::uno::Reference< css::xml::sax::XFastContextHandler > xContext;
3867 if ( nElement == XML_ELEMENT(DRAW, XML_ENHANCED_GEOMETRY) )
3869 uno::Reference< beans::XPropertySet > xPropSet( mxShape,uno::UNO_QUERY );
3870 if ( xPropSet.is() )
3871 xContext = new XMLEnhancedCustomShapeContext( GetImport(), mxShape, maCustomShapeGeometry );
3873 // delegate to parent class if no context could be created
3874 if (!xContext)
3875 xContext = SdXMLShapeContext::createFastChildContext( nElement,
3876 xAttrList);
3877 return xContext;
3880 SdXMLTableShapeContext::SdXMLTableShapeContext( SvXMLImport& rImport, const css::uno::Reference< css::xml::sax::XFastAttributeList>& xAttrList, css::uno::Reference< css::drawing::XShapes > const & rShapes )
3881 : SdXMLShapeContext( rImport, xAttrList, rShapes, false )
3885 SdXMLTableShapeContext::~SdXMLTableShapeContext()
3889 void SdXMLTableShapeContext::startFastElement (sal_Int32 nElement,
3890 const css::uno::Reference< css::xml::sax::XFastAttributeList >& xAttrList)
3892 OUString service(u"com.sun.star.drawing.TableShape"_ustr);
3894 bool bIsPresShape = !maPresentationClass.isEmpty() && GetImport().GetShapeImport()->IsPresentationShapesSupported();
3895 if( bIsPresShape )
3897 if( IsXMLToken( maPresentationClass, XML_TABLE ) )
3899 service = "com.sun.star.presentation.TableShape";
3903 AddShape(service);
3905 if( !mxShape.is() )
3906 return;
3908 SetLayer();
3910 uno::Reference< beans::XPropertySet > xProps(mxShape, uno::UNO_QUERY);
3912 if(bIsPresShape && xProps.is())
3914 uno::Reference< beans::XPropertySetInfo > xPropsInfo( xProps->getPropertySetInfo() );
3915 if( xPropsInfo.is() )
3917 if( !mbIsPlaceholder && xPropsInfo->hasPropertyByName(u"IsEmptyPresentationObject"_ustr))
3918 xProps->setPropertyValue(u"IsEmptyPresentationObject"_ustr, css::uno::Any(false) );
3920 if( mbIsUserTransformed && xPropsInfo->hasPropertyByName(u"IsPlaceholderDependent"_ustr))
3921 xProps->setPropertyValue(u"IsPlaceholderDependent"_ustr, css::uno::Any(false) );
3925 SetStyle();
3927 if( xProps.is() )
3929 if( !msTemplateStyleName.isEmpty() ) try
3931 Reference< XStyleFamiliesSupplier > xFamiliesSupp( GetImport().GetModel(), UNO_QUERY_THROW );
3932 Reference< XNameAccess > xFamilies( xFamiliesSupp->getStyleFamilies() );
3933 Reference< XNameAccess > xTableFamily( xFamilies->getByName( u"table"_ustr ), UNO_QUERY_THROW );
3934 Reference< XStyle > xTableStyle( xTableFamily->getByName( msTemplateStyleName ), UNO_QUERY_THROW );
3935 xProps->setPropertyValue(u"TableTemplate"_ustr, Any( xTableStyle ) );
3937 catch(const Exception&)
3939 DBG_UNHANDLED_EXCEPTION("xmloff.draw");
3942 const XMLPropertyMapEntry* pEntry = &aXMLTableShapeAttributes[0];
3943 for( int i = 0; !pEntry->IsEnd() && (i < 6); i++, pEntry++ )
3947 xProps->setPropertyValue( pEntry->getApiName(), Any( maTemplateStylesUsed[i] ) );
3949 catch(const Exception&)
3951 DBG_UNHANDLED_EXCEPTION("xmloff.draw");
3956 GetImport().GetShapeImport()->finishShape( mxShape, mxAttrList, mxShapes );
3958 const rtl::Reference< XMLTableImport >& xTableImport( GetImport().GetShapeImport()->GetShapeTableImport() );
3959 if( xTableImport.is() && xProps.is() )
3961 uno::Reference< table::XColumnRowRange > xColumnRowRange(
3962 xProps->getPropertyValue(u"Model"_ustr), uno::UNO_QUERY );
3964 if( xColumnRowRange.is() )
3965 mxTableImportContext = xTableImport->CreateTableContext( xColumnRowRange );
3967 if( mxTableImportContext.is() )
3968 mxTableImportContext->startFastElement( nElement, xAttrList );
3972 void SdXMLTableShapeContext::endFastElement(sal_Int32 nElement)
3974 if( mxTableImportContext.is() )
3975 mxTableImportContext->endFastElement(nElement);
3977 SdXMLShapeContext::endFastElement(nElement);
3979 if( mxShape.is() )
3981 // set pos, size, shear and rotate
3982 SetTransformation();
3986 // this is called from the parent group for each unparsed attribute in the attribute list
3987 bool SdXMLTableShapeContext::processAttribute( const sax_fastparser::FastAttributeList::FastAttributeIter & aIter )
3989 auto nElement = aIter.getToken();
3990 if( IsTokenInNamespace(nElement, XML_NAMESPACE_TABLE) )
3992 if( (nElement & TOKEN_MASK) == XML_TEMPLATE_NAME )
3994 msTemplateStyleName = aIter.toString();
3996 else
3998 int i = 0;
3999 const XMLPropertyMapEntry* pEntry = &aXMLTableShapeAttributes[0];
4000 while( !pEntry->IsEnd() && (i < 6) )
4002 if( (nElement & TOKEN_MASK) == pEntry->meXMLName )
4004 if( IsXMLToken( aIter, XML_TRUE ) )
4005 maTemplateStylesUsed[i] = true;
4006 break;
4008 pEntry++;
4009 i++;
4013 return SdXMLShapeContext::processAttribute( aIter );
4016 css::uno::Reference< css::xml::sax::XFastContextHandler > SdXMLTableShapeContext::createFastChildContext(
4017 sal_Int32 nElement,
4018 const css::uno::Reference< css::xml::sax::XFastAttributeList >& xAttrList )
4020 if( mxTableImportContext.is() && IsTokenInNamespace(nElement, XML_NAMESPACE_TABLE) )
4021 return mxTableImportContext->createFastChildContext(nElement, xAttrList);
4022 return SdXMLShapeContext::createFastChildContext(nElement, xAttrList);
4025 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */