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 OUStringLiteral
gsZIndex( u
"ZOrder" );
158 constexpr OUStringLiteral
gsPrintable( u
"Printable" );
159 constexpr OUStringLiteral
gsVisible( u
"Visible" );
160 constexpr OUStringLiteral
gsModel( u
"Model" );
161 constexpr OUStringLiteral
gsStartShape( u
"StartShape" );
162 constexpr OUStringLiteral
gsEndShape( u
"EndShape" );
163 constexpr OUStringLiteral
gsOnClick( u
"OnClick" );
164 constexpr OUStringLiteral
gsEventType( u
"EventType" );
165 constexpr OUStringLiteral
gsPresentation( u
"Presentation" );
166 constexpr OUStringLiteral
gsMacroName( u
"MacroName" );
167 constexpr OUStringLiteral
gsScript( u
"Script" );
168 constexpr OUStringLiteral
gsLibrary( u
"Library" );
169 constexpr OUStringLiteral
gsClickAction( u
"ClickAction" );
170 constexpr OUStringLiteral
gsBookmark( u
"Bookmark" );
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 layers
.erase(std::remove_if(layers
.begin(), layers
.end(),
1050 [](Layer
const& rLayer
) { return rLayer
.shapes
.empty(); }),
1052 bool isSorted(true);
1053 for (size_t i
= 1; i
< layers
.size(); ++i
)
1055 assert(layers
[i
].nMin
!= layers
[i
-1].nMax
); // unique!
1056 if (layers
[i
].nMin
< layers
[i
-1].nMax
)
1064 return; // nothing to do
1066 uno::Sequence
<sal_Int32
> aNewOrder(nCount
);
1067 auto iterInsert(aNewOrder
.getArray());
1068 for (auto const& rLayer
: layers
)
1070 assert(rLayer
.nMin
<= rLayer
.nMax
); // empty layers have been removed
1071 iterInsert
= std::copy(rLayer
.shapes
.begin(), rLayer
.shapes
.end(), iterInsert
);
1075 xShapes3
->sort(aNewOrder
);
1077 catch (uno::Exception
const&)
1079 SAL_WARN("xmloff", "FixZOrder: exception");
1083 } // namespace xmloff
1085 void XMLShapeExport::seekShapes( const uno::Reference
< drawing::XShapes
>& xShapes
) noexcept
1089 maCurrentShapesIter
= maShapesInfos
.find( xShapes
);
1090 if( maCurrentShapesIter
== maShapesInfos
.end() )
1092 auto itPair
= maShapesInfos
.emplace( xShapes
, ImplXMLShapeExportInfoVector( static_cast<ShapesInfos::size_type
>(xShapes
->getCount()) ) );
1094 maCurrentShapesIter
= itPair
.first
;
1096 SAL_WARN_IF( maCurrentShapesIter
== maShapesInfos
.end(), "xmloff", "XMLShapeExport::seekShapes(): insert into stl::map failed" );
1099 SAL_WARN_IF( (*maCurrentShapesIter
).second
.size() != static_cast<ShapesInfos::size_type
>(xShapes
->getCount()), "xmloff", "XMLShapeExport::seekShapes(): XShapes size varied between calls" );
1104 maCurrentShapesIter
= maShapesInfos
.end();
1108 void XMLShapeExport::exportAutoStyles()
1110 // export all autostyle infos
1114 GetExport().GetAutoStylePool()->exportXML( XmlStyleFamily::SD_GRAPHICS_ID
);
1117 // ...for presentation
1119 GetExport().GetAutoStylePool()->exportXML( XmlStyleFamily::SD_PRESENTATION_ID
);
1122 if( mxShapeTableExport
.is() )
1123 mxShapeTableExport
->exportAutoStyles();
1126 /// returns the export property mapper for external chaining
1127 SvXMLExportPropertyMapper
* XMLShapeExport::CreateShapePropMapper(
1128 SvXMLExport
& rExport
)
1130 rtl::Reference
< XMLPropertyHandlerFactory
> xFactory
= new XMLSdPropHdlFactory( rExport
.GetModel(), rExport
);
1131 rtl::Reference
< XMLPropertySetMapper
> xMapper
= new XMLShapePropertySetMapper( xFactory
, true );
1132 rExport
.GetTextParagraphExport(); // get or create text paragraph export
1133 SvXMLExportPropertyMapper
* pResult
=
1134 new XMLShapeExportPropertyMapper( xMapper
, rExport
);
1135 // chain text attributes
1139 void XMLShapeExport::ImpCalcShapeType(const uno::Reference
< drawing::XShape
>& xShape
,
1140 XmlShapeType
& eShapeType
)
1142 // set in every case, so init here
1143 eShapeType
= XmlShapeType::Unknown
;
1148 OUString
aType(xShape
->getShapeType());
1150 if(!aType
.match("com.sun.star."))
1153 if(aType
.match("drawing.", 13))
1156 if (aType
.match("Rectangle", 21)) { eShapeType
= XmlShapeType::DrawRectangleShape
; }
1158 // #i72177# Note: Correcting CustomShape, CustomShape->Custom, len from 9 (was wrong anyways) to 6.
1159 // As can be seen at the other compares, the appendix "Shape" is left out of the comparison.
1160 else if(aType
.match("Custom", 21)) { eShapeType
= XmlShapeType::DrawCustomShape
; }
1162 else if(aType
.match("Ellipse", 21)) { eShapeType
= XmlShapeType::DrawEllipseShape
; }
1163 else if(aType
.match("Control", 21)) { eShapeType
= XmlShapeType::DrawControlShape
; }
1164 else if(aType
.match("Connector", 21)) { eShapeType
= XmlShapeType::DrawConnectorShape
; }
1165 else if(aType
.match("Measure", 21)) { eShapeType
= XmlShapeType::DrawMeasureShape
; }
1166 else if(aType
.match("Line", 21)) { eShapeType
= XmlShapeType::DrawLineShape
; }
1168 // #i72177# Note: This covers two types by purpose, PolyPolygonShape and PolyPolygonPathShape
1169 else if(aType
.match("PolyPolygon", 21)) { eShapeType
= XmlShapeType::DrawPolyPolygonShape
; }
1171 // #i72177# Note: This covers two types by purpose, PolyLineShape and PolyLinePathShape
1172 else if(aType
.match("PolyLine", 21)) { eShapeType
= XmlShapeType::DrawPolyLineShape
; }
1174 else if(aType
.match("OpenBezier", 21)) { eShapeType
= XmlShapeType::DrawOpenBezierShape
; }
1175 else if(aType
.match("ClosedBezier", 21)) { eShapeType
= XmlShapeType::DrawClosedBezierShape
; }
1177 // #i72177# FreeHand (opened and closed) now supports the types OpenFreeHandShape and
1178 // ClosedFreeHandShape respectively. Represent them as bezier shapes
1179 else if(aType
.match("OpenFreeHand", 21)) { eShapeType
= XmlShapeType::DrawOpenBezierShape
; }
1180 else if(aType
.match("ClosedFreeHand", 21)) { eShapeType
= XmlShapeType::DrawClosedBezierShape
; }
1182 else if(aType
.match("GraphicObject", 21)) { eShapeType
= XmlShapeType::DrawGraphicObjectShape
; }
1183 else if(aType
.match("Group", 21)) { eShapeType
= XmlShapeType::DrawGroupShape
; }
1184 else if(aType
.match("Text", 21)) { eShapeType
= XmlShapeType::DrawTextShape
; }
1185 else if(aType
.match("OLE2", 21))
1187 eShapeType
= XmlShapeType::DrawOLE2Shape
;
1189 // get info about presentation shape
1190 uno::Reference
<beans::XPropertySet
> xPropSet(xShape
, uno::UNO_QUERY
);
1195 if(xPropSet
->getPropertyValue("CLSID") >>= sCLSID
)
1197 #if !ENABLE_WASM_STRIP_CHART
1198 // WASM_CHART change
1199 // TODO: With Chart extracted this cannot really happen since
1200 // no Chart could've been added at all
1201 if (sCLSID
== mrExport
.GetChartExport()->getChartCLSID() ||
1205 sCLSID
== SvGlobalName( SO3_RPTCH_CLASSID
).GetHexName() )
1207 eShapeType
= XmlShapeType::DrawChartShape
;
1209 else if (sCLSID
== SvGlobalName( SO3_SC_CLASSID
).GetHexName() )
1211 eShapeType
= XmlShapeType::DrawSheetShape
;
1215 // general OLE2 Object
1220 else if(aType
.match("Page", 21)) { eShapeType
= XmlShapeType::DrawPageShape
; }
1221 else if(aType
.match("Frame", 21)) { eShapeType
= XmlShapeType::DrawFrameShape
; }
1222 else if(aType
.match("Caption", 21)) { eShapeType
= XmlShapeType::DrawCaptionShape
; }
1223 else if(aType
.match("Plugin", 21)) { eShapeType
= XmlShapeType::DrawPluginShape
; }
1224 else if(aType
.match("Applet", 21)) { eShapeType
= XmlShapeType::DrawAppletShape
; }
1225 else if(aType
.match("MediaShape", 21)) { eShapeType
= XmlShapeType::DrawMediaShape
; }
1226 else if(aType
.match("TableShape", 21)) { eShapeType
= XmlShapeType::DrawTableShape
; }
1229 else if(aType
.match("Scene", 21 + 7)) { eShapeType
= XmlShapeType::Draw3DSceneObject
; }
1230 else if(aType
.match("Cube", 21 + 7)) { eShapeType
= XmlShapeType::Draw3DCubeObject
; }
1231 else if(aType
.match("Sphere", 21 + 7)) { eShapeType
= XmlShapeType::Draw3DSphereObject
; }
1232 else if(aType
.match("Lathe", 21 + 7)) { eShapeType
= XmlShapeType::Draw3DLatheObject
; }
1233 else if(aType
.match("Extrude", 21 + 7)) { eShapeType
= XmlShapeType::Draw3DExtrudeObject
; }
1235 else if(aType
.match("presentation.", 13))
1237 // presentation shapes
1238 if (aType
.match("TitleText", 26)) { eShapeType
= XmlShapeType::PresTitleTextShape
; }
1239 else if(aType
.match("Outliner", 26)) { eShapeType
= XmlShapeType::PresOutlinerShape
; }
1240 else if(aType
.match("Subtitle", 26)) { eShapeType
= XmlShapeType::PresSubtitleShape
; }
1241 else if(aType
.match("GraphicObject", 26)) { eShapeType
= XmlShapeType::PresGraphicObjectShape
; }
1242 else if(aType
.match("Page", 26)) { eShapeType
= XmlShapeType::PresPageShape
; }
1243 else if(aType
.match("OLE2", 26))
1245 eShapeType
= XmlShapeType::PresOLE2Shape
;
1247 // get info about presentation shape
1248 uno::Reference
<beans::XPropertySet
> xPropSet(xShape
, uno::UNO_QUERY
);
1250 if(xPropSet
.is()) try
1253 if(xPropSet
->getPropertyValue("CLSID") >>= sCLSID
)
1255 if( sCLSID
== SvGlobalName( SO3_SC_CLASSID
).GetHexName() )
1257 eShapeType
= XmlShapeType::PresSheetShape
;
1261 catch(const uno::Exception
&)
1263 SAL_WARN( "xmloff", "XMLShapeExport::ImpCalcShapeType(), expected ole shape to have the CLSID property?" );
1266 else if(aType
.match("Chart", 26)) { eShapeType
= XmlShapeType::PresChartShape
; }
1267 else if(aType
.match("OrgChart", 26)) { eShapeType
= XmlShapeType::PresOrgChartShape
; }
1268 else if(aType
.match("CalcShape", 26)) { eShapeType
= XmlShapeType::PresSheetShape
; }
1269 else if(aType
.match("TableShape", 26)) { eShapeType
= XmlShapeType::PresTableShape
; }
1270 else if(aType
.match("Notes", 26)) { eShapeType
= XmlShapeType::PresNotesShape
; }
1271 else if(aType
.match("HandoutShape", 26)) { eShapeType
= XmlShapeType::HandoutShape
; }
1272 else if(aType
.match("HeaderShape", 26)) { eShapeType
= XmlShapeType::PresHeaderShape
; }
1273 else if(aType
.match("FooterShape", 26)) { eShapeType
= XmlShapeType::PresFooterShape
; }
1274 else if(aType
.match("SlideNumberShape", 26)) { eShapeType
= XmlShapeType::PresSlideNumberShape
; }
1275 else if(aType
.match("DateTimeShape", 26)) { eShapeType
= XmlShapeType::PresDateTimeShape
; }
1276 else if(aType
.match("MediaShape", 26)) { eShapeType
= XmlShapeType::PresMediaShape
; }
1280 /** exports all user defined gluepoints */
1281 void XMLShapeExport::ImpExportGluePoints( const uno::Reference
< drawing::XShape
>& xShape
)
1283 uno::Reference
< drawing::XGluePointsSupplier
> xSupplier( xShape
, uno::UNO_QUERY
);
1284 if( !xSupplier
.is() )
1287 uno::Reference
< container::XIdentifierAccess
> xGluePoints( xSupplier
->getGluePoints(), uno::UNO_QUERY
);
1288 if( !xGluePoints
.is() )
1291 drawing::GluePoint2 aGluePoint
;
1293 const uno::Sequence
< sal_Int32
> aIdSequence( xGluePoints
->getIdentifiers() );
1295 for( const sal_Int32 nIdentifier
: aIdSequence
)
1297 if( (xGluePoints
->getByIdentifier( nIdentifier
) >>= aGluePoint
) && aGluePoint
.IsUserDefined
)
1299 // export only user defined gluepoints
1301 const OUString
sId( OUString::number( nIdentifier
) );
1302 mrExport
.AddAttribute(XML_NAMESPACE_DRAW
, XML_ID
, sId
);
1304 mrExport
.GetMM100UnitConverter().convertMeasureToXML(msBuffer
,
1305 aGluePoint
.Position
.X
);
1306 mrExport
.AddAttribute(XML_NAMESPACE_SVG
, XML_X
, msBuffer
.makeStringAndClear());
1308 mrExport
.GetMM100UnitConverter().convertMeasureToXML(msBuffer
,
1309 aGluePoint
.Position
.Y
);
1310 mrExport
.AddAttribute(XML_NAMESPACE_SVG
, XML_Y
, msBuffer
.makeStringAndClear());
1312 if( !aGluePoint
.IsRelative
)
1314 SvXMLUnitConverter::convertEnum( msBuffer
, aGluePoint
.PositionAlignment
, aXML_GlueAlignment_EnumMap
);
1315 mrExport
.AddAttribute( XML_NAMESPACE_DRAW
, XML_ALIGN
, msBuffer
.makeStringAndClear() );
1318 if( aGluePoint
.Escape
!= drawing::EscapeDirection_SMART
)
1320 SvXMLUnitConverter::convertEnum( msBuffer
, aGluePoint
.Escape
, aXML_GlueEscapeDirection_EnumMap
);
1321 mrExport
.AddAttribute( XML_NAMESPACE_DRAW
, XML_ESCAPE_DIRECTION
, msBuffer
.makeStringAndClear() );
1324 SvXMLElementExport
aEventsElemt(mrExport
, XML_NAMESPACE_DRAW
, XML_GLUE_POINT
, true, true);
1329 void XMLShapeExport::ImpExportSignatureLine(const uno::Reference
<drawing::XShape
>& xShape
)
1331 uno::Reference
<beans::XPropertySet
> xPropSet(xShape
, uno::UNO_QUERY
);
1333 bool bIsSignatureLine
= false;
1334 xPropSet
->getPropertyValue("IsSignatureLine") >>= bIsSignatureLine
;
1335 if (!bIsSignatureLine
)
1338 OUString aSignatureLineId
;
1339 xPropSet
->getPropertyValue("SignatureLineId") >>= aSignatureLineId
;
1340 mrExport
.AddAttribute(XML_NAMESPACE_LO_EXT
, XML_ID
, aSignatureLineId
);
1342 OUString aSuggestedSignerName
;
1343 xPropSet
->getPropertyValue("SignatureLineSuggestedSignerName") >>= aSuggestedSignerName
;
1344 if (!aSuggestedSignerName
.isEmpty())
1345 mrExport
.AddAttribute(XML_NAMESPACE_LO_EXT
, XML_SUGGESTED_SIGNER_NAME
, aSuggestedSignerName
);
1347 OUString aSuggestedSignerTitle
;
1348 xPropSet
->getPropertyValue("SignatureLineSuggestedSignerTitle") >>= aSuggestedSignerTitle
;
1349 if (!aSuggestedSignerTitle
.isEmpty())
1350 mrExport
.AddAttribute(XML_NAMESPACE_LO_EXT
, XML_SUGGESTED_SIGNER_TITLE
, aSuggestedSignerTitle
);
1352 OUString aSuggestedSignerEmail
;
1353 xPropSet
->getPropertyValue("SignatureLineSuggestedSignerEmail") >>= aSuggestedSignerEmail
;
1354 if (!aSuggestedSignerEmail
.isEmpty())
1355 mrExport
.AddAttribute(XML_NAMESPACE_LO_EXT
, XML_SUGGESTED_SIGNER_EMAIL
, aSuggestedSignerEmail
);
1357 OUString aSigningInstructions
;
1358 xPropSet
->getPropertyValue("SignatureLineSigningInstructions") >>= aSigningInstructions
;
1359 if (!aSigningInstructions
.isEmpty())
1360 mrExport
.AddAttribute(XML_NAMESPACE_LO_EXT
, XML_SIGNING_INSTRUCTIONS
, aSigningInstructions
);
1362 bool bShowSignDate
= false;
1363 xPropSet
->getPropertyValue("SignatureLineShowSignDate") >>= bShowSignDate
;
1364 mrExport
.AddAttribute(XML_NAMESPACE_LO_EXT
, XML_SHOW_SIGN_DATE
,
1365 bShowSignDate
? XML_TRUE
: XML_FALSE
);
1367 bool bCanAddComment
= false;
1368 xPropSet
->getPropertyValue("SignatureLineCanAddComment") >>= bCanAddComment
;
1369 mrExport
.AddAttribute(XML_NAMESPACE_LO_EXT
, XML_CAN_ADD_COMMENT
,
1370 bCanAddComment
? XML_TRUE
: XML_FALSE
);
1372 SvXMLElementExport
aSignatureLineElement(mrExport
, XML_NAMESPACE_LO_EXT
, XML_SIGNATURELINE
, true,
1376 void XMLShapeExport::ImpExportQRCode(const uno::Reference
<drawing::XShape
>& xShape
)
1378 uno::Reference
<beans::XPropertySet
> xPropSet(xShape
, uno::UNO_QUERY
);
1380 uno::Any aAny
= xPropSet
->getPropertyValue("BarCodeProperties");
1382 css::drawing::BarCode aBarCode
;
1383 if(!(aAny
>>= aBarCode
))
1386 mrExport
.AddAttribute(XML_NAMESPACE_OFFICE
, XML_STRING_VALUE
, aBarCode
.Payload
);
1387 /* Export QR Code as per customised schema, @see OpenDocument-schema-v1.3+libreoffice */
1389 switch(aBarCode
.ErrorCorrection
){
1390 case css::drawing::BarCodeErrorCorrection::LOW
:
1393 case css::drawing::BarCodeErrorCorrection::MEDIUM
:
1396 case css::drawing::BarCodeErrorCorrection::QUARTILE
:
1399 case css::drawing::BarCodeErrorCorrection::HIGH
:
1403 mrExport
.AddAttribute(XML_NAMESPACE_LO_EXT
, XML_QRCODE_ERROR_CORRECTION
, temp
);
1404 mrExport
.AddAttribute(XML_NAMESPACE_LO_EXT
, XML_QRCODE_BORDER
, OUStringBuffer(20).append(aBarCode
.Border
).makeStringAndClear());
1405 mrExport
.AddAttribute(XML_NAMESPACE_LO_EXT
, XML_QRCODE_TYPE
, OUStringBuffer(20).append(aBarCode
.Type
).makeStringAndClear());
1407 SvXMLElementExport
aBarCodeElement(mrExport
, XML_NAMESPACE_LO_EXT
, XML_QRCODE
, true,
1411 void XMLShapeExport::ExportGraphicDefaults()
1413 rtl::Reference
<XMLStyleExport
> aStEx(new XMLStyleExport(mrExport
, mrExport
.GetAutoStylePool().get()));
1415 // construct PropertySetMapper
1416 rtl::Reference
< SvXMLExportPropertyMapper
> xPropertySetMapper( CreateShapePropMapper( mrExport
) );
1417 static_cast<XMLShapeExportPropertyMapper
*>(xPropertySetMapper
.get())->SetAutoStyles( false );
1419 // chain text attributes
1420 xPropertySetMapper
->ChainExportMapper(XMLTextParagraphExport::CreateParaExtPropMapper(mrExport
));
1422 // chain special Writer/text frame default attributes
1423 xPropertySetMapper
->ChainExportMapper(XMLTextParagraphExport::CreateParaDefaultExtPropMapper(mrExport
));
1425 // write graphic family default style
1426 uno::Reference
< lang::XMultiServiceFactory
> xFact( mrExport
.GetModel(), uno::UNO_QUERY
);
1432 uno::Reference
< beans::XPropertySet
> xDefaults( xFact
->createInstance("com.sun.star.drawing.Defaults"), uno::UNO_QUERY
);
1433 if( xDefaults
.is() )
1435 aStEx
->exportDefaultStyle( xDefaults
, XML_STYLE_FAMILY_SD_GRAPHICS_NAME
, xPropertySetMapper
);
1437 // write graphic styles (family name differs depending on the module)
1438 aStEx
->exportStyleFamily("graphics", OUString(XML_STYLE_FAMILY_SD_GRAPHICS_NAME
), xPropertySetMapper
, false, XmlStyleFamily::SD_GRAPHICS_ID
);
1439 aStEx
->exportStyleFamily("GraphicStyles", OUString(XML_STYLE_FAMILY_SD_GRAPHICS_NAME
), xPropertySetMapper
, false, XmlStyleFamily::SD_GRAPHICS_ID
);
1442 catch(const lang::ServiceNotRegisteredException
&)
1447 void XMLShapeExport::onExport( const css::uno::Reference
< css::drawing::XShape
>& )
1451 const rtl::Reference
< XMLTableExport
>& XMLShapeExport::GetShapeTableExport()
1453 if( !mxShapeTableExport
.is() )
1455 rtl::Reference
< XMLPropertyHandlerFactory
> xFactory( new XMLSdPropHdlFactory( mrExport
.GetModel(), mrExport
) );
1456 rtl::Reference
< XMLPropertySetMapper
> xMapper( new XMLShapePropertySetMapper( xFactory
, true ) );
1457 mrExport
.GetTextParagraphExport(); // get or create text paragraph export
1458 rtl::Reference
< SvXMLExportPropertyMapper
> xPropertySetMapper( new XMLShapeExportPropertyMapper( xMapper
, mrExport
) );
1459 mxShapeTableExport
= new XMLTableExport( mrExport
, xPropertySetMapper
, xFactory
);
1462 return mxShapeTableExport
;
1465 void XMLShapeExport::ImpExportNewTrans(const uno::Reference
< beans::XPropertySet
>& xPropSet
,
1466 XMLShapeExportFlags nFeatures
, awt::Point
* pRefPoint
)
1469 ::basegfx::B2DHomMatrix aMatrix
;
1470 ImpExportNewTrans_GetB2DHomMatrix(aMatrix
, xPropSet
);
1472 // decompose and correct about pRefPoint
1473 ::basegfx::B2DTuple aTRScale
;
1474 double fTRShear(0.0);
1475 double fTRRotate(0.0);
1476 ::basegfx::B2DTuple aTRTranslate
;
1477 ImpExportNewTrans_DecomposeAndRefPoint(aMatrix
, aTRScale
, fTRShear
, fTRRotate
, aTRTranslate
, pRefPoint
);
1479 // use features and write
1480 ImpExportNewTrans_FeaturesAndWrite(aTRScale
, fTRShear
, fTRRotate
, aTRTranslate
, nFeatures
);
1483 void XMLShapeExport::ImpExportNewTrans_GetB2DHomMatrix(::basegfx::B2DHomMatrix
& rMatrix
,
1484 const uno::Reference
< beans::XPropertySet
>& xPropSet
)
1486 /* Get <TransformationInHoriL2R>, if it exist
1487 and if the document is exported into the OpenOffice.org file format.
1488 This property only exists at service css::text::Shape - the
1489 Writer UNO service for shapes.
1490 This code is needed, because the positioning attributes in the
1491 OpenOffice.org file format are given in horizontal left-to-right layout
1492 regardless the layout direction the shape is in. In the OASIS Open Office
1493 file format the positioning attributes are correctly given in the layout
1494 direction the shape is in. Thus, this code provides the conversion from
1495 the OASIS Open Office file format to the OpenOffice.org file format. (#i28749#)
1498 if ( !( GetExport().getExportFlags() & SvXMLExportFlags::OASIS
) &&
1499 xPropSet
->getPropertySetInfo()->hasPropertyByName("TransformationInHoriL2R") )
1501 aAny
= xPropSet
->getPropertyValue("TransformationInHoriL2R");
1505 aAny
= xPropSet
->getPropertyValue("Transformation");
1507 drawing::HomogenMatrix3 aMatrix
;
1510 rMatrix
.set(0, 0, aMatrix
.Line1
.Column1
);
1511 rMatrix
.set(0, 1, aMatrix
.Line1
.Column2
);
1512 rMatrix
.set(0, 2, aMatrix
.Line1
.Column3
);
1513 rMatrix
.set(1, 0, aMatrix
.Line2
.Column1
);
1514 rMatrix
.set(1, 1, aMatrix
.Line2
.Column2
);
1515 rMatrix
.set(1, 2, aMatrix
.Line2
.Column3
);
1516 // For this to be a valid 2D transform matrix, the last row must be [0,0,1]
1517 assert( aMatrix
.Line3
.Column1
== 0 );
1518 assert( aMatrix
.Line3
.Column2
== 0 );
1519 assert( aMatrix
.Line3
.Column3
== 1 );
1522 void XMLShapeExport::ImpExportNewTrans_DecomposeAndRefPoint(const ::basegfx::B2DHomMatrix
& rMatrix
, ::basegfx::B2DTuple
& rTRScale
,
1523 double& fTRShear
, double& fTRRotate
, ::basegfx::B2DTuple
& rTRTranslate
, css::awt::Point
* pRefPoint
)
1526 rMatrix
.decompose(rTRScale
, rTRTranslate
, fTRRotate
, fTRShear
);
1528 // correct translation about pRefPoint
1531 rTRTranslate
-= ::basegfx::B2DTuple(pRefPoint
->X
, pRefPoint
->Y
);
1535 void XMLShapeExport::ImpExportNewTrans_FeaturesAndWrite(::basegfx::B2DTuple
const & rTRScale
, double fTRShear
,
1536 double fTRRotate
, ::basegfx::B2DTuple
const & rTRTranslate
, const XMLShapeExportFlags nFeatures
)
1538 // always write Size (rTRScale) since this statement carries the union
1541 OUStringBuffer sStringBuffer
;
1542 ::basegfx::B2DTuple
aTRScale(rTRScale
);
1545 if(!(nFeatures
& XMLShapeExportFlags::WIDTH
))
1551 if( aTRScale
.getX() > 0.0 )
1552 aTRScale
.setX(aTRScale
.getX() - 1.0);
1553 else if( aTRScale
.getX() < 0.0 )
1554 aTRScale
.setX(aTRScale
.getX() + 1.0);
1557 mrExport
.GetMM100UnitConverter().convertMeasureToXML(sStringBuffer
,
1558 FRound(aTRScale
.getX()));
1559 aStr
= sStringBuffer
.makeStringAndClear();
1560 mrExport
.AddAttribute(XML_NAMESPACE_SVG
, XML_WIDTH
, aStr
);
1563 if(!(nFeatures
& XMLShapeExportFlags::HEIGHT
))
1569 if( aTRScale
.getY() > 0.0 )
1570 aTRScale
.setY(aTRScale
.getY() - 1.0);
1571 else if( aTRScale
.getY() < 0.0 )
1572 aTRScale
.setY(aTRScale
.getY() + 1.0);
1575 mrExport
.GetMM100UnitConverter().convertMeasureToXML(sStringBuffer
,
1576 FRound(aTRScale
.getY()));
1577 aStr
= sStringBuffer
.makeStringAndClear();
1578 mrExport
.AddAttribute(XML_NAMESPACE_SVG
, XML_HEIGHT
, aStr
);
1580 // decide if transformation is necessary
1581 bool bTransformationIsNecessary(fTRShear
!= 0.0 || fTRRotate
!= 0.0);
1583 if(bTransformationIsNecessary
)
1585 // write transformation, but WITHOUT scale which is exported as size above
1586 SdXMLImExTransform2D aTransform
;
1588 aTransform
.AddSkewX(atan(fTRShear
));
1591 // fTRRotate is mathematically correct, but due to the error
1592 // we export/import it mirrored. Since the API implementation is fixed and
1593 // uses the correctly oriented angle, it is necessary for compatibility to
1594 // mirror the angle here to stay at the old behaviour. There is a follow-up
1595 // task (#i78698#) to fix this in the next ODF FileFormat version
1596 aTransform
.AddRotate(-fTRRotate
);
1598 aTransform
.AddTranslate(rTRTranslate
);
1600 // does transformation need to be exported?
1601 if(aTransform
.NeedsAction())
1602 mrExport
.AddAttribute(XML_NAMESPACE_DRAW
, XML_TRANSFORM
, aTransform
.GetExportString(mrExport
.GetMM100UnitConverter()));
1606 // no shear, no rotate; just add object position to export and we are done
1607 if(nFeatures
& XMLShapeExportFlags::X
)
1610 mrExport
.GetMM100UnitConverter().convertMeasureToXML(sStringBuffer
,
1611 FRound(rTRTranslate
.getX()));
1612 aStr
= sStringBuffer
.makeStringAndClear();
1613 mrExport
.AddAttribute(XML_NAMESPACE_SVG
, XML_X
, aStr
);
1616 if(nFeatures
& XMLShapeExportFlags::Y
)
1619 mrExport
.GetMM100UnitConverter().convertMeasureToXML(sStringBuffer
,
1620 FRound(rTRTranslate
.getY()));
1621 aStr
= sStringBuffer
.makeStringAndClear();
1622 mrExport
.AddAttribute(XML_NAMESPACE_SVG
, XML_Y
, aStr
);
1627 bool XMLShapeExport::ImpExportPresentationAttributes( const uno::Reference
< beans::XPropertySet
>& xPropSet
, const OUString
& rClass
)
1629 bool bIsEmpty
= false;
1631 // write presentation class entry
1632 mrExport
.AddAttribute(XML_NAMESPACE_PRESENTATION
, XML_CLASS
, rClass
);
1636 uno::Reference
< beans::XPropertySetInfo
> xPropSetInfo( xPropSet
->getPropertySetInfo() );
1639 // is empty pres. shape?
1640 if( xPropSetInfo
.is() && xPropSetInfo
->hasPropertyByName("IsEmptyPresentationObject"))
1642 xPropSet
->getPropertyValue("IsEmptyPresentationObject") >>= bIsEmpty
;
1644 mrExport
.AddAttribute(XML_NAMESPACE_PRESENTATION
, XML_PLACEHOLDER
, XML_TRUE
);
1647 // is user-transformed?
1648 if( xPropSetInfo
.is() && xPropSetInfo
->hasPropertyByName("IsPlaceholderDependent"))
1651 xPropSet
->getPropertyValue("IsPlaceholderDependent") >>= bTemp
;
1653 mrExport
.AddAttribute(XML_NAMESPACE_PRESENTATION
, XML_USER_TRANSFORMED
, XML_TRUE
);
1660 void XMLShapeExport::ImpExportText( const uno::Reference
< drawing::XShape
>& xShape
, TextPNS eExtensionNS
)
1662 if (eExtensionNS
== TextPNS::EXTENSION
)
1664 if ((mrExport
.getSaneDefaultVersion() & SvtSaveOptions::ODFSVER_EXTENDED
) == 0)
1666 return; // do not export to ODF 1.1/1.2/1.3
1669 uno::Reference
< text::XText
> xText( xShape
, uno::UNO_QUERY
);
1672 uno::Reference
< container::XEnumerationAccess
> xEnumAccess( xShape
, uno::UNO_QUERY
);
1673 if( xEnumAccess
.is() && xEnumAccess
->hasElements() )
1674 mrExport
.GetTextParagraphExport()->exportText( xText
, false, true, eExtensionNS
);
1682 CLICKACTION
= 0x0001,
1689 CLICKEVENTTYPE
= 0x0080,
1697 template<> struct typed_flags
<Found
> : is_typed_flags
<Found
, 0x03ff> {};
1700 void XMLShapeExport::ImpExportEvents( const uno::Reference
< drawing::XShape
>& xShape
)
1702 uno::Reference
< document::XEventsSupplier
> xEventsSupplier( xShape
, uno::UNO_QUERY
);
1703 if( !xEventsSupplier
.is() )
1706 uno::Reference
< container::XNameAccess
> xEvents
= xEventsSupplier
->getEvents();
1707 SAL_WARN_IF( !xEvents
.is(), "xmloff", "XEventsSupplier::getEvents() returned NULL" );
1711 Found nFound
= Found::NONE
;
1713 OUString aClickEventType
;
1714 presentation::ClickAction eClickAction
= presentation::ClickAction_NONE
;
1715 presentation::AnimationEffect eEffect
= presentation::AnimationEffect_NONE
;
1716 presentation::AnimationSpeed eSpeed
= presentation::AnimationSpeed_SLOW
;
1717 OUString aStrSoundURL
;
1718 bool bPlayFull
= false;
1719 sal_Int32 nVerb
= 0;
1721 OUString aStrLibrary
;
1722 OUString aStrBookmark
;
1724 uno::Sequence
< beans::PropertyValue
> aClickProperties
;
1725 if( xEvents
->hasByName( gsOnClick
) && (xEvents
->getByName( gsOnClick
) >>= aClickProperties
) )
1727 for( const auto& rProperty
: std::as_const(aClickProperties
) )
1729 if( !( nFound
& Found::CLICKEVENTTYPE
) && rProperty
.Name
== gsEventType
)
1731 if( rProperty
.Value
>>= aClickEventType
)
1732 nFound
|= Found::CLICKEVENTTYPE
;
1734 else if( !( nFound
& Found::CLICKACTION
) && rProperty
.Name
== gsClickAction
)
1736 if( rProperty
.Value
>>= eClickAction
)
1737 nFound
|= Found::CLICKACTION
;
1739 else if( !( nFound
& Found::MACRO
) && ( rProperty
.Name
== gsMacroName
|| rProperty
.Name
== gsScript
) )
1741 if( rProperty
.Value
>>= aStrMacro
)
1742 nFound
|= Found::MACRO
;
1744 else if( !( nFound
& Found::LIBRARY
) && rProperty
.Name
== gsLibrary
)
1746 if( rProperty
.Value
>>= aStrLibrary
)
1747 nFound
|= Found::LIBRARY
;
1749 else if( !( nFound
& Found::EFFECT
) && rProperty
.Name
== gsEffect
)
1751 if( rProperty
.Value
>>= eEffect
)
1752 nFound
|= Found::EFFECT
;
1754 else if( !( nFound
& Found::BOOKMARK
) && rProperty
.Name
== gsBookmark
)
1756 if( rProperty
.Value
>>= aStrBookmark
)
1757 nFound
|= Found::BOOKMARK
;
1759 else if( !( nFound
& Found::SPEED
) && rProperty
.Name
== gsSpeed
)
1761 if( rProperty
.Value
>>= eSpeed
)
1762 nFound
|= Found::SPEED
;
1764 else if( !( nFound
& Found::SOUNDURL
) && rProperty
.Name
== gsSoundURL
)
1766 if( rProperty
.Value
>>= aStrSoundURL
)
1767 nFound
|= Found::SOUNDURL
;
1769 else if( !( nFound
& Found::PLAYFULL
) && rProperty
.Name
== gsPlayFull
)
1771 if( rProperty
.Value
>>= bPlayFull
)
1772 nFound
|= Found::PLAYFULL
;
1774 else if( !( nFound
& Found::VERB
) && rProperty
.Name
== gsVerb
)
1776 if( rProperty
.Value
>>= nVerb
)
1777 nFound
|= Found::VERB
;
1782 // create the XML elements
1784 if( aClickEventType
== gsPresentation
)
1786 if( !(nFound
& Found::CLICKACTION
) || (eClickAction
== presentation::ClickAction_NONE
) )
1789 SvXMLElementExport
aEventsElemt(mrExport
, XML_NAMESPACE_OFFICE
, XML_EVENT_LISTENERS
, true, true);
1791 enum XMLTokenEnum eStrAction
;
1793 switch( eClickAction
)
1795 case presentation::ClickAction_PREVPAGE
: eStrAction
= XML_PREVIOUS_PAGE
; break;
1796 case presentation::ClickAction_NEXTPAGE
: eStrAction
= XML_NEXT_PAGE
; break;
1797 case presentation::ClickAction_FIRSTPAGE
: eStrAction
= XML_FIRST_PAGE
; break;
1798 case presentation::ClickAction_LASTPAGE
: eStrAction
= XML_LAST_PAGE
; break;
1799 case presentation::ClickAction_INVISIBLE
: eStrAction
= XML_HIDE
; break;
1800 case presentation::ClickAction_STOPPRESENTATION
:eStrAction
= XML_STOP
; break;
1801 case presentation::ClickAction_PROGRAM
: eStrAction
= XML_EXECUTE
; break;
1802 case presentation::ClickAction_BOOKMARK
: eStrAction
= XML_SHOW
; break;
1803 case presentation::ClickAction_DOCUMENT
: eStrAction
= XML_SHOW
; break;
1804 case presentation::ClickAction_MACRO
: eStrAction
= XML_EXECUTE_MACRO
; break;
1805 case presentation::ClickAction_VERB
: eStrAction
= XML_VERB
; break;
1806 case presentation::ClickAction_VANISH
: eStrAction
= XML_FADE_OUT
; break;
1807 case presentation::ClickAction_SOUND
: eStrAction
= XML_SOUND
; break;
1809 OSL_FAIL( "unknown presentation::ClickAction found!" );
1810 eStrAction
= XML_UNKNOWN
;
1813 OUString
aEventQName(
1814 mrExport
.GetNamespaceMap().GetQNameByKey(
1815 XML_NAMESPACE_DOM
, "click" ) );
1816 mrExport
.AddAttribute( XML_NAMESPACE_SCRIPT
, XML_EVENT_NAME
, aEventQName
);
1817 mrExport
.AddAttribute( XML_NAMESPACE_PRESENTATION
, XML_ACTION
, eStrAction
);
1819 if( eClickAction
== presentation::ClickAction_VANISH
)
1821 if( nFound
& Found::EFFECT
)
1824 XMLEffectDirection eDirection
;
1825 sal_Int16 nStartScale
;
1828 SdXMLImplSetEffect( eEffect
, eKind
, eDirection
, nStartScale
, bIn
);
1830 if( eKind
!= EK_none
)
1832 SvXMLUnitConverter::convertEnum( msBuffer
, eKind
, aXML_AnimationEffect_EnumMap
);
1833 mrExport
.AddAttribute( XML_NAMESPACE_PRESENTATION
, XML_EFFECT
, msBuffer
.makeStringAndClear() );
1836 if( eDirection
!= ED_none
)
1838 SvXMLUnitConverter::convertEnum( msBuffer
, eDirection
, aXML_AnimationDirection_EnumMap
);
1839 mrExport
.AddAttribute( XML_NAMESPACE_PRESENTATION
, XML_DIRECTION
, msBuffer
.makeStringAndClear() );
1842 if( nStartScale
!= -1 )
1844 ::sax::Converter::convertPercent( msBuffer
, nStartScale
);
1845 mrExport
.AddAttribute( XML_NAMESPACE_PRESENTATION
, XML_START_SCALE
, msBuffer
.makeStringAndClear() );
1849 if( nFound
& Found::SPEED
&& eEffect
!= presentation::AnimationEffect_NONE
)
1851 if( eSpeed
!= presentation::AnimationSpeed_MEDIUM
)
1853 SvXMLUnitConverter::convertEnum( msBuffer
, eSpeed
, aXML_AnimationSpeed_EnumMap
);
1854 mrExport
.AddAttribute( XML_NAMESPACE_PRESENTATION
, XML_SPEED
, msBuffer
.makeStringAndClear() );
1859 if( eClickAction
== presentation::ClickAction_PROGRAM
||
1860 eClickAction
== presentation::ClickAction_BOOKMARK
||
1861 eClickAction
== presentation::ClickAction_DOCUMENT
)
1863 if( eClickAction
== presentation::ClickAction_BOOKMARK
)
1864 msBuffer
.append( '#' );
1866 msBuffer
.append( aStrBookmark
);
1867 mrExport
.AddAttribute(XML_NAMESPACE_XLINK
, XML_HREF
, GetExport().GetRelativeReference(msBuffer
.makeStringAndClear()) );
1868 mrExport
.AddAttribute( XML_NAMESPACE_XLINK
, XML_TYPE
, XML_SIMPLE
);
1869 mrExport
.AddAttribute( XML_NAMESPACE_XLINK
, XML_SHOW
, XML_EMBED
);
1870 mrExport
.AddAttribute( XML_NAMESPACE_XLINK
, XML_ACTUATE
, XML_ONREQUEST
);
1873 if( ( nFound
& Found::VERB
) && eClickAction
== presentation::ClickAction_VERB
)
1875 msBuffer
.append( nVerb
);
1876 mrExport
.AddAttribute(XML_NAMESPACE_PRESENTATION
, XML_VERB
, msBuffer
.makeStringAndClear());
1879 SvXMLElementExport
aEventElemt(mrExport
, XML_NAMESPACE_PRESENTATION
, XML_EVENT_LISTENER
, true, true);
1881 if( eClickAction
== presentation::ClickAction_VANISH
|| eClickAction
== presentation::ClickAction_SOUND
)
1883 if( ( nFound
& Found::SOUNDURL
) && !aStrSoundURL
.isEmpty() )
1885 mrExport
.AddAttribute(XML_NAMESPACE_XLINK
, XML_HREF
, GetExport().GetRelativeReference(aStrSoundURL
) );
1886 mrExport
.AddAttribute( XML_NAMESPACE_XLINK
, XML_TYPE
, XML_SIMPLE
);
1887 mrExport
.AddAttribute( XML_NAMESPACE_XLINK
, XML_SHOW
, XML_NEW
);
1888 mrExport
.AddAttribute( XML_NAMESPACE_XLINK
, XML_ACTUATE
, XML_ONREQUEST
);
1889 if( nFound
& Found::PLAYFULL
&& bPlayFull
)
1890 mrExport
.AddAttribute( XML_NAMESPACE_PRESENTATION
, XML_PLAY_FULL
, XML_TRUE
);
1892 SvXMLElementExport
aElem( mrExport
, XML_NAMESPACE_PRESENTATION
, XML_SOUND
, true, true );
1896 else if( aClickEventType
== gsStarBasic
)
1898 if( nFound
& Found::MACRO
)
1900 SvXMLElementExport
aEventsElemt(mrExport
, XML_NAMESPACE_OFFICE
, XML_EVENT_LISTENERS
, true, true);
1902 mrExport
.AddAttribute( XML_NAMESPACE_SCRIPT
, XML_LANGUAGE
,
1903 mrExport
.GetNamespaceMap().GetQNameByKey(
1906 OUString
aEventQName(
1907 mrExport
.GetNamespaceMap().GetQNameByKey(
1908 XML_NAMESPACE_DOM
, "click" ) );
1909 mrExport
.AddAttribute( XML_NAMESPACE_SCRIPT
, XML_EVENT_NAME
, aEventQName
);
1911 if( nFound
& Found::LIBRARY
)
1913 const OUString
& sLocation( GetXMLToken(
1914 (aStrLibrary
.equalsIgnoreAsciiCase("StarOffice") ||
1915 aStrLibrary
.equalsIgnoreAsciiCase("application") ) ? XML_APPLICATION
1917 mrExport
.AddAttribute(XML_NAMESPACE_SCRIPT
, XML_MACRO_NAME
,
1918 sLocation
+ ":" + aStrMacro
);
1922 mrExport
.AddAttribute( XML_NAMESPACE_SCRIPT
, XML_MACRO_NAME
, aStrMacro
);
1925 SvXMLElementExport
aEventElemt(mrExport
, XML_NAMESPACE_SCRIPT
, XML_EVENT_LISTENER
, true, true);
1928 else if( aClickEventType
== gsScript
)
1930 if( nFound
& Found::MACRO
)
1932 SvXMLElementExport
aEventsElemt(mrExport
, XML_NAMESPACE_OFFICE
, XML_EVENT_LISTENERS
, true, true);
1934 mrExport
.AddAttribute( XML_NAMESPACE_SCRIPT
, XML_LANGUAGE
, mrExport
.GetNamespaceMap().GetQNameByKey(
1935 XML_NAMESPACE_OOO
, GetXMLToken(XML_SCRIPT
) ) );
1936 OUString
aEventQName(
1937 mrExport
.GetNamespaceMap().GetQNameByKey(
1938 XML_NAMESPACE_DOM
, "click" ) );
1939 mrExport
.AddAttribute( XML_NAMESPACE_SCRIPT
, XML_EVENT_NAME
, aEventQName
);
1940 mrExport
.AddAttribute( XML_NAMESPACE_XLINK
, XML_HREF
, aStrMacro
);
1941 mrExport
.AddAttribute( XML_NAMESPACE_XLINK
, XML_TYPE
, "simple" );
1943 SvXMLElementExport
aEventElemt(mrExport
, XML_NAMESPACE_SCRIPT
, XML_EVENT_LISTENER
, true, true);
1948 /** #i68101# export shape Title and Description */
1949 void XMLShapeExport::ImpExportDescription( const uno::Reference
< drawing::XShape
>& xShape
)
1954 OUString aDescription
;
1956 uno::Reference
< beans::XPropertySet
> xProps( xShape
, uno::UNO_QUERY_THROW
);
1957 xProps
->getPropertyValue("Title") >>= aTitle
;
1958 xProps
->getPropertyValue("Description") >>= aDescription
;
1960 if(!aTitle
.isEmpty())
1962 SvXMLElementExport
aEventElemt(mrExport
, XML_NAMESPACE_SVG
, XML_TITLE
, true, false);
1963 mrExport
.Characters( aTitle
);
1966 if(!aDescription
.isEmpty())
1968 SvXMLElementExport
aEventElemt(mrExport
, XML_NAMESPACE_SVG
, XML_DESC
, true, false );
1969 mrExport
.Characters( aDescription
);
1972 catch( uno::Exception
& )
1974 DBG_UNHANDLED_EXCEPTION( "xmloff", "exporting Title and/or Description for shape" );
1978 void XMLShapeExport::ImpExportGroupShape( const uno::Reference
< drawing::XShape
>& xShape
, XMLShapeExportFlags nFeatures
, awt::Point
* pRefPoint
)
1980 uno::Reference
< drawing::XShapes
> xShapes(xShape
, uno::UNO_QUERY
);
1981 if(!(xShapes
.is() && xShapes
->getCount()))
1984 // write group shape
1985 bool bCreateNewline( (nFeatures
& XMLShapeExportFlags::NO_WS
) == XMLShapeExportFlags::NONE
); // #86116#/#92210#
1986 SvXMLElementExport
aPGR(mrExport
, XML_NAMESPACE_DRAW
, XML_G
, bCreateNewline
, true);
1988 ImpExportDescription( xShape
); // #i68101#
1989 ImpExportEvents( xShape
);
1990 ImpExportGluePoints( xShape
);
1992 // #89764# if export of position is suppressed for group shape,
1993 // positions of contained objects should be written relative to
1994 // the upper left edge of the group.
1995 awt::Point aUpperLeft
;
1997 if(!(nFeatures
& XMLShapeExportFlags::POSITION
))
1999 nFeatures
|= XMLShapeExportFlags::POSITION
;
2000 aUpperLeft
= xShape
->getPosition();
2001 pRefPoint
= &aUpperLeft
;
2005 exportShapes( xShapes
, nFeatures
, pRefPoint
);
2008 void XMLShapeExport::ImpExportTextBoxShape(
2009 const uno::Reference
< drawing::XShape
>& xShape
,
2010 XmlShapeType eShapeType
, XMLShapeExportFlags nFeatures
, awt::Point
* pRefPoint
)
2012 const uno::Reference
< beans::XPropertySet
> xPropSet(xShape
, uno::UNO_QUERY
);
2016 // presentation attribute (if presentation)
2017 bool bIsPresShape(false);
2018 bool bIsEmptyPresObj(false);
2023 case XmlShapeType::PresSubtitleShape
:
2025 aStr
= GetXMLToken(XML_SUBTITLE
);
2026 bIsPresShape
= true;
2029 case XmlShapeType::PresTitleTextShape
:
2031 aStr
= GetXMLToken(XML_TITLE
);
2032 bIsPresShape
= true;
2035 case XmlShapeType::PresOutlinerShape
:
2037 aStr
= GetXMLToken(XML_PRESENTATION_OUTLINE
);
2038 bIsPresShape
= true;
2041 case XmlShapeType::PresNotesShape
:
2043 aStr
= GetXMLToken(XML_NOTES
);
2044 bIsPresShape
= true;
2047 case XmlShapeType::PresHeaderShape
:
2049 aStr
= GetXMLToken(XML_HEADER
);
2050 bIsPresShape
= true;
2053 case XmlShapeType::PresFooterShape
:
2055 aStr
= GetXMLToken(XML_FOOTER
);
2056 bIsPresShape
= true;
2059 case XmlShapeType::PresSlideNumberShape
:
2061 aStr
= GetXMLToken(XML_PAGE_NUMBER
);
2062 bIsPresShape
= true;
2065 case XmlShapeType::PresDateTimeShape
:
2067 aStr
= GetXMLToken(XML_DATE_TIME
);
2068 bIsPresShape
= true;
2076 ImpExportNewTrans(xPropSet
, nFeatures
, pRefPoint
);
2079 bIsEmptyPresObj
= ImpExportPresentationAttributes( xPropSet
, aStr
);
2081 bool bCreateNewline( (nFeatures
& XMLShapeExportFlags::NO_WS
) == XMLShapeExportFlags::NONE
); // #86116#/#92210#
2082 SvXMLElementExport
aElem( mrExport
, XML_NAMESPACE_DRAW
,
2083 XML_FRAME
, bCreateNewline
, true );
2085 // evtl. corner radius?
2086 sal_Int32
nCornerRadius(0);
2087 xPropSet
->getPropertyValue("CornerRadius") >>= nCornerRadius
;
2090 OUStringBuffer sStringBuffer
;
2091 mrExport
.GetMM100UnitConverter().convertMeasureToXML(sStringBuffer
,
2093 mrExport
.AddAttribute(XML_NAMESPACE_DRAW
, XML_CORNER_RADIUS
, sStringBuffer
.makeStringAndClear());
2098 SvXMLElementExport
aOBJ(mrExport
, XML_NAMESPACE_DRAW
, XML_TEXT_BOX
, true, true);
2099 if(!bIsEmptyPresObj
)
2100 ImpExportText( xShape
);
2103 ImpExportDescription( xShape
); // #i68101#
2104 ImpExportEvents( xShape
);
2105 ImpExportGluePoints( xShape
);
2109 void XMLShapeExport::ImpExportRectangleShape(
2110 const uno::Reference
< drawing::XShape
>& xShape
,
2111 XMLShapeExportFlags nFeatures
, css::awt::Point
* pRefPoint
)
2113 const uno::Reference
< beans::XPropertySet
> xPropSet(xShape
, uno::UNO_QUERY
);
2118 ImpExportNewTrans(xPropSet
, nFeatures
, pRefPoint
);
2120 // evtl. corner radius?
2121 sal_Int32
nCornerRadius(0);
2122 xPropSet
->getPropertyValue("CornerRadius") >>= nCornerRadius
;
2125 OUStringBuffer sStringBuffer
;
2126 mrExport
.GetMM100UnitConverter().convertMeasureToXML(sStringBuffer
,
2128 mrExport
.AddAttribute(XML_NAMESPACE_DRAW
, XML_CORNER_RADIUS
, sStringBuffer
.makeStringAndClear());
2132 bool bCreateNewline( (nFeatures
& XMLShapeExportFlags::NO_WS
) == XMLShapeExportFlags::NONE
); // #86116#/#92210#
2133 SvXMLElementExport
aOBJ(mrExport
, XML_NAMESPACE_DRAW
, XML_RECT
, bCreateNewline
, true);
2135 ImpExportDescription( xShape
); // #i68101#
2136 ImpExportEvents( xShape
);
2137 ImpExportGluePoints( xShape
);
2138 ImpExportText( xShape
);
2141 void XMLShapeExport::ImpExportLineShape(
2142 const uno::Reference
< drawing::XShape
>& xShape
,
2143 XMLShapeExportFlags nFeatures
, awt::Point
* pRefPoint
)
2145 const uno::Reference
< beans::XPropertySet
> xPropSet(xShape
, uno::UNO_QUERY
);
2150 OUStringBuffer sStringBuffer
;
2151 awt::Point
aStart(0,0);
2152 awt::Point
aEnd(1,1);
2154 // #85920# use 'Geometry' to get the points of the line
2155 // since this slot take anchor pos into account.
2158 ::basegfx::B2DHomMatrix aMatrix
;
2159 ImpExportNewTrans_GetB2DHomMatrix(aMatrix
, xPropSet
);
2161 // decompose and correct about pRefPoint
2162 ::basegfx::B2DTuple aTRScale
;
2163 double fTRShear(0.0);
2164 double fTRRotate(0.0);
2165 ::basegfx::B2DTuple aTRTranslate
;
2166 ImpExportNewTrans_DecomposeAndRefPoint(aMatrix
, aTRScale
, fTRShear
, fTRRotate
, aTRTranslate
, pRefPoint
);
2168 // create base position
2169 awt::Point
aBasePosition(FRound(aTRTranslate
.getX()), FRound(aTRTranslate
.getY()));
2171 if (xPropSet
->getPropertySetInfo()->hasPropertyByName("Geometry"))
2173 // get the two points
2174 uno::Any
aAny(xPropSet
->getPropertyValue("Geometry"));
2175 if (auto pSourcePolyPolygon
2176 = o3tl::tryAccess
<drawing::PointSequenceSequence
>(aAny
))
2178 if (pSourcePolyPolygon
->getLength() > 0)
2180 const drawing::PointSequence
& rInnerSequence
= (*pSourcePolyPolygon
)[0];
2181 if (rInnerSequence
.hasElements())
2183 const awt::Point
& rPoint
= rInnerSequence
[0];
2184 aStart
= awt::Point(rPoint
.X
+ aBasePosition
.X
, rPoint
.Y
+ aBasePosition
.Y
);
2186 if (rInnerSequence
.getLength() > 1)
2188 const awt::Point
& rPoint
= rInnerSequence
[1];
2189 aEnd
= awt::Point(rPoint
.X
+ aBasePosition
.X
, rPoint
.Y
+ aBasePosition
.Y
);
2195 if( nFeatures
& XMLShapeExportFlags::X
)
2198 mrExport
.GetMM100UnitConverter().convertMeasureToXML(sStringBuffer
,
2200 aStr
= sStringBuffer
.makeStringAndClear();
2201 mrExport
.AddAttribute(XML_NAMESPACE_SVG
, XML_X1
, aStr
);
2208 if( nFeatures
& XMLShapeExportFlags::Y
)
2211 mrExport
.GetMM100UnitConverter().convertMeasureToXML(sStringBuffer
,
2213 aStr
= sStringBuffer
.makeStringAndClear();
2214 mrExport
.AddAttribute(XML_NAMESPACE_SVG
, XML_Y1
, aStr
);
2222 mrExport
.GetMM100UnitConverter().convertMeasureToXML(sStringBuffer
,
2224 aStr
= sStringBuffer
.makeStringAndClear();
2225 mrExport
.AddAttribute(XML_NAMESPACE_SVG
, XML_X2
, aStr
);
2228 mrExport
.GetMM100UnitConverter().convertMeasureToXML(sStringBuffer
,
2230 aStr
= sStringBuffer
.makeStringAndClear();
2231 mrExport
.AddAttribute(XML_NAMESPACE_SVG
, XML_Y2
, aStr
);
2234 bool bCreateNewline( (nFeatures
& XMLShapeExportFlags::NO_WS
) == XMLShapeExportFlags::NONE
); // #86116#/#92210#
2235 SvXMLElementExport
aOBJ(mrExport
, XML_NAMESPACE_DRAW
, XML_LINE
, bCreateNewline
, true);
2237 ImpExportDescription( xShape
); // #i68101#
2238 ImpExportEvents( xShape
);
2239 ImpExportGluePoints( xShape
);
2240 ImpExportText( xShape
);
2244 void XMLShapeExport::ImpExportEllipseShape(
2245 const uno::Reference
< drawing::XShape
>& xShape
,
2246 XMLShapeExportFlags nFeatures
, awt::Point
* pRefPoint
)
2248 const uno::Reference
< beans::XPropertySet
> xPropSet(xShape
, uno::UNO_QUERY
);
2252 // get size to decide between Circle and Ellipse
2253 awt::Size aSize
= xShape
->getSize();
2254 sal_Int32
nRx((aSize
.Width
+ 1) / 2);
2255 sal_Int32
nRy((aSize
.Height
+ 1) / 2);
2256 bool bCircle(nRx
== nRy
);
2259 ImpExportNewTrans(xPropSet
, nFeatures
, pRefPoint
);
2261 drawing::CircleKind eKind
= drawing::CircleKind_FULL
;
2262 xPropSet
->getPropertyValue("CircleKind") >>= eKind
;
2263 if( eKind
!= drawing::CircleKind_FULL
)
2265 OUStringBuffer sStringBuffer
;
2266 sal_Int32 nStartAngle
= 0;
2267 sal_Int32 nEndAngle
= 0;
2268 xPropSet
->getPropertyValue("CircleStartAngle") >>= nStartAngle
;
2269 xPropSet
->getPropertyValue("CircleEndAngle") >>= nEndAngle
;
2271 const double dStartAngle
= nStartAngle
/ 100.0;
2272 const double dEndAngle
= nEndAngle
/ 100.0;
2274 // export circle kind
2275 SvXMLUnitConverter::convertEnum( sStringBuffer
, eKind
, aXML_CircleKind_EnumMap
);
2276 mrExport
.AddAttribute(XML_NAMESPACE_DRAW
, XML_KIND
, sStringBuffer
.makeStringAndClear() );
2278 // export start angle
2279 ::sax::Converter::convertDouble( sStringBuffer
, dStartAngle
);
2280 mrExport
.AddAttribute(XML_NAMESPACE_DRAW
, XML_START_ANGLE
, sStringBuffer
.makeStringAndClear() );
2283 ::sax::Converter::convertDouble( sStringBuffer
, dEndAngle
);
2284 mrExport
.AddAttribute(XML_NAMESPACE_DRAW
, XML_END_ANGLE
, sStringBuffer
.makeStringAndClear() );
2287 bool bCreateNewline( (nFeatures
& XMLShapeExportFlags::NO_WS
) == XMLShapeExportFlags::NONE
); // #86116#/#92210#
2289 // write ellipse or circle
2290 SvXMLElementExport
aOBJ(mrExport
, XML_NAMESPACE_DRAW
,
2291 bCircle
? XML_CIRCLE
: XML_ELLIPSE
,
2292 bCreateNewline
, true);
2294 ImpExportDescription( xShape
); // #i68101#
2295 ImpExportEvents( xShape
);
2296 ImpExportGluePoints( xShape
);
2297 ImpExportText( xShape
);
2301 void XMLShapeExport::ImpExportPolygonShape(
2302 const uno::Reference
< drawing::XShape
>& xShape
,
2303 XmlShapeType eShapeType
, XMLShapeExportFlags nFeatures
, awt::Point
* pRefPoint
)
2305 const uno::Reference
< beans::XPropertySet
> xPropSet(xShape
, uno::UNO_QUERY
);
2309 bool bBezier(eShapeType
== XmlShapeType::DrawClosedBezierShape
2310 || eShapeType
== XmlShapeType::DrawOpenBezierShape
);
2313 ::basegfx::B2DHomMatrix aMatrix
;
2314 ImpExportNewTrans_GetB2DHomMatrix(aMatrix
, xPropSet
);
2316 // decompose and correct about pRefPoint
2317 ::basegfx::B2DTuple aTRScale
;
2318 double fTRShear(0.0);
2319 double fTRRotate(0.0);
2320 ::basegfx::B2DTuple aTRTranslate
;
2321 ImpExportNewTrans_DecomposeAndRefPoint(aMatrix
, aTRScale
, fTRShear
, fTRRotate
, aTRTranslate
, pRefPoint
);
2323 // use features and write
2324 ImpExportNewTrans_FeaturesAndWrite(aTRScale
, fTRShear
, fTRRotate
, aTRTranslate
, nFeatures
);
2326 // create and export ViewBox
2327 awt::Size
aSize(FRound(aTRScale
.getX()), FRound(aTRScale
.getY()));
2328 SdXMLImExViewBox
aViewBox(0, 0, aSize
.Width
, aSize
.Height
);
2329 mrExport
.AddAttribute(XML_NAMESPACE_SVG
, XML_VIEWBOX
, aViewBox
.GetExportString());
2331 bool bCreateNewline( (nFeatures
& XMLShapeExportFlags::NO_WS
) == XMLShapeExportFlags::NONE
); // #86116#/#92210#
2333 // prepare name (with most used)
2334 enum ::xmloff::token::XMLTokenEnum
eName(XML_PATH
);
2336 uno::Any
aAny( xPropSet
->getPropertyValue("Geometry") );
2337 basegfx::B2DPolyPolygon aPolyPolygon
;
2339 // tdf#145240 the Any can contain PolyPolygonBezierCoords or PointSequenceSequence
2340 // (see OWN_ATTR_BASE_GEOMETRY in SvxShapePolyPolygon::getPropertyValueImpl),
2341 // so be more flexible in interpreting it. Try to access bezier first:
2343 auto pSourcePolyPolygon
= o3tl::tryAccess
<drawing::PolyPolygonBezierCoords
>(aAny
);
2345 if(pSourcePolyPolygon
&& pSourcePolyPolygon
->Coordinates
.getLength())
2347 aPolyPolygon
= basegfx::utils::UnoPolyPolygonBezierCoordsToB2DPolyPolygon(*pSourcePolyPolygon
);
2351 // if received no data, try to access point sequence second:
2352 if(0 == aPolyPolygon
.count())
2354 auto pSourcePolyPolygon
= o3tl::tryAccess
<drawing::PointSequenceSequence
>(aAny
);
2356 if(pSourcePolyPolygon
)
2358 aPolyPolygon
= basegfx::utils::UnoPointSequenceSequenceToB2DPolyPolygon(*pSourcePolyPolygon
);
2362 if(aPolyPolygon
.count())
2364 if(!bBezier
&& !aPolyPolygon
.areControlPointsUsed() && 1 == aPolyPolygon
.count())
2366 // simple polygon shape, can be written as svg:points sequence
2367 const basegfx::B2DPolygon
& aPolygon(aPolyPolygon
.getB2DPolygon(0));
2368 const OUString
aPointString(basegfx::utils::exportToSvgPoints(aPolygon
));
2370 // write point array
2371 mrExport
.AddAttribute(XML_NAMESPACE_DRAW
, XML_POINTS
, aPointString
);
2374 eName
= aPolygon
.isClosed() ? XML_POLYGON
: XML_POLYLINE
;
2378 // complex polygon shape, write as svg:d
2379 const OUString
aPolygonString(
2380 basegfx::utils::exportToSvgD(
2382 true, // bUseRelativeCoordinates
2383 false, // bDetectQuadraticBeziers: not used in old, but maybe activated now
2384 true)); // bHandleRelativeNextPointCompatible
2386 // write point array
2387 mrExport
.AddAttribute(XML_NAMESPACE_SVG
, XML_D
, aPolygonString
);
2391 // write object, but after attributes are added since this call will
2392 // consume all of these added attributes and the destructor will close the
2393 // scope. Also before text is added; this may add sub-scopes as needed
2394 SvXMLElementExport
aOBJ(
2401 ImpExportDescription( xShape
); // #i68101#
2402 ImpExportEvents( xShape
);
2403 ImpExportGluePoints( xShape
);
2404 ImpExportText( xShape
);
2411 OUString
getNameFromStreamURL(std::u16string_view rURL
)
2413 static constexpr std::u16string_view
sPackageURL(u
"vnd.sun.star.Package:");
2417 if (o3tl::starts_with(rURL
, sPackageURL
))
2419 std::u16string_view sRequestedName
= rURL
.substr(sPackageURL
.size());
2420 size_t nLastIndex
= sRequestedName
.rfind('/') + 1;
2421 if ((nLastIndex
> 0) && (nLastIndex
< sRequestedName
.size()))
2422 sRequestedName
= sRequestedName
.substr(nLastIndex
);
2423 nLastIndex
= sRequestedName
.rfind('.');
2424 if (nLastIndex
!= std::u16string_view::npos
)
2425 sRequestedName
= sRequestedName
.substr(0, nLastIndex
);
2426 if (!sRequestedName
.empty())
2427 sResult
= sRequestedName
;
2433 } // end anonymous namespace
2435 void XMLShapeExport::ImpExportGraphicObjectShape(
2436 const uno::Reference
< drawing::XShape
>& xShape
,
2437 XmlShapeType eShapeType
, XMLShapeExportFlags nFeatures
, awt::Point
* pRefPoint
)
2439 const uno::Reference
< beans::XPropertySet
> xPropSet(xShape
, uno::UNO_QUERY
);
2443 bool bIsEmptyPresObj
= false;
2446 ImpExportNewTrans(xPropSet
, nFeatures
, pRefPoint
);
2448 if(eShapeType
== XmlShapeType::PresGraphicObjectShape
)
2449 bIsEmptyPresObj
= ImpExportPresentationAttributes( xPropSet
, GetXMLToken(XML_GRAPHIC
) );
2451 bool bCreateNewline( (nFeatures
& XMLShapeExportFlags::NO_WS
) == XMLShapeExportFlags::NONE
); // #86116#/#92210#
2452 SvXMLElementExport
aElem( mrExport
, XML_NAMESPACE_DRAW
,
2453 XML_FRAME
, bCreateNewline
, true );
2455 if (!bIsEmptyPresObj
)
2457 uno::Reference
<graphic::XGraphic
> xGraphic
;
2458 OUString sOutMimeType
;
2461 OUString aStreamURL
;
2462 xPropSet
->getPropertyValue("GraphicStreamURL") >>= aStreamURL
;
2463 OUString sRequestedName
= getNameFromStreamURL(aStreamURL
);
2465 xPropSet
->getPropertyValue("Graphic") >>= xGraphic
;
2467 OUString sInternalURL
;
2470 sInternalURL
= mrExport
.AddEmbeddedXGraphic(xGraphic
, sOutMimeType
, sRequestedName
);
2472 if (!sInternalURL
.isEmpty())
2474 // apply possible changed stream URL to embedded image object
2475 if (!sRequestedName
.isEmpty())
2477 OUString newStreamURL
= "vnd.sun.star.Package:";
2478 if (sInternalURL
[0] == '#')
2480 newStreamURL
+= sInternalURL
.subView(1, sInternalURL
.getLength() - 1);
2484 newStreamURL
+= sInternalURL
;
2487 if (newStreamURL
!= aStreamURL
)
2489 xPropSet
->setPropertyValue("GraphicStreamURL", uno::Any(newStreamURL
));
2493 mrExport
.AddAttribute(XML_NAMESPACE_XLINK
, XML_HREF
, sInternalURL
);
2494 mrExport
.AddAttribute(XML_NAMESPACE_XLINK
, XML_TYPE
, XML_SIMPLE
);
2495 mrExport
.AddAttribute(XML_NAMESPACE_XLINK
, XML_SHOW
, XML_EMBED
);
2496 mrExport
.AddAttribute(XML_NAMESPACE_XLINK
, XML_ACTUATE
, XML_ONLOAD
);
2501 if (GetExport().getSaneDefaultVersion() > SvtSaveOptions::ODFSVER_012
)
2503 if (sOutMimeType
.isEmpty())
2505 GetExport().GetGraphicMimeTypeFromStream(xGraphic
, sOutMimeType
);
2507 if (!sOutMimeType
.isEmpty())
2508 { // ODF 1.3 OFFICE-3943
2509 GetExport().AddAttribute(
2510 SvtSaveOptions::ODFSVER_013
<= GetExport().getSaneDefaultVersion()
2511 ? XML_NAMESPACE_DRAW
2512 : XML_NAMESPACE_LO_EXT
,
2513 "mime-type", sOutMimeType
);
2517 SvXMLElementExport
aElement(mrExport
, XML_NAMESPACE_DRAW
, XML_IMAGE
, true, true);
2519 // optional office:binary-data
2522 mrExport
.AddEmbeddedXGraphicAsBase64(xGraphic
);
2524 if (!bIsEmptyPresObj
)
2525 ImpExportText(xShape
);
2528 //Resolves: fdo#62461 put preferred image first above, followed by
2530 const bool bAddReplacementImages
= officecfg::Office::Common::Save::Graphic::AddReplacementImages::get();
2531 if( !bIsEmptyPresObj
&& bAddReplacementImages
)
2533 uno::Reference
<graphic::XGraphic
> xReplacementGraphic
;
2534 xPropSet
->getPropertyValue("ReplacementGraphic") >>= xReplacementGraphic
;
2536 // If there is no url, then the graphic is empty
2537 if (xReplacementGraphic
.is())
2540 const OUString aHref
= mrExport
.AddEmbeddedXGraphic(xReplacementGraphic
, aMimeType
);
2542 if (aMimeType
.isEmpty())
2543 mrExport
.GetGraphicMimeTypeFromStream(xReplacementGraphic
, aMimeType
);
2545 if (!aHref
.isEmpty())
2547 mrExport
.AddAttribute(XML_NAMESPACE_XLINK
, XML_HREF
, aHref
);
2548 mrExport
.AddAttribute(XML_NAMESPACE_XLINK
, XML_TYPE
, XML_SIMPLE
);
2549 mrExport
.AddAttribute(XML_NAMESPACE_XLINK
, XML_SHOW
, XML_EMBED
);
2550 mrExport
.AddAttribute(XML_NAMESPACE_XLINK
, XML_ACTUATE
, XML_ONLOAD
);
2553 if (!aMimeType
.isEmpty() && GetExport().getSaneDefaultVersion() > SvtSaveOptions::ODFSVER_012
)
2554 { // ODF 1.3 OFFICE-3943
2555 mrExport
.AddAttribute(
2556 SvtSaveOptions::ODFSVER_013
<= GetExport().getSaneDefaultVersion()
2557 ? XML_NAMESPACE_DRAW
2558 : XML_NAMESPACE_LO_EXT
,
2559 "mime-type", aMimeType
);
2562 SvXMLElementExport
aElement(mrExport
, XML_NAMESPACE_DRAW
, XML_IMAGE
, true, true);
2564 // optional office:binary-data
2565 mrExport
.AddEmbeddedXGraphicAsBase64(xReplacementGraphic
);
2570 ImpExportEvents( xShape
);
2571 ImpExportGluePoints( xShape
);
2574 GetExport().GetImageMapExport().Export( xPropSet
);
2575 ImpExportDescription( xShape
); // #i68101#
2577 // Signature Line, QR Code - needs to be after the images!
2578 if (GetExport().getSaneDefaultVersion() & SvtSaveOptions::ODFSVER_EXTENDED
)
2580 ImpExportSignatureLine(xShape
);
2581 ImpExportQRCode(xShape
);
2585 void XMLShapeExport::ImpExportChartShape(
2586 const uno::Reference
< drawing::XShape
>& xShape
,
2587 XmlShapeType eShapeType
, XMLShapeExportFlags nFeatures
, awt::Point
* pRefPoint
,
2588 comphelper::AttributeList
* pAttrList
)
2590 ImpExportOLE2Shape( xShape
, eShapeType
, nFeatures
, pRefPoint
, pAttrList
);
2593 void XMLShapeExport::ImpExportControlShape(
2594 const uno::Reference
< drawing::XShape
>& xShape
,
2595 XMLShapeExportFlags nFeatures
, awt::Point
* pRefPoint
)
2597 const uno::Reference
< beans::XPropertySet
> xPropSet(xShape
, uno::UNO_QUERY
);
2601 ImpExportNewTrans(xPropSet
, nFeatures
, pRefPoint
);
2604 uno::Reference
< drawing::XControlShape
> xControl( xShape
, uno::UNO_QUERY
);
2605 SAL_WARN_IF( !xControl
.is(), "xmloff", "Control shape is not supporting XControlShape" );
2608 uno::Reference
< beans::XPropertySet
> xControlModel( xControl
->getControl(), uno::UNO_QUERY
);
2609 SAL_WARN_IF( !xControlModel
.is(), "xmloff", "Control shape has not XControlModel" );
2610 if( xControlModel
.is() )
2612 OUString sControlId
= mrExport
.GetFormExport()->getControlId( xControlModel
);
2613 mrExport
.AddAttribute( XML_NAMESPACE_DRAW
, XML_CONTROL
, sControlId
);
2617 bool bCreateNewline( (nFeatures
& XMLShapeExportFlags::NO_WS
) == XMLShapeExportFlags::NONE
); // #86116#/#92210#
2618 SvXMLElementExport
aOBJ(mrExport
, XML_NAMESPACE_DRAW
, XML_CONTROL
, bCreateNewline
, true);
2620 ImpExportDescription( xShape
); // #i68101#
2623 void XMLShapeExport::ImpExportConnectorShape(
2624 const uno::Reference
< drawing::XShape
>& xShape
,
2625 XMLShapeExportFlags nFeatures
/* = SEF_DEFAULT */, awt::Point
* pRefPoint
/* = NULL */)
2627 uno::Reference
< beans::XPropertySet
> xProps( xShape
, uno::UNO_QUERY
);
2630 OUStringBuffer sStringBuffer
;
2632 // export connection kind
2633 drawing::ConnectorType eType
= drawing::ConnectorType_STANDARD
;
2634 uno::Any aAny
= xProps
->getPropertyValue("EdgeKind");
2637 if( eType
!= drawing::ConnectorType_STANDARD
)
2639 SvXMLUnitConverter::convertEnum( sStringBuffer
, eType
, aXML_ConnectionKind_EnumMap
);
2640 aStr
= sStringBuffer
.makeStringAndClear();
2641 mrExport
.AddAttribute(XML_NAMESPACE_DRAW
, XML_TYPE
, aStr
);
2645 sal_Int32 nDelta1
= 0, nDelta2
= 0, nDelta3
= 0;
2647 aAny
= xProps
->getPropertyValue("EdgeLine1Delta");
2649 aAny
= xProps
->getPropertyValue("EdgeLine2Delta");
2651 aAny
= xProps
->getPropertyValue("EdgeLine3Delta");
2654 if( nDelta1
!= 0 || nDelta2
!= 0 || nDelta3
!= 0 )
2656 mrExport
.GetMM100UnitConverter().convertMeasureToXML(sStringBuffer
,
2658 if( nDelta2
!= 0 || nDelta3
!= 0 )
2660 sStringBuffer
.append( ' ' );
2661 mrExport
.GetMM100UnitConverter().convertMeasureToXML(sStringBuffer
,
2665 sStringBuffer
.append( ' ' );
2666 mrExport
.GetMM100UnitConverter().convertMeasureToXML(
2667 sStringBuffer
, nDelta3
);
2671 aStr
= sStringBuffer
.makeStringAndClear();
2672 mrExport
.AddAttribute(XML_NAMESPACE_DRAW
, XML_LINE_SKEW
, aStr
);
2675 // export start and end point
2676 awt::Point
aStart(0,0);
2677 awt::Point
aEnd(1,1);
2679 /* Get <StartPositionInHoriL2R> and
2680 <EndPositionInHoriL2R>, if they exist and if the document is exported
2681 into the OpenOffice.org file format.
2682 These properties only exist at service css::text::Shape - the
2683 Writer UNO service for shapes.
2684 This code is needed, because the positioning attributes in the
2685 OpenOffice.org file format are given in horizontal left-to-right layout
2686 regardless the layout direction the shape is in. In the OASIS Open Office
2687 file format the positioning attributes are correctly given in the layout
2688 direction the shape is in. Thus, this code provides the conversion from
2689 the OASIS Open Office file format to the OpenOffice.org file format. (#i36248#)
2691 if ( !( GetExport().getExportFlags() & SvXMLExportFlags::OASIS
) &&
2692 xProps
->getPropertySetInfo()->hasPropertyByName("StartPositionInHoriL2R") &&
2693 xProps
->getPropertySetInfo()->hasPropertyByName("EndPositionInHoriL2R") )
2695 xProps
->getPropertyValue("StartPositionInHoriL2R") >>= aStart
;
2696 xProps
->getPropertyValue("EndPositionInHoriL2R") >>= aEnd
;
2700 xProps
->getPropertyValue("StartPosition") >>= aStart
;
2701 xProps
->getPropertyValue("EndPosition") >>= aEnd
;
2706 aStart
.X
-= pRefPoint
->X
;
2707 aStart
.Y
-= pRefPoint
->Y
;
2708 aEnd
.X
-= pRefPoint
->X
;
2709 aEnd
.Y
-= pRefPoint
->Y
;
2712 if( nFeatures
& XMLShapeExportFlags::X
)
2715 mrExport
.GetMM100UnitConverter().convertMeasureToXML(sStringBuffer
,
2717 aStr
= sStringBuffer
.makeStringAndClear();
2718 mrExport
.AddAttribute(XML_NAMESPACE_SVG
, XML_X1
, aStr
);
2725 if( nFeatures
& XMLShapeExportFlags::Y
)
2728 mrExport
.GetMM100UnitConverter().convertMeasureToXML(sStringBuffer
,
2730 aStr
= sStringBuffer
.makeStringAndClear();
2731 mrExport
.AddAttribute(XML_NAMESPACE_SVG
, XML_Y1
, aStr
);
2739 mrExport
.GetMM100UnitConverter().convertMeasureToXML(sStringBuffer
, aEnd
.X
);
2740 aStr
= sStringBuffer
.makeStringAndClear();
2741 mrExport
.AddAttribute(XML_NAMESPACE_SVG
, XML_X2
, aStr
);
2744 mrExport
.GetMM100UnitConverter().convertMeasureToXML(sStringBuffer
, aEnd
.Y
);
2745 aStr
= sStringBuffer
.makeStringAndClear();
2746 mrExport
.AddAttribute(XML_NAMESPACE_SVG
, XML_Y2
, aStr
);
2749 uno::Reference
< uno::XInterface
> xRefS
;
2750 uno::Reference
< uno::XInterface
> xRefE
;
2752 // export start connection
2753 xProps
->getPropertyValue("StartShape") >>= xRefS
;
2756 const OUString
& rShapeId
= mrExport
.getInterfaceToIdentifierMapper().getIdentifier( xRefS
);
2757 mrExport
.AddAttribute(XML_NAMESPACE_DRAW
, XML_START_SHAPE
, rShapeId
);
2759 aAny
= xProps
->getPropertyValue("StartGluePointIndex");
2760 sal_Int32 nGluePointId
= 0;
2761 if( aAny
>>= nGluePointId
)
2763 if( nGluePointId
!= -1 )
2765 mrExport
.AddAttribute(XML_NAMESPACE_DRAW
, XML_START_GLUE_POINT
, OUString::number( nGluePointId
));
2770 // export end connection
2771 xProps
->getPropertyValue("EndShape") >>= xRefE
;
2774 const OUString
& rShapeId
= mrExport
.getInterfaceToIdentifierMapper().getIdentifier( xRefE
);
2775 mrExport
.AddAttribute(XML_NAMESPACE_DRAW
, XML_END_SHAPE
, rShapeId
);
2777 aAny
= xProps
->getPropertyValue("EndGluePointIndex");
2778 sal_Int32 nGluePointId
= 0;
2779 if( aAny
>>= nGluePointId
)
2781 if( nGluePointId
!= -1 )
2783 mrExport
.AddAttribute(XML_NAMESPACE_DRAW
, XML_END_GLUE_POINT
, OUString::number( nGluePointId
));
2788 // get PolygonBezier
2789 aAny
= xProps
->getPropertyValue("PolyPolygonBezier");
2790 auto pSourcePolyPolygon
= o3tl::tryAccess
<drawing::PolyPolygonBezierCoords
>(aAny
);
2791 if(pSourcePolyPolygon
&& pSourcePolyPolygon
->Coordinates
.getLength())
2793 const basegfx::B2DPolyPolygon
aPolyPolygon(
2794 basegfx::utils::UnoPolyPolygonBezierCoordsToB2DPolyPolygon(
2795 *pSourcePolyPolygon
));
2796 const OUString
aPolygonString(
2797 basegfx::utils::exportToSvgD(
2799 true, // bUseRelativeCoordinates
2800 false, // bDetectQuadraticBeziers: not used in old, but maybe activated now
2801 true)); // bHandleRelativeNextPointCompatible
2803 // write point array
2804 mrExport
.AddAttribute(XML_NAMESPACE_SVG
, XML_D
, aPolygonString
);
2808 ::basegfx::B2DHomMatrix aMatrix
;
2809 ImpExportNewTrans_GetB2DHomMatrix(aMatrix
, xProps
);
2811 // decompose and correct about pRefPoint
2812 ::basegfx::B2DTuple aTRScale
;
2813 double fTRShear(0.0);
2814 double fTRRotate(0.0);
2815 ::basegfx::B2DTuple aTRTranslate
;
2816 ImpExportNewTrans_DecomposeAndRefPoint(aMatrix
, aTRScale
, fTRShear
,
2817 fTRRotate
, aTRTranslate
, pRefPoint
);
2819 // fdo#49678: create and export ViewBox
2820 awt::Size
aSize(FRound(aTRScale
.getX()), FRound(aTRScale
.getY()));
2821 SdXMLImExViewBox
aViewBox(0, 0, aSize
.Width
, aSize
.Height
);
2822 mrExport
.AddAttribute(XML_NAMESPACE_SVG
, XML_VIEWBOX
, aViewBox
.GetExportString());
2824 // write connector shape. Add Export later.
2825 bool bCreateNewline( (nFeatures
& XMLShapeExportFlags::NO_WS
) == XMLShapeExportFlags::NONE
); // #86116#/#92210#
2826 SvXMLElementExport
aOBJ(mrExport
, XML_NAMESPACE_DRAW
, XML_CONNECTOR
, bCreateNewline
, true);
2828 ImpExportDescription( xShape
); // #i68101#
2829 ImpExportEvents( xShape
);
2830 ImpExportGluePoints( xShape
);
2831 ImpExportText( xShape
);
2834 void XMLShapeExport::ImpExportMeasureShape(
2835 const uno::Reference
< drawing::XShape
>& xShape
,
2836 XMLShapeExportFlags nFeatures
/* = SEF_DEFAULT */, awt::Point
const * pRefPoint
/* = NULL */)
2838 uno::Reference
< beans::XPropertySet
> xProps( xShape
, uno::UNO_QUERY
);
2841 OUStringBuffer sStringBuffer
;
2843 // export start and end point
2844 awt::Point
aStart(0,0);
2845 awt::Point
aEnd(1,1);
2847 /* Get <StartPositionInHoriL2R> and
2848 <EndPositionInHoriL2R>, if they exist and if the document is exported
2849 into the OpenOffice.org file format.
2850 These properties only exist at service css::text::Shape - the
2851 Writer UNO service for shapes.
2852 This code is needed, because the positioning attributes in the
2853 OpenOffice.org file format are given in horizontal left-to-right layout
2854 regardless the layout direction the shape is in. In the OASIS Open Office
2855 file format the positioning attributes are correctly given in the layout
2856 direction the shape is in. Thus, this code provides the conversion from
2857 the OASIS Open Office file format to the OpenOffice.org file format. (#i36248#)
2859 if ( !( GetExport().getExportFlags() & SvXMLExportFlags::OASIS
) &&
2860 xProps
->getPropertySetInfo()->hasPropertyByName("StartPositionInHoriL2R") &&
2861 xProps
->getPropertySetInfo()->hasPropertyByName("EndPositionInHoriL2R") )
2863 xProps
->getPropertyValue("StartPositionInHoriL2R") >>= aStart
;
2864 xProps
->getPropertyValue("EndPositionInHoriL2R") >>= aEnd
;
2868 xProps
->getPropertyValue("StartPosition") >>= aStart
;
2869 xProps
->getPropertyValue("EndPosition") >>= aEnd
;
2874 aStart
.X
-= pRefPoint
->X
;
2875 aStart
.Y
-= pRefPoint
->Y
;
2876 aEnd
.X
-= pRefPoint
->X
;
2877 aEnd
.Y
-= pRefPoint
->Y
;
2880 if( nFeatures
& XMLShapeExportFlags::X
)
2883 mrExport
.GetMM100UnitConverter().convertMeasureToXML(sStringBuffer
,
2885 aStr
= sStringBuffer
.makeStringAndClear();
2886 mrExport
.AddAttribute(XML_NAMESPACE_SVG
, XML_X1
, aStr
);
2893 if( nFeatures
& XMLShapeExportFlags::Y
)
2896 mrExport
.GetMM100UnitConverter().convertMeasureToXML(sStringBuffer
,
2898 aStr
= sStringBuffer
.makeStringAndClear();
2899 mrExport
.AddAttribute(XML_NAMESPACE_SVG
, XML_Y1
, aStr
);
2907 mrExport
.GetMM100UnitConverter().convertMeasureToXML(sStringBuffer
, aEnd
.X
);
2908 aStr
= sStringBuffer
.makeStringAndClear();
2909 mrExport
.AddAttribute(XML_NAMESPACE_SVG
, XML_X2
, aStr
);
2912 mrExport
.GetMM100UnitConverter().convertMeasureToXML(sStringBuffer
, aEnd
.Y
);
2913 aStr
= sStringBuffer
.makeStringAndClear();
2914 mrExport
.AddAttribute(XML_NAMESPACE_SVG
, XML_Y2
, aStr
);
2916 // write measure shape
2917 bool bCreateNewline( (nFeatures
& XMLShapeExportFlags::NO_WS
) == XMLShapeExportFlags::NONE
); // #86116#/#92210#
2918 SvXMLElementExport
aOBJ(mrExport
, XML_NAMESPACE_DRAW
, XML_MEASURE
, bCreateNewline
, true);
2920 ImpExportDescription( xShape
); // #i68101#
2921 ImpExportEvents( xShape
);
2922 ImpExportGluePoints( xShape
);
2924 uno::Reference
< text::XText
> xText( xShape
, uno::UNO_QUERY
);
2926 mrExport
.GetTextParagraphExport()->exportText( xText
);
2929 void XMLShapeExport::ImpExportOLE2Shape(
2930 const uno::Reference
< drawing::XShape
>& xShape
,
2931 XmlShapeType eShapeType
, XMLShapeExportFlags nFeatures
/* = SEF_DEFAULT */, awt::Point
* pRefPoint
/* = NULL */,
2932 comphelper::AttributeList
* pAttrList
/* = NULL */ )
2934 uno::Reference
< beans::XPropertySet
> xPropSet(xShape
, uno::UNO_QUERY
);
2935 uno::Reference
< container::XNamed
> xNamed(xShape
, uno::UNO_QUERY
);
2937 SAL_WARN_IF( !xPropSet
.is() || !xNamed
.is(), "xmloff", "ole shape is not implementing needed interfaces");
2938 if(!(xPropSet
.is() && xNamed
.is()))
2942 ImpExportNewTrans(xPropSet
, nFeatures
, pRefPoint
);
2944 bool bIsEmptyPresObj
= false;
2946 // presentation settings
2947 if(eShapeType
== XmlShapeType::PresOLE2Shape
)
2948 bIsEmptyPresObj
= ImpExportPresentationAttributes( xPropSet
, GetXMLToken(XML_OBJECT
) );
2949 else if(eShapeType
== XmlShapeType::PresChartShape
)
2950 bIsEmptyPresObj
= ImpExportPresentationAttributes( xPropSet
, GetXMLToken(XML_CHART
) );
2951 else if(eShapeType
== XmlShapeType::PresSheetShape
)
2952 bIsEmptyPresObj
= ImpExportPresentationAttributes( xPropSet
, GetXMLToken(XML_TABLE
) );
2954 bool bCreateNewline( (nFeatures
& XMLShapeExportFlags::NO_WS
) == XMLShapeExportFlags::NONE
); // #86116#/#92210#
2955 bool bExportEmbedded(mrExport
.getExportFlags() & SvXMLExportFlags::EMBEDDED
);
2956 OUString sPersistName
;
2957 SvXMLElementExport
aElement( mrExport
, XML_NAMESPACE_DRAW
,
2958 XML_FRAME
, bCreateNewline
, true );
2960 if (!bIsEmptyPresObj
)
2964 mrExport
.AddAttributeList(pAttrList
);
2969 bool bInternal
= false;
2970 xPropSet
->getPropertyValue("IsInternal") >>= bInternal
;
2976 // OOo internal links have no storage persistence, URL is stored in the XML file
2977 // the result LinkURL is empty in case the object is not a link
2978 xPropSet
->getPropertyValue("LinkURL") >>= sURL
;
2981 xPropSet
->getPropertyValue("PersistName") >>= sPersistName
;
2982 if ( sURL
.isEmpty() )
2984 if( !sPersistName
.isEmpty() )
2986 sURL
= "vnd.sun.star.EmbeddedObject:" + sPersistName
;
2991 xPropSet
->getPropertyValue("CLSID") >>= sClassId
;
2993 if( !sClassId
.isEmpty() )
2994 mrExport
.AddAttribute(XML_NAMESPACE_DRAW
, XML_CLASS_ID
, sClassId
);
2996 if(!bExportEmbedded
)
2999 if( !sURL
.isEmpty() )
3001 // #96717# in theorie, if we don't have a URL we shouldn't even
3002 // export this OLE shape. But practically it's too risky right now
3003 // to change this so we better dispose this on load
3004 sURL
= mrExport
.AddEmbeddedObject( sURL
);
3006 mrExport
.AddAttribute(XML_NAMESPACE_XLINK
, XML_HREF
, sURL
);
3007 mrExport
.AddAttribute( XML_NAMESPACE_XLINK
, XML_TYPE
, XML_SIMPLE
);
3008 mrExport
.AddAttribute( XML_NAMESPACE_XLINK
, XML_SHOW
, XML_EMBED
);
3009 mrExport
.AddAttribute( XML_NAMESPACE_XLINK
, XML_ACTUATE
, XML_ONLOAD
);
3013 // tdf#153179 Export the preview graphic of the object if the object is missing.
3014 uno::Reference
<graphic::XGraphic
> xGraphic
;
3015 xPropSet
->getPropertyValue("Graphic") >>= xGraphic
;
3020 const OUString aHref
= mrExport
.AddEmbeddedXGraphic(xGraphic
, aMimeType
);
3022 if (aMimeType
.isEmpty())
3023 mrExport
.GetGraphicMimeTypeFromStream(xGraphic
, aMimeType
);
3025 if (!aHref
.isEmpty())
3027 mrExport
.AddAttribute(XML_NAMESPACE_XLINK
, XML_HREF
, aHref
);
3028 mrExport
.AddAttribute(XML_NAMESPACE_XLINK
, XML_TYPE
, XML_SIMPLE
);
3029 mrExport
.AddAttribute(XML_NAMESPACE_XLINK
, XML_SHOW
, XML_EMBED
);
3030 mrExport
.AddAttribute(XML_NAMESPACE_XLINK
, XML_ACTUATE
, XML_ONLOAD
);
3033 if (!aMimeType
.isEmpty()
3034 && GetExport().getSaneDefaultVersion() > SvtSaveOptions::ODFSVER_012
)
3035 { // ODF 1.3 OFFICE-3943
3036 mrExport
.AddAttribute(SvtSaveOptions::ODFSVER_013
3037 <= GetExport().getSaneDefaultVersion()
3038 ? XML_NAMESPACE_DRAW
3039 : XML_NAMESPACE_LO_EXT
,
3040 "mime-type", aMimeType
);
3043 SvXMLElementExport
aImageElem(mrExport
, XML_NAMESPACE_DRAW
, XML_IMAGE
, true,
3046 // optional office:binary-data
3047 mrExport
.AddEmbeddedXGraphicAsBase64(xGraphic
);
3049 ImpExportEvents(xShape
);
3050 ImpExportGluePoints(xShape
);
3051 ImpExportDescription(xShape
);
3059 enum XMLTokenEnum eElem
= sClassId
.isEmpty() ? XML_OBJECT
: XML_OBJECT_OLE
;
3060 SvXMLElementExport
aElem( mrExport
, XML_NAMESPACE_DRAW
, eElem
, true, true );
3062 // tdf#112547 export text as child of draw:object, where import expects it
3063 if (!bIsEmptyPresObj
&& supportsText(eShapeType
))
3065 // #i118485# Add text export, the draw OLE shape allows text now
3066 ImpExportText( xShape
, TextPNS::EXTENSION
);
3069 if(bExportEmbedded
&& !bIsEmptyPresObj
)
3074 uno::Reference
< lang::XComponent
> xComp
;
3075 xPropSet
->getPropertyValue("Model") >>= xComp
;
3076 SAL_WARN_IF( !xComp
.is(), "xmloff", "no xModel for own OLE format" );
3077 mrExport
.ExportEmbeddedOwnObject( xComp
);
3082 // this is an alien object ( currently MSOLE is the only supported type of such objects )
3083 // in case it is not an OASIS format the object should be asked to store replacement image if possible
3085 OUString
sURLRequest( sURL
);
3086 if ( !( mrExport
.getExportFlags() & SvXMLExportFlags::OASIS
) )
3087 sURLRequest
+= "?oasis=false";
3088 mrExport
.AddEmbeddedObjectAsBase64( sURLRequest
);
3092 if( !bIsEmptyPresObj
)
3094 OUString sURL
= XML_EMBEDDEDOBJECTGRAPHIC_URL_BASE
+ sPersistName
;
3095 if( !bExportEmbedded
)
3097 sURL
= GetExport().AddEmbeddedObject( sURL
);
3098 mrExport
.AddAttribute(XML_NAMESPACE_XLINK
, XML_HREF
, sURL
);
3099 mrExport
.AddAttribute( XML_NAMESPACE_XLINK
, XML_TYPE
, XML_SIMPLE
);
3100 mrExport
.AddAttribute( XML_NAMESPACE_XLINK
, XML_SHOW
, XML_EMBED
);
3101 mrExport
.AddAttribute( XML_NAMESPACE_XLINK
, XML_ACTUATE
, XML_ONLOAD
);
3104 SvXMLElementExport
aElem( GetExport(), XML_NAMESPACE_DRAW
,
3105 XML_IMAGE
, false, true );
3107 if( bExportEmbedded
)
3108 GetExport().AddEmbeddedObjectAsBase64( sURL
);
3111 ImpExportEvents( xShape
);
3112 ImpExportGluePoints( xShape
);
3113 ImpExportDescription( xShape
); // #i68101#
3117 void XMLShapeExport::ImpExportPageShape(
3118 const uno::Reference
< drawing::XShape
>& xShape
,
3119 XmlShapeType eShapeType
, XMLShapeExportFlags nFeatures
/* = SEF_DEFAULT */, awt::Point
* pRefPoint
/* = NULL */)
3121 const uno::Reference
< beans::XPropertySet
> xPropSet(xShape
, uno::UNO_QUERY
);
3125 // #86163# Transformation
3126 ImpExportNewTrans(xPropSet
, nFeatures
, pRefPoint
);
3128 // export page number used for this page
3129 uno::Reference
< beans::XPropertySetInfo
> xPropSetInfo( xPropSet
->getPropertySetInfo() );
3130 static const OUStringLiteral
aPageNumberStr(u
"PageNumber");
3131 if( xPropSetInfo
.is() && xPropSetInfo
->hasPropertyByName(aPageNumberStr
))
3133 sal_Int32 nPageNumber
= 0;
3134 xPropSet
->getPropertyValue(aPageNumberStr
) >>= nPageNumber
;
3136 mrExport
.AddAttribute(XML_NAMESPACE_DRAW
, XML_PAGE_NUMBER
, OUString::number(nPageNumber
));
3139 // a presentation page shape, normally used on notes pages only. If
3140 // it is used not as presentation shape, it may have been created with
3141 // copy-paste exchange between draw and impress (this IS possible...)
3142 if(eShapeType
== XmlShapeType::PresPageShape
)
3144 mrExport
.AddAttribute(XML_NAMESPACE_PRESENTATION
, XML_CLASS
,
3149 bool bCreateNewline( (nFeatures
& XMLShapeExportFlags::NO_WS
) == XMLShapeExportFlags::NONE
); // #86116#/#92210#
3150 SvXMLElementExport
aOBJ(mrExport
, XML_NAMESPACE_DRAW
, XML_PAGE_THUMBNAIL
, bCreateNewline
, true);
3153 void XMLShapeExport::ImpExportCaptionShape(
3154 const uno::Reference
< drawing::XShape
>& xShape
,
3155 XMLShapeExportFlags nFeatures
/* = SEF_DEFAULT */, awt::Point
* pRefPoint
/* = NULL */)
3157 const uno::Reference
< beans::XPropertySet
> xPropSet(xShape
, uno::UNO_QUERY
);
3162 ImpExportNewTrans(xPropSet
, nFeatures
, pRefPoint
);
3164 // evtl. corner radius?
3165 sal_Int32
nCornerRadius(0);
3166 xPropSet
->getPropertyValue("CornerRadius") >>= nCornerRadius
;
3169 OUStringBuffer sStringBuffer
;
3170 mrExport
.GetMM100UnitConverter().convertMeasureToXML(sStringBuffer
,
3172 mrExport
.AddAttribute(XML_NAMESPACE_DRAW
, XML_CORNER_RADIUS
, sStringBuffer
.makeStringAndClear());
3175 awt::Point aCaptionPoint
;
3176 xPropSet
->getPropertyValue("CaptionPoint") >>= aCaptionPoint
;
3178 mrExport
.GetMM100UnitConverter().convertMeasureToXML(msBuffer
,
3180 mrExport
.AddAttribute( XML_NAMESPACE_DRAW
, XML_CAPTION_POINT_X
, msBuffer
.makeStringAndClear() );
3181 mrExport
.GetMM100UnitConverter().convertMeasureToXML(msBuffer
,
3183 mrExport
.AddAttribute( XML_NAMESPACE_DRAW
, XML_CAPTION_POINT_Y
, msBuffer
.makeStringAndClear() );
3185 // write Caption shape. Add export later.
3186 bool bCreateNewline( (nFeatures
& XMLShapeExportFlags::NO_WS
) == XMLShapeExportFlags::NONE
); // #86116#/#92210#
3187 bool bAnnotation( (nFeatures
& XMLShapeExportFlags::ANNOTATION
) == XMLShapeExportFlags::ANNOTATION
);
3189 SvXMLElementExport
aObj( mrExport
,
3190 (bAnnotation
? XML_NAMESPACE_OFFICE
3191 : XML_NAMESPACE_DRAW
),
3192 (bAnnotation
? XML_ANNOTATION
: XML_CAPTION
),
3193 bCreateNewline
, true );
3195 ImpExportDescription( xShape
); // #i68101#
3196 ImpExportEvents( xShape
);
3197 ImpExportGluePoints( xShape
);
3199 mrExport
.exportAnnotationMeta( xShape
);
3200 ImpExportText( xShape
);
3204 void XMLShapeExport::ImpExportFrameShape(
3205 const uno::Reference
< drawing::XShape
>& xShape
,
3206 XMLShapeExportFlags nFeatures
, css::awt::Point
* pRefPoint
)
3208 const uno::Reference
< beans::XPropertySet
> xPropSet(xShape
, uno::UNO_QUERY
);
3213 ImpExportNewTrans(xPropSet
, nFeatures
, pRefPoint
);
3215 bool bCreateNewline( (nFeatures
& XMLShapeExportFlags::NO_WS
) == XMLShapeExportFlags::NONE
); // #86116#/#92210#
3216 SvXMLElementExport
aElem( mrExport
, XML_NAMESPACE_DRAW
,
3217 XML_FRAME
, bCreateNewline
, true );
3221 xPropSet
->getPropertyValue("FrameURL") >>= aStr
;
3222 mrExport
.AddAttribute ( XML_NAMESPACE_XLINK
, XML_HREF
, GetExport().GetRelativeReference(aStr
) );
3223 mrExport
.AddAttribute ( XML_NAMESPACE_XLINK
, XML_TYPE
, XML_SIMPLE
);
3224 mrExport
.AddAttribute ( XML_NAMESPACE_XLINK
, XML_SHOW
, XML_EMBED
);
3225 mrExport
.AddAttribute ( XML_NAMESPACE_XLINK
, XML_ACTUATE
, XML_ONLOAD
);
3228 xPropSet
->getPropertyValue("FrameName") >>= aStr
;
3229 if( !aStr
.isEmpty() )
3230 mrExport
.AddAttribute( XML_NAMESPACE_DRAW
, XML_FRAME_NAME
, aStr
);
3232 // write floating frame
3234 SvXMLElementExport
aOBJ(mrExport
, XML_NAMESPACE_DRAW
, XML_FLOATING_FRAME
, true, true);
3237 ImpExportDescription(xShape
);
3240 void XMLShapeExport::ImpExportAppletShape(
3241 const uno::Reference
< drawing::XShape
>& xShape
,
3242 XMLShapeExportFlags nFeatures
, css::awt::Point
* pRefPoint
)
3244 const uno::Reference
< beans::XPropertySet
> xPropSet(xShape
, uno::UNO_QUERY
);
3249 ImpExportNewTrans(xPropSet
, nFeatures
, pRefPoint
);
3251 bool bCreateNewline( (nFeatures
& XMLShapeExportFlags::NO_WS
) == XMLShapeExportFlags::NONE
); // #86116#/#92210#
3252 SvXMLElementExport
aElement( mrExport
, XML_NAMESPACE_DRAW
,
3253 XML_FRAME
, bCreateNewline
, true );
3257 xPropSet
->getPropertyValue("AppletCodeBase") >>= aStr
;
3258 mrExport
.AddAttribute ( XML_NAMESPACE_XLINK
, XML_HREF
, GetExport().GetRelativeReference(aStr
) );
3259 mrExport
.AddAttribute ( XML_NAMESPACE_XLINK
, XML_TYPE
, XML_SIMPLE
);
3260 mrExport
.AddAttribute ( XML_NAMESPACE_XLINK
, XML_SHOW
, XML_EMBED
);
3261 mrExport
.AddAttribute ( XML_NAMESPACE_XLINK
, XML_ACTUATE
, XML_ONLOAD
);
3263 // export draw:applet-name
3264 xPropSet
->getPropertyValue("AppletName") >>= aStr
;
3265 if( !aStr
.isEmpty() )
3266 mrExport
.AddAttribute( XML_NAMESPACE_DRAW
, XML_APPLET_NAME
, aStr
);
3269 xPropSet
->getPropertyValue("AppletCode") >>= aStr
;
3270 mrExport
.AddAttribute( XML_NAMESPACE_DRAW
, XML_CODE
, aStr
);
3272 // export draw:may-script
3273 bool bIsScript
= false;
3274 xPropSet
->getPropertyValue("AppletIsScript") >>= bIsScript
;
3275 mrExport
.AddAttribute( XML_NAMESPACE_DRAW
, XML_MAY_SCRIPT
, bIsScript
? XML_TRUE
: XML_FALSE
);
3279 SvXMLElementExport
aOBJ(mrExport
, XML_NAMESPACE_DRAW
, XML_APPLET
, true, true);
3281 // export parameters
3282 uno::Sequence
< beans::PropertyValue
> aCommands
;
3283 xPropSet
->getPropertyValue("AppletCommands") >>= aCommands
;
3284 for( const auto& rCommand
: std::as_const(aCommands
) )
3286 rCommand
.Value
>>= aStr
;
3287 mrExport
.AddAttribute( XML_NAMESPACE_DRAW
, XML_NAME
, rCommand
.Name
);
3288 mrExport
.AddAttribute( XML_NAMESPACE_DRAW
, XML_VALUE
, aStr
);
3289 SvXMLElementExport
aElem( mrExport
, XML_NAMESPACE_DRAW
, XML_PARAM
, false, true );
3293 ImpExportDescription(xShape
);
3296 void XMLShapeExport::ImpExportPluginShape(
3297 const uno::Reference
< drawing::XShape
>& xShape
,
3298 XMLShapeExportFlags nFeatures
, css::awt::Point
* pRefPoint
)
3300 const uno::Reference
< beans::XPropertySet
> xPropSet(xShape
, uno::UNO_QUERY
);
3305 ImpExportNewTrans(xPropSet
, nFeatures
, pRefPoint
);
3307 bool bCreateNewline( (nFeatures
& XMLShapeExportFlags::NO_WS
) == XMLShapeExportFlags::NONE
); // #86116#/#92210#
3308 SvXMLElementExport
aElement( mrExport
, XML_NAMESPACE_DRAW
,
3309 XML_FRAME
, bCreateNewline
, true );
3311 // export plugin url
3313 xPropSet
->getPropertyValue("PluginURL") >>= aStr
;
3314 mrExport
.AddAttribute ( XML_NAMESPACE_XLINK
, XML_HREF
, GetExport().GetRelativeReference(aStr
) );
3315 mrExport
.AddAttribute ( XML_NAMESPACE_XLINK
, XML_TYPE
, XML_SIMPLE
);
3316 mrExport
.AddAttribute ( XML_NAMESPACE_XLINK
, XML_SHOW
, XML_EMBED
);
3317 mrExport
.AddAttribute ( XML_NAMESPACE_XLINK
, XML_ACTUATE
, XML_ONLOAD
);
3320 xPropSet
->getPropertyValue("PluginMimeType") >>= aStr
;
3322 mrExport
.AddAttribute( XML_NAMESPACE_DRAW
, XML_MIME_TYPE
, aStr
);
3326 SvXMLElementExport
aOBJ(mrExport
, XML_NAMESPACE_DRAW
, XML_PLUGIN
, true, true);
3328 // export parameters
3329 uno::Sequence
< beans::PropertyValue
> aCommands
;
3330 xPropSet
->getPropertyValue("PluginCommands") >>= aCommands
;
3331 for( const auto& rCommand
: std::as_const(aCommands
) )
3333 rCommand
.Value
>>= aStr
;
3334 mrExport
.AddAttribute( XML_NAMESPACE_DRAW
, XML_NAME
, rCommand
.Name
);
3335 mrExport
.AddAttribute( XML_NAMESPACE_DRAW
, XML_VALUE
, aStr
);
3336 SvXMLElementExport
aElem( mrExport
, XML_NAMESPACE_DRAW
, XML_PARAM
, false, true );
3340 ImpExportDescription(xShape
);
3343 static void lcl_CopyStream(
3344 uno::Reference
<io::XInputStream
> const& xInStream
,
3345 uno::Reference
<embed::XStorage
> const& xTarget
,
3346 OUString
const& rPath
, const OUString
& rMimeType
)
3348 ::comphelper::LifecycleProxy proxy
;
3349 uno::Reference
<io::XStream
> const xStream(
3350 ::comphelper::OStorageHelper::GetStreamAtPackageURL(xTarget
, rPath
,
3351 embed::ElementModes::WRITE
| embed::ElementModes::TRUNCATE
, proxy
));
3352 uno::Reference
<io::XOutputStream
> const xOutStream(
3353 (xStream
.is()) ? xStream
->getOutputStream() : nullptr);
3354 if (!xOutStream
.is())
3356 SAL_WARN("xmloff", "no output stream");
3357 throw uno::Exception("no output stream",nullptr);
3359 uno::Reference
< beans::XPropertySet
> const xStreamProps(xStream
,
3361 if (xStreamProps
.is()) { // this is NOT supported in FileSystemStorage
3362 xStreamProps
->setPropertyValue("MediaType",
3363 uno::Any(rMimeType
));
3364 xStreamProps
->setPropertyValue( // turn off compression
3368 ::comphelper::OStorageHelper::CopyInputToOutput(xInStream
, xOutStream
);
3369 xOutStream
->closeOutput();
3370 proxy
.commitStorages();
3374 lcl_StoreMediaAndGetURL(SvXMLExport
& rExport
,
3375 uno::Reference
<beans::XPropertySet
> const& xPropSet
,
3376 OUString
const& rURL
, const OUString
& rMimeType
)
3379 if (rURL
.startsWithIgnoreAsciiCase("vnd.sun.star.Package:", &urlPath
))
3381 try // video is embedded
3383 uno::Reference
<embed::XStorage
> const xTarget(
3384 rExport
.GetTargetStorage(), uno::UNO_SET_THROW
);
3385 uno::Reference
<io::XInputStream
> xInStream
;
3386 xPropSet
->getPropertyValue("PrivateStream")
3389 if (!xInStream
.is())
3391 SAL_WARN("xmloff", "no input stream");
3395 lcl_CopyStream(xInStream
, xTarget
, rURL
, rMimeType
);
3399 catch (uno::Exception
const&)
3401 TOOLS_INFO_EXCEPTION("xmloff", "exception while storing embedded media");
3407 return rExport
.GetRelativeReference(rURL
); // linked
3413 void ExportGraphicPreview(const uno::Reference
<graphic::XGraphic
>& xGraphic
, SvXMLExport
& rExport
, const std::u16string_view
& rPrefix
, const std::u16string_view
& rExtension
, const OUString
& rMimeType
)
3415 const bool bExportEmbedded(rExport
.getExportFlags() & SvXMLExportFlags::EMBEDDED
);
3417 if( xGraphic
.is() ) try
3419 uno::Reference
< uno::XComponentContext
> xContext
= rExport
.getComponentContext();
3421 uno::Reference
< embed::XStorage
> xPictureStorage
;
3422 uno::Reference
< embed::XStorage
> xStorage
;
3423 uno::Reference
< io::XStream
> xPictureStream
;
3425 OUString sPictureName
;
3426 if( bExportEmbedded
)
3428 xPictureStream
.set( xContext
->getServiceManager()->createInstanceWithContext( "com.sun.star.comp.MemoryStream", xContext
), uno::UNO_QUERY_THROW
);
3432 xStorage
.set( rExport
.GetTargetStorage(), uno::UNO_SET_THROW
);
3434 xPictureStorage
.set( xStorage
->openStorageElement( "Pictures" , ::embed::ElementModes::READWRITE
), uno::UNO_SET_THROW
);
3436 sal_Int32 nIndex
= 0;
3439 sPictureName
= rPrefix
+ OUString::number( ++nIndex
) + rExtension
;
3441 while( xPictureStorage
->hasByName( sPictureName
) );
3443 xPictureStream
.set( xPictureStorage
->openStreamElement( sPictureName
, ::embed::ElementModes::READWRITE
), uno::UNO_SET_THROW
);
3446 uno::Reference
< graphic::XGraphicProvider
> xProvider( graphic::GraphicProvider::create(xContext
) );
3447 uno::Sequence
< beans::PropertyValue
> aArgs
{
3448 comphelper::makePropertyValue("MimeType", rMimeType
),
3449 comphelper::makePropertyValue("OutputStream", xPictureStream
->getOutputStream())
3451 xProvider
->storeGraphic( xGraphic
, aArgs
);
3453 if( xPictureStorage
.is() )
3455 uno::Reference
< embed::XTransactedObject
> xTrans( xPictureStorage
, uno::UNO_QUERY
);
3460 if( !bExportEmbedded
)
3462 OUString sURL
= "Pictures/" + sPictureName
;
3463 rExport
.AddAttribute( XML_NAMESPACE_XLINK
, XML_HREF
, sURL
);
3464 rExport
.AddAttribute( XML_NAMESPACE_XLINK
, XML_TYPE
, XML_SIMPLE
);
3465 rExport
.AddAttribute( XML_NAMESPACE_XLINK
, XML_SHOW
, XML_EMBED
);
3466 rExport
.AddAttribute( XML_NAMESPACE_XLINK
, XML_ACTUATE
, XML_ONLOAD
);
3469 SvXMLElementExport
aElem( rExport
, XML_NAMESPACE_DRAW
, XML_IMAGE
, false, true );
3471 if( bExportEmbedded
)
3473 uno::Reference
< io::XSeekableInputStream
> xSeekable( xPictureStream
, uno::UNO_QUERY_THROW
);
3476 XMLBase64Export
aBase64Exp( rExport
);
3477 aBase64Exp
.exportOfficeBinaryDataElement( uno::Reference
< io::XInputStream
>( xPictureStream
, uno::UNO_QUERY_THROW
) );
3480 catch( uno::Exception
const & )
3482 DBG_UNHANDLED_EXCEPTION("xmloff.draw");
3487 void XMLShapeExport::ImpExportMediaShape(
3488 const uno::Reference
< drawing::XShape
>& xShape
,
3489 XmlShapeType eShapeType
, XMLShapeExportFlags nFeatures
, css::awt::Point
* pRefPoint
)
3491 const uno::Reference
< beans::XPropertySet
> xPropSet(xShape
, uno::UNO_QUERY
);
3496 ImpExportNewTrans(xPropSet
, nFeatures
, pRefPoint
);
3498 if(eShapeType
== XmlShapeType::PresMediaShape
)
3500 (void)ImpExportPresentationAttributes( xPropSet
, GetXMLToken(XML_OBJECT
) );
3502 bool bCreateNewline( (nFeatures
& XMLShapeExportFlags::NO_WS
) == XMLShapeExportFlags::NONE
); // #86116#/#92210#
3503 SvXMLElementExport
aElem( mrExport
, XML_NAMESPACE_DRAW
,
3504 XML_FRAME
, bCreateNewline
, true );
3508 xPropSet
->getPropertyValue("MediaURL") >>= aMediaURL
;
3510 xPropSet
->getPropertyValue("MediaMimeType") >>= sMimeType
;
3512 OUString
const persistentURL
=
3513 lcl_StoreMediaAndGetURL(GetExport(), xPropSet
, aMediaURL
, sMimeType
);
3515 mrExport
.AddAttribute ( XML_NAMESPACE_XLINK
, XML_HREF
, persistentURL
);
3516 mrExport
.AddAttribute ( XML_NAMESPACE_XLINK
, XML_TYPE
, XML_SIMPLE
);
3517 mrExport
.AddAttribute ( XML_NAMESPACE_XLINK
, XML_SHOW
, XML_EMBED
);
3518 mrExport
.AddAttribute ( XML_NAMESPACE_XLINK
, XML_ACTUATE
, XML_ONLOAD
);
3521 mrExport
.AddAttribute( XML_NAMESPACE_DRAW
, XML_MIME_TYPE
, sMimeType
);
3524 auto pPluginOBJ
= std::make_unique
<SvXMLElementExport
>(mrExport
, XML_NAMESPACE_DRAW
, XML_PLUGIN
, !( nFeatures
& XMLShapeExportFlags::NO_WS
), true);
3526 // export parameters
3527 const OUString
aFalseStr( "false" ), aTrueStr( "true" );
3530 static const OUStringLiteral
aLoopStr( u
"Loop" );
3531 xPropSet
->getPropertyValue( aLoopStr
) >>= bLoop
;
3532 mrExport
.AddAttribute( XML_NAMESPACE_DRAW
, XML_NAME
, aLoopStr
);
3533 mrExport
.AddAttribute( XML_NAMESPACE_DRAW
, XML_VALUE
, bLoop
? aTrueStr
: aFalseStr
);
3534 delete new SvXMLElementExport( mrExport
, XML_NAMESPACE_DRAW
, XML_PARAM
, false, true );
3537 static const OUStringLiteral
aMuteStr( u
"Mute" );
3538 xPropSet
->getPropertyValue( aMuteStr
) >>= bMute
;
3539 mrExport
.AddAttribute( XML_NAMESPACE_DRAW
, XML_NAME
, aMuteStr
);
3540 mrExport
.AddAttribute( XML_NAMESPACE_DRAW
, XML_VALUE
, bMute
? aTrueStr
: aFalseStr
);
3541 delete new SvXMLElementExport( mrExport
, XML_NAMESPACE_DRAW
, XML_PARAM
, false, true );
3543 sal_Int16 nVolumeDB
= 0;
3544 xPropSet
->getPropertyValue("VolumeDB") >>= nVolumeDB
;
3545 mrExport
.AddAttribute( XML_NAMESPACE_DRAW
, XML_NAME
, "VolumeDB" );
3546 mrExport
.AddAttribute( XML_NAMESPACE_DRAW
, XML_VALUE
, OUString::number( nVolumeDB
) );
3547 delete new SvXMLElementExport( mrExport
, XML_NAMESPACE_DRAW
, XML_PARAM
, false, true );
3549 media::ZoomLevel eZoom
;
3550 OUString aZoomValue
;
3551 xPropSet
->getPropertyValue("Zoom") >>= eZoom
;
3554 case media::ZoomLevel_ZOOM_1_TO_4
: aZoomValue
= "25%"; break;
3555 case media::ZoomLevel_ZOOM_1_TO_2
: aZoomValue
= "50%"; break;
3556 case media::ZoomLevel_ORIGINAL
: aZoomValue
= "100%"; break;
3557 case media::ZoomLevel_ZOOM_2_TO_1
: aZoomValue
= "200%"; break;
3558 case media::ZoomLevel_ZOOM_4_TO_1
: aZoomValue
= "400%"; break;
3559 case media::ZoomLevel_FIT_TO_WINDOW
: aZoomValue
= "fit"; break;
3560 case media::ZoomLevel_FIT_TO_WINDOW_FIXED_ASPECT
: aZoomValue
= "fixedfit"; break;
3561 case media::ZoomLevel_FULLSCREEN
: aZoomValue
= "fullscreen"; break;
3567 if( !aZoomValue
.isEmpty() )
3569 mrExport
.AddAttribute( XML_NAMESPACE_DRAW
, XML_NAME
, "Zoom" );
3570 mrExport
.AddAttribute( XML_NAMESPACE_DRAW
, XML_VALUE
, aZoomValue
);
3571 delete new SvXMLElementExport( mrExport
, XML_NAMESPACE_DRAW
, XML_PARAM
, false, true );
3576 uno::Reference
<graphic::XGraphic
> xGraphic
;
3577 xPropSet
->getPropertyValue("Graphic") >>= xGraphic
;
3578 Graphic
aGraphic(xGraphic
);
3579 if (!aGraphic
.IsNone())
3581 // The media has a preview, export it.
3582 ExportGraphicPreview(xGraphic
, mrExport
, u
"MediaPreview", u
".png", "image/png");
3585 ImpExportDescription(xShape
);
3588 void XMLShapeExport::ImpExport3DSceneShape( const uno::Reference
< drawing::XShape
>& xShape
, XMLShapeExportFlags nFeatures
, awt::Point
* pRefPoint
)
3590 uno::Reference
< drawing::XShapes
> xShapes(xShape
, uno::UNO_QUERY
);
3591 if(!(xShapes
.is() && xShapes
->getCount()))
3594 uno::Reference
< beans::XPropertySet
> xPropSet( xShape
, uno::UNO_QUERY
);
3595 SAL_WARN_IF( !xPropSet
.is(), "xmloff", "XMLShapeExport::ImpExport3DSceneShape can't export a scene without a propertyset" );
3596 if( !xPropSet
.is() )
3600 ImpExportNewTrans(xPropSet
, nFeatures
, pRefPoint
);
3603 export3DSceneAttributes( xPropSet
);
3605 // write 3DScene shape
3606 bool bCreateNewline( (nFeatures
& XMLShapeExportFlags::NO_WS
) == XMLShapeExportFlags::NONE
); // #86116#/#92210#
3607 SvXMLElementExport
aOBJ( mrExport
, XML_NAMESPACE_DR3D
, XML_SCENE
, bCreateNewline
, true);
3609 ImpExportDescription( xShape
); // #i68101#
3610 ImpExportEvents( xShape
);
3612 // write 3DSceneLights
3613 export3DLamps( xPropSet
);
3615 // #89764# if export of position is suppressed for group shape,
3616 // positions of contained objects should be written relative to
3617 // the upper left edge of the group.
3618 awt::Point aUpperLeft
;
3620 if(!(nFeatures
& XMLShapeExportFlags::POSITION
))
3622 nFeatures
|= XMLShapeExportFlags::POSITION
;
3623 aUpperLeft
= xShape
->getPosition();
3624 pRefPoint
= &aUpperLeft
;
3628 exportShapes( xShapes
, nFeatures
, pRefPoint
);
3631 void XMLShapeExport::ImpExport3DShape(
3632 const uno::Reference
< drawing::XShape
>& xShape
,
3633 XmlShapeType eShapeType
)
3635 const uno::Reference
< beans::XPropertySet
> xPropSet(xShape
, uno::UNO_QUERY
);
3640 OUStringBuffer sStringBuffer
;
3642 // transformation (UNO_NAME_3D_TRANSFORM_MATRIX == "D3DTransformMatrix")
3643 uno::Any aAny
= xPropSet
->getPropertyValue("D3DTransformMatrix");
3644 drawing::HomogenMatrix aHomMat
;
3646 SdXMLImExTransform3D aTransform
;
3647 aTransform
.AddHomogenMatrix(aHomMat
);
3648 if(aTransform
.NeedsAction())
3649 mrExport
.AddAttribute(XML_NAMESPACE_DR3D
, XML_TRANSFORM
, aTransform
.GetExportString(mrExport
.GetMM100UnitConverter()));
3653 case XmlShapeType::Draw3DCubeObject
:
3656 aAny
= xPropSet
->getPropertyValue("D3DPosition");
3657 drawing::Position3D aPosition3D
;
3658 aAny
>>= aPosition3D
;
3659 ::basegfx::B3DVector
aPos3D(aPosition3D
.PositionX
, aPosition3D
.PositionY
, aPosition3D
.PositionZ
);
3662 aAny
= xPropSet
->getPropertyValue("D3DSize");
3663 drawing::Direction3D aDirection3D
;
3664 aAny
>>= aDirection3D
;
3665 ::basegfx::B3DVector
aDir3D(aDirection3D
.DirectionX
, aDirection3D
.DirectionY
, aDirection3D
.DirectionZ
);
3667 // transform maxEdge from distance to pos
3668 aDir3D
= aPos3D
+ aDir3D
;
3671 if(aPos3D
!= ::basegfx::B3DVector(-2500.0, -2500.0, -2500.0)) // write only when not default
3673 SvXMLUnitConverter::convertB3DVector(sStringBuffer
, aPos3D
);
3674 aStr
= sStringBuffer
.makeStringAndClear();
3675 mrExport
.AddAttribute(XML_NAMESPACE_DR3D
, XML_MIN_EDGE
, aStr
);
3679 if(aDir3D
!= ::basegfx::B3DVector(2500.0, 2500.0, 2500.0)) // write only when not default
3681 SvXMLUnitConverter::convertB3DVector(sStringBuffer
, aDir3D
);
3682 aStr
= sStringBuffer
.makeStringAndClear();
3683 mrExport
.AddAttribute(XML_NAMESPACE_DR3D
, XML_MAX_EDGE
, aStr
);
3686 // write 3DCube shape
3687 // #i123542# Do this *after* the attributes are added, else these will be lost since opening
3688 // the scope will clear the global attribute list at the exporter
3689 SvXMLElementExport
aOBJ(mrExport
, XML_NAMESPACE_DR3D
, XML_CUBE
, true, true);
3693 case XmlShapeType::Draw3DSphereObject
:
3696 aAny
= xPropSet
->getPropertyValue("D3DPosition");
3697 drawing::Position3D aPosition3D
;
3698 aAny
>>= aPosition3D
;
3699 ::basegfx::B3DVector
aPos3D(aPosition3D
.PositionX
, aPosition3D
.PositionY
, aPosition3D
.PositionZ
);
3702 aAny
= xPropSet
->getPropertyValue("D3DSize");
3703 drawing::Direction3D aDirection3D
;
3704 aAny
>>= aDirection3D
;
3705 ::basegfx::B3DVector
aDir3D(aDirection3D
.DirectionX
, aDirection3D
.DirectionY
, aDirection3D
.DirectionZ
);
3708 if(aPos3D
!= ::basegfx::B3DVector(0.0, 0.0, 0.0)) // write only when not default
3710 SvXMLUnitConverter::convertB3DVector(sStringBuffer
, aPos3D
);
3711 aStr
= sStringBuffer
.makeStringAndClear();
3712 mrExport
.AddAttribute(XML_NAMESPACE_DR3D
, XML_CENTER
, aStr
);
3716 if(aDir3D
!= ::basegfx::B3DVector(5000.0, 5000.0, 5000.0)) // write only when not default
3718 SvXMLUnitConverter::convertB3DVector(sStringBuffer
, aDir3D
);
3719 aStr
= sStringBuffer
.makeStringAndClear();
3720 mrExport
.AddAttribute(XML_NAMESPACE_DR3D
, XML_SIZE
, aStr
);
3723 // write 3DSphere shape
3724 // #i123542# Do this *after* the attributes are added, else these will be lost since opening
3725 // the scope will clear the global attribute list at the exporter
3726 SvXMLElementExport
aOBJ(mrExport
, XML_NAMESPACE_DR3D
, XML_SPHERE
, true, true);
3730 case XmlShapeType::Draw3DLatheObject
:
3731 case XmlShapeType::Draw3DExtrudeObject
:
3733 // write special 3DLathe/3DExtrude attributes, get 3D tools::PolyPolygon as drawing::PolyPolygonShape3D
3734 aAny
= xPropSet
->getPropertyValue("D3DPolyPolygon3D");
3735 drawing::PolyPolygonShape3D aUnoPolyPolygon3D
;
3736 aAny
>>= aUnoPolyPolygon3D
;
3738 // convert to 3D PolyPolygon
3739 const basegfx::B3DPolyPolygon
aPolyPolygon3D(
3740 basegfx::utils::UnoPolyPolygonShape3DToB3DPolyPolygon(
3741 aUnoPolyPolygon3D
));
3743 // convert to 2D tools::PolyPolygon using identity 3D transformation (just grep X and Y)
3744 const basegfx::B3DHomMatrix aB3DHomMatrixFor2DConversion
;
3745 const basegfx::B2DPolyPolygon
aPolyPolygon(
3746 basegfx::utils::createB2DPolyPolygonFromB3DPolyPolygon(
3748 aB3DHomMatrixFor2DConversion
));
3750 // get 2D range of it
3751 const basegfx::B2DRange
aPolyPolygonRange(aPolyPolygon
.getB2DRange());
3754 SdXMLImExViewBox
aViewBox(
3755 aPolyPolygonRange
.getMinX(),
3756 aPolyPolygonRange
.getMinY(),
3757 aPolyPolygonRange
.getWidth(),
3758 aPolyPolygonRange
.getHeight());
3760 mrExport
.AddAttribute(XML_NAMESPACE_SVG
, XML_VIEWBOX
, aViewBox
.GetExportString());
3762 // prepare svg:d string
3763 const OUString
aPolygonString(
3764 basegfx::utils::exportToSvgD(
3766 true, // bUseRelativeCoordinates
3767 false, // bDetectQuadraticBeziers TTTT: not used in old, but maybe activated now
3768 true)); // bHandleRelativeNextPointCompatible
3770 // write point array
3771 mrExport
.AddAttribute(XML_NAMESPACE_SVG
, XML_D
, aPolygonString
);
3773 if(eShapeType
== XmlShapeType::Draw3DLatheObject
)
3775 // write 3DLathe shape
3776 SvXMLElementExport
aOBJ(mrExport
, XML_NAMESPACE_DR3D
, XML_ROTATE
, true, true);
3780 // write 3DExtrude shape
3781 SvXMLElementExport
aOBJ(mrExport
, XML_NAMESPACE_DR3D
, XML_EXTRUDE
, true, true);
3790 /** helper for chart that adds all attributes of a 3d scene element to the export */
3791 void XMLShapeExport::export3DSceneAttributes( const css::uno::Reference
< css::beans::XPropertySet
>& xPropSet
)
3794 OUStringBuffer sStringBuffer
;
3796 // world transformation (UNO_NAME_3D_TRANSFORM_MATRIX == "D3DTransformMatrix")
3797 uno::Any aAny
= xPropSet
->getPropertyValue("D3DTransformMatrix");
3798 drawing::HomogenMatrix aHomMat
;
3800 SdXMLImExTransform3D aTransform
;
3801 aTransform
.AddHomogenMatrix(aHomMat
);
3802 if(aTransform
.NeedsAction())
3803 mrExport
.AddAttribute(XML_NAMESPACE_DR3D
, XML_TRANSFORM
, aTransform
.GetExportString(mrExport
.GetMM100UnitConverter()));
3806 aAny
= xPropSet
->getPropertyValue("D3DCameraGeometry");
3807 drawing::CameraGeometry aCamGeo
;
3810 ::basegfx::B3DVector
aVRP(aCamGeo
.vrp
.PositionX
, aCamGeo
.vrp
.PositionY
, aCamGeo
.vrp
.PositionZ
);
3811 if(aVRP
!= ::basegfx::B3DVector(0.0, 0.0, 1.0)) // write only when not default
3813 SvXMLUnitConverter::convertB3DVector(sStringBuffer
, aVRP
);
3814 aStr
= sStringBuffer
.makeStringAndClear();
3815 mrExport
.AddAttribute(XML_NAMESPACE_DR3D
, XML_VRP
, aStr
);
3818 ::basegfx::B3DVector
aVPN(aCamGeo
.vpn
.DirectionX
, aCamGeo
.vpn
.DirectionY
, aCamGeo
.vpn
.DirectionZ
);
3819 if(aVPN
!= ::basegfx::B3DVector(0.0, 0.0, 1.0)) // write only when not default
3821 SvXMLUnitConverter::convertB3DVector(sStringBuffer
, aVPN
);
3822 aStr
= sStringBuffer
.makeStringAndClear();
3823 mrExport
.AddAttribute(XML_NAMESPACE_DR3D
, XML_VPN
, aStr
);
3826 ::basegfx::B3DVector
aVUP(aCamGeo
.vup
.DirectionX
, aCamGeo
.vup
.DirectionY
, aCamGeo
.vup
.DirectionZ
);
3827 if(aVUP
!= ::basegfx::B3DVector(0.0, 1.0, 0.0)) // write only when not default
3829 SvXMLUnitConverter::convertB3DVector(sStringBuffer
, aVUP
);
3830 aStr
= sStringBuffer
.makeStringAndClear();
3831 mrExport
.AddAttribute(XML_NAMESPACE_DR3D
, XML_VUP
, aStr
);
3834 // projection "D3DScenePerspective" drawing::ProjectionMode
3835 aAny
= xPropSet
->getPropertyValue("D3DScenePerspective");
3836 drawing::ProjectionMode aPrjMode
;
3838 if(aPrjMode
== drawing::ProjectionMode_PARALLEL
)
3839 aStr
= GetXMLToken(XML_PARALLEL
);
3841 aStr
= GetXMLToken(XML_PERSPECTIVE
);
3842 mrExport
.AddAttribute(XML_NAMESPACE_DR3D
, XML_PROJECTION
, aStr
);
3845 aAny
= xPropSet
->getPropertyValue("D3DSceneDistance");
3846 sal_Int32 nDistance
= 0;
3848 mrExport
.GetMM100UnitConverter().convertMeasureToXML(sStringBuffer
,
3850 aStr
= sStringBuffer
.makeStringAndClear();
3851 mrExport
.AddAttribute(XML_NAMESPACE_DR3D
, XML_DISTANCE
, aStr
);
3854 aAny
= xPropSet
->getPropertyValue("D3DSceneFocalLength");
3855 sal_Int32 nFocalLength
= 0;
3856 aAny
>>= nFocalLength
;
3857 mrExport
.GetMM100UnitConverter().convertMeasureToXML(sStringBuffer
,
3859 aStr
= sStringBuffer
.makeStringAndClear();
3860 mrExport
.AddAttribute(XML_NAMESPACE_DR3D
, XML_FOCAL_LENGTH
, aStr
);
3863 aAny
= xPropSet
->getPropertyValue("D3DSceneShadowSlant");
3864 sal_Int16 nShadowSlant
= 0;
3865 aAny
>>= nShadowSlant
;
3866 mrExport
.AddAttribute(XML_NAMESPACE_DR3D
, XML_SHADOW_SLANT
, OUString::number(static_cast<sal_Int32
>(nShadowSlant
)));
3869 aAny
= xPropSet
->getPropertyValue("D3DSceneShadeMode");
3870 drawing::ShadeMode aShadeMode
;
3871 if(aAny
>>= aShadeMode
)
3873 if(aShadeMode
== drawing::ShadeMode_FLAT
)
3874 aStr
= GetXMLToken(XML_FLAT
);
3875 else if(aShadeMode
== drawing::ShadeMode_PHONG
)
3876 aStr
= GetXMLToken(XML_PHONG
);
3877 else if(aShadeMode
== drawing::ShadeMode_SMOOTH
)
3878 aStr
= GetXMLToken(XML_GOURAUD
);
3880 aStr
= GetXMLToken(XML_DRAFT
);
3884 // ShadeMode enum not there, write default
3885 aStr
= GetXMLToken(XML_GOURAUD
);
3887 mrExport
.AddAttribute(XML_NAMESPACE_DR3D
, XML_SHADE_MODE
, aStr
);
3890 aAny
= xPropSet
->getPropertyValue("D3DSceneAmbientColor");
3891 sal_Int32 nAmbientColor
= 0;
3892 aAny
>>= nAmbientColor
;
3893 ::sax::Converter::convertColor(sStringBuffer
, nAmbientColor
);
3894 aStr
= sStringBuffer
.makeStringAndClear();
3895 mrExport
.AddAttribute(XML_NAMESPACE_DR3D
, XML_AMBIENT_COLOR
, aStr
);
3898 aAny
= xPropSet
->getPropertyValue("D3DSceneTwoSidedLighting");
3899 bool bTwoSidedLighting
= false;
3900 aAny
>>= bTwoSidedLighting
;
3901 ::sax::Converter::convertBool(sStringBuffer
, bTwoSidedLighting
);
3902 aStr
= sStringBuffer
.makeStringAndClear();
3903 mrExport
.AddAttribute(XML_NAMESPACE_DR3D
, XML_LIGHTING_MODE
, aStr
);
3906 /** helper for chart that exports all lamps from the propertyset */
3907 void XMLShapeExport::export3DLamps( const css::uno::Reference
< css::beans::XPropertySet
>& xPropSet
)
3909 // write lamps 1..8 as content
3911 OUStringBuffer sStringBuffer
;
3913 static const OUStringLiteral
aColorPropName(u
"D3DSceneLightColor");
3914 static const OUStringLiteral
aDirectionPropName(u
"D3DSceneLightDirection");
3915 static const OUStringLiteral
aLightOnPropName(u
"D3DSceneLightOn");
3917 ::basegfx::B3DVector aLightDirection
;
3918 drawing::Direction3D aLightDir
;
3919 bool bLightOnOff
= false;
3920 for(sal_Int32 nLamp
= 1; nLamp
<= 8; nLamp
++)
3922 OUString aIndexStr
= OUString::number( nLamp
);
3925 OUString aPropName
= aColorPropName
+ aIndexStr
;
3926 sal_Int32 nLightColor
= 0;
3927 xPropSet
->getPropertyValue( aPropName
) >>= nLightColor
;
3928 ::sax::Converter::convertColor(sStringBuffer
, nLightColor
);
3929 aStr
= sStringBuffer
.makeStringAndClear();
3930 mrExport
.AddAttribute(XML_NAMESPACE_DR3D
, XML_DIFFUSE_COLOR
, aStr
);
3933 aPropName
= aDirectionPropName
+ aIndexStr
;
3934 xPropSet
->getPropertyValue(aPropName
) >>= aLightDir
;
3935 aLightDirection
= ::basegfx::B3DVector(aLightDir
.DirectionX
, aLightDir
.DirectionY
, aLightDir
.DirectionZ
);
3936 SvXMLUnitConverter::convertB3DVector(sStringBuffer
, aLightDirection
);
3937 aStr
= sStringBuffer
.makeStringAndClear();
3938 mrExport
.AddAttribute(XML_NAMESPACE_DR3D
, XML_DIRECTION
, aStr
);
3941 aPropName
= aLightOnPropName
+ aIndexStr
;
3942 xPropSet
->getPropertyValue(aPropName
) >>= bLightOnOff
;
3943 ::sax::Converter::convertBool(sStringBuffer
, bLightOnOff
);
3944 aStr
= sStringBuffer
.makeStringAndClear();
3945 mrExport
.AddAttribute(XML_NAMESPACE_DR3D
, XML_ENABLED
, aStr
);
3948 mrExport
.AddAttribute(XML_NAMESPACE_DR3D
, XML_SPECULAR
,
3949 nLamp
== 1 ? XML_TRUE
: XML_FALSE
);
3951 // write light entry
3952 SvXMLElementExport
aOBJ(mrExport
, XML_NAMESPACE_DR3D
, XML_LIGHT
, true, true);
3957 // using namespace css::io;
3958 // using namespace ::xmloff::EnhancedCustomShapeToken;
3961 static void ExportParameter( OUStringBuffer
& rStrBuffer
, const css::drawing::EnhancedCustomShapeParameter
& rParameter
)
3963 if ( !rStrBuffer
.isEmpty() )
3964 rStrBuffer
.append( ' ' );
3965 if ( rParameter
.Value
.getValueTypeClass() == uno::TypeClass_DOUBLE
)
3967 double fNumber
= 0.0;
3968 rParameter
.Value
>>= fNumber
;
3969 ::rtl::math::doubleToUStringBuffer( rStrBuffer
, fNumber
, rtl_math_StringFormat_Automatic
, rtl_math_DecimalPlaces_Max
, '.', true );
3973 sal_Int32 nValue
= 0;
3974 rParameter
.Value
>>= nValue
;
3976 switch( rParameter
.Type
)
3978 case css::drawing::EnhancedCustomShapeParameterType::EQUATION
:
3980 rStrBuffer
.append( "?f" + OUString::number( nValue
) );
3984 case css::drawing::EnhancedCustomShapeParameterType::ADJUSTMENT
:
3986 rStrBuffer
.append( '$' );
3987 rStrBuffer
.append( nValue
);
3991 case css::drawing::EnhancedCustomShapeParameterType::BOTTOM
:
3992 rStrBuffer
.append( GetXMLToken( XML_BOTTOM
) ); break;
3993 case css::drawing::EnhancedCustomShapeParameterType::RIGHT
:
3994 rStrBuffer
.append( GetXMLToken( XML_RIGHT
) ); break;
3995 case css::drawing::EnhancedCustomShapeParameterType::TOP
:
3996 rStrBuffer
.append( GetXMLToken( XML_TOP
) ); break;
3997 case css::drawing::EnhancedCustomShapeParameterType::LEFT
:
3998 rStrBuffer
.append( GetXMLToken( XML_LEFT
) ); break;
3999 case css::drawing::EnhancedCustomShapeParameterType::XSTRETCH
:
4000 rStrBuffer
.append( GetXMLToken( XML_XSTRETCH
) ); break;
4001 case css::drawing::EnhancedCustomShapeParameterType::YSTRETCH
:
4002 rStrBuffer
.append( GetXMLToken( XML_YSTRETCH
) ); break;
4003 case css::drawing::EnhancedCustomShapeParameterType::HASSTROKE
:
4004 rStrBuffer
.append( GetXMLToken( XML_HASSTROKE
) ); break;
4005 case css::drawing::EnhancedCustomShapeParameterType::HASFILL
:
4006 rStrBuffer
.append( GetXMLToken( XML_HASFILL
) ); break;
4007 case css::drawing::EnhancedCustomShapeParameterType::WIDTH
:
4008 rStrBuffer
.append( GetXMLToken( XML_WIDTH
) ); break;
4009 case css::drawing::EnhancedCustomShapeParameterType::HEIGHT
:
4010 rStrBuffer
.append( GetXMLToken( XML_HEIGHT
) ); break;
4011 case css::drawing::EnhancedCustomShapeParameterType::LOGWIDTH
:
4012 rStrBuffer
.append( GetXMLToken( XML_LOGWIDTH
) ); break;
4013 case css::drawing::EnhancedCustomShapeParameterType::LOGHEIGHT
:
4014 rStrBuffer
.append( GetXMLToken( XML_LOGHEIGHT
) ); break;
4016 rStrBuffer
.append( nValue
);
4021 static void ImpExportEquations( SvXMLExport
& rExport
, const uno::Sequence
< OUString
>& rEquations
)
4024 for ( i
= 0; i
< rEquations
.getLength(); i
++ )
4026 OUString aStr
= "f" + OUString::number( i
);
4027 rExport
.AddAttribute( XML_NAMESPACE_DRAW
, XML_NAME
, aStr
);
4029 aStr
= rEquations
[ i
];
4030 sal_Int32 nIndex
= 0;
4033 nIndex
= aStr
.indexOf( '?', nIndex
);
4036 aStr
= OUString::Concat(aStr
.subView(0, nIndex
+ 1)) + "f"
4037 + aStr
.subView(nIndex
+ 1, aStr
.getLength() - nIndex
- 1);
4040 } while( nIndex
!= -1 );
4041 rExport
.AddAttribute( XML_NAMESPACE_DRAW
, XML_FORMULA
, aStr
);
4042 SvXMLElementExport
aOBJ( rExport
, XML_NAMESPACE_DRAW
, XML_EQUATION
, true, true );
4046 static void ImpExportHandles( SvXMLExport
& rExport
, const uno::Sequence
< beans::PropertyValues
>& rHandles
)
4048 if ( !rHandles
.hasElements() )
4052 OUStringBuffer aStrBuffer
;
4054 for ( const uno::Sequence
< beans::PropertyValue
>& rPropSeq
: rHandles
)
4056 bool bPosition
= false;
4057 for ( const beans::PropertyValue
& rPropVal
: rPropSeq
)
4059 switch( EASGet( rPropVal
.Name
) )
4063 css::drawing::EnhancedCustomShapeParameterPair aPosition
;
4064 if ( rPropVal
.Value
>>= aPosition
)
4066 ExportParameter( aStrBuffer
, aPosition
.First
);
4067 ExportParameter( aStrBuffer
, aPosition
.Second
);
4068 aStr
= aStrBuffer
.makeStringAndClear();
4069 rExport
.AddAttribute( XML_NAMESPACE_DRAW
, XML_HANDLE_POSITION
, aStr
);
4074 case EAS_MirroredX
:
4077 if ( rPropVal
.Value
>>= bMirroredX
)
4078 rExport
.AddAttribute( XML_NAMESPACE_DRAW
, XML_HANDLE_MIRROR_HORIZONTAL
,
4079 bMirroredX
? GetXMLToken( XML_TRUE
) : GetXMLToken( XML_FALSE
) );
4082 case EAS_MirroredY
:
4085 if ( rPropVal
.Value
>>= bMirroredY
)
4086 rExport
.AddAttribute( XML_NAMESPACE_DRAW
, XML_HANDLE_MIRROR_VERTICAL
,
4087 bMirroredY
? GetXMLToken( XML_TRUE
) : GetXMLToken( XML_FALSE
) );
4093 if ( rPropVal
.Value
>>= bSwitched
)
4094 rExport
.AddAttribute( XML_NAMESPACE_DRAW
, XML_HANDLE_SWITCHED
,
4095 bSwitched
? GetXMLToken( XML_TRUE
) : GetXMLToken( XML_FALSE
) );
4100 css::drawing::EnhancedCustomShapeParameterPair aPolar
;
4101 if ( rPropVal
.Value
>>= aPolar
)
4103 ExportParameter( aStrBuffer
, aPolar
.First
);
4104 ExportParameter( aStrBuffer
, aPolar
.Second
);
4105 aStr
= aStrBuffer
.makeStringAndClear();
4106 rExport
.AddAttribute( XML_NAMESPACE_DRAW
, XML_HANDLE_POLAR
, aStr
);
4110 case EAS_RadiusRangeMinimum
:
4112 css::drawing::EnhancedCustomShapeParameter aRadiusRangeMinimum
;
4113 if ( rPropVal
.Value
>>= aRadiusRangeMinimum
)
4115 ExportParameter( aStrBuffer
, aRadiusRangeMinimum
);
4116 aStr
= aStrBuffer
.makeStringAndClear();
4117 rExport
.AddAttribute( XML_NAMESPACE_DRAW
, XML_HANDLE_RADIUS_RANGE_MINIMUM
, aStr
);
4121 case EAS_RadiusRangeMaximum
:
4123 css::drawing::EnhancedCustomShapeParameter aRadiusRangeMaximum
;
4124 if ( rPropVal
.Value
>>= aRadiusRangeMaximum
)
4126 ExportParameter( aStrBuffer
, aRadiusRangeMaximum
);
4127 aStr
= aStrBuffer
.makeStringAndClear();
4128 rExport
.AddAttribute( XML_NAMESPACE_DRAW
, XML_HANDLE_RADIUS_RANGE_MAXIMUM
, aStr
);
4132 case EAS_RangeXMinimum
:
4134 css::drawing::EnhancedCustomShapeParameter aXRangeMinimum
;
4135 if ( rPropVal
.Value
>>= aXRangeMinimum
)
4137 ExportParameter( aStrBuffer
, aXRangeMinimum
);
4138 aStr
= aStrBuffer
.makeStringAndClear();
4139 rExport
.AddAttribute( XML_NAMESPACE_DRAW
, XML_HANDLE_RANGE_X_MINIMUM
, aStr
);
4143 case EAS_RangeXMaximum
:
4145 css::drawing::EnhancedCustomShapeParameter aXRangeMaximum
;
4146 if ( rPropVal
.Value
>>= aXRangeMaximum
)
4148 ExportParameter( aStrBuffer
, aXRangeMaximum
);
4149 aStr
= aStrBuffer
.makeStringAndClear();
4150 rExport
.AddAttribute( XML_NAMESPACE_DRAW
, XML_HANDLE_RANGE_X_MAXIMUM
, aStr
);
4154 case EAS_RangeYMinimum
:
4156 css::drawing::EnhancedCustomShapeParameter aYRangeMinimum
;
4157 if ( rPropVal
.Value
>>= aYRangeMinimum
)
4159 ExportParameter( aStrBuffer
, aYRangeMinimum
);
4160 aStr
= aStrBuffer
.makeStringAndClear();
4161 rExport
.AddAttribute( XML_NAMESPACE_DRAW
, XML_HANDLE_RANGE_Y_MINIMUM
, aStr
);
4165 case EAS_RangeYMaximum
:
4167 css::drawing::EnhancedCustomShapeParameter aYRangeMaximum
;
4168 if ( rPropVal
.Value
>>= aYRangeMaximum
)
4170 ExportParameter( aStrBuffer
, aYRangeMaximum
);
4171 aStr
= aStrBuffer
.makeStringAndClear();
4172 rExport
.AddAttribute( XML_NAMESPACE_DRAW
, XML_HANDLE_RANGE_Y_MAXIMUM
, aStr
);
4181 SvXMLElementExport
aOBJ( rExport
, XML_NAMESPACE_DRAW
, XML_HANDLE
, true, true );
4183 rExport
.ClearAttrList();
4187 static void ImpExportEnhancedPath( SvXMLExport
& rExport
,
4188 const uno::Sequence
< css::drawing::EnhancedCustomShapeParameterPair
>& rCoordinates
,
4189 const uno::Sequence
< css::drawing::EnhancedCustomShapeSegment
>& rSegments
,
4190 bool bExtended
= false )
4194 OUStringBuffer aStrBuffer
;
4195 bool bNeedExtended
= false;
4197 sal_Int32 i
, j
, k
, l
;
4199 sal_Int32 nCoords
= rCoordinates
.getLength();
4200 sal_Int32 nSegments
= rSegments
.getLength();
4201 bool bSimpleSegments
= nSegments
== 0;
4202 if ( bSimpleSegments
)
4204 for ( j
= i
= 0; j
< nSegments
; j
++ )
4206 css::drawing::EnhancedCustomShapeSegment aSegment
;
4207 if ( bSimpleSegments
)
4209 // if there are not enough segments we will default them
4215 aSegment
.Command
= css::drawing::EnhancedCustomShapeSegmentCommand::MOVETO
;
4220 aSegment
.Count
= static_cast<sal_Int16
>(std::min( nCoords
- 1, sal_Int32(32767) ));
4221 aSegment
.Command
= css::drawing::EnhancedCustomShapeSegmentCommand::LINETO
;
4227 aSegment
.Command
= css::drawing::EnhancedCustomShapeSegmentCommand::CLOSESUBPATH
;
4233 aSegment
.Command
= css::drawing::EnhancedCustomShapeSegmentCommand::ENDSUBPATH
;
4239 aSegment
= rSegments
[ j
];
4241 if ( !aStrBuffer
.isEmpty() )
4242 aStrBuffer
.append( ' ' );
4244 sal_Int32 nParameter
= 0;
4245 switch( aSegment
.Command
)
4247 case css::drawing::EnhancedCustomShapeSegmentCommand::CLOSESUBPATH
:
4248 aStrBuffer
.append( 'Z' ); break;
4249 case css::drawing::EnhancedCustomShapeSegmentCommand::ENDSUBPATH
:
4250 aStrBuffer
.append( 'N' ); break;
4251 case css::drawing::EnhancedCustomShapeSegmentCommand::NOFILL
:
4252 aStrBuffer
.append( 'F' ); break;
4253 case css::drawing::EnhancedCustomShapeSegmentCommand::NOSTROKE
:
4254 aStrBuffer
.append( 'S' ); break;
4256 case css::drawing::EnhancedCustomShapeSegmentCommand::MOVETO
:
4257 aStrBuffer
.append( 'M' ); nParameter
= 1; break;
4258 case css::drawing::EnhancedCustomShapeSegmentCommand::LINETO
:
4259 aStrBuffer
.append( 'L' ); nParameter
= 1; break;
4260 case css::drawing::EnhancedCustomShapeSegmentCommand::CURVETO
:
4261 aStrBuffer
.append( 'C' ); nParameter
= 3; break;
4262 case css::drawing::EnhancedCustomShapeSegmentCommand::ANGLEELLIPSETO
:
4263 aStrBuffer
.append( 'T' ); nParameter
= 3; break;
4264 case css::drawing::EnhancedCustomShapeSegmentCommand::ANGLEELLIPSE
:
4265 aStrBuffer
.append( 'U' ); nParameter
= 3; break;
4266 case css::drawing::EnhancedCustomShapeSegmentCommand::ARCTO
:
4267 aStrBuffer
.append( 'A' ); nParameter
= 4; break;
4268 case css::drawing::EnhancedCustomShapeSegmentCommand::ARC
:
4269 aStrBuffer
.append( 'B' ); nParameter
= 4; break;
4270 case css::drawing::EnhancedCustomShapeSegmentCommand::CLOCKWISEARCTO
:
4271 aStrBuffer
.append( 'W' ); nParameter
= 4; break;
4272 case css::drawing::EnhancedCustomShapeSegmentCommand::CLOCKWISEARC
:
4273 aStrBuffer
.append( 'V' ); nParameter
= 4; break;
4274 case css::drawing::EnhancedCustomShapeSegmentCommand::ELLIPTICALQUADRANTX
:
4275 aStrBuffer
.append( 'X' ); nParameter
= 1; break;
4276 case css::drawing::EnhancedCustomShapeSegmentCommand::ELLIPTICALQUADRANTY
:
4277 aStrBuffer
.append( 'Y' ); nParameter
= 1; break;
4278 case css::drawing::EnhancedCustomShapeSegmentCommand::QUADRATICCURVETO
:
4279 aStrBuffer
.append( 'Q' ); nParameter
= 2; break;
4280 case css::drawing::EnhancedCustomShapeSegmentCommand::ARCANGLETO
:
4282 aStrBuffer
.append( 'G' );
4285 aStrBuffer
.setLength( aStrBuffer
.getLength() - 1);
4286 bNeedExtended
= true;
4290 case css::drawing::EnhancedCustomShapeSegmentCommand::DARKEN
:
4292 aStrBuffer
.append( 'H' );
4294 bNeedExtended
= true;
4296 case css::drawing::EnhancedCustomShapeSegmentCommand::DARKENLESS
:
4298 aStrBuffer
.append( 'I' );
4300 bNeedExtended
= true;
4302 case css::drawing::EnhancedCustomShapeSegmentCommand::LIGHTEN
:
4304 aStrBuffer
.append( 'J' );
4306 bNeedExtended
= true;
4308 case css::drawing::EnhancedCustomShapeSegmentCommand::LIGHTENLESS
:
4310 aStrBuffer
.append( 'K' );
4312 bNeedExtended
= true;
4314 default : // ups, seems to be something wrong
4317 aSegment
.Command
= css::drawing::EnhancedCustomShapeSegmentCommand::LINETO
;
4323 for ( k
= 0; k
< aSegment
.Count
; k
++ )
4325 if ( ( i
+ nParameter
) <= nCoords
)
4327 for ( l
= 0; l
< nParameter
; l
++ )
4329 ExportParameter( aStrBuffer
, rCoordinates
[ i
].First
);
4330 ExportParameter( aStrBuffer
, rCoordinates
[ i
++ ].Second
);
4335 j
= nSegments
; // error -> exiting
4341 aStr
= aStrBuffer
.makeStringAndClear();
4342 rExport
.AddAttribute( bExtended
? XML_NAMESPACE_DRAW_EXT
: XML_NAMESPACE_DRAW
, XML_ENHANCED_PATH
, aStr
);
4343 if (!bExtended
&& bNeedExtended
&& (rExport
.getSaneDefaultVersion() & SvtSaveOptions::ODFSVER_EXTENDED
))
4344 ImpExportEnhancedPath( rExport
, rCoordinates
, rSegments
, true );
4347 static void ImpExportEnhancedGeometry( SvXMLExport
& rExport
, const uno::Reference
< beans::XPropertySet
>& xPropSet
)
4349 bool bEquations
= false;
4350 uno::Sequence
< OUString
> aEquations
;
4352 bool bHandles
= false;
4353 uno::Sequence
< beans::PropertyValues
> aHandles
;
4355 uno::Sequence
< css::drawing::EnhancedCustomShapeSegment
> aSegments
;
4356 uno::Sequence
< css::drawing::EnhancedCustomShapeParameterPair
> aCoordinates
;
4358 uno::Sequence
< css::drawing::EnhancedCustomShapeAdjustmentValue
> aAdjustmentValues
;
4361 OUStringBuffer aStrBuffer
;
4362 double fTextRotateAngle(0.0);
4363 double fTextPreRotateAngle(0.0); // will be consolidated with fTextRotateAngle at the end
4364 SvXMLUnitConverter
& rUnitConverter
= rExport
.GetMM100UnitConverter();
4366 uno::Reference
< beans::XPropertySetInfo
> xPropSetInfo( xPropSet
->getPropertySetInfo() );
4369 static const OUStringLiteral
sCustomShapeGeometry( u
"CustomShapeGeometry" );
4370 if ( xPropSetInfo
.is() && xPropSetInfo
->hasPropertyByName( sCustomShapeGeometry
) )
4372 uno::Any
aGeoPropSet( xPropSet
->getPropertyValue( sCustomShapeGeometry
) );
4373 uno::Sequence
< beans::PropertyValue
> aGeoPropSeq
;
4375 if ( aGeoPropSet
>>= aGeoPropSeq
)
4377 bool bCoordinates
= false;
4378 OUString
aCustomShapeType( "non-primitive" );
4380 for ( const beans::PropertyValue
& rGeoProp
: std::as_const(aGeoPropSeq
) )
4382 switch( EASGet( rGeoProp
.Name
) )
4386 rGeoProp
.Value
>>= aCustomShapeType
;
4389 case EAS_MirroredX
:
4392 if ( rGeoProp
.Value
>>= bMirroredX
)
4393 rExport
.AddAttribute( XML_NAMESPACE_DRAW
, XML_MIRROR_HORIZONTAL
,
4394 bMirroredX
? GetXMLToken( XML_TRUE
) : GetXMLToken( XML_FALSE
) );
4397 case EAS_MirroredY
:
4400 if ( rGeoProp
.Value
>>= bMirroredY
)
4401 rExport
.AddAttribute( XML_NAMESPACE_DRAW
, XML_MIRROR_VERTICAL
,
4402 bMirroredY
? GetXMLToken( XML_TRUE
) : GetXMLToken( XML_FALSE
) );
4407 awt::Rectangle aRect
;
4408 if ( rGeoProp
.Value
>>= aRect
)
4410 SdXMLImExViewBox
aViewBox( aRect
.X
, aRect
.Y
, aRect
.Width
, aRect
.Height
);
4411 rExport
.AddAttribute( XML_NAMESPACE_SVG
, XML_VIEWBOX
, aViewBox
.GetExportString() );
4415 case EAS_TextPreRotateAngle
:
4417 rGeoProp
.Value
>>= fTextPreRotateAngle
;
4420 case EAS_TextRotateAngle
:
4422 rGeoProp
.Value
>>= fTextRotateAngle
;
4425 case EAS_Extrusion
:
4427 uno::Sequence
< beans::PropertyValue
> aExtrusionPropSeq
;
4428 if ( rGeoProp
.Value
>>= aExtrusionPropSeq
)
4430 bool bSkewValuesProvided
= false;
4431 for ( const beans::PropertyValue
& rProp
: std::as_const(aExtrusionPropSeq
) )
4433 switch( EASGet( rProp
.Name
) )
4435 case EAS_Extrusion
:
4438 if ( rProp
.Value
>>= bExtrusionOn
)
4439 rExport
.AddAttribute( XML_NAMESPACE_DRAW
, XML_EXTRUSION
,
4440 bExtrusionOn
? GetXMLToken( XML_TRUE
) : GetXMLToken( XML_FALSE
) );
4443 case EAS_Brightness
:
4445 double fExtrusionBrightness
= 0;
4446 if ( rProp
.Value
>>= fExtrusionBrightness
)
4448 ::sax::Converter::convertDouble(
4450 fExtrusionBrightness
,
4452 util::MeasureUnit::PERCENT
,
4453 util::MeasureUnit::PERCENT
);
4454 aStrBuffer
.append( '%' );
4455 aStr
= aStrBuffer
.makeStringAndClear();
4456 rExport
.AddAttribute( XML_NAMESPACE_DRAW
, XML_EXTRUSION_BRIGHTNESS
, aStr
);
4462 css::drawing::EnhancedCustomShapeParameterPair aDepthParaPair
;
4463 if ( rProp
.Value
>>= aDepthParaPair
)
4466 if ( aDepthParaPair
.First
.Value
>>= fDepth
)
4468 rExport
.GetMM100UnitConverter().convertDouble( aStrBuffer
, fDepth
);
4469 ExportParameter( aStrBuffer
, aDepthParaPair
.Second
);
4470 aStr
= aStrBuffer
.makeStringAndClear();
4471 rExport
.AddAttribute( XML_NAMESPACE_DRAW
, XML_EXTRUSION_DEPTH
, aStr
);
4476 case EAS_Diffusion
:
4478 double fExtrusionDiffusion
= 0;
4479 if ( rProp
.Value
>>= fExtrusionDiffusion
)
4481 ::sax::Converter::convertDouble(
4483 fExtrusionDiffusion
,
4485 util::MeasureUnit::PERCENT
,
4486 util::MeasureUnit::PERCENT
);
4487 aStrBuffer
.append( '%' );
4488 aStr
= aStrBuffer
.makeStringAndClear();
4489 rExport
.AddAttribute( XML_NAMESPACE_DRAW
, XML_EXTRUSION_DIFFUSION
, aStr
);
4493 case EAS_NumberOfLineSegments
:
4495 sal_Int32 nExtrusionNumberOfLineSegments
= 0;
4496 if ( rProp
.Value
>>= nExtrusionNumberOfLineSegments
)
4497 rExport
.AddAttribute( XML_NAMESPACE_DRAW
, XML_EXTRUSION_NUMBER_OF_LINE_SEGMENTS
, OUString::number( nExtrusionNumberOfLineSegments
) );
4500 case EAS_LightFace
:
4502 bool bExtrusionLightFace
;
4503 if ( rProp
.Value
>>= bExtrusionLightFace
)
4504 rExport
.AddAttribute( XML_NAMESPACE_DRAW
, XML_EXTRUSION_LIGHT_FACE
,
4505 bExtrusionLightFace
? GetXMLToken( XML_TRUE
) : GetXMLToken( XML_FALSE
) );
4508 case EAS_FirstLightHarsh
:
4510 bool bExtrusionFirstLightHarsh
;
4511 if ( rProp
.Value
>>= bExtrusionFirstLightHarsh
)
4512 rExport
.AddAttribute( XML_NAMESPACE_DRAW
, XML_EXTRUSION_FIRST_LIGHT_HARSH
,
4513 bExtrusionFirstLightHarsh
? GetXMLToken( XML_TRUE
) : GetXMLToken( XML_FALSE
) );
4516 case EAS_SecondLightHarsh
:
4518 bool bExtrusionSecondLightHarsh
;
4519 if ( rProp
.Value
>>= bExtrusionSecondLightHarsh
)
4520 rExport
.AddAttribute( XML_NAMESPACE_DRAW
, XML_EXTRUSION_SECOND_LIGHT_HARSH
,
4521 bExtrusionSecondLightHarsh
? GetXMLToken( XML_TRUE
) : GetXMLToken( XML_FALSE
) );
4524 case EAS_FirstLightLevel
:
4526 double fExtrusionFirstLightLevel
= 0;
4527 if ( rProp
.Value
>>= fExtrusionFirstLightLevel
)
4529 ::sax::Converter::convertDouble(
4531 fExtrusionFirstLightLevel
,
4533 util::MeasureUnit::PERCENT
,
4534 util::MeasureUnit::PERCENT
);
4535 aStrBuffer
.append( '%' );
4536 aStr
= aStrBuffer
.makeStringAndClear();
4537 rExport
.AddAttribute( XML_NAMESPACE_DRAW
, XML_EXTRUSION_FIRST_LIGHT_LEVEL
, aStr
);
4541 case EAS_SecondLightLevel
:
4543 double fExtrusionSecondLightLevel
= 0;
4544 if ( rProp
.Value
>>= fExtrusionSecondLightLevel
)
4546 ::sax::Converter::convertDouble(
4548 fExtrusionSecondLightLevel
,
4550 util::MeasureUnit::PERCENT
,
4551 util::MeasureUnit::PERCENT
);
4552 aStrBuffer
.append( '%' );
4553 aStr
= aStrBuffer
.makeStringAndClear();
4554 rExport
.AddAttribute( XML_NAMESPACE_DRAW
, XML_EXTRUSION_SECOND_LIGHT_LEVEL
, aStr
);
4558 case EAS_FirstLightDirection
:
4560 drawing::Direction3D aExtrusionFirstLightDirection
;
4561 if ( rProp
.Value
>>= aExtrusionFirstLightDirection
)
4563 ::basegfx::B3DVector
aVec3D( aExtrusionFirstLightDirection
.DirectionX
, aExtrusionFirstLightDirection
.DirectionY
,
4564 aExtrusionFirstLightDirection
.DirectionZ
);
4565 SvXMLUnitConverter::convertB3DVector( aStrBuffer
, aVec3D
);
4566 aStr
= aStrBuffer
.makeStringAndClear();
4567 rExport
.AddAttribute( XML_NAMESPACE_DRAW
, XML_EXTRUSION_FIRST_LIGHT_DIRECTION
, aStr
);
4571 case EAS_SecondLightDirection
:
4573 drawing::Direction3D aExtrusionSecondLightDirection
;
4574 if ( rProp
.Value
>>= aExtrusionSecondLightDirection
)
4576 ::basegfx::B3DVector
aVec3D( aExtrusionSecondLightDirection
.DirectionX
, aExtrusionSecondLightDirection
.DirectionY
,
4577 aExtrusionSecondLightDirection
.DirectionZ
);
4578 SvXMLUnitConverter::convertB3DVector( aStrBuffer
, aVec3D
);
4579 aStr
= aStrBuffer
.makeStringAndClear();
4580 rExport
.AddAttribute( XML_NAMESPACE_DRAW
, XML_EXTRUSION_SECOND_LIGHT_DIRECTION
, aStr
);
4586 bool bExtrusionMetal
;
4587 if ( rProp
.Value
>>= bExtrusionMetal
)
4588 rExport
.AddAttribute( XML_NAMESPACE_DRAW
, XML_EXTRUSION_METAL
,
4589 bExtrusionMetal
? GetXMLToken( XML_TRUE
) : GetXMLToken( XML_FALSE
) );
4592 case EAS_MetalType
:
4594 // export only if ODF extensions are enabled
4595 sal_Int16 eMetalType
;
4596 if (rProp
.Value
>>= eMetalType
)
4598 SvtSaveOptions::ODFSaneDefaultVersion eVersion
= rExport
.getSaneDefaultVersion();
4599 if (eVersion
> SvtSaveOptions::ODFSVER_013
4600 && (eVersion
& SvtSaveOptions::ODFSVER_EXTENDED
))
4602 if (eMetalType
== drawing::EnhancedCustomShapeMetalType::MetalMSCompatible
)
4603 aStr
= "loext:MetalMSCompatible";
4605 aStr
= "draw:MetalODF";
4606 rExport
.AddAttribute(XML_NAMESPACE_LO_EXT
, XML_EXTRUSION_METAL_TYPE
, aStr
);
4611 case EAS_ShadeMode
:
4614 drawing::ShadeMode eShadeMode
;
4615 if( rProp
.Value
>>= eShadeMode
)
4617 if( eShadeMode
== drawing::ShadeMode_FLAT
)
4618 aStr
= GetXMLToken( XML_FLAT
);
4619 else if( eShadeMode
== drawing::ShadeMode_PHONG
)
4620 aStr
= GetXMLToken( XML_PHONG
);
4621 else if( eShadeMode
== drawing::ShadeMode_SMOOTH
)
4622 aStr
= GetXMLToken( XML_GOURAUD
);
4624 aStr
= GetXMLToken( XML_DRAFT
);
4628 // ShadeMode enum not there, write default
4629 aStr
= GetXMLToken( XML_FLAT
);
4631 rExport
.AddAttribute( XML_NAMESPACE_DR3D
, XML_SHADE_MODE
, aStr
);
4634 case EAS_RotateAngle
:
4636 css::drawing::EnhancedCustomShapeParameterPair aRotateAngleParaPair
;
4637 if ( rProp
.Value
>>= aRotateAngleParaPair
)
4639 ExportParameter( aStrBuffer
, aRotateAngleParaPair
.First
);
4640 ExportParameter( aStrBuffer
, aRotateAngleParaPair
.Second
);
4641 aStr
= aStrBuffer
.makeStringAndClear();
4642 rExport
.AddAttribute( XML_NAMESPACE_DRAW
, XML_EXTRUSION_ROTATION_ANGLE
, aStr
);
4646 case EAS_RotationCenter
:
4648 drawing::Direction3D aExtrusionRotationCenter
;
4649 if ( rProp
.Value
>>= aExtrusionRotationCenter
)
4651 ::basegfx::B3DVector
aVec3D( aExtrusionRotationCenter
.DirectionX
, aExtrusionRotationCenter
.DirectionY
,
4652 aExtrusionRotationCenter
.DirectionZ
);
4653 SvXMLUnitConverter::convertB3DVector( aStrBuffer
, aVec3D
);
4654 aStr
= aStrBuffer
.makeStringAndClear();
4655 rExport
.AddAttribute( XML_NAMESPACE_DRAW
, XML_EXTRUSION_ROTATION_CENTER
, aStr
);
4659 case EAS_Shininess
:
4661 double fExtrusionShininess
= 0;
4662 if ( rProp
.Value
>>= fExtrusionShininess
)
4664 ::sax::Converter::convertDouble(
4666 fExtrusionShininess
,
4668 util::MeasureUnit::PERCENT
,
4669 util::MeasureUnit::PERCENT
);
4670 aStrBuffer
.append( '%' );
4671 aStr
= aStrBuffer
.makeStringAndClear();
4672 rExport
.AddAttribute( XML_NAMESPACE_DRAW
, XML_EXTRUSION_SHININESS
, aStr
);
4678 css::drawing::EnhancedCustomShapeParameterPair aSkewParaPair
;
4679 if ( rProp
.Value
>>= aSkewParaPair
)
4681 bSkewValuesProvided
= true;
4682 ExportParameter( aStrBuffer
, aSkewParaPair
.First
);
4683 ExportParameter( aStrBuffer
, aSkewParaPair
.Second
);
4684 aStr
= aStrBuffer
.makeStringAndClear();
4685 rExport
.AddAttribute( XML_NAMESPACE_DRAW
, XML_EXTRUSION_SKEW
, aStr
);
4689 case EAS_Specularity
:
4691 double fExtrusionSpecularity
= 0;
4692 if ( rProp
.Value
>>= fExtrusionSpecularity
)
4694 SvtSaveOptions::ODFSaneDefaultVersion eVersion
= rExport
.getSaneDefaultVersion();
4695 if (fExtrusionSpecularity
> 100.0 && eVersion
>= SvtSaveOptions::ODFSVER_012
4696 && (eVersion
& SvtSaveOptions::ODFSVER_EXTENDED
))
4698 // tdf#147580 write values > 100% in loext
4699 ::sax::Converter::convertDouble(
4701 fExtrusionSpecularity
,
4703 util::MeasureUnit::PERCENT
,
4704 util::MeasureUnit::PERCENT
);
4705 aStrBuffer
.append( '%' );
4706 aStr
= aStrBuffer
.makeStringAndClear();
4707 rExport
.AddAttribute( XML_NAMESPACE_LO_EXT
, XML_EXTRUSION_SPECULARITY_LOEXT
, aStr
);
4709 // tdf#147580 ODF 1 allows arbitrary percent, later versions not
4710 if (eVersion
>= SvtSaveOptions::ODFSVER_012
)
4712 fExtrusionSpecularity
= std::clamp
<double>(fExtrusionSpecularity
, 0.0, 100.0);
4714 ::sax::Converter::convertDouble(
4716 fExtrusionSpecularity
,
4718 util::MeasureUnit::PERCENT
,
4719 util::MeasureUnit::PERCENT
);
4720 aStrBuffer
.append( '%' );
4721 aStr
= aStrBuffer
.makeStringAndClear();
4722 rExport
.AddAttribute( XML_NAMESPACE_DRAW
, XML_EXTRUSION_SPECULARITY
, aStr
);
4726 case EAS_ProjectionMode
:
4728 drawing::ProjectionMode eProjectionMode
;
4729 if ( rProp
.Value
>>= eProjectionMode
)
4730 rExport
.AddAttribute( XML_NAMESPACE_DR3D
, XML_PROJECTION
,
4731 eProjectionMode
== drawing::ProjectionMode_PARALLEL
? GetXMLToken( XML_PARALLEL
) : GetXMLToken( XML_PERSPECTIVE
) );
4734 case EAS_ViewPoint
:
4736 drawing::Position3D aExtrusionViewPoint
;
4737 if ( rProp
.Value
>>= aExtrusionViewPoint
)
4739 rUnitConverter
.convertPosition3D( aStrBuffer
, aExtrusionViewPoint
);
4740 aStr
= aStrBuffer
.makeStringAndClear();
4741 rExport
.AddAttribute( XML_NAMESPACE_DRAW
, XML_EXTRUSION_VIEWPOINT
, aStr
);
4747 css::drawing::EnhancedCustomShapeParameterPair aOriginParaPair
;
4748 if ( rProp
.Value
>>= aOriginParaPair
)
4750 ExportParameter( aStrBuffer
, aOriginParaPair
.First
);
4751 ExportParameter( aStrBuffer
, aOriginParaPair
.Second
);
4752 aStr
= aStrBuffer
.makeStringAndClear();
4753 rExport
.AddAttribute( XML_NAMESPACE_DRAW
, XML_EXTRUSION_ORIGIN
, aStr
);
4759 bool bExtrusionColor
;
4760 if ( rProp
.Value
>>= bExtrusionColor
)
4762 rExport
.AddAttribute( XML_NAMESPACE_DRAW
, XML_EXTRUSION_COLOR
,
4763 bExtrusionColor
? GetXMLToken( XML_TRUE
) : GetXMLToken( XML_FALSE
) );
4771 // tdf#141301: no specific skew values provided
4772 if (!bSkewValuesProvided
)
4774 // so we need to export default values explicitly
4775 rExport
.AddAttribute( XML_NAMESPACE_DRAW
, XML_EXTRUSION_SKEW
, "50 -135");
4782 uno::Sequence
< beans::PropertyValue
> aTextPathPropSeq
;
4783 if ( rGeoProp
.Value
>>= aTextPathPropSeq
)
4785 for ( const beans::PropertyValue
& rProp
: std::as_const(aTextPathPropSeq
) )
4787 switch( EASGet( rProp
.Name
) )
4792 if ( rProp
.Value
>>= bTextPathOn
)
4793 rExport
.AddAttribute( XML_NAMESPACE_DRAW
, XML_TEXT_PATH
,
4794 bTextPathOn
? GetXMLToken( XML_TRUE
) : GetXMLToken( XML_FALSE
) );
4797 case EAS_TextPathMode
:
4799 css::drawing::EnhancedCustomShapeTextPathMode eTextPathMode
;
4800 if ( rProp
.Value
>>= eTextPathMode
)
4802 switch ( eTextPathMode
)
4804 case css::drawing::EnhancedCustomShapeTextPathMode_NORMAL
: aStr
= GetXMLToken( XML_NORMAL
); break;
4805 case css::drawing::EnhancedCustomShapeTextPathMode_PATH
: aStr
= GetXMLToken( XML_PATH
); break;
4806 case css::drawing::EnhancedCustomShapeTextPathMode_SHAPE
: aStr
= GetXMLToken( XML_SHAPE
); break;
4810 if ( !aStr
.isEmpty() )
4811 rExport
.AddAttribute( XML_NAMESPACE_DRAW
, XML_TEXT_PATH_MODE
, aStr
);
4818 if ( rProp
.Value
>>= bScaleX
)
4820 aStr
= bScaleX
? GetXMLToken( XML_SHAPE
) : GetXMLToken( XML_PATH
);
4821 rExport
.AddAttribute( XML_NAMESPACE_DRAW
, XML_TEXT_PATH_SCALE
, aStr
);
4825 case EAS_SameLetterHeights
:
4827 bool bSameLetterHeights
;
4828 if ( rProp
.Value
>>= bSameLetterHeights
)
4829 rExport
.AddAttribute( XML_NAMESPACE_DRAW
, XML_TEXT_PATH_SAME_LETTER_HEIGHTS
,
4830 bSameLetterHeights
? GetXMLToken( XML_TRUE
) : GetXMLToken( XML_FALSE
) );
4842 uno::Sequence
< beans::PropertyValue
> aPathPropSeq
;
4843 if ( rGeoProp
.Value
>>= aPathPropSeq
)
4845 for ( const beans::PropertyValue
& rProp
: std::as_const(aPathPropSeq
) )
4847 switch( EASGet( rProp
.Name
) )
4849 case EAS_SubViewSize
:
4851 // export draw:sub-view-size (do not export in ODF 1.3 or older)
4852 if ((rExport
.getSaneDefaultVersion() & SvtSaveOptions::ODFSVER_EXTENDED
) == 0)
4856 uno::Sequence
< awt::Size
> aSubViewSizes
;
4857 rProp
.Value
>>= aSubViewSizes
;
4859 for ( int nIdx
= 0; nIdx
< aSubViewSizes
.getLength(); nIdx
++ )
4862 aStrBuffer
.append(' ');
4863 aStrBuffer
.append( aSubViewSizes
[nIdx
].Width
);
4864 aStrBuffer
.append(' ');
4865 aStrBuffer
.append( aSubViewSizes
[nIdx
].Height
);
4867 aStr
= aStrBuffer
.makeStringAndClear();
4868 rExport
.AddAttribute( XML_NAMESPACE_DRAW_EXT
, XML_SUB_VIEW_SIZE
, aStr
);
4871 case EAS_ExtrusionAllowed
:
4873 bool bExtrusionAllowed
;
4874 if ( rProp
.Value
>>= bExtrusionAllowed
)
4875 rExport
.AddAttribute( XML_NAMESPACE_DRAW
, XML_EXTRUSION_ALLOWED
,
4876 bExtrusionAllowed
? GetXMLToken( XML_TRUE
) : GetXMLToken( XML_FALSE
) );
4879 case EAS_ConcentricGradientFillAllowed
:
4881 bool bConcentricGradientFillAllowed
;
4882 if ( rProp
.Value
>>= bConcentricGradientFillAllowed
)
4883 rExport
.AddAttribute( XML_NAMESPACE_DRAW
, XML_CONCENTRIC_GRADIENT_FILL_ALLOWED
,
4884 bConcentricGradientFillAllowed
? GetXMLToken( XML_TRUE
) : GetXMLToken( XML_FALSE
) );
4887 case EAS_TextPathAllowed
:
4889 bool bTextPathAllowed
;
4890 if ( rProp
.Value
>>= bTextPathAllowed
)
4891 rExport
.AddAttribute( XML_NAMESPACE_DRAW
, XML_TEXT_PATH_ALLOWED
,
4892 bTextPathAllowed
? GetXMLToken( XML_TRUE
) : GetXMLToken( XML_FALSE
) );
4895 case EAS_GluePoints
:
4897 css::uno::Sequence
< css::drawing::EnhancedCustomShapeParameterPair
> aGluePoints
;
4898 if ( rProp
.Value
>>= aGluePoints
)
4900 if ( aGluePoints
.hasElements() )
4902 for( const auto& rGluePoint
: std::as_const(aGluePoints
) )
4904 ExportParameter( aStrBuffer
, rGluePoint
.First
);
4905 ExportParameter( aStrBuffer
, rGluePoint
.Second
);
4907 aStr
= aStrBuffer
.makeStringAndClear();
4909 rExport
.AddAttribute( XML_NAMESPACE_DRAW
, XML_GLUE_POINTS
, aStr
);
4913 case EAS_GluePointType
:
4915 sal_Int16 nGluePointType
= sal_Int16();
4916 if ( rProp
.Value
>>= nGluePointType
)
4918 switch ( nGluePointType
)
4920 case css::drawing::EnhancedCustomShapeGluePointType::NONE
: aStr
= GetXMLToken( XML_NONE
); break;
4921 case css::drawing::EnhancedCustomShapeGluePointType::SEGMENTS
: aStr
= GetXMLToken( XML_SEGMENTS
); break;
4922 case css::drawing::EnhancedCustomShapeGluePointType::RECT
: aStr
= GetXMLToken( XML_RECTANGLE
); break;
4924 if ( !aStr
.isEmpty() )
4925 rExport
.AddAttribute( XML_NAMESPACE_DRAW
, XML_GLUE_POINT_TYPE
, aStr
);
4929 case EAS_Coordinates
:
4931 bCoordinates
= ( rProp
.Value
>>= aCoordinates
);
4936 rProp
.Value
>>= aSegments
;
4941 sal_Int32 nStretchPoint
= 0;
4942 if ( rProp
.Value
>>= nStretchPoint
)
4943 rExport
.AddAttribute( XML_NAMESPACE_DRAW
, XML_PATH_STRETCHPOINT_X
, OUString::number( nStretchPoint
) );
4948 sal_Int32 nStretchPoint
= 0;
4949 if ( rProp
.Value
>>= nStretchPoint
)
4950 rExport
.AddAttribute( XML_NAMESPACE_DRAW
, XML_PATH_STRETCHPOINT_Y
, OUString::number( nStretchPoint
) );
4953 case EAS_TextFrames
:
4955 css::uno::Sequence
< css::drawing::EnhancedCustomShapeTextFrame
> aPathTextFrames
;
4956 if ( rProp
.Value
>>= aPathTextFrames
)
4958 if ( aPathTextFrames
.hasElements() )
4960 for ( const auto& rPathTextFrame
: std::as_const(aPathTextFrames
) )
4962 ExportParameter( aStrBuffer
, rPathTextFrame
.TopLeft
.First
);
4963 ExportParameter( aStrBuffer
, rPathTextFrame
.TopLeft
.Second
);
4964 ExportParameter( aStrBuffer
, rPathTextFrame
.BottomRight
.First
);
4965 ExportParameter( aStrBuffer
, rPathTextFrame
.BottomRight
.Second
);
4967 aStr
= aStrBuffer
.makeStringAndClear();
4969 rExport
.AddAttribute( XML_NAMESPACE_DRAW
, XML_TEXT_AREAS
, aStr
);
4980 case EAS_Equations
:
4982 bEquations
= ( rGeoProp
.Value
>>= aEquations
);
4987 bHandles
= ( rGeoProp
.Value
>>= aHandles
);
4990 case EAS_AdjustmentValues
:
4992 rGeoProp
.Value
>>= aAdjustmentValues
;
5000 // ToDo: Where is TextPreRotateAngle still used? We cannot save it in ODF.
5001 fTextRotateAngle
+= fTextPreRotateAngle
;
5002 // Workaround for writing-mode bt-lr and tb-rl90 in ODF strict,
5003 // otherwise loext:writing-mode is used in style export.
5004 if (!(rExport
.getSaneDefaultVersion() & SvtSaveOptions::ODFSVER_EXTENDED
))
5006 if (xPropSetInfo
->hasPropertyByName(u
"WritingMode"))
5008 sal_Int16 nDirection
= -1;
5009 xPropSet
->getPropertyValue(u
"WritingMode") >>= nDirection
;
5010 if (nDirection
== text::WritingMode2::TB_RL90
)
5011 fTextRotateAngle
-= 90;
5012 else if (nDirection
== text::WritingMode2::BT_LR
)
5013 fTextRotateAngle
-= 270;
5016 if (fTextRotateAngle
!= 0)
5018 ::sax::Converter::convertDouble( aStrBuffer
, fTextRotateAngle
);
5019 aStr
= aStrBuffer
.makeStringAndClear();
5020 rExport
.AddAttribute( XML_NAMESPACE_DRAW
, XML_TEXT_ROTATE_ANGLE
, aStr
);
5023 rExport
.AddAttribute( XML_NAMESPACE_DRAW
, XML_TYPE
, aCustomShapeType
);
5026 sal_Int32 nAdjustmentValues
= aAdjustmentValues
.getLength();
5027 if ( nAdjustmentValues
)
5029 sal_Int32 i
, nValue
= 0;
5030 for ( i
= 0; i
< nAdjustmentValues
; i
++ )
5033 aStrBuffer
.append( ' ' );
5035 const css::drawing::EnhancedCustomShapeAdjustmentValue
& rAdj
= aAdjustmentValues
[ i
];
5036 if ( rAdj
.State
== beans::PropertyState_DIRECT_VALUE
)
5038 if ( rAdj
.Value
.getValueTypeClass() == uno::TypeClass_DOUBLE
)
5040 double fValue
= 0.0;
5041 rAdj
.Value
>>= fValue
;
5042 ::sax::Converter::convertDouble(aStrBuffer
, fValue
);
5046 rAdj
.Value
>>= nValue
;
5047 aStrBuffer
.append(nValue
);
5052 // this should not be, but better than setting nothing
5053 aStrBuffer
.append("0");
5056 aStr
= aStrBuffer
.makeStringAndClear();
5057 rExport
.AddAttribute( XML_NAMESPACE_DRAW
, XML_MODIFIERS
, aStr
);
5060 ImpExportEnhancedPath( rExport
, aCoordinates
, aSegments
);
5063 SvXMLElementExport
aOBJ( rExport
, XML_NAMESPACE_DRAW
, XML_ENHANCED_GEOMETRY
, true, true );
5065 ImpExportEquations( rExport
, aEquations
);
5067 ImpExportHandles( rExport
, aHandles
);
5070 void XMLShapeExport::ImpExportCustomShape(
5071 const uno::Reference
< drawing::XShape
>& xShape
,
5072 XMLShapeExportFlags nFeatures
, css::awt::Point
* pRefPoint
)
5074 const uno::Reference
< beans::XPropertySet
> xPropSet(xShape
, uno::UNO_QUERY
);
5075 if ( !xPropSet
.is() )
5078 uno::Reference
< beans::XPropertySetInfo
> xPropSetInfo( xPropSet
->getPropertySetInfo() );
5081 ImpExportNewTrans( xPropSet
, nFeatures
, pRefPoint
);
5083 if ( xPropSetInfo
.is() )
5086 if ( xPropSetInfo
->hasPropertyByName( "CustomShapeEngine" ) )
5088 uno::Any
aEngine( xPropSet
->getPropertyValue( "CustomShapeEngine" ) );
5089 if ( ( aEngine
>>= aStr
) && !aStr
.isEmpty() )
5090 mrExport
.AddAttribute( XML_NAMESPACE_DRAW
, XML_ENGINE
, aStr
);
5092 if ( xPropSetInfo
->hasPropertyByName( "CustomShapeData" ) )
5094 uno::Any
aData( xPropSet
->getPropertyValue( "CustomShapeData" ) );
5095 if ( ( aData
>>= aStr
) && !aStr
.isEmpty() )
5096 mrExport
.AddAttribute( XML_NAMESPACE_DRAW
, XML_DATA
, aStr
);
5099 bool bCreateNewline( (nFeatures
& XMLShapeExportFlags::NO_WS
) == XMLShapeExportFlags::NONE
); // #86116#/#92210#
5100 SvXMLElementExport
aOBJ( mrExport
, XML_NAMESPACE_DRAW
, XML_CUSTOM_SHAPE
, bCreateNewline
, true );
5101 ImpExportDescription( xShape
); // #i68101#
5102 ImpExportEvents( xShape
);
5103 ImpExportGluePoints( xShape
);
5104 ImpExportText( xShape
);
5105 ImpExportEnhancedGeometry( mrExport
, xPropSet
);
5109 void XMLShapeExport::ImpExportTableShape( const uno::Reference
< drawing::XShape
>& xShape
, XmlShapeType eShapeType
, XMLShapeExportFlags nFeatures
, css::awt::Point
* pRefPoint
)
5111 uno::Reference
< beans::XPropertySet
> xPropSet(xShape
, uno::UNO_QUERY
);
5112 uno::Reference
< container::XNamed
> xNamed(xShape
, uno::UNO_QUERY
);
5114 SAL_WARN_IF( !xPropSet
.is() || !xNamed
.is(), "xmloff", "xmloff::XMLShapeExport::ImpExportTableShape(), table shape is not implementing needed interfaces");
5115 if(!(xPropSet
.is() && xNamed
.is()))
5121 ImpExportNewTrans(xPropSet
, nFeatures
, pRefPoint
);
5123 bool bIsEmptyPresObj
= false;
5125 // presentation settings
5126 if(eShapeType
== XmlShapeType::PresTableShape
)
5127 bIsEmptyPresObj
= ImpExportPresentationAttributes( xPropSet
, GetXMLToken(XML_TABLE
) );
5129 const bool bCreateNewline( (nFeatures
& XMLShapeExportFlags::NO_WS
) == XMLShapeExportFlags::NONE
);
5131 SvXMLElementExport
aElement( mrExport
, XML_NAMESPACE_DRAW
, XML_FRAME
, bCreateNewline
, true );
5133 // do not export in ODF 1.1 or older
5134 if (mrExport
.getSaneDefaultVersion() >= SvtSaveOptions::ODFSVER_012
)
5136 if( !bIsEmptyPresObj
)
5138 uno::Reference
< container::XNamed
> xTemplate( xPropSet
->getPropertyValue("TableTemplate"), uno::UNO_QUERY
);
5139 if( xTemplate
.is() )
5141 const OUString
sTemplate( xTemplate
->getName() );
5142 if( !sTemplate
.isEmpty() )
5144 mrExport
.AddAttribute(XML_NAMESPACE_TABLE
, XML_TEMPLATE_NAME
, sTemplate
);
5146 for( const XMLPropertyMapEntry
* pEntry
= &aXMLTableShapeAttributes
[0]; !pEntry
->IsEnd(); pEntry
++ )
5151 xPropSet
->getPropertyValue( pEntry
->getApiName() ) >>= bBool
;
5153 mrExport
.AddAttribute(pEntry
->mnNameSpace
, pEntry
->meXMLName
, XML_TRUE
);
5155 catch( uno::Exception
& )
5157 DBG_UNHANDLED_EXCEPTION("xmloff.draw");
5163 uno::Reference
< table::XColumnRowRange
> xRange( xPropSet
->getPropertyValue( gsModel
), uno::UNO_QUERY_THROW
);
5164 GetShapeTableExport()->exportTable( xRange
);
5168 if( !bIsEmptyPresObj
)
5170 uno::Reference
< graphic::XGraphic
> xGraphic( xPropSet
->getPropertyValue("ReplacementGraphic"), uno::UNO_QUERY
);
5171 ExportGraphicPreview(xGraphic
, mrExport
, u
"TablePreview", u
".svm", "image/x-vclgraphic");
5174 ImpExportEvents( xShape
);
5175 ImpExportGluePoints( xShape
);
5176 ImpExportDescription( xShape
); // #i68101#
5178 catch( uno::Exception
const & )
5180 DBG_UNHANDLED_EXCEPTION("xmloff.draw");
5184 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */