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