1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
20 #include <config_wasm_strip.h>
22 #include <basegfx/matrix/b2dhommatrix.hxx>
23 #include <basegfx/matrix/b3dhommatrix.hxx>
24 #include <basegfx/polygon/b2dpolypolygon.hxx>
25 #include <basegfx/polygon/b2dpolypolygontools.hxx>
26 #include <basegfx/polygon/b2dpolygontools.hxx>
27 #include <basegfx/polygon/b3dpolypolygon.hxx>
28 #include <basegfx/polygon/b3dpolypolygontools.hxx>
29 #include <basegfx/tuple/b2dtuple.hxx>
30 #include <basegfx/vector/b3dvector.hxx>
32 #include <com/sun/star/beans/XPropertyState.hpp>
33 #include <com/sun/star/beans/PropertyValues.hpp>
34 #include <com/sun/star/container/XChild.hpp>
35 #include <com/sun/star/container/XEnumerationAccess.hpp>
36 #include <com/sun/star/container/XIdentifierAccess.hpp>
37 #include <com/sun/star/container/XNamed.hpp>
38 #include <com/sun/star/document/XEventsSupplier.hpp>
39 #include <com/sun/star/drawing/Alignment.hpp>
40 #include <com/sun/star/drawing/CameraGeometry.hpp>
41 #include <com/sun/star/drawing/CircleKind.hpp>
42 #include <com/sun/star/drawing/ConnectorType.hpp>
43 #include <com/sun/star/drawing/Direction3D.hpp>
44 #include <com/sun/star/drawing/EscapeDirection.hpp>
45 #include <com/sun/star/drawing/EnhancedCustomShapeAdjustmentValue.hpp>
46 #include <com/sun/star/drawing/EnhancedCustomShapeGluePointType.hpp>
47 #include <com/sun/star/drawing/EnhancedCustomShapeParameterPair.hpp>
48 #include <com/sun/star/drawing/EnhancedCustomShapeParameterType.hpp>
49 #include <com/sun/star/drawing/EnhancedCustomShapeMetalType.hpp>
50 #include <com/sun/star/drawing/EnhancedCustomShapeSegment.hpp>
51 #include <com/sun/star/drawing/EnhancedCustomShapeSegmentCommand.hpp>
52 #include <com/sun/star/drawing/EnhancedCustomShapeTextFrame.hpp>
53 #include <com/sun/star/drawing/EnhancedCustomShapeTextPathMode.hpp>
54 #include <com/sun/star/drawing/GluePoint2.hpp>
55 #include <com/sun/star/drawing/HomogenMatrix.hpp>
56 #include <com/sun/star/drawing/HomogenMatrix3.hpp>
57 #include <com/sun/star/drawing/PolyPolygonBezierCoords.hpp>
58 #include <com/sun/star/drawing/PolyPolygonShape3D.hpp>
59 #include <com/sun/star/drawing/Position3D.hpp>
60 #include <com/sun/star/drawing/ProjectionMode.hpp>
61 #include <com/sun/star/drawing/ShadeMode.hpp>
62 #include <com/sun/star/drawing/XControlShape.hpp>
63 #include <com/sun/star/drawing/XCustomShapeEngine.hpp>
64 #include <com/sun/star/drawing/XGluePointsSupplier.hpp>
65 #include <com/sun/star/drawing/BarCode.hpp>
66 #include <com/sun/star/drawing/BarCodeErrorCorrection.hpp>
67 #include <com/sun/star/drawing/XShapes3.hpp>
68 #include <com/sun/star/embed/ElementModes.hpp>
69 #include <com/sun/star/embed/XStorage.hpp>
70 #include <com/sun/star/embed/XTransactedObject.hpp>
71 #include <com/sun/star/graphic/XGraphic.hpp>
72 #include <com/sun/star/graphic/GraphicProvider.hpp>
73 #include <com/sun/star/graphic/XGraphicProvider.hpp>
74 #include <com/sun/star/io/XSeekableInputStream.hpp>
75 #include <com/sun/star/io/XStream.hpp>
76 #include <com/sun/star/lang/ServiceNotRegisteredException.hpp>
77 #include <com/sun/star/lang/XMultiServiceFactory.hpp>
78 #include <com/sun/star/media/ZoomLevel.hpp>
79 #include <com/sun/star/presentation/AnimationSpeed.hpp>
80 #include <com/sun/star/presentation/ClickAction.hpp>
81 #include <com/sun/star/style/XStyle.hpp>
82 #include <com/sun/star/table/XColumnRowRange.hpp>
83 #include <com/sun/star/text/WritingMode2.hpp>
84 #include <com/sun/star/text/XText.hpp>
86 #include <comphelper/classids.hxx>
87 #include <comphelper/processfactory.hxx>
88 #include <comphelper/propertyvalue.hxx>
89 #include <comphelper/storagehelper.hxx>
90 #include <officecfg/Office/Common.hxx>
92 #include <o3tl/any.hxx>
93 #include <o3tl/typed_flags_set.hxx>
94 #include <o3tl/string_view.hxx>
96 #include <rtl/math.hxx>
97 #include <rtl/ustrbuf.hxx>
98 #include <rtl/ustring.hxx>
99 #include <sal/log.hxx>
101 #include <sax/tools/converter.hxx>
103 #include <tools/debug.hxx>
104 #include <tools/globname.hxx>
105 #include <tools/helpers.hxx>
106 #include <comphelper/diagnose_ex.hxx>
107 #include <vcl/graph.hxx>
109 #include <xmloff/contextid.hxx>
110 #include <xmloff/families.hxx>
111 #include <xmloff/namespacemap.hxx>
112 #include <xmloff/shapeexport.hxx>
113 #include <xmloff/unointerfacetouniqueidentifiermapper.hxx>
114 #include <xmloff/xmlexp.hxx>
115 #include <xmloff/xmlnamespace.hxx>
116 #include <xmloff/xmltoken.hxx>
117 #include <xmloff/xmluconv.hxx>
118 #include <xmloff/table/XMLTableExport.hxx>
119 #include <xmloff/ProgressBarHelper.hxx>
122 #include <EnhancedCustomShapeToken.hxx>
123 #include "sdpropls.hxx"
124 #include <xexptran.hxx>
125 #include "ximpshap.hxx"
126 #include <XMLBase64Export.hxx>
127 #include <XMLImageMapExport.hxx>
130 using namespace ::com::sun::star
;
131 using namespace ::xmloff::EnhancedCustomShapeToken
;
132 using namespace ::xmloff::token
;
134 constexpr OUStringLiteral XML_EMBEDDEDOBJECTGRAPHIC_URL_BASE
= u
"vnd.sun.star.GraphicObject:";
138 bool supportsText(XmlShapeType eShapeType
)
140 return eShapeType
!= XmlShapeType::PresChartShape
&&
141 eShapeType
!= XmlShapeType::PresOLE2Shape
&&
142 eShapeType
!= XmlShapeType::DrawSheetShape
&&
143 eShapeType
!= XmlShapeType::PresSheetShape
&&
144 eShapeType
!= XmlShapeType::Draw3DSceneObject
&&
145 eShapeType
!= XmlShapeType::Draw3DCubeObject
&&
146 eShapeType
!= XmlShapeType::Draw3DSphereObject
&&
147 eShapeType
!= XmlShapeType::Draw3DLatheObject
&&
148 eShapeType
!= XmlShapeType::Draw3DExtrudeObject
&&
149 eShapeType
!= XmlShapeType::DrawPageShape
&&
150 eShapeType
!= XmlShapeType::PresPageShape
&&
151 eShapeType
!= XmlShapeType::DrawGroupShape
;
157 constexpr OUString
gsZIndex( u
"ZOrder"_ustr
);
158 constexpr OUStringLiteral
gsPrintable( u
"Printable" );
159 constexpr OUStringLiteral
gsVisible( u
"Visible" );
160 constexpr OUString
gsModel( u
"Model"_ustr
);
161 constexpr OUStringLiteral
gsStartShape( u
"StartShape" );
162 constexpr OUStringLiteral
gsEndShape( u
"EndShape" );
163 constexpr OUString
gsOnClick( u
"OnClick"_ustr
);
164 constexpr OUStringLiteral
gsEventType( u
"EventType" );
165 constexpr OUStringLiteral
gsPresentation( u
"Presentation" );
166 constexpr OUStringLiteral
gsMacroName( u
"MacroName" );
167 constexpr OUString
gsScript( u
"Script"_ustr
);
168 constexpr OUStringLiteral
gsLibrary( u
"Library" );
169 constexpr OUStringLiteral
gsClickAction( u
"ClickAction" );
170 constexpr OUString
gsBookmark( u
"Bookmark"_ustr
);
171 constexpr OUStringLiteral
gsEffect( u
"Effect" );
172 constexpr OUStringLiteral
gsPlayFull( u
"PlayFull" );
173 constexpr OUStringLiteral
gsVerb( u
"Verb" );
174 constexpr OUStringLiteral
gsSoundURL( u
"SoundURL" );
175 constexpr OUStringLiteral
gsSpeed( u
"Speed" );
176 constexpr OUStringLiteral
gsStarBasic( u
"StarBasic" );
177 constexpr OUStringLiteral
gsHyperlink( u
"Hyperlink" );
179 XMLShapeExport::XMLShapeExport(SvXMLExport
& rExp
,
180 SvXMLExportPropertyMapper
*pExtMapper
)
182 maCurrentShapesIter(maShapesInfos
.end()),
183 mbExportLayer( false ),
184 // #88546# init to sal_False
185 mbHandleProgressBar( false )
187 // construct PropertySetMapper
188 mxPropertySetMapper
= CreateShapePropMapper( mrExport
);
191 rtl::Reference
< SvXMLExportPropertyMapper
> xExtMapper( pExtMapper
);
192 mxPropertySetMapper
->ChainExportMapper( xExtMapper
);
196 // chain text attributes
197 xPropertySetMapper->ChainExportMapper(XMLTextParagraphExport::CreateParaExtPropMapper(rExp));
200 mrExport
.GetAutoStylePool()->AddFamily(
201 XmlStyleFamily::SD_GRAPHICS_ID
,
202 XML_STYLE_FAMILY_SD_GRAPHICS_NAME
,
203 GetPropertySetMapper(),
204 XML_STYLE_FAMILY_SD_GRAPHICS_PREFIX
);
205 mrExport
.GetAutoStylePool()->AddFamily(
206 XmlStyleFamily::SD_PRESENTATION_ID
,
207 XML_STYLE_FAMILY_SD_PRESENTATION_NAME
,
208 GetPropertySetMapper(),
209 XML_STYLE_FAMILY_SD_PRESENTATION_PREFIX
);
211 // create table export helper and let him add his families in time
212 GetShapeTableExport();
215 XMLShapeExport::~XMLShapeExport()
219 // sj: replacing CustomShapes with standard objects that are also supported in OpenOffice.org format
220 uno::Reference
< drawing::XShape
> XMLShapeExport::checkForCustomShapeReplacement( const uno::Reference
< drawing::XShape
>& xShape
)
222 uno::Reference
< drawing::XShape
> xCustomShapeReplacement
;
224 if( !( GetExport().getExportFlags() & SvXMLExportFlags::OASIS
) )
226 OUString
aType( xShape
->getShapeType() );
227 if( aType
== "com.sun.star.drawing.CustomShape" )
229 uno::Reference
< beans::XPropertySet
> xSet( xShape
, uno::UNO_QUERY
);
233 xSet
->getPropertyValue("CustomShapeEngine") >>= aEngine
;
234 if ( aEngine
.isEmpty() )
236 aEngine
= "com.sun.star.drawing.EnhancedCustomShapeEngine";
238 uno::Reference
< uno::XComponentContext
> xContext( ::comphelper::getProcessComponentContext() );
240 if ( !aEngine
.isEmpty() )
242 uno::Sequence
< beans::PropertyValue
> aPropValues
{
243 comphelper::makePropertyValue("CustomShape", xShape
),
244 comphelper::makePropertyValue("ForceGroupWithText", true)
246 uno::Sequence
< uno::Any
> aArgument
= { uno::Any(aPropValues
) };
247 uno::Reference
< uno::XInterface
> xInterface(
248 xContext
->getServiceManager()->createInstanceWithArgumentsAndContext(aEngine
, aArgument
, xContext
) );
249 if ( xInterface
.is() )
251 uno::Reference
< drawing::XCustomShapeEngine
> xCustomShapeEngine(
252 uno::Reference
< drawing::XCustomShapeEngine
>( xInterface
, uno::UNO_QUERY
) );
253 if ( xCustomShapeEngine
.is() )
254 xCustomShapeReplacement
= xCustomShapeEngine
->render();
260 return xCustomShapeReplacement
;
263 // This method collects all automatic styles for the given XShape
264 void XMLShapeExport::collectShapeAutoStyles(const uno::Reference
< drawing::XShape
>& xShape
)
266 if( maCurrentShapesIter
== maShapesInfos
.end() )
268 OSL_FAIL( "XMLShapeExport::collectShapeAutoStyles(): no call to seekShapes()!" );
271 sal_Int32 nZIndex
= 0;
272 uno::Reference
< beans::XPropertySet
> xPropSet(xShape
, uno::UNO_QUERY
);
274 xPropSet
->getPropertyValue(gsZIndex
) >>= nZIndex
;
276 ImplXMLShapeExportInfoVector
& aShapeInfoVector
= (*maCurrentShapesIter
).second
;
278 if( static_cast<sal_Int32
>(aShapeInfoVector
.size()) <= nZIndex
)
280 OSL_FAIL( "XMLShapeExport::collectShapeAutoStyles(): no shape info allocated for a given shape" );
284 ImplXMLShapeExportInfo
& aShapeInfo
= aShapeInfoVector
[nZIndex
];
286 uno::Reference
< drawing::XShape
> xCustomShapeReplacement
= checkForCustomShapeReplacement( xShape
);
287 if ( xCustomShapeReplacement
.is() )
288 aShapeInfo
.xCustomShapeReplacement
= xCustomShapeReplacement
;
290 // first compute the shapes type
291 ImpCalcShapeType(xShape
, aShapeInfo
.meShapeType
);
293 // #i118485# enabled XmlShapeType::DrawChartShape and XmlShapeType::DrawOLE2Shape
295 const bool bObjSupportsText
=
296 supportsText(aShapeInfo
.meShapeType
);
298 const bool bObjSupportsStyle
=
299 aShapeInfo
.meShapeType
!= XmlShapeType::DrawGroupShape
;
301 bool bIsEmptyPresObj
= false;
303 if ( aShapeInfo
.xCustomShapeReplacement
.is() )
307 if( xPropSet
.is() && bObjSupportsText
)
309 uno::Reference
< text::XText
> xText(xShape
, uno::UNO_QUERY
);
314 // tdf#153161: it seems that the call to XTextRange::getString flushes the changes
315 // for some objects, that otherwise fail to get exported correctly. Maybe at some
316 // point it would make sense to find a better place for more targeted flush.
319 catch (uno::RuntimeException
const&)
321 // E.g., SwXTextFrame that contains only a table will throw; this is not an error
324 uno::Reference
< beans::XPropertySetInfo
> xPropSetInfo( xPropSet
->getPropertySetInfo() );
326 if( xPropSetInfo
.is() && xPropSetInfo
->hasPropertyByName("IsEmptyPresentationObject") )
328 uno::Any aAny
= xPropSet
->getPropertyValue("IsEmptyPresentationObject");
329 aAny
>>= bIsEmptyPresObj
;
334 GetExport().GetTextParagraphExport()->collectTextAutoStyles( xText
);
339 // compute the shape parent style
342 uno::Reference
< beans::XPropertySetInfo
> xPropertySetInfo( xPropSet
->getPropertySetInfo() );
344 OUString aParentName
;
345 uno::Reference
< style::XStyle
> xStyle
;
347 if( bObjSupportsStyle
)
349 if( xPropertySetInfo
.is() && xPropertySetInfo
->hasPropertyByName("Style") )
350 xPropSet
->getPropertyValue("Style") >>= xStyle
;
355 uno::Reference
< beans::XPropertySet
> xStylePropSet(xStyle
, uno::UNO_QUERY
);
356 SAL_WARN_IF( !xStylePropSet
.is(), "xmloff", "style without a XPropertySet?" );
359 if(xStylePropSet
.is())
361 OUString aFamilyName
;
362 xStylePropSet
->getPropertyValue("Family") >>= aFamilyName
;
363 if( !aFamilyName
.isEmpty() && aFamilyName
!= "graphics" )
364 aShapeInfo
.mnFamily
= XmlStyleFamily::SD_PRESENTATION_ID
;
367 catch(const beans::UnknownPropertyException
&)
371 "XMLShapeExport::collectShapeAutoStyles: style has no 'Family' property");
374 // get parent-style name
375 if(XmlStyleFamily::SD_PRESENTATION_ID
== aShapeInfo
.mnFamily
)
377 aParentName
= msPresentationStylePrefix
;
380 aParentName
+= xStyle
->getName();
384 if (aParentName
.isEmpty() && xPropertySetInfo
->hasPropertyByName("TextBox") && xPropSet
->getPropertyValue("TextBox").hasValue() && xPropSet
->getPropertyValue("TextBox").get
<bool>())
386 // Shapes with a Writer TextBox always have a parent style.
387 // If there would be none, then assign the default one.
388 aParentName
= "Frame";
392 std::vector
< XMLPropertyState
> aPropStates
;
394 sal_Int32 nCount
= 0;
395 if( !bIsEmptyPresObj
|| (aShapeInfo
.meShapeType
!= XmlShapeType::PresPageShape
) )
397 aPropStates
= GetPropertySetMapper()->Filter(mrExport
, xPropSet
);
399 if (XmlShapeType::DrawControlShape
== aShapeInfo
.meShapeType
)
401 // for control shapes, we additionally need the number format style (if any)
402 uno::Reference
< drawing::XControlShape
> xControl(xShape
, uno::UNO_QUERY
);
403 DBG_ASSERT(xControl
.is(), "XMLShapeExport::collectShapeAutoStyles: ShapeType control, but no XControlShape!");
406 uno::Reference
< beans::XPropertySet
> xControlModel(xControl
->getControl(), uno::UNO_QUERY
);
407 DBG_ASSERT(xControlModel
.is(), "XMLShapeExport::collectShapeAutoStyles: no control model on the control shape!");
409 OUString sNumberStyle
= mrExport
.GetFormExport()->getControlNumberStyle(xControlModel
);
410 if (!sNumberStyle
.isEmpty())
412 sal_Int32 nIndex
= GetPropertySetMapper()->getPropertySetMapper()->FindEntryIndex(CTF_SD_CONTROL_SHAPE_DATA_STYLE
);
413 // TODO : this retrieval of the index could be moved into the ctor, holding the index
414 // as member, thus saving time.
415 DBG_ASSERT(-1 != nIndex
, "XMLShapeExport::collectShapeAutoStyles: could not obtain the index for our context id!");
417 XMLPropertyState
aNewState(nIndex
, uno::Any(sNumberStyle
));
418 aPropStates
.push_back(aNewState
);
423 nCount
= std::count_if(aPropStates
.cbegin(), aPropStates
.cend(),
424 [](const XMLPropertyState
& rProp
) { return rProp
.mnIndex
!= -1; });
429 // no hard attributes, use parent style name for export
430 aShapeInfo
.msStyleName
= aParentName
;
434 // there are filtered properties -> hard attributes
435 // try to find this style in AutoStylePool
436 aShapeInfo
.msStyleName
= mrExport
.GetAutoStylePool()->Find(aShapeInfo
.mnFamily
, aParentName
, aPropStates
);
438 if(aShapeInfo
.msStyleName
.isEmpty())
440 // Style did not exist, add it to AutoStalePool
441 aShapeInfo
.msStyleName
= mrExport
.GetAutoStylePool()->Add(aShapeInfo
.mnFamily
, aParentName
, std::move(aPropStates
));
445 // optionally generate auto style for text attributes
446 if( (!bIsEmptyPresObj
|| (aShapeInfo
.meShapeType
!= XmlShapeType::PresPageShape
)) && bObjSupportsText
)
448 aPropStates
= GetExport().GetTextParagraphExport()->GetParagraphPropertyMapper()->Filter(mrExport
, xPropSet
);
450 // yet more additionally, we need to care for the ParaAdjust property
451 if ( XmlShapeType::DrawControlShape
== aShapeInfo
.meShapeType
)
453 uno::Reference
< beans::XPropertySetInfo
> xPropSetInfo( xPropSet
->getPropertySetInfo() );
454 uno::Reference
< beans::XPropertyState
> xPropState( xPropSet
, uno::UNO_QUERY
);
455 if ( xPropSetInfo
.is() && xPropState
.is() )
458 // * if controls shapes have a ParaAdjust property, then this is the Align property of the control model
459 // * control models are allowed to have an Align of "void"
460 // * the Default for control model's Align is TextAlign_LEFT
461 // * defaults for style properties are not written, but we need to write the "left",
462 // because we need to distinguish this "left" from the case where not align attribute
463 // is present which means "void"
464 if ( xPropSetInfo
->hasPropertyByName( "ParaAdjust" )
465 && ( beans::PropertyState_DEFAULT_VALUE
== xPropState
->getPropertyState( "ParaAdjust" ) )
468 sal_Int32 nIndex
= GetExport().GetTextParagraphExport()->GetParagraphPropertyMapper()->getPropertySetMapper()->FindEntryIndex( CTF_SD_SHAPE_PARA_ADJUST
);
469 // TODO : this retrieval of the index should be moved into the ctor, holding the index
470 // as member, thus saving time.
471 DBG_ASSERT(-1 != nIndex
, "XMLShapeExport::collectShapeAutoStyles: could not obtain the index for the ParaAdjust context id!");
473 uno::Any aParaAdjustValue
= xPropSet
->getPropertyValue( "ParaAdjust" );
474 XMLPropertyState
aAlignDefaultState( nIndex
, aParaAdjustValue
);
476 aPropStates
.push_back( aAlignDefaultState
);
481 nCount
= std::count_if(aPropStates
.cbegin(), aPropStates
.cend(),
482 [](const XMLPropertyState
& rProp
) { return rProp
.mnIndex
!= -1; });
486 aShapeInfo
.msTextStyleName
= mrExport
.GetAutoStylePool()->Find( XmlStyleFamily::TEXT_PARAGRAPH
, "", aPropStates
);
487 if(aShapeInfo
.msTextStyleName
.isEmpty())
489 // Style did not exist, add it to AutoStalePool
490 aShapeInfo
.msTextStyleName
= mrExport
.GetAutoStylePool()->Add(XmlStyleFamily::TEXT_PARAGRAPH
, "", std::move(aPropStates
));
496 // prepare animation information if needed
497 if( mxAnimationsExporter
.is() )
498 XMLAnimationsExporter::prepare( xShape
);
500 // check for special shapes
502 switch( aShapeInfo
.meShapeType
)
504 case XmlShapeType::DrawConnectorShape
:
506 uno::Reference
< uno::XInterface
> xConnection
;
508 // create shape ids for export later
509 xPropSet
->getPropertyValue( gsStartShape
) >>= xConnection
;
510 if( xConnection
.is() )
511 mrExport
.getInterfaceToIdentifierMapper().registerReference( xConnection
);
513 xPropSet
->getPropertyValue( gsEndShape
) >>= xConnection
;
514 if( xConnection
.is() )
515 mrExport
.getInterfaceToIdentifierMapper().registerReference( xConnection
);
518 case XmlShapeType::PresTableShape
:
519 case XmlShapeType::DrawTableShape
:
523 uno::Reference
< table::XColumnRowRange
> xRange( xPropSet
->getPropertyValue( gsModel
), uno::UNO_QUERY_THROW
);
524 GetShapeTableExport()->collectTableAutoStyles( xRange
);
526 catch(const uno::Exception
&)
528 DBG_UNHANDLED_EXCEPTION( "xmloff", "collecting auto styles for a table" );
536 // check for shape collections (group shape or 3d scene)
537 // and collect contained shapes style infos
538 const uno::Reference
< drawing::XShape
>& xCollection
= aShapeInfo
.xCustomShapeReplacement
.is()
539 ? aShapeInfo
.xCustomShapeReplacement
: xShape
;
541 uno::Reference
< drawing::XShapes
> xShapes( xCollection
, uno::UNO_QUERY
);
544 collectShapesAutoStyles( xShapes
);
551 class NewTextListsHelper
554 explicit NewTextListsHelper( SvXMLExport
& rExp
)
557 mrExport
.GetTextParagraphExport()->PushNewTextListsHelper();
560 ~NewTextListsHelper()
562 mrExport
.GetTextParagraphExport()->PopTextListsHelper();
566 SvXMLExport
& mrExport
;
569 // This method exports the given XShape
570 void XMLShapeExport::exportShape(const uno::Reference
< drawing::XShape
>& xShape
,
571 XMLShapeExportFlags nFeatures
/* = SEF_DEFAULT */,
572 css::awt::Point
* pRefPoint
/* = NULL */,
573 comphelper::AttributeList
* pAttrList
/* = NULL */ )
575 SAL_INFO("xmloff", xShape
->getShapeType());
576 if( maCurrentShapesIter
== maShapesInfos
.end() )
578 SAL_WARN( "xmloff", "XMLShapeExport::exportShape(): no auto styles where collected before export" );
581 sal_Int32 nZIndex
= 0;
582 uno::Reference
< beans::XPropertySet
> xSet( xShape
, uno::UNO_QUERY
);
586 xSet
->getPropertyValue(gsHyperlink
) >>= sHyperlink
;
588 catch (beans::UnknownPropertyException
)
592 std::unique_ptr
< SvXMLElementExport
> pHyperlinkElement
;
594 // Need to stash the attributes that are pre-loaded for the shape export
595 // (otherwise they will become attributes of the draw:a element)
596 uno::Reference
<xml::sax::XAttributeList
> xSaveAttribs(
597 new comphelper::AttributeList(GetExport().GetAttrList()));
598 GetExport().ClearAttrList();
599 if( xSet
.is() && (GetExport().GetModelType() == SvtModuleOptions::EFactory::DRAW
) )
601 // export hyperlinks with <a><shape/></a>. Currently only in draw since draw
602 // does not support document events
605 presentation::ClickAction eAction
= presentation::ClickAction_NONE
;
606 xSet
->getPropertyValue(gsOnClick
) >>= eAction
;
608 if( (eAction
== presentation::ClickAction_DOCUMENT
) ||
609 (eAction
== presentation::ClickAction_BOOKMARK
) )
612 xSet
->getPropertyValue(gsBookmark
) >>= sURL
;
614 if( !sURL
.isEmpty() )
616 mrExport
.AddAttribute( XML_NAMESPACE_XLINK
, XML_HREF
, sURL
);
617 mrExport
.AddAttribute( XML_NAMESPACE_XLINK
, XML_TYPE
, XML_SIMPLE
);
618 mrExport
.AddAttribute( XML_NAMESPACE_XLINK
, XML_SHOW
, XML_EMBED
);
619 pHyperlinkElement
.reset( new SvXMLElementExport(mrExport
, XML_NAMESPACE_DRAW
, XML_A
, true, true) );
623 catch(const uno::Exception
&)
625 TOOLS_WARN_EXCEPTION("xmloff", "XMLShapeExport::exportShape(): exception during hyperlink export");
628 else if (xSet
.is() && !sHyperlink
.isEmpty())
630 mrExport
.AddAttribute( XML_NAMESPACE_XLINK
, XML_HREF
, sHyperlink
);
631 mrExport
.AddAttribute( XML_NAMESPACE_XLINK
, XML_TYPE
, XML_SIMPLE
);
632 pHyperlinkElement
.reset( new SvXMLElementExport(mrExport
, XML_NAMESPACE_DRAW
, XML_A
, true, true) );
634 // re-add stashed attributes
635 GetExport().AddAttributeList(xSaveAttribs
);
638 xSet
->getPropertyValue(gsZIndex
) >>= nZIndex
;
640 ImplXMLShapeExportInfoVector
& aShapeInfoVector
= (*maCurrentShapesIter
).second
;
642 if( static_cast<sal_Int32
>(aShapeInfoVector
.size()) <= nZIndex
)
644 SAL_WARN( "xmloff", "XMLShapeExport::exportShape(): no shape info collected for a given shape" );
648 NewTextListsHelper
aNewTextListsHelper( mrExport
);
650 const ImplXMLShapeExportInfo
& aShapeInfo
= aShapeInfoVector
[nZIndex
];
653 // check if this is the correct ShapesInfo
654 uno::Reference
< container::XChild
> xChild( xShape
, uno::UNO_QUERY
);
657 uno::Reference
< drawing::XShapes
> xParent( xChild
->getParent(), uno::UNO_QUERY
);
658 SAL_WARN_IF( !xParent
.is() && xParent
.get() == (*maCurrentShapesIter
).first
.get(), "xmloff", "XMLShapeExport::exportShape(): Wrong call to XMLShapeExport::seekShapes()" );
661 // first compute the shapes type
663 XmlShapeType
eShapeType(XmlShapeType::NotYetSet
);
664 ImpCalcShapeType(xShape
, eShapeType
);
666 SAL_WARN_IF( eShapeType
!= aShapeInfo
.meShapeType
, "xmloff", "exportShape callings do not correspond to collectShapeAutoStyles calls!: " << xShape
->getShapeType() );
670 // collect animation information if needed
671 if( mxAnimationsExporter
.is() )
672 mxAnimationsExporter
->collect( xShape
, mrExport
);
674 /* Export shapes name if he has one (#i51726#)
675 Export of the shape name for text documents only if the OpenDocument
676 file format is written - exceptions are group shapes.
677 Note: Writer documents in OpenOffice.org file format doesn't contain
678 any names for shapes, except for group shapes.
681 if ( ( GetExport().GetModelType() != SvtModuleOptions::EFactory::WRITER
&&
682 GetExport().GetModelType() != SvtModuleOptions::EFactory::WRITERWEB
&&
683 GetExport().GetModelType() != SvtModuleOptions::EFactory::WRITERGLOBAL
) ||
684 ( GetExport().getExportFlags() & SvXMLExportFlags::OASIS
) ||
685 aShapeInfo
.meShapeType
== XmlShapeType::DrawGroupShape
||
686 ( aShapeInfo
.meShapeType
== XmlShapeType::DrawCustomShape
&&
687 aShapeInfo
.xCustomShapeReplacement
.is() ) )
689 uno::Reference
< container::XNamed
> xNamed( xShape
, uno::UNO_QUERY
);
692 const OUString
aName( xNamed
->getName() );
693 if( !aName
.isEmpty() )
694 mrExport
.AddAttribute(XML_NAMESPACE_DRAW
, XML_NAME
, aName
);
700 if( !aShapeInfo
.msStyleName
.isEmpty() )
702 if(XmlStyleFamily::SD_GRAPHICS_ID
== aShapeInfo
.mnFamily
)
703 mrExport
.AddAttribute(XML_NAMESPACE_DRAW
, XML_STYLE_NAME
, mrExport
.EncodeStyleName( aShapeInfo
.msStyleName
) );
705 mrExport
.AddAttribute(XML_NAMESPACE_PRESENTATION
, XML_STYLE_NAME
, mrExport
.EncodeStyleName( aShapeInfo
.msStyleName
) );
708 // export text style name
709 if( !aShapeInfo
.msTextStyleName
.isEmpty() )
711 mrExport
.AddAttribute(XML_NAMESPACE_DRAW
, XML_TEXT_STYLE_NAME
, aShapeInfo
.msTextStyleName
);
714 // export shapes id if needed
716 uno::Reference
< uno::XInterface
> xRef( xShape
, uno::UNO_QUERY
);
717 const OUString
& rShapeId
= mrExport
.getInterfaceToIdentifierMapper().getIdentifier( xRef
);
718 if( !rShapeId
.isEmpty() )
720 mrExport
.AddAttributeIdLegacy(XML_NAMESPACE_DRAW
, rShapeId
);
724 // export layer information
727 // check for group or scene shape and not export layer if this is one
728 uno::Reference
< drawing::XShapes
> xShapes( xShape
, uno::UNO_QUERY
);
733 uno::Reference
< beans::XPropertySet
> xProps( xShape
, uno::UNO_QUERY
);
735 xProps
->getPropertyValue("LayerName") >>= aLayerName
;
736 mrExport
.AddAttribute(XML_NAMESPACE_DRAW
, XML_LAYER
, aLayerName
);
739 catch(const uno::Exception
&)
741 DBG_UNHANDLED_EXCEPTION( "xmloff", "exporting layer name for shape" );
746 // export draw:display (do not export in ODF 1.3 or older)
747 if (xSet
.is() && (mrExport
.getSaneDefaultVersion() & SvtSaveOptions::ODFSVER_EXTENDED
))
749 if( aShapeInfo
.meShapeType
!= XmlShapeType::DrawPageShape
&& aShapeInfo
.meShapeType
!= XmlShapeType::PresPageShape
&&
750 aShapeInfo
.meShapeType
!= XmlShapeType::HandoutShape
&& aShapeInfo
.meShapeType
!= XmlShapeType::DrawChartShape
)
753 bool bVisible
= true;
754 bool bPrintable
= true;
756 xSet
->getPropertyValue(gsVisible
) >>= bVisible
;
757 xSet
->getPropertyValue(gsPrintable
) >>= bPrintable
;
759 XMLTokenEnum eDisplayToken
= XML_TOKEN_INVALID
;
760 const unsigned short nDisplay
= (bVisible
? 2 : 0) | (bPrintable
? 1 : 0);
763 case 0: eDisplayToken
= XML_NONE
; break;
764 case 1: eDisplayToken
= XML_PRINTER
; break;
765 case 2: eDisplayToken
= XML_SCREEN
; break;
766 // case 3: eDisplayToken = XML_ALWAYS break; this is the default
769 if( eDisplayToken
!= XML_TOKEN_INVALID
)
770 mrExport
.AddAttribute(XML_NAMESPACE_DRAW_EXT
, XML_DISPLAY
, eDisplayToken
);
772 catch(const uno::Exception
&)
774 DBG_UNHANDLED_EXCEPTION("xmloff.draw");
778 // #82003# test export count
779 // #91587# ALWAYS increment since now ALL to be exported shapes are counted.
780 if(mrExport
.GetShapeExport()->IsHandleProgressBarEnabled())
782 mrExport
.GetProgressBarHelper()->Increment();
787 // export shape element
788 switch(aShapeInfo
.meShapeType
)
790 case XmlShapeType::DrawRectangleShape
:
792 ImpExportRectangleShape(xShape
, nFeatures
, pRefPoint
);
795 case XmlShapeType::DrawEllipseShape
:
797 ImpExportEllipseShape(xShape
, nFeatures
, pRefPoint
);
800 case XmlShapeType::DrawLineShape
:
802 ImpExportLineShape(xShape
, nFeatures
, pRefPoint
);
805 case XmlShapeType::DrawPolyPolygonShape
: // closed PolyPolygon
806 case XmlShapeType::DrawPolyLineShape
: // open PolyPolygon
807 case XmlShapeType::DrawClosedBezierShape
: // closed tools::PolyPolygon containing curves
808 case XmlShapeType::DrawOpenBezierShape
: // open tools::PolyPolygon containing curves
810 ImpExportPolygonShape(xShape
, aShapeInfo
.meShapeType
, nFeatures
, pRefPoint
);
814 case XmlShapeType::DrawTextShape
:
815 case XmlShapeType::PresTitleTextShape
:
816 case XmlShapeType::PresOutlinerShape
:
817 case XmlShapeType::PresSubtitleShape
:
818 case XmlShapeType::PresNotesShape
:
819 case XmlShapeType::PresHeaderShape
:
820 case XmlShapeType::PresFooterShape
:
821 case XmlShapeType::PresSlideNumberShape
:
822 case XmlShapeType::PresDateTimeShape
:
824 ImpExportTextBoxShape(xShape
, aShapeInfo
.meShapeType
, nFeatures
, pRefPoint
);
828 case XmlShapeType::DrawGraphicObjectShape
:
829 case XmlShapeType::PresGraphicObjectShape
:
831 ImpExportGraphicObjectShape(xShape
, aShapeInfo
.meShapeType
, nFeatures
, pRefPoint
);
835 case XmlShapeType::DrawChartShape
:
836 case XmlShapeType::PresChartShape
:
838 ImpExportChartShape(xShape
, aShapeInfo
.meShapeType
, nFeatures
, pRefPoint
, pAttrList
);
842 case XmlShapeType::DrawControlShape
:
844 ImpExportControlShape(xShape
, nFeatures
, pRefPoint
);
848 case XmlShapeType::DrawConnectorShape
:
850 ImpExportConnectorShape(xShape
, nFeatures
, pRefPoint
);
854 case XmlShapeType::DrawMeasureShape
:
856 ImpExportMeasureShape(xShape
, nFeatures
, pRefPoint
);
860 case XmlShapeType::DrawOLE2Shape
:
861 case XmlShapeType::PresOLE2Shape
:
862 case XmlShapeType::DrawSheetShape
:
863 case XmlShapeType::PresSheetShape
:
865 ImpExportOLE2Shape(xShape
, aShapeInfo
.meShapeType
, nFeatures
, pRefPoint
);
869 case XmlShapeType::PresTableShape
:
870 case XmlShapeType::DrawTableShape
:
872 ImpExportTableShape( xShape
, aShapeInfo
.meShapeType
, nFeatures
, pRefPoint
);
876 case XmlShapeType::DrawPageShape
:
877 case XmlShapeType::PresPageShape
:
878 case XmlShapeType::HandoutShape
:
880 ImpExportPageShape(xShape
, aShapeInfo
.meShapeType
, nFeatures
, pRefPoint
);
884 case XmlShapeType::DrawCaptionShape
:
886 ImpExportCaptionShape(xShape
, nFeatures
, pRefPoint
);
890 case XmlShapeType::Draw3DCubeObject
:
891 case XmlShapeType::Draw3DSphereObject
:
892 case XmlShapeType::Draw3DLatheObject
:
893 case XmlShapeType::Draw3DExtrudeObject
:
895 ImpExport3DShape(xShape
, aShapeInfo
.meShapeType
);
899 case XmlShapeType::Draw3DSceneObject
:
901 ImpExport3DSceneShape( xShape
, nFeatures
, pRefPoint
);
905 case XmlShapeType::DrawGroupShape
:
908 ImpExportGroupShape( xShape
, nFeatures
, pRefPoint
);
912 case XmlShapeType::DrawFrameShape
:
914 ImpExportFrameShape(xShape
, nFeatures
, pRefPoint
);
918 case XmlShapeType::DrawAppletShape
:
920 ImpExportAppletShape(xShape
, nFeatures
, pRefPoint
);
924 case XmlShapeType::DrawPluginShape
:
926 ImpExportPluginShape(xShape
, nFeatures
, pRefPoint
);
930 case XmlShapeType::DrawCustomShape
:
932 if ( aShapeInfo
.xCustomShapeReplacement
.is() )
933 ImpExportGroupShape( aShapeInfo
.xCustomShapeReplacement
, nFeatures
, pRefPoint
);
935 ImpExportCustomShape( xShape
, nFeatures
, pRefPoint
);
939 case XmlShapeType::PresMediaShape
:
940 case XmlShapeType::DrawMediaShape
:
942 ImpExportMediaShape( xShape
, aShapeInfo
.meShapeType
, nFeatures
, pRefPoint
);
946 case XmlShapeType::PresOrgChartShape
:
947 case XmlShapeType::Unknown
:
948 case XmlShapeType::NotYetSet
:
951 // this should never happen and is an error
952 OSL_FAIL("XMLEXP: WriteShape: unknown or unexpected type of shape in export!");
957 pHyperlinkElement
.reset();
960 // if there was an error and no element for the shape was exported
961 // we need to clear the attribute list or the attributes will be
962 // set on the next exported element, which can result in corrupt
963 // xml files due to duplicate attributes
965 mrExport
.CheckAttrList(); // asserts in non pro if we have attributes left
966 mrExport
.ClearAttrList(); // clears the attributes
969 // This method collects all automatic styles for the shapes inside the given XShapes collection
970 void XMLShapeExport::collectShapesAutoStyles( const uno::Reference
< drawing::XShapes
>& xShapes
)
972 ShapesInfos::iterator aOldCurrentShapesIter
= maCurrentShapesIter
;
973 seekShapes( xShapes
);
975 uno::Reference
< drawing::XShape
> xShape
;
976 const sal_Int32
nShapeCount(xShapes
->getCount());
977 for(sal_Int32 nShapeId
= 0; nShapeId
< nShapeCount
; nShapeId
++)
979 xShapes
->getByIndex(nShapeId
) >>= xShape
;
980 SAL_WARN_IF( !xShape
.is(), "xmloff", "Shape without a XShape?" );
984 collectShapeAutoStyles( xShape
);
987 maCurrentShapesIter
= aOldCurrentShapesIter
;
990 // This method exports all XShape inside the given XShapes collection
991 void XMLShapeExport::exportShapes( const uno::Reference
< drawing::XShapes
>& xShapes
, XMLShapeExportFlags nFeatures
/* = SEF_DEFAULT */, awt::Point
* pRefPoint
/* = NULL */ )
993 ShapesInfos::iterator aOldCurrentShapesIter
= maCurrentShapesIter
;
994 seekShapes( xShapes
);
996 uno::Reference
< drawing::XShape
> xShape
;
997 const sal_Int32
nShapeCount(xShapes
->getCount());
998 for(sal_Int32 nShapeId
= 0; nShapeId
< nShapeCount
; nShapeId
++)
1000 xShapes
->getByIndex(nShapeId
) >>= xShape
;
1001 SAL_WARN_IF( !xShape
.is(), "xmloff", "Shape without a XShape?" );
1005 exportShape( xShape
, nFeatures
, pRefPoint
);
1008 maCurrentShapesIter
= aOldCurrentShapesIter
;
1013 void FixZOrder(uno::Reference
<drawing::XShapes
> const& xShapes
,
1014 std::function
<unsigned int (uno::Reference
<beans::XPropertySet
> const&)> const& rGetLayer
)
1016 uno::Reference
<drawing::XShapes3
> const xShapes3(xShapes
, uno::UNO_QUERY
);
1017 assert(xShapes3
.is());
1020 return; // only SvxDrawPage implements this
1022 struct Layer
{ std::vector
<sal_Int32
> shapes
; sal_Int32 nMin
= SAL_MAX_INT32
; sal_Int32 nMax
= 0; };
1023 std::vector
<Layer
> layers
;
1024 // shapes are sorted by ZOrder
1025 sal_Int32
const nCount(xShapes
->getCount());
1026 for (sal_Int32 i
= 0; i
< nCount
; ++i
)
1028 uno::Reference
<beans::XPropertySet
> const xShape(xShapes
->getByIndex(i
), uno::UNO_QUERY
);
1031 SAL_WARN("xmloff", "FixZOrder: null shape, cannot sort");
1034 unsigned int const nLayer(rGetLayer(xShape
));
1035 if (layers
.size() <= nLayer
)
1037 layers
.resize(nLayer
+ 1);
1039 layers
[nLayer
].shapes
.emplace_back(i
);
1040 if (i
< layers
[nLayer
].nMin
)
1042 layers
[nLayer
].nMin
= i
;
1044 if (layers
[nLayer
].nMax
< i
)
1046 layers
[nLayer
].nMax
= i
;
1049 std::erase_if(layers
, [](Layer
const& rLayer
) { return rLayer
.shapes
.empty(); });
1050 bool isSorted(true);
1051 for (size_t i
= 1; i
< layers
.size(); ++i
)
1053 assert(layers
[i
].nMin
!= layers
[i
-1].nMax
); // unique!
1054 if (layers
[i
].nMin
< layers
[i
-1].nMax
)
1062 return; // nothing to do
1064 uno::Sequence
<sal_Int32
> aNewOrder(nCount
);
1065 auto iterInsert(aNewOrder
.getArray());
1066 for (auto const& rLayer
: layers
)
1068 assert(rLayer
.nMin
<= rLayer
.nMax
); // empty layers have been removed
1069 iterInsert
= std::copy(rLayer
.shapes
.begin(), rLayer
.shapes
.end(), iterInsert
);
1073 xShapes3
->sort(aNewOrder
);
1075 catch (uno::Exception
const&)
1077 SAL_WARN("xmloff", "FixZOrder: exception");
1081 } // namespace xmloff
1083 void XMLShapeExport::seekShapes( const uno::Reference
< drawing::XShapes
>& xShapes
) noexcept
1087 maCurrentShapesIter
= maShapesInfos
.find( xShapes
);
1088 if( maCurrentShapesIter
== maShapesInfos
.end() )
1090 auto itPair
= maShapesInfos
.emplace( xShapes
, ImplXMLShapeExportInfoVector( static_cast<ShapesInfos::size_type
>(xShapes
->getCount()) ) );
1092 maCurrentShapesIter
= itPair
.first
;
1094 SAL_WARN_IF( maCurrentShapesIter
== maShapesInfos
.end(), "xmloff", "XMLShapeExport::seekShapes(): insert into stl::map failed" );
1097 SAL_WARN_IF( (*maCurrentShapesIter
).second
.size() != static_cast<ShapesInfos::size_type
>(xShapes
->getCount()), "xmloff", "XMLShapeExport::seekShapes(): XShapes size varied between calls" );
1102 maCurrentShapesIter
= maShapesInfos
.end();
1106 void XMLShapeExport::exportAutoStyles()
1108 // export all autostyle infos
1112 GetExport().GetAutoStylePool()->exportXML( XmlStyleFamily::SD_GRAPHICS_ID
);
1115 // ...for presentation
1117 GetExport().GetAutoStylePool()->exportXML( XmlStyleFamily::SD_PRESENTATION_ID
);
1120 if( mxShapeTableExport
.is() )
1121 mxShapeTableExport
->exportAutoStyles();
1124 /// returns the export property mapper for external chaining
1125 SvXMLExportPropertyMapper
* XMLShapeExport::CreateShapePropMapper(
1126 SvXMLExport
& rExport
)
1128 rtl::Reference
< XMLPropertyHandlerFactory
> xFactory
= new XMLSdPropHdlFactory( rExport
.GetModel(), rExport
);
1129 rtl::Reference
< XMLPropertySetMapper
> xMapper
= new XMLShapePropertySetMapper( xFactory
, true );
1130 rExport
.GetTextParagraphExport(); // get or create text paragraph export
1131 SvXMLExportPropertyMapper
* pResult
=
1132 new XMLShapeExportPropertyMapper( xMapper
, rExport
);
1133 // chain text attributes
1137 void XMLShapeExport::ImpCalcShapeType(const uno::Reference
< drawing::XShape
>& xShape
,
1138 XmlShapeType
& eShapeType
)
1140 // set in every case, so init here
1141 eShapeType
= XmlShapeType::Unknown
;
1146 OUString
aType(xShape
->getShapeType());
1148 if(!aType
.match("com.sun.star."))
1151 if(aType
.match("drawing.", 13))
1154 if (aType
.match("Rectangle", 21)) { eShapeType
= XmlShapeType::DrawRectangleShape
; }
1156 // #i72177# Note: Correcting CustomShape, CustomShape->Custom, len from 9 (was wrong anyways) to 6.
1157 // As can be seen at the other compares, the appendix "Shape" is left out of the comparison.
1158 else if(aType
.match("Custom", 21)) { eShapeType
= XmlShapeType::DrawCustomShape
; }
1160 else if(aType
.match("Ellipse", 21)) { eShapeType
= XmlShapeType::DrawEllipseShape
; }
1161 else if(aType
.match("Control", 21)) { eShapeType
= XmlShapeType::DrawControlShape
; }
1162 else if(aType
.match("Connector", 21)) { eShapeType
= XmlShapeType::DrawConnectorShape
; }
1163 else if(aType
.match("Measure", 21)) { eShapeType
= XmlShapeType::DrawMeasureShape
; }
1164 else if(aType
.match("Line", 21)) { eShapeType
= XmlShapeType::DrawLineShape
; }
1166 // #i72177# Note: This covers two types by purpose, PolyPolygonShape and PolyPolygonPathShape
1167 else if(aType
.match("PolyPolygon", 21)) { eShapeType
= XmlShapeType::DrawPolyPolygonShape
; }
1169 // #i72177# Note: This covers two types by purpose, PolyLineShape and PolyLinePathShape
1170 else if(aType
.match("PolyLine", 21)) { eShapeType
= XmlShapeType::DrawPolyLineShape
; }
1172 else if(aType
.match("OpenBezier", 21)) { eShapeType
= XmlShapeType::DrawOpenBezierShape
; }
1173 else if(aType
.match("ClosedBezier", 21)) { eShapeType
= XmlShapeType::DrawClosedBezierShape
; }
1175 // #i72177# FreeHand (opened and closed) now supports the types OpenFreeHandShape and
1176 // ClosedFreeHandShape respectively. Represent them as bezier shapes
1177 else if(aType
.match("OpenFreeHand", 21)) { eShapeType
= XmlShapeType::DrawOpenBezierShape
; }
1178 else if(aType
.match("ClosedFreeHand", 21)) { eShapeType
= XmlShapeType::DrawClosedBezierShape
; }
1180 else if(aType
.match("GraphicObject", 21)) { eShapeType
= XmlShapeType::DrawGraphicObjectShape
; }
1181 else if(aType
.match("Group", 21)) { eShapeType
= XmlShapeType::DrawGroupShape
; }
1182 else if(aType
.match("Text", 21)) { eShapeType
= XmlShapeType::DrawTextShape
; }
1183 else if(aType
.match("OLE2", 21))
1185 eShapeType
= XmlShapeType::DrawOLE2Shape
;
1187 // get info about presentation shape
1188 uno::Reference
<beans::XPropertySet
> xPropSet(xShape
, uno::UNO_QUERY
);
1193 if(xPropSet
->getPropertyValue("CLSID") >>= sCLSID
)
1195 #if !ENABLE_WASM_STRIP_CHART
1196 // WASM_CHART change
1197 // TODO: With Chart extracted this cannot really happen since
1198 // no Chart could've been added at all
1199 if (sCLSID
== mrExport
.GetChartExport()->getChartCLSID() ||
1203 sCLSID
== SvGlobalName( SO3_RPTCH_CLASSID
).GetHexName() )
1205 eShapeType
= XmlShapeType::DrawChartShape
;
1207 else if (sCLSID
== SvGlobalName( SO3_SC_CLASSID
).GetHexName() )
1209 eShapeType
= XmlShapeType::DrawSheetShape
;
1213 // general OLE2 Object
1218 else if(aType
.match("Page", 21)) { eShapeType
= XmlShapeType::DrawPageShape
; }
1219 else if(aType
.match("Frame", 21)) { eShapeType
= XmlShapeType::DrawFrameShape
; }
1220 else if(aType
.match("Caption", 21)) { eShapeType
= XmlShapeType::DrawCaptionShape
; }
1221 else if(aType
.match("Plugin", 21)) { eShapeType
= XmlShapeType::DrawPluginShape
; }
1222 else if(aType
.match("Applet", 21)) { eShapeType
= XmlShapeType::DrawAppletShape
; }
1223 else if(aType
.match("MediaShape", 21)) { eShapeType
= XmlShapeType::DrawMediaShape
; }
1224 else if(aType
.match("TableShape", 21)) { eShapeType
= XmlShapeType::DrawTableShape
; }
1227 else if(aType
.match("Scene", 21 + 7)) { eShapeType
= XmlShapeType::Draw3DSceneObject
; }
1228 else if(aType
.match("Cube", 21 + 7)) { eShapeType
= XmlShapeType::Draw3DCubeObject
; }
1229 else if(aType
.match("Sphere", 21 + 7)) { eShapeType
= XmlShapeType::Draw3DSphereObject
; }
1230 else if(aType
.match("Lathe", 21 + 7)) { eShapeType
= XmlShapeType::Draw3DLatheObject
; }
1231 else if(aType
.match("Extrude", 21 + 7)) { eShapeType
= XmlShapeType::Draw3DExtrudeObject
; }
1233 else if(aType
.match("presentation.", 13))
1235 // presentation shapes
1236 if (aType
.match("TitleText", 26)) { eShapeType
= XmlShapeType::PresTitleTextShape
; }
1237 else if(aType
.match("Outliner", 26)) { eShapeType
= XmlShapeType::PresOutlinerShape
; }
1238 else if(aType
.match("Subtitle", 26)) { eShapeType
= XmlShapeType::PresSubtitleShape
; }
1239 else if(aType
.match("GraphicObject", 26)) { eShapeType
= XmlShapeType::PresGraphicObjectShape
; }
1240 else if(aType
.match("Page", 26)) { eShapeType
= XmlShapeType::PresPageShape
; }
1241 else if(aType
.match("OLE2", 26))
1243 eShapeType
= XmlShapeType::PresOLE2Shape
;
1245 // get info about presentation shape
1246 uno::Reference
<beans::XPropertySet
> xPropSet(xShape
, uno::UNO_QUERY
);
1248 if(xPropSet
.is()) try
1251 if(xPropSet
->getPropertyValue("CLSID") >>= sCLSID
)
1253 if( sCLSID
== SvGlobalName( SO3_SC_CLASSID
).GetHexName() )
1255 eShapeType
= XmlShapeType::PresSheetShape
;
1259 catch(const uno::Exception
&)
1261 SAL_WARN( "xmloff", "XMLShapeExport::ImpCalcShapeType(), expected ole shape to have the CLSID property?" );
1264 else if(aType
.match("Chart", 26)) { eShapeType
= XmlShapeType::PresChartShape
; }
1265 else if(aType
.match("OrgChart", 26)) { eShapeType
= XmlShapeType::PresOrgChartShape
; }
1266 else if(aType
.match("CalcShape", 26)) { eShapeType
= XmlShapeType::PresSheetShape
; }
1267 else if(aType
.match("TableShape", 26)) { eShapeType
= XmlShapeType::PresTableShape
; }
1268 else if(aType
.match("Notes", 26)) { eShapeType
= XmlShapeType::PresNotesShape
; }
1269 else if(aType
.match("HandoutShape", 26)) { eShapeType
= XmlShapeType::HandoutShape
; }
1270 else if(aType
.match("HeaderShape", 26)) { eShapeType
= XmlShapeType::PresHeaderShape
; }
1271 else if(aType
.match("FooterShape", 26)) { eShapeType
= XmlShapeType::PresFooterShape
; }
1272 else if(aType
.match("SlideNumberShape", 26)) { eShapeType
= XmlShapeType::PresSlideNumberShape
; }
1273 else if(aType
.match("DateTimeShape", 26)) { eShapeType
= XmlShapeType::PresDateTimeShape
; }
1274 else if(aType
.match("MediaShape", 26)) { eShapeType
= XmlShapeType::PresMediaShape
; }
1278 /** exports all user defined gluepoints */
1279 void XMLShapeExport::ImpExportGluePoints( const uno::Reference
< drawing::XShape
>& xShape
)
1281 uno::Reference
< drawing::XGluePointsSupplier
> xSupplier( xShape
, uno::UNO_QUERY
);
1282 if( !xSupplier
.is() )
1285 uno::Reference
< container::XIdentifierAccess
> xGluePoints( xSupplier
->getGluePoints(), uno::UNO_QUERY
);
1286 if( !xGluePoints
.is() )
1289 drawing::GluePoint2 aGluePoint
;
1291 const uno::Sequence
< sal_Int32
> aIdSequence( xGluePoints
->getIdentifiers() );
1293 for( const sal_Int32 nIdentifier
: aIdSequence
)
1295 if( (xGluePoints
->getByIdentifier( nIdentifier
) >>= aGluePoint
) && aGluePoint
.IsUserDefined
)
1297 // export only user defined gluepoints
1299 const OUString
sId( OUString::number( nIdentifier
) );
1300 mrExport
.AddAttribute(XML_NAMESPACE_DRAW
, XML_ID
, sId
);
1302 mrExport
.GetMM100UnitConverter().convertMeasureToXML(msBuffer
,
1303 aGluePoint
.Position
.X
);
1304 mrExport
.AddAttribute(XML_NAMESPACE_SVG
, XML_X
, msBuffer
.makeStringAndClear());
1306 mrExport
.GetMM100UnitConverter().convertMeasureToXML(msBuffer
,
1307 aGluePoint
.Position
.Y
);
1308 mrExport
.AddAttribute(XML_NAMESPACE_SVG
, XML_Y
, msBuffer
.makeStringAndClear());
1310 if( !aGluePoint
.IsRelative
)
1312 SvXMLUnitConverter::convertEnum( msBuffer
, aGluePoint
.PositionAlignment
, aXML_GlueAlignment_EnumMap
);
1313 mrExport
.AddAttribute( XML_NAMESPACE_DRAW
, XML_ALIGN
, msBuffer
.makeStringAndClear() );
1316 if( aGluePoint
.Escape
!= drawing::EscapeDirection_SMART
)
1318 SvXMLUnitConverter::convertEnum( msBuffer
, aGluePoint
.Escape
, aXML_GlueEscapeDirection_EnumMap
);
1319 mrExport
.AddAttribute( XML_NAMESPACE_DRAW
, XML_ESCAPE_DIRECTION
, msBuffer
.makeStringAndClear() );
1322 SvXMLElementExport
aEventsElemt(mrExport
, XML_NAMESPACE_DRAW
, XML_GLUE_POINT
, true, true);
1327 void XMLShapeExport::ImpExportSignatureLine(const uno::Reference
<drawing::XShape
>& xShape
)
1329 uno::Reference
<beans::XPropertySet
> xPropSet(xShape
, uno::UNO_QUERY
);
1331 bool bIsSignatureLine
= false;
1332 xPropSet
->getPropertyValue("IsSignatureLine") >>= bIsSignatureLine
;
1333 if (!bIsSignatureLine
)
1336 OUString aSignatureLineId
;
1337 xPropSet
->getPropertyValue("SignatureLineId") >>= aSignatureLineId
;
1338 mrExport
.AddAttribute(XML_NAMESPACE_LO_EXT
, XML_ID
, aSignatureLineId
);
1340 OUString aSuggestedSignerName
;
1341 xPropSet
->getPropertyValue("SignatureLineSuggestedSignerName") >>= aSuggestedSignerName
;
1342 if (!aSuggestedSignerName
.isEmpty())
1343 mrExport
.AddAttribute(XML_NAMESPACE_LO_EXT
, XML_SUGGESTED_SIGNER_NAME
, aSuggestedSignerName
);
1345 OUString aSuggestedSignerTitle
;
1346 xPropSet
->getPropertyValue("SignatureLineSuggestedSignerTitle") >>= aSuggestedSignerTitle
;
1347 if (!aSuggestedSignerTitle
.isEmpty())
1348 mrExport
.AddAttribute(XML_NAMESPACE_LO_EXT
, XML_SUGGESTED_SIGNER_TITLE
, aSuggestedSignerTitle
);
1350 OUString aSuggestedSignerEmail
;
1351 xPropSet
->getPropertyValue("SignatureLineSuggestedSignerEmail") >>= aSuggestedSignerEmail
;
1352 if (!aSuggestedSignerEmail
.isEmpty())
1353 mrExport
.AddAttribute(XML_NAMESPACE_LO_EXT
, XML_SUGGESTED_SIGNER_EMAIL
, aSuggestedSignerEmail
);
1355 OUString aSigningInstructions
;
1356 xPropSet
->getPropertyValue("SignatureLineSigningInstructions") >>= aSigningInstructions
;
1357 if (!aSigningInstructions
.isEmpty())
1358 mrExport
.AddAttribute(XML_NAMESPACE_LO_EXT
, XML_SIGNING_INSTRUCTIONS
, aSigningInstructions
);
1360 bool bShowSignDate
= false;
1361 xPropSet
->getPropertyValue("SignatureLineShowSignDate") >>= bShowSignDate
;
1362 mrExport
.AddAttribute(XML_NAMESPACE_LO_EXT
, XML_SHOW_SIGN_DATE
,
1363 bShowSignDate
? XML_TRUE
: XML_FALSE
);
1365 bool bCanAddComment
= false;
1366 xPropSet
->getPropertyValue("SignatureLineCanAddComment") >>= bCanAddComment
;
1367 mrExport
.AddAttribute(XML_NAMESPACE_LO_EXT
, XML_CAN_ADD_COMMENT
,
1368 bCanAddComment
? XML_TRUE
: XML_FALSE
);
1370 SvXMLElementExport
aSignatureLineElement(mrExport
, XML_NAMESPACE_LO_EXT
, XML_SIGNATURELINE
, true,
1374 void XMLShapeExport::ImpExportQRCode(const uno::Reference
<drawing::XShape
>& xShape
)
1376 uno::Reference
<beans::XPropertySet
> xPropSet(xShape
, uno::UNO_QUERY
);
1378 uno::Any aAny
= xPropSet
->getPropertyValue("BarCodeProperties");
1380 css::drawing::BarCode aBarCode
;
1381 if(!(aAny
>>= aBarCode
))
1384 mrExport
.AddAttribute(XML_NAMESPACE_OFFICE
, XML_STRING_VALUE
, aBarCode
.Payload
);
1385 /* Export QR Code as per customised schema, @see OpenDocument-schema-v1.3+libreoffice */
1387 switch(aBarCode
.ErrorCorrection
){
1388 case css::drawing::BarCodeErrorCorrection::LOW
:
1391 case css::drawing::BarCodeErrorCorrection::MEDIUM
:
1394 case css::drawing::BarCodeErrorCorrection::QUARTILE
:
1397 case css::drawing::BarCodeErrorCorrection::HIGH
:
1401 mrExport
.AddAttribute(XML_NAMESPACE_LO_EXT
, XML_QRCODE_ERROR_CORRECTION
, temp
);
1402 mrExport
.AddAttribute(XML_NAMESPACE_LO_EXT
, XML_QRCODE_BORDER
, OUStringBuffer(20).append(aBarCode
.Border
).makeStringAndClear());
1403 mrExport
.AddAttribute(XML_NAMESPACE_LO_EXT
, XML_QRCODE_TYPE
, OUStringBuffer(20).append(aBarCode
.Type
).makeStringAndClear());
1405 SvXMLElementExport
aBarCodeElement(mrExport
, XML_NAMESPACE_LO_EXT
, XML_QRCODE
, true,
1409 void XMLShapeExport::ExportGraphicDefaults()
1411 rtl::Reference
<XMLStyleExport
> aStEx(new XMLStyleExport(mrExport
, mrExport
.GetAutoStylePool().get()));
1413 // construct PropertySetMapper
1414 rtl::Reference
< SvXMLExportPropertyMapper
> xPropertySetMapper( CreateShapePropMapper( mrExport
) );
1415 static_cast<XMLShapeExportPropertyMapper
*>(xPropertySetMapper
.get())->SetAutoStyles( false );
1417 // chain text attributes
1418 xPropertySetMapper
->ChainExportMapper(XMLTextParagraphExport::CreateParaExtPropMapper(mrExport
));
1420 // chain special Writer/text frame default attributes
1421 xPropertySetMapper
->ChainExportMapper(XMLTextParagraphExport::CreateParaDefaultExtPropMapper(mrExport
));
1423 // write graphic family default style
1424 uno::Reference
< lang::XMultiServiceFactory
> xFact( mrExport
.GetModel(), uno::UNO_QUERY
);
1430 uno::Reference
< beans::XPropertySet
> xDefaults( xFact
->createInstance("com.sun.star.drawing.Defaults"), uno::UNO_QUERY
);
1431 if( xDefaults
.is() )
1433 aStEx
->exportDefaultStyle( xDefaults
, XML_STYLE_FAMILY_SD_GRAPHICS_NAME
, xPropertySetMapper
);
1435 // write graphic styles (family name differs depending on the module)
1436 aStEx
->exportStyleFamily("graphics", XML_STYLE_FAMILY_SD_GRAPHICS_NAME
, xPropertySetMapper
, false, XmlStyleFamily::SD_GRAPHICS_ID
);
1437 aStEx
->exportStyleFamily("GraphicStyles", XML_STYLE_FAMILY_SD_GRAPHICS_NAME
, xPropertySetMapper
, false, XmlStyleFamily::SD_GRAPHICS_ID
);
1440 catch(const lang::ServiceNotRegisteredException
&)
1445 void XMLShapeExport::onExport( const css::uno::Reference
< css::drawing::XShape
>& )
1449 const rtl::Reference
< XMLTableExport
>& XMLShapeExport::GetShapeTableExport()
1451 if( !mxShapeTableExport
.is() )
1453 rtl::Reference
< XMLPropertyHandlerFactory
> xFactory( new XMLSdPropHdlFactory( mrExport
.GetModel(), mrExport
) );
1454 rtl::Reference
< XMLPropertySetMapper
> xMapper( new XMLShapePropertySetMapper( xFactory
, true ) );
1455 mrExport
.GetTextParagraphExport(); // get or create text paragraph export
1456 rtl::Reference
< SvXMLExportPropertyMapper
> xPropertySetMapper( new XMLShapeExportPropertyMapper( xMapper
, mrExport
) );
1457 mxShapeTableExport
= new XMLTableExport( mrExport
, xPropertySetMapper
, xFactory
);
1460 return mxShapeTableExport
;
1463 void XMLShapeExport::ImpExportNewTrans(const uno::Reference
< beans::XPropertySet
>& xPropSet
,
1464 XMLShapeExportFlags nFeatures
, awt::Point
* pRefPoint
)
1467 ::basegfx::B2DHomMatrix aMatrix
;
1468 ImpExportNewTrans_GetB2DHomMatrix(aMatrix
, xPropSet
);
1470 // decompose and correct about pRefPoint
1471 ::basegfx::B2DTuple aTRScale
;
1472 double fTRShear(0.0);
1473 double fTRRotate(0.0);
1474 ::basegfx::B2DTuple aTRTranslate
;
1475 ImpExportNewTrans_DecomposeAndRefPoint(aMatrix
, aTRScale
, fTRShear
, fTRRotate
, aTRTranslate
, pRefPoint
);
1477 // use features and write
1478 ImpExportNewTrans_FeaturesAndWrite(aTRScale
, fTRShear
, fTRRotate
, aTRTranslate
, nFeatures
);
1481 void XMLShapeExport::ImpExportNewTrans_GetB2DHomMatrix(::basegfx::B2DHomMatrix
& rMatrix
,
1482 const uno::Reference
< beans::XPropertySet
>& xPropSet
)
1484 /* Get <TransformationInHoriL2R>, if it exist
1485 and if the document is exported into the OpenOffice.org file format.
1486 This property only exists at service css::text::Shape - the
1487 Writer UNO service for shapes.
1488 This code is needed, because the positioning attributes in the
1489 OpenOffice.org file format are given in horizontal left-to-right layout
1490 regardless the layout direction the shape is in. In the OASIS Open Office
1491 file format the positioning attributes are correctly given in the layout
1492 direction the shape is in. Thus, this code provides the conversion from
1493 the OASIS Open Office file format to the OpenOffice.org file format. (#i28749#)
1496 if ( !( GetExport().getExportFlags() & SvXMLExportFlags::OASIS
) &&
1497 xPropSet
->getPropertySetInfo()->hasPropertyByName("TransformationInHoriL2R") )
1499 aAny
= xPropSet
->getPropertyValue("TransformationInHoriL2R");
1503 aAny
= xPropSet
->getPropertyValue("Transformation");
1505 drawing::HomogenMatrix3 aMatrix
;
1508 rMatrix
.set(0, 0, aMatrix
.Line1
.Column1
);
1509 rMatrix
.set(0, 1, aMatrix
.Line1
.Column2
);
1510 rMatrix
.set(0, 2, aMatrix
.Line1
.Column3
);
1511 rMatrix
.set(1, 0, aMatrix
.Line2
.Column1
);
1512 rMatrix
.set(1, 1, aMatrix
.Line2
.Column2
);
1513 rMatrix
.set(1, 2, aMatrix
.Line2
.Column3
);
1514 // For this to be a valid 2D transform matrix, the last row must be [0,0,1]
1515 assert( aMatrix
.Line3
.Column1
== 0 );
1516 assert( aMatrix
.Line3
.Column2
== 0 );
1517 assert( aMatrix
.Line3
.Column3
== 1 );
1520 void XMLShapeExport::ImpExportNewTrans_DecomposeAndRefPoint(const ::basegfx::B2DHomMatrix
& rMatrix
, ::basegfx::B2DTuple
& rTRScale
,
1521 double& fTRShear
, double& fTRRotate
, ::basegfx::B2DTuple
& rTRTranslate
, css::awt::Point
* pRefPoint
)
1524 rMatrix
.decompose(rTRScale
, rTRTranslate
, fTRRotate
, fTRShear
);
1526 // correct translation about pRefPoint
1529 rTRTranslate
-= ::basegfx::B2DTuple(pRefPoint
->X
, pRefPoint
->Y
);
1533 void XMLShapeExport::ImpExportNewTrans_FeaturesAndWrite(::basegfx::B2DTuple
const & rTRScale
, double fTRShear
,
1534 double fTRRotate
, ::basegfx::B2DTuple
const & rTRTranslate
, const XMLShapeExportFlags nFeatures
)
1536 // always write Size (rTRScale) since this statement carries the union
1539 OUStringBuffer sStringBuffer
;
1540 ::basegfx::B2DTuple
aTRScale(rTRScale
);
1543 if(!(nFeatures
& XMLShapeExportFlags::WIDTH
))
1549 if( aTRScale
.getX() > 0.0 )
1550 aTRScale
.setX(aTRScale
.getX() - 1.0);
1551 else if( aTRScale
.getX() < 0.0 )
1552 aTRScale
.setX(aTRScale
.getX() + 1.0);
1555 mrExport
.GetMM100UnitConverter().convertMeasureToXML(sStringBuffer
,
1556 FRound(aTRScale
.getX()));
1557 aStr
= sStringBuffer
.makeStringAndClear();
1558 mrExport
.AddAttribute(XML_NAMESPACE_SVG
, XML_WIDTH
, aStr
);
1561 if(!(nFeatures
& XMLShapeExportFlags::HEIGHT
))
1567 if( aTRScale
.getY() > 0.0 )
1568 aTRScale
.setY(aTRScale
.getY() - 1.0);
1569 else if( aTRScale
.getY() < 0.0 )
1570 aTRScale
.setY(aTRScale
.getY() + 1.0);
1573 mrExport
.GetMM100UnitConverter().convertMeasureToXML(sStringBuffer
,
1574 FRound(aTRScale
.getY()));
1575 aStr
= sStringBuffer
.makeStringAndClear();
1576 mrExport
.AddAttribute(XML_NAMESPACE_SVG
, XML_HEIGHT
, aStr
);
1578 // decide if transformation is necessary
1579 bool bTransformationIsNecessary(fTRShear
!= 0.0 || fTRRotate
!= 0.0);
1581 if(bTransformationIsNecessary
)
1583 // write transformation, but WITHOUT scale which is exported as size above
1584 SdXMLImExTransform2D aTransform
;
1586 aTransform
.AddSkewX(atan(fTRShear
));
1589 // fTRRotate is mathematically correct, but due to the error
1590 // we export/import it mirrored. Since the API implementation is fixed and
1591 // uses the correctly oriented angle, it is necessary for compatibility to
1592 // mirror the angle here to stay at the old behaviour. There is a follow-up
1593 // task (#i78698#) to fix this in the next ODF FileFormat version
1594 aTransform
.AddRotate(-fTRRotate
);
1596 aTransform
.AddTranslate(rTRTranslate
);
1598 // does transformation need to be exported?
1599 if(aTransform
.NeedsAction())
1600 mrExport
.AddAttribute(XML_NAMESPACE_DRAW
, XML_TRANSFORM
, aTransform
.GetExportString(mrExport
.GetMM100UnitConverter()));
1604 // no shear, no rotate; just add object position to export and we are done
1605 if(nFeatures
& XMLShapeExportFlags::X
)
1608 mrExport
.GetMM100UnitConverter().convertMeasureToXML(sStringBuffer
,
1609 FRound(rTRTranslate
.getX()));
1610 aStr
= sStringBuffer
.makeStringAndClear();
1611 mrExport
.AddAttribute(XML_NAMESPACE_SVG
, XML_X
, aStr
);
1614 if(nFeatures
& XMLShapeExportFlags::Y
)
1617 mrExport
.GetMM100UnitConverter().convertMeasureToXML(sStringBuffer
,
1618 FRound(rTRTranslate
.getY()));
1619 aStr
= sStringBuffer
.makeStringAndClear();
1620 mrExport
.AddAttribute(XML_NAMESPACE_SVG
, XML_Y
, aStr
);
1625 bool XMLShapeExport::ImpExportPresentationAttributes( const uno::Reference
< beans::XPropertySet
>& xPropSet
, const OUString
& rClass
)
1627 bool bIsEmpty
= false;
1629 // write presentation class entry
1630 mrExport
.AddAttribute(XML_NAMESPACE_PRESENTATION
, XML_CLASS
, rClass
);
1634 uno::Reference
< beans::XPropertySetInfo
> xPropSetInfo( xPropSet
->getPropertySetInfo() );
1637 // is empty pres. shape?
1638 if( xPropSetInfo
.is() && xPropSetInfo
->hasPropertyByName("IsEmptyPresentationObject"))
1640 xPropSet
->getPropertyValue("IsEmptyPresentationObject") >>= bIsEmpty
;
1642 mrExport
.AddAttribute(XML_NAMESPACE_PRESENTATION
, XML_PLACEHOLDER
, XML_TRUE
);
1645 // is user-transformed?
1646 if( xPropSetInfo
.is() && xPropSetInfo
->hasPropertyByName("IsPlaceholderDependent"))
1649 xPropSet
->getPropertyValue("IsPlaceholderDependent") >>= bTemp
;
1651 mrExport
.AddAttribute(XML_NAMESPACE_PRESENTATION
, XML_USER_TRANSFORMED
, XML_TRUE
);
1658 void XMLShapeExport::ImpExportText( const uno::Reference
< drawing::XShape
>& xShape
, TextPNS eExtensionNS
)
1660 if (eExtensionNS
== TextPNS::EXTENSION
)
1662 if ((mrExport
.getSaneDefaultVersion() & SvtSaveOptions::ODFSVER_EXTENDED
) == 0)
1664 return; // do not export to ODF 1.1/1.2/1.3
1667 uno::Reference
< text::XText
> xText( xShape
, uno::UNO_QUERY
);
1670 uno::Reference
< container::XEnumerationAccess
> xEnumAccess( xShape
, uno::UNO_QUERY
);
1671 if( xEnumAccess
.is() && xEnumAccess
->hasElements() )
1672 mrExport
.GetTextParagraphExport()->exportText( xText
, false, true, eExtensionNS
);
1680 CLICKACTION
= 0x0001,
1687 CLICKEVENTTYPE
= 0x0080,
1695 template<> struct typed_flags
<Found
> : is_typed_flags
<Found
, 0x03ff> {};
1698 void XMLShapeExport::ImpExportEvents( const uno::Reference
< drawing::XShape
>& xShape
)
1700 uno::Reference
< document::XEventsSupplier
> xEventsSupplier( xShape
, uno::UNO_QUERY
);
1701 if( !xEventsSupplier
.is() )
1704 uno::Reference
< container::XNameAccess
> xEvents
= xEventsSupplier
->getEvents();
1705 SAL_WARN_IF( !xEvents
.is(), "xmloff", "XEventsSupplier::getEvents() returned NULL" );
1709 Found nFound
= Found::NONE
;
1711 OUString aClickEventType
;
1712 presentation::ClickAction eClickAction
= presentation::ClickAction_NONE
;
1713 presentation::AnimationEffect eEffect
= presentation::AnimationEffect_NONE
;
1714 presentation::AnimationSpeed eSpeed
= presentation::AnimationSpeed_SLOW
;
1715 OUString aStrSoundURL
;
1716 bool bPlayFull
= false;
1717 sal_Int32 nVerb
= 0;
1719 OUString aStrLibrary
;
1720 OUString aStrBookmark
;
1722 uno::Sequence
< beans::PropertyValue
> aClickProperties
;
1723 if( xEvents
->hasByName( gsOnClick
) && (xEvents
->getByName( gsOnClick
) >>= aClickProperties
) )
1725 for( const auto& rProperty
: std::as_const(aClickProperties
) )
1727 if( !( nFound
& Found::CLICKEVENTTYPE
) && rProperty
.Name
== gsEventType
)
1729 if( rProperty
.Value
>>= aClickEventType
)
1730 nFound
|= Found::CLICKEVENTTYPE
;
1732 else if( !( nFound
& Found::CLICKACTION
) && rProperty
.Name
== gsClickAction
)
1734 if( rProperty
.Value
>>= eClickAction
)
1735 nFound
|= Found::CLICKACTION
;
1737 else if( !( nFound
& Found::MACRO
) && ( rProperty
.Name
== gsMacroName
|| rProperty
.Name
== gsScript
) )
1739 if( rProperty
.Value
>>= aStrMacro
)
1740 nFound
|= Found::MACRO
;
1742 else if( !( nFound
& Found::LIBRARY
) && rProperty
.Name
== gsLibrary
)
1744 if( rProperty
.Value
>>= aStrLibrary
)
1745 nFound
|= Found::LIBRARY
;
1747 else if( !( nFound
& Found::EFFECT
) && rProperty
.Name
== gsEffect
)
1749 if( rProperty
.Value
>>= eEffect
)
1750 nFound
|= Found::EFFECT
;
1752 else if( !( nFound
& Found::BOOKMARK
) && rProperty
.Name
== gsBookmark
)
1754 if( rProperty
.Value
>>= aStrBookmark
)
1755 nFound
|= Found::BOOKMARK
;
1757 else if( !( nFound
& Found::SPEED
) && rProperty
.Name
== gsSpeed
)
1759 if( rProperty
.Value
>>= eSpeed
)
1760 nFound
|= Found::SPEED
;
1762 else if( !( nFound
& Found::SOUNDURL
) && rProperty
.Name
== gsSoundURL
)
1764 if( rProperty
.Value
>>= aStrSoundURL
)
1765 nFound
|= Found::SOUNDURL
;
1767 else if( !( nFound
& Found::PLAYFULL
) && rProperty
.Name
== gsPlayFull
)
1769 if( rProperty
.Value
>>= bPlayFull
)
1770 nFound
|= Found::PLAYFULL
;
1772 else if( !( nFound
& Found::VERB
) && rProperty
.Name
== gsVerb
)
1774 if( rProperty
.Value
>>= nVerb
)
1775 nFound
|= Found::VERB
;
1780 // create the XML elements
1782 if( aClickEventType
== gsPresentation
)
1784 if( !(nFound
& Found::CLICKACTION
) || (eClickAction
== presentation::ClickAction_NONE
) )
1787 SvXMLElementExport
aEventsElemt(mrExport
, XML_NAMESPACE_OFFICE
, XML_EVENT_LISTENERS
, true, true);
1789 enum XMLTokenEnum eStrAction
;
1791 switch( eClickAction
)
1793 case presentation::ClickAction_PREVPAGE
: eStrAction
= XML_PREVIOUS_PAGE
; break;
1794 case presentation::ClickAction_NEXTPAGE
: eStrAction
= XML_NEXT_PAGE
; break;
1795 case presentation::ClickAction_FIRSTPAGE
: eStrAction
= XML_FIRST_PAGE
; break;
1796 case presentation::ClickAction_LASTPAGE
: eStrAction
= XML_LAST_PAGE
; break;
1797 case presentation::ClickAction_INVISIBLE
: eStrAction
= XML_HIDE
; break;
1798 case presentation::ClickAction_STOPPRESENTATION
:eStrAction
= XML_STOP
; break;
1799 case presentation::ClickAction_PROGRAM
: eStrAction
= XML_EXECUTE
; break;
1800 case presentation::ClickAction_BOOKMARK
: eStrAction
= XML_SHOW
; break;
1801 case presentation::ClickAction_DOCUMENT
: eStrAction
= XML_SHOW
; break;
1802 case presentation::ClickAction_MACRO
: eStrAction
= XML_EXECUTE_MACRO
; break;
1803 case presentation::ClickAction_VERB
: eStrAction
= XML_VERB
; break;
1804 case presentation::ClickAction_VANISH
: eStrAction
= XML_FADE_OUT
; break;
1805 case presentation::ClickAction_SOUND
: eStrAction
= XML_SOUND
; break;
1807 OSL_FAIL( "unknown presentation::ClickAction found!" );
1808 eStrAction
= XML_UNKNOWN
;
1811 OUString
aEventQName(
1812 mrExport
.GetNamespaceMap().GetQNameByKey(
1813 XML_NAMESPACE_DOM
, "click" ) );
1814 mrExport
.AddAttribute( XML_NAMESPACE_SCRIPT
, XML_EVENT_NAME
, aEventQName
);
1815 mrExport
.AddAttribute( XML_NAMESPACE_PRESENTATION
, XML_ACTION
, eStrAction
);
1817 if( eClickAction
== presentation::ClickAction_VANISH
)
1819 if( nFound
& Found::EFFECT
)
1822 XMLEffectDirection eDirection
;
1823 sal_Int16 nStartScale
;
1826 SdXMLImplSetEffect( eEffect
, eKind
, eDirection
, nStartScale
, bIn
);
1828 if( eKind
!= EK_none
)
1830 SvXMLUnitConverter::convertEnum( msBuffer
, eKind
, aXML_AnimationEffect_EnumMap
);
1831 mrExport
.AddAttribute( XML_NAMESPACE_PRESENTATION
, XML_EFFECT
, msBuffer
.makeStringAndClear() );
1834 if( eDirection
!= ED_none
)
1836 SvXMLUnitConverter::convertEnum( msBuffer
, eDirection
, aXML_AnimationDirection_EnumMap
);
1837 mrExport
.AddAttribute( XML_NAMESPACE_PRESENTATION
, XML_DIRECTION
, msBuffer
.makeStringAndClear() );
1840 if( nStartScale
!= -1 )
1842 ::sax::Converter::convertPercent( msBuffer
, nStartScale
);
1843 mrExport
.AddAttribute( XML_NAMESPACE_PRESENTATION
, XML_START_SCALE
, msBuffer
.makeStringAndClear() );
1847 if( nFound
& Found::SPEED
&& eEffect
!= presentation::AnimationEffect_NONE
)
1849 if( eSpeed
!= presentation::AnimationSpeed_MEDIUM
)
1851 SvXMLUnitConverter::convertEnum( msBuffer
, eSpeed
, aXML_AnimationSpeed_EnumMap
);
1852 mrExport
.AddAttribute( XML_NAMESPACE_PRESENTATION
, XML_SPEED
, msBuffer
.makeStringAndClear() );
1857 if( eClickAction
== presentation::ClickAction_PROGRAM
||
1858 eClickAction
== presentation::ClickAction_BOOKMARK
||
1859 eClickAction
== presentation::ClickAction_DOCUMENT
)
1861 if( eClickAction
== presentation::ClickAction_BOOKMARK
)
1862 msBuffer
.append( '#' );
1864 msBuffer
.append( aStrBookmark
);
1865 mrExport
.AddAttribute(XML_NAMESPACE_XLINK
, XML_HREF
, GetExport().GetRelativeReference(msBuffer
.makeStringAndClear()) );
1866 mrExport
.AddAttribute( XML_NAMESPACE_XLINK
, XML_TYPE
, XML_SIMPLE
);
1867 mrExport
.AddAttribute( XML_NAMESPACE_XLINK
, XML_SHOW
, XML_EMBED
);
1868 mrExport
.AddAttribute( XML_NAMESPACE_XLINK
, XML_ACTUATE
, XML_ONREQUEST
);
1871 if( ( nFound
& Found::VERB
) && eClickAction
== presentation::ClickAction_VERB
)
1873 msBuffer
.append( nVerb
);
1874 mrExport
.AddAttribute(XML_NAMESPACE_PRESENTATION
, XML_VERB
, msBuffer
.makeStringAndClear());
1877 SvXMLElementExport
aEventElemt(mrExport
, XML_NAMESPACE_PRESENTATION
, XML_EVENT_LISTENER
, true, true);
1879 if( eClickAction
== presentation::ClickAction_VANISH
|| eClickAction
== presentation::ClickAction_SOUND
)
1881 if( ( nFound
& Found::SOUNDURL
) && !aStrSoundURL
.isEmpty() )
1883 mrExport
.AddAttribute(XML_NAMESPACE_XLINK
, XML_HREF
, GetExport().GetRelativeReference(aStrSoundURL
) );
1884 mrExport
.AddAttribute( XML_NAMESPACE_XLINK
, XML_TYPE
, XML_SIMPLE
);
1885 mrExport
.AddAttribute( XML_NAMESPACE_XLINK
, XML_SHOW
, XML_NEW
);
1886 mrExport
.AddAttribute( XML_NAMESPACE_XLINK
, XML_ACTUATE
, XML_ONREQUEST
);
1887 if( nFound
& Found::PLAYFULL
&& bPlayFull
)
1888 mrExport
.AddAttribute( XML_NAMESPACE_PRESENTATION
, XML_PLAY_FULL
, XML_TRUE
);
1890 SvXMLElementExport
aElem( mrExport
, XML_NAMESPACE_PRESENTATION
, XML_SOUND
, true, true );
1894 else if( aClickEventType
== gsStarBasic
)
1896 if( nFound
& Found::MACRO
)
1898 SvXMLElementExport
aEventsElemt(mrExport
, XML_NAMESPACE_OFFICE
, XML_EVENT_LISTENERS
, true, true);
1900 mrExport
.AddAttribute( XML_NAMESPACE_SCRIPT
, XML_LANGUAGE
,
1901 mrExport
.GetNamespaceMap().GetQNameByKey(
1904 OUString
aEventQName(
1905 mrExport
.GetNamespaceMap().GetQNameByKey(
1906 XML_NAMESPACE_DOM
, "click" ) );
1907 mrExport
.AddAttribute( XML_NAMESPACE_SCRIPT
, XML_EVENT_NAME
, aEventQName
);
1909 if( nFound
& Found::LIBRARY
)
1911 const OUString
& sLocation( GetXMLToken(
1912 (aStrLibrary
.equalsIgnoreAsciiCase("StarOffice") ||
1913 aStrLibrary
.equalsIgnoreAsciiCase("application") ) ? XML_APPLICATION
1915 mrExport
.AddAttribute(XML_NAMESPACE_SCRIPT
, XML_MACRO_NAME
,
1916 sLocation
+ ":" + aStrMacro
);
1920 mrExport
.AddAttribute( XML_NAMESPACE_SCRIPT
, XML_MACRO_NAME
, aStrMacro
);
1923 SvXMLElementExport
aEventElemt(mrExport
, XML_NAMESPACE_SCRIPT
, XML_EVENT_LISTENER
, true, true);
1926 else if( aClickEventType
== gsScript
)
1928 if( nFound
& Found::MACRO
)
1930 SvXMLElementExport
aEventsElemt(mrExport
, XML_NAMESPACE_OFFICE
, XML_EVENT_LISTENERS
, true, true);
1932 mrExport
.AddAttribute( XML_NAMESPACE_SCRIPT
, XML_LANGUAGE
, mrExport
.GetNamespaceMap().GetQNameByKey(
1933 XML_NAMESPACE_OOO
, GetXMLToken(XML_SCRIPT
) ) );
1934 OUString
aEventQName(
1935 mrExport
.GetNamespaceMap().GetQNameByKey(
1936 XML_NAMESPACE_DOM
, "click" ) );
1937 mrExport
.AddAttribute( XML_NAMESPACE_SCRIPT
, XML_EVENT_NAME
, aEventQName
);
1938 mrExport
.AddAttribute( XML_NAMESPACE_XLINK
, XML_HREF
, aStrMacro
);
1939 mrExport
.AddAttribute( XML_NAMESPACE_XLINK
, XML_TYPE
, "simple" );
1941 SvXMLElementExport
aEventElemt(mrExport
, XML_NAMESPACE_SCRIPT
, XML_EVENT_LISTENER
, true, true);
1946 /** #i68101# export shape Title and Description */
1947 void XMLShapeExport::ImpExportDescription( const uno::Reference
< drawing::XShape
>& xShape
)
1952 OUString aDescription
;
1954 uno::Reference
< beans::XPropertySet
> xProps( xShape
, uno::UNO_QUERY_THROW
);
1955 xProps
->getPropertyValue("Title") >>= aTitle
;
1956 xProps
->getPropertyValue("Description") >>= aDescription
;
1958 if(!aTitle
.isEmpty())
1960 SvXMLElementExport
aEventElemt(mrExport
, XML_NAMESPACE_SVG
, XML_TITLE
, true, false);
1961 mrExport
.Characters( aTitle
);
1964 if(!aDescription
.isEmpty())
1966 SvXMLElementExport
aEventElemt(mrExport
, XML_NAMESPACE_SVG
, XML_DESC
, true, false );
1967 mrExport
.Characters( aDescription
);
1970 catch( uno::Exception
& )
1972 DBG_UNHANDLED_EXCEPTION( "xmloff", "exporting Title and/or Description for shape" );
1976 void XMLShapeExport::ImpExportGroupShape( const uno::Reference
< drawing::XShape
>& xShape
, XMLShapeExportFlags nFeatures
, awt::Point
* pRefPoint
)
1978 uno::Reference
< drawing::XShapes
> xShapes(xShape
, uno::UNO_QUERY
);
1979 if(!(xShapes
.is() && xShapes
->getCount()))
1982 // write group shape
1983 bool bCreateNewline( (nFeatures
& XMLShapeExportFlags::NO_WS
) == XMLShapeExportFlags::NONE
); // #86116#/#92210#
1984 SvXMLElementExport
aPGR(mrExport
, XML_NAMESPACE_DRAW
, XML_G
, bCreateNewline
, true);
1986 ImpExportDescription( xShape
); // #i68101#
1987 ImpExportEvents( xShape
);
1988 ImpExportGluePoints( xShape
);
1990 // #89764# if export of position is suppressed for group shape,
1991 // positions of contained objects should be written relative to
1992 // the upper left edge of the group.
1993 awt::Point aUpperLeft
;
1995 if(!(nFeatures
& XMLShapeExportFlags::POSITION
))
1997 nFeatures
|= XMLShapeExportFlags::POSITION
;
1998 aUpperLeft
= xShape
->getPosition();
1999 pRefPoint
= &aUpperLeft
;
2003 exportShapes( xShapes
, nFeatures
, pRefPoint
);
2006 void XMLShapeExport::ImpExportTextBoxShape(
2007 const uno::Reference
< drawing::XShape
>& xShape
,
2008 XmlShapeType eShapeType
, XMLShapeExportFlags nFeatures
, awt::Point
* pRefPoint
)
2010 const uno::Reference
< beans::XPropertySet
> xPropSet(xShape
, uno::UNO_QUERY
);
2014 // presentation attribute (if presentation)
2015 bool bIsPresShape(false);
2016 bool bIsEmptyPresObj(false);
2021 case XmlShapeType::PresSubtitleShape
:
2023 aStr
= GetXMLToken(XML_SUBTITLE
);
2024 bIsPresShape
= true;
2027 case XmlShapeType::PresTitleTextShape
:
2029 aStr
= GetXMLToken(XML_TITLE
);
2030 bIsPresShape
= true;
2033 case XmlShapeType::PresOutlinerShape
:
2035 aStr
= GetXMLToken(XML_PRESENTATION_OUTLINE
);
2036 bIsPresShape
= true;
2039 case XmlShapeType::PresNotesShape
:
2041 aStr
= GetXMLToken(XML_NOTES
);
2042 bIsPresShape
= true;
2045 case XmlShapeType::PresHeaderShape
:
2047 aStr
= GetXMLToken(XML_HEADER
);
2048 bIsPresShape
= true;
2051 case XmlShapeType::PresFooterShape
:
2053 aStr
= GetXMLToken(XML_FOOTER
);
2054 bIsPresShape
= true;
2057 case XmlShapeType::PresSlideNumberShape
:
2059 aStr
= GetXMLToken(XML_PAGE_NUMBER
);
2060 bIsPresShape
= true;
2063 case XmlShapeType::PresDateTimeShape
:
2065 aStr
= GetXMLToken(XML_DATE_TIME
);
2066 bIsPresShape
= true;
2074 ImpExportNewTrans(xPropSet
, nFeatures
, pRefPoint
);
2077 bIsEmptyPresObj
= ImpExportPresentationAttributes( xPropSet
, aStr
);
2079 bool bCreateNewline( (nFeatures
& XMLShapeExportFlags::NO_WS
) == XMLShapeExportFlags::NONE
); // #86116#/#92210#
2080 SvXMLElementExport
aElem( mrExport
, XML_NAMESPACE_DRAW
,
2081 XML_FRAME
, bCreateNewline
, true );
2083 // evtl. corner radius?
2084 sal_Int32
nCornerRadius(0);
2085 xPropSet
->getPropertyValue("CornerRadius") >>= nCornerRadius
;
2088 OUStringBuffer sStringBuffer
;
2089 mrExport
.GetMM100UnitConverter().convertMeasureToXML(sStringBuffer
,
2091 mrExport
.AddAttribute(XML_NAMESPACE_DRAW
, XML_CORNER_RADIUS
, sStringBuffer
.makeStringAndClear());
2096 SvXMLElementExport
aOBJ(mrExport
, XML_NAMESPACE_DRAW
, XML_TEXT_BOX
, true, true);
2097 if(!bIsEmptyPresObj
)
2098 ImpExportText( xShape
);
2101 ImpExportDescription( xShape
); // #i68101#
2102 ImpExportEvents( xShape
);
2103 ImpExportGluePoints( xShape
);
2107 void XMLShapeExport::ImpExportRectangleShape(
2108 const uno::Reference
< drawing::XShape
>& xShape
,
2109 XMLShapeExportFlags nFeatures
, css::awt::Point
* pRefPoint
)
2111 const uno::Reference
< beans::XPropertySet
> xPropSet(xShape
, uno::UNO_QUERY
);
2116 ImpExportNewTrans(xPropSet
, nFeatures
, pRefPoint
);
2118 // evtl. corner radius?
2119 sal_Int32
nCornerRadius(0);
2120 xPropSet
->getPropertyValue("CornerRadius") >>= nCornerRadius
;
2123 OUStringBuffer sStringBuffer
;
2124 mrExport
.GetMM100UnitConverter().convertMeasureToXML(sStringBuffer
,
2126 mrExport
.AddAttribute(XML_NAMESPACE_DRAW
, XML_CORNER_RADIUS
, sStringBuffer
.makeStringAndClear());
2130 bool bCreateNewline( (nFeatures
& XMLShapeExportFlags::NO_WS
) == XMLShapeExportFlags::NONE
); // #86116#/#92210#
2131 SvXMLElementExport
aOBJ(mrExport
, XML_NAMESPACE_DRAW
, XML_RECT
, bCreateNewline
, true);
2133 ImpExportDescription( xShape
); // #i68101#
2134 ImpExportEvents( xShape
);
2135 ImpExportGluePoints( xShape
);
2136 ImpExportText( xShape
);
2139 void XMLShapeExport::ImpExportLineShape(
2140 const uno::Reference
< drawing::XShape
>& xShape
,
2141 XMLShapeExportFlags nFeatures
, awt::Point
* pRefPoint
)
2143 const uno::Reference
< beans::XPropertySet
> xPropSet(xShape
, uno::UNO_QUERY
);
2148 OUStringBuffer sStringBuffer
;
2149 awt::Point
aStart(0,0);
2150 awt::Point
aEnd(1,1);
2152 // #85920# use 'Geometry' to get the points of the line
2153 // since this slot take anchor pos into account.
2156 ::basegfx::B2DHomMatrix aMatrix
;
2157 ImpExportNewTrans_GetB2DHomMatrix(aMatrix
, xPropSet
);
2159 // decompose and correct about pRefPoint
2160 ::basegfx::B2DTuple aTRScale
;
2161 double fTRShear(0.0);
2162 double fTRRotate(0.0);
2163 ::basegfx::B2DTuple aTRTranslate
;
2164 ImpExportNewTrans_DecomposeAndRefPoint(aMatrix
, aTRScale
, fTRShear
, fTRRotate
, aTRTranslate
, pRefPoint
);
2166 // create base position
2167 awt::Point
aBasePosition(FRound(aTRTranslate
.getX()), FRound(aTRTranslate
.getY()));
2169 if (xPropSet
->getPropertySetInfo()->hasPropertyByName("Geometry"))
2171 // get the two points
2172 uno::Any
aAny(xPropSet
->getPropertyValue("Geometry"));
2173 if (auto pSourcePolyPolygon
2174 = o3tl::tryAccess
<drawing::PointSequenceSequence
>(aAny
))
2176 if (pSourcePolyPolygon
->getLength() > 0)
2178 const drawing::PointSequence
& rInnerSequence
= (*pSourcePolyPolygon
)[0];
2179 if (rInnerSequence
.hasElements())
2181 const awt::Point
& rPoint
= rInnerSequence
[0];
2182 aStart
= awt::Point(rPoint
.X
+ aBasePosition
.X
, rPoint
.Y
+ aBasePosition
.Y
);
2184 if (rInnerSequence
.getLength() > 1)
2186 const awt::Point
& rPoint
= rInnerSequence
[1];
2187 aEnd
= awt::Point(rPoint
.X
+ aBasePosition
.X
, rPoint
.Y
+ aBasePosition
.Y
);
2193 if( nFeatures
& XMLShapeExportFlags::X
)
2196 mrExport
.GetMM100UnitConverter().convertMeasureToXML(sStringBuffer
,
2198 aStr
= sStringBuffer
.makeStringAndClear();
2199 mrExport
.AddAttribute(XML_NAMESPACE_SVG
, XML_X1
, aStr
);
2206 if( nFeatures
& XMLShapeExportFlags::Y
)
2209 mrExport
.GetMM100UnitConverter().convertMeasureToXML(sStringBuffer
,
2211 aStr
= sStringBuffer
.makeStringAndClear();
2212 mrExport
.AddAttribute(XML_NAMESPACE_SVG
, XML_Y1
, aStr
);
2220 mrExport
.GetMM100UnitConverter().convertMeasureToXML(sStringBuffer
,
2222 aStr
= sStringBuffer
.makeStringAndClear();
2223 mrExport
.AddAttribute(XML_NAMESPACE_SVG
, XML_X2
, aStr
);
2226 mrExport
.GetMM100UnitConverter().convertMeasureToXML(sStringBuffer
,
2228 aStr
= sStringBuffer
.makeStringAndClear();
2229 mrExport
.AddAttribute(XML_NAMESPACE_SVG
, XML_Y2
, aStr
);
2232 bool bCreateNewline( (nFeatures
& XMLShapeExportFlags::NO_WS
) == XMLShapeExportFlags::NONE
); // #86116#/#92210#
2233 SvXMLElementExport
aOBJ(mrExport
, XML_NAMESPACE_DRAW
, XML_LINE
, bCreateNewline
, true);
2235 ImpExportDescription( xShape
); // #i68101#
2236 ImpExportEvents( xShape
);
2237 ImpExportGluePoints( xShape
);
2238 ImpExportText( xShape
);
2242 void XMLShapeExport::ImpExportEllipseShape(
2243 const uno::Reference
< drawing::XShape
>& xShape
,
2244 XMLShapeExportFlags nFeatures
, awt::Point
* pRefPoint
)
2246 const uno::Reference
< beans::XPropertySet
> xPropSet(xShape
, uno::UNO_QUERY
);
2250 // get size to decide between Circle and Ellipse
2251 awt::Size aSize
= xShape
->getSize();
2252 sal_Int32
nRx((aSize
.Width
+ 1) / 2);
2253 sal_Int32
nRy((aSize
.Height
+ 1) / 2);
2254 bool bCircle(nRx
== nRy
);
2257 ImpExportNewTrans(xPropSet
, nFeatures
, pRefPoint
);
2259 drawing::CircleKind eKind
= drawing::CircleKind_FULL
;
2260 xPropSet
->getPropertyValue("CircleKind") >>= eKind
;
2261 if( eKind
!= drawing::CircleKind_FULL
)
2263 OUStringBuffer sStringBuffer
;
2264 sal_Int32 nStartAngle
= 0;
2265 sal_Int32 nEndAngle
= 0;
2266 xPropSet
->getPropertyValue("CircleStartAngle") >>= nStartAngle
;
2267 xPropSet
->getPropertyValue("CircleEndAngle") >>= nEndAngle
;
2269 const double dStartAngle
= nStartAngle
/ 100.0;
2270 const double dEndAngle
= nEndAngle
/ 100.0;
2272 // export circle kind
2273 SvXMLUnitConverter::convertEnum( sStringBuffer
, eKind
, aXML_CircleKind_EnumMap
);
2274 mrExport
.AddAttribute(XML_NAMESPACE_DRAW
, XML_KIND
, sStringBuffer
.makeStringAndClear() );
2276 // export start angle
2277 ::sax::Converter::convertDouble( sStringBuffer
, dStartAngle
);
2278 mrExport
.AddAttribute(XML_NAMESPACE_DRAW
, XML_START_ANGLE
, sStringBuffer
.makeStringAndClear() );
2281 ::sax::Converter::convertDouble( sStringBuffer
, dEndAngle
);
2282 mrExport
.AddAttribute(XML_NAMESPACE_DRAW
, XML_END_ANGLE
, sStringBuffer
.makeStringAndClear() );
2285 bool bCreateNewline( (nFeatures
& XMLShapeExportFlags::NO_WS
) == XMLShapeExportFlags::NONE
); // #86116#/#92210#
2287 // write ellipse or circle
2288 SvXMLElementExport
aOBJ(mrExport
, XML_NAMESPACE_DRAW
,
2289 bCircle
? XML_CIRCLE
: XML_ELLIPSE
,
2290 bCreateNewline
, true);
2292 ImpExportDescription( xShape
); // #i68101#
2293 ImpExportEvents( xShape
);
2294 ImpExportGluePoints( xShape
);
2295 ImpExportText( xShape
);
2299 void XMLShapeExport::ImpExportPolygonShape(
2300 const uno::Reference
< drawing::XShape
>& xShape
,
2301 XmlShapeType eShapeType
, XMLShapeExportFlags nFeatures
, awt::Point
* pRefPoint
)
2303 const uno::Reference
< beans::XPropertySet
> xPropSet(xShape
, uno::UNO_QUERY
);
2307 bool bBezier(eShapeType
== XmlShapeType::DrawClosedBezierShape
2308 || eShapeType
== XmlShapeType::DrawOpenBezierShape
);
2311 ::basegfx::B2DHomMatrix aMatrix
;
2312 ImpExportNewTrans_GetB2DHomMatrix(aMatrix
, xPropSet
);
2314 // decompose and correct about pRefPoint
2315 ::basegfx::B2DTuple aTRScale
;
2316 double fTRShear(0.0);
2317 double fTRRotate(0.0);
2318 ::basegfx::B2DTuple aTRTranslate
;
2319 ImpExportNewTrans_DecomposeAndRefPoint(aMatrix
, aTRScale
, fTRShear
, fTRRotate
, aTRTranslate
, pRefPoint
);
2321 // use features and write
2322 ImpExportNewTrans_FeaturesAndWrite(aTRScale
, fTRShear
, fTRRotate
, aTRTranslate
, nFeatures
);
2324 // create and export ViewBox
2325 awt::Size
aSize(FRound(aTRScale
.getX()), FRound(aTRScale
.getY()));
2326 SdXMLImExViewBox
aViewBox(0, 0, aSize
.Width
, aSize
.Height
);
2327 mrExport
.AddAttribute(XML_NAMESPACE_SVG
, XML_VIEWBOX
, aViewBox
.GetExportString());
2329 bool bCreateNewline( (nFeatures
& XMLShapeExportFlags::NO_WS
) == XMLShapeExportFlags::NONE
); // #86116#/#92210#
2331 // prepare name (with most used)
2332 enum ::xmloff::token::XMLTokenEnum
eName(XML_PATH
);
2334 uno::Any
aAny( xPropSet
->getPropertyValue("Geometry") );
2335 basegfx::B2DPolyPolygon aPolyPolygon
;
2337 // tdf#145240 the Any can contain PolyPolygonBezierCoords or PointSequenceSequence
2338 // (see OWN_ATTR_BASE_GEOMETRY in SvxShapePolyPolygon::getPropertyValueImpl),
2339 // so be more flexible in interpreting it. Try to access bezier first:
2341 auto pSourcePolyPolygon
= o3tl::tryAccess
<drawing::PolyPolygonBezierCoords
>(aAny
);
2343 if(pSourcePolyPolygon
&& pSourcePolyPolygon
->Coordinates
.getLength())
2345 aPolyPolygon
= basegfx::utils::UnoPolyPolygonBezierCoordsToB2DPolyPolygon(*pSourcePolyPolygon
);
2349 // if received no data, try to access point sequence second:
2350 if(0 == aPolyPolygon
.count())
2352 auto pSourcePolyPolygon
= o3tl::tryAccess
<drawing::PointSequenceSequence
>(aAny
);
2354 if(pSourcePolyPolygon
)
2356 aPolyPolygon
= basegfx::utils::UnoPointSequenceSequenceToB2DPolyPolygon(*pSourcePolyPolygon
);
2360 if(aPolyPolygon
.count())
2362 if(!bBezier
&& !aPolyPolygon
.areControlPointsUsed() && 1 == aPolyPolygon
.count())
2364 // simple polygon shape, can be written as svg:points sequence
2365 const basegfx::B2DPolygon
& aPolygon(aPolyPolygon
.getB2DPolygon(0));
2366 const OUString
aPointString(basegfx::utils::exportToSvgPoints(aPolygon
));
2368 // write point array
2369 mrExport
.AddAttribute(XML_NAMESPACE_DRAW
, XML_POINTS
, aPointString
);
2372 eName
= aPolygon
.isClosed() ? XML_POLYGON
: XML_POLYLINE
;
2376 // complex polygon shape, write as svg:d
2377 const OUString
aPolygonString(
2378 basegfx::utils::exportToSvgD(
2380 true, // bUseRelativeCoordinates
2381 false, // bDetectQuadraticBeziers: not used in old, but maybe activated now
2382 true)); // bHandleRelativeNextPointCompatible
2384 // write point array
2385 mrExport
.AddAttribute(XML_NAMESPACE_SVG
, XML_D
, aPolygonString
);
2389 // write object, but after attributes are added since this call will
2390 // consume all of these added attributes and the destructor will close the
2391 // scope. Also before text is added; this may add sub-scopes as needed
2392 SvXMLElementExport
aOBJ(
2399 ImpExportDescription( xShape
); // #i68101#
2400 ImpExportEvents( xShape
);
2401 ImpExportGluePoints( xShape
);
2402 ImpExportText( xShape
);
2409 OUString
getNameFromStreamURL(std::u16string_view rURL
)
2411 static constexpr std::u16string_view
sPackageURL(u
"vnd.sun.star.Package:");
2415 if (o3tl::starts_with(rURL
, sPackageURL
))
2417 std::u16string_view sRequestedName
= rURL
.substr(sPackageURL
.size());
2418 size_t nLastIndex
= sRequestedName
.rfind('/') + 1;
2419 if ((nLastIndex
> 0) && (nLastIndex
< sRequestedName
.size()))
2420 sRequestedName
= sRequestedName
.substr(nLastIndex
);
2421 nLastIndex
= sRequestedName
.rfind('.');
2422 if (nLastIndex
!= std::u16string_view::npos
)
2423 sRequestedName
= sRequestedName
.substr(0, nLastIndex
);
2424 if (!sRequestedName
.empty())
2425 sResult
= sRequestedName
;
2431 } // end anonymous namespace
2433 void XMLShapeExport::ImpExportGraphicObjectShape(
2434 const uno::Reference
< drawing::XShape
>& xShape
,
2435 XmlShapeType eShapeType
, XMLShapeExportFlags nFeatures
, awt::Point
* pRefPoint
)
2437 const uno::Reference
< beans::XPropertySet
> xPropSet(xShape
, uno::UNO_QUERY
);
2441 bool bIsEmptyPresObj
= false;
2444 ImpExportNewTrans(xPropSet
, nFeatures
, pRefPoint
);
2446 if(eShapeType
== XmlShapeType::PresGraphicObjectShape
)
2447 bIsEmptyPresObj
= ImpExportPresentationAttributes( xPropSet
, GetXMLToken(XML_GRAPHIC
) );
2449 bool bCreateNewline( (nFeatures
& XMLShapeExportFlags::NO_WS
) == XMLShapeExportFlags::NONE
); // #86116#/#92210#
2450 SvXMLElementExport
aElem( mrExport
, XML_NAMESPACE_DRAW
,
2451 XML_FRAME
, bCreateNewline
, true );
2453 if (!bIsEmptyPresObj
)
2455 uno::Reference
<graphic::XGraphic
> xGraphic
;
2456 OUString sOutMimeType
;
2459 OUString aStreamURL
;
2460 xPropSet
->getPropertyValue("GraphicStreamURL") >>= aStreamURL
;
2461 OUString sRequestedName
= getNameFromStreamURL(aStreamURL
);
2463 xPropSet
->getPropertyValue("Graphic") >>= xGraphic
;
2465 OUString sInternalURL
;
2468 sInternalURL
= mrExport
.AddEmbeddedXGraphic(xGraphic
, sOutMimeType
, sRequestedName
);
2470 if (!sInternalURL
.isEmpty())
2472 // apply possible changed stream URL to embedded image object
2473 if (!sRequestedName
.isEmpty())
2475 OUString newStreamURL
= "vnd.sun.star.Package:";
2476 if (sInternalURL
[0] == '#')
2478 newStreamURL
+= sInternalURL
.subView(1, sInternalURL
.getLength() - 1);
2482 newStreamURL
+= sInternalURL
;
2485 if (newStreamURL
!= aStreamURL
)
2487 xPropSet
->setPropertyValue("GraphicStreamURL", uno::Any(newStreamURL
));
2491 mrExport
.AddAttribute(XML_NAMESPACE_XLINK
, XML_HREF
, sInternalURL
);
2492 mrExport
.AddAttribute(XML_NAMESPACE_XLINK
, XML_TYPE
, XML_SIMPLE
);
2493 mrExport
.AddAttribute(XML_NAMESPACE_XLINK
, XML_SHOW
, XML_EMBED
);
2494 mrExport
.AddAttribute(XML_NAMESPACE_XLINK
, XML_ACTUATE
, XML_ONLOAD
);
2499 if (GetExport().getSaneDefaultVersion() > SvtSaveOptions::ODFSVER_012
)
2501 if (sOutMimeType
.isEmpty())
2503 GetExport().GetGraphicMimeTypeFromStream(xGraphic
, sOutMimeType
);
2505 if (!sOutMimeType
.isEmpty())
2506 { // ODF 1.3 OFFICE-3943
2507 GetExport().AddAttribute(
2508 SvtSaveOptions::ODFSVER_013
<= GetExport().getSaneDefaultVersion()
2509 ? XML_NAMESPACE_DRAW
2510 : XML_NAMESPACE_LO_EXT
,
2511 "mime-type", sOutMimeType
);
2515 SvXMLElementExport
aElement(mrExport
, XML_NAMESPACE_DRAW
, XML_IMAGE
, true, true);
2517 // optional office:binary-data
2520 mrExport
.AddEmbeddedXGraphicAsBase64(xGraphic
);
2522 if (!bIsEmptyPresObj
)
2523 ImpExportText(xShape
);
2526 //Resolves: fdo#62461 put preferred image first above, followed by
2528 const bool bAddReplacementImages
= officecfg::Office::Common::Save::Graphic::AddReplacementImages::get();
2529 if( !bIsEmptyPresObj
&& bAddReplacementImages
)
2531 uno::Reference
<graphic::XGraphic
> xReplacementGraphic
;
2532 xPropSet
->getPropertyValue("ReplacementGraphic") >>= xReplacementGraphic
;
2534 // If there is no url, then the graphic is empty
2535 if (xReplacementGraphic
.is())
2538 const OUString aHref
= mrExport
.AddEmbeddedXGraphic(xReplacementGraphic
, aMimeType
);
2540 if (aMimeType
.isEmpty())
2541 mrExport
.GetGraphicMimeTypeFromStream(xReplacementGraphic
, aMimeType
);
2543 if (!aHref
.isEmpty())
2545 mrExport
.AddAttribute(XML_NAMESPACE_XLINK
, XML_HREF
, aHref
);
2546 mrExport
.AddAttribute(XML_NAMESPACE_XLINK
, XML_TYPE
, XML_SIMPLE
);
2547 mrExport
.AddAttribute(XML_NAMESPACE_XLINK
, XML_SHOW
, XML_EMBED
);
2548 mrExport
.AddAttribute(XML_NAMESPACE_XLINK
, XML_ACTUATE
, XML_ONLOAD
);
2551 if (!aMimeType
.isEmpty() && GetExport().getSaneDefaultVersion() > SvtSaveOptions::ODFSVER_012
)
2552 { // ODF 1.3 OFFICE-3943
2553 mrExport
.AddAttribute(
2554 SvtSaveOptions::ODFSVER_013
<= GetExport().getSaneDefaultVersion()
2555 ? XML_NAMESPACE_DRAW
2556 : XML_NAMESPACE_LO_EXT
,
2557 "mime-type", aMimeType
);
2560 SvXMLElementExport
aElement(mrExport
, XML_NAMESPACE_DRAW
, XML_IMAGE
, true, true);
2562 // optional office:binary-data
2563 mrExport
.AddEmbeddedXGraphicAsBase64(xReplacementGraphic
);
2568 ImpExportEvents( xShape
);
2569 ImpExportGluePoints( xShape
);
2572 GetExport().GetImageMapExport().Export( xPropSet
);
2573 ImpExportDescription( xShape
); // #i68101#
2575 // Signature Line, QR Code - needs to be after the images!
2576 if (GetExport().getSaneDefaultVersion() & SvtSaveOptions::ODFSVER_EXTENDED
)
2578 ImpExportSignatureLine(xShape
);
2579 ImpExportQRCode(xShape
);
2583 void XMLShapeExport::ImpExportChartShape(
2584 const uno::Reference
< drawing::XShape
>& xShape
,
2585 XmlShapeType eShapeType
, XMLShapeExportFlags nFeatures
, awt::Point
* pRefPoint
,
2586 comphelper::AttributeList
* pAttrList
)
2588 ImpExportOLE2Shape( xShape
, eShapeType
, nFeatures
, pRefPoint
, pAttrList
);
2591 void XMLShapeExport::ImpExportControlShape(
2592 const uno::Reference
< drawing::XShape
>& xShape
,
2593 XMLShapeExportFlags nFeatures
, awt::Point
* pRefPoint
)
2595 const uno::Reference
< beans::XPropertySet
> xPropSet(xShape
, uno::UNO_QUERY
);
2599 ImpExportNewTrans(xPropSet
, nFeatures
, pRefPoint
);
2602 uno::Reference
< drawing::XControlShape
> xControl( xShape
, uno::UNO_QUERY
);
2603 SAL_WARN_IF( !xControl
.is(), "xmloff", "Control shape is not supporting XControlShape" );
2606 uno::Reference
< beans::XPropertySet
> xControlModel( xControl
->getControl(), uno::UNO_QUERY
);
2607 SAL_WARN_IF( !xControlModel
.is(), "xmloff", "Control shape has not XControlModel" );
2608 if( xControlModel
.is() )
2610 OUString sControlId
= mrExport
.GetFormExport()->getControlId( xControlModel
);
2611 mrExport
.AddAttribute( XML_NAMESPACE_DRAW
, XML_CONTROL
, sControlId
);
2615 bool bCreateNewline( (nFeatures
& XMLShapeExportFlags::NO_WS
) == XMLShapeExportFlags::NONE
); // #86116#/#92210#
2616 SvXMLElementExport
aOBJ(mrExport
, XML_NAMESPACE_DRAW
, XML_CONTROL
, bCreateNewline
, true);
2618 ImpExportDescription( xShape
); // #i68101#
2621 void XMLShapeExport::ImpExportConnectorShape(
2622 const uno::Reference
< drawing::XShape
>& xShape
,
2623 XMLShapeExportFlags nFeatures
/* = SEF_DEFAULT */, awt::Point
* pRefPoint
/* = NULL */)
2625 uno::Reference
< beans::XPropertySet
> xProps( xShape
, uno::UNO_QUERY
);
2628 OUStringBuffer sStringBuffer
;
2630 // export connection kind
2631 drawing::ConnectorType eType
= drawing::ConnectorType_STANDARD
;
2632 uno::Any aAny
= xProps
->getPropertyValue("EdgeKind");
2635 if( eType
!= drawing::ConnectorType_STANDARD
)
2637 SvXMLUnitConverter::convertEnum( sStringBuffer
, eType
, aXML_ConnectionKind_EnumMap
);
2638 aStr
= sStringBuffer
.makeStringAndClear();
2639 mrExport
.AddAttribute(XML_NAMESPACE_DRAW
, XML_TYPE
, aStr
);
2643 sal_Int32 nDelta1
= 0, nDelta2
= 0, nDelta3
= 0;
2645 aAny
= xProps
->getPropertyValue("EdgeLine1Delta");
2647 aAny
= xProps
->getPropertyValue("EdgeLine2Delta");
2649 aAny
= xProps
->getPropertyValue("EdgeLine3Delta");
2652 if( nDelta1
!= 0 || nDelta2
!= 0 || nDelta3
!= 0 )
2654 mrExport
.GetMM100UnitConverter().convertMeasureToXML(sStringBuffer
,
2656 if( nDelta2
!= 0 || nDelta3
!= 0 )
2658 sStringBuffer
.append( ' ' );
2659 mrExport
.GetMM100UnitConverter().convertMeasureToXML(sStringBuffer
,
2663 sStringBuffer
.append( ' ' );
2664 mrExport
.GetMM100UnitConverter().convertMeasureToXML(
2665 sStringBuffer
, nDelta3
);
2669 aStr
= sStringBuffer
.makeStringAndClear();
2670 mrExport
.AddAttribute(XML_NAMESPACE_DRAW
, XML_LINE_SKEW
, aStr
);
2673 // export start and end point
2674 awt::Point
aStart(0,0);
2675 awt::Point
aEnd(1,1);
2677 /* Get <StartPositionInHoriL2R> and
2678 <EndPositionInHoriL2R>, if they exist and if the document is exported
2679 into the OpenOffice.org file format.
2680 These properties only exist at service css::text::Shape - the
2681 Writer UNO service for shapes.
2682 This code is needed, because the positioning attributes in the
2683 OpenOffice.org file format are given in horizontal left-to-right layout
2684 regardless the layout direction the shape is in. In the OASIS Open Office
2685 file format the positioning attributes are correctly given in the layout
2686 direction the shape is in. Thus, this code provides the conversion from
2687 the OASIS Open Office file format to the OpenOffice.org file format. (#i36248#)
2689 if ( !( GetExport().getExportFlags() & SvXMLExportFlags::OASIS
) &&
2690 xProps
->getPropertySetInfo()->hasPropertyByName("StartPositionInHoriL2R") &&
2691 xProps
->getPropertySetInfo()->hasPropertyByName("EndPositionInHoriL2R") )
2693 xProps
->getPropertyValue("StartPositionInHoriL2R") >>= aStart
;
2694 xProps
->getPropertyValue("EndPositionInHoriL2R") >>= aEnd
;
2698 xProps
->getPropertyValue("StartPosition") >>= aStart
;
2699 xProps
->getPropertyValue("EndPosition") >>= aEnd
;
2704 aStart
.X
-= pRefPoint
->X
;
2705 aStart
.Y
-= pRefPoint
->Y
;
2706 aEnd
.X
-= pRefPoint
->X
;
2707 aEnd
.Y
-= pRefPoint
->Y
;
2710 if( nFeatures
& XMLShapeExportFlags::X
)
2713 mrExport
.GetMM100UnitConverter().convertMeasureToXML(sStringBuffer
,
2715 aStr
= sStringBuffer
.makeStringAndClear();
2716 mrExport
.AddAttribute(XML_NAMESPACE_SVG
, XML_X1
, aStr
);
2723 if( nFeatures
& XMLShapeExportFlags::Y
)
2726 mrExport
.GetMM100UnitConverter().convertMeasureToXML(sStringBuffer
,
2728 aStr
= sStringBuffer
.makeStringAndClear();
2729 mrExport
.AddAttribute(XML_NAMESPACE_SVG
, XML_Y1
, aStr
);
2737 mrExport
.GetMM100UnitConverter().convertMeasureToXML(sStringBuffer
, aEnd
.X
);
2738 aStr
= sStringBuffer
.makeStringAndClear();
2739 mrExport
.AddAttribute(XML_NAMESPACE_SVG
, XML_X2
, aStr
);
2742 mrExport
.GetMM100UnitConverter().convertMeasureToXML(sStringBuffer
, aEnd
.Y
);
2743 aStr
= sStringBuffer
.makeStringAndClear();
2744 mrExport
.AddAttribute(XML_NAMESPACE_SVG
, XML_Y2
, aStr
);
2747 uno::Reference
< uno::XInterface
> xRefS
;
2748 uno::Reference
< uno::XInterface
> xRefE
;
2750 // export start connection
2751 xProps
->getPropertyValue("StartShape") >>= xRefS
;
2754 const OUString
& rShapeId
= mrExport
.getInterfaceToIdentifierMapper().getIdentifier( xRefS
);
2755 mrExport
.AddAttribute(XML_NAMESPACE_DRAW
, XML_START_SHAPE
, rShapeId
);
2757 aAny
= xProps
->getPropertyValue("StartGluePointIndex");
2758 sal_Int32 nGluePointId
= 0;
2759 if( aAny
>>= nGluePointId
)
2761 if( nGluePointId
!= -1 )
2763 mrExport
.AddAttribute(XML_NAMESPACE_DRAW
, XML_START_GLUE_POINT
, OUString::number( nGluePointId
));
2768 // export end connection
2769 xProps
->getPropertyValue("EndShape") >>= xRefE
;
2772 const OUString
& rShapeId
= mrExport
.getInterfaceToIdentifierMapper().getIdentifier( xRefE
);
2773 mrExport
.AddAttribute(XML_NAMESPACE_DRAW
, XML_END_SHAPE
, rShapeId
);
2775 aAny
= xProps
->getPropertyValue("EndGluePointIndex");
2776 sal_Int32 nGluePointId
= 0;
2777 if( aAny
>>= nGluePointId
)
2779 if( nGluePointId
!= -1 )
2781 mrExport
.AddAttribute(XML_NAMESPACE_DRAW
, XML_END_GLUE_POINT
, OUString::number( nGluePointId
));
2786 // get PolygonBezier
2787 aAny
= xProps
->getPropertyValue("PolyPolygonBezier");
2788 auto pSourcePolyPolygon
= o3tl::tryAccess
<drawing::PolyPolygonBezierCoords
>(aAny
);
2789 if(pSourcePolyPolygon
&& pSourcePolyPolygon
->Coordinates
.getLength())
2791 const basegfx::B2DPolyPolygon
aPolyPolygon(
2792 basegfx::utils::UnoPolyPolygonBezierCoordsToB2DPolyPolygon(
2793 *pSourcePolyPolygon
));
2794 const OUString
aPolygonString(
2795 basegfx::utils::exportToSvgD(
2797 true, // bUseRelativeCoordinates
2798 false, // bDetectQuadraticBeziers: not used in old, but maybe activated now
2799 true)); // bHandleRelativeNextPointCompatible
2801 // write point array
2802 mrExport
.AddAttribute(XML_NAMESPACE_SVG
, XML_D
, aPolygonString
);
2806 ::basegfx::B2DHomMatrix aMatrix
;
2807 ImpExportNewTrans_GetB2DHomMatrix(aMatrix
, xProps
);
2809 // decompose and correct about pRefPoint
2810 ::basegfx::B2DTuple aTRScale
;
2811 double fTRShear(0.0);
2812 double fTRRotate(0.0);
2813 ::basegfx::B2DTuple aTRTranslate
;
2814 ImpExportNewTrans_DecomposeAndRefPoint(aMatrix
, aTRScale
, fTRShear
,
2815 fTRRotate
, aTRTranslate
, pRefPoint
);
2817 // fdo#49678: create and export ViewBox
2818 awt::Size
aSize(FRound(aTRScale
.getX()), FRound(aTRScale
.getY()));
2819 SdXMLImExViewBox
aViewBox(0, 0, aSize
.Width
, aSize
.Height
);
2820 mrExport
.AddAttribute(XML_NAMESPACE_SVG
, XML_VIEWBOX
, aViewBox
.GetExportString());
2822 // write connector shape. Add Export later.
2823 bool bCreateNewline( (nFeatures
& XMLShapeExportFlags::NO_WS
) == XMLShapeExportFlags::NONE
); // #86116#/#92210#
2824 SvXMLElementExport
aOBJ(mrExport
, XML_NAMESPACE_DRAW
, XML_CONNECTOR
, bCreateNewline
, true);
2826 ImpExportDescription( xShape
); // #i68101#
2827 ImpExportEvents( xShape
);
2828 ImpExportGluePoints( xShape
);
2829 ImpExportText( xShape
);
2832 void XMLShapeExport::ImpExportMeasureShape(
2833 const uno::Reference
< drawing::XShape
>& xShape
,
2834 XMLShapeExportFlags nFeatures
/* = SEF_DEFAULT */, awt::Point
const * pRefPoint
/* = NULL */)
2836 uno::Reference
< beans::XPropertySet
> xProps( xShape
, uno::UNO_QUERY
);
2839 OUStringBuffer sStringBuffer
;
2841 // export start and end point
2842 awt::Point
aStart(0,0);
2843 awt::Point
aEnd(1,1);
2845 /* Get <StartPositionInHoriL2R> and
2846 <EndPositionInHoriL2R>, if they exist and if the document is exported
2847 into the OpenOffice.org file format.
2848 These properties only exist at service css::text::Shape - the
2849 Writer UNO service for shapes.
2850 This code is needed, because the positioning attributes in the
2851 OpenOffice.org file format are given in horizontal left-to-right layout
2852 regardless the layout direction the shape is in. In the OASIS Open Office
2853 file format the positioning attributes are correctly given in the layout
2854 direction the shape is in. Thus, this code provides the conversion from
2855 the OASIS Open Office file format to the OpenOffice.org file format. (#i36248#)
2857 if ( !( GetExport().getExportFlags() & SvXMLExportFlags::OASIS
) &&
2858 xProps
->getPropertySetInfo()->hasPropertyByName("StartPositionInHoriL2R") &&
2859 xProps
->getPropertySetInfo()->hasPropertyByName("EndPositionInHoriL2R") )
2861 xProps
->getPropertyValue("StartPositionInHoriL2R") >>= aStart
;
2862 xProps
->getPropertyValue("EndPositionInHoriL2R") >>= aEnd
;
2866 xProps
->getPropertyValue("StartPosition") >>= aStart
;
2867 xProps
->getPropertyValue("EndPosition") >>= aEnd
;
2872 aStart
.X
-= pRefPoint
->X
;
2873 aStart
.Y
-= pRefPoint
->Y
;
2874 aEnd
.X
-= pRefPoint
->X
;
2875 aEnd
.Y
-= pRefPoint
->Y
;
2878 if( nFeatures
& XMLShapeExportFlags::X
)
2881 mrExport
.GetMM100UnitConverter().convertMeasureToXML(sStringBuffer
,
2883 aStr
= sStringBuffer
.makeStringAndClear();
2884 mrExport
.AddAttribute(XML_NAMESPACE_SVG
, XML_X1
, aStr
);
2891 if( nFeatures
& XMLShapeExportFlags::Y
)
2894 mrExport
.GetMM100UnitConverter().convertMeasureToXML(sStringBuffer
,
2896 aStr
= sStringBuffer
.makeStringAndClear();
2897 mrExport
.AddAttribute(XML_NAMESPACE_SVG
, XML_Y1
, aStr
);
2905 mrExport
.GetMM100UnitConverter().convertMeasureToXML(sStringBuffer
, aEnd
.X
);
2906 aStr
= sStringBuffer
.makeStringAndClear();
2907 mrExport
.AddAttribute(XML_NAMESPACE_SVG
, XML_X2
, aStr
);
2910 mrExport
.GetMM100UnitConverter().convertMeasureToXML(sStringBuffer
, aEnd
.Y
);
2911 aStr
= sStringBuffer
.makeStringAndClear();
2912 mrExport
.AddAttribute(XML_NAMESPACE_SVG
, XML_Y2
, aStr
);
2914 // write measure shape
2915 bool bCreateNewline( (nFeatures
& XMLShapeExportFlags::NO_WS
) == XMLShapeExportFlags::NONE
); // #86116#/#92210#
2916 SvXMLElementExport
aOBJ(mrExport
, XML_NAMESPACE_DRAW
, XML_MEASURE
, bCreateNewline
, true);
2918 ImpExportDescription( xShape
); // #i68101#
2919 ImpExportEvents( xShape
);
2920 ImpExportGluePoints( xShape
);
2922 uno::Reference
< text::XText
> xText( xShape
, uno::UNO_QUERY
);
2924 mrExport
.GetTextParagraphExport()->exportText( xText
);
2927 void XMLShapeExport::ImpExportOLE2Shape(
2928 const uno::Reference
< drawing::XShape
>& xShape
,
2929 XmlShapeType eShapeType
, XMLShapeExportFlags nFeatures
/* = SEF_DEFAULT */, awt::Point
* pRefPoint
/* = NULL */,
2930 comphelper::AttributeList
* pAttrList
/* = NULL */ )
2932 uno::Reference
< beans::XPropertySet
> xPropSet(xShape
, uno::UNO_QUERY
);
2933 uno::Reference
< container::XNamed
> xNamed(xShape
, uno::UNO_QUERY
);
2935 SAL_WARN_IF( !xPropSet
.is() || !xNamed
.is(), "xmloff", "ole shape is not implementing needed interfaces");
2936 if(!(xPropSet
.is() && xNamed
.is()))
2940 ImpExportNewTrans(xPropSet
, nFeatures
, pRefPoint
);
2942 bool bIsEmptyPresObj
= false;
2944 // presentation settings
2945 if(eShapeType
== XmlShapeType::PresOLE2Shape
)
2946 bIsEmptyPresObj
= ImpExportPresentationAttributes( xPropSet
, GetXMLToken(XML_OBJECT
) );
2947 else if(eShapeType
== XmlShapeType::PresChartShape
)
2948 bIsEmptyPresObj
= ImpExportPresentationAttributes( xPropSet
, GetXMLToken(XML_CHART
) );
2949 else if(eShapeType
== XmlShapeType::PresSheetShape
)
2950 bIsEmptyPresObj
= ImpExportPresentationAttributes( xPropSet
, GetXMLToken(XML_TABLE
) );
2952 bool bCreateNewline( (nFeatures
& XMLShapeExportFlags::NO_WS
) == XMLShapeExportFlags::NONE
); // #86116#/#92210#
2953 bool bExportEmbedded(mrExport
.getExportFlags() & SvXMLExportFlags::EMBEDDED
);
2954 OUString sPersistName
;
2955 SvXMLElementExport
aElement( mrExport
, XML_NAMESPACE_DRAW
,
2956 XML_FRAME
, bCreateNewline
, true );
2958 if (!bIsEmptyPresObj
)
2962 mrExport
.AddAttributeList(pAttrList
);
2967 bool bInternal
= false;
2968 xPropSet
->getPropertyValue("IsInternal") >>= bInternal
;
2974 // OOo internal links have no storage persistence, URL is stored in the XML file
2975 // the result LinkURL is empty in case the object is not a link
2976 xPropSet
->getPropertyValue("LinkURL") >>= sURL
;
2979 xPropSet
->getPropertyValue("PersistName") >>= sPersistName
;
2980 if ( sURL
.isEmpty() )
2982 if( !sPersistName
.isEmpty() )
2984 sURL
= "vnd.sun.star.EmbeddedObject:" + sPersistName
;
2989 xPropSet
->getPropertyValue("CLSID") >>= sClassId
;
2991 if( !sClassId
.isEmpty() )
2992 mrExport
.AddAttribute(XML_NAMESPACE_DRAW
, XML_CLASS_ID
, sClassId
);
2994 if(!bExportEmbedded
)
2997 if( !sURL
.isEmpty() )
2999 // #96717# in theorie, if we don't have a URL we shouldn't even
3000 // export this OLE shape. But practically it's too risky right now
3001 // to change this so we better dispose this on load
3002 sURL
= mrExport
.AddEmbeddedObject( sURL
);
3004 mrExport
.AddAttribute(XML_NAMESPACE_XLINK
, XML_HREF
, sURL
);
3005 mrExport
.AddAttribute( XML_NAMESPACE_XLINK
, XML_TYPE
, XML_SIMPLE
);
3006 mrExport
.AddAttribute( XML_NAMESPACE_XLINK
, XML_SHOW
, XML_EMBED
);
3007 mrExport
.AddAttribute( XML_NAMESPACE_XLINK
, XML_ACTUATE
, XML_ONLOAD
);
3011 // tdf#153179 Export the preview graphic of the object if the object is missing.
3012 uno::Reference
<graphic::XGraphic
> xGraphic
;
3013 xPropSet
->getPropertyValue("Graphic") >>= xGraphic
;
3018 const OUString aHref
= mrExport
.AddEmbeddedXGraphic(xGraphic
, aMimeType
);
3020 if (aMimeType
.isEmpty())
3021 mrExport
.GetGraphicMimeTypeFromStream(xGraphic
, aMimeType
);
3023 if (!aHref
.isEmpty())
3025 mrExport
.AddAttribute(XML_NAMESPACE_XLINK
, XML_HREF
, aHref
);
3026 mrExport
.AddAttribute(XML_NAMESPACE_XLINK
, XML_TYPE
, XML_SIMPLE
);
3027 mrExport
.AddAttribute(XML_NAMESPACE_XLINK
, XML_SHOW
, XML_EMBED
);
3028 mrExport
.AddAttribute(XML_NAMESPACE_XLINK
, XML_ACTUATE
, XML_ONLOAD
);
3031 if (!aMimeType
.isEmpty()
3032 && GetExport().getSaneDefaultVersion() > SvtSaveOptions::ODFSVER_012
)
3033 { // ODF 1.3 OFFICE-3943
3034 mrExport
.AddAttribute(SvtSaveOptions::ODFSVER_013
3035 <= GetExport().getSaneDefaultVersion()
3036 ? XML_NAMESPACE_DRAW
3037 : XML_NAMESPACE_LO_EXT
,
3038 "mime-type", aMimeType
);
3041 SvXMLElementExport
aImageElem(mrExport
, XML_NAMESPACE_DRAW
, XML_IMAGE
, true,
3044 // optional office:binary-data
3045 mrExport
.AddEmbeddedXGraphicAsBase64(xGraphic
);
3047 ImpExportEvents(xShape
);
3048 ImpExportGluePoints(xShape
);
3049 ImpExportDescription(xShape
);
3057 enum XMLTokenEnum eElem
= sClassId
.isEmpty() ? XML_OBJECT
: XML_OBJECT_OLE
;
3058 SvXMLElementExport
aElem( mrExport
, XML_NAMESPACE_DRAW
, eElem
, true, true );
3060 // tdf#112547 export text as child of draw:object, where import expects it
3061 if (!bIsEmptyPresObj
&& supportsText(eShapeType
))
3063 // #i118485# Add text export, the draw OLE shape allows text now
3064 ImpExportText( xShape
, TextPNS::EXTENSION
);
3067 if(bExportEmbedded
&& !bIsEmptyPresObj
)
3072 uno::Reference
< lang::XComponent
> xComp
;
3073 xPropSet
->getPropertyValue("Model") >>= xComp
;
3074 SAL_WARN_IF( !xComp
.is(), "xmloff", "no xModel for own OLE format" );
3075 mrExport
.ExportEmbeddedOwnObject( xComp
);
3080 // this is an alien object ( currently MSOLE is the only supported type of such objects )
3081 // in case it is not an OASIS format the object should be asked to store replacement image if possible
3083 OUString
sURLRequest( sURL
);
3084 if ( !( mrExport
.getExportFlags() & SvXMLExportFlags::OASIS
) )
3085 sURLRequest
+= "?oasis=false";
3086 mrExport
.AddEmbeddedObjectAsBase64( sURLRequest
);
3090 if( !bIsEmptyPresObj
)
3092 OUString sURL
= XML_EMBEDDEDOBJECTGRAPHIC_URL_BASE
+ sPersistName
;
3093 if( !bExportEmbedded
)
3095 sURL
= GetExport().AddEmbeddedObject( sURL
);
3096 mrExport
.AddAttribute(XML_NAMESPACE_XLINK
, XML_HREF
, sURL
);
3097 mrExport
.AddAttribute( XML_NAMESPACE_XLINK
, XML_TYPE
, XML_SIMPLE
);
3098 mrExport
.AddAttribute( XML_NAMESPACE_XLINK
, XML_SHOW
, XML_EMBED
);
3099 mrExport
.AddAttribute( XML_NAMESPACE_XLINK
, XML_ACTUATE
, XML_ONLOAD
);
3102 SvXMLElementExport
aElem( GetExport(), XML_NAMESPACE_DRAW
,
3103 XML_IMAGE
, false, true );
3105 if( bExportEmbedded
)
3106 GetExport().AddEmbeddedObjectAsBase64( sURL
);
3109 ImpExportEvents( xShape
);
3110 ImpExportGluePoints( xShape
);
3111 ImpExportDescription( xShape
); // #i68101#
3115 void XMLShapeExport::ImpExportPageShape(
3116 const uno::Reference
< drawing::XShape
>& xShape
,
3117 XmlShapeType eShapeType
, XMLShapeExportFlags nFeatures
/* = SEF_DEFAULT */, awt::Point
* pRefPoint
/* = NULL */)
3119 const uno::Reference
< beans::XPropertySet
> xPropSet(xShape
, uno::UNO_QUERY
);
3123 // #86163# Transformation
3124 ImpExportNewTrans(xPropSet
, nFeatures
, pRefPoint
);
3126 // export page number used for this page
3127 uno::Reference
< beans::XPropertySetInfo
> xPropSetInfo( xPropSet
->getPropertySetInfo() );
3128 static constexpr OUString
aPageNumberStr(u
"PageNumber"_ustr
);
3129 if( xPropSetInfo
.is() && xPropSetInfo
->hasPropertyByName(aPageNumberStr
))
3131 sal_Int32 nPageNumber
= 0;
3132 xPropSet
->getPropertyValue(aPageNumberStr
) >>= nPageNumber
;
3134 mrExport
.AddAttribute(XML_NAMESPACE_DRAW
, XML_PAGE_NUMBER
, OUString::number(nPageNumber
));
3137 // a presentation page shape, normally used on notes pages only. If
3138 // it is used not as presentation shape, it may have been created with
3139 // copy-paste exchange between draw and impress (this IS possible...)
3140 if(eShapeType
== XmlShapeType::PresPageShape
)
3142 mrExport
.AddAttribute(XML_NAMESPACE_PRESENTATION
, XML_CLASS
,
3147 bool bCreateNewline( (nFeatures
& XMLShapeExportFlags::NO_WS
) == XMLShapeExportFlags::NONE
); // #86116#/#92210#
3148 SvXMLElementExport
aOBJ(mrExport
, XML_NAMESPACE_DRAW
, XML_PAGE_THUMBNAIL
, bCreateNewline
, true);
3151 void XMLShapeExport::ImpExportCaptionShape(
3152 const uno::Reference
< drawing::XShape
>& xShape
,
3153 XMLShapeExportFlags nFeatures
/* = SEF_DEFAULT */, awt::Point
* pRefPoint
/* = NULL */)
3155 const uno::Reference
< beans::XPropertySet
> xPropSet(xShape
, uno::UNO_QUERY
);
3160 ImpExportNewTrans(xPropSet
, nFeatures
, pRefPoint
);
3162 // evtl. corner radius?
3163 sal_Int32
nCornerRadius(0);
3164 xPropSet
->getPropertyValue("CornerRadius") >>= nCornerRadius
;
3167 OUStringBuffer sStringBuffer
;
3168 mrExport
.GetMM100UnitConverter().convertMeasureToXML(sStringBuffer
,
3170 mrExport
.AddAttribute(XML_NAMESPACE_DRAW
, XML_CORNER_RADIUS
, sStringBuffer
.makeStringAndClear());
3173 awt::Point aCaptionPoint
;
3174 xPropSet
->getPropertyValue("CaptionPoint") >>= aCaptionPoint
;
3176 mrExport
.GetMM100UnitConverter().convertMeasureToXML(msBuffer
,
3178 mrExport
.AddAttribute( XML_NAMESPACE_DRAW
, XML_CAPTION_POINT_X
, msBuffer
.makeStringAndClear() );
3179 mrExport
.GetMM100UnitConverter().convertMeasureToXML(msBuffer
,
3181 mrExport
.AddAttribute( XML_NAMESPACE_DRAW
, XML_CAPTION_POINT_Y
, msBuffer
.makeStringAndClear() );
3183 // write Caption shape. Add export later.
3184 bool bCreateNewline( (nFeatures
& XMLShapeExportFlags::NO_WS
) == XMLShapeExportFlags::NONE
); // #86116#/#92210#
3185 bool bAnnotation( (nFeatures
& XMLShapeExportFlags::ANNOTATION
) == XMLShapeExportFlags::ANNOTATION
);
3187 SvXMLElementExport
aObj( mrExport
,
3188 (bAnnotation
? XML_NAMESPACE_OFFICE
3189 : XML_NAMESPACE_DRAW
),
3190 (bAnnotation
? XML_ANNOTATION
: XML_CAPTION
),
3191 bCreateNewline
, true );
3193 ImpExportDescription( xShape
); // #i68101#
3194 ImpExportEvents( xShape
);
3195 ImpExportGluePoints( xShape
);
3197 mrExport
.exportAnnotationMeta( xShape
);
3198 ImpExportText( xShape
);
3202 void XMLShapeExport::ImpExportFrameShape(
3203 const uno::Reference
< drawing::XShape
>& xShape
,
3204 XMLShapeExportFlags nFeatures
, css::awt::Point
* pRefPoint
)
3206 const uno::Reference
< beans::XPropertySet
> xPropSet(xShape
, uno::UNO_QUERY
);
3211 ImpExportNewTrans(xPropSet
, nFeatures
, pRefPoint
);
3213 bool bCreateNewline( (nFeatures
& XMLShapeExportFlags::NO_WS
) == XMLShapeExportFlags::NONE
); // #86116#/#92210#
3214 SvXMLElementExport
aElem( mrExport
, XML_NAMESPACE_DRAW
,
3215 XML_FRAME
, bCreateNewline
, true );
3219 xPropSet
->getPropertyValue("FrameURL") >>= aStr
;
3220 mrExport
.AddAttribute ( XML_NAMESPACE_XLINK
, XML_HREF
, GetExport().GetRelativeReference(aStr
) );
3221 mrExport
.AddAttribute ( XML_NAMESPACE_XLINK
, XML_TYPE
, XML_SIMPLE
);
3222 mrExport
.AddAttribute ( XML_NAMESPACE_XLINK
, XML_SHOW
, XML_EMBED
);
3223 mrExport
.AddAttribute ( XML_NAMESPACE_XLINK
, XML_ACTUATE
, XML_ONLOAD
);
3226 xPropSet
->getPropertyValue("FrameName") >>= aStr
;
3227 if( !aStr
.isEmpty() )
3228 mrExport
.AddAttribute( XML_NAMESPACE_DRAW
, XML_FRAME_NAME
, aStr
);
3230 // write floating frame
3232 SvXMLElementExport
aOBJ(mrExport
, XML_NAMESPACE_DRAW
, XML_FLOATING_FRAME
, true, true);
3235 ImpExportDescription(xShape
);
3238 void XMLShapeExport::ImpExportAppletShape(
3239 const uno::Reference
< drawing::XShape
>& xShape
,
3240 XMLShapeExportFlags nFeatures
, css::awt::Point
* pRefPoint
)
3242 const uno::Reference
< beans::XPropertySet
> xPropSet(xShape
, uno::UNO_QUERY
);
3247 ImpExportNewTrans(xPropSet
, nFeatures
, pRefPoint
);
3249 bool bCreateNewline( (nFeatures
& XMLShapeExportFlags::NO_WS
) == XMLShapeExportFlags::NONE
); // #86116#/#92210#
3250 SvXMLElementExport
aElement( mrExport
, XML_NAMESPACE_DRAW
,
3251 XML_FRAME
, bCreateNewline
, true );
3255 xPropSet
->getPropertyValue("AppletCodeBase") >>= aStr
;
3256 mrExport
.AddAttribute ( XML_NAMESPACE_XLINK
, XML_HREF
, GetExport().GetRelativeReference(aStr
) );
3257 mrExport
.AddAttribute ( XML_NAMESPACE_XLINK
, XML_TYPE
, XML_SIMPLE
);
3258 mrExport
.AddAttribute ( XML_NAMESPACE_XLINK
, XML_SHOW
, XML_EMBED
);
3259 mrExport
.AddAttribute ( XML_NAMESPACE_XLINK
, XML_ACTUATE
, XML_ONLOAD
);
3261 // export draw:applet-name
3262 xPropSet
->getPropertyValue("AppletName") >>= aStr
;
3263 if( !aStr
.isEmpty() )
3264 mrExport
.AddAttribute( XML_NAMESPACE_DRAW
, XML_APPLET_NAME
, aStr
);
3267 xPropSet
->getPropertyValue("AppletCode") >>= aStr
;
3268 mrExport
.AddAttribute( XML_NAMESPACE_DRAW
, XML_CODE
, aStr
);
3270 // export draw:may-script
3271 bool bIsScript
= false;
3272 xPropSet
->getPropertyValue("AppletIsScript") >>= bIsScript
;
3273 mrExport
.AddAttribute( XML_NAMESPACE_DRAW
, XML_MAY_SCRIPT
, bIsScript
? XML_TRUE
: XML_FALSE
);
3277 SvXMLElementExport
aOBJ(mrExport
, XML_NAMESPACE_DRAW
, XML_APPLET
, true, true);
3279 // export parameters
3280 uno::Sequence
< beans::PropertyValue
> aCommands
;
3281 xPropSet
->getPropertyValue("AppletCommands") >>= aCommands
;
3282 for( const auto& rCommand
: std::as_const(aCommands
) )
3284 rCommand
.Value
>>= aStr
;
3285 mrExport
.AddAttribute( XML_NAMESPACE_DRAW
, XML_NAME
, rCommand
.Name
);
3286 mrExport
.AddAttribute( XML_NAMESPACE_DRAW
, XML_VALUE
, aStr
);
3287 SvXMLElementExport
aElem( mrExport
, XML_NAMESPACE_DRAW
, XML_PARAM
, false, true );
3291 ImpExportDescription(xShape
);
3294 void XMLShapeExport::ImpExportPluginShape(
3295 const uno::Reference
< drawing::XShape
>& xShape
,
3296 XMLShapeExportFlags nFeatures
, css::awt::Point
* pRefPoint
)
3298 const uno::Reference
< beans::XPropertySet
> xPropSet(xShape
, uno::UNO_QUERY
);
3303 ImpExportNewTrans(xPropSet
, nFeatures
, pRefPoint
);
3305 bool bCreateNewline( (nFeatures
& XMLShapeExportFlags::NO_WS
) == XMLShapeExportFlags::NONE
); // #86116#/#92210#
3306 SvXMLElementExport
aElement( mrExport
, XML_NAMESPACE_DRAW
,
3307 XML_FRAME
, bCreateNewline
, true );
3309 // export plugin url
3311 xPropSet
->getPropertyValue("PluginURL") >>= aStr
;
3312 mrExport
.AddAttribute ( XML_NAMESPACE_XLINK
, XML_HREF
, GetExport().GetRelativeReference(aStr
) );
3313 mrExport
.AddAttribute ( XML_NAMESPACE_XLINK
, XML_TYPE
, XML_SIMPLE
);
3314 mrExport
.AddAttribute ( XML_NAMESPACE_XLINK
, XML_SHOW
, XML_EMBED
);
3315 mrExport
.AddAttribute ( XML_NAMESPACE_XLINK
, XML_ACTUATE
, XML_ONLOAD
);
3318 xPropSet
->getPropertyValue("PluginMimeType") >>= aStr
;
3320 mrExport
.AddAttribute( XML_NAMESPACE_DRAW
, XML_MIME_TYPE
, aStr
);
3324 SvXMLElementExport
aOBJ(mrExport
, XML_NAMESPACE_DRAW
, XML_PLUGIN
, true, true);
3326 // export parameters
3327 uno::Sequence
< beans::PropertyValue
> aCommands
;
3328 xPropSet
->getPropertyValue("PluginCommands") >>= aCommands
;
3329 for( const auto& rCommand
: std::as_const(aCommands
) )
3331 rCommand
.Value
>>= aStr
;
3332 mrExport
.AddAttribute( XML_NAMESPACE_DRAW
, XML_NAME
, rCommand
.Name
);
3333 mrExport
.AddAttribute( XML_NAMESPACE_DRAW
, XML_VALUE
, aStr
);
3334 SvXMLElementExport
aElem( mrExport
, XML_NAMESPACE_DRAW
, XML_PARAM
, false, true );
3338 ImpExportDescription(xShape
);
3341 static void lcl_CopyStream(
3342 uno::Reference
<io::XInputStream
> const& xInStream
,
3343 uno::Reference
<embed::XStorage
> const& xTarget
,
3344 OUString
const& rPath
, const OUString
& rMimeType
)
3346 ::comphelper::LifecycleProxy proxy
;
3347 uno::Reference
<io::XStream
> const xStream(
3348 ::comphelper::OStorageHelper::GetStreamAtPackageURL(xTarget
, rPath
,
3349 embed::ElementModes::WRITE
| embed::ElementModes::TRUNCATE
, proxy
));
3350 uno::Reference
<io::XOutputStream
> const xOutStream(
3351 (xStream
.is()) ? xStream
->getOutputStream() : nullptr);
3352 if (!xOutStream
.is())
3354 SAL_WARN("xmloff", "no output stream");
3355 throw uno::Exception("no output stream",nullptr);
3357 uno::Reference
< beans::XPropertySet
> const xStreamProps(xStream
,
3359 if (xStreamProps
.is()) { // this is NOT supported in FileSystemStorage
3360 xStreamProps
->setPropertyValue("MediaType",
3361 uno::Any(rMimeType
));
3362 xStreamProps
->setPropertyValue( // turn off compression
3366 ::comphelper::OStorageHelper::CopyInputToOutput(xInStream
, xOutStream
);
3367 xOutStream
->closeOutput();
3368 proxy
.commitStorages();
3372 lcl_StoreMediaAndGetURL(SvXMLExport
& rExport
,
3373 uno::Reference
<beans::XPropertySet
> const& xPropSet
,
3374 OUString
const& rURL
, const OUString
& rMimeType
)
3377 if (rURL
.startsWithIgnoreAsciiCase("vnd.sun.star.Package:", &urlPath
))
3379 try // video is embedded
3381 uno::Reference
<embed::XStorage
> const xTarget(
3382 rExport
.GetTargetStorage(), uno::UNO_SET_THROW
);
3383 uno::Reference
<io::XInputStream
> xInStream
;
3384 xPropSet
->getPropertyValue("PrivateStream")
3387 if (!xInStream
.is())
3389 SAL_WARN("xmloff", "no input stream");
3393 lcl_CopyStream(xInStream
, xTarget
, rURL
, rMimeType
);
3397 catch (uno::Exception
const&)
3399 TOOLS_INFO_EXCEPTION("xmloff", "exception while storing embedded media");
3405 return rExport
.GetRelativeReference(rURL
); // linked
3411 void ExportGraphicPreview(const uno::Reference
<graphic::XGraphic
>& xGraphic
, SvXMLExport
& rExport
, const std::u16string_view
& rPrefix
, const std::u16string_view
& rExtension
, const OUString
& rMimeType
)
3413 const bool bExportEmbedded(rExport
.getExportFlags() & SvXMLExportFlags::EMBEDDED
);
3415 if( xGraphic
.is() ) try
3417 uno::Reference
< uno::XComponentContext
> xContext
= rExport
.getComponentContext();
3419 uno::Reference
< embed::XStorage
> xPictureStorage
;
3420 uno::Reference
< embed::XStorage
> xStorage
;
3421 uno::Reference
< io::XStream
> xPictureStream
;
3423 OUString sPictureName
;
3424 if( bExportEmbedded
)
3426 xPictureStream
.set( xContext
->getServiceManager()->createInstanceWithContext( "com.sun.star.comp.MemoryStream", xContext
), uno::UNO_QUERY_THROW
);
3430 xStorage
.set( rExport
.GetTargetStorage(), uno::UNO_SET_THROW
);
3432 xPictureStorage
.set( xStorage
->openStorageElement( "Pictures" , ::embed::ElementModes::READWRITE
), uno::UNO_SET_THROW
);
3434 sal_Int32 nIndex
= 0;
3437 sPictureName
= rPrefix
+ OUString::number( ++nIndex
) + rExtension
;
3439 while( xPictureStorage
->hasByName( sPictureName
) );
3441 xPictureStream
.set( xPictureStorage
->openStreamElement( sPictureName
, ::embed::ElementModes::READWRITE
), uno::UNO_SET_THROW
);
3444 uno::Reference
< graphic::XGraphicProvider
> xProvider( graphic::GraphicProvider::create(xContext
) );
3445 uno::Sequence
< beans::PropertyValue
> aArgs
{
3446 comphelper::makePropertyValue("MimeType", rMimeType
),
3447 comphelper::makePropertyValue("OutputStream", xPictureStream
->getOutputStream())
3449 xProvider
->storeGraphic( xGraphic
, aArgs
);
3451 if( xPictureStorage
.is() )
3453 uno::Reference
< embed::XTransactedObject
> xTrans( xPictureStorage
, uno::UNO_QUERY
);
3458 if( !bExportEmbedded
)
3460 OUString sURL
= "Pictures/" + sPictureName
;
3461 rExport
.AddAttribute( XML_NAMESPACE_XLINK
, XML_HREF
, sURL
);
3462 rExport
.AddAttribute( XML_NAMESPACE_XLINK
, XML_TYPE
, XML_SIMPLE
);
3463 rExport
.AddAttribute( XML_NAMESPACE_XLINK
, XML_SHOW
, XML_EMBED
);
3464 rExport
.AddAttribute( XML_NAMESPACE_XLINK
, XML_ACTUATE
, XML_ONLOAD
);
3467 SvXMLElementExport
aElem( rExport
, XML_NAMESPACE_DRAW
, XML_IMAGE
, false, true );
3469 if( bExportEmbedded
)
3471 uno::Reference
< io::XSeekableInputStream
> xSeekable( xPictureStream
, uno::UNO_QUERY_THROW
);
3474 XMLBase64Export
aBase64Exp( rExport
);
3475 aBase64Exp
.exportOfficeBinaryDataElement( uno::Reference
< io::XInputStream
>( xPictureStream
, uno::UNO_QUERY_THROW
) );
3478 catch( uno::Exception
const & )
3480 DBG_UNHANDLED_EXCEPTION("xmloff.draw");
3485 void XMLShapeExport::ImpExportMediaShape(
3486 const uno::Reference
< drawing::XShape
>& xShape
,
3487 XmlShapeType eShapeType
, XMLShapeExportFlags nFeatures
, css::awt::Point
* pRefPoint
)
3489 const uno::Reference
< beans::XPropertySet
> xPropSet(xShape
, uno::UNO_QUERY
);
3494 ImpExportNewTrans(xPropSet
, nFeatures
, pRefPoint
);
3496 if(eShapeType
== XmlShapeType::PresMediaShape
)
3498 (void)ImpExportPresentationAttributes( xPropSet
, GetXMLToken(XML_OBJECT
) );
3500 bool bCreateNewline( (nFeatures
& XMLShapeExportFlags::NO_WS
) == XMLShapeExportFlags::NONE
); // #86116#/#92210#
3501 SvXMLElementExport
aElem( mrExport
, XML_NAMESPACE_DRAW
,
3502 XML_FRAME
, bCreateNewline
, true );
3506 xPropSet
->getPropertyValue("MediaURL") >>= aMediaURL
;
3508 xPropSet
->getPropertyValue("MediaMimeType") >>= sMimeType
;
3510 OUString
const persistentURL
=
3511 lcl_StoreMediaAndGetURL(GetExport(), xPropSet
, aMediaURL
, sMimeType
);
3513 mrExport
.AddAttribute ( XML_NAMESPACE_XLINK
, XML_HREF
, persistentURL
);
3514 mrExport
.AddAttribute ( XML_NAMESPACE_XLINK
, XML_TYPE
, XML_SIMPLE
);
3515 mrExport
.AddAttribute ( XML_NAMESPACE_XLINK
, XML_SHOW
, XML_EMBED
);
3516 mrExport
.AddAttribute ( XML_NAMESPACE_XLINK
, XML_ACTUATE
, XML_ONLOAD
);
3519 mrExport
.AddAttribute( XML_NAMESPACE_DRAW
, XML_MIME_TYPE
, sMimeType
);
3522 auto pPluginOBJ
= std::make_unique
<SvXMLElementExport
>(mrExport
, XML_NAMESPACE_DRAW
, XML_PLUGIN
, !( nFeatures
& XMLShapeExportFlags::NO_WS
), true);
3524 // export parameters
3525 static constexpr OUString
aFalseStr( u
"false"_ustr
);
3526 static constexpr OUString
aTrueStr( u
"true"_ustr
);
3529 static constexpr OUString
aLoopStr( u
"Loop"_ustr
);
3530 xPropSet
->getPropertyValue( aLoopStr
) >>= bLoop
;
3531 mrExport
.AddAttribute( XML_NAMESPACE_DRAW
, XML_NAME
, aLoopStr
);
3532 mrExport
.AddAttribute( XML_NAMESPACE_DRAW
, XML_VALUE
, bLoop
? aTrueStr
: aFalseStr
);
3533 delete new SvXMLElementExport( mrExport
, XML_NAMESPACE_DRAW
, XML_PARAM
, false, true );
3536 static constexpr OUString
aMuteStr( u
"Mute"_ustr
);
3537 xPropSet
->getPropertyValue( aMuteStr
) >>= bMute
;
3538 mrExport
.AddAttribute( XML_NAMESPACE_DRAW
, XML_NAME
, aMuteStr
);
3539 mrExport
.AddAttribute( XML_NAMESPACE_DRAW
, XML_VALUE
, bMute
? aTrueStr
: aFalseStr
);
3540 delete new SvXMLElementExport( mrExport
, XML_NAMESPACE_DRAW
, XML_PARAM
, false, true );
3542 sal_Int16 nVolumeDB
= 0;
3543 xPropSet
->getPropertyValue("VolumeDB") >>= nVolumeDB
;
3544 mrExport
.AddAttribute( XML_NAMESPACE_DRAW
, XML_NAME
, "VolumeDB" );
3545 mrExport
.AddAttribute( XML_NAMESPACE_DRAW
, XML_VALUE
, OUString::number( nVolumeDB
) );
3546 delete new SvXMLElementExport( mrExport
, XML_NAMESPACE_DRAW
, XML_PARAM
, false, true );
3548 media::ZoomLevel eZoom
;
3549 OUString aZoomValue
;
3550 xPropSet
->getPropertyValue("Zoom") >>= eZoom
;
3553 case media::ZoomLevel_ZOOM_1_TO_4
: aZoomValue
= "25%"; break;
3554 case media::ZoomLevel_ZOOM_1_TO_2
: aZoomValue
= "50%"; break;
3555 case media::ZoomLevel_ORIGINAL
: aZoomValue
= "100%"; break;
3556 case media::ZoomLevel_ZOOM_2_TO_1
: aZoomValue
= "200%"; break;
3557 case media::ZoomLevel_ZOOM_4_TO_1
: aZoomValue
= "400%"; break;
3558 case media::ZoomLevel_FIT_TO_WINDOW
: aZoomValue
= "fit"; break;
3559 case media::ZoomLevel_FIT_TO_WINDOW_FIXED_ASPECT
: aZoomValue
= "fixedfit"; break;
3560 case media::ZoomLevel_FULLSCREEN
: aZoomValue
= "fullscreen"; break;
3566 if( !aZoomValue
.isEmpty() )
3568 mrExport
.AddAttribute( XML_NAMESPACE_DRAW
, XML_NAME
, "Zoom" );
3569 mrExport
.AddAttribute( XML_NAMESPACE_DRAW
, XML_VALUE
, aZoomValue
);
3570 delete new SvXMLElementExport( mrExport
, XML_NAMESPACE_DRAW
, XML_PARAM
, false, true );
3575 uno::Reference
<graphic::XGraphic
> xGraphic
;
3576 xPropSet
->getPropertyValue("Graphic") >>= xGraphic
;
3577 Graphic
aGraphic(xGraphic
);
3578 if (!aGraphic
.IsNone())
3580 // The media has a preview, export it.
3581 ExportGraphicPreview(xGraphic
, mrExport
, u
"MediaPreview", u
".png", "image/png");
3584 ImpExportDescription(xShape
);
3587 void XMLShapeExport::ImpExport3DSceneShape( const uno::Reference
< drawing::XShape
>& xShape
, XMLShapeExportFlags nFeatures
, awt::Point
* pRefPoint
)
3589 uno::Reference
< drawing::XShapes
> xShapes(xShape
, uno::UNO_QUERY
);
3590 if(!(xShapes
.is() && xShapes
->getCount()))
3593 uno::Reference
< beans::XPropertySet
> xPropSet( xShape
, uno::UNO_QUERY
);
3594 SAL_WARN_IF( !xPropSet
.is(), "xmloff", "XMLShapeExport::ImpExport3DSceneShape can't export a scene without a propertyset" );
3595 if( !xPropSet
.is() )
3599 ImpExportNewTrans(xPropSet
, nFeatures
, pRefPoint
);
3602 export3DSceneAttributes( xPropSet
);
3604 // write 3DScene shape
3605 bool bCreateNewline( (nFeatures
& XMLShapeExportFlags::NO_WS
) == XMLShapeExportFlags::NONE
); // #86116#/#92210#
3606 SvXMLElementExport
aOBJ( mrExport
, XML_NAMESPACE_DR3D
, XML_SCENE
, bCreateNewline
, true);
3608 ImpExportDescription( xShape
); // #i68101#
3609 ImpExportEvents( xShape
);
3611 // write 3DSceneLights
3612 export3DLamps( xPropSet
);
3614 // #89764# if export of position is suppressed for group shape,
3615 // positions of contained objects should be written relative to
3616 // the upper left edge of the group.
3617 awt::Point aUpperLeft
;
3619 if(!(nFeatures
& XMLShapeExportFlags::POSITION
))
3621 nFeatures
|= XMLShapeExportFlags::POSITION
;
3622 aUpperLeft
= xShape
->getPosition();
3623 pRefPoint
= &aUpperLeft
;
3627 exportShapes( xShapes
, nFeatures
, pRefPoint
);
3630 void XMLShapeExport::ImpExport3DShape(
3631 const uno::Reference
< drawing::XShape
>& xShape
,
3632 XmlShapeType eShapeType
)
3634 const uno::Reference
< beans::XPropertySet
> xPropSet(xShape
, uno::UNO_QUERY
);
3639 OUStringBuffer sStringBuffer
;
3641 // transformation (UNO_NAME_3D_TRANSFORM_MATRIX == "D3DTransformMatrix")
3642 uno::Any aAny
= xPropSet
->getPropertyValue("D3DTransformMatrix");
3643 drawing::HomogenMatrix aHomMat
;
3645 SdXMLImExTransform3D aTransform
;
3646 aTransform
.AddHomogenMatrix(aHomMat
);
3647 if(aTransform
.NeedsAction())
3648 mrExport
.AddAttribute(XML_NAMESPACE_DR3D
, XML_TRANSFORM
, aTransform
.GetExportString(mrExport
.GetMM100UnitConverter()));
3652 case XmlShapeType::Draw3DCubeObject
:
3655 aAny
= xPropSet
->getPropertyValue("D3DPosition");
3656 drawing::Position3D aPosition3D
;
3657 aAny
>>= aPosition3D
;
3658 ::basegfx::B3DVector
aPos3D(aPosition3D
.PositionX
, aPosition3D
.PositionY
, aPosition3D
.PositionZ
);
3661 aAny
= xPropSet
->getPropertyValue("D3DSize");
3662 drawing::Direction3D aDirection3D
;
3663 aAny
>>= aDirection3D
;
3664 ::basegfx::B3DVector
aDir3D(aDirection3D
.DirectionX
, aDirection3D
.DirectionY
, aDirection3D
.DirectionZ
);
3666 // transform maxEdge from distance to pos
3667 aDir3D
= aPos3D
+ aDir3D
;
3670 if(aPos3D
!= ::basegfx::B3DVector(-2500.0, -2500.0, -2500.0)) // write only when not default
3672 SvXMLUnitConverter::convertB3DVector(sStringBuffer
, aPos3D
);
3673 aStr
= sStringBuffer
.makeStringAndClear();
3674 mrExport
.AddAttribute(XML_NAMESPACE_DR3D
, XML_MIN_EDGE
, aStr
);
3678 if(aDir3D
!= ::basegfx::B3DVector(2500.0, 2500.0, 2500.0)) // write only when not default
3680 SvXMLUnitConverter::convertB3DVector(sStringBuffer
, aDir3D
);
3681 aStr
= sStringBuffer
.makeStringAndClear();
3682 mrExport
.AddAttribute(XML_NAMESPACE_DR3D
, XML_MAX_EDGE
, aStr
);
3685 // write 3DCube shape
3686 // #i123542# Do this *after* the attributes are added, else these will be lost since opening
3687 // the scope will clear the global attribute list at the exporter
3688 SvXMLElementExport
aOBJ(mrExport
, XML_NAMESPACE_DR3D
, XML_CUBE
, true, true);
3692 case XmlShapeType::Draw3DSphereObject
:
3695 aAny
= xPropSet
->getPropertyValue("D3DPosition");
3696 drawing::Position3D aPosition3D
;
3697 aAny
>>= aPosition3D
;
3698 ::basegfx::B3DVector
aPos3D(aPosition3D
.PositionX
, aPosition3D
.PositionY
, aPosition3D
.PositionZ
);
3701 aAny
= xPropSet
->getPropertyValue("D3DSize");
3702 drawing::Direction3D aDirection3D
;
3703 aAny
>>= aDirection3D
;
3704 ::basegfx::B3DVector
aDir3D(aDirection3D
.DirectionX
, aDirection3D
.DirectionY
, aDirection3D
.DirectionZ
);
3707 if(aPos3D
!= ::basegfx::B3DVector(0.0, 0.0, 0.0)) // write only when not default
3709 SvXMLUnitConverter::convertB3DVector(sStringBuffer
, aPos3D
);
3710 aStr
= sStringBuffer
.makeStringAndClear();
3711 mrExport
.AddAttribute(XML_NAMESPACE_DR3D
, XML_CENTER
, aStr
);
3715 if(aDir3D
!= ::basegfx::B3DVector(5000.0, 5000.0, 5000.0)) // write only when not default
3717 SvXMLUnitConverter::convertB3DVector(sStringBuffer
, aDir3D
);
3718 aStr
= sStringBuffer
.makeStringAndClear();
3719 mrExport
.AddAttribute(XML_NAMESPACE_DR3D
, XML_SIZE
, aStr
);
3722 // write 3DSphere shape
3723 // #i123542# Do this *after* the attributes are added, else these will be lost since opening
3724 // the scope will clear the global attribute list at the exporter
3725 SvXMLElementExport
aOBJ(mrExport
, XML_NAMESPACE_DR3D
, XML_SPHERE
, true, true);
3729 case XmlShapeType::Draw3DLatheObject
:
3730 case XmlShapeType::Draw3DExtrudeObject
:
3732 // write special 3DLathe/3DExtrude attributes, get 3D tools::PolyPolygon as drawing::PolyPolygonShape3D
3733 aAny
= xPropSet
->getPropertyValue("D3DPolyPolygon3D");
3734 drawing::PolyPolygonShape3D aUnoPolyPolygon3D
;
3735 aAny
>>= aUnoPolyPolygon3D
;
3737 // convert to 3D PolyPolygon
3738 const basegfx::B3DPolyPolygon
aPolyPolygon3D(
3739 basegfx::utils::UnoPolyPolygonShape3DToB3DPolyPolygon(
3740 aUnoPolyPolygon3D
));
3742 // convert to 2D tools::PolyPolygon using identity 3D transformation (just grep X and Y)
3743 const basegfx::B3DHomMatrix aB3DHomMatrixFor2DConversion
;
3744 const basegfx::B2DPolyPolygon
aPolyPolygon(
3745 basegfx::utils::createB2DPolyPolygonFromB3DPolyPolygon(
3747 aB3DHomMatrixFor2DConversion
));
3749 // get 2D range of it
3750 const basegfx::B2DRange
aPolyPolygonRange(aPolyPolygon
.getB2DRange());
3753 SdXMLImExViewBox
aViewBox(
3754 aPolyPolygonRange
.getMinX(),
3755 aPolyPolygonRange
.getMinY(),
3756 aPolyPolygonRange
.getWidth(),
3757 aPolyPolygonRange
.getHeight());
3759 mrExport
.AddAttribute(XML_NAMESPACE_SVG
, XML_VIEWBOX
, aViewBox
.GetExportString());
3761 // prepare svg:d string
3762 const OUString
aPolygonString(
3763 basegfx::utils::exportToSvgD(
3765 true, // bUseRelativeCoordinates
3766 false, // bDetectQuadraticBeziers TTTT: not used in old, but maybe activated now
3767 true)); // bHandleRelativeNextPointCompatible
3769 // write point array
3770 mrExport
.AddAttribute(XML_NAMESPACE_SVG
, XML_D
, aPolygonString
);
3772 if(eShapeType
== XmlShapeType::Draw3DLatheObject
)
3774 // write 3DLathe shape
3775 SvXMLElementExport
aOBJ(mrExport
, XML_NAMESPACE_DR3D
, XML_ROTATE
, true, true);
3779 // write 3DExtrude shape
3780 SvXMLElementExport
aOBJ(mrExport
, XML_NAMESPACE_DR3D
, XML_EXTRUDE
, true, true);
3789 /** helper for chart that adds all attributes of a 3d scene element to the export */
3790 void XMLShapeExport::export3DSceneAttributes( const css::uno::Reference
< css::beans::XPropertySet
>& xPropSet
)
3793 OUStringBuffer sStringBuffer
;
3795 // world transformation (UNO_NAME_3D_TRANSFORM_MATRIX == "D3DTransformMatrix")
3796 uno::Any aAny
= xPropSet
->getPropertyValue("D3DTransformMatrix");
3797 drawing::HomogenMatrix aHomMat
;
3799 SdXMLImExTransform3D aTransform
;
3800 aTransform
.AddHomogenMatrix(aHomMat
);
3801 if(aTransform
.NeedsAction())
3802 mrExport
.AddAttribute(XML_NAMESPACE_DR3D
, XML_TRANSFORM
, aTransform
.GetExportString(mrExport
.GetMM100UnitConverter()));
3805 aAny
= xPropSet
->getPropertyValue("D3DCameraGeometry");
3806 drawing::CameraGeometry aCamGeo
;
3809 ::basegfx::B3DVector
aVRP(aCamGeo
.vrp
.PositionX
, aCamGeo
.vrp
.PositionY
, aCamGeo
.vrp
.PositionZ
);
3810 if(aVRP
!= ::basegfx::B3DVector(0.0, 0.0, 1.0)) // write only when not default
3812 SvXMLUnitConverter::convertB3DVector(sStringBuffer
, aVRP
);
3813 aStr
= sStringBuffer
.makeStringAndClear();
3814 mrExport
.AddAttribute(XML_NAMESPACE_DR3D
, XML_VRP
, aStr
);
3817 ::basegfx::B3DVector
aVPN(aCamGeo
.vpn
.DirectionX
, aCamGeo
.vpn
.DirectionY
, aCamGeo
.vpn
.DirectionZ
);
3818 if(aVPN
!= ::basegfx::B3DVector(0.0, 0.0, 1.0)) // write only when not default
3820 SvXMLUnitConverter::convertB3DVector(sStringBuffer
, aVPN
);
3821 aStr
= sStringBuffer
.makeStringAndClear();
3822 mrExport
.AddAttribute(XML_NAMESPACE_DR3D
, XML_VPN
, aStr
);
3825 ::basegfx::B3DVector
aVUP(aCamGeo
.vup
.DirectionX
, aCamGeo
.vup
.DirectionY
, aCamGeo
.vup
.DirectionZ
);
3826 if(aVUP
!= ::basegfx::B3DVector(0.0, 1.0, 0.0)) // write only when not default
3828 SvXMLUnitConverter::convertB3DVector(sStringBuffer
, aVUP
);
3829 aStr
= sStringBuffer
.makeStringAndClear();
3830 mrExport
.AddAttribute(XML_NAMESPACE_DR3D
, XML_VUP
, aStr
);
3833 // projection "D3DScenePerspective" drawing::ProjectionMode
3834 aAny
= xPropSet
->getPropertyValue("D3DScenePerspective");
3835 drawing::ProjectionMode aPrjMode
;
3837 if(aPrjMode
== drawing::ProjectionMode_PARALLEL
)
3838 aStr
= GetXMLToken(XML_PARALLEL
);
3840 aStr
= GetXMLToken(XML_PERSPECTIVE
);
3841 mrExport
.AddAttribute(XML_NAMESPACE_DR3D
, XML_PROJECTION
, aStr
);
3844 aAny
= xPropSet
->getPropertyValue("D3DSceneDistance");
3845 sal_Int32 nDistance
= 0;
3847 mrExport
.GetMM100UnitConverter().convertMeasureToXML(sStringBuffer
,
3849 aStr
= sStringBuffer
.makeStringAndClear();
3850 mrExport
.AddAttribute(XML_NAMESPACE_DR3D
, XML_DISTANCE
, aStr
);
3853 aAny
= xPropSet
->getPropertyValue("D3DSceneFocalLength");
3854 sal_Int32 nFocalLength
= 0;
3855 aAny
>>= nFocalLength
;
3856 mrExport
.GetMM100UnitConverter().convertMeasureToXML(sStringBuffer
,
3858 aStr
= sStringBuffer
.makeStringAndClear();
3859 mrExport
.AddAttribute(XML_NAMESPACE_DR3D
, XML_FOCAL_LENGTH
, aStr
);
3862 aAny
= xPropSet
->getPropertyValue("D3DSceneShadowSlant");
3863 sal_Int16 nShadowSlant
= 0;
3864 aAny
>>= nShadowSlant
;
3865 mrExport
.AddAttribute(XML_NAMESPACE_DR3D
, XML_SHADOW_SLANT
, OUString::number(static_cast<sal_Int32
>(nShadowSlant
)));
3868 aAny
= xPropSet
->getPropertyValue("D3DSceneShadeMode");
3869 drawing::ShadeMode aShadeMode
;
3870 if(aAny
>>= aShadeMode
)
3872 if(aShadeMode
== drawing::ShadeMode_FLAT
)
3873 aStr
= GetXMLToken(XML_FLAT
);
3874 else if(aShadeMode
== drawing::ShadeMode_PHONG
)
3875 aStr
= GetXMLToken(XML_PHONG
);
3876 else if(aShadeMode
== drawing::ShadeMode_SMOOTH
)
3877 aStr
= GetXMLToken(XML_GOURAUD
);
3879 aStr
= GetXMLToken(XML_DRAFT
);
3883 // ShadeMode enum not there, write default
3884 aStr
= GetXMLToken(XML_GOURAUD
);
3886 mrExport
.AddAttribute(XML_NAMESPACE_DR3D
, XML_SHADE_MODE
, aStr
);
3889 aAny
= xPropSet
->getPropertyValue("D3DSceneAmbientColor");
3890 sal_Int32 nAmbientColor
= 0;
3891 aAny
>>= nAmbientColor
;
3892 ::sax::Converter::convertColor(sStringBuffer
, nAmbientColor
);
3893 aStr
= sStringBuffer
.makeStringAndClear();
3894 mrExport
.AddAttribute(XML_NAMESPACE_DR3D
, XML_AMBIENT_COLOR
, aStr
);
3897 aAny
= xPropSet
->getPropertyValue("D3DSceneTwoSidedLighting");
3898 bool bTwoSidedLighting
= false;
3899 aAny
>>= bTwoSidedLighting
;
3900 ::sax::Converter::convertBool(sStringBuffer
, bTwoSidedLighting
);
3901 aStr
= sStringBuffer
.makeStringAndClear();
3902 mrExport
.AddAttribute(XML_NAMESPACE_DR3D
, XML_LIGHTING_MODE
, aStr
);
3905 /** helper for chart that exports all lamps from the propertyset */
3906 void XMLShapeExport::export3DLamps( const css::uno::Reference
< css::beans::XPropertySet
>& xPropSet
)
3908 // write lamps 1..8 as content
3910 OUStringBuffer sStringBuffer
;
3912 static constexpr OUStringLiteral
aColorPropName(u
"D3DSceneLightColor");
3913 static constexpr OUStringLiteral
aDirectionPropName(u
"D3DSceneLightDirection");
3914 static constexpr OUStringLiteral
aLightOnPropName(u
"D3DSceneLightOn");
3916 ::basegfx::B3DVector aLightDirection
;
3917 drawing::Direction3D aLightDir
;
3918 bool bLightOnOff
= false;
3919 for(sal_Int32 nLamp
= 1; nLamp
<= 8; nLamp
++)
3921 OUString aIndexStr
= OUString::number( nLamp
);
3924 OUString aPropName
= aColorPropName
+ aIndexStr
;
3925 sal_Int32 nLightColor
= 0;
3926 xPropSet
->getPropertyValue( aPropName
) >>= nLightColor
;
3927 ::sax::Converter::convertColor(sStringBuffer
, nLightColor
);
3928 aStr
= sStringBuffer
.makeStringAndClear();
3929 mrExport
.AddAttribute(XML_NAMESPACE_DR3D
, XML_DIFFUSE_COLOR
, aStr
);
3932 aPropName
= aDirectionPropName
+ aIndexStr
;
3933 xPropSet
->getPropertyValue(aPropName
) >>= aLightDir
;
3934 aLightDirection
= ::basegfx::B3DVector(aLightDir
.DirectionX
, aLightDir
.DirectionY
, aLightDir
.DirectionZ
);
3935 SvXMLUnitConverter::convertB3DVector(sStringBuffer
, aLightDirection
);
3936 aStr
= sStringBuffer
.makeStringAndClear();
3937 mrExport
.AddAttribute(XML_NAMESPACE_DR3D
, XML_DIRECTION
, aStr
);
3940 aPropName
= aLightOnPropName
+ aIndexStr
;
3941 xPropSet
->getPropertyValue(aPropName
) >>= bLightOnOff
;
3942 ::sax::Converter::convertBool(sStringBuffer
, bLightOnOff
);
3943 aStr
= sStringBuffer
.makeStringAndClear();
3944 mrExport
.AddAttribute(XML_NAMESPACE_DR3D
, XML_ENABLED
, aStr
);
3947 mrExport
.AddAttribute(XML_NAMESPACE_DR3D
, XML_SPECULAR
,
3948 nLamp
== 1 ? XML_TRUE
: XML_FALSE
);
3950 // write light entry
3951 SvXMLElementExport
aOBJ(mrExport
, XML_NAMESPACE_DR3D
, XML_LIGHT
, true, true);
3956 // using namespace css::io;
3957 // using namespace ::xmloff::EnhancedCustomShapeToken;
3960 static void ExportParameter( OUStringBuffer
& rStrBuffer
, const css::drawing::EnhancedCustomShapeParameter
& rParameter
)
3962 if ( !rStrBuffer
.isEmpty() )
3963 rStrBuffer
.append( ' ' );
3964 if ( rParameter
.Value
.getValueTypeClass() == uno::TypeClass_DOUBLE
)
3966 double fNumber
= 0.0;
3967 rParameter
.Value
>>= fNumber
;
3968 ::rtl::math::doubleToUStringBuffer( rStrBuffer
, fNumber
, rtl_math_StringFormat_Automatic
, rtl_math_DecimalPlaces_Max
, '.', true );
3972 sal_Int32 nValue
= 0;
3973 rParameter
.Value
>>= nValue
;
3975 switch( rParameter
.Type
)
3977 case css::drawing::EnhancedCustomShapeParameterType::EQUATION
:
3979 rStrBuffer
.append( "?f" + OUString::number( nValue
) );
3983 case css::drawing::EnhancedCustomShapeParameterType::ADJUSTMENT
:
3985 rStrBuffer
.append( '$' );
3986 rStrBuffer
.append( nValue
);
3990 case css::drawing::EnhancedCustomShapeParameterType::BOTTOM
:
3991 rStrBuffer
.append( GetXMLToken( XML_BOTTOM
) ); break;
3992 case css::drawing::EnhancedCustomShapeParameterType::RIGHT
:
3993 rStrBuffer
.append( GetXMLToken( XML_RIGHT
) ); break;
3994 case css::drawing::EnhancedCustomShapeParameterType::TOP
:
3995 rStrBuffer
.append( GetXMLToken( XML_TOP
) ); break;
3996 case css::drawing::EnhancedCustomShapeParameterType::LEFT
:
3997 rStrBuffer
.append( GetXMLToken( XML_LEFT
) ); break;
3998 case css::drawing::EnhancedCustomShapeParameterType::XSTRETCH
:
3999 rStrBuffer
.append( GetXMLToken( XML_XSTRETCH
) ); break;
4000 case css::drawing::EnhancedCustomShapeParameterType::YSTRETCH
:
4001 rStrBuffer
.append( GetXMLToken( XML_YSTRETCH
) ); break;
4002 case css::drawing::EnhancedCustomShapeParameterType::HASSTROKE
:
4003 rStrBuffer
.append( GetXMLToken( XML_HASSTROKE
) ); break;
4004 case css::drawing::EnhancedCustomShapeParameterType::HASFILL
:
4005 rStrBuffer
.append( GetXMLToken( XML_HASFILL
) ); break;
4006 case css::drawing::EnhancedCustomShapeParameterType::WIDTH
:
4007 rStrBuffer
.append( GetXMLToken( XML_WIDTH
) ); break;
4008 case css::drawing::EnhancedCustomShapeParameterType::HEIGHT
:
4009 rStrBuffer
.append( GetXMLToken( XML_HEIGHT
) ); break;
4010 case css::drawing::EnhancedCustomShapeParameterType::LOGWIDTH
:
4011 rStrBuffer
.append( GetXMLToken( XML_LOGWIDTH
) ); break;
4012 case css::drawing::EnhancedCustomShapeParameterType::LOGHEIGHT
:
4013 rStrBuffer
.append( GetXMLToken( XML_LOGHEIGHT
) ); break;
4015 rStrBuffer
.append( nValue
);
4020 static void ImpExportEquations( SvXMLExport
& rExport
, const uno::Sequence
< OUString
>& rEquations
)
4023 for ( i
= 0; i
< rEquations
.getLength(); i
++ )
4025 OUString aStr
= "f" + OUString::number( i
);
4026 rExport
.AddAttribute( XML_NAMESPACE_DRAW
, XML_NAME
, aStr
);
4028 aStr
= rEquations
[ i
];
4029 sal_Int32 nIndex
= 0;
4032 nIndex
= aStr
.indexOf( '?', nIndex
);
4035 aStr
= OUString::Concat(aStr
.subView(0, nIndex
+ 1)) + "f"
4036 + aStr
.subView(nIndex
+ 1, aStr
.getLength() - nIndex
- 1);
4039 } while( nIndex
!= -1 );
4040 rExport
.AddAttribute( XML_NAMESPACE_DRAW
, XML_FORMULA
, aStr
);
4041 SvXMLElementExport
aOBJ( rExport
, XML_NAMESPACE_DRAW
, XML_EQUATION
, true, true );
4045 static void ImpExportHandles( SvXMLExport
& rExport
, const uno::Sequence
< beans::PropertyValues
>& rHandles
)
4047 if ( !rHandles
.hasElements() )
4051 OUStringBuffer aStrBuffer
;
4053 for ( const uno::Sequence
< beans::PropertyValue
>& rPropSeq
: rHandles
)
4055 bool bPosition
= false;
4056 for ( const beans::PropertyValue
& rPropVal
: rPropSeq
)
4058 switch( EASGet( rPropVal
.Name
) )
4062 css::drawing::EnhancedCustomShapeParameterPair aPosition
;
4063 if ( rPropVal
.Value
>>= aPosition
)
4065 ExportParameter( aStrBuffer
, aPosition
.First
);
4066 ExportParameter( aStrBuffer
, aPosition
.Second
);
4067 aStr
= aStrBuffer
.makeStringAndClear();
4068 rExport
.AddAttribute( XML_NAMESPACE_DRAW
, XML_HANDLE_POSITION
, aStr
);
4073 case EAS_MirroredX
:
4076 if ( rPropVal
.Value
>>= bMirroredX
)
4077 rExport
.AddAttribute( XML_NAMESPACE_DRAW
, XML_HANDLE_MIRROR_HORIZONTAL
,
4078 bMirroredX
? GetXMLToken( XML_TRUE
) : GetXMLToken( XML_FALSE
) );
4081 case EAS_MirroredY
:
4084 if ( rPropVal
.Value
>>= bMirroredY
)
4085 rExport
.AddAttribute( XML_NAMESPACE_DRAW
, XML_HANDLE_MIRROR_VERTICAL
,
4086 bMirroredY
? GetXMLToken( XML_TRUE
) : GetXMLToken( XML_FALSE
) );
4092 if ( rPropVal
.Value
>>= bSwitched
)
4093 rExport
.AddAttribute( XML_NAMESPACE_DRAW
, XML_HANDLE_SWITCHED
,
4094 bSwitched
? GetXMLToken( XML_TRUE
) : GetXMLToken( XML_FALSE
) );
4099 css::drawing::EnhancedCustomShapeParameterPair aPolar
;
4100 if ( rPropVal
.Value
>>= aPolar
)
4102 ExportParameter( aStrBuffer
, aPolar
.First
);
4103 ExportParameter( aStrBuffer
, aPolar
.Second
);
4104 aStr
= aStrBuffer
.makeStringAndClear();
4105 rExport
.AddAttribute( XML_NAMESPACE_DRAW
, XML_HANDLE_POLAR
, aStr
);
4109 case EAS_RadiusRangeMinimum
:
4111 css::drawing::EnhancedCustomShapeParameter aRadiusRangeMinimum
;
4112 if ( rPropVal
.Value
>>= aRadiusRangeMinimum
)
4114 ExportParameter( aStrBuffer
, aRadiusRangeMinimum
);
4115 aStr
= aStrBuffer
.makeStringAndClear();
4116 rExport
.AddAttribute( XML_NAMESPACE_DRAW
, XML_HANDLE_RADIUS_RANGE_MINIMUM
, aStr
);
4120 case EAS_RadiusRangeMaximum
:
4122 css::drawing::EnhancedCustomShapeParameter aRadiusRangeMaximum
;
4123 if ( rPropVal
.Value
>>= aRadiusRangeMaximum
)
4125 ExportParameter( aStrBuffer
, aRadiusRangeMaximum
);
4126 aStr
= aStrBuffer
.makeStringAndClear();
4127 rExport
.AddAttribute( XML_NAMESPACE_DRAW
, XML_HANDLE_RADIUS_RANGE_MAXIMUM
, aStr
);
4131 case EAS_RangeXMinimum
:
4133 css::drawing::EnhancedCustomShapeParameter aXRangeMinimum
;
4134 if ( rPropVal
.Value
>>= aXRangeMinimum
)
4136 ExportParameter( aStrBuffer
, aXRangeMinimum
);
4137 aStr
= aStrBuffer
.makeStringAndClear();
4138 rExport
.AddAttribute( XML_NAMESPACE_DRAW
, XML_HANDLE_RANGE_X_MINIMUM
, aStr
);
4142 case EAS_RangeXMaximum
:
4144 css::drawing::EnhancedCustomShapeParameter aXRangeMaximum
;
4145 if ( rPropVal
.Value
>>= aXRangeMaximum
)
4147 ExportParameter( aStrBuffer
, aXRangeMaximum
);
4148 aStr
= aStrBuffer
.makeStringAndClear();
4149 rExport
.AddAttribute( XML_NAMESPACE_DRAW
, XML_HANDLE_RANGE_X_MAXIMUM
, aStr
);
4153 case EAS_RangeYMinimum
:
4155 css::drawing::EnhancedCustomShapeParameter aYRangeMinimum
;
4156 if ( rPropVal
.Value
>>= aYRangeMinimum
)
4158 ExportParameter( aStrBuffer
, aYRangeMinimum
);
4159 aStr
= aStrBuffer
.makeStringAndClear();
4160 rExport
.AddAttribute( XML_NAMESPACE_DRAW
, XML_HANDLE_RANGE_Y_MINIMUM
, aStr
);
4164 case EAS_RangeYMaximum
:
4166 css::drawing::EnhancedCustomShapeParameter aYRangeMaximum
;
4167 if ( rPropVal
.Value
>>= aYRangeMaximum
)
4169 ExportParameter( aStrBuffer
, aYRangeMaximum
);
4170 aStr
= aStrBuffer
.makeStringAndClear();
4171 rExport
.AddAttribute( XML_NAMESPACE_DRAW
, XML_HANDLE_RANGE_Y_MAXIMUM
, aStr
);
4180 SvXMLElementExport
aOBJ( rExport
, XML_NAMESPACE_DRAW
, XML_HANDLE
, true, true );
4182 rExport
.ClearAttrList();
4186 static void ImpExportEnhancedPath( SvXMLExport
& rExport
,
4187 const uno::Sequence
< css::drawing::EnhancedCustomShapeParameterPair
>& rCoordinates
,
4188 const uno::Sequence
< css::drawing::EnhancedCustomShapeSegment
>& rSegments
,
4189 bool bExtended
= false )
4193 OUStringBuffer aStrBuffer
;
4194 bool bNeedExtended
= false;
4196 sal_Int32 i
, j
, k
, l
;
4198 sal_Int32 nCoords
= rCoordinates
.getLength();
4199 sal_Int32 nSegments
= rSegments
.getLength();
4200 bool bSimpleSegments
= nSegments
== 0;
4201 if ( bSimpleSegments
)
4203 for ( j
= i
= 0; j
< nSegments
; j
++ )
4205 css::drawing::EnhancedCustomShapeSegment aSegment
;
4206 if ( bSimpleSegments
)
4208 // if there are not enough segments we will default them
4214 aSegment
.Command
= css::drawing::EnhancedCustomShapeSegmentCommand::MOVETO
;
4219 aSegment
.Count
= static_cast<sal_Int16
>(std::min( nCoords
- 1, sal_Int32(32767) ));
4220 aSegment
.Command
= css::drawing::EnhancedCustomShapeSegmentCommand::LINETO
;
4226 aSegment
.Command
= css::drawing::EnhancedCustomShapeSegmentCommand::CLOSESUBPATH
;
4232 aSegment
.Command
= css::drawing::EnhancedCustomShapeSegmentCommand::ENDSUBPATH
;
4238 aSegment
= rSegments
[ j
];
4240 if ( !aStrBuffer
.isEmpty() )
4241 aStrBuffer
.append( ' ' );
4243 sal_Int32 nParameter
= 0;
4244 switch( aSegment
.Command
)
4246 case css::drawing::EnhancedCustomShapeSegmentCommand::CLOSESUBPATH
:
4247 aStrBuffer
.append( 'Z' ); break;
4248 case css::drawing::EnhancedCustomShapeSegmentCommand::ENDSUBPATH
:
4249 aStrBuffer
.append( 'N' ); break;
4250 case css::drawing::EnhancedCustomShapeSegmentCommand::NOFILL
:
4251 aStrBuffer
.append( 'F' ); break;
4252 case css::drawing::EnhancedCustomShapeSegmentCommand::NOSTROKE
:
4253 aStrBuffer
.append( 'S' ); break;
4255 case css::drawing::EnhancedCustomShapeSegmentCommand::MOVETO
:
4256 aStrBuffer
.append( 'M' ); nParameter
= 1; break;
4257 case css::drawing::EnhancedCustomShapeSegmentCommand::LINETO
:
4258 aStrBuffer
.append( 'L' ); nParameter
= 1; break;
4259 case css::drawing::EnhancedCustomShapeSegmentCommand::CURVETO
:
4260 aStrBuffer
.append( 'C' ); nParameter
= 3; break;
4261 case css::drawing::EnhancedCustomShapeSegmentCommand::ANGLEELLIPSETO
:
4262 aStrBuffer
.append( 'T' ); nParameter
= 3; break;
4263 case css::drawing::EnhancedCustomShapeSegmentCommand::ANGLEELLIPSE
:
4264 aStrBuffer
.append( 'U' ); nParameter
= 3; break;
4265 case css::drawing::EnhancedCustomShapeSegmentCommand::ARCTO
:
4266 aStrBuffer
.append( 'A' ); nParameter
= 4; break;
4267 case css::drawing::EnhancedCustomShapeSegmentCommand::ARC
:
4268 aStrBuffer
.append( 'B' ); nParameter
= 4; break;
4269 case css::drawing::EnhancedCustomShapeSegmentCommand::CLOCKWISEARCTO
:
4270 aStrBuffer
.append( 'W' ); nParameter
= 4; break;
4271 case css::drawing::EnhancedCustomShapeSegmentCommand::CLOCKWISEARC
:
4272 aStrBuffer
.append( 'V' ); nParameter
= 4; break;
4273 case css::drawing::EnhancedCustomShapeSegmentCommand::ELLIPTICALQUADRANTX
:
4274 aStrBuffer
.append( 'X' ); nParameter
= 1; break;
4275 case css::drawing::EnhancedCustomShapeSegmentCommand::ELLIPTICALQUADRANTY
:
4276 aStrBuffer
.append( 'Y' ); nParameter
= 1; break;
4277 case css::drawing::EnhancedCustomShapeSegmentCommand::QUADRATICCURVETO
:
4278 aStrBuffer
.append( 'Q' ); nParameter
= 2; break;
4279 case css::drawing::EnhancedCustomShapeSegmentCommand::ARCANGLETO
:
4281 aStrBuffer
.append( 'G' );
4284 aStrBuffer
.setLength( aStrBuffer
.getLength() - 1);
4285 bNeedExtended
= true;
4289 case css::drawing::EnhancedCustomShapeSegmentCommand::DARKEN
:
4291 aStrBuffer
.append( 'H' );
4293 bNeedExtended
= true;
4295 case css::drawing::EnhancedCustomShapeSegmentCommand::DARKENLESS
:
4297 aStrBuffer
.append( 'I' );
4299 bNeedExtended
= true;
4301 case css::drawing::EnhancedCustomShapeSegmentCommand::LIGHTEN
:
4303 aStrBuffer
.append( 'J' );
4305 bNeedExtended
= true;
4307 case css::drawing::EnhancedCustomShapeSegmentCommand::LIGHTENLESS
:
4309 aStrBuffer
.append( 'K' );
4311 bNeedExtended
= true;
4313 default : // ups, seems to be something wrong
4316 aSegment
.Command
= css::drawing::EnhancedCustomShapeSegmentCommand::LINETO
;
4322 for ( k
= 0; k
< aSegment
.Count
; k
++ )
4324 if ( ( i
+ nParameter
) <= nCoords
)
4326 for ( l
= 0; l
< nParameter
; l
++ )
4328 ExportParameter( aStrBuffer
, rCoordinates
[ i
].First
);
4329 ExportParameter( aStrBuffer
, rCoordinates
[ i
++ ].Second
);
4334 j
= nSegments
; // error -> exiting
4340 aStr
= aStrBuffer
.makeStringAndClear();
4341 rExport
.AddAttribute( bExtended
? XML_NAMESPACE_DRAW_EXT
: XML_NAMESPACE_DRAW
, XML_ENHANCED_PATH
, aStr
);
4342 if (!bExtended
&& bNeedExtended
&& (rExport
.getSaneDefaultVersion() & SvtSaveOptions::ODFSVER_EXTENDED
))
4343 ImpExportEnhancedPath( rExport
, rCoordinates
, rSegments
, true );
4346 static void ImpExportEnhancedGeometry( SvXMLExport
& rExport
, const uno::Reference
< beans::XPropertySet
>& xPropSet
)
4348 bool bEquations
= false;
4349 uno::Sequence
< OUString
> aEquations
;
4351 bool bHandles
= false;
4352 uno::Sequence
< beans::PropertyValues
> aHandles
;
4354 uno::Sequence
< css::drawing::EnhancedCustomShapeSegment
> aSegments
;
4355 uno::Sequence
< css::drawing::EnhancedCustomShapeParameterPair
> aCoordinates
;
4357 uno::Sequence
< css::drawing::EnhancedCustomShapeAdjustmentValue
> aAdjustmentValues
;
4360 OUStringBuffer aStrBuffer
;
4361 double fTextRotateAngle(0.0);
4362 double fTextPreRotateAngle(0.0); // will be consolidated with fTextRotateAngle at the end
4363 SvXMLUnitConverter
& rUnitConverter
= rExport
.GetMM100UnitConverter();
4365 uno::Reference
< beans::XPropertySetInfo
> xPropSetInfo( xPropSet
->getPropertySetInfo() );
4368 static constexpr OUString
sCustomShapeGeometry( u
"CustomShapeGeometry"_ustr
);
4369 if ( xPropSetInfo
.is() && xPropSetInfo
->hasPropertyByName( sCustomShapeGeometry
) )
4371 uno::Any
aGeoPropSet( xPropSet
->getPropertyValue( sCustomShapeGeometry
) );
4372 uno::Sequence
< beans::PropertyValue
> aGeoPropSeq
;
4374 if ( aGeoPropSet
>>= aGeoPropSeq
)
4376 bool bCoordinates
= false;
4377 OUString
aCustomShapeType( "non-primitive" );
4379 for ( const beans::PropertyValue
& rGeoProp
: std::as_const(aGeoPropSeq
) )
4381 switch( EASGet( rGeoProp
.Name
) )
4385 rGeoProp
.Value
>>= aCustomShapeType
;
4388 case EAS_MirroredX
:
4391 if ( rGeoProp
.Value
>>= bMirroredX
)
4392 rExport
.AddAttribute( XML_NAMESPACE_DRAW
, XML_MIRROR_HORIZONTAL
,
4393 bMirroredX
? GetXMLToken( XML_TRUE
) : GetXMLToken( XML_FALSE
) );
4396 case EAS_MirroredY
:
4399 if ( rGeoProp
.Value
>>= bMirroredY
)
4400 rExport
.AddAttribute( XML_NAMESPACE_DRAW
, XML_MIRROR_VERTICAL
,
4401 bMirroredY
? GetXMLToken( XML_TRUE
) : GetXMLToken( XML_FALSE
) );
4406 awt::Rectangle aRect
;
4407 if ( rGeoProp
.Value
>>= aRect
)
4409 SdXMLImExViewBox
aViewBox( aRect
.X
, aRect
.Y
, aRect
.Width
, aRect
.Height
);
4410 rExport
.AddAttribute( XML_NAMESPACE_SVG
, XML_VIEWBOX
, aViewBox
.GetExportString() );
4414 case EAS_TextPreRotateAngle
:
4416 rGeoProp
.Value
>>= fTextPreRotateAngle
;
4419 case EAS_TextRotateAngle
:
4421 rGeoProp
.Value
>>= fTextRotateAngle
;
4424 case EAS_Extrusion
:
4426 uno::Sequence
< beans::PropertyValue
> aExtrusionPropSeq
;
4427 if ( rGeoProp
.Value
>>= aExtrusionPropSeq
)
4429 bool bSkewValuesProvided
= false;
4430 for ( const beans::PropertyValue
& rProp
: std::as_const(aExtrusionPropSeq
) )
4432 switch( EASGet( rProp
.Name
) )
4434 case EAS_Extrusion
:
4437 if ( rProp
.Value
>>= bExtrusionOn
)
4438 rExport
.AddAttribute( XML_NAMESPACE_DRAW
, XML_EXTRUSION
,
4439 bExtrusionOn
? GetXMLToken( XML_TRUE
) : GetXMLToken( XML_FALSE
) );
4442 case EAS_Brightness
:
4444 double fExtrusionBrightness
= 0;
4445 if ( rProp
.Value
>>= fExtrusionBrightness
)
4447 ::sax::Converter::convertDouble(
4449 fExtrusionBrightness
,
4451 util::MeasureUnit::PERCENT
,
4452 util::MeasureUnit::PERCENT
);
4453 aStrBuffer
.append( '%' );
4454 aStr
= aStrBuffer
.makeStringAndClear();
4455 rExport
.AddAttribute( XML_NAMESPACE_DRAW
, XML_EXTRUSION_BRIGHTNESS
, aStr
);
4461 css::drawing::EnhancedCustomShapeParameterPair aDepthParaPair
;
4462 if ( rProp
.Value
>>= aDepthParaPair
)
4465 if ( aDepthParaPair
.First
.Value
>>= fDepth
)
4467 rExport
.GetMM100UnitConverter().convertDouble( aStrBuffer
, fDepth
);
4468 ExportParameter( aStrBuffer
, aDepthParaPair
.Second
);
4469 aStr
= aStrBuffer
.makeStringAndClear();
4470 rExport
.AddAttribute( XML_NAMESPACE_DRAW
, XML_EXTRUSION_DEPTH
, aStr
);
4475 case EAS_Diffusion
:
4477 double fExtrusionDiffusion
= 0;
4478 if ( rProp
.Value
>>= fExtrusionDiffusion
)
4480 ::sax::Converter::convertDouble(
4482 fExtrusionDiffusion
,
4484 util::MeasureUnit::PERCENT
,
4485 util::MeasureUnit::PERCENT
);
4486 aStrBuffer
.append( '%' );
4487 aStr
= aStrBuffer
.makeStringAndClear();
4488 rExport
.AddAttribute( XML_NAMESPACE_DRAW
, XML_EXTRUSION_DIFFUSION
, aStr
);
4492 case EAS_NumberOfLineSegments
:
4494 sal_Int32 nExtrusionNumberOfLineSegments
= 0;
4495 if ( rProp
.Value
>>= nExtrusionNumberOfLineSegments
)
4496 rExport
.AddAttribute( XML_NAMESPACE_DRAW
, XML_EXTRUSION_NUMBER_OF_LINE_SEGMENTS
, OUString::number( nExtrusionNumberOfLineSegments
) );
4499 case EAS_LightFace
:
4501 bool bExtrusionLightFace
;
4502 if ( rProp
.Value
>>= bExtrusionLightFace
)
4503 rExport
.AddAttribute( XML_NAMESPACE_DRAW
, XML_EXTRUSION_LIGHT_FACE
,
4504 bExtrusionLightFace
? GetXMLToken( XML_TRUE
) : GetXMLToken( XML_FALSE
) );
4507 case EAS_FirstLightHarsh
:
4509 bool bExtrusionFirstLightHarsh
;
4510 if ( rProp
.Value
>>= bExtrusionFirstLightHarsh
)
4511 rExport
.AddAttribute( XML_NAMESPACE_DRAW
, XML_EXTRUSION_FIRST_LIGHT_HARSH
,
4512 bExtrusionFirstLightHarsh
? GetXMLToken( XML_TRUE
) : GetXMLToken( XML_FALSE
) );
4515 case EAS_SecondLightHarsh
:
4517 bool bExtrusionSecondLightHarsh
;
4518 if ( rProp
.Value
>>= bExtrusionSecondLightHarsh
)
4519 rExport
.AddAttribute( XML_NAMESPACE_DRAW
, XML_EXTRUSION_SECOND_LIGHT_HARSH
,
4520 bExtrusionSecondLightHarsh
? GetXMLToken( XML_TRUE
) : GetXMLToken( XML_FALSE
) );
4523 case EAS_FirstLightLevel
:
4525 double fExtrusionFirstLightLevel
= 0;
4526 if ( rProp
.Value
>>= fExtrusionFirstLightLevel
)
4528 ::sax::Converter::convertDouble(
4530 fExtrusionFirstLightLevel
,
4532 util::MeasureUnit::PERCENT
,
4533 util::MeasureUnit::PERCENT
);
4534 aStrBuffer
.append( '%' );
4535 aStr
= aStrBuffer
.makeStringAndClear();
4536 rExport
.AddAttribute( XML_NAMESPACE_DRAW
, XML_EXTRUSION_FIRST_LIGHT_LEVEL
, aStr
);
4540 case EAS_SecondLightLevel
:
4542 double fExtrusionSecondLightLevel
= 0;
4543 if ( rProp
.Value
>>= fExtrusionSecondLightLevel
)
4545 ::sax::Converter::convertDouble(
4547 fExtrusionSecondLightLevel
,
4549 util::MeasureUnit::PERCENT
,
4550 util::MeasureUnit::PERCENT
);
4551 aStrBuffer
.append( '%' );
4552 aStr
= aStrBuffer
.makeStringAndClear();
4553 rExport
.AddAttribute( XML_NAMESPACE_DRAW
, XML_EXTRUSION_SECOND_LIGHT_LEVEL
, aStr
);
4557 case EAS_FirstLightDirection
:
4559 drawing::Direction3D aExtrusionFirstLightDirection
;
4560 if ( rProp
.Value
>>= aExtrusionFirstLightDirection
)
4562 ::basegfx::B3DVector
aVec3D( aExtrusionFirstLightDirection
.DirectionX
, aExtrusionFirstLightDirection
.DirectionY
,
4563 aExtrusionFirstLightDirection
.DirectionZ
);
4564 SvXMLUnitConverter::convertB3DVector( aStrBuffer
, aVec3D
);
4565 aStr
= aStrBuffer
.makeStringAndClear();
4566 rExport
.AddAttribute( XML_NAMESPACE_DRAW
, XML_EXTRUSION_FIRST_LIGHT_DIRECTION
, aStr
);
4570 case EAS_SecondLightDirection
:
4572 drawing::Direction3D aExtrusionSecondLightDirection
;
4573 if ( rProp
.Value
>>= aExtrusionSecondLightDirection
)
4575 ::basegfx::B3DVector
aVec3D( aExtrusionSecondLightDirection
.DirectionX
, aExtrusionSecondLightDirection
.DirectionY
,
4576 aExtrusionSecondLightDirection
.DirectionZ
);
4577 SvXMLUnitConverter::convertB3DVector( aStrBuffer
, aVec3D
);
4578 aStr
= aStrBuffer
.makeStringAndClear();
4579 rExport
.AddAttribute( XML_NAMESPACE_DRAW
, XML_EXTRUSION_SECOND_LIGHT_DIRECTION
, aStr
);
4585 bool bExtrusionMetal
;
4586 if ( rProp
.Value
>>= bExtrusionMetal
)
4587 rExport
.AddAttribute( XML_NAMESPACE_DRAW
, XML_EXTRUSION_METAL
,
4588 bExtrusionMetal
? GetXMLToken( XML_TRUE
) : GetXMLToken( XML_FALSE
) );
4591 case EAS_MetalType
:
4593 // export only if ODF extensions are enabled
4594 sal_Int16 eMetalType
;
4595 if (rProp
.Value
>>= eMetalType
)
4597 SvtSaveOptions::ODFSaneDefaultVersion eVersion
= rExport
.getSaneDefaultVersion();
4598 if (eVersion
> SvtSaveOptions::ODFSVER_013
4599 && (eVersion
& SvtSaveOptions::ODFSVER_EXTENDED
))
4601 if (eMetalType
== drawing::EnhancedCustomShapeMetalType::MetalMSCompatible
)
4602 aStr
= "loext:MetalMSCompatible";
4604 aStr
= "draw:MetalODF";
4605 rExport
.AddAttribute(XML_NAMESPACE_LO_EXT
, XML_EXTRUSION_METAL_TYPE
, aStr
);
4610 case EAS_ShadeMode
:
4613 drawing::ShadeMode eShadeMode
;
4614 if( rProp
.Value
>>= eShadeMode
)
4616 if( eShadeMode
== drawing::ShadeMode_FLAT
)
4617 aStr
= GetXMLToken( XML_FLAT
);
4618 else if( eShadeMode
== drawing::ShadeMode_PHONG
)
4619 aStr
= GetXMLToken( XML_PHONG
);
4620 else if( eShadeMode
== drawing::ShadeMode_SMOOTH
)
4621 aStr
= GetXMLToken( XML_GOURAUD
);
4623 aStr
= GetXMLToken( XML_DRAFT
);
4627 // ShadeMode enum not there, write default
4628 aStr
= GetXMLToken( XML_FLAT
);
4630 rExport
.AddAttribute( XML_NAMESPACE_DR3D
, XML_SHADE_MODE
, aStr
);
4633 case EAS_RotateAngle
:
4635 css::drawing::EnhancedCustomShapeParameterPair aRotateAngleParaPair
;
4636 if ( rProp
.Value
>>= aRotateAngleParaPair
)
4638 ExportParameter( aStrBuffer
, aRotateAngleParaPair
.First
);
4639 ExportParameter( aStrBuffer
, aRotateAngleParaPair
.Second
);
4640 aStr
= aStrBuffer
.makeStringAndClear();
4641 rExport
.AddAttribute( XML_NAMESPACE_DRAW
, XML_EXTRUSION_ROTATION_ANGLE
, aStr
);
4645 case EAS_RotationCenter
:
4647 drawing::Direction3D aExtrusionRotationCenter
;
4648 if ( rProp
.Value
>>= aExtrusionRotationCenter
)
4650 ::basegfx::B3DVector
aVec3D( aExtrusionRotationCenter
.DirectionX
, aExtrusionRotationCenter
.DirectionY
,
4651 aExtrusionRotationCenter
.DirectionZ
);
4652 SvXMLUnitConverter::convertB3DVector( aStrBuffer
, aVec3D
);
4653 aStr
= aStrBuffer
.makeStringAndClear();
4654 rExport
.AddAttribute( XML_NAMESPACE_DRAW
, XML_EXTRUSION_ROTATION_CENTER
, aStr
);
4658 case EAS_Shininess
:
4660 double fExtrusionShininess
= 0;
4661 if ( rProp
.Value
>>= fExtrusionShininess
)
4663 ::sax::Converter::convertDouble(
4665 fExtrusionShininess
,
4667 util::MeasureUnit::PERCENT
,
4668 util::MeasureUnit::PERCENT
);
4669 aStrBuffer
.append( '%' );
4670 aStr
= aStrBuffer
.makeStringAndClear();
4671 rExport
.AddAttribute( XML_NAMESPACE_DRAW
, XML_EXTRUSION_SHININESS
, aStr
);
4677 css::drawing::EnhancedCustomShapeParameterPair aSkewParaPair
;
4678 if ( rProp
.Value
>>= aSkewParaPair
)
4680 bSkewValuesProvided
= true;
4681 ExportParameter( aStrBuffer
, aSkewParaPair
.First
);
4682 ExportParameter( aStrBuffer
, aSkewParaPair
.Second
);
4683 aStr
= aStrBuffer
.makeStringAndClear();
4684 rExport
.AddAttribute( XML_NAMESPACE_DRAW
, XML_EXTRUSION_SKEW
, aStr
);
4688 case EAS_Specularity
:
4690 double fExtrusionSpecularity
= 0;
4691 if ( rProp
.Value
>>= fExtrusionSpecularity
)
4693 SvtSaveOptions::ODFSaneDefaultVersion eVersion
= rExport
.getSaneDefaultVersion();
4694 if (fExtrusionSpecularity
> 100.0 && eVersion
>= SvtSaveOptions::ODFSVER_012
4695 && (eVersion
& SvtSaveOptions::ODFSVER_EXTENDED
))
4697 // tdf#147580 write values > 100% in loext
4698 ::sax::Converter::convertDouble(
4700 fExtrusionSpecularity
,
4702 util::MeasureUnit::PERCENT
,
4703 util::MeasureUnit::PERCENT
);
4704 aStrBuffer
.append( '%' );
4705 aStr
= aStrBuffer
.makeStringAndClear();
4706 rExport
.AddAttribute( XML_NAMESPACE_LO_EXT
, XML_EXTRUSION_SPECULARITY_LOEXT
, aStr
);
4708 // tdf#147580 ODF 1 allows arbitrary percent, later versions not
4709 if (eVersion
>= SvtSaveOptions::ODFSVER_012
)
4711 fExtrusionSpecularity
= std::clamp
<double>(fExtrusionSpecularity
, 0.0, 100.0);
4713 ::sax::Converter::convertDouble(
4715 fExtrusionSpecularity
,
4717 util::MeasureUnit::PERCENT
,
4718 util::MeasureUnit::PERCENT
);
4719 aStrBuffer
.append( '%' );
4720 aStr
= aStrBuffer
.makeStringAndClear();
4721 rExport
.AddAttribute( XML_NAMESPACE_DRAW
, XML_EXTRUSION_SPECULARITY
, aStr
);
4725 case EAS_ProjectionMode
:
4727 drawing::ProjectionMode eProjectionMode
;
4728 if ( rProp
.Value
>>= eProjectionMode
)
4729 rExport
.AddAttribute( XML_NAMESPACE_DR3D
, XML_PROJECTION
,
4730 eProjectionMode
== drawing::ProjectionMode_PARALLEL
? GetXMLToken( XML_PARALLEL
) : GetXMLToken( XML_PERSPECTIVE
) );
4733 case EAS_ViewPoint
:
4735 drawing::Position3D aExtrusionViewPoint
;
4736 if ( rProp
.Value
>>= aExtrusionViewPoint
)
4738 rUnitConverter
.convertPosition3D( aStrBuffer
, aExtrusionViewPoint
);
4739 aStr
= aStrBuffer
.makeStringAndClear();
4740 rExport
.AddAttribute( XML_NAMESPACE_DRAW
, XML_EXTRUSION_VIEWPOINT
, aStr
);
4746 css::drawing::EnhancedCustomShapeParameterPair aOriginParaPair
;
4747 if ( rProp
.Value
>>= aOriginParaPair
)
4749 ExportParameter( aStrBuffer
, aOriginParaPair
.First
);
4750 ExportParameter( aStrBuffer
, aOriginParaPair
.Second
);
4751 aStr
= aStrBuffer
.makeStringAndClear();
4752 rExport
.AddAttribute( XML_NAMESPACE_DRAW
, XML_EXTRUSION_ORIGIN
, aStr
);
4758 bool bExtrusionColor
;
4759 if ( rProp
.Value
>>= bExtrusionColor
)
4761 rExport
.AddAttribute( XML_NAMESPACE_DRAW
, XML_EXTRUSION_COLOR
,
4762 bExtrusionColor
? GetXMLToken( XML_TRUE
) : GetXMLToken( XML_FALSE
) );
4770 // tdf#141301: no specific skew values provided
4771 if (!bSkewValuesProvided
)
4773 // so we need to export default values explicitly
4774 rExport
.AddAttribute( XML_NAMESPACE_DRAW
, XML_EXTRUSION_SKEW
, "50 -135");
4781 uno::Sequence
< beans::PropertyValue
> aTextPathPropSeq
;
4782 if ( rGeoProp
.Value
>>= aTextPathPropSeq
)
4784 for ( const beans::PropertyValue
& rProp
: std::as_const(aTextPathPropSeq
) )
4786 switch( EASGet( rProp
.Name
) )
4791 if ( rProp
.Value
>>= bTextPathOn
)
4792 rExport
.AddAttribute( XML_NAMESPACE_DRAW
, XML_TEXT_PATH
,
4793 bTextPathOn
? GetXMLToken( XML_TRUE
) : GetXMLToken( XML_FALSE
) );
4796 case EAS_TextPathMode
:
4798 css::drawing::EnhancedCustomShapeTextPathMode eTextPathMode
;
4799 if ( rProp
.Value
>>= eTextPathMode
)
4801 switch ( eTextPathMode
)
4803 case css::drawing::EnhancedCustomShapeTextPathMode_NORMAL
: aStr
= GetXMLToken( XML_NORMAL
); break;
4804 case css::drawing::EnhancedCustomShapeTextPathMode_PATH
: aStr
= GetXMLToken( XML_PATH
); break;
4805 case css::drawing::EnhancedCustomShapeTextPathMode_SHAPE
: aStr
= GetXMLToken( XML_SHAPE
); break;
4809 if ( !aStr
.isEmpty() )
4810 rExport
.AddAttribute( XML_NAMESPACE_DRAW
, XML_TEXT_PATH_MODE
, aStr
);
4817 if ( rProp
.Value
>>= bScaleX
)
4819 aStr
= bScaleX
? GetXMLToken( XML_SHAPE
) : GetXMLToken( XML_PATH
);
4820 rExport
.AddAttribute( XML_NAMESPACE_DRAW
, XML_TEXT_PATH_SCALE
, aStr
);
4824 case EAS_SameLetterHeights
:
4826 bool bSameLetterHeights
;
4827 if ( rProp
.Value
>>= bSameLetterHeights
)
4828 rExport
.AddAttribute( XML_NAMESPACE_DRAW
, XML_TEXT_PATH_SAME_LETTER_HEIGHTS
,
4829 bSameLetterHeights
? GetXMLToken( XML_TRUE
) : GetXMLToken( XML_FALSE
) );
4841 uno::Sequence
< beans::PropertyValue
> aPathPropSeq
;
4842 if ( rGeoProp
.Value
>>= aPathPropSeq
)
4844 for ( const beans::PropertyValue
& rProp
: std::as_const(aPathPropSeq
) )
4846 switch( EASGet( rProp
.Name
) )
4848 case EAS_SubViewSize
:
4850 // export draw:sub-view-size (do not export in ODF 1.3 or older)
4851 if ((rExport
.getSaneDefaultVersion() & SvtSaveOptions::ODFSVER_EXTENDED
) == 0)
4855 uno::Sequence
< awt::Size
> aSubViewSizes
;
4856 rProp
.Value
>>= aSubViewSizes
;
4858 for ( int nIdx
= 0; nIdx
< aSubViewSizes
.getLength(); nIdx
++ )
4861 aStrBuffer
.append(' ');
4862 aStrBuffer
.append( aSubViewSizes
[nIdx
].Width
);
4863 aStrBuffer
.append(' ');
4864 aStrBuffer
.append( aSubViewSizes
[nIdx
].Height
);
4866 aStr
= aStrBuffer
.makeStringAndClear();
4867 rExport
.AddAttribute( XML_NAMESPACE_DRAW_EXT
, XML_SUB_VIEW_SIZE
, aStr
);
4870 case EAS_ExtrusionAllowed
:
4872 bool bExtrusionAllowed
;
4873 if ( rProp
.Value
>>= bExtrusionAllowed
)
4874 rExport
.AddAttribute( XML_NAMESPACE_DRAW
, XML_EXTRUSION_ALLOWED
,
4875 bExtrusionAllowed
? GetXMLToken( XML_TRUE
) : GetXMLToken( XML_FALSE
) );
4878 case EAS_ConcentricGradientFillAllowed
:
4880 bool bConcentricGradientFillAllowed
;
4881 if ( rProp
.Value
>>= bConcentricGradientFillAllowed
)
4882 rExport
.AddAttribute( XML_NAMESPACE_DRAW
, XML_CONCENTRIC_GRADIENT_FILL_ALLOWED
,
4883 bConcentricGradientFillAllowed
? GetXMLToken( XML_TRUE
) : GetXMLToken( XML_FALSE
) );
4886 case EAS_TextPathAllowed
:
4888 bool bTextPathAllowed
;
4889 if ( rProp
.Value
>>= bTextPathAllowed
)
4890 rExport
.AddAttribute( XML_NAMESPACE_DRAW
, XML_TEXT_PATH_ALLOWED
,
4891 bTextPathAllowed
? GetXMLToken( XML_TRUE
) : GetXMLToken( XML_FALSE
) );
4894 case EAS_GluePoints
:
4896 css::uno::Sequence
< css::drawing::EnhancedCustomShapeParameterPair
> aGluePoints
;
4897 if ( rProp
.Value
>>= aGluePoints
)
4899 if ( aGluePoints
.hasElements() )
4901 for( const auto& rGluePoint
: std::as_const(aGluePoints
) )
4903 ExportParameter( aStrBuffer
, rGluePoint
.First
);
4904 ExportParameter( aStrBuffer
, rGluePoint
.Second
);
4906 aStr
= aStrBuffer
.makeStringAndClear();
4908 rExport
.AddAttribute( XML_NAMESPACE_DRAW
, XML_GLUE_POINTS
, aStr
);
4912 case EAS_GluePointType
:
4914 sal_Int16 nGluePointType
= sal_Int16();
4915 if ( rProp
.Value
>>= nGluePointType
)
4917 switch ( nGluePointType
)
4919 case css::drawing::EnhancedCustomShapeGluePointType::NONE
: aStr
= GetXMLToken( XML_NONE
); break;
4920 case css::drawing::EnhancedCustomShapeGluePointType::SEGMENTS
: aStr
= GetXMLToken( XML_SEGMENTS
); break;
4921 case css::drawing::EnhancedCustomShapeGluePointType::RECT
: aStr
= GetXMLToken( XML_RECTANGLE
); break;
4923 if ( !aStr
.isEmpty() )
4924 rExport
.AddAttribute( XML_NAMESPACE_DRAW
, XML_GLUE_POINT_TYPE
, aStr
);
4928 case EAS_Coordinates
:
4930 bCoordinates
= ( rProp
.Value
>>= aCoordinates
);
4935 rProp
.Value
>>= aSegments
;
4940 sal_Int32 nStretchPoint
= 0;
4941 if ( rProp
.Value
>>= nStretchPoint
)
4942 rExport
.AddAttribute( XML_NAMESPACE_DRAW
, XML_PATH_STRETCHPOINT_X
, OUString::number( nStretchPoint
) );
4947 sal_Int32 nStretchPoint
= 0;
4948 if ( rProp
.Value
>>= nStretchPoint
)
4949 rExport
.AddAttribute( XML_NAMESPACE_DRAW
, XML_PATH_STRETCHPOINT_Y
, OUString::number( nStretchPoint
) );
4952 case EAS_TextFrames
:
4954 css::uno::Sequence
< css::drawing::EnhancedCustomShapeTextFrame
> aPathTextFrames
;
4955 if ( rProp
.Value
>>= aPathTextFrames
)
4957 if ( aPathTextFrames
.hasElements() )
4959 for ( const auto& rPathTextFrame
: std::as_const(aPathTextFrames
) )
4961 ExportParameter( aStrBuffer
, rPathTextFrame
.TopLeft
.First
);
4962 ExportParameter( aStrBuffer
, rPathTextFrame
.TopLeft
.Second
);
4963 ExportParameter( aStrBuffer
, rPathTextFrame
.BottomRight
.First
);
4964 ExportParameter( aStrBuffer
, rPathTextFrame
.BottomRight
.Second
);
4966 aStr
= aStrBuffer
.makeStringAndClear();
4968 rExport
.AddAttribute( XML_NAMESPACE_DRAW
, XML_TEXT_AREAS
, aStr
);
4979 case EAS_Equations
:
4981 bEquations
= ( rGeoProp
.Value
>>= aEquations
);
4986 bHandles
= ( rGeoProp
.Value
>>= aHandles
);
4989 case EAS_AdjustmentValues
:
4991 rGeoProp
.Value
>>= aAdjustmentValues
;
4999 // ToDo: Where is TextPreRotateAngle still used? We cannot save it in ODF.
5000 fTextRotateAngle
+= fTextPreRotateAngle
;
5001 // Workaround for writing-mode bt-lr and tb-rl90 in ODF strict,
5002 // otherwise loext:writing-mode is used in style export.
5003 if (!(rExport
.getSaneDefaultVersion() & SvtSaveOptions::ODFSVER_EXTENDED
))
5005 if (xPropSetInfo
->hasPropertyByName(u
"WritingMode"_ustr
))
5007 sal_Int16 nDirection
= -1;
5008 xPropSet
->getPropertyValue(u
"WritingMode"_ustr
) >>= nDirection
;
5009 if (nDirection
== text::WritingMode2::TB_RL90
)
5010 fTextRotateAngle
-= 90;
5011 else if (nDirection
== text::WritingMode2::BT_LR
)
5012 fTextRotateAngle
-= 270;
5015 if (fTextRotateAngle
!= 0)
5017 ::sax::Converter::convertDouble( aStrBuffer
, fTextRotateAngle
);
5018 aStr
= aStrBuffer
.makeStringAndClear();
5019 rExport
.AddAttribute( XML_NAMESPACE_DRAW
, XML_TEXT_ROTATE_ANGLE
, aStr
);
5022 rExport
.AddAttribute( XML_NAMESPACE_DRAW
, XML_TYPE
, aCustomShapeType
);
5025 sal_Int32 nAdjustmentValues
= aAdjustmentValues
.getLength();
5026 if ( nAdjustmentValues
)
5028 sal_Int32 i
, nValue
= 0;
5029 for ( i
= 0; i
< nAdjustmentValues
; i
++ )
5032 aStrBuffer
.append( ' ' );
5034 const css::drawing::EnhancedCustomShapeAdjustmentValue
& rAdj
= aAdjustmentValues
[ i
];
5035 if ( rAdj
.State
== beans::PropertyState_DIRECT_VALUE
)
5037 if ( rAdj
.Value
.getValueTypeClass() == uno::TypeClass_DOUBLE
)
5039 double fValue
= 0.0;
5040 rAdj
.Value
>>= fValue
;
5041 ::sax::Converter::convertDouble(aStrBuffer
, fValue
);
5045 rAdj
.Value
>>= nValue
;
5046 aStrBuffer
.append(nValue
);
5051 // this should not be, but better than setting nothing
5052 aStrBuffer
.append("0");
5055 aStr
= aStrBuffer
.makeStringAndClear();
5056 rExport
.AddAttribute( XML_NAMESPACE_DRAW
, XML_MODIFIERS
, aStr
);
5059 ImpExportEnhancedPath( rExport
, aCoordinates
, aSegments
);
5062 SvXMLElementExport
aOBJ( rExport
, XML_NAMESPACE_DRAW
, XML_ENHANCED_GEOMETRY
, true, true );
5064 ImpExportEquations( rExport
, aEquations
);
5066 ImpExportHandles( rExport
, aHandles
);
5069 void XMLShapeExport::ImpExportCustomShape(
5070 const uno::Reference
< drawing::XShape
>& xShape
,
5071 XMLShapeExportFlags nFeatures
, css::awt::Point
* pRefPoint
)
5073 const uno::Reference
< beans::XPropertySet
> xPropSet(xShape
, uno::UNO_QUERY
);
5074 if ( !xPropSet
.is() )
5077 uno::Reference
< beans::XPropertySetInfo
> xPropSetInfo( xPropSet
->getPropertySetInfo() );
5080 ImpExportNewTrans( xPropSet
, nFeatures
, pRefPoint
);
5082 if ( xPropSetInfo
.is() )
5085 if ( xPropSetInfo
->hasPropertyByName( "CustomShapeEngine" ) )
5087 uno::Any
aEngine( xPropSet
->getPropertyValue( "CustomShapeEngine" ) );
5088 if ( ( aEngine
>>= aStr
) && !aStr
.isEmpty() )
5089 mrExport
.AddAttribute( XML_NAMESPACE_DRAW
, XML_ENGINE
, aStr
);
5091 if ( xPropSetInfo
->hasPropertyByName( "CustomShapeData" ) )
5093 uno::Any
aData( xPropSet
->getPropertyValue( "CustomShapeData" ) );
5094 if ( ( aData
>>= aStr
) && !aStr
.isEmpty() )
5095 mrExport
.AddAttribute( XML_NAMESPACE_DRAW
, XML_DATA
, aStr
);
5098 bool bCreateNewline( (nFeatures
& XMLShapeExportFlags::NO_WS
) == XMLShapeExportFlags::NONE
); // #86116#/#92210#
5099 SvXMLElementExport
aOBJ( mrExport
, XML_NAMESPACE_DRAW
, XML_CUSTOM_SHAPE
, bCreateNewline
, true );
5100 ImpExportDescription( xShape
); // #i68101#
5101 ImpExportEvents( xShape
);
5102 ImpExportGluePoints( xShape
);
5103 ImpExportText( xShape
);
5104 ImpExportEnhancedGeometry( mrExport
, xPropSet
);
5108 void XMLShapeExport::ImpExportTableShape( const uno::Reference
< drawing::XShape
>& xShape
, XmlShapeType eShapeType
, XMLShapeExportFlags nFeatures
, css::awt::Point
* pRefPoint
)
5110 uno::Reference
< beans::XPropertySet
> xPropSet(xShape
, uno::UNO_QUERY
);
5111 uno::Reference
< container::XNamed
> xNamed(xShape
, uno::UNO_QUERY
);
5113 SAL_WARN_IF( !xPropSet
.is() || !xNamed
.is(), "xmloff", "xmloff::XMLShapeExport::ImpExportTableShape(), table shape is not implementing needed interfaces");
5114 if(!(xPropSet
.is() && xNamed
.is()))
5120 ImpExportNewTrans(xPropSet
, nFeatures
, pRefPoint
);
5122 bool bIsEmptyPresObj
= false;
5124 // presentation settings
5125 if(eShapeType
== XmlShapeType::PresTableShape
)
5126 bIsEmptyPresObj
= ImpExportPresentationAttributes( xPropSet
, GetXMLToken(XML_TABLE
) );
5128 const bool bCreateNewline( (nFeatures
& XMLShapeExportFlags::NO_WS
) == XMLShapeExportFlags::NONE
);
5130 SvXMLElementExport
aElement( mrExport
, XML_NAMESPACE_DRAW
, XML_FRAME
, bCreateNewline
, true );
5132 // do not export in ODF 1.1 or older
5133 if (mrExport
.getSaneDefaultVersion() >= SvtSaveOptions::ODFSVER_012
)
5135 if( !bIsEmptyPresObj
)
5137 uno::Reference
< container::XNamed
> xTemplate( xPropSet
->getPropertyValue("TableTemplate"), uno::UNO_QUERY
);
5138 if( xTemplate
.is() )
5140 const OUString
sTemplate( xTemplate
->getName() );
5141 if( !sTemplate
.isEmpty() )
5143 mrExport
.AddAttribute(XML_NAMESPACE_TABLE
, XML_TEMPLATE_NAME
, sTemplate
);
5145 for( const XMLPropertyMapEntry
* pEntry
= &aXMLTableShapeAttributes
[0]; !pEntry
->IsEnd(); pEntry
++ )
5150 xPropSet
->getPropertyValue( pEntry
->getApiName() ) >>= bBool
;
5152 mrExport
.AddAttribute(pEntry
->mnNameSpace
, pEntry
->meXMLName
, XML_TRUE
);
5154 catch( uno::Exception
& )
5156 DBG_UNHANDLED_EXCEPTION("xmloff.draw");
5162 uno::Reference
< table::XColumnRowRange
> xRange( xPropSet
->getPropertyValue( gsModel
), uno::UNO_QUERY_THROW
);
5163 GetShapeTableExport()->exportTable( xRange
);
5167 if( !bIsEmptyPresObj
)
5169 uno::Reference
< graphic::XGraphic
> xGraphic( xPropSet
->getPropertyValue("ReplacementGraphic"), uno::UNO_QUERY
);
5170 ExportGraphicPreview(xGraphic
, mrExport
, u
"TablePreview", u
".svm", "image/x-vclgraphic");
5173 ImpExportEvents( xShape
);
5174 ImpExportGluePoints( xShape
);
5175 ImpExportDescription( xShape
); // #i68101#
5177 catch( uno::Exception
const & )
5179 DBG_UNHANDLED_EXCEPTION("xmloff.draw");
5183 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */