bump product version to 5.0.4.1
[LibreOffice.git] / xmloff / source / draw / shapeexport.cxx
blob96dfd640fb201568b10a303add3e4daf3874cf85
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
20 #include <basegfx/matrix/b2dhommatrix.hxx>
21 #include <basegfx/matrix/b2dhommatrixtools.hxx>
22 #include <basegfx/matrix/b3dhommatrix.hxx>
23 #include <basegfx/point/b2dpoint.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/chart/XChartDocument.hpp>
35 #include <com/sun/star/container/XChild.hpp>
36 #include <com/sun/star/container/XEnumerationAccess.hpp>
37 #include <com/sun/star/container/XIdentifierAccess.hpp>
38 #include <com/sun/star/container/XIdentifierContainer.hpp>
39 #include <com/sun/star/container/XNamed.hpp>
40 #include <com/sun/star/document/XEventsSupplier.hpp>
41 #include <com/sun/star/drawing/Alignment.hpp>
42 #include <com/sun/star/drawing/CameraGeometry.hpp>
43 #include <com/sun/star/drawing/CircleKind.hpp>
44 #include <com/sun/star/drawing/ConnectorType.hpp>
45 #include <com/sun/star/drawing/Direction3D.hpp>
46 #include <com/sun/star/drawing/DoubleSequence.hpp>
47 #include <com/sun/star/drawing/EscapeDirection.hpp>
48 #include <com/sun/star/drawing/EnhancedCustomShapeAdjustmentValue.hpp>
49 #include <com/sun/star/drawing/EnhancedCustomShapeGluePointType.hpp>
50 #include <com/sun/star/drawing/EnhancedCustomShapeParameterPair.hpp>
51 #include <com/sun/star/drawing/EnhancedCustomShapeParameterType.hpp>
52 #include <com/sun/star/drawing/EnhancedCustomShapeSegment.hpp>
53 #include <com/sun/star/drawing/EnhancedCustomShapeSegmentCommand.hpp>
54 #include <com/sun/star/drawing/EnhancedCustomShapeTextFrame.hpp>
55 #include <com/sun/star/drawing/EnhancedCustomShapeTextPathMode.hpp>
56 #include <com/sun/star/drawing/GluePoint2.hpp>
57 #include <com/sun/star/drawing/HomogenMatrix.hpp>
58 #include <com/sun/star/drawing/HomogenMatrix3.hpp>
59 #include <com/sun/star/drawing/PolyPolygonBezierCoords.hpp>
60 #include <com/sun/star/drawing/PolyPolygonShape3D.hpp>
61 #include <com/sun/star/drawing/Position3D.hpp>
62 #include <com/sun/star/drawing/ProjectionMode.hpp>
63 #include <com/sun/star/drawing/ShadeMode.hpp>
64 #include <com/sun/star/drawing/XControlShape.hpp>
65 #include <com/sun/star/drawing/XCustomShapeEngine.hpp>
66 #include <com/sun/star/drawing/XGluePointsSupplier.hpp>
67 #include <com/sun/star/embed/ElementModes.hpp>
68 #include <com/sun/star/embed/XTransactedObject.hpp>
69 #include <com/sun/star/graphic/XGraphic.hpp>
70 #include <com/sun/star/graphic/GraphicProvider.hpp>
71 #include <com/sun/star/graphic/XGraphicProvider.hpp>
72 #include <com/sun/star/io/XSeekableInputStream.hpp>
73 #include <com/sun/star/lang/ServiceNotRegisteredException.hpp>
74 #include <com/sun/star/lang/XMultiServiceFactory.hpp>
75 #include <com/sun/star/media/ZoomLevel.hpp>
76 #include <com/sun/star/presentation/AnimationSpeed.hpp>
77 #include <com/sun/star/presentation/ClickAction.hpp>
78 #include <com/sun/star/style/XStyle.hpp>
79 #include <com/sun/star/style/XStyleFamiliesSupplier.hpp>
80 #include <com/sun/star/table/XColumnRowRange.hpp>
81 #include <com/sun/star/text/XText.hpp>
82 #include <com/sun/star/document/XStorageBasedDocument.hpp>
84 #include <comphelper/classids.hxx>
85 #include <comphelper/processfactory.hxx>
86 #include <comphelper/storagehelper.hxx>
88 #include <rtl/math.hxx>
89 #include <rtl/ustrbuf.hxx>
91 #include <sax/tools/converter.hxx>
93 #include <tools/debug.hxx>
94 #include <tools/globname.hxx>
95 #include <tools/helpers.hxx>
96 #include <tools/urlobj.hxx>
98 #include <xmloff/contextid.hxx>
99 #include <xmloff/families.hxx>
100 #include <xmloff/nmspmap.hxx>
101 #include <xmloff/shapeexport.hxx>
102 #include <xmloff/unointerfacetouniqueidentifiermapper.hxx>
103 #include <xmloff/xmlexp.hxx>
104 #include <xmloff/xmlnmspe.hxx>
105 #include <xmloff/xmltoken.hxx>
106 #include <xmloff/xmluconv.hxx>
108 #include "anim.hxx"
109 #include "EnhancedCustomShapeToken.hxx"
110 #include "PropertySetMerger.hxx"
111 #include "sdpropls.hxx"
112 #include "sdxmlexp_impl.hxx"
113 #include "xexptran.hxx"
114 #include "XMLBase64Export.hxx"
115 #include "XMLImageMapExport.hxx"
116 #include <boost/scoped_ptr.hpp>
118 #include <config_features.h>
120 using namespace ::com::sun::star;
121 using namespace ::xmloff::EnhancedCustomShapeToken;
122 using namespace ::xmloff::token;
124 namespace {
126 bool supportsText(XmlShapeType eShapeType)
128 return eShapeType != XmlShapeTypePresChartShape &&
129 eShapeType != XmlShapeTypePresOLE2Shape &&
130 eShapeType != XmlShapeTypeDrawSheetShape &&
131 eShapeType != XmlShapeTypePresSheetShape &&
132 eShapeType != XmlShapeTypeDraw3DSceneObject &&
133 eShapeType != XmlShapeTypeDraw3DCubeObject &&
134 eShapeType != XmlShapeTypeDraw3DSphereObject &&
135 eShapeType != XmlShapeTypeDraw3DLatheObject &&
136 eShapeType != XmlShapeTypeDraw3DExtrudeObject &&
137 eShapeType != XmlShapeTypeDrawPageShape &&
138 eShapeType != XmlShapeTypePresPageShape &&
139 eShapeType != XmlShapeTypeDrawGroupShape;
145 XMLShapeExport::XMLShapeExport(SvXMLExport& rExp,
146 SvXMLExportPropertyMapper *pExtMapper )
147 : mrExport( rExp ),
148 maShapesInfos(),
149 maCurrentShapesIter(maShapesInfos.end()),
150 mbExportLayer( false ),
151 // #88546# init to sal_False
152 mbHandleProgressBar( false ),
153 msZIndex( "ZOrder" ),
154 msPrintable( "Printable" ),
155 msVisible( "Visible" ),
156 msEmptyPres( "IsEmptyPresentationObject" ),
157 msModel( "Model" ),
158 msStartShape( "StartShape" ),
159 msEndShape( "EndShape" ),
160 msOnClick( "OnClick" ),
161 msEventType( "EventType" ),
162 msPresentation( "Presentation" ),
163 msMacroName( "MacroName" ),
164 msScript( "Script" ),
165 msLibrary( "Library" ),
166 msClickAction( "ClickAction" ),
167 msBookmark( "Bookmark" ),
168 msEffect( "Effect" ),
169 msPlayFull( "PlayFull" ),
170 msVerb( "Verb" ),
171 msSoundURL( "SoundURL" ),
172 msSpeed( "Speed" ),
173 msStarBasic( "StarBasic" )
175 // construct PropertyHandlerFactory
176 mxSdPropHdlFactory = new XMLSdPropHdlFactory( mrExport.GetModel(), rExp );
177 // construct PropertySetMapper
178 mxPropertySetMapper = CreateShapePropMapper( mrExport );
179 if( pExtMapper )
181 rtl::Reference < SvXMLExportPropertyMapper > xExtMapper( pExtMapper );
182 mxPropertySetMapper->ChainExportMapper( xExtMapper );
186 // chain text attributes
187 xPropertySetMapper->ChainExportMapper(XMLTextParagraphExport::CreateParaExtPropMapper(rExp));
190 mrExport.GetAutoStylePool()->AddFamily(
191 XML_STYLE_FAMILY_SD_GRAPHICS_ID,
192 OUString(XML_STYLE_FAMILY_SD_GRAPHICS_NAME),
193 GetPropertySetMapper(),
194 OUString(XML_STYLE_FAMILY_SD_GRAPHICS_PREFIX));
195 mrExport.GetAutoStylePool()->AddFamily(
196 XML_STYLE_FAMILY_SD_PRESENTATION_ID,
197 OUString(XML_STYLE_FAMILY_SD_PRESENTATION_NAME),
198 GetPropertySetMapper(),
199 OUString(XML_STYLE_FAMILY_SD_PRESENTATION_PREFIX));
201 maCurrentInfo = maShapeInfos.end();
203 // create table export helper and let him add his families in time
204 GetShapeTableExport();
207 XMLShapeExport::~XMLShapeExport()
211 // sj: replacing CustomShapes with standard objects that are also supported in OpenOffice.org format
212 uno::Reference< drawing::XShape > XMLShapeExport::checkForCustomShapeReplacement( const uno::Reference< drawing::XShape >& xShape )
214 uno::Reference< drawing::XShape > xCustomShapeReplacement;
216 if( !( GetExport().getExportFlags() & SvXMLExportFlags::OASIS ) )
218 OUString aType( xShape->getShapeType() );
219 if( aType == "com.sun.star.drawing.CustomShape" )
221 uno::Reference< beans::XPropertySet > xSet( xShape, uno::UNO_QUERY );
222 if( xSet.is() )
224 OUString aEngine;
225 xSet->getPropertyValue("CustomShapeEngine") >>= aEngine;
226 if ( aEngine.isEmpty() )
228 aEngine = "com.sun.star.drawing.EnhancedCustomShapeEngine";
230 uno::Reference< uno::XComponentContext > xContext( ::comphelper::getProcessComponentContext() );
232 if ( !aEngine.isEmpty() )
234 uno::Sequence< uno::Any > aArgument( 1 );
235 uno::Sequence< beans::PropertyValue > aPropValues( 2 );
236 aPropValues[ 0 ].Name = "CustomShape";
237 aPropValues[ 0 ].Value <<= xShape;
238 bool bForceGroupWithText = true;
239 aPropValues[ 1 ].Name = "ForceGroupWithText";
240 aPropValues[ 1 ].Value <<= bForceGroupWithText;
241 aArgument[ 0 ] <<= aPropValues;
242 uno::Reference< uno::XInterface > xInterface(
243 xContext->getServiceManager()->createInstanceWithArgumentsAndContext(aEngine, aArgument, xContext) );
244 if ( xInterface.is() )
246 uno::Reference< drawing::XCustomShapeEngine > xCustomShapeEngine(
247 uno::Reference< drawing::XCustomShapeEngine >( xInterface, uno::UNO_QUERY ) );
248 if ( xCustomShapeEngine.is() )
249 xCustomShapeReplacement = xCustomShapeEngine->render();
255 return xCustomShapeReplacement;
258 // This method collects all automatic styles for the given XShape
259 void XMLShapeExport::collectShapeAutoStyles(const uno::Reference< drawing::XShape >& xShape )
261 if( maCurrentShapesIter == maShapesInfos.end() )
263 OSL_FAIL( "XMLShapeExport::collectShapeAutoStyles(): no call to seekShapes()!" );
264 return;
266 sal_Int32 nZIndex = 0;
267 uno::Reference< beans::XPropertySet > xPropSet(xShape, uno::UNO_QUERY);
268 if( xPropSet.is() )
269 xPropSet->getPropertyValue(msZIndex) >>= nZIndex;
271 ImplXMLShapeExportInfoVector& aShapeInfoVector = (*maCurrentShapesIter).second;
273 if( (sal_Int32)aShapeInfoVector.size() <= nZIndex )
275 OSL_FAIL( "XMLShapeExport::collectShapeAutoStyles(): no shape info allocated for a given shape" );
276 return;
279 ImplXMLShapeExportInfo& aShapeInfo = aShapeInfoVector[nZIndex];
281 uno::Reference< drawing::XShape > xCustomShapeReplacement = checkForCustomShapeReplacement( xShape );
282 if ( xCustomShapeReplacement.is() )
283 aShapeInfo.xCustomShapeReplacement = xCustomShapeReplacement;
285 // first compute the shapes type
286 ImpCalcShapeType(xShape, aShapeInfo.meShapeType);
288 // #i118485# enabled XmlShapeTypeDrawChartShape and XmlShapeTypeDrawOLE2Shape
289 // to have text
290 const bool bObjSupportsText =
291 supportsText(aShapeInfo.meShapeType);
293 const bool bObjSupportsStyle =
294 aShapeInfo.meShapeType != XmlShapeTypeDrawGroupShape;
296 bool bIsEmptyPresObj = false;
298 if ( aShapeInfo.xCustomShapeReplacement.is() )
299 xPropSet.clear();
301 // prep text styles
302 if( xPropSet.is() && bObjSupportsText )
304 uno::Reference< text::XText > xText(xShape, uno::UNO_QUERY);
305 if(xText.is() && !xText->getString().isEmpty())
307 uno::Reference< beans::XPropertySetInfo > xPropSetInfo( xPropSet->getPropertySetInfo() );
309 if( xPropSetInfo.is() && xPropSetInfo->hasPropertyByName(msEmptyPres) )
311 uno::Any aAny = xPropSet->getPropertyValue(msEmptyPres);
312 aAny >>= bIsEmptyPresObj;
315 if(!bIsEmptyPresObj)
317 GetExport().GetTextParagraphExport()->collectTextAutoStyles( xText );
322 // compute the shape parent style
323 if( xPropSet.is() )
325 uno::Reference< beans::XPropertySetInfo > xPropertySetInfo( xPropSet->getPropertySetInfo() );
327 OUString aParentName;
328 uno::Reference< style::XStyle > xStyle;
330 if( bObjSupportsStyle )
332 if( xPropertySetInfo.is() && xPropertySetInfo->hasPropertyByName("Style") )
333 xPropSet->getPropertyValue("Style") >>= xStyle;
335 if(xStyle.is())
337 // get family ID
338 uno::Reference< beans::XPropertySet > xStylePropSet(xStyle, uno::UNO_QUERY);
339 DBG_ASSERT( xStylePropSet.is(), "style without a XPropertySet?" );
342 if(xStylePropSet.is())
344 OUString aFamilyName;
345 xStylePropSet->getPropertyValue("Family") >>= aFamilyName;
346 if( !aFamilyName.isEmpty() && aFamilyName != "graphics" )
347 aShapeInfo.mnFamily = XML_STYLE_FAMILY_SD_PRESENTATION_ID;
350 catch(const beans::UnknownPropertyException&)
352 // Ignored.
353 DBG_ASSERT(false,
354 "XMLShapeExport::collectShapeAutoStyles: style has no 'Family' property");
357 // get parent-style name
358 if(XML_STYLE_FAMILY_SD_PRESENTATION_ID == aShapeInfo.mnFamily)
360 aParentName = msPresentationStylePrefix;
363 aParentName += xStyle->getName();
367 if (aParentName.isEmpty() && xPropertySetInfo->hasPropertyByName("TextBox") && xPropSet->getPropertyValue("TextBox").hasValue() && xPropSet->getPropertyValue("TextBox").get<bool>())
369 // Shapes with a Writer TextBox always have a parent style.
370 // If there would be none, then just assign the first available.
371 uno::Reference<style::XStyleFamiliesSupplier> xStyleFamiliesSupplier(GetExport().GetModel(), uno::UNO_QUERY);
372 uno::Reference<container::XNameAccess> xStyleFamilies = xStyleFamiliesSupplier->getStyleFamilies();
373 uno::Reference<container::XNameAccess> xFrameStyles = xStyleFamilies->getByName("FrameStyles").get< uno::Reference<container::XNameAccess> >();
374 uno::Sequence<OUString> aFrameStyles = xFrameStyles->getElementNames();
375 if (aFrameStyles.hasElements())
376 aParentName = aFrameStyles[0];
379 // filter propset
380 std::vector< XMLPropertyState > xPropStates;
382 sal_Int32 nCount = 0;
383 if( (!bIsEmptyPresObj || (aShapeInfo.meShapeType != XmlShapeTypePresPageShape)) )
385 xPropStates = GetPropertySetMapper()->Filter( xPropSet );
387 if (XmlShapeTypeDrawControlShape == aShapeInfo.meShapeType)
389 // for control shapes, we additionally need the number format style (if any)
390 uno::Reference< drawing::XControlShape > xControl(xShape, uno::UNO_QUERY);
391 DBG_ASSERT(xControl.is(), "XMLShapeExport::collectShapeAutoStyles: ShapeType control, but no XControlShape!");
392 if (xControl.is())
394 uno::Reference< beans::XPropertySet > xControlModel(xControl->getControl(), uno::UNO_QUERY);
395 DBG_ASSERT(xControlModel.is(), "XMLShapeExport::collectShapeAutoStyles: no control model on the control shape!");
397 OUString sNumberStyle = mrExport.GetFormExport()->getControlNumberStyle(xControlModel);
398 if (!sNumberStyle.isEmpty())
400 sal_Int32 nIndex = GetPropertySetMapper()->getPropertySetMapper()->FindEntryIndex(CTF_SD_CONTROL_SHAPE_DATA_STYLE);
401 // TODO : this retrieval of the index could be moved into the ctor, holding the index
402 // as member, thus saving time.
403 DBG_ASSERT(-1 != nIndex, "XMLShapeExport::collectShapeAutoStyles: could not obtain the index for our context id!");
405 XMLPropertyState aNewState(nIndex, uno::makeAny(sNumberStyle));
406 xPropStates.push_back(aNewState);
411 std::vector< XMLPropertyState >::iterator aIter = xPropStates.begin();
412 std::vector< XMLPropertyState >::iterator aEnd = xPropStates.end();
413 while( aIter != aEnd )
415 if( aIter->mnIndex != -1 )
416 nCount++;
417 ++aIter;
421 if(nCount == 0)
423 // no hard attributes, use parent style name for export
424 aShapeInfo.msStyleName = aParentName;
426 else
428 // there are filtered properties -> hard attributes
429 // try to find this style in AutoStylePool
430 aShapeInfo.msStyleName = mrExport.GetAutoStylePool()->Find(aShapeInfo.mnFamily, aParentName, xPropStates);
432 if(aShapeInfo.msStyleName.isEmpty())
434 // Style did not exist, add it to AutoStalePool
435 aShapeInfo.msStyleName = mrExport.GetAutoStylePool()->Add(aShapeInfo.mnFamily, aParentName, xPropStates);
439 // optionaly generate auto style for text attributes
440 if( (!bIsEmptyPresObj || (aShapeInfo.meShapeType != XmlShapeTypePresPageShape)) && bObjSupportsText )
442 xPropStates = GetExport().GetTextParagraphExport()->GetParagraphPropertyMapper()->Filter( xPropSet );
444 // yet more additionally, we need to care for the ParaAdjust property
445 if ( XmlShapeTypeDrawControlShape == aShapeInfo.meShapeType )
447 uno::Reference< beans::XPropertySetInfo > xPropSetInfo( xPropSet->getPropertySetInfo() );
448 uno::Reference< beans::XPropertyState > xPropState( xPropSet, uno::UNO_QUERY );
449 if ( xPropSetInfo.is() && xPropState.is() )
451 // this is because:
452 // * if controls shapes have a ParaAdjust property, then this is the Align property of the control model
453 // * control models are allowed to have an Align of "void"
454 // * the Default for control model's Align is TextAlign_LEFT
455 // * defaults for style properties are not written, but we need to write the "left",
456 // because we need to distiguish this "left" from the case where not align attribute
457 // is present which means "void"
458 if ( xPropSetInfo->hasPropertyByName( "ParaAdjust" )
459 && ( beans::PropertyState_DEFAULT_VALUE == xPropState->getPropertyState( "ParaAdjust" ) )
462 sal_Int32 nIndex = GetExport().GetTextParagraphExport()->GetParagraphPropertyMapper()->getPropertySetMapper()->FindEntryIndex( CTF_SD_SHAPE_PARA_ADJUST );
463 // TODO : this retrieval of the index should be moved into the ctor, holding the index
464 // as member, thus saving time.
465 DBG_ASSERT(-1 != nIndex, "XMLShapeExport::collectShapeAutoStyles: could not obtain the index for the ParaAdjust context id!");
467 uno::Any aParaAdjustValue = xPropSet->getPropertyValue( "ParaAdjust" );
468 XMLPropertyState aAlignDefaultState( nIndex, aParaAdjustValue );
470 xPropStates.push_back( aAlignDefaultState );
475 nCount = 0;
476 std::vector< XMLPropertyState >::iterator aIter = xPropStates.begin();
477 std::vector< XMLPropertyState >::iterator aEnd = xPropStates.end();
478 while( aIter != aEnd )
480 if( aIter->mnIndex != -1 )
481 nCount++;
482 ++aIter;
485 if( nCount )
487 const OUString aEmpty;
488 aShapeInfo.msTextStyleName = mrExport.GetAutoStylePool()->Find( XML_STYLE_FAMILY_TEXT_PARAGRAPH, aEmpty, xPropStates );
489 if(aShapeInfo.msTextStyleName.isEmpty())
491 // Style did not exist, add it to AutoStalePool
492 aShapeInfo.msTextStyleName = mrExport.GetAutoStylePool()->Add(XML_STYLE_FAMILY_TEXT_PARAGRAPH, aEmpty, xPropStates);
498 // prepare animation information if needed
499 if( mxAnimationsExporter.is() )
500 mxAnimationsExporter->prepare( xShape, mrExport );
502 // check for special shapes
504 switch( aShapeInfo.meShapeType )
506 case XmlShapeTypeDrawConnectorShape:
508 uno::Reference< uno::XInterface > xConnection;
510 // create shape ids for export later
511 xPropSet->getPropertyValue( msStartShape ) >>= xConnection;
512 if( xConnection.is() )
513 mrExport.getInterfaceToIdentifierMapper().registerReference( xConnection );
515 xPropSet->getPropertyValue( msEndShape ) >>= xConnection;
516 if( xConnection.is() )
517 mrExport.getInterfaceToIdentifierMapper().registerReference( xConnection );
518 break;
520 case XmlShapeTypePresTableShape:
521 case XmlShapeTypeDrawTableShape:
525 uno::Reference< table::XColumnRowRange > xRange( xPropSet->getPropertyValue( msModel ), uno::UNO_QUERY_THROW );
526 GetShapeTableExport()->collectTableAutoStyles( xRange );
528 catch(const uno::Exception&)
530 OSL_FAIL( "XMLShapeExport::collectShapeAutoStyles(): exception caught while collection auto styles for a table!" );
532 break;
534 default:
535 break;
538 maShapeInfos.push_back( aShapeInfo );
539 maCurrentInfo = maShapeInfos.begin();
541 // check for shape collections (group shape or 3d scene)
542 // and collect contained shapes style infos
543 const uno::Reference< drawing::XShape >& xCollection = aShapeInfo.xCustomShapeReplacement.is()
544 ? aShapeInfo.xCustomShapeReplacement : xShape;
546 uno::Reference< drawing::XShapes > xShapes( xCollection, uno::UNO_QUERY );
547 if( xShapes.is() )
549 collectShapesAutoStyles( xShapes );
554 namespace
556 class NewTextListsHelper
558 public:
559 NewTextListsHelper( SvXMLExport& rExp )
560 : mrExport( rExp )
562 mrExport.GetTextParagraphExport()->PushNewTextListsHelper();
565 ~NewTextListsHelper()
567 mrExport.GetTextParagraphExport()->PopTextListsHelper();
570 private:
571 SvXMLExport& mrExport;
574 // This method exports the given XShape
575 void XMLShapeExport::exportShape(const uno::Reference< drawing::XShape >& xShape,
576 XMLShapeExportFlags nFeatures /* = SEF_DEFAULT */,
577 com::sun::star::awt::Point* pRefPoint /* = NULL */,
578 SvXMLAttributeList* pAttrList /* = NULL */ )
580 SAL_INFO("xmloff", xShape->getShapeType());
581 if( maCurrentShapesIter == maShapesInfos.end() )
583 SAL_WARN( "xmloff", "XMLShapeExport::exportShape(): no auto styles where collected before export" );
584 return;
586 sal_Int32 nZIndex = 0;
587 uno::Reference< beans::XPropertySet > xSet( xShape, uno::UNO_QUERY );
589 boost::scoped_ptr< SvXMLElementExport > mpHyperlinkElement;
591 // export hyperlinks with <a><shape/></a>. Currently only in draw since draw
592 // does not support document events
593 if( xSet.is() && (GetExport().GetModelType() == SvtModuleOptions::EFactory::DRAW) ) try
595 presentation::ClickAction eAction = presentation::ClickAction_NONE;
596 xSet->getPropertyValue("OnClick") >>= eAction;
598 if( (eAction == presentation::ClickAction_DOCUMENT) ||
599 (eAction == presentation::ClickAction_BOOKMARK) )
601 OUString sURL;
602 xSet->getPropertyValue(msBookmark) >>= sURL;
604 if( !sURL.isEmpty() )
606 mrExport.AddAttribute( XML_NAMESPACE_XLINK, XML_HREF, sURL );
607 mrExport.AddAttribute( XML_NAMESPACE_XLINK, XML_TYPE, XML_SIMPLE );
608 mrExport.AddAttribute( XML_NAMESPACE_XLINK, XML_SHOW, XML_EMBED );
609 mpHyperlinkElement.reset( new SvXMLElementExport(mrExport, XML_NAMESPACE_DRAW, XML_A, true, true) );
613 catch(const uno::Exception&)
615 SAL_WARN("xmloff", "XMLShapeExport::exportShape(): exception during hyperlink export");
618 if( xSet.is() )
619 xSet->getPropertyValue(msZIndex) >>= nZIndex;
621 ImplXMLShapeExportInfoVector& aShapeInfoVector = (*maCurrentShapesIter).second;
623 if( (sal_Int32)aShapeInfoVector.size() <= nZIndex )
625 SAL_WARN( "xmloff", "XMLShapeExport::exportShape(): no shape info collected for a given shape" );
626 return;
629 NewTextListsHelper aNewTextListsHelper( mrExport );
631 const ImplXMLShapeExportInfo& aShapeInfo = aShapeInfoVector[nZIndex];
633 #ifdef DBG_UTIL
634 // check if this is the correct ShapesInfo
635 uno::Reference< container::XChild > xChild( xShape, uno::UNO_QUERY );
636 if( xChild.is() )
638 uno::Reference< drawing::XShapes > xParent( xChild->getParent(), uno::UNO_QUERY );
639 DBG_ASSERT( xParent.is() && xParent.get() == (*maCurrentShapesIter).first.get(), "XMLShapeExport::exportShape(): Wrong call to XMLShapeExport::seekShapes()" );
642 // first compute the shapes type
644 XmlShapeType eShapeType(XmlShapeTypeNotYetSet);
645 ImpCalcShapeType(xShape, eShapeType);
647 SAL_WARN_IF( eShapeType != aShapeInfo.meShapeType, "xmloff", "exportShape callings do not correspond to collectShapeAutoStyles calls!: " << xShape->getShapeType() );
649 #endif
651 // collect animation information if needed
652 if( mxAnimationsExporter.is() )
653 mxAnimationsExporter->collect( xShape, mrExport );
655 /* Export shapes name if he has one (#i51726#)
656 Export of the shape name for text documents only if the OpenDocument
657 file format is written - exceptions are group shapes.
658 Note: Writer documents in OpenOffice.org file format doesn't contain
659 any names for shapes, except for group shapes.
662 if ( ( GetExport().GetModelType() != SvtModuleOptions::EFactory::WRITER &&
663 GetExport().GetModelType() != SvtModuleOptions::EFactory::WRITERWEB &&
664 GetExport().GetModelType() != SvtModuleOptions::EFactory::WRITERGLOBAL ) ||
665 !( GetExport().getExportFlags() & SvXMLExportFlags::OASIS ) ||
666 aShapeInfo.meShapeType == XmlShapeTypeDrawGroupShape ||
667 ( aShapeInfo.meShapeType == XmlShapeTypeDrawCustomShape &&
668 aShapeInfo.xCustomShapeReplacement.is() ) )
670 uno::Reference< container::XNamed > xNamed( xShape, uno::UNO_QUERY );
671 if( xNamed.is() )
673 const OUString aName( xNamed->getName() );
674 if( !aName.isEmpty() )
675 mrExport.AddAttribute(XML_NAMESPACE_DRAW, XML_NAME, aName );
680 // export style name
681 if( !aShapeInfo.msStyleName.isEmpty() )
683 if(XML_STYLE_FAMILY_SD_GRAPHICS_ID == aShapeInfo.mnFamily)
684 mrExport.AddAttribute(XML_NAMESPACE_DRAW, XML_STYLE_NAME, mrExport.EncodeStyleName( aShapeInfo.msStyleName) );
685 else
686 mrExport.AddAttribute(XML_NAMESPACE_PRESENTATION, XML_STYLE_NAME, mrExport.EncodeStyleName( aShapeInfo.msStyleName) );
689 // export text style name
690 if( !aShapeInfo.msTextStyleName.isEmpty() )
692 mrExport.AddAttribute(XML_NAMESPACE_DRAW, XML_TEXT_STYLE_NAME, aShapeInfo.msTextStyleName );
695 // export shapes id if needed
697 uno::Reference< uno::XInterface > xRef( xShape, uno::UNO_QUERY );
698 const OUString& rShapeId = mrExport.getInterfaceToIdentifierMapper().getIdentifier( xRef );
699 if( !rShapeId.isEmpty() )
701 mrExport.AddAttributeIdLegacy(XML_NAMESPACE_DRAW, rShapeId);
705 // export layer information
706 if( IsLayerExportEnabled() )
708 // check for group or scene shape and not export layer if this is one
709 uno::Reference< drawing::XShapes > xShapes( xShape, uno::UNO_QUERY );
710 if( !xShapes.is() )
714 uno::Reference< beans::XPropertySet > xProps( xShape, uno::UNO_QUERY );
715 OUString aLayerName;
716 xProps->getPropertyValue("LayerName") >>= aLayerName;
717 mrExport.AddAttribute(XML_NAMESPACE_DRAW, XML_LAYER, aLayerName );
720 catch(const uno::Exception&)
722 OSL_FAIL( "could not export layer name for shape!" );
727 // export draw:display (do not export in ODF 1.2 or older)
728 if( xSet.is() && ( mrExport.getDefaultVersion() > SvtSaveOptions::ODFVER_012 ) )
730 if( aShapeInfo.meShapeType != XmlShapeTypeDrawPageShape && aShapeInfo.meShapeType != XmlShapeTypePresPageShape &&
731 aShapeInfo.meShapeType != XmlShapeTypeHandoutShape && aShapeInfo.meShapeType != XmlShapeTypeDrawChartShape )
735 bool bVisible = true;
736 bool bPrintable = true;
738 xSet->getPropertyValue(msVisible) >>= bVisible;
739 xSet->getPropertyValue(msPrintable) >>= bPrintable;
741 XMLTokenEnum eDisplayToken = XML_TOKEN_INVALID;
742 const unsigned short nDisplay = (bVisible ? 2 : 0) | (bPrintable ? 1 : 0);
743 switch( nDisplay )
745 case 0: eDisplayToken = XML_NONE; break;
746 case 1: eDisplayToken = XML_PRINTER; break;
747 case 2: eDisplayToken = XML_SCREEN; break;
748 // case 3: eDisplayToken = XML_ALWAYS break; this is the default
751 if( eDisplayToken != XML_TOKEN_INVALID )
752 mrExport.AddAttribute(XML_NAMESPACE_DRAW_EXT, XML_DISPLAY, eDisplayToken );
754 catch(const uno::Exception&)
756 OSL_FAIL( "XMLShapeExport::exportShape(), exception caught!" );
760 // #82003# test export count
761 // #91587# ALWAYS increment since now ALL to be exported shapes are counted.
762 if(mrExport.GetShapeExport()->IsHandleProgressBarEnabled())
764 mrExport.GetProgressBarHelper()->Increment();
767 onExport( xShape );
769 // export shape element
770 switch(aShapeInfo.meShapeType)
772 case XmlShapeTypeDrawRectangleShape:
774 ImpExportRectangleShape(xShape, aShapeInfo.meShapeType, nFeatures, pRefPoint );
775 break;
777 case XmlShapeTypeDrawEllipseShape:
779 ImpExportEllipseShape(xShape, aShapeInfo.meShapeType, nFeatures, pRefPoint );
780 break;
782 case XmlShapeTypeDrawLineShape:
784 ImpExportLineShape(xShape, aShapeInfo.meShapeType, nFeatures, pRefPoint );
785 break;
787 case XmlShapeTypeDrawPolyPolygonShape: // closed PolyPolygon
788 case XmlShapeTypeDrawPolyLineShape: // open PolyPolygon
789 case XmlShapeTypeDrawClosedBezierShape: // closed tools::PolyPolygon containing curves
790 case XmlShapeTypeDrawOpenBezierShape: // open tools::PolyPolygon containing curves
792 ImpExportPolygonShape(xShape, aShapeInfo.meShapeType, nFeatures, pRefPoint );
793 break;
796 case XmlShapeTypeDrawTextShape:
797 case XmlShapeTypePresTitleTextShape:
798 case XmlShapeTypePresOutlinerShape:
799 case XmlShapeTypePresSubtitleShape:
800 case XmlShapeTypePresNotesShape:
801 case XmlShapeTypePresHeaderShape:
802 case XmlShapeTypePresFooterShape:
803 case XmlShapeTypePresSlideNumberShape:
804 case XmlShapeTypePresDateTimeShape:
806 ImpExportTextBoxShape(xShape, aShapeInfo.meShapeType, nFeatures, pRefPoint );
807 break;
810 case XmlShapeTypeDrawGraphicObjectShape:
811 case XmlShapeTypePresGraphicObjectShape:
813 ImpExportGraphicObjectShape(xShape, aShapeInfo.meShapeType, nFeatures, pRefPoint );
814 break;
817 case XmlShapeTypeDrawChartShape:
818 case XmlShapeTypePresChartShape:
820 ImpExportChartShape(xShape, aShapeInfo.meShapeType, nFeatures, pRefPoint, pAttrList );
821 break;
824 case XmlShapeTypeDrawControlShape:
826 ImpExportControlShape(xShape, aShapeInfo.meShapeType, nFeatures, pRefPoint );
827 break;
830 case XmlShapeTypeDrawConnectorShape:
832 ImpExportConnectorShape(xShape, aShapeInfo.meShapeType, nFeatures, pRefPoint );
833 break;
836 case XmlShapeTypeDrawMeasureShape:
838 ImpExportMeasureShape(xShape, aShapeInfo.meShapeType, nFeatures, pRefPoint );
839 break;
842 case XmlShapeTypeDrawOLE2Shape:
843 case XmlShapeTypePresOLE2Shape:
844 case XmlShapeTypeDrawSheetShape:
845 case XmlShapeTypePresSheetShape:
847 ImpExportOLE2Shape(xShape, aShapeInfo.meShapeType, nFeatures, pRefPoint );
848 break;
851 case XmlShapeTypePresTableShape:
852 case XmlShapeTypeDrawTableShape:
854 ImpExportTableShape( xShape, aShapeInfo.meShapeType, nFeatures, pRefPoint );
855 break;
858 case XmlShapeTypeDrawPageShape:
859 case XmlShapeTypePresPageShape:
860 case XmlShapeTypeHandoutShape:
862 ImpExportPageShape(xShape, aShapeInfo.meShapeType, nFeatures, pRefPoint );
863 break;
866 case XmlShapeTypeDrawCaptionShape:
868 ImpExportCaptionShape(xShape, aShapeInfo.meShapeType, nFeatures, pRefPoint );
869 break;
872 case XmlShapeTypeDraw3DCubeObject:
873 case XmlShapeTypeDraw3DSphereObject:
874 case XmlShapeTypeDraw3DLatheObject:
875 case XmlShapeTypeDraw3DExtrudeObject:
877 ImpExport3DShape(xShape, aShapeInfo.meShapeType);
878 break;
881 case XmlShapeTypeDraw3DSceneObject:
883 ImpExport3DSceneShape( xShape, aShapeInfo.meShapeType, nFeatures, pRefPoint );
884 break;
887 case XmlShapeTypeDrawGroupShape:
889 // empty group
890 ImpExportGroupShape( xShape, aShapeInfo.meShapeType, nFeatures, pRefPoint );
891 break;
894 case XmlShapeTypeDrawFrameShape:
896 ImpExportFrameShape(xShape, aShapeInfo.meShapeType, nFeatures, pRefPoint );
897 break;
900 case XmlShapeTypeDrawAppletShape:
902 ImpExportAppletShape(xShape, aShapeInfo.meShapeType, nFeatures, pRefPoint );
903 break;
906 case XmlShapeTypeDrawPluginShape:
908 ImpExportPluginShape(xShape, aShapeInfo.meShapeType, nFeatures, pRefPoint );
909 break;
912 case XmlShapeTypeDrawCustomShape:
914 if ( aShapeInfo.xCustomShapeReplacement.is() )
915 ImpExportGroupShape( aShapeInfo.xCustomShapeReplacement, XmlShapeTypeDrawGroupShape, nFeatures, pRefPoint );
916 else
917 ImpExportCustomShape( xShape, aShapeInfo.meShapeType, nFeatures, pRefPoint );
918 break;
921 case XmlShapeTypePresMediaShape:
922 case XmlShapeTypeDrawMediaShape:
924 ImpExportMediaShape( xShape, aShapeInfo.meShapeType, nFeatures, pRefPoint );
925 break;
928 case XmlShapeTypePresOrgChartShape:
929 case XmlShapeTypeUnknown:
930 case XmlShapeTypeNotYetSet:
931 default:
933 // this should never happen and is an error
934 OSL_FAIL("XMLEXP: WriteShape: unknown or unexpected type of shape in export!");
935 break;
939 mpHyperlinkElement.reset();
941 // #97489# #97111#
942 // if there was an error and no element for the shape was exported
943 // we need to clear the attribute list or the attributes will be
944 // set on the next exported element, which can result in corrupt
945 // xml files due to duplicate attributes
947 mrExport.CheckAttrList(); // asserts in non pro if we have attributes left
948 mrExport.ClearAttrList(); // clears the attributes
951 // This method collects all automatic styles for the shapes inside the given XShapes collection
952 void XMLShapeExport::collectShapesAutoStyles( const uno::Reference < drawing::XShapes >& xShapes )
954 ShapesInfos::iterator aOldCurrentShapesIter = maCurrentShapesIter;
955 seekShapes( xShapes );
957 uno::Reference< drawing::XShape > xShape;
958 const sal_Int32 nShapeCount(xShapes->getCount());
959 for(sal_Int32 nShapeId = 0; nShapeId < nShapeCount; nShapeId++)
961 xShapes->getByIndex(nShapeId) >>= xShape;
962 SAL_WARN_IF( !xShape.is(), "xmloff", "Shape without a XShape?" );
963 if(!xShape.is())
964 continue;
966 collectShapeAutoStyles( xShape );
969 maCurrentShapesIter = aOldCurrentShapesIter;
972 // This method exports all XShape inside the given XShapes collection
973 void XMLShapeExport::exportShapes( const uno::Reference < drawing::XShapes >& xShapes, XMLShapeExportFlags nFeatures /* = SEF_DEFAULT */, awt::Point* pRefPoint /* = NULL */ )
975 ShapesInfos::iterator aOldCurrentShapesIter = maCurrentShapesIter;
976 seekShapes( xShapes );
978 uno::Reference< drawing::XShape > xShape;
979 const sal_Int32 nShapeCount(xShapes->getCount());
980 for(sal_Int32 nShapeId = 0; nShapeId < nShapeCount; nShapeId++)
982 xShapes->getByIndex(nShapeId) >>= xShape;
983 SAL_WARN_IF( !xShape.is(), "xmloff", "Shape without a XShape?" );
984 if(!xShape.is())
985 continue;
987 exportShape( xShape, nFeatures, pRefPoint );
990 maCurrentShapesIter = aOldCurrentShapesIter;
993 void XMLShapeExport::seekShapes( const uno::Reference< drawing::XShapes >& xShapes ) throw()
995 if( xShapes.is() )
997 maCurrentShapesIter = maShapesInfos.find( xShapes );
998 if( maCurrentShapesIter == maShapesInfos.end() )
1000 ImplXMLShapeExportInfoVector aNewInfoVector;
1001 aNewInfoVector.resize( (ShapesInfos::size_type) xShapes->getCount() );
1002 maShapesInfos[ xShapes ] = aNewInfoVector;
1004 maCurrentShapesIter = maShapesInfos.find( xShapes );
1006 DBG_ASSERT( maCurrentShapesIter != maShapesInfos.end(), "XMLShapeExport::seekShapes(): insert into stl::map failed" );
1009 DBG_ASSERT( (*maCurrentShapesIter).second.size() == (ShapesInfos::size_type)xShapes->getCount(), "XMLShapeExport::seekShapes(): XShapes size varied between calls" );
1012 else
1014 maCurrentShapesIter = maShapesInfos.end();
1018 void XMLShapeExport::exportAutoStyles()
1020 // export all autostyle infos
1022 // ...for graphic
1024 GetExport().GetAutoStylePool()->exportXML(
1025 XML_STYLE_FAMILY_SD_GRAPHICS_ID
1026 , GetExport().GetDocHandler(),
1027 GetExport().GetMM100UnitConverter(),
1028 GetExport().GetNamespaceMap()
1032 // ...for presentation
1034 GetExport().GetAutoStylePool()->exportXML(
1035 XML_STYLE_FAMILY_SD_PRESENTATION_ID
1036 , GetExport().GetDocHandler(),
1037 GetExport().GetMM100UnitConverter(),
1038 GetExport().GetNamespaceMap()
1042 if( mxShapeTableExport.is() )
1043 mxShapeTableExport->exportAutoStyles();
1046 /// returns the export property mapper for external chaining
1047 SvXMLExportPropertyMapper* XMLShapeExport::CreateShapePropMapper(
1048 SvXMLExport& rExport )
1050 rtl::Reference< XMLPropertyHandlerFactory > xFactory = new XMLSdPropHdlFactory( rExport.GetModel(), rExport );
1051 rtl::Reference < XMLPropertySetMapper > xMapper = new XMLShapePropertySetMapper( xFactory, true );
1052 rExport.GetTextParagraphExport(); // get or create text paragraph export
1053 SvXMLExportPropertyMapper* pResult =
1054 new XMLShapeExportPropertyMapper( xMapper, rExport );
1055 // chain text attributes
1056 return pResult;
1059 void XMLShapeExport::ImpCalcShapeType(const uno::Reference< drawing::XShape >& xShape,
1060 XmlShapeType& eShapeType)
1062 // set in every case, so init here
1063 eShapeType = XmlShapeTypeUnknown;
1065 uno::Reference< drawing::XShapeDescriptor > xShapeDescriptor(xShape, uno::UNO_QUERY);
1066 if(xShapeDescriptor.is())
1068 OUString aType(xShapeDescriptor->getShapeType());
1070 if(aType.match("com.sun.star."))
1072 if(aType.match("drawing.", 13))
1074 // drawing shapes
1075 if (aType.match("Rectangle", 21)) { eShapeType = XmlShapeTypeDrawRectangleShape; }
1077 // #i72177# Note: Correcting CustomShape, CustomShape->Custom, len from 9 (was wrong anyways) to 6.
1078 // As can be seen at the other compares, the appendix "Shape" is left out of the comparison.
1079 else if(aType.match("Custom", 21)) { eShapeType = XmlShapeTypeDrawCustomShape; }
1081 else if(aType.match("Ellipse", 21)) { eShapeType = XmlShapeTypeDrawEllipseShape; }
1082 else if(aType.match("Control", 21)) { eShapeType = XmlShapeTypeDrawControlShape; }
1083 else if(aType.match("Connector", 21)) { eShapeType = XmlShapeTypeDrawConnectorShape; }
1084 else if(aType.match("Measure", 21)) { eShapeType = XmlShapeTypeDrawMeasureShape; }
1085 else if(aType.match("Line", 21)) { eShapeType = XmlShapeTypeDrawLineShape; }
1087 // #i72177# Note: This covers two types by purpose, PolyPolygonShape and PolyPolygonPathShape
1088 else if(aType.match("PolyPolygon", 21)) { eShapeType = XmlShapeTypeDrawPolyPolygonShape; }
1090 // #i72177# Note: This covers two types by purpose, PolyLineShape and PolyLinePathShape
1091 else if(aType.match("PolyLine", 21)) { eShapeType = XmlShapeTypeDrawPolyLineShape; }
1093 else if(aType.match("OpenBezier", 21)) { eShapeType = XmlShapeTypeDrawOpenBezierShape; }
1094 else if(aType.match("ClosedBezier", 21)) { eShapeType = XmlShapeTypeDrawClosedBezierShape; }
1096 // #i72177# FreeHand (opened and closed) now supports the types OpenFreeHandShape and
1097 // ClosedFreeHandShape respectively. Represent them as bezier shapes
1098 else if(aType.match("OpenFreeHand", 21)) { eShapeType = XmlShapeTypeDrawOpenBezierShape; }
1099 else if(aType.match("ClosedFreeHand", 21)) { eShapeType = XmlShapeTypeDrawClosedBezierShape; }
1101 else if(aType.match("GraphicObject", 21)) { eShapeType = XmlShapeTypeDrawGraphicObjectShape; }
1102 else if(aType.match("Group", 21)) { eShapeType = XmlShapeTypeDrawGroupShape; }
1103 else if(aType.match("Text", 21)) { eShapeType = XmlShapeTypeDrawTextShape; }
1104 else if(aType.match("OLE2", 21))
1106 eShapeType = XmlShapeTypeDrawOLE2Shape;
1108 // get info about presentation shape
1109 uno::Reference <beans::XPropertySet> xPropSet(xShape, uno::UNO_QUERY);
1111 if(xPropSet.is())
1113 OUString sCLSID;
1114 if(xPropSet->getPropertyValue("CLSID") >>= sCLSID)
1116 if (sCLSID.equals(mrExport.GetChartExport()->getChartCLSID()) ||
1117 sCLSID.equals(OUString( SvGlobalName( SO3_RPTCH_CLASSID ).GetHexName())))
1119 eShapeType = XmlShapeTypeDrawChartShape;
1121 else if (sCLSID.equals(OUString( SvGlobalName( SO3_SC_CLASSID ).GetHexName())))
1123 eShapeType = XmlShapeTypeDrawSheetShape;
1125 else
1127 // general OLE2 Object
1132 else if(aType.match("Page", 21)) { eShapeType = XmlShapeTypeDrawPageShape; }
1133 else if(aType.match("Frame", 21)) { eShapeType = XmlShapeTypeDrawFrameShape; }
1134 else if(aType.match("Caption", 21)) { eShapeType = XmlShapeTypeDrawCaptionShape; }
1135 else if(aType.match("Plugin", 21)) { eShapeType = XmlShapeTypeDrawPluginShape; }
1136 else if(aType.match("Applet", 21)) { eShapeType = XmlShapeTypeDrawAppletShape; }
1137 else if(aType.match("MediaShape", 21)) { eShapeType = XmlShapeTypeDrawMediaShape; }
1138 else if(aType.match("TableShape", 21)) { eShapeType = XmlShapeTypeDrawTableShape; }
1140 // 3D shapes
1141 else if(aType.match("Scene", 21 + 7)) { eShapeType = XmlShapeTypeDraw3DSceneObject; }
1142 else if(aType.match("Cube", 21 + 7)) { eShapeType = XmlShapeTypeDraw3DCubeObject; }
1143 else if(aType.match("Sphere", 21 + 7)) { eShapeType = XmlShapeTypeDraw3DSphereObject; }
1144 else if(aType.match("Lathe", 21 + 7)) { eShapeType = XmlShapeTypeDraw3DLatheObject; }
1145 else if(aType.match("Extrude", 21 + 7)) { eShapeType = XmlShapeTypeDraw3DExtrudeObject; }
1147 else if(aType.match("presentation.", 13))
1149 // presentation shapes
1150 if (aType.match("TitleText", 26)) { eShapeType = XmlShapeTypePresTitleTextShape; }
1151 else if(aType.match("Outliner", 26)) { eShapeType = XmlShapeTypePresOutlinerShape; }
1152 else if(aType.match("Subtitle", 26)) { eShapeType = XmlShapeTypePresSubtitleShape; }
1153 else if(aType.match("GraphicObject", 26)) { eShapeType = XmlShapeTypePresGraphicObjectShape; }
1154 else if(aType.match("Page", 26)) { eShapeType = XmlShapeTypePresPageShape; }
1155 else if(aType.match("OLE2", 26))
1157 eShapeType = XmlShapeTypePresOLE2Shape;
1159 // get info about presentation shape
1160 uno::Reference <beans::XPropertySet> xPropSet(xShape, uno::UNO_QUERY);
1162 if(xPropSet.is()) try
1164 OUString sCLSID;
1165 if(xPropSet->getPropertyValue("CLSID") >>= sCLSID)
1167 if( sCLSID.equals(OUString( SvGlobalName( SO3_SC_CLASSID ).GetHexName())) )
1169 eShapeType = XmlShapeTypePresSheetShape;
1173 catch(const uno::Exception&)
1175 SAL_WARN( "xmloff", "XMLShapeExport::ImpCalcShapeType(), expected ole shape to have the CLSID property?" );
1178 else if(aType.match("Chart", 26)) { eShapeType = XmlShapeTypePresChartShape; }
1179 else if(aType.match("OrgChart", 26)) { eShapeType = XmlShapeTypePresOrgChartShape; }
1180 else if(aType.match("CalcShape", 26)) { eShapeType = XmlShapeTypePresSheetShape; }
1181 else if(aType.match("TableShape", 26)) { eShapeType = XmlShapeTypePresTableShape; }
1182 else if(aType.match("Notes", 26)) { eShapeType = XmlShapeTypePresNotesShape; }
1183 else if(aType.match("HandoutShape", 26)) { eShapeType = XmlShapeTypeHandoutShape; }
1184 else if(aType.match("HeaderShape", 26)) { eShapeType = XmlShapeTypePresHeaderShape; }
1185 else if(aType.match("FooterShape", 26)) { eShapeType = XmlShapeTypePresFooterShape; }
1186 else if(aType.match("SlideNumberShape", 26)) { eShapeType = XmlShapeTypePresSlideNumberShape; }
1187 else if(aType.match("DateTimeShape", 26)) { eShapeType = XmlShapeTypePresDateTimeShape; }
1188 else if(aType.match("MediaShape", 26)) { eShapeType = XmlShapeTypePresMediaShape; }
1194 extern SvXMLEnumMapEntry aXML_GlueAlignment_EnumMap[];
1195 extern SvXMLEnumMapEntry aXML_GlueEscapeDirection_EnumMap[];
1197 /** exports all user defined glue points */
1198 void XMLShapeExport::ImpExportGluePoints( const uno::Reference< drawing::XShape >& xShape )
1200 uno::Reference< drawing::XGluePointsSupplier > xSupplier( xShape, uno::UNO_QUERY );
1201 if( !xSupplier.is() )
1202 return;
1204 uno::Reference< container::XIdentifierAccess > xGluePoints( xSupplier->getGluePoints(), uno::UNO_QUERY );
1205 if( !xGluePoints.is() )
1206 return;
1208 drawing::GluePoint2 aGluePoint;
1210 uno::Sequence< sal_Int32 > aIdSequence( xGluePoints->getIdentifiers() );
1212 const sal_Int32 nCount = aIdSequence.getLength();
1213 for( sal_Int32 nIndex = 0; nIndex < nCount; nIndex++ )
1215 const sal_Int32 nIdentifier = aIdSequence[nIndex];
1216 if( (xGluePoints->getByIdentifier( nIdentifier ) >>= aGluePoint) && aGluePoint.IsUserDefined )
1218 // export only user defined glue points
1220 const OUString sId( OUString::number( nIdentifier ) );
1221 mrExport.AddAttribute(XML_NAMESPACE_DRAW, XML_ID, sId );
1223 mrExport.GetMM100UnitConverter().convertMeasureToXML(msBuffer,
1224 aGluePoint.Position.X);
1225 mrExport.AddAttribute(XML_NAMESPACE_SVG, XML_X, msBuffer.makeStringAndClear());
1227 mrExport.GetMM100UnitConverter().convertMeasureToXML(msBuffer,
1228 aGluePoint.Position.Y);
1229 mrExport.AddAttribute(XML_NAMESPACE_SVG, XML_Y, msBuffer.makeStringAndClear());
1231 if( !aGluePoint.IsRelative )
1233 SvXMLUnitConverter::convertEnum( msBuffer, aGluePoint.PositionAlignment, aXML_GlueAlignment_EnumMap );
1234 mrExport.AddAttribute( XML_NAMESPACE_DRAW, XML_ALIGN, msBuffer.makeStringAndClear() );
1237 if( aGluePoint.Escape != drawing::EscapeDirection_SMART )
1239 SvXMLUnitConverter::convertEnum( msBuffer, aGluePoint.Escape, aXML_GlueEscapeDirection_EnumMap );
1240 mrExport.AddAttribute( XML_NAMESPACE_DRAW, XML_ESCAPE_DIRECTION, msBuffer.makeStringAndClear() );
1243 SvXMLElementExport aEventsElemt(mrExport, XML_NAMESPACE_DRAW, XML_GLUE_POINT, true, true);
1248 void XMLShapeExport::ExportGraphicDefaults()
1250 XMLStyleExport aStEx(mrExport, OUString(), mrExport.GetAutoStylePool().get());
1252 // construct PropertySetMapper
1253 rtl::Reference< SvXMLExportPropertyMapper > xPropertySetMapper( CreateShapePropMapper( mrExport ) );
1254 static_cast<XMLShapeExportPropertyMapper*>(xPropertySetMapper.get())->SetAutoStyles( false );
1256 // chain text attributes
1257 xPropertySetMapper->ChainExportMapper(XMLTextParagraphExport::CreateParaExtPropMapper(mrExport));
1259 // chain special Writer/text frame default attributes
1260 xPropertySetMapper->ChainExportMapper(XMLTextParagraphExport::CreateParaDefaultExtPropMapper(mrExport));
1262 // write graphic family default style
1263 uno::Reference< lang::XMultiServiceFactory > xFact( mrExport.GetModel(), uno::UNO_QUERY );
1264 if( xFact.is() )
1268 uno::Reference< beans::XPropertySet > xDefaults( xFact->createInstance("com.sun.star.drawing.Defaults"), uno::UNO_QUERY );
1269 if( xDefaults.is() )
1271 aStEx.exportDefaultStyle( xDefaults, OUString(XML_STYLE_FAMILY_SD_GRAPHICS_NAME), xPropertySetMapper );
1273 // write graphic family styles
1274 aStEx.exportStyleFamily("graphics", OUString(XML_STYLE_FAMILY_SD_GRAPHICS_NAME), xPropertySetMapper, false, XML_STYLE_FAMILY_SD_GRAPHICS_ID);
1277 catch(const lang::ServiceNotRegisteredException&)
1283 void XMLShapeExport::onExport( const com::sun::star::uno::Reference < com::sun::star::drawing::XShape >& )
1287 const rtl::Reference< XMLTableExport >& XMLShapeExport::GetShapeTableExport()
1289 if( !mxShapeTableExport.is() )
1291 rtl::Reference< XMLPropertyHandlerFactory > xFactory( new XMLSdPropHdlFactory( mrExport.GetModel(), mrExport ) );
1292 rtl::Reference < XMLPropertySetMapper > xMapper( new XMLShapePropertySetMapper( xFactory.get(), true ) );
1293 mrExport.GetTextParagraphExport(); // get or create text paragraph export
1294 rtl::Reference< SvXMLExportPropertyMapper > xPropertySetMapper( new XMLShapeExportPropertyMapper( xMapper, mrExport ) );
1295 mxShapeTableExport = new XMLTableExport( mrExport, xPropertySetMapper, xFactory );
1298 return mxShapeTableExport;
1301 void XMLShapeExport::ImpExportNewTrans(const uno::Reference< beans::XPropertySet >& xPropSet,
1302 XMLShapeExportFlags nFeatures, awt::Point* pRefPoint)
1304 // get matrix
1305 ::basegfx::B2DHomMatrix aMatrix;
1306 ImpExportNewTrans_GetB2DHomMatrix(aMatrix, xPropSet);
1308 // decompose and correct abour pRefPoint
1309 ::basegfx::B2DTuple aTRScale;
1310 double fTRShear(0.0);
1311 double fTRRotate(0.0);
1312 ::basegfx::B2DTuple aTRTranslate;
1313 ImpExportNewTrans_DecomposeAndRefPoint(aMatrix, aTRScale, fTRShear, fTRRotate, aTRTranslate, pRefPoint);
1315 // use features and write
1316 ImpExportNewTrans_FeaturesAndWrite(aTRScale, fTRShear, fTRRotate, aTRTranslate, nFeatures);
1319 void XMLShapeExport::ImpExportNewTrans_GetB2DHomMatrix(::basegfx::B2DHomMatrix& rMatrix,
1320 const uno::Reference< beans::XPropertySet >& xPropSet)
1322 /* Get <TransformationInHoriL2R>, if it exist
1323 and if the document is exported into the OpenOffice.org file format.
1324 This property only exists at service com::sun::star::text::Shape - the
1325 Writer UNO service for shapes.
1326 This code is needed, because the positioning attributes in the
1327 OpenOffice.org file format are given in horizontal left-to-right layout
1328 regardless the layout direction the shape is in. In the OASIS Open Office
1329 file format the positioning attributes are correctly given in the layout
1330 direction the shape is in. Thus, this code provides the conversion from
1331 the OASIS Open Office file format to the OpenOffice.org file format. (#i28749#)
1333 uno::Any aAny;
1334 if ( !( GetExport().getExportFlags() & SvXMLExportFlags::OASIS ) &&
1335 xPropSet->getPropertySetInfo()->hasPropertyByName("TransformationInHoriL2R") )
1337 aAny = xPropSet->getPropertyValue("TransformationInHoriL2R");
1339 else
1341 aAny = xPropSet->getPropertyValue("Transformation");
1343 drawing::HomogenMatrix3 aMatrix;
1344 aAny >>= aMatrix;
1346 rMatrix.set(0, 0, aMatrix.Line1.Column1);
1347 rMatrix.set(0, 1, aMatrix.Line1.Column2);
1348 rMatrix.set(0, 2, aMatrix.Line1.Column3);
1349 rMatrix.set(1, 0, aMatrix.Line2.Column1);
1350 rMatrix.set(1, 1, aMatrix.Line2.Column2);
1351 rMatrix.set(1, 2, aMatrix.Line2.Column3);
1352 rMatrix.set(2, 0, aMatrix.Line3.Column1);
1353 rMatrix.set(2, 1, aMatrix.Line3.Column2);
1354 rMatrix.set(2, 2, aMatrix.Line3.Column3);
1357 void XMLShapeExport::ImpExportNewTrans_DecomposeAndRefPoint(const ::basegfx::B2DHomMatrix& rMatrix, ::basegfx::B2DTuple& rTRScale,
1358 double& fTRShear, double& fTRRotate, ::basegfx::B2DTuple& rTRTranslate, com::sun::star::awt::Point* pRefPoint)
1360 // decompose matrix
1361 rMatrix.decompose(rTRScale, rTRTranslate, fTRRotate, fTRShear);
1363 // correct translation about pRefPoint
1364 if(pRefPoint)
1366 rTRTranslate -= ::basegfx::B2DTuple(pRefPoint->X, pRefPoint->Y);
1370 void XMLShapeExport::ImpExportNewTrans_FeaturesAndWrite(::basegfx::B2DTuple& rTRScale, double fTRShear,
1371 double fTRRotate, ::basegfx::B2DTuple& rTRTranslate, const XMLShapeExportFlags nFeatures)
1373 // always write Size (rTRScale) since this statement carries the union
1374 // of the object
1375 OUString aStr;
1376 OUStringBuffer sStringBuffer;
1377 ::basegfx::B2DTuple aTRScale(rTRScale);
1379 // svg: width
1380 if(!(nFeatures & XMLShapeExportFlags::WIDTH))
1382 aTRScale.setX(1.0);
1384 else
1386 if( aTRScale.getX() > 0.0 )
1387 aTRScale.setX(aTRScale.getX() - 1.0);
1388 else if( aTRScale.getX() < 0.0 )
1389 aTRScale.setX(aTRScale.getX() + 1.0);
1392 mrExport.GetMM100UnitConverter().convertMeasureToXML(sStringBuffer,
1393 FRound(aTRScale.getX()));
1394 aStr = sStringBuffer.makeStringAndClear();
1395 mrExport.AddAttribute(XML_NAMESPACE_SVG, XML_WIDTH, aStr);
1397 // svg: height
1398 if(!(nFeatures & XMLShapeExportFlags::HEIGHT))
1400 aTRScale.setY(1.0);
1402 else
1404 if( aTRScale.getY() > 0.0 )
1405 aTRScale.setY(aTRScale.getY() - 1.0);
1406 else if( aTRScale.getY() < 0.0 )
1407 aTRScale.setY(aTRScale.getY() + 1.0);
1410 mrExport.GetMM100UnitConverter().convertMeasureToXML(sStringBuffer,
1411 FRound(aTRScale.getY()));
1412 aStr = sStringBuffer.makeStringAndClear();
1413 mrExport.AddAttribute(XML_NAMESPACE_SVG, XML_HEIGHT, aStr);
1415 // decide if transformation is necessary
1416 bool bTransformationIsNecessary(fTRShear != 0.0 || fTRRotate != 0.0);
1418 if(bTransformationIsNecessary)
1420 // write transformation, but WITHOUT scale which is exported as size above
1421 SdXMLImExTransform2D aTransform;
1423 aTransform.AddSkewX(atan(fTRShear));
1425 // #i78696#
1426 // fTRRotate is mathematically correct, but due to the error
1427 // we export/import it mirrored. Since the API implementation is fixed and
1428 // uses the correctly oriented angle, it is necessary for compatibility to
1429 // mirror the angle here to stay at the old behaviour. There is a follow-up
1430 // task (#i78698#) to fix this in the next ODF FileFormat version
1431 aTransform.AddRotate(-fTRRotate);
1433 aTransform.AddTranslate(rTRTranslate);
1435 // does transformation need to be exported?
1436 if(aTransform.NeedsAction())
1437 mrExport.AddAttribute(XML_NAMESPACE_DRAW, XML_TRANSFORM, aTransform.GetExportString(mrExport.GetMM100UnitConverter()));
1439 else
1441 // no shear, no rotate; just add object position to export and we are done
1442 if(nFeatures & XMLShapeExportFlags::X)
1444 // svg: x
1445 mrExport.GetMM100UnitConverter().convertMeasureToXML(sStringBuffer,
1446 FRound(rTRTranslate.getX()));
1447 aStr = sStringBuffer.makeStringAndClear();
1448 mrExport.AddAttribute(XML_NAMESPACE_SVG, XML_X, aStr);
1451 if(nFeatures & XMLShapeExportFlags::Y)
1453 // svg: y
1454 mrExport.GetMM100UnitConverter().convertMeasureToXML(sStringBuffer,
1455 FRound(rTRTranslate.getY()));
1456 aStr = sStringBuffer.makeStringAndClear();
1457 mrExport.AddAttribute(XML_NAMESPACE_SVG, XML_Y, aStr);
1462 bool XMLShapeExport::ImpExportPresentationAttributes( const uno::Reference< beans::XPropertySet >& xPropSet, const OUString& rClass )
1464 bool bIsEmpty = false;
1466 // write presentation class entry
1467 mrExport.AddAttribute(XML_NAMESPACE_PRESENTATION, XML_CLASS, rClass);
1469 if( xPropSet.is() )
1471 uno::Reference< beans::XPropertySetInfo > xPropSetInfo( xPropSet->getPropertySetInfo() );
1474 // is empty pes shape?
1475 if( xPropSetInfo.is() && xPropSetInfo->hasPropertyByName("IsEmptyPresentationObject"))
1477 xPropSet->getPropertyValue("IsEmptyPresentationObject") >>= bIsEmpty;
1478 if( bIsEmpty )
1479 mrExport.AddAttribute(XML_NAMESPACE_PRESENTATION, XML_PLACEHOLDER, XML_TRUE);
1482 // is user-transformed?
1483 if( xPropSetInfo.is() && xPropSetInfo->hasPropertyByName("IsPlaceholderDependent"))
1485 bool bTemp = false;
1486 xPropSet->getPropertyValue("IsPlaceholderDependent") >>= bTemp;
1487 if(!bTemp)
1488 mrExport.AddAttribute(XML_NAMESPACE_PRESENTATION, XML_USER_TRANSFORMED, XML_TRUE);
1492 return bIsEmpty;
1495 void XMLShapeExport::ImpExportText( const uno::Reference< drawing::XShape >& xShape, TextPNS eExtensionNS )
1497 uno::Reference< text::XText > xText( xShape, uno::UNO_QUERY );
1498 if( xText.is() )
1500 uno::Reference< container::XEnumerationAccess > xEnumAccess( xShape, uno::UNO_QUERY );
1501 if( xEnumAccess.is() && xEnumAccess->hasElements() )
1502 mrExport.GetTextParagraphExport()->exportText( xText, false, true, eExtensionNS );
1507 namespace {
1509 const sal_Int32 FOUND_CLICKACTION = 0x00000001;
1510 const sal_Int32 FOUND_BOOKMARK = 0x00000002;
1511 const sal_Int32 FOUND_EFFECT = 0x00000004;
1512 const sal_Int32 FOUND_PLAYFULL = 0x00000008;
1513 const sal_Int32 FOUND_VERB = 0x00000010;
1514 const sal_Int32 FOUND_SOUNDURL = 0x00000020;
1515 const sal_Int32 FOUND_SPEED = 0x00000040;
1516 const sal_Int32 FOUND_CLICKEVENTTYPE = 0x00000080;
1517 const sal_Int32 FOUND_MACRO = 0x00000100;
1518 const sal_Int32 FOUND_LIBRARY = 0x00000200;
1520 } // namespace
1522 void XMLShapeExport::ImpExportEvents( const uno::Reference< drawing::XShape >& xShape )
1524 uno::Reference< document::XEventsSupplier > xEventsSupplier( xShape, uno::UNO_QUERY );
1525 if( !xEventsSupplier.is() )
1526 return;
1528 uno::Reference< container::XNameAccess > xEvents( xEventsSupplier->getEvents(), uno::UNO_QUERY );
1529 DBG_ASSERT( xEvents.is(), "XEventsSupplier::getEvents() returned NULL" );
1530 if( !xEvents.is() )
1531 return;
1533 sal_Int32 nFound = 0;
1535 OUString aClickEventType;
1536 presentation::ClickAction eClickAction = presentation::ClickAction_NONE;
1537 presentation::AnimationEffect eEffect = presentation::AnimationEffect_NONE;
1538 presentation::AnimationSpeed eSpeed = presentation::AnimationSpeed_SLOW;
1539 OUString aStrSoundURL;
1540 bool bPlayFull = false;
1541 sal_Int32 nVerb = 0;
1542 OUString aStrMacro;
1543 OUString aStrLibrary;
1544 OUString aStrBookmark;
1546 uno::Sequence< beans::PropertyValue > aClickProperties;
1547 if( xEvents->hasByName( msOnClick ) && (xEvents->getByName( msOnClick ) >>= aClickProperties) )
1549 const beans::PropertyValue* pProperty = aClickProperties.getConstArray();
1550 const beans::PropertyValue* pPropertyEnd = pProperty + aClickProperties.getLength();
1551 for( ; pProperty != pPropertyEnd; ++pProperty )
1553 if( ( ( nFound & FOUND_CLICKEVENTTYPE ) == 0 ) && pProperty->Name == msEventType )
1555 if( pProperty->Value >>= aClickEventType )
1556 nFound |= FOUND_CLICKEVENTTYPE;
1558 else if( ( ( nFound & FOUND_CLICKACTION ) == 0 ) && pProperty->Name == msClickAction )
1560 if( pProperty->Value >>= eClickAction )
1561 nFound |= FOUND_CLICKACTION;
1563 else if( ( ( nFound & FOUND_MACRO ) == 0 ) && ( pProperty->Name == msMacroName || pProperty->Name == msScript ) )
1565 if( pProperty->Value >>= aStrMacro )
1566 nFound |= FOUND_MACRO;
1568 else if( ( ( nFound & FOUND_LIBRARY ) == 0 ) && pProperty->Name == msLibrary )
1570 if( pProperty->Value >>= aStrLibrary )
1571 nFound |= FOUND_LIBRARY;
1573 else if( ( ( nFound & FOUND_EFFECT ) == 0 ) && pProperty->Name == msEffect )
1575 if( pProperty->Value >>= eEffect )
1576 nFound |= FOUND_EFFECT;
1578 else if( ( ( nFound & FOUND_BOOKMARK ) == 0 ) && pProperty->Name == msBookmark )
1580 if( pProperty->Value >>= aStrBookmark )
1581 nFound |= FOUND_BOOKMARK;
1583 else if( ( ( nFound & FOUND_SPEED ) == 0 ) && pProperty->Name == msSpeed )
1585 if( pProperty->Value >>= eSpeed )
1586 nFound |= FOUND_SPEED;
1588 else if( ( ( nFound & FOUND_SOUNDURL ) == 0 ) && pProperty->Name == msSoundURL )
1590 if( pProperty->Value >>= aStrSoundURL )
1591 nFound |= FOUND_SOUNDURL;
1593 else if( ( ( nFound & FOUND_PLAYFULL ) == 0 ) && pProperty->Name == msPlayFull )
1595 if( pProperty->Value >>= bPlayFull )
1596 nFound |= FOUND_PLAYFULL;
1598 else if( ( ( nFound & FOUND_VERB ) == 0 ) && pProperty->Name == msVerb )
1600 if( pProperty->Value >>= nVerb )
1601 nFound |= FOUND_VERB;
1606 // create the XML elements
1608 if( aClickEventType == msPresentation )
1610 if( ((nFound & FOUND_CLICKACTION) == 0) || (eClickAction == presentation::ClickAction_NONE) )
1611 return;
1613 SvXMLElementExport aEventsElemt(mrExport, XML_NAMESPACE_OFFICE, XML_EVENT_LISTENERS, true, true);
1615 enum XMLTokenEnum eStrAction;
1617 switch( eClickAction )
1619 case presentation::ClickAction_PREVPAGE: eStrAction = XML_PREVIOUS_PAGE; break;
1620 case presentation::ClickAction_NEXTPAGE: eStrAction = XML_NEXT_PAGE; break;
1621 case presentation::ClickAction_FIRSTPAGE: eStrAction = XML_FIRST_PAGE; break;
1622 case presentation::ClickAction_LASTPAGE: eStrAction = XML_LAST_PAGE; break;
1623 case presentation::ClickAction_INVISIBLE: eStrAction = XML_HIDE; break;
1624 case presentation::ClickAction_STOPPRESENTATION:eStrAction = XML_STOP; break;
1625 case presentation::ClickAction_PROGRAM: eStrAction = XML_EXECUTE; break;
1626 case presentation::ClickAction_BOOKMARK: eStrAction = XML_SHOW; break;
1627 case presentation::ClickAction_DOCUMENT: eStrAction = XML_SHOW; break;
1628 case presentation::ClickAction_MACRO: eStrAction = XML_EXECUTE_MACRO; break;
1629 case presentation::ClickAction_VERB: eStrAction = XML_VERB; break;
1630 case presentation::ClickAction_VANISH: eStrAction = XML_FADE_OUT; break;
1631 case presentation::ClickAction_SOUND: eStrAction = XML_SOUND; break;
1632 default:
1633 OSL_FAIL( "unknown presentation::ClickAction found!" );
1634 eStrAction = XML_UNKNOWN;
1637 OUString aEventQName(
1638 mrExport.GetNamespaceMap().GetQNameByKey(
1639 XML_NAMESPACE_DOM, OUString( "click" ) ) );
1640 mrExport.AddAttribute( XML_NAMESPACE_SCRIPT, XML_EVENT_NAME, aEventQName );
1641 mrExport.AddAttribute( XML_NAMESPACE_PRESENTATION, XML_ACTION, eStrAction );
1643 if( eClickAction == presentation::ClickAction_VANISH )
1645 if( nFound & FOUND_EFFECT )
1647 XMLEffect eKind;
1648 XMLEffectDirection eDirection;
1649 sal_Int16 nStartScale;
1650 bool bIn;
1652 SdXMLImplSetEffect( eEffect, eKind, eDirection, nStartScale, bIn );
1654 if( eKind != EK_none )
1656 SvXMLUnitConverter::convertEnum( msBuffer, eKind, aXML_AnimationEffect_EnumMap );
1657 mrExport.AddAttribute( XML_NAMESPACE_PRESENTATION, XML_EFFECT, msBuffer.makeStringAndClear() );
1660 if( eDirection != ED_none )
1662 SvXMLUnitConverter::convertEnum( msBuffer, eDirection, aXML_AnimationDirection_EnumMap );
1663 mrExport.AddAttribute( XML_NAMESPACE_PRESENTATION, XML_DIRECTION, msBuffer.makeStringAndClear() );
1666 if( nStartScale != -1 )
1668 ::sax::Converter::convertPercent( msBuffer, nStartScale );
1669 mrExport.AddAttribute( XML_NAMESPACE_PRESENTATION, XML_START_SCALE, msBuffer.makeStringAndClear() );
1673 if( nFound & FOUND_SPEED && eEffect != presentation::AnimationEffect_NONE )
1675 if( eSpeed != presentation::AnimationSpeed_MEDIUM )
1677 SvXMLUnitConverter::convertEnum( msBuffer, eSpeed, aXML_AnimationSpeed_EnumMap );
1678 mrExport.AddAttribute( XML_NAMESPACE_PRESENTATION, XML_SPEED, msBuffer.makeStringAndClear() );
1683 if( eClickAction == presentation::ClickAction_PROGRAM ||
1684 eClickAction == presentation::ClickAction_BOOKMARK ||
1685 eClickAction == presentation::ClickAction_DOCUMENT )
1687 if( eClickAction == presentation::ClickAction_BOOKMARK )
1688 msBuffer.append( '#' );
1690 msBuffer.append( aStrBookmark );
1691 mrExport.AddAttribute(XML_NAMESPACE_XLINK, XML_HREF, GetExport().GetRelativeReference(msBuffer.makeStringAndClear()) );
1692 mrExport.AddAttribute( XML_NAMESPACE_XLINK, XML_TYPE, XML_SIMPLE );
1693 mrExport.AddAttribute( XML_NAMESPACE_XLINK, XML_SHOW, XML_EMBED );
1694 mrExport.AddAttribute( XML_NAMESPACE_XLINK, XML_ACTUATE, XML_ONREQUEST );
1697 if( ( nFound & FOUND_VERB ) && eClickAction == presentation::ClickAction_VERB )
1699 msBuffer.append( nVerb );
1700 mrExport.AddAttribute(XML_NAMESPACE_PRESENTATION, XML_VERB, msBuffer.makeStringAndClear());
1703 SvXMLElementExport aEventElemt(mrExport, XML_NAMESPACE_PRESENTATION, XML_EVENT_LISTENER, true, true);
1705 if( eClickAction == presentation::ClickAction_VANISH || eClickAction == presentation::ClickAction_SOUND )
1707 if( ( nFound & FOUND_SOUNDURL ) && !aStrSoundURL.isEmpty() )
1709 mrExport.AddAttribute(XML_NAMESPACE_XLINK, XML_HREF, GetExport().GetRelativeReference(aStrSoundURL) );
1710 mrExport.AddAttribute( XML_NAMESPACE_XLINK, XML_TYPE, XML_SIMPLE );
1711 mrExport.AddAttribute( XML_NAMESPACE_XLINK, XML_SHOW, XML_NEW );
1712 mrExport.AddAttribute( XML_NAMESPACE_XLINK, XML_ACTUATE, XML_ONREQUEST );
1713 if( nFound & FOUND_PLAYFULL && bPlayFull )
1714 mrExport.AddAttribute( XML_NAMESPACE_PRESENTATION, XML_PLAY_FULL, XML_TRUE );
1716 SvXMLElementExport aElem( mrExport, XML_NAMESPACE_PRESENTATION, XML_SOUND, true, true );
1720 else if( aClickEventType == msStarBasic )
1722 if( nFound & FOUND_MACRO )
1724 SvXMLElementExport aEventsElemt(mrExport, XML_NAMESPACE_OFFICE, XML_EVENT_LISTENERS, true, true);
1726 mrExport.AddAttribute( XML_NAMESPACE_SCRIPT, XML_LANGUAGE,
1727 mrExport.GetNamespaceMap().GetQNameByKey(
1728 XML_NAMESPACE_OOO,
1729 OUString( "starbasic" ) ) );
1730 OUString aEventQName(
1731 mrExport.GetNamespaceMap().GetQNameByKey(
1732 XML_NAMESPACE_DOM, OUString( "click" ) ) );
1733 mrExport.AddAttribute( XML_NAMESPACE_SCRIPT, XML_EVENT_NAME, aEventQName );
1735 if( nFound & FOUND_LIBRARY )
1737 OUString sLocation( GetXMLToken(
1738 (aStrLibrary.equalsIgnoreAsciiCase("StarOffice") ||
1739 aStrLibrary.equalsIgnoreAsciiCase("application") ) ? XML_APPLICATION
1740 : XML_DOCUMENT ) );
1741 mrExport.AddAttribute(XML_NAMESPACE_SCRIPT, XML_MACRO_NAME,
1742 sLocation + ":" + aStrMacro);
1744 else
1746 mrExport.AddAttribute( XML_NAMESPACE_SCRIPT, XML_MACRO_NAME, aStrMacro );
1749 SvXMLElementExport aEventElemt(mrExport, XML_NAMESPACE_SCRIPT, XML_EVENT_LISTENER, true, true);
1752 else if( aClickEventType == msScript )
1754 if( nFound & FOUND_MACRO )
1756 SvXMLElementExport aEventsElemt(mrExport, XML_NAMESPACE_OFFICE, XML_EVENT_LISTENERS, true, true);
1757 if ( nFound & FOUND_MACRO )
1759 mrExport.AddAttribute( XML_NAMESPACE_SCRIPT, XML_LANGUAGE, mrExport.GetNamespaceMap().GetQNameByKey(
1760 XML_NAMESPACE_OOO, GetXMLToken(XML_SCRIPT) ) );
1761 OUString aEventQName(
1762 mrExport.GetNamespaceMap().GetQNameByKey(
1763 XML_NAMESPACE_DOM, OUString( "click" ) ) );
1764 mrExport.AddAttribute( XML_NAMESPACE_SCRIPT, XML_EVENT_NAME, aEventQName );
1765 mrExport.AddAttribute( XML_NAMESPACE_XLINK, XML_HREF, aStrMacro );
1766 mrExport.AddAttribute( XML_NAMESPACE_XLINK, XML_TYPE, "simple" );
1768 SvXMLElementExport aEventElemt(mrExport, XML_NAMESPACE_SCRIPT, XML_EVENT_LISTENER, true, true);
1774 /** #i68101# export shape Title and Description */
1775 void XMLShapeExport::ImpExportDescription( const uno::Reference< drawing::XShape >& xShape )
1779 OUString aTitle;
1780 OUString aDescription;
1782 uno::Reference< beans::XPropertySet > xProps( xShape, uno::UNO_QUERY_THROW );
1783 xProps->getPropertyValue("Title") >>= aTitle;
1784 xProps->getPropertyValue("Description") >>= aDescription;
1786 if(!aTitle.isEmpty())
1788 SvXMLElementExport aEventElemt(mrExport, XML_NAMESPACE_SVG, XML_TITLE, true, false);
1789 mrExport.Characters( aTitle );
1792 if(!aDescription.isEmpty())
1794 SvXMLElementExport aEventElemt(mrExport, XML_NAMESPACE_SVG, XML_DESC, true, false );
1795 mrExport.Characters( aDescription );
1798 catch( uno::Exception& )
1800 OSL_FAIL( "could not export Title and/or Description for shape!" );
1804 void XMLShapeExport::ImpExportGroupShape( const uno::Reference< drawing::XShape >& xShape, XmlShapeType, XMLShapeExportFlags nFeatures, awt::Point* pRefPoint)
1806 uno::Reference< drawing::XShapes > xShapes(xShape, uno::UNO_QUERY);
1807 if(xShapes.is() && xShapes->getCount())
1809 // write group shape
1810 bool bCreateNewline( (nFeatures & XMLShapeExportFlags::NO_WS) == XMLShapeExportFlags::NONE ); // #86116#/#92210#
1811 SvXMLElementExport aPGR(mrExport, XML_NAMESPACE_DRAW, XML_G, bCreateNewline, true);
1813 ImpExportDescription( xShape ); // #i68101#
1814 ImpExportEvents( xShape );
1815 ImpExportGluePoints( xShape );
1817 // #89764# if export of position is suppressed for group shape,
1818 // positions of contained objects should be written relative to
1819 // the upper left edge of the group.
1820 awt::Point aUpperLeft;
1822 if(!(nFeatures & XMLShapeExportFlags::POSITION))
1824 nFeatures |= XMLShapeExportFlags::POSITION;
1825 aUpperLeft = xShape->getPosition();
1826 pRefPoint = &aUpperLeft;
1829 // write members
1830 exportShapes( xShapes, nFeatures, pRefPoint );
1834 void XMLShapeExport::ImpExportTextBoxShape(
1835 const uno::Reference< drawing::XShape >& xShape,
1836 XmlShapeType eShapeType, XMLShapeExportFlags nFeatures, awt::Point* pRefPoint)
1838 const uno::Reference< beans::XPropertySet > xPropSet(xShape, uno::UNO_QUERY);
1839 if(xPropSet.is())
1841 uno::Reference< beans::XPropertySetInfo > xPropSetInfo( xPropSet->getPropertySetInfo() );
1843 // presentation attribute (if presentation)
1844 bool bIsPresShape(false);
1845 bool bIsEmptyPresObj(false);
1846 OUString aStr;
1848 switch(eShapeType)
1850 case XmlShapeTypePresSubtitleShape:
1852 aStr = GetXMLToken(XML_PRESENTATION_SUBTITLE);
1853 bIsPresShape = true;
1854 break;
1856 case XmlShapeTypePresTitleTextShape:
1858 aStr = GetXMLToken(XML_PRESENTATION_TITLE);
1859 bIsPresShape = true;
1860 break;
1862 case XmlShapeTypePresOutlinerShape:
1864 aStr = GetXMLToken(XML_PRESENTATION_OUTLINE);
1865 bIsPresShape = true;
1866 break;
1868 case XmlShapeTypePresNotesShape:
1870 aStr = GetXMLToken(XML_PRESENTATION_NOTES);
1871 bIsPresShape = true;
1872 break;
1874 case XmlShapeTypePresHeaderShape:
1876 aStr = GetXMLToken(XML_HEADER);
1877 bIsPresShape = true;
1878 break;
1880 case XmlShapeTypePresFooterShape:
1882 aStr = GetXMLToken(XML_FOOTER);
1883 bIsPresShape = true;
1884 break;
1886 case XmlShapeTypePresSlideNumberShape:
1888 aStr = GetXMLToken(XML_PAGE_NUMBER);
1889 bIsPresShape = true;
1890 break;
1892 case XmlShapeTypePresDateTimeShape:
1894 aStr = GetXMLToken(XML_DATE_TIME);
1895 bIsPresShape = true;
1896 break;
1898 default:
1899 break;
1902 // Transformation
1903 ImpExportNewTrans(xPropSet, nFeatures, pRefPoint);
1905 if(bIsPresShape)
1906 bIsEmptyPresObj = ImpExportPresentationAttributes( xPropSet, aStr );
1908 bool bCreateNewline( (nFeatures & XMLShapeExportFlags::NO_WS) == XMLShapeExportFlags::NONE ); // #86116#/#92210#
1909 SvXMLElementExport aElem( mrExport, XML_NAMESPACE_DRAW,
1910 XML_FRAME, bCreateNewline, true );
1912 // evtl. corner radius?
1913 sal_Int32 nCornerRadius(0L);
1914 xPropSet->getPropertyValue("CornerRadius") >>= nCornerRadius;
1915 if(nCornerRadius)
1917 OUStringBuffer sStringBuffer;
1918 mrExport.GetMM100UnitConverter().convertMeasureToXML(sStringBuffer,
1919 nCornerRadius);
1920 mrExport.AddAttribute(XML_NAMESPACE_DRAW, XML_CORNER_RADIUS, sStringBuffer.makeStringAndClear());
1924 // write text-box
1925 SvXMLElementExport aOBJ(mrExport, XML_NAMESPACE_DRAW, XML_TEXT_BOX, true, true);
1926 if(!bIsEmptyPresObj)
1927 ImpExportText( xShape );
1930 ImpExportDescription( xShape ); // #i68101#
1931 ImpExportEvents( xShape );
1932 ImpExportGluePoints( xShape );
1936 void XMLShapeExport::ImpExportRectangleShape(
1937 const uno::Reference< drawing::XShape >& xShape,
1938 XmlShapeType, XMLShapeExportFlags nFeatures, com::sun::star::awt::Point* pRefPoint)
1940 const uno::Reference< beans::XPropertySet > xPropSet(xShape, uno::UNO_QUERY);
1941 if(xPropSet.is())
1943 // Transformation
1944 ImpExportNewTrans(xPropSet, nFeatures, pRefPoint);
1946 // evtl. corner radius?
1947 sal_Int32 nCornerRadius(0L);
1948 xPropSet->getPropertyValue("CornerRadius") >>= nCornerRadius;
1949 if(nCornerRadius)
1951 OUStringBuffer sStringBuffer;
1952 mrExport.GetMM100UnitConverter().convertMeasureToXML(sStringBuffer,
1953 nCornerRadius);
1954 mrExport.AddAttribute(XML_NAMESPACE_DRAW, XML_CORNER_RADIUS, sStringBuffer.makeStringAndClear());
1957 // write rectangle
1958 bool bCreateNewline( (nFeatures & XMLShapeExportFlags::NO_WS) == XMLShapeExportFlags::NONE ); // #86116#/#92210#
1959 SvXMLElementExport aOBJ(mrExport, XML_NAMESPACE_DRAW, XML_RECT, bCreateNewline, true);
1961 ImpExportDescription( xShape ); // #i68101#
1962 ImpExportEvents( xShape );
1963 ImpExportGluePoints( xShape );
1964 ImpExportText( xShape );
1968 void XMLShapeExport::ImpExportLineShape(
1969 const uno::Reference< drawing::XShape >& xShape,
1970 XmlShapeType, XMLShapeExportFlags nFeatures, awt::Point* pRefPoint)
1972 const uno::Reference< beans::XPropertySet > xPropSet(xShape, uno::UNO_QUERY);
1973 if(xPropSet.is())
1975 OUString aStr;
1976 OUStringBuffer sStringBuffer;
1977 awt::Point aStart(0,0);
1978 awt::Point aEnd(1,1);
1980 // #85920# use 'Geometry' to get the points of the line
1981 // since this slot take anchor pos into account.
1983 // get matrix
1984 ::basegfx::B2DHomMatrix aMatrix;
1985 ImpExportNewTrans_GetB2DHomMatrix(aMatrix, xPropSet);
1987 // decompose and correct about pRefPoint
1988 ::basegfx::B2DTuple aTRScale;
1989 double fTRShear(0.0);
1990 double fTRRotate(0.0);
1991 ::basegfx::B2DTuple aTRTranslate;
1992 ImpExportNewTrans_DecomposeAndRefPoint(aMatrix, aTRScale, fTRShear, fTRRotate, aTRTranslate, pRefPoint);
1994 // create base position
1995 awt::Point aBasePosition(FRound(aTRTranslate.getX()), FRound(aTRTranslate.getY()));
1997 // get the two points
1998 uno::Any aAny(xPropSet->getPropertyValue("Geometry"));
1999 drawing::PointSequenceSequence const * pSourcePolyPolygon = static_cast<drawing::PointSequenceSequence const *>(aAny.getValue());
2001 if(pSourcePolyPolygon)
2003 drawing::PointSequence* pOuterSequence = const_cast<css::drawing::PointSequenceSequence *>(pSourcePolyPolygon)->getArray();
2004 if(pOuterSequence)
2006 drawing::PointSequence* pInnerSequence = pOuterSequence++;
2007 if(pInnerSequence)
2009 awt::Point* pArray = pInnerSequence->getArray();
2010 if(pArray)
2012 if(pInnerSequence->getLength() > 0)
2014 aStart = awt::Point(
2015 pArray->X + aBasePosition.X,
2016 pArray->Y + aBasePosition.Y);
2017 pArray++;
2020 if(pInnerSequence->getLength() > 1)
2022 aEnd = awt::Point(
2023 pArray->X + aBasePosition.X,
2024 pArray->Y + aBasePosition.Y);
2031 if( nFeatures & XMLShapeExportFlags::X )
2033 // svg: x1
2034 mrExport.GetMM100UnitConverter().convertMeasureToXML(sStringBuffer,
2035 aStart.X);
2036 aStr = sStringBuffer.makeStringAndClear();
2037 mrExport.AddAttribute(XML_NAMESPACE_SVG, XML_X1, aStr);
2039 else
2041 aEnd.X -= aStart.X;
2044 if( nFeatures & XMLShapeExportFlags::Y )
2046 // svg: y1
2047 mrExport.GetMM100UnitConverter().convertMeasureToXML(sStringBuffer,
2048 aStart.Y);
2049 aStr = sStringBuffer.makeStringAndClear();
2050 mrExport.AddAttribute(XML_NAMESPACE_SVG, XML_Y1, aStr);
2052 else
2054 aEnd.Y -= aStart.Y;
2057 // svg: x2
2058 mrExport.GetMM100UnitConverter().convertMeasureToXML(sStringBuffer,
2059 aEnd.X);
2060 aStr = sStringBuffer.makeStringAndClear();
2061 mrExport.AddAttribute(XML_NAMESPACE_SVG, XML_X2, aStr);
2063 // svg: y2
2064 mrExport.GetMM100UnitConverter().convertMeasureToXML(sStringBuffer,
2065 aEnd.Y);
2066 aStr = sStringBuffer.makeStringAndClear();
2067 mrExport.AddAttribute(XML_NAMESPACE_SVG, XML_Y2, aStr);
2069 // write line
2070 bool bCreateNewline( (nFeatures & XMLShapeExportFlags::NO_WS) == XMLShapeExportFlags::NONE ); // #86116#/#92210#
2071 SvXMLElementExport aOBJ(mrExport, XML_NAMESPACE_DRAW, XML_LINE, bCreateNewline, true);
2073 ImpExportDescription( xShape ); // #i68101#
2074 ImpExportEvents( xShape );
2075 ImpExportGluePoints( xShape );
2076 ImpExportText( xShape );
2080 void XMLShapeExport::ImpExportEllipseShape(
2081 const uno::Reference< drawing::XShape >& xShape,
2082 XmlShapeType, XMLShapeExportFlags nFeatures, awt::Point* pRefPoint)
2084 const uno::Reference< beans::XPropertySet > xPropSet(xShape, uno::UNO_QUERY);
2085 if(xPropSet.is())
2087 // get size to decide between Circle and Ellipse
2088 awt::Size aSize = xShape->getSize();
2089 sal_Int32 nRx((aSize.Width + 1) / 2);
2090 sal_Int32 nRy((aSize.Height + 1) / 2);
2091 bool bCircle(nRx == nRy);
2093 // Transformation
2094 ImpExportNewTrans(xPropSet, nFeatures, pRefPoint);
2096 drawing::CircleKind eKind = drawing::CircleKind_FULL;
2097 xPropSet->getPropertyValue("CircleKind") >>= eKind;
2098 if( eKind != drawing::CircleKind_FULL )
2100 OUStringBuffer sStringBuffer;
2101 sal_Int32 nStartAngle = 0;
2102 sal_Int32 nEndAngle = 0;
2103 xPropSet->getPropertyValue("CircleStartAngle") >>= nStartAngle;
2104 xPropSet->getPropertyValue("CircleEndAngle") >>= nEndAngle;
2106 const double dStartAngle = nStartAngle / 100.0;
2107 const double dEndAngle = nEndAngle / 100.0;
2109 // export circle kind
2110 SvXMLUnitConverter::convertEnum( sStringBuffer, (sal_uInt16)eKind, aXML_CircleKind_EnumMap );
2111 mrExport.AddAttribute(XML_NAMESPACE_DRAW, XML_KIND, sStringBuffer.makeStringAndClear() );
2113 // export start angle
2114 ::sax::Converter::convertDouble( sStringBuffer, dStartAngle );
2115 mrExport.AddAttribute(XML_NAMESPACE_DRAW, XML_START_ANGLE, sStringBuffer.makeStringAndClear() );
2117 // export end angle
2118 ::sax::Converter::convertDouble( sStringBuffer, dEndAngle );
2119 mrExport.AddAttribute(XML_NAMESPACE_DRAW, XML_END_ANGLE, sStringBuffer.makeStringAndClear() );
2122 bool bCreateNewline( (nFeatures & XMLShapeExportFlags::NO_WS) == XMLShapeExportFlags::NONE ); // #86116#/#92210#
2124 // write ellipse or circle
2125 SvXMLElementExport aOBJ(mrExport, XML_NAMESPACE_DRAW,
2126 bCircle ? XML_CIRCLE : XML_ELLIPSE,
2127 bCreateNewline, true);
2129 ImpExportDescription( xShape ); // #i68101#
2130 ImpExportEvents( xShape );
2131 ImpExportGluePoints( xShape );
2132 ImpExportText( xShape );
2137 void XMLShapeExport::ImpExportPolygonShape(
2138 const uno::Reference< drawing::XShape >& xShape,
2139 XmlShapeType eShapeType, XMLShapeExportFlags nFeatures, awt::Point* pRefPoint)
2141 const uno::Reference< beans::XPropertySet > xPropSet(xShape, uno::UNO_QUERY);
2142 if(xPropSet.is())
2144 bool bBezier(eShapeType == XmlShapeTypeDrawClosedBezierShape
2145 || eShapeType == XmlShapeTypeDrawOpenBezierShape);
2147 // get matrix
2148 ::basegfx::B2DHomMatrix aMatrix;
2149 ImpExportNewTrans_GetB2DHomMatrix(aMatrix, xPropSet);
2151 // decompose and correct abour pRefPoint
2152 ::basegfx::B2DTuple aTRScale;
2153 double fTRShear(0.0);
2154 double fTRRotate(0.0);
2155 ::basegfx::B2DTuple aTRTranslate;
2156 ImpExportNewTrans_DecomposeAndRefPoint(aMatrix, aTRScale, fTRShear, fTRRotate, aTRTranslate, pRefPoint);
2158 // use features and write
2159 ImpExportNewTrans_FeaturesAndWrite(aTRScale, fTRShear, fTRRotate, aTRTranslate, nFeatures);
2161 // create and export ViewBox
2162 awt::Point aPoint(0, 0);
2163 awt::Size aSize(FRound(aTRScale.getX()), FRound(aTRScale.getY()));
2164 SdXMLImExViewBox aViewBox(0, 0, aSize.Width, aSize.Height);
2165 mrExport.AddAttribute(XML_NAMESPACE_SVG, XML_VIEWBOX, aViewBox.GetExportString());
2167 bool bCreateNewline( (nFeatures & XMLShapeExportFlags::NO_WS) == XMLShapeExportFlags::NONE ); // #86116#/#92210#
2169 // prepare name (with most used)
2170 enum ::xmloff::token::XMLTokenEnum eName(XML_PATH);
2172 if(bBezier)
2174 // get PolygonBezier
2175 uno::Any aAny( xPropSet->getPropertyValue("Geometry") );
2176 const basegfx::B2DPolyPolygon aPolyPolygon(
2177 basegfx::tools::UnoPolyPolygonBezierCoordsToB2DPolyPolygon(*static_cast<drawing::PolyPolygonBezierCoords const *>(aAny.getValue())));
2179 if(aPolyPolygon.count())
2181 // complex polygon shape, write as svg:d
2182 const OUString aPolygonString(
2183 basegfx::tools::exportToSvgD(
2184 aPolyPolygon,
2185 true, // bUseRelativeCoordinates
2186 false, // bDetectQuadraticBeziers: not used in old, but maybe activated now
2187 true)); // bHandleRelativeNextPointCompatible
2189 // write point array
2190 mrExport.AddAttribute(XML_NAMESPACE_SVG, XML_D, aPolygonString);
2193 else
2195 // get non-bezier polygon
2196 uno::Any aAny( xPropSet->getPropertyValue("Geometry") );
2197 const basegfx::B2DPolyPolygon aPolyPolygon(
2198 basegfx::tools::UnoPointSequenceSequenceToB2DPolyPolygon(*static_cast<drawing::PointSequenceSequence const *>(aAny.getValue())));
2200 if(!aPolyPolygon.areControlPointsUsed() && 1 == aPolyPolygon.count())
2202 // simple polygon shape, can be written as svg:points sequence
2203 const basegfx::B2DPolygon aPolygon(aPolyPolygon.getB2DPolygon(0));
2204 const OUString aPointString(basegfx::tools::exportToSvgPoints(aPolygon));
2206 // write point array
2207 mrExport.AddAttribute(XML_NAMESPACE_DRAW, XML_POINTS, aPointString);
2209 // set name
2210 eName = aPolygon.isClosed() ? XML_POLYGON : XML_POLYLINE;
2212 else
2214 // complex polygon shape, write as svg:d
2215 const OUString aPolygonString(
2216 basegfx::tools::exportToSvgD(
2217 aPolyPolygon,
2218 true, // bUseRelativeCoordinates
2219 false, // bDetectQuadraticBeziers: not used in old, but maybe activated now
2220 true)); // bHandleRelativeNextPointCompatible
2222 // write point array
2223 mrExport.AddAttribute(XML_NAMESPACE_SVG, XML_D, aPolygonString);
2227 // write object, but after attributes are added since this call will
2228 // consume all of these added attributes and the destructor will close the
2229 // scope. Also before text is added; this may add sub-scopes as needed
2230 SvXMLElementExport aOBJ(
2231 mrExport,
2232 XML_NAMESPACE_DRAW,
2233 eName,
2234 bCreateNewline,
2235 true);
2237 ImpExportDescription( xShape ); // #i68101#
2238 ImpExportEvents( xShape );
2239 ImpExportGluePoints( xShape );
2240 ImpExportText( xShape );
2244 void XMLShapeExport::ImpExportGraphicObjectShape(
2245 const uno::Reference< drawing::XShape >& xShape,
2246 XmlShapeType eShapeType, XMLShapeExportFlags nFeatures, awt::Point* pRefPoint)
2248 const uno::Reference< beans::XPropertySet > xPropSet(xShape, uno::UNO_QUERY);
2249 if(xPropSet.is())
2251 bool bIsEmptyPresObj = false;
2252 uno::Reference< beans::XPropertySetInfo > xPropSetInfo( xPropSet->getPropertySetInfo() );
2254 // Transformation
2255 ImpExportNewTrans(xPropSet, nFeatures, pRefPoint);
2257 OUString sImageURL;
2259 if(eShapeType == XmlShapeTypePresGraphicObjectShape)
2260 bIsEmptyPresObj = ImpExportPresentationAttributes( xPropSet, GetXMLToken(XML_PRESENTATION_GRAPHIC) );
2262 bool bCreateNewline( (nFeatures & XMLShapeExportFlags::NO_WS) == XMLShapeExportFlags::NONE ); // #86116#/#92210#
2263 SvXMLElementExport aElem( mrExport, XML_NAMESPACE_DRAW,
2264 XML_FRAME, bCreateNewline, true );
2266 const bool bSaveBackwardsCompatible = bool( mrExport.getExportFlags() & SvXMLExportFlags::SAVEBACKWARDCOMPATIBLE );
2268 if( !bIsEmptyPresObj || bSaveBackwardsCompatible )
2270 if( !bIsEmptyPresObj )
2272 OUString aStreamURL;
2274 xPropSet->getPropertyValue("GraphicStreamURL") >>= aStreamURL;
2275 xPropSet->getPropertyValue("GraphicURL") >>= sImageURL;
2277 OUString aResolveURL( sImageURL );
2278 const OUString sPackageURL( "vnd.sun.star.Package:" );
2280 // trying to preserve the filename for embedded images which already have its stream inside the package
2281 bool bIsEmbeddedImageWithExistingStreamInPackage = false;
2282 if ( aStreamURL.match( sPackageURL, 0 ) )
2284 bIsEmbeddedImageWithExistingStreamInPackage = true;
2286 OUString sRequestedName( aStreamURL.copy( sPackageURL.getLength(), aStreamURL.getLength() - sPackageURL.getLength() ) );
2287 sal_Int32 nLastIndex = sRequestedName.lastIndexOf( '/' ) + 1;
2288 if ( ( nLastIndex > 0 ) && ( nLastIndex < sRequestedName.getLength() ) )
2289 sRequestedName = sRequestedName.copy( nLastIndex, sRequestedName.getLength() - nLastIndex );
2290 nLastIndex = sRequestedName.lastIndexOf( '.' );
2291 if ( nLastIndex >= 0 )
2292 sRequestedName = sRequestedName.copy( 0, nLastIndex );
2293 if ( !sRequestedName.isEmpty() )
2295 aResolveURL = aResolveURL.concat( "?requestedName=");
2296 aResolveURL = aResolveURL.concat( sRequestedName );
2300 const OUString aStr = mrExport.AddEmbeddedGraphicObject( aResolveURL );
2301 mrExport.AddAttribute(XML_NAMESPACE_XLINK, XML_HREF, aStr );
2303 if( !aStr.isEmpty() )
2305 // apply possible changed stream URL to embedded image object
2306 if ( bIsEmbeddedImageWithExistingStreamInPackage )
2308 aStreamURL = sPackageURL;
2309 if ( aStr[0] == '#' )
2311 aStreamURL = aStreamURL.concat( aStr.copy( 1, aStr.getLength() - 1 ) );
2313 else
2315 aStreamURL = aStreamURL.concat( aStr );
2318 uno::Any aAny;
2319 aAny <<= aStreamURL;
2320 xPropSet->setPropertyValue( "GraphicStreamURL", aAny );
2323 mrExport.AddAttribute(XML_NAMESPACE_XLINK, XML_TYPE, XML_SIMPLE );
2324 mrExport.AddAttribute(XML_NAMESPACE_XLINK, XML_SHOW, XML_EMBED );
2325 mrExport.AddAttribute(XML_NAMESPACE_XLINK, XML_ACTUATE, XML_ONLOAD );
2328 else
2330 OUString aStr;
2331 mrExport.AddAttribute(XML_NAMESPACE_XLINK, XML_HREF, aStr );
2332 mrExport.AddAttribute(XML_NAMESPACE_XLINK, XML_TYPE, XML_SIMPLE );
2333 mrExport.AddAttribute(XML_NAMESPACE_XLINK, XML_SHOW, XML_EMBED );
2334 mrExport.AddAttribute(XML_NAMESPACE_XLINK, XML_ACTUATE, XML_ONLOAD );
2338 SvXMLElementExport aOBJ(mrExport, XML_NAMESPACE_DRAW, XML_IMAGE, true, true);
2340 if( !sImageURL.isEmpty() )
2342 // optional office:binary-data
2343 mrExport.AddEmbeddedGraphicObjectAsBase64( sImageURL );
2345 if( !bIsEmptyPresObj )
2346 ImpExportText( xShape );
2349 //Resolves: fdo#62461 put preferred image first above, followed by
2350 //fallback here
2351 if( !bIsEmptyPresObj )
2353 OUString aReplacementUrl;
2354 xPropSet->getPropertyValue("ReplacementGraphicURL") >>= aReplacementUrl;
2356 // If there is no url, then then graphic is empty
2357 if(!aReplacementUrl.isEmpty())
2359 const OUString aStr = mrExport.AddEmbeddedGraphicObject(aReplacementUrl);
2361 if(aStr.getLength())
2363 mrExport.AddAttribute(XML_NAMESPACE_XLINK, XML_HREF, aStr);
2364 mrExport.AddAttribute(XML_NAMESPACE_XLINK, XML_TYPE, XML_SIMPLE );
2365 mrExport.AddAttribute(XML_NAMESPACE_XLINK, XML_SHOW, XML_EMBED );
2366 mrExport.AddAttribute(XML_NAMESPACE_XLINK, XML_ACTUATE, XML_ONLOAD );
2368 // xlink:href for replacement, only written for Svg content
2369 SvXMLElementExport aOBJ(mrExport, XML_NAMESPACE_DRAW, XML_IMAGE, true, true);
2371 // optional office:binary-data
2372 mrExport.AddEmbeddedGraphicObjectAsBase64(aReplacementUrl);
2378 ImpExportEvents( xShape );
2379 ImpExportGluePoints( xShape );
2381 // image map
2382 GetExport().GetImageMapExport().Export( xPropSet );
2383 ImpExportDescription( xShape ); // #i68101#
2387 void XMLShapeExport::ImpExportChartShape(
2388 const uno::Reference< drawing::XShape >& xShape,
2389 XmlShapeType eShapeType, XMLShapeExportFlags nFeatures, awt::Point* pRefPoint,
2390 SvXMLAttributeList* pAttrList )
2392 ImpExportOLE2Shape( xShape, eShapeType, nFeatures, pRefPoint, pAttrList );
2395 void XMLShapeExport::ImpExportControlShape(
2396 const uno::Reference< drawing::XShape >& xShape,
2397 XmlShapeType, XMLShapeExportFlags nFeatures, awt::Point* pRefPoint)
2399 const uno::Reference< beans::XPropertySet > xPropSet(xShape, uno::UNO_QUERY);
2400 if(xPropSet.is())
2402 // Transformation
2403 ImpExportNewTrans(xPropSet, nFeatures, pRefPoint);
2406 uno::Reference< drawing::XControlShape > xControl( xShape, uno::UNO_QUERY );
2407 DBG_ASSERT( xControl.is(), "Control shape is not supporting XControlShape" );
2408 if( xControl.is() )
2410 uno::Reference< beans::XPropertySet > xControlModel( xControl->getControl(), uno::UNO_QUERY );
2411 DBG_ASSERT( xControlModel.is(), "Control shape has not XControlModel" );
2412 if( xControlModel.is() )
2414 mrExport.AddAttribute( XML_NAMESPACE_DRAW, XML_CONTROL, mrExport.GetFormExport()->getControlId( xControlModel ) );
2418 bool bCreateNewline( (nFeatures & XMLShapeExportFlags::NO_WS) == XMLShapeExportFlags::NONE ); // #86116#/#92210#
2419 SvXMLElementExport aOBJ(mrExport, XML_NAMESPACE_DRAW, XML_CONTROL, bCreateNewline, true);
2421 ImpExportDescription( xShape ); // #i68101#
2424 void XMLShapeExport::ImpExportConnectorShape(
2425 const uno::Reference< drawing::XShape >& xShape,
2426 XmlShapeType, XMLShapeExportFlags nFeatures /* = SEF_DEFAULT */, awt::Point* pRefPoint /* = NULL */)
2428 uno::Reference< beans::XPropertySet > xProps( xShape, uno::UNO_QUERY );
2430 OUString aStr;
2431 OUStringBuffer sStringBuffer;
2433 // export connection kind
2434 drawing::ConnectorType eType = drawing::ConnectorType_STANDARD;
2435 uno::Any aAny = xProps->getPropertyValue("EdgeKind");
2436 aAny >>= eType;
2438 if( eType != drawing::ConnectorType_STANDARD )
2440 SvXMLUnitConverter::convertEnum( sStringBuffer, (sal_uInt16)eType, aXML_ConnectionKind_EnumMap );
2441 aStr = sStringBuffer.makeStringAndClear();
2442 mrExport.AddAttribute(XML_NAMESPACE_DRAW, XML_TYPE, aStr);
2445 // export line skew
2446 sal_Int32 nDelta1 = 0, nDelta2 = 0, nDelta3 = 0;
2448 aAny = xProps->getPropertyValue("EdgeLine1Delta");
2449 aAny >>= nDelta1;
2450 aAny = xProps->getPropertyValue("EdgeLine2Delta");
2451 aAny >>= nDelta2;
2452 aAny = xProps->getPropertyValue("EdgeLine3Delta");
2453 aAny >>= nDelta3;
2455 if( nDelta1 != 0 || nDelta2 != 0 || nDelta3 != 0 )
2457 mrExport.GetMM100UnitConverter().convertMeasureToXML(sStringBuffer,
2458 nDelta1);
2459 if( nDelta2 != 0 || nDelta3 != 0 )
2461 sStringBuffer.append( ' ' );
2462 mrExport.GetMM100UnitConverter().convertMeasureToXML(sStringBuffer,
2463 nDelta2);
2464 if( nDelta3 != 0 )
2466 sStringBuffer.append( ' ' );
2467 mrExport.GetMM100UnitConverter().convertMeasureToXML(
2468 sStringBuffer, nDelta3);
2472 aStr = sStringBuffer.makeStringAndClear();
2473 mrExport.AddAttribute(XML_NAMESPACE_DRAW, XML_LINE_SKEW, aStr);
2476 // export start and end point
2477 awt::Point aStart(0,0);
2478 awt::Point aEnd(1,1);
2480 /* Get <StartPositionInHoriL2R> and
2481 <EndPositionInHoriL2R>, if they exist and if the document is exported
2482 into the OpenOffice.org file format.
2483 These properties only exist at service com::sun::star::text::Shape - the
2484 Writer UNO service for shapes.
2485 This code is needed, because the positioning attributes in the
2486 OpenOffice.org file format are given in horizontal left-to-right layout
2487 regardless the layout direction the shape is in. In the OASIS Open Office
2488 file format the positioning attributes are correctly given in the layout
2489 direction the shape is in. Thus, this code provides the conversion from
2490 the OASIS Open Office file format to the OpenOffice.org file format. (#i36248#)
2492 if ( !( GetExport().getExportFlags() & SvXMLExportFlags::OASIS ) &&
2493 xProps->getPropertySetInfo()->hasPropertyByName("StartPositionInHoriL2R") &&
2494 xProps->getPropertySetInfo()->hasPropertyByName("EndPositionInHoriL2R") )
2496 xProps->getPropertyValue("StartPositionInHoriL2R") >>= aStart;
2497 xProps->getPropertyValue("EndPositionInHoriL2R") >>= aEnd;
2499 else
2501 xProps->getPropertyValue("StartPosition") >>= aStart;
2502 xProps->getPropertyValue("EndPosition") >>= aEnd;
2505 if( pRefPoint )
2507 aStart.X -= pRefPoint->X;
2508 aStart.Y -= pRefPoint->Y;
2509 aEnd.X -= pRefPoint->X;
2510 aEnd.Y -= pRefPoint->Y;
2513 if( nFeatures & XMLShapeExportFlags::X )
2515 // svg: x1
2516 mrExport.GetMM100UnitConverter().convertMeasureToXML(sStringBuffer,
2517 aStart.X);
2518 aStr = sStringBuffer.makeStringAndClear();
2519 mrExport.AddAttribute(XML_NAMESPACE_SVG, XML_X1, aStr);
2521 else
2523 aEnd.X -= aStart.X;
2526 if( nFeatures & XMLShapeExportFlags::Y )
2528 // svg: y1
2529 mrExport.GetMM100UnitConverter().convertMeasureToXML(sStringBuffer,
2530 aStart.Y);
2531 aStr = sStringBuffer.makeStringAndClear();
2532 mrExport.AddAttribute(XML_NAMESPACE_SVG, XML_Y1, aStr);
2534 else
2536 aEnd.Y -= aStart.Y;
2539 // svg: x2
2540 mrExport.GetMM100UnitConverter().convertMeasureToXML(sStringBuffer, aEnd.X);
2541 aStr = sStringBuffer.makeStringAndClear();
2542 mrExport.AddAttribute(XML_NAMESPACE_SVG, XML_X2, aStr);
2544 // svg: y2
2545 mrExport.GetMM100UnitConverter().convertMeasureToXML(sStringBuffer, aEnd.Y);
2546 aStr = sStringBuffer.makeStringAndClear();
2547 mrExport.AddAttribute(XML_NAMESPACE_SVG, XML_Y2, aStr);
2549 // #i39320#
2550 uno::Reference< uno::XInterface > xRefS;
2551 uno::Reference< uno::XInterface > xRefE;
2553 // export start connection
2554 xProps->getPropertyValue("StartShape") >>= xRefS;
2555 if( xRefS.is() )
2557 const OUString& rShapeId = mrExport.getInterfaceToIdentifierMapper().getIdentifier( xRefS );
2558 mrExport.AddAttribute(XML_NAMESPACE_DRAW, XML_START_SHAPE, rShapeId);
2560 aAny = xProps->getPropertyValue("StartGluePointIndex");
2561 sal_Int32 nGluePointId = 0;
2562 if( aAny >>= nGluePointId )
2564 if( nGluePointId != -1 )
2566 mrExport.AddAttribute(XML_NAMESPACE_DRAW, XML_START_GLUE_POINT, OUString::number( nGluePointId ));
2571 // export end connection
2572 xProps->getPropertyValue("EndShape") >>= xRefE;
2573 if( xRefE.is() )
2575 const OUString& rShapeId = mrExport.getInterfaceToIdentifierMapper().getIdentifier( xRefE );
2576 mrExport.AddAttribute(XML_NAMESPACE_DRAW, XML_END_SHAPE, rShapeId);
2578 aAny = xProps->getPropertyValue("EndGluePointIndex");
2579 sal_Int32 nGluePointId = 0;
2580 if( aAny >>= nGluePointId )
2582 if( nGluePointId != -1 )
2584 mrExport.AddAttribute(XML_NAMESPACE_DRAW, XML_END_GLUE_POINT, OUString::number( nGluePointId ));
2589 if( xProps->getPropertyValue("PolyPolygonBezier") >>= aAny )
2591 // get PolygonBezier
2592 drawing::PolyPolygonBezierCoords const * pSourcePolyPolygon = static_cast<drawing::PolyPolygonBezierCoords const *>(aAny.getValue());
2594 if(pSourcePolyPolygon && pSourcePolyPolygon->Coordinates.getLength())
2596 const basegfx::B2DPolyPolygon aPolyPolygon(
2597 basegfx::tools::UnoPolyPolygonBezierCoordsToB2DPolyPolygon(
2598 *pSourcePolyPolygon));
2599 const OUString aPolygonString(
2600 basegfx::tools::exportToSvgD(
2601 aPolyPolygon,
2602 true, // bUseRelativeCoordinates
2603 false, // bDetectQuadraticBeziers: not used in old, but maybe activated now
2604 true)); // bHandleRelativeNextPointCompatible
2606 // write point array
2607 mrExport.AddAttribute(XML_NAMESPACE_SVG, XML_D, aPolygonString);
2611 // get matrix
2612 ::basegfx::B2DHomMatrix aMatrix;
2613 ImpExportNewTrans_GetB2DHomMatrix(aMatrix, xProps);
2615 // decompose and correct about pRefPoint
2616 ::basegfx::B2DTuple aTRScale;
2617 double fTRShear(0.0);
2618 double fTRRotate(0.0);
2619 ::basegfx::B2DTuple aTRTranslate;
2620 ImpExportNewTrans_DecomposeAndRefPoint(aMatrix, aTRScale, fTRShear,
2621 fTRRotate, aTRTranslate, pRefPoint);
2623 // fdo#49678: create and export ViewBox
2624 awt::Point aPoint(0, 0);
2625 awt::Size aSize(FRound(aTRScale.getX()), FRound(aTRScale.getY()));
2626 SdXMLImExViewBox aViewBox(0, 0, aSize.Width, aSize.Height);
2627 mrExport.AddAttribute(XML_NAMESPACE_SVG, XML_VIEWBOX, aViewBox.GetExportString());
2629 // write connector shape. Add Export later.
2630 bool bCreateNewline( (nFeatures & XMLShapeExportFlags::NO_WS) == XMLShapeExportFlags::NONE ); // #86116#/#92210#
2631 SvXMLElementExport aOBJ(mrExport, XML_NAMESPACE_DRAW, XML_CONNECTOR, bCreateNewline, true);
2633 ImpExportDescription( xShape ); // #i68101#
2634 ImpExportEvents( xShape );
2635 ImpExportGluePoints( xShape );
2636 ImpExportText( xShape );
2639 void XMLShapeExport::ImpExportMeasureShape(
2640 const uno::Reference< drawing::XShape >& xShape,
2641 XmlShapeType, XMLShapeExportFlags nFeatures /* = SEF_DEFAULT */, awt::Point* pRefPoint /* = NULL */)
2643 uno::Reference< beans::XPropertySet > xProps( xShape, uno::UNO_QUERY );
2645 OUString aStr;
2646 OUStringBuffer sStringBuffer;
2648 // export start and end point
2649 awt::Point aStart(0,0);
2650 awt::Point aEnd(1,1);
2652 /* Get <StartPositionInHoriL2R> and
2653 <EndPositionInHoriL2R>, if they exist and if the document is exported
2654 into the OpenOffice.org file format.
2655 These properties only exist at service com::sun::star::text::Shape - the
2656 Writer UNO service for shapes.
2657 This code is needed, because the positioning attributes in the
2658 OpenOffice.org file format are given in horizontal left-to-right layout
2659 regardless the layout direction the shape is in. In the OASIS Open Office
2660 file format the positioning attributes are correctly given in the layout
2661 direction the shape is in. Thus, this code provides the conversion from
2662 the OASIS Open Office file format to the OpenOffice.org file format. (#i36248#)
2664 if ( !( GetExport().getExportFlags() & SvXMLExportFlags::OASIS ) &&
2665 xProps->getPropertySetInfo()->hasPropertyByName("StartPositionInHoriL2R") &&
2666 xProps->getPropertySetInfo()->hasPropertyByName("EndPositionInHoriL2R") )
2668 xProps->getPropertyValue("StartPositionInHoriL2R") >>= aStart;
2669 xProps->getPropertyValue("EndPositionInHoriL2R") >>= aEnd;
2671 else
2673 xProps->getPropertyValue("StartPosition") >>= aStart;
2674 xProps->getPropertyValue("EndPosition") >>= aEnd;
2677 if( pRefPoint )
2679 aStart.X -= pRefPoint->X;
2680 aStart.Y -= pRefPoint->Y;
2681 aEnd.X -= pRefPoint->X;
2682 aEnd.Y -= pRefPoint->Y;
2685 if( nFeatures & XMLShapeExportFlags::X )
2687 // svg: x1
2688 mrExport.GetMM100UnitConverter().convertMeasureToXML(sStringBuffer,
2689 aStart.X);
2690 aStr = sStringBuffer.makeStringAndClear();
2691 mrExport.AddAttribute(XML_NAMESPACE_SVG, XML_X1, aStr);
2693 else
2695 aEnd.X -= aStart.X;
2698 if( nFeatures & XMLShapeExportFlags::Y )
2700 // svg: y1
2701 mrExport.GetMM100UnitConverter().convertMeasureToXML(sStringBuffer,
2702 aStart.Y);
2703 aStr = sStringBuffer.makeStringAndClear();
2704 mrExport.AddAttribute(XML_NAMESPACE_SVG, XML_Y1, aStr);
2706 else
2708 aEnd.Y -= aStart.Y;
2711 // svg: x2
2712 mrExport.GetMM100UnitConverter().convertMeasureToXML(sStringBuffer, aEnd.X);
2713 aStr = sStringBuffer.makeStringAndClear();
2714 mrExport.AddAttribute(XML_NAMESPACE_SVG, XML_X2, aStr);
2716 // svg: y2
2717 mrExport.GetMM100UnitConverter().convertMeasureToXML(sStringBuffer, aEnd.Y);
2718 aStr = sStringBuffer.makeStringAndClear();
2719 mrExport.AddAttribute(XML_NAMESPACE_SVG, XML_Y2, aStr);
2721 // write measure shape
2722 bool bCreateNewline( (nFeatures & XMLShapeExportFlags::NO_WS) == XMLShapeExportFlags::NONE ); // #86116#/#92210#
2723 SvXMLElementExport aOBJ(mrExport, XML_NAMESPACE_DRAW, XML_MEASURE, bCreateNewline, true);
2725 ImpExportDescription( xShape ); // #i68101#
2726 ImpExportEvents( xShape );
2727 ImpExportGluePoints( xShape );
2729 uno::Reference< text::XText > xText( xShape, uno::UNO_QUERY );
2730 if( xText.is() )
2731 mrExport.GetTextParagraphExport()->exportText( xText );
2734 void XMLShapeExport::ImpExportOLE2Shape(
2735 const uno::Reference< drawing::XShape >& xShape,
2736 XmlShapeType eShapeType, XMLShapeExportFlags nFeatures /* = SEF_DEFAULT */, awt::Point* pRefPoint /* = NULL */,
2737 SvXMLAttributeList* pAttrList /* = NULL */ )
2739 uno::Reference< beans::XPropertySet > xPropSet(xShape, uno::UNO_QUERY);
2740 uno::Reference< container::XNamed > xNamed(xShape, uno::UNO_QUERY);
2742 DBG_ASSERT( xPropSet.is() && xNamed.is(), "ole shape is not implementing needed interfaces");
2743 if(xPropSet.is() && xNamed.is())
2745 // Transformation
2746 ImpExportNewTrans(xPropSet, nFeatures, pRefPoint);
2748 bool bIsEmptyPresObj = false;
2750 // presentation settings
2751 if(eShapeType == XmlShapeTypePresOLE2Shape)
2752 bIsEmptyPresObj = ImpExportPresentationAttributes( xPropSet, GetXMLToken(XML_PRESENTATION_OBJECT) );
2753 else if(eShapeType == XmlShapeTypePresChartShape)
2754 bIsEmptyPresObj = ImpExportPresentationAttributes( xPropSet, GetXMLToken(XML_PRESENTATION_CHART) );
2755 else if(eShapeType == XmlShapeTypePresSheetShape)
2756 bIsEmptyPresObj = ImpExportPresentationAttributes( xPropSet, GetXMLToken(XML_PRESENTATION_TABLE) );
2758 bool bCreateNewline( (nFeatures & XMLShapeExportFlags::NO_WS) == XMLShapeExportFlags::NONE ); // #86116#/#92210#
2759 bool bExportEmbedded(mrExport.getExportFlags() & SvXMLExportFlags::EMBEDDED);
2760 OUString sPersistName;
2761 SvXMLElementExport aElement( mrExport, XML_NAMESPACE_DRAW,
2762 XML_FRAME, bCreateNewline, true );
2764 const bool bSaveBackwardsCompatible = bool( mrExport.getExportFlags() & SvXMLExportFlags::SAVEBACKWARDCOMPATIBLE );
2766 if( !bIsEmptyPresObj || bSaveBackwardsCompatible )
2768 if (pAttrList)
2770 mrExport.AddAttributeList(pAttrList);
2773 OUString sClassId;
2774 OUString sURL;
2775 bool bInternal = false;
2776 xPropSet->getPropertyValue("IsInternal") >>= bInternal;
2778 if( !bIsEmptyPresObj )
2781 if ( bInternal )
2783 // OOo internal links have no storage persistence, URL is stored in the XML file
2784 // the result LinkURL is empty in case the object is not a link
2785 xPropSet->getPropertyValue("LinkURL") >>= sURL;
2788 xPropSet->getPropertyValue("PersistName") >>= sPersistName;
2789 if ( sURL.isEmpty() )
2791 if( !sPersistName.isEmpty() )
2793 sURL = "vnd.sun.star.EmbeddedObject:" + sPersistName;
2797 if( !bInternal )
2798 xPropSet->getPropertyValue("CLSID") >>= sClassId;
2800 if( !sClassId.isEmpty() )
2801 mrExport.AddAttribute(XML_NAMESPACE_DRAW, XML_CLASS_ID, sClassId );
2803 if(supportsText(eShapeType))
2805 // #i118485# Add text export, the draw OLE shape allows text now
2806 // fdo#58571 chart objects don't allow text:p
2807 ImpExportText( xShape, TextPNS::EXTENSION );
2810 if(!bExportEmbedded)
2812 // xlink:href
2813 if( !sURL.isEmpty() )
2815 // #96717# in theorie, if we don't have a url we shouldn't even
2816 // export this ole shape. But practical its to risky right now
2817 // to change this so we better dispose this on load
2818 sURL = mrExport.AddEmbeddedObject( sURL );
2820 mrExport.AddAttribute(XML_NAMESPACE_XLINK, XML_HREF, sURL );
2821 mrExport.AddAttribute( XML_NAMESPACE_XLINK, XML_TYPE, XML_SIMPLE );
2822 mrExport.AddAttribute( XML_NAMESPACE_XLINK, XML_SHOW, XML_EMBED );
2823 mrExport.AddAttribute( XML_NAMESPACE_XLINK, XML_ACTUATE, XML_ONLOAD );
2827 else
2829 // export empty href for empty placeholders to be valid ODF
2830 OUString sEmptyURL;
2832 mrExport.AddAttribute(XML_NAMESPACE_XLINK, XML_HREF, sEmptyURL );
2833 mrExport.AddAttribute( XML_NAMESPACE_XLINK, XML_TYPE, XML_SIMPLE );
2834 mrExport.AddAttribute( XML_NAMESPACE_XLINK, XML_SHOW, XML_EMBED );
2835 mrExport.AddAttribute( XML_NAMESPACE_XLINK, XML_ACTUATE, XML_ONLOAD );
2838 enum XMLTokenEnum eElem = sClassId.isEmpty() ? XML_OBJECT : XML_OBJECT_OLE ;
2839 SvXMLElementExport aElem( mrExport, XML_NAMESPACE_DRAW, eElem, true, true );
2841 if(bExportEmbedded && !bIsEmptyPresObj)
2843 // #100592#
2844 if(bInternal)
2846 // embedded XML
2847 uno::Reference< lang::XComponent > xComp;
2848 xPropSet->getPropertyValue("Model") >>= xComp;
2849 DBG_ASSERT( xComp.is(), "no xModel for own OLE format" );
2850 mrExport.ExportEmbeddedOwnObject( xComp );
2852 else
2854 // embed as Base64
2855 // this is an alien object ( currently MSOLE is the only supported type of such objects )
2856 // in case it is not an OASIS format the object should be asked to store replacement image if possible
2858 OUString sURLRequest( sURL );
2859 if ( !( mrExport.getExportFlags() & SvXMLExportFlags::OASIS ) )
2860 sURLRequest += "?oasis=false";
2861 mrExport.AddEmbeddedObjectAsBase64( sURLRequest );
2865 if( !bIsEmptyPresObj )
2867 OUString sURL( "vnd.sun.star.GraphicObject:" );
2868 sURL += sPersistName;
2869 if( !bExportEmbedded )
2871 sURL = GetExport().AddEmbeddedObject( sURL );
2872 mrExport.AddAttribute(XML_NAMESPACE_XLINK, XML_HREF, sURL );
2873 mrExport.AddAttribute( XML_NAMESPACE_XLINK, XML_TYPE, XML_SIMPLE );
2874 mrExport.AddAttribute( XML_NAMESPACE_XLINK, XML_SHOW, XML_EMBED );
2875 mrExport.AddAttribute( XML_NAMESPACE_XLINK, XML_ACTUATE, XML_ONLOAD );
2878 SvXMLElementExport aElem( GetExport(), XML_NAMESPACE_DRAW,
2879 XML_IMAGE, false, true );
2881 if( bExportEmbedded )
2882 GetExport().AddEmbeddedObjectAsBase64( sURL );
2885 ImpExportEvents( xShape );
2886 ImpExportGluePoints( xShape );
2887 ImpExportDescription( xShape ); // #i68101#
2891 void XMLShapeExport::ImpExportPageShape(
2892 const uno::Reference< drawing::XShape >& xShape,
2893 XmlShapeType eShapeType, XMLShapeExportFlags nFeatures /* = SEF_DEFAULT */, awt::Point* pRefPoint /* = NULL */)
2895 const uno::Reference< beans::XPropertySet > xPropSet(xShape, uno::UNO_QUERY);
2896 if(xPropSet.is())
2898 // #86163# Transformation
2899 ImpExportNewTrans(xPropSet, nFeatures, pRefPoint);
2901 // export page number used for this page
2902 uno::Reference< beans::XPropertySetInfo > xPropSetInfo( xPropSet->getPropertySetInfo() );
2903 const OUString aPageNumberStr("PageNumber");
2904 if( xPropSetInfo.is() && xPropSetInfo->hasPropertyByName(aPageNumberStr))
2906 sal_Int32 nPageNumber = 0;
2907 xPropSet->getPropertyValue(aPageNumberStr) >>= nPageNumber;
2908 if( nPageNumber )
2909 mrExport.AddAttribute(XML_NAMESPACE_DRAW, XML_PAGE_NUMBER, OUString::number(nPageNumber));
2912 // a presentation page shape, normally used on notes pages only. If
2913 // it is used not as presentation shape, it may have been created with
2914 // copy-paste exchange between draw and impress (this IS possible...)
2915 if(eShapeType == XmlShapeTypePresPageShape)
2917 mrExport.AddAttribute(XML_NAMESPACE_PRESENTATION, XML_CLASS,
2918 XML_PRESENTATION_PAGE);
2921 // write Page shape
2922 bool bCreateNewline( (nFeatures & XMLShapeExportFlags::NO_WS) == XMLShapeExportFlags::NONE ); // #86116#/#92210#
2923 SvXMLElementExport aOBJ(mrExport, XML_NAMESPACE_DRAW, XML_PAGE_THUMBNAIL, bCreateNewline, true);
2927 void XMLShapeExport::ImpExportCaptionShape(
2928 const uno::Reference< drawing::XShape >& xShape,
2929 XmlShapeType, XMLShapeExportFlags nFeatures /* = SEF_DEFAULT */, awt::Point* pRefPoint /* = NULL */)
2931 const uno::Reference< beans::XPropertySet > xPropSet(xShape, uno::UNO_QUERY);
2932 if(xPropSet.is())
2934 // Transformation
2935 ImpExportNewTrans(xPropSet, nFeatures, pRefPoint);
2937 // evtl. corner radius?
2938 sal_Int32 nCornerRadius(0L);
2939 xPropSet->getPropertyValue("CornerRadius") >>= nCornerRadius;
2940 if(nCornerRadius)
2942 OUStringBuffer sStringBuffer;
2943 mrExport.GetMM100UnitConverter().convertMeasureToXML(sStringBuffer,
2944 nCornerRadius);
2945 mrExport.AddAttribute(XML_NAMESPACE_DRAW, XML_CORNER_RADIUS, sStringBuffer.makeStringAndClear());
2948 awt::Point aCaptionPoint;
2949 xPropSet->getPropertyValue("CaptionPoint") >>= aCaptionPoint;
2951 mrExport.GetMM100UnitConverter().convertMeasureToXML(msBuffer,
2952 aCaptionPoint.X);
2953 mrExport.AddAttribute( XML_NAMESPACE_DRAW, XML_CAPTION_POINT_X, msBuffer.makeStringAndClear() );
2954 mrExport.GetMM100UnitConverter().convertMeasureToXML(msBuffer,
2955 aCaptionPoint.Y);
2956 mrExport.AddAttribute( XML_NAMESPACE_DRAW, XML_CAPTION_POINT_Y, msBuffer.makeStringAndClear() );
2958 // write Caption shape. Add export later.
2959 bool bCreateNewline( (nFeatures & XMLShapeExportFlags::NO_WS) == XMLShapeExportFlags::NONE ); // #86116#/#92210#
2960 bool bAnnotation( (nFeatures & XMLShapeExportFlags::ANNOTATION) == XMLShapeExportFlags::ANNOTATION );
2962 SvXMLElementExport aObj( mrExport,
2963 (bAnnotation ? XML_NAMESPACE_OFFICE
2964 : XML_NAMESPACE_DRAW),
2965 (bAnnotation ? XML_ANNOTATION : XML_CAPTION),
2966 bCreateNewline, true );
2968 ImpExportDescription( xShape ); // #i68101#
2969 ImpExportEvents( xShape );
2970 ImpExportGluePoints( xShape );
2971 if( bAnnotation )
2972 mrExport.exportAnnotationMeta( xShape );
2973 ImpExportText( xShape );
2977 void XMLShapeExport::ImpExportFrameShape(
2978 const uno::Reference< drawing::XShape >& xShape,
2979 XmlShapeType, XMLShapeExportFlags nFeatures, com::sun::star::awt::Point* pRefPoint)
2981 const uno::Reference< beans::XPropertySet > xPropSet(xShape, uno::UNO_QUERY);
2982 if(xPropSet.is())
2984 // Transformation
2985 ImpExportNewTrans(xPropSet, nFeatures, pRefPoint);
2987 bool bCreateNewline( (nFeatures & XMLShapeExportFlags::NO_WS) == XMLShapeExportFlags::NONE ); // #86116#/#92210#
2988 SvXMLElementExport aElem( mrExport, XML_NAMESPACE_DRAW,
2989 XML_FRAME, bCreateNewline, true );
2991 // export frame url
2992 OUString aStr;
2993 xPropSet->getPropertyValue("FrameURL") >>= aStr;
2994 mrExport.AddAttribute ( XML_NAMESPACE_XLINK, XML_HREF, GetExport().GetRelativeReference(aStr) );
2995 mrExport.AddAttribute ( XML_NAMESPACE_XLINK, XML_TYPE, XML_SIMPLE );
2996 mrExport.AddAttribute ( XML_NAMESPACE_XLINK, XML_SHOW, XML_EMBED );
2997 mrExport.AddAttribute ( XML_NAMESPACE_XLINK, XML_ACTUATE, XML_ONLOAD );
2999 // export name
3000 xPropSet->getPropertyValue("FrameName") >>= aStr;
3001 if( !aStr.isEmpty() )
3002 mrExport.AddAttribute( XML_NAMESPACE_DRAW, XML_FRAME_NAME, aStr );
3004 // write floating frame
3006 SvXMLElementExport aOBJ(mrExport, XML_NAMESPACE_DRAW, XML_FLOATING_FRAME, true, true);
3011 void XMLShapeExport::ImpExportAppletShape(
3012 const uno::Reference< drawing::XShape >& xShape,
3013 XmlShapeType, XMLShapeExportFlags nFeatures, com::sun::star::awt::Point* pRefPoint)
3015 const uno::Reference< beans::XPropertySet > xPropSet(xShape, uno::UNO_QUERY);
3016 if(xPropSet.is())
3018 // Transformation
3019 ImpExportNewTrans(xPropSet, nFeatures, pRefPoint);
3021 bool bCreateNewline( (nFeatures & XMLShapeExportFlags::NO_WS) == XMLShapeExportFlags::NONE ); // #86116#/#92210#
3022 SvXMLElementExport aElement( mrExport, XML_NAMESPACE_DRAW,
3023 XML_FRAME, bCreateNewline, true );
3025 // export frame url
3026 OUString aStr;
3027 xPropSet->getPropertyValue("AppletCodeBase") >>= aStr;
3028 mrExport.AddAttribute ( XML_NAMESPACE_XLINK, XML_HREF, GetExport().GetRelativeReference(aStr) );
3029 mrExport.AddAttribute ( XML_NAMESPACE_XLINK, XML_TYPE, XML_SIMPLE );
3030 mrExport.AddAttribute ( XML_NAMESPACE_XLINK, XML_SHOW, XML_EMBED );
3031 mrExport.AddAttribute ( XML_NAMESPACE_XLINK, XML_ACTUATE, XML_ONLOAD );
3033 // export draw:applet-name
3034 xPropSet->getPropertyValue("AppletName") >>= aStr;
3035 if( !aStr.isEmpty() )
3036 mrExport.AddAttribute( XML_NAMESPACE_DRAW, XML_APPLET_NAME, aStr );
3038 // export draw:code
3039 xPropSet->getPropertyValue("AppletCode") >>= aStr;
3040 mrExport.AddAttribute( XML_NAMESPACE_DRAW, XML_CODE, aStr );
3042 // export draw:may-script
3043 bool bIsScript = false;
3044 xPropSet->getPropertyValue("AppletIsScript") >>= bIsScript;
3045 mrExport.AddAttribute( XML_NAMESPACE_DRAW, XML_MAY_SCRIPT, bIsScript ? XML_TRUE : XML_FALSE );
3048 // write applet
3049 SvXMLElementExport aOBJ(mrExport, XML_NAMESPACE_DRAW, XML_APPLET, true, true);
3051 // export parameters
3052 uno::Sequence< beans::PropertyValue > aCommands;
3053 xPropSet->getPropertyValue("AppletCommands") >>= aCommands;
3054 const sal_Int32 nCount = aCommands.getLength();
3055 for( sal_Int32 nIndex = 0; nIndex < nCount; nIndex++ )
3057 aCommands[nIndex].Value >>= aStr;
3058 mrExport.AddAttribute( XML_NAMESPACE_DRAW, XML_NAME, aCommands[nIndex].Name );
3059 mrExport.AddAttribute( XML_NAMESPACE_DRAW, XML_VALUE, aStr );
3060 SvXMLElementExport aElem( mrExport, XML_NAMESPACE_DRAW, XML_PARAM, false, true );
3066 void XMLShapeExport::ImpExportPluginShape(
3067 const uno::Reference< drawing::XShape >& xShape,
3068 XmlShapeType, XMLShapeExportFlags nFeatures, com::sun::star::awt::Point* pRefPoint)
3070 const uno::Reference< beans::XPropertySet > xPropSet(xShape, uno::UNO_QUERY);
3071 if(xPropSet.is())
3073 // Transformation
3074 ImpExportNewTrans(xPropSet, nFeatures, pRefPoint);
3076 bool bCreateNewline( (nFeatures & XMLShapeExportFlags::NO_WS) == XMLShapeExportFlags::NONE ); // #86116#/#92210#
3077 SvXMLElementExport aElement( mrExport, XML_NAMESPACE_DRAW,
3078 XML_FRAME, bCreateNewline, true );
3080 // export plugin url
3081 OUString aStr;
3082 xPropSet->getPropertyValue("PluginURL") >>= aStr;
3083 mrExport.AddAttribute ( XML_NAMESPACE_XLINK, XML_HREF, GetExport().GetRelativeReference(aStr) );
3084 mrExport.AddAttribute ( XML_NAMESPACE_XLINK, XML_TYPE, XML_SIMPLE );
3085 mrExport.AddAttribute ( XML_NAMESPACE_XLINK, XML_SHOW, XML_EMBED );
3086 mrExport.AddAttribute ( XML_NAMESPACE_XLINK, XML_ACTUATE, XML_ONLOAD );
3088 // export mime-type
3089 xPropSet->getPropertyValue("PluginMimeType") >>= aStr;
3090 if(!aStr.isEmpty())
3091 mrExport.AddAttribute( XML_NAMESPACE_DRAW, XML_MIME_TYPE, aStr );
3094 // write plugin
3095 SvXMLElementExport aOBJ(mrExport, XML_NAMESPACE_DRAW, XML_PLUGIN, true, true);
3097 // export parameters
3098 uno::Sequence< beans::PropertyValue > aCommands;
3099 xPropSet->getPropertyValue("PluginCommands") >>= aCommands;
3100 const sal_Int32 nCount = aCommands.getLength();
3101 for( sal_Int32 nIndex = 0; nIndex < nCount; nIndex++ )
3103 aCommands[nIndex].Value >>= aStr;
3104 mrExport.AddAttribute( XML_NAMESPACE_DRAW, XML_NAME, aCommands[nIndex].Name );
3105 mrExport.AddAttribute( XML_NAMESPACE_DRAW, XML_VALUE, aStr );
3106 SvXMLElementExport aElem( mrExport, XML_NAMESPACE_DRAW, XML_PARAM, false, true );
3112 static void lcl_CopyStream(
3113 uno::Reference<io::XInputStream> const& xInStream,
3114 uno::Reference<embed::XStorage> const& xTarget,
3115 OUString const& rPath, const OUString& rMimeType)
3117 ::comphelper::LifecycleProxy proxy;
3118 uno::Reference<io::XStream> const xStream(
3119 ::comphelper::OStorageHelper::GetStreamAtPackageURL(xTarget, rPath,
3120 embed::ElementModes::WRITE | embed::ElementModes::TRUNCATE, proxy));
3121 uno::Reference<io::XOutputStream> const xOutStream(
3122 (xStream.is()) ? xStream->getOutputStream() : 0);
3123 if (!xOutStream.is())
3125 SAL_WARN("xmloff", "no output stream");
3126 throw uno::Exception("no output stream",0);
3128 uno::Reference< beans::XPropertySet > const xStreamProps(xStream,
3129 uno::UNO_QUERY);
3130 if (xStreamProps.is()) { // this is NOT supported in FileSystemStorage
3131 xStreamProps->setPropertyValue("MediaType",
3132 uno::makeAny(rMimeType));
3133 xStreamProps->setPropertyValue( // turn off compression
3134 "Compressed",
3135 uno::makeAny(sal_False));
3137 ::comphelper::OStorageHelper::CopyInputToOutput(xInStream, xOutStream);
3138 xOutStream->closeOutput();
3139 proxy.commitStorages();
3142 static OUString
3143 lcl_StoreMediaAndGetURL(SvXMLExport & rExport,
3144 uno::Reference<beans::XPropertySet> const& xPropSet,
3145 OUString const& rURL, const OUString& rMimeType)
3147 OUString urlPath;
3148 if (rURL.startsWithIgnoreAsciiCase("vnd.sun.star.Package:", &urlPath))
3150 try // video is embedded
3152 uno::Reference<embed::XStorage> const xTarget(
3153 rExport.GetTargetStorage(), uno::UNO_QUERY_THROW);
3154 uno::Reference<io::XInputStream> xInStream;
3155 xPropSet->getPropertyValue("PrivateStream")
3156 >>= xInStream;
3158 if (!xInStream.is())
3160 SAL_WARN("xmloff", "no input stream");
3161 return OUString();
3164 lcl_CopyStream(xInStream, xTarget, rURL, rMimeType);
3166 return urlPath;
3168 catch (uno::Exception const& e)
3170 SAL_INFO("xmloff", "exception while storing embedded media: '"
3171 << e.Message << "'");
3173 return OUString();
3175 else
3177 return rExport.GetRelativeReference(rURL); // linked
3181 #if HAVE_FEATURE_GLTF
3182 static void lcl_StoreGltfExternals(
3183 SvXMLExport& rExport,
3184 const OUString& rURL )
3186 OUString sUrlPath;
3187 if (rURL.startsWithIgnoreAsciiCase("vnd.sun.star.Package:", &sUrlPath))
3189 sUrlPath = sUrlPath.copy(0,sUrlPath.lastIndexOf("/"));
3192 // Base storage
3193 uno::Reference<document::XStorageBasedDocument> const xSBD(
3194 rExport.GetModel(), uno::UNO_QUERY_THROW);
3195 const uno::Reference<embed::XStorage> xStorage(
3196 xSBD->getDocumentStorage(), uno::UNO_QUERY_THROW);
3198 // Model source
3199 ::comphelper::LifecycleProxy proxy;
3200 const uno::Reference<embed::XStorage> xModelStorage(
3201 ::comphelper::OStorageHelper::GetStorageAtPath(xStorage, sUrlPath,
3202 embed::ElementModes::READ, proxy));
3204 // Target storage
3205 uno::Reference<embed::XStorage> const xTarget(
3206 rExport.GetTargetStorage(), uno::UNO_QUERY_THROW);
3208 // Target of all models
3209 const uno::Reference<embed::XStorage> xModelsTarget(
3210 xTarget->openStorageElement(sUrlPath.copy(0,sUrlPath.lastIndexOf("/")), embed::ElementModes::WRITE));
3212 // Target of current model
3213 const OUString sModelName = sUrlPath.copy(sUrlPath.lastIndexOf("/")+1);
3214 const uno::Reference<embed::XStorage> xModelTarget(
3215 xModelsTarget->openStorageElement(sModelName, embed::ElementModes::WRITE));
3217 xModelStorage->copyToStorage(xModelTarget);
3219 const uno::Reference<embed::XTransactedObject> xModelsTransaction(xModelsTarget, uno::UNO_QUERY);
3220 if (xModelsTransaction.is())
3222 xModelsTransaction->commit();
3225 catch (uno::Exception const& e)
3227 SAL_INFO("xmloff", "exception while saving embedded model: '" << e.Message << "'");
3232 static void lcl_StoreGltfFallback(
3233 SvXMLExport& rExport,
3234 const uno::Reference<beans::XPropertySet>& rPropSet,
3235 const OUString& rURL )
3237 OUString sUrlPath;
3238 if (rURL.startsWithIgnoreAsciiCase("vnd.sun.star.Package:", &sUrlPath))
3240 sUrlPath = sUrlPath.copy(0,sUrlPath.lastIndexOf("/"));
3243 // Base storage
3244 uno::Reference<document::XStorageBasedDocument> const xSBD(
3245 rExport.GetModel(), uno::UNO_QUERY_THROW);
3246 const uno::Reference<embed::XStorage> xStorage(
3247 xSBD->getDocumentStorage(), uno::UNO_QUERY_THROW);
3249 // Model source
3250 ::comphelper::LifecycleProxy proxy;
3251 const uno::Reference<embed::XStorage> xModelStorage(
3252 ::comphelper::OStorageHelper::GetStorageAtPath(xStorage, sUrlPath,
3253 embed::ElementModes::READ, proxy));
3255 // Target storage
3256 uno::Reference<embed::XStorage> const xTarget(
3257 rExport.GetTargetStorage(), uno::UNO_QUERY_THROW);
3259 // Target of all models
3260 const uno::Reference<embed::XStorage> xModelsTarget(
3261 xTarget->openStorageElement(sUrlPath.copy(0,sUrlPath.lastIndexOf("/")), embed::ElementModes::WRITE));
3263 /// Save the fallback image under the 'Models/Fallbacks/' folder
3264 uno::Reference< graphic::XGraphic > xGraphic( rPropSet->getPropertyValue("FallbackGraphic"), uno::UNO_QUERY );
3265 if( xGraphic.is() )
3267 // Fallback storage
3268 const uno::Reference<embed::XStorage> xFallbackTarget(
3269 xModelsTarget->openStorageElement("Fallbacks", embed::ElementModes::WRITE));
3271 const OUString sModelName = sUrlPath.copy(sUrlPath.lastIndexOf("/")+1);
3272 uno::Reference< io::XStream > xPictureStream(
3273 xFallbackTarget->openStreamElement( sModelName + ".png", embed::ElementModes::WRITE ), uno::UNO_QUERY_THROW );
3275 uno::Reference< graphic::XGraphicProvider > xProvider( graphic::GraphicProvider::create(comphelper::getProcessComponentContext()) );
3276 uno::Sequence< beans::PropertyValue > aArgs( 2 );
3277 aArgs[ 0 ].Name = "MimeType";
3278 aArgs[ 0 ].Value <<= OUString( "image/png" );
3279 aArgs[ 1 ].Name = "OutputStream";
3280 aArgs[ 1 ].Value <<= xPictureStream->getOutputStream();
3281 xProvider->storeGraphic( xGraphic, aArgs );
3283 const uno::Reference<embed::XTransactedObject> xFallbackTransaction(xFallbackTarget, uno::UNO_QUERY);
3284 if (xFallbackTransaction.is())
3286 xFallbackTransaction->commit();
3289 const OUString sFallbackURL( sUrlPath.copy(0,sUrlPath.lastIndexOf("/")) + "/Fallbacks/" + sModelName + ".png");
3290 rExport.AddAttribute(XML_NAMESPACE_XLINK, XML_HREF, sFallbackURL );
3291 rExport.AddAttribute( XML_NAMESPACE_XLINK, XML_TYPE, XML_SIMPLE );
3292 rExport.AddAttribute( XML_NAMESPACE_XLINK, XML_SHOW, XML_EMBED );
3293 rExport.AddAttribute( XML_NAMESPACE_XLINK, XML_ACTUATE, XML_ONLOAD );
3295 SvXMLElementExport aImage( rExport, XML_NAMESPACE_DRAW, XML_IMAGE, false, true );
3298 const uno::Reference<embed::XTransactedObject> xModelsTransaction(xModelsTarget, uno::UNO_QUERY);
3299 if (xModelsTransaction.is())
3301 xModelsTransaction->commit();
3304 catch (uno::Exception const& e)
3306 SAL_INFO("xmloff", "exception while saving fallback image of glTF model: '" << e.Message << "'");
3311 #endif
3313 void XMLShapeExport::ImpExportMediaShape(
3314 const uno::Reference< drawing::XShape >& xShape,
3315 XmlShapeType eShapeType, XMLShapeExportFlags nFeatures, com::sun::star::awt::Point* pRefPoint)
3317 const uno::Reference< beans::XPropertySet > xPropSet(xShape, uno::UNO_QUERY);
3318 if(xPropSet.is())
3320 // Transformation
3321 ImpExportNewTrans(xPropSet, nFeatures, pRefPoint);
3323 if(eShapeType == XmlShapeTypePresMediaShape)
3325 (void)ImpExportPresentationAttributes( xPropSet, GetXMLToken(XML_PRESENTATION_OBJECT) );
3327 bool bCreateNewline( (nFeatures & XMLShapeExportFlags::NO_WS) == XMLShapeExportFlags::NONE ); // #86116#/#92210#
3328 SvXMLElementExport aElem( mrExport, XML_NAMESPACE_DRAW,
3329 XML_FRAME, bCreateNewline, true );
3331 // export media url
3332 OUString aMediaURL;
3333 xPropSet->getPropertyValue("MediaURL") >>= aMediaURL;
3334 OUString sMimeType;
3335 xPropSet->getPropertyValue("MediaMimeType") >>= sMimeType;
3337 OUString const persistentURL =
3338 lcl_StoreMediaAndGetURL(GetExport(), xPropSet, aMediaURL, sMimeType);
3339 #if HAVE_FEATURE_GLTF
3340 if( sMimeType == "model/vnd.gltf+json" )
3341 lcl_StoreGltfExternals(GetExport(), aMediaURL);
3342 #endif
3344 mrExport.AddAttribute ( XML_NAMESPACE_XLINK, XML_HREF, persistentURL );
3345 mrExport.AddAttribute ( XML_NAMESPACE_XLINK, XML_TYPE, XML_SIMPLE );
3346 mrExport.AddAttribute ( XML_NAMESPACE_XLINK, XML_SHOW, XML_EMBED );
3347 mrExport.AddAttribute ( XML_NAMESPACE_XLINK, XML_ACTUATE, XML_ONLOAD );
3349 // export mime-type
3350 mrExport.AddAttribute( XML_NAMESPACE_DRAW, XML_MIME_TYPE, sMimeType );
3352 // write plugin
3353 SvXMLElementExport* pPluginOBJ = new SvXMLElementExport(mrExport, XML_NAMESPACE_DRAW, XML_PLUGIN, !( nFeatures & XMLShapeExportFlags::NO_WS ), true);
3355 // export parameters
3356 const OUString aFalseStr( "false" ), aTrueStr( "true" );
3358 bool bLoop = false;
3359 const OUString aLoopStr( "Loop" );
3360 xPropSet->getPropertyValue( aLoopStr ) >>= bLoop;
3361 mrExport.AddAttribute( XML_NAMESPACE_DRAW, XML_NAME, aLoopStr );
3362 mrExport.AddAttribute( XML_NAMESPACE_DRAW, XML_VALUE, bLoop ? aTrueStr : aFalseStr );
3363 delete( new SvXMLElementExport( mrExport, XML_NAMESPACE_DRAW, XML_PARAM, false, true ) );
3365 bool bMute = false;
3366 const OUString aMuteStr( "Mute" );
3367 xPropSet->getPropertyValue( aMuteStr ) >>= bMute;
3368 mrExport.AddAttribute( XML_NAMESPACE_DRAW, XML_NAME, aMuteStr );
3369 mrExport.AddAttribute( XML_NAMESPACE_DRAW, XML_VALUE, bMute ? aTrueStr : aFalseStr );
3370 delete( new SvXMLElementExport( mrExport, XML_NAMESPACE_DRAW, XML_PARAM, false, true ) );
3372 sal_Int16 nVolumeDB = 0;
3373 const OUString aVolumeDBStr( "VolumeDB" );
3374 xPropSet->getPropertyValue("VolumeDB") >>= nVolumeDB;
3375 mrExport.AddAttribute( XML_NAMESPACE_DRAW, XML_NAME, aVolumeDBStr );
3376 mrExport.AddAttribute( XML_NAMESPACE_DRAW, XML_VALUE, OUString::number( nVolumeDB ) );
3377 delete( new SvXMLElementExport( mrExport, XML_NAMESPACE_DRAW, XML_PARAM, false, true ) );
3379 media::ZoomLevel eZoom;
3380 const OUString aZoomStr( "Zoom" );
3381 OUString aZoomValue;
3382 xPropSet->getPropertyValue("Zoom") >>= eZoom;
3383 switch( eZoom )
3385 case( media::ZoomLevel_ZOOM_1_TO_4 ) : aZoomValue = "25%"; break;
3386 case( media::ZoomLevel_ZOOM_1_TO_2 ) : aZoomValue = "50%"; break;
3387 case( media::ZoomLevel_ORIGINAL ) : aZoomValue = "100%"; break;
3388 case( media::ZoomLevel_ZOOM_2_TO_1 ) : aZoomValue = "200%"; break;
3389 case( media::ZoomLevel_ZOOM_4_TO_1 ) : aZoomValue = "400%"; break;
3390 case( media::ZoomLevel_FIT_TO_WINDOW ): aZoomValue = "fit"; break;
3391 case( media::ZoomLevel_FIT_TO_WINDOW_FIXED_ASPECT ): aZoomValue = "fixedfit"; break;
3392 case( media::ZoomLevel_FULLSCREEN ) : aZoomValue = "fullscreen"; break;
3394 default:
3395 break;
3398 if( !aZoomValue.isEmpty() )
3400 mrExport.AddAttribute( XML_NAMESPACE_DRAW, XML_NAME, aZoomStr );
3401 mrExport.AddAttribute( XML_NAMESPACE_DRAW, XML_VALUE, aZoomValue );
3402 delete( new SvXMLElementExport( mrExport, XML_NAMESPACE_DRAW, XML_PARAM, false, true ) );
3405 delete pPluginOBJ;
3406 #if HAVE_FEATURE_GLTF
3407 if( sMimeType == "model/vnd.gltf+json" )
3408 lcl_StoreGltfFallback(GetExport(), xPropSet, aMediaURL);
3409 #endif
3413 void XMLShapeExport::ImpExport3DSceneShape( const uno::Reference< drawing::XShape >& xShape, XmlShapeType, XMLShapeExportFlags nFeatures, awt::Point* pRefPoint)
3415 uno::Reference< drawing::XShapes > xShapes(xShape, uno::UNO_QUERY);
3416 if(xShapes.is() && xShapes->getCount())
3418 uno::Reference< beans::XPropertySet > xPropSet( xShape, uno::UNO_QUERY );
3419 DBG_ASSERT( xPropSet.is(), "XMLShapeExport::ImpExport3DSceneShape can't export a scene without a propertyset" );
3420 if( xPropSet.is() )
3422 // Transformation
3423 ImpExportNewTrans(xPropSet, nFeatures, pRefPoint);
3425 // 3d attributes
3426 export3DSceneAttributes( xPropSet );
3428 // write 3DScene shape
3429 bool bCreateNewline( (nFeatures & XMLShapeExportFlags::NO_WS) == XMLShapeExportFlags::NONE ); // #86116#/#92210#
3430 SvXMLElementExport aOBJ( mrExport, XML_NAMESPACE_DR3D, XML_SCENE, bCreateNewline, true);
3432 ImpExportDescription( xShape ); // #i68101#
3433 ImpExportEvents( xShape );
3435 // write 3DSceneLights
3436 export3DLamps( xPropSet );
3438 // #89764# if export of position is suppressed for group shape,
3439 // positions of contained objects should be written relative to
3440 // the upper left edge of the group.
3441 awt::Point aUpperLeft;
3443 if(!(nFeatures & XMLShapeExportFlags::POSITION))
3445 nFeatures |= XMLShapeExportFlags::POSITION;
3446 aUpperLeft = xShape->getPosition();
3447 pRefPoint = &aUpperLeft;
3450 // write members
3451 exportShapes( xShapes, nFeatures, pRefPoint );
3456 void XMLShapeExport::ImpExport3DShape(
3457 const uno::Reference< drawing::XShape >& xShape,
3458 XmlShapeType eShapeType, XMLShapeExportFlags /* nFeatures = SEF_DEFAULT */, awt::Point* /*pRefPoint = NULL */)
3460 const uno::Reference< beans::XPropertySet > xPropSet(xShape, uno::UNO_QUERY);
3461 if(xPropSet.is())
3463 OUString aStr;
3464 OUStringBuffer sStringBuffer;
3466 // transformation (UNO_NAME_3D_TRANSFORM_MATRIX == "D3DTransformMatrix")
3467 uno::Any aAny = xPropSet->getPropertyValue("D3DTransformMatrix");
3468 drawing::HomogenMatrix xHomMat;
3469 aAny >>= xHomMat;
3470 SdXMLImExTransform3D aTransform;
3471 aTransform.AddHomogenMatrix(xHomMat);
3472 if(aTransform.NeedsAction())
3473 mrExport.AddAttribute(XML_NAMESPACE_DR3D, XML_TRANSFORM, aTransform.GetExportString(mrExport.GetMM100UnitConverter()));
3475 switch(eShapeType)
3477 case XmlShapeTypeDraw3DCubeObject:
3479 // minEdge
3480 aAny = xPropSet->getPropertyValue("D3DPosition");
3481 drawing::Position3D aPosition3D;
3482 aAny >>= aPosition3D;
3483 ::basegfx::B3DVector aPos3D(aPosition3D.PositionX, aPosition3D.PositionY, aPosition3D.PositionZ);
3485 // maxEdge
3486 aAny = xPropSet->getPropertyValue("D3DSize");
3487 drawing::Direction3D aDirection3D;
3488 aAny >>= aDirection3D;
3489 ::basegfx::B3DVector aDir3D(aDirection3D.DirectionX, aDirection3D.DirectionY, aDirection3D.DirectionZ);
3491 // transform maxEdge from distance to pos
3492 aDir3D = aPos3D + aDir3D;
3494 // write minEdge
3495 if(aPos3D != ::basegfx::B3DVector(-2500.0, -2500.0, -2500.0)) // write only when not default
3497 SvXMLUnitConverter::convertB3DVector(sStringBuffer, aPos3D);
3498 aStr = sStringBuffer.makeStringAndClear();
3499 mrExport.AddAttribute(XML_NAMESPACE_DR3D, XML_MIN_EDGE, aStr);
3502 // write maxEdge
3503 if(aDir3D != ::basegfx::B3DVector(2500.0, 2500.0, 2500.0)) // write only when not default
3505 SvXMLUnitConverter::convertB3DVector(sStringBuffer, aDir3D);
3506 aStr = sStringBuffer.makeStringAndClear();
3507 mrExport.AddAttribute(XML_NAMESPACE_DR3D, XML_MAX_EDGE, aStr);
3510 // write 3DCube shape
3511 // #i123542# Do this *after* the attributes are added, else these will be lost since opening
3512 // the scope will clear the global attribute list at the exporter
3513 SvXMLElementExport aOBJ(mrExport, XML_NAMESPACE_DR3D, XML_CUBE, true, true);
3515 break;
3517 case XmlShapeTypeDraw3DSphereObject:
3519 // Center
3520 aAny = xPropSet->getPropertyValue("D3DPosition");
3521 drawing::Position3D aPosition3D;
3522 aAny >>= aPosition3D;
3523 ::basegfx::B3DVector aPos3D(aPosition3D.PositionX, aPosition3D.PositionY, aPosition3D.PositionZ);
3525 // Size
3526 aAny = xPropSet->getPropertyValue("D3DSize");
3527 drawing::Direction3D aDirection3D;
3528 aAny >>= aDirection3D;
3529 ::basegfx::B3DVector aDir3D(aDirection3D.DirectionX, aDirection3D.DirectionY, aDirection3D.DirectionZ);
3531 // write Center
3532 if(aPos3D != ::basegfx::B3DVector(0.0, 0.0, 0.0)) // write only when not default
3534 SvXMLUnitConverter::convertB3DVector(sStringBuffer, aPos3D);
3535 aStr = sStringBuffer.makeStringAndClear();
3536 mrExport.AddAttribute(XML_NAMESPACE_DR3D, XML_CENTER, aStr);
3539 // write Size
3540 if(aDir3D != ::basegfx::B3DVector(5000.0, 5000.0, 5000.0)) // write only when not default
3542 SvXMLUnitConverter::convertB3DVector(sStringBuffer, aDir3D);
3543 aStr = sStringBuffer.makeStringAndClear();
3544 mrExport.AddAttribute(XML_NAMESPACE_DR3D, XML_SIZE, aStr);
3547 // write 3DSphere shape
3548 // #i123542# Do this *after* the attributes are added, else these will be lost since opening
3549 // the scope will clear the global attribute list at the exporter
3550 SvXMLElementExport aOBJ(mrExport, XML_NAMESPACE_DR3D, XML_SPHERE, true, true);
3552 break;
3554 case XmlShapeTypeDraw3DLatheObject:
3555 case XmlShapeTypeDraw3DExtrudeObject:
3557 // write special 3DLathe/3DExtrude attributes, get 3D tools::PolyPolygon as drawing::PolyPolygonShape3D
3558 aAny = xPropSet->getPropertyValue("D3DPolyPolygon3D");
3559 drawing::PolyPolygonShape3D xPolyPolygon3D;
3560 aAny >>= xPolyPolygon3D;
3562 // convert to 3D PolyPolygon
3563 const basegfx::B3DPolyPolygon aPolyPolygon3D(
3564 basegfx::tools::UnoPolyPolygonShape3DToB3DPolyPolygon(
3565 xPolyPolygon3D));
3567 // convert to 2D tools::PolyPolygon using identity 3D transformation (just grep X and Y)
3568 const basegfx::B3DHomMatrix aB3DHomMatrixFor2DConversion;
3569 const basegfx::B2DPolyPolygon aPolyPolygon(
3570 basegfx::tools::createB2DPolyPolygonFromB3DPolyPolygon(
3571 aPolyPolygon3D,
3572 aB3DHomMatrixFor2DConversion));
3574 // get 2D range of it
3575 const basegfx::B2DRange aPolyPolygonRange(aPolyPolygon.getB2DRange());
3577 // export ViewBox
3578 SdXMLImExViewBox aViewBox(
3579 aPolyPolygonRange.getMinX(),
3580 aPolyPolygonRange.getMinY(),
3581 aPolyPolygonRange.getWidth(),
3582 aPolyPolygonRange.getHeight());
3584 mrExport.AddAttribute(XML_NAMESPACE_SVG, XML_VIEWBOX, aViewBox.GetExportString());
3586 // prepare svg:d string
3587 const OUString aPolygonString(
3588 basegfx::tools::exportToSvgD(
3589 aPolyPolygon,
3590 true, // bUseRelativeCoordinates
3591 false, // bDetectQuadraticBeziers TTTT: not used in old, but maybe activated now
3592 true)); // bHandleRelativeNextPointCompatible
3594 // write point array
3595 mrExport.AddAttribute(XML_NAMESPACE_SVG, XML_D, aPolygonString);
3597 if(eShapeType == XmlShapeTypeDraw3DLatheObject)
3599 // write 3DLathe shape
3600 SvXMLElementExport aOBJ(mrExport, XML_NAMESPACE_DR3D, XML_ROTATE, true, true);
3602 else
3604 // write 3DExtrude shape
3605 SvXMLElementExport aOBJ(mrExport, XML_NAMESPACE_DR3D, XML_EXTRUDE, true, true);
3607 break;
3609 default:
3610 break;
3615 /** helper for chart that adds all attributes of a 3d scene element to the export */
3616 void XMLShapeExport::export3DSceneAttributes( const com::sun::star::uno::Reference< com::sun::star::beans::XPropertySet >& xPropSet )
3618 OUString aStr;
3619 OUStringBuffer sStringBuffer;
3621 // world transformation (UNO_NAME_3D_TRANSFORM_MATRIX == "D3DTransformMatrix")
3622 uno::Any aAny = xPropSet->getPropertyValue("D3DTransformMatrix");
3623 drawing::HomogenMatrix xHomMat;
3624 aAny >>= xHomMat;
3625 SdXMLImExTransform3D aTransform;
3626 aTransform.AddHomogenMatrix(xHomMat);
3627 if(aTransform.NeedsAction())
3628 mrExport.AddAttribute(XML_NAMESPACE_DR3D, XML_TRANSFORM, aTransform.GetExportString(mrExport.GetMM100UnitConverter()));
3630 // VRP, VPN, VUP
3631 aAny = xPropSet->getPropertyValue("D3DCameraGeometry");
3632 drawing::CameraGeometry aCamGeo;
3633 aAny >>= aCamGeo;
3635 ::basegfx::B3DVector aVRP(aCamGeo.vrp.PositionX, aCamGeo.vrp.PositionY, aCamGeo.vrp.PositionZ);
3636 if(aVRP != ::basegfx::B3DVector(0.0, 0.0, 1.0)) // write only when not default
3638 SvXMLUnitConverter::convertB3DVector(sStringBuffer, aVRP);
3639 aStr = sStringBuffer.makeStringAndClear();
3640 mrExport.AddAttribute(XML_NAMESPACE_DR3D, XML_VRP, aStr);
3643 ::basegfx::B3DVector aVPN(aCamGeo.vpn.DirectionX, aCamGeo.vpn.DirectionY, aCamGeo.vpn.DirectionZ);
3644 if(aVPN != ::basegfx::B3DVector(0.0, 0.0, 1.0)) // write only when not default
3646 SvXMLUnitConverter::convertB3DVector(sStringBuffer, aVPN);
3647 aStr = sStringBuffer.makeStringAndClear();
3648 mrExport.AddAttribute(XML_NAMESPACE_DR3D, XML_VPN, aStr);
3651 ::basegfx::B3DVector aVUP(aCamGeo.vup.DirectionX, aCamGeo.vup.DirectionY, aCamGeo.vup.DirectionZ);
3652 if(aVUP != ::basegfx::B3DVector(0.0, 1.0, 0.0)) // write only when not default
3654 SvXMLUnitConverter::convertB3DVector(sStringBuffer, aVUP);
3655 aStr = sStringBuffer.makeStringAndClear();
3656 mrExport.AddAttribute(XML_NAMESPACE_DR3D, XML_VUP, aStr);
3659 // projection "D3DScenePerspective" drawing::ProjectionMode
3660 aAny = xPropSet->getPropertyValue("D3DScenePerspective");
3661 drawing::ProjectionMode xPrjMode;
3662 aAny >>= xPrjMode;
3663 if(xPrjMode == drawing::ProjectionMode_PARALLEL)
3664 aStr = GetXMLToken(XML_PARALLEL);
3665 else
3666 aStr = GetXMLToken(XML_PERSPECTIVE);
3667 mrExport.AddAttribute(XML_NAMESPACE_DR3D, XML_PROJECTION, aStr);
3669 // distance
3670 aAny = xPropSet->getPropertyValue("D3DSceneDistance");
3671 sal_Int32 nDistance = 0;
3672 aAny >>= nDistance;
3673 mrExport.GetMM100UnitConverter().convertMeasureToXML(sStringBuffer,
3674 nDistance);
3675 aStr = sStringBuffer.makeStringAndClear();
3676 mrExport.AddAttribute(XML_NAMESPACE_DR3D, XML_DISTANCE, aStr);
3678 // focalLength
3679 aAny = xPropSet->getPropertyValue("D3DSceneFocalLength");
3680 sal_Int32 nFocalLength = 0;
3681 aAny >>= nFocalLength;
3682 mrExport.GetMM100UnitConverter().convertMeasureToXML(sStringBuffer,
3683 nFocalLength);
3684 aStr = sStringBuffer.makeStringAndClear();
3685 mrExport.AddAttribute(XML_NAMESPACE_DR3D, XML_FOCAL_LENGTH, aStr);
3687 // shadowSlant
3688 aAny = xPropSet->getPropertyValue("D3DSceneShadowSlant");
3689 sal_Int16 nShadowSlant = 0;
3690 aAny >>= nShadowSlant;
3691 ::sax::Converter::convertNumber(sStringBuffer, (sal_Int32)nShadowSlant);
3692 aStr = sStringBuffer.makeStringAndClear();
3693 mrExport.AddAttribute(XML_NAMESPACE_DR3D, XML_SHADOW_SLANT, aStr);
3695 // shadeMode
3696 aAny = xPropSet->getPropertyValue("D3DSceneShadeMode");
3697 drawing::ShadeMode xShadeMode;
3698 if(aAny >>= xShadeMode)
3700 if(xShadeMode == drawing::ShadeMode_FLAT)
3701 aStr = GetXMLToken(XML_FLAT);
3702 else if(xShadeMode == drawing::ShadeMode_PHONG)
3703 aStr = GetXMLToken(XML_PHONG);
3704 else if(xShadeMode == drawing::ShadeMode_SMOOTH)
3705 aStr = GetXMLToken(XML_GOURAUD);
3706 else
3707 aStr = GetXMLToken(XML_DRAFT);
3709 else
3711 // ShadeMode enum not there, write default
3712 aStr = GetXMLToken(XML_GOURAUD);
3714 mrExport.AddAttribute(XML_NAMESPACE_DR3D, XML_SHADE_MODE, aStr);
3716 // ambientColor
3717 aAny = xPropSet->getPropertyValue("D3DSceneAmbientColor");
3718 sal_Int32 nAmbientColor = 0;
3719 aAny >>= nAmbientColor;
3720 ::sax::Converter::convertColor(sStringBuffer, nAmbientColor);
3721 aStr = sStringBuffer.makeStringAndClear();
3722 mrExport.AddAttribute(XML_NAMESPACE_DR3D, XML_AMBIENT_COLOR, aStr);
3724 // lightingMode
3725 aAny = xPropSet->getPropertyValue("D3DSceneTwoSidedLighting");
3726 bool bTwoSidedLighting = false;
3727 aAny >>= bTwoSidedLighting;
3728 ::sax::Converter::convertBool(sStringBuffer, bTwoSidedLighting);
3729 aStr = sStringBuffer.makeStringAndClear();
3730 mrExport.AddAttribute(XML_NAMESPACE_DR3D, XML_LIGHTING_MODE, aStr);
3733 /** helper for chart that exports all lamps from the propertyset */
3734 void XMLShapeExport::export3DLamps( const com::sun::star::uno::Reference< com::sun::star::beans::XPropertySet >& xPropSet )
3736 // write lamps 1..8 as content
3737 OUString aStr;
3738 OUStringBuffer sStringBuffer;
3740 const OUString aColorPropName("D3DSceneLightColor");
3741 const OUString aDirectionPropName("D3DSceneLightDirection");
3742 const OUString aLightOnPropName("D3DSceneLightOn");
3744 OUString aPropName;
3745 OUString aIndexStr;
3746 ::basegfx::B3DVector aLightDirection;
3747 drawing::Direction3D xLightDir;
3748 bool bLightOnOff = false;
3749 for(sal_Int32 nLamp = 1; nLamp <= 8; nLamp++)
3751 aIndexStr = OUString::number( nLamp );
3753 // lightcolor
3754 aPropName = aColorPropName;
3755 aPropName += aIndexStr;
3756 sal_Int32 nLightColor = 0;
3757 xPropSet->getPropertyValue( aPropName ) >>= nLightColor;
3758 ::sax::Converter::convertColor(sStringBuffer, nLightColor);
3759 aStr = sStringBuffer.makeStringAndClear();
3760 mrExport.AddAttribute(XML_NAMESPACE_DR3D, XML_DIFFUSE_COLOR, aStr);
3762 // lightdirection
3763 aPropName = aDirectionPropName;
3764 aPropName += aIndexStr;
3765 xPropSet->getPropertyValue(aPropName) >>= xLightDir;
3766 aLightDirection = ::basegfx::B3DVector(xLightDir.DirectionX, xLightDir.DirectionY, xLightDir.DirectionZ);
3767 SvXMLUnitConverter::convertB3DVector(sStringBuffer, aLightDirection);
3768 aStr = sStringBuffer.makeStringAndClear();
3769 mrExport.AddAttribute(XML_NAMESPACE_DR3D, XML_DIRECTION, aStr);
3771 // lighton
3772 aPropName = aLightOnPropName;
3773 aPropName += aIndexStr;
3774 xPropSet->getPropertyValue(aPropName) >>= bLightOnOff;
3775 ::sax::Converter::convertBool(sStringBuffer, bLightOnOff);
3776 aStr = sStringBuffer.makeStringAndClear();
3777 mrExport.AddAttribute(XML_NAMESPACE_DR3D, XML_ENABLED, aStr);
3779 // specular
3780 mrExport.AddAttribute(XML_NAMESPACE_DR3D, XML_SPECULAR,
3781 nLamp == 1 ? XML_TRUE : XML_FALSE);
3783 // write light entry
3784 SvXMLElementExport aOBJ(mrExport, XML_NAMESPACE_DR3D, XML_LIGHT, true, true);
3789 // using namespace ::com::sun::star::io;
3790 // using namespace ::xmloff::EnhancedCustomShapeToken;
3793 void ExportParameter( OUStringBuffer& rStrBuffer, const com::sun::star::drawing::EnhancedCustomShapeParameter& rParameter )
3795 if ( !rStrBuffer.isEmpty() )
3796 rStrBuffer.append( ' ' );
3797 if ( rParameter.Value.getValueTypeClass() == uno::TypeClass_DOUBLE )
3799 double fNumber = 0.0;
3800 rParameter.Value >>= fNumber;
3801 ::rtl::math::doubleToUStringBuffer( rStrBuffer, fNumber, rtl_math_StringFormat_Automatic, rtl_math_DecimalPlaces_Max, '.', true );
3803 else
3805 sal_Int32 nValue = 0;
3806 rParameter.Value >>= nValue;
3808 switch( rParameter.Type )
3810 case com::sun::star::drawing::EnhancedCustomShapeParameterType::EQUATION :
3812 rStrBuffer.append( "?f" + OUString::number( nValue ) );
3814 break;
3816 case com::sun::star::drawing::EnhancedCustomShapeParameterType::ADJUSTMENT :
3818 rStrBuffer.append( '$' );
3819 rStrBuffer.append( OUString::number( nValue ) );
3821 break;
3823 case com::sun::star::drawing::EnhancedCustomShapeParameterType::BOTTOM :
3824 rStrBuffer.append( GetXMLToken( XML_BOTTOM ) ); break;
3825 case com::sun::star::drawing::EnhancedCustomShapeParameterType::RIGHT :
3826 rStrBuffer.append( GetXMLToken( XML_RIGHT ) ); break;
3827 case com::sun::star::drawing::EnhancedCustomShapeParameterType::TOP :
3828 rStrBuffer.append( GetXMLToken( XML_TOP ) ); break;
3829 case com::sun::star::drawing::EnhancedCustomShapeParameterType::LEFT :
3830 rStrBuffer.append( GetXMLToken( XML_LEFT ) ); break;
3831 case com::sun::star::drawing::EnhancedCustomShapeParameterType::XSTRETCH :
3832 rStrBuffer.append( GetXMLToken( XML_XSTRETCH ) ); break;
3833 case com::sun::star::drawing::EnhancedCustomShapeParameterType::YSTRETCH :
3834 rStrBuffer.append( GetXMLToken( XML_YSTRETCH ) ); break;
3835 case com::sun::star::drawing::EnhancedCustomShapeParameterType::HASSTROKE :
3836 rStrBuffer.append( GetXMLToken( XML_HASSTROKE ) ); break;
3837 case com::sun::star::drawing::EnhancedCustomShapeParameterType::HASFILL :
3838 rStrBuffer.append( GetXMLToken( XML_HASFILL ) ); break;
3839 case com::sun::star::drawing::EnhancedCustomShapeParameterType::WIDTH :
3840 rStrBuffer.append( GetXMLToken( XML_WIDTH ) ); break;
3841 case com::sun::star::drawing::EnhancedCustomShapeParameterType::HEIGHT :
3842 rStrBuffer.append( GetXMLToken( XML_HEIGHT ) ); break;
3843 case com::sun::star::drawing::EnhancedCustomShapeParameterType::LOGWIDTH :
3844 rStrBuffer.append( GetXMLToken( XML_LOGWIDTH ) ); break;
3845 case com::sun::star::drawing::EnhancedCustomShapeParameterType::LOGHEIGHT :
3846 rStrBuffer.append( GetXMLToken( XML_LOGHEIGHT ) ); break;
3847 default :
3848 rStrBuffer.append( OUString::number( nValue ) );
3853 void ImpExportEquations( SvXMLExport& rExport, const uno::Sequence< OUString >& rEquations )
3855 sal_Int32 i;
3856 for ( i = 0; i < rEquations.getLength(); i++ )
3858 OUString aStr('f');
3859 aStr += OUString::number( i );
3860 rExport.AddAttribute( XML_NAMESPACE_DRAW, XML_NAME, aStr );
3862 aStr = rEquations[ i ];
3863 sal_Int32 nIndex = 0;
3866 nIndex = aStr.indexOf( '?', nIndex );
3867 if ( nIndex != -1 )
3869 OUString aNew( aStr.copy( 0, nIndex + 1 ) );
3870 aNew += OUString('f');
3871 aNew += aStr.copy( nIndex + 1, ( aStr.getLength() - nIndex ) - 1 );
3872 aStr = aNew;
3873 nIndex++;
3875 } while( nIndex != -1 );
3876 rExport.AddAttribute( XML_NAMESPACE_DRAW, XML_FORMULA, aStr );
3877 SvXMLElementExport aOBJ( rExport, XML_NAMESPACE_DRAW, XML_EQUATION, true, true );
3881 void ImpExportHandles( SvXMLExport& rExport, const uno::Sequence< beans::PropertyValues >& rHandles )
3883 sal_uInt32 i, j, nElements = rHandles.getLength();
3884 if ( nElements )
3886 OUString aStr;
3887 OUStringBuffer aStrBuffer;
3889 for ( i = 0; i < nElements; i++ )
3891 bool bPosition = false;
3892 const uno::Sequence< beans::PropertyValue >& rPropSeq = rHandles[ i ];
3893 for ( j = 0; j < (sal_uInt32)rPropSeq.getLength(); j++ )
3895 const beans::PropertyValue& rPropVal = rPropSeq[ j ];
3896 switch( EASGet( rPropVal.Name ) )
3898 case EAS_Position :
3900 com::sun::star::drawing::EnhancedCustomShapeParameterPair aPosition;
3901 if ( rPropVal.Value >>= aPosition )
3903 ExportParameter( aStrBuffer, aPosition.First );
3904 ExportParameter( aStrBuffer, aPosition.Second );
3905 aStr = aStrBuffer.makeStringAndClear();
3906 rExport.AddAttribute( XML_NAMESPACE_DRAW, XML_HANDLE_POSITION, aStr );
3907 bPosition = true;
3910 break;
3911 case EAS_MirroredX :
3913 bool bMirroredX;
3914 if ( rPropVal.Value >>= bMirroredX )
3915 rExport.AddAttribute( XML_NAMESPACE_DRAW, XML_HANDLE_MIRROR_HORIZONTAL,
3916 bMirroredX ? GetXMLToken( XML_TRUE ) : GetXMLToken( XML_FALSE ) );
3918 break;
3919 case EAS_MirroredY :
3921 bool bMirroredY;
3922 if ( rPropVal.Value >>= bMirroredY )
3923 rExport.AddAttribute( XML_NAMESPACE_DRAW, XML_HANDLE_MIRROR_VERTICAL,
3924 bMirroredY ? GetXMLToken( XML_TRUE ) : GetXMLToken( XML_FALSE ) );
3926 break;
3927 case EAS_Switched :
3929 bool bSwitched;
3930 if ( rPropVal.Value >>= bSwitched )
3931 rExport.AddAttribute( XML_NAMESPACE_DRAW, XML_HANDLE_SWITCHED,
3932 bSwitched ? GetXMLToken( XML_TRUE ) : GetXMLToken( XML_FALSE ) );
3934 break;
3935 case EAS_Polar :
3937 com::sun::star::drawing::EnhancedCustomShapeParameterPair aPolar;
3938 if ( rPropVal.Value >>= aPolar )
3940 ExportParameter( aStrBuffer, aPolar.First );
3941 ExportParameter( aStrBuffer, aPolar.Second );
3942 aStr = aStrBuffer.makeStringAndClear();
3943 rExport.AddAttribute( XML_NAMESPACE_DRAW, XML_HANDLE_POLAR, aStr );
3946 break;
3947 case EAS_RadiusRangeMinimum :
3949 com::sun::star::drawing::EnhancedCustomShapeParameter aRadiusRangeMinimum;
3950 if ( rPropVal.Value >>= aRadiusRangeMinimum )
3952 ExportParameter( aStrBuffer, aRadiusRangeMinimum );
3953 aStr = aStrBuffer.makeStringAndClear();
3954 rExport.AddAttribute( XML_NAMESPACE_DRAW, XML_HANDLE_RADIUS_RANGE_MINIMUM, aStr );
3957 break;
3958 case EAS_RadiusRangeMaximum :
3960 com::sun::star::drawing::EnhancedCustomShapeParameter aRadiusRangeMaximum;
3961 if ( rPropVal.Value >>= aRadiusRangeMaximum )
3963 ExportParameter( aStrBuffer, aRadiusRangeMaximum );
3964 aStr = aStrBuffer.makeStringAndClear();
3965 rExport.AddAttribute( XML_NAMESPACE_DRAW, XML_HANDLE_RADIUS_RANGE_MAXIMUM, aStr );
3968 break;
3969 case EAS_RangeXMinimum :
3971 com::sun::star::drawing::EnhancedCustomShapeParameter aXRangeMinimum;
3972 if ( rPropVal.Value >>= aXRangeMinimum )
3974 ExportParameter( aStrBuffer, aXRangeMinimum );
3975 aStr = aStrBuffer.makeStringAndClear();
3976 rExport.AddAttribute( XML_NAMESPACE_DRAW, XML_HANDLE_RANGE_X_MINIMUM, aStr );
3979 break;
3980 case EAS_RangeXMaximum :
3982 com::sun::star::drawing::EnhancedCustomShapeParameter aXRangeMaximum;
3983 if ( rPropVal.Value >>= aXRangeMaximum )
3985 ExportParameter( aStrBuffer, aXRangeMaximum );
3986 aStr = aStrBuffer.makeStringAndClear();
3987 rExport.AddAttribute( XML_NAMESPACE_DRAW, XML_HANDLE_RANGE_X_MAXIMUM, aStr );
3990 break;
3991 case EAS_RangeYMinimum :
3993 com::sun::star::drawing::EnhancedCustomShapeParameter aYRangeMinimum;
3994 if ( rPropVal.Value >>= aYRangeMinimum )
3996 ExportParameter( aStrBuffer, aYRangeMinimum );
3997 aStr = aStrBuffer.makeStringAndClear();
3998 rExport.AddAttribute( XML_NAMESPACE_DRAW, XML_HANDLE_RANGE_Y_MINIMUM, aStr );
4001 break;
4002 case EAS_RangeYMaximum :
4004 com::sun::star::drawing::EnhancedCustomShapeParameter aYRangeMaximum;
4005 if ( rPropVal.Value >>= aYRangeMaximum )
4007 ExportParameter( aStrBuffer, aYRangeMaximum );
4008 aStr = aStrBuffer.makeStringAndClear();
4009 rExport.AddAttribute( XML_NAMESPACE_DRAW, XML_HANDLE_RANGE_Y_MAXIMUM, aStr );
4012 break;
4013 default:
4014 break;
4017 if ( bPosition )
4018 SvXMLElementExport aOBJ( rExport, XML_NAMESPACE_DRAW, XML_HANDLE, true, true );
4019 else
4020 rExport.ClearAttrList();
4025 void ImpExportEnhancedPath( SvXMLExport& rExport,
4026 const uno::Sequence< com::sun::star::drawing::EnhancedCustomShapeParameterPair >& rCoordinates,
4027 const uno::Sequence< com::sun::star::drawing::EnhancedCustomShapeSegment >& rSegments,
4028 bool bExtended = false )
4031 OUString aStr;
4032 OUStringBuffer aStrBuffer;
4033 bool bNeedExtended = false;
4035 sal_Int32 i, j, k, l;
4037 sal_Int32 nCoords = rCoordinates.getLength();
4038 sal_Int32 nSegments = rSegments.getLength();
4039 bool bSimpleSegments = nSegments == 0;
4040 if ( bSimpleSegments )
4041 nSegments = 4;
4042 for ( j = i = 0; j < nSegments; j++ )
4044 com::sun::star::drawing::EnhancedCustomShapeSegment aSegment;
4045 if ( bSimpleSegments )
4047 // if there are not enough segments we will default them
4048 switch( j )
4050 case 0 :
4052 aSegment.Count = 1;
4053 aSegment.Command = com::sun::star::drawing::EnhancedCustomShapeSegmentCommand::MOVETO;
4055 break;
4056 case 1 :
4058 aSegment.Count = (sal_Int16)std::min( nCoords - 1, (sal_Int32)32767 );
4059 aSegment.Command = com::sun::star::drawing::EnhancedCustomShapeSegmentCommand::LINETO;
4061 break;
4062 case 2 :
4064 aSegment.Count = 1;
4065 aSegment.Command = com::sun::star::drawing::EnhancedCustomShapeSegmentCommand::CLOSESUBPATH;
4067 break;
4068 case 3 :
4070 aSegment.Count = 1;
4071 aSegment.Command = com::sun::star::drawing::EnhancedCustomShapeSegmentCommand::ENDSUBPATH;
4073 break;
4076 else
4077 aSegment = rSegments[ j ];
4079 if ( !aStrBuffer.isEmpty() )
4080 aStrBuffer.append( ' ' );
4082 sal_Int32 nParameter = 0;
4083 switch( aSegment.Command )
4085 case com::sun::star::drawing::EnhancedCustomShapeSegmentCommand::CLOSESUBPATH :
4086 aStrBuffer.append( 'Z' ); break;
4087 case com::sun::star::drawing::EnhancedCustomShapeSegmentCommand::ENDSUBPATH :
4088 aStrBuffer.append( 'N' ); break;
4089 case com::sun::star::drawing::EnhancedCustomShapeSegmentCommand::NOFILL :
4090 aStrBuffer.append( 'F' ); break;
4091 case com::sun::star::drawing::EnhancedCustomShapeSegmentCommand::NOSTROKE :
4092 aStrBuffer.append( 'S' ); break;
4094 case com::sun::star::drawing::EnhancedCustomShapeSegmentCommand::MOVETO :
4095 aStrBuffer.append( 'M' ); nParameter = 1; break;
4096 case com::sun::star::drawing::EnhancedCustomShapeSegmentCommand::LINETO :
4097 aStrBuffer.append( 'L' ); nParameter = 1; break;
4098 case com::sun::star::drawing::EnhancedCustomShapeSegmentCommand::CURVETO :
4099 aStrBuffer.append( 'C' ); nParameter = 3; break;
4100 case com::sun::star::drawing::EnhancedCustomShapeSegmentCommand::ANGLEELLIPSETO :
4101 aStrBuffer.append( 'T' ); nParameter = 3; break;
4102 case com::sun::star::drawing::EnhancedCustomShapeSegmentCommand::ANGLEELLIPSE :
4103 aStrBuffer.append( 'U' ); nParameter = 3; break;
4104 case com::sun::star::drawing::EnhancedCustomShapeSegmentCommand::ARCTO :
4105 aStrBuffer.append( 'A' ); nParameter = 4; break;
4106 case com::sun::star::drawing::EnhancedCustomShapeSegmentCommand::ARC :
4107 aStrBuffer.append( 'B' ); nParameter = 4; break;
4108 case com::sun::star::drawing::EnhancedCustomShapeSegmentCommand::CLOCKWISEARCTO :
4109 aStrBuffer.append( 'W' ); nParameter = 4; break;
4110 case com::sun::star::drawing::EnhancedCustomShapeSegmentCommand::CLOCKWISEARC :
4111 aStrBuffer.append( 'V' ); nParameter = 4; break;
4112 case com::sun::star::drawing::EnhancedCustomShapeSegmentCommand::ELLIPTICALQUADRANTX :
4113 aStrBuffer.append( 'X' ); nParameter = 1; break;
4114 case com::sun::star::drawing::EnhancedCustomShapeSegmentCommand::ELLIPTICALQUADRANTY :
4115 aStrBuffer.append( 'Y' ); nParameter = 1; break;
4116 case com::sun::star::drawing::EnhancedCustomShapeSegmentCommand::QUADRATICCURVETO :
4117 aStrBuffer.append( 'Q' ); nParameter = 2; break;
4118 case com::sun::star::drawing::EnhancedCustomShapeSegmentCommand::ARCANGLETO :
4119 if ( bExtended ) {
4120 aStrBuffer.append( 'G' );
4121 nParameter = 2;
4122 } else {
4123 aStrBuffer.setLength( aStrBuffer.getLength() - 1);
4124 bNeedExtended = true;
4125 i += 2;
4127 break;
4128 case com::sun::star::drawing::EnhancedCustomShapeSegmentCommand::DARKEN :
4129 if ( bExtended )
4130 aStrBuffer.append( 'H' );
4131 else
4132 bNeedExtended = true;
4133 break;
4134 case com::sun::star::drawing::EnhancedCustomShapeSegmentCommand::DARKENLESS :
4135 if ( bExtended )
4136 aStrBuffer.append( 'I' );
4137 else
4138 bNeedExtended = true;
4139 break;
4140 case com::sun::star::drawing::EnhancedCustomShapeSegmentCommand::LIGHTEN :
4141 if ( bExtended )
4142 aStrBuffer.append( 'J' );
4143 else
4144 bNeedExtended = true;
4145 break;
4146 case com::sun::star::drawing::EnhancedCustomShapeSegmentCommand::LIGHTENLESS :
4147 if ( bExtended )
4148 aStrBuffer.append( 'K' );
4149 else
4150 bNeedExtended = true;
4151 break;
4152 default : // ups, seems to be something wrong
4154 aSegment.Count = 1;
4155 aSegment.Command = com::sun::star::drawing::EnhancedCustomShapeSegmentCommand::LINETO;
4157 break;
4159 if ( nParameter )
4161 for ( k = 0; k < aSegment.Count; k++ )
4163 if ( ( i + nParameter ) <= nCoords )
4165 for ( l = 0; l < nParameter; l++ )
4167 ExportParameter( aStrBuffer, rCoordinates[ i ].First );
4168 ExportParameter( aStrBuffer, rCoordinates[ i++ ].Second );
4171 else
4173 j = nSegments; // error -> exiting
4174 break;
4179 aStr = aStrBuffer.makeStringAndClear();
4180 rExport.AddAttribute( bExtended ? XML_NAMESPACE_DRAW_EXT : XML_NAMESPACE_DRAW, XML_ENHANCED_PATH, aStr );
4181 if ( !bExtended && bNeedExtended )
4182 ImpExportEnhancedPath( rExport, rCoordinates, rSegments, true );
4185 void ImpExportEnhancedGeometry( SvXMLExport& rExport, const uno::Reference< beans::XPropertySet >& xPropSet )
4187 bool bEquations = false;
4188 uno::Sequence< OUString > aEquations;
4190 bool bHandles = false;
4191 uno::Sequence< beans::PropertyValues > aHandles;
4193 bool bCoordinates = false;
4194 uno::Sequence< com::sun::star::drawing::EnhancedCustomShapeSegment > aSegments;
4195 uno::Sequence< com::sun::star::drawing::EnhancedCustomShapeParameterPair > aCoordinates;
4197 uno::Sequence< com::sun::star::drawing::EnhancedCustomShapeAdjustmentValue > aAdjustmentValues;
4199 OUString aStr;
4200 OUStringBuffer aStrBuffer;
4201 SvXMLUnitConverter& rUnitConverter = rExport.GetMM100UnitConverter();
4203 uno::Reference< beans::XPropertySetInfo > xPropSetInfo( xPropSet->getPropertySetInfo() );
4205 // geometry
4206 const OUString sCustomShapeGeometry( "CustomShapeGeometry" );
4207 if ( xPropSetInfo.is() && xPropSetInfo->hasPropertyByName( sCustomShapeGeometry ) )
4209 uno::Any aGeoPropSet( xPropSet->getPropertyValue( sCustomShapeGeometry ) );
4210 uno::Sequence< beans::PropertyValue > aGeoPropSeq;
4212 if ( aGeoPropSet >>= aGeoPropSeq )
4214 const OUString sCustomShapeType( "non-primitive" );
4215 OUString aCustomShapeType( sCustomShapeType );
4217 sal_Int32 j, nGeoPropCount = aGeoPropSeq.getLength();
4218 for ( j = 0; j < nGeoPropCount; j++ )
4220 const beans::PropertyValue& rGeoProp = aGeoPropSeq[ j ];
4221 switch( EASGet( rGeoProp.Name ) )
4223 case EAS_Type :
4225 rGeoProp.Value >>= aCustomShapeType;
4227 break;
4228 case EAS_MirroredX :
4230 bool bMirroredX;
4231 if ( rGeoProp.Value >>= bMirroredX )
4232 rExport.AddAttribute( XML_NAMESPACE_DRAW, XML_MIRROR_HORIZONTAL,
4233 bMirroredX ? GetXMLToken( XML_TRUE ) : GetXMLToken( XML_FALSE ) );
4235 break;
4236 case EAS_MirroredY :
4238 bool bMirroredY;
4239 if ( rGeoProp.Value >>= bMirroredY )
4240 rExport.AddAttribute( XML_NAMESPACE_DRAW, XML_MIRROR_VERTICAL,
4241 bMirroredY ? GetXMLToken( XML_TRUE ) : GetXMLToken( XML_FALSE ) );
4243 break;
4244 case EAS_ViewBox :
4246 awt::Rectangle aRect;
4247 if ( rGeoProp.Value >>= aRect )
4249 SdXMLImExViewBox aViewBox( aRect.X, aRect.Y, aRect.Width, aRect.Height );
4250 rExport.AddAttribute( XML_NAMESPACE_SVG, XML_VIEWBOX, aViewBox.GetExportString() );
4253 break;
4254 case EAS_TextRotateAngle :
4256 double fTextRotateAngle = 0;
4257 if ( rGeoProp.Value >>= fTextRotateAngle )
4259 ::sax::Converter::convertDouble(
4260 aStrBuffer, fTextRotateAngle );
4261 aStr = aStrBuffer.makeStringAndClear();
4262 rExport.AddAttribute( XML_NAMESPACE_DRAW, XML_TEXT_ROTATE_ANGLE, aStr );
4265 break;
4266 case EAS_Extrusion :
4268 uno::Sequence< beans::PropertyValue > aExtrusionPropSeq;
4269 if ( rGeoProp.Value >>= aExtrusionPropSeq )
4271 sal_Int32 i, nCount = aExtrusionPropSeq.getLength();
4272 for ( i = 0; i < nCount; i++ )
4274 const beans::PropertyValue& rProp = aExtrusionPropSeq[ i ];
4275 switch( EASGet( rProp.Name ) )
4277 case EAS_Extrusion :
4279 bool bExtrusionOn;
4280 if ( rProp.Value >>= bExtrusionOn )
4281 rExport.AddAttribute( XML_NAMESPACE_DRAW, XML_EXTRUSION,
4282 bExtrusionOn ? GetXMLToken( XML_TRUE ) : GetXMLToken( XML_FALSE ) );
4284 break;
4285 case EAS_Brightness :
4287 double fExtrusionBrightness = 0;
4288 if ( rProp.Value >>= fExtrusionBrightness )
4290 ::sax::Converter::convertDouble(
4291 aStrBuffer,
4292 fExtrusionBrightness,
4293 false,
4294 util::MeasureUnit::PERCENT,
4295 util::MeasureUnit::PERCENT);
4296 aStrBuffer.append( '%' );
4297 aStr = aStrBuffer.makeStringAndClear();
4298 rExport.AddAttribute( XML_NAMESPACE_DRAW, XML_EXTRUSION_BRIGHTNESS, aStr );
4301 break;
4302 case EAS_Depth :
4304 com::sun::star::drawing::EnhancedCustomShapeParameterPair aDepthParaPair;
4305 if ( rProp.Value >>= aDepthParaPair )
4307 double fDepth = 0;
4308 if ( aDepthParaPair.First.Value >>= fDepth )
4310 rExport.GetMM100UnitConverter().convertDouble( aStrBuffer, fDepth, true );
4311 ExportParameter( aStrBuffer, aDepthParaPair.Second );
4312 aStr = aStrBuffer.makeStringAndClear();
4313 rExport.AddAttribute( XML_NAMESPACE_DRAW, XML_EXTRUSION_DEPTH, aStr );
4317 break;
4318 case EAS_Diffusion :
4320 double fExtrusionDiffusion = 0;
4321 if ( rProp.Value >>= fExtrusionDiffusion )
4323 ::sax::Converter::convertDouble(
4324 aStrBuffer,
4325 fExtrusionDiffusion,
4326 false,
4327 util::MeasureUnit::PERCENT,
4328 util::MeasureUnit::PERCENT);
4329 aStrBuffer.append( '%' );
4330 aStr = aStrBuffer.makeStringAndClear();
4331 rExport.AddAttribute( XML_NAMESPACE_DRAW, XML_EXTRUSION_DIFFUSION, aStr );
4334 break;
4335 case EAS_NumberOfLineSegments :
4337 sal_Int32 nExtrusionNumberOfLineSegments = 0;
4338 if ( rProp.Value >>= nExtrusionNumberOfLineSegments )
4339 rExport.AddAttribute( XML_NAMESPACE_DRAW, XML_EXTRUSION_NUMBER_OF_LINE_SEGMENTS, OUString::number( nExtrusionNumberOfLineSegments ) );
4341 break;
4342 case EAS_LightFace :
4344 bool bExtrusionLightFace;
4345 if ( rProp.Value >>= bExtrusionLightFace )
4346 rExport.AddAttribute( XML_NAMESPACE_DRAW, XML_EXTRUSION_LIGHT_FACE,
4347 bExtrusionLightFace ? GetXMLToken( XML_TRUE ) : GetXMLToken( XML_FALSE ) );
4349 break;
4350 case EAS_FirstLightHarsh :
4352 bool bExtrusionFirstLightHarsh;
4353 if ( rProp.Value >>= bExtrusionFirstLightHarsh )
4354 rExport.AddAttribute( XML_NAMESPACE_DRAW, XML_EXTRUSION_FIRST_LIGHT_HARSH,
4355 bExtrusionFirstLightHarsh ? GetXMLToken( XML_TRUE ) : GetXMLToken( XML_FALSE ) );
4357 break;
4358 case EAS_SecondLightHarsh :
4360 bool bExtrusionSecondLightHarsh;
4361 if ( rProp.Value >>= bExtrusionSecondLightHarsh )
4362 rExport.AddAttribute( XML_NAMESPACE_DRAW, XML_EXTRUSION_SECOND_LIGHT_HARSH,
4363 bExtrusionSecondLightHarsh ? GetXMLToken( XML_TRUE ) : GetXMLToken( XML_FALSE ) );
4365 break;
4366 case EAS_FirstLightLevel :
4368 double fExtrusionFirstLightLevel = 0;
4369 if ( rProp.Value >>= fExtrusionFirstLightLevel )
4371 ::sax::Converter::convertDouble(
4372 aStrBuffer,
4373 fExtrusionFirstLightLevel,
4374 false,
4375 util::MeasureUnit::PERCENT,
4376 util::MeasureUnit::PERCENT);
4377 aStrBuffer.append( '%' );
4378 aStr = aStrBuffer.makeStringAndClear();
4379 rExport.AddAttribute( XML_NAMESPACE_DRAW, XML_EXTRUSION_FIRST_LIGHT_LEVEL, aStr );
4382 break;
4383 case EAS_SecondLightLevel :
4385 double fExtrusionSecondLightLevel = 0;
4386 if ( rProp.Value >>= fExtrusionSecondLightLevel )
4388 ::sax::Converter::convertDouble(
4389 aStrBuffer,
4390 fExtrusionSecondLightLevel,
4391 false,
4392 util::MeasureUnit::PERCENT,
4393 util::MeasureUnit::PERCENT);
4394 aStrBuffer.append( '%' );
4395 aStr = aStrBuffer.makeStringAndClear();
4396 rExport.AddAttribute( XML_NAMESPACE_DRAW, XML_EXTRUSION_SECOND_LIGHT_LEVEL, aStr );
4399 break;
4400 case EAS_FirstLightDirection :
4402 drawing::Direction3D aExtrusionFirstLightDirection;
4403 if ( rProp.Value >>= aExtrusionFirstLightDirection )
4405 ::basegfx::B3DVector aVec3D( aExtrusionFirstLightDirection.DirectionX, aExtrusionFirstLightDirection.DirectionY,
4406 aExtrusionFirstLightDirection.DirectionZ );
4407 SvXMLUnitConverter::convertB3DVector( aStrBuffer, aVec3D );
4408 aStr = aStrBuffer.makeStringAndClear();
4409 rExport.AddAttribute( XML_NAMESPACE_DRAW, XML_EXTRUSION_FIRST_LIGHT_DIRECTION, aStr );
4412 break;
4413 case EAS_SecondLightDirection :
4415 drawing::Direction3D aExtrusionSecondLightDirection;
4416 if ( rProp.Value >>= aExtrusionSecondLightDirection )
4418 ::basegfx::B3DVector aVec3D( aExtrusionSecondLightDirection.DirectionX, aExtrusionSecondLightDirection.DirectionY,
4419 aExtrusionSecondLightDirection.DirectionZ );
4420 SvXMLUnitConverter::convertB3DVector( aStrBuffer, aVec3D );
4421 aStr = aStrBuffer.makeStringAndClear();
4422 rExport.AddAttribute( XML_NAMESPACE_DRAW, XML_EXTRUSION_SECOND_LIGHT_DIRECTION, aStr );
4425 break;
4426 case EAS_Metal :
4428 bool bExtrusionMetal;
4429 if ( rProp.Value >>= bExtrusionMetal )
4430 rExport.AddAttribute( XML_NAMESPACE_DRAW, XML_EXTRUSION_METAL,
4431 bExtrusionMetal ? GetXMLToken( XML_TRUE ) : GetXMLToken( XML_FALSE ) );
4433 break;
4434 case EAS_ShadeMode :
4436 // shadeMode
4437 drawing::ShadeMode eShadeMode;
4438 if( rProp.Value >>= eShadeMode )
4440 if( eShadeMode == drawing::ShadeMode_FLAT )
4441 aStr = GetXMLToken( XML_FLAT );
4442 else if( eShadeMode == drawing::ShadeMode_PHONG )
4443 aStr = GetXMLToken( XML_PHONG );
4444 else if( eShadeMode == drawing::ShadeMode_SMOOTH )
4445 aStr = GetXMLToken( XML_GOURAUD );
4446 else
4447 aStr = GetXMLToken( XML_DRAFT );
4449 else
4451 // ShadeMode enum not there, write default
4452 aStr = GetXMLToken( XML_FLAT);
4454 rExport.AddAttribute( XML_NAMESPACE_DR3D, XML_SHADE_MODE, aStr );
4456 break;
4457 case EAS_RotateAngle :
4459 com::sun::star::drawing::EnhancedCustomShapeParameterPair aRotateAngleParaPair;
4460 if ( rProp.Value >>= aRotateAngleParaPair )
4462 ExportParameter( aStrBuffer, aRotateAngleParaPair.First );
4463 ExportParameter( aStrBuffer, aRotateAngleParaPair.Second );
4464 aStr = aStrBuffer.makeStringAndClear();
4465 rExport.AddAttribute( XML_NAMESPACE_DRAW, XML_EXTRUSION_ROTATION_ANGLE, aStr );
4468 break;
4469 case EAS_RotationCenter :
4471 drawing::Direction3D aExtrusionRotationCenter;
4472 if ( rProp.Value >>= aExtrusionRotationCenter )
4474 ::basegfx::B3DVector aVec3D( aExtrusionRotationCenter.DirectionX, aExtrusionRotationCenter.DirectionY,
4475 aExtrusionRotationCenter.DirectionZ );
4476 SvXMLUnitConverter::convertB3DVector( aStrBuffer, aVec3D );
4477 aStr = aStrBuffer.makeStringAndClear();
4478 rExport.AddAttribute( XML_NAMESPACE_DRAW, XML_EXTRUSION_ROTATION_CENTER, aStr );
4481 break;
4482 case EAS_Shininess :
4484 double fExtrusionShininess = 0;
4485 if ( rProp.Value >>= fExtrusionShininess )
4487 ::sax::Converter::convertDouble(
4488 aStrBuffer,
4489 fExtrusionShininess,
4490 false,
4491 util::MeasureUnit::PERCENT,
4492 util::MeasureUnit::PERCENT);
4493 aStrBuffer.append( '%' );
4494 aStr = aStrBuffer.makeStringAndClear();
4495 rExport.AddAttribute( XML_NAMESPACE_DRAW, XML_EXTRUSION_SHININESS, aStr );
4498 break;
4499 case EAS_Skew :
4501 com::sun::star::drawing::EnhancedCustomShapeParameterPair aSkewParaPair;
4502 if ( rProp.Value >>= aSkewParaPair )
4504 ExportParameter( aStrBuffer, aSkewParaPair.First );
4505 ExportParameter( aStrBuffer, aSkewParaPair.Second );
4506 aStr = aStrBuffer.makeStringAndClear();
4507 rExport.AddAttribute( XML_NAMESPACE_DRAW, XML_EXTRUSION_SKEW, aStr );
4510 break;
4511 case EAS_Specularity :
4513 double fExtrusionSpecularity = 0;
4514 if ( rProp.Value >>= fExtrusionSpecularity )
4516 ::sax::Converter::convertDouble(
4517 aStrBuffer,
4518 fExtrusionSpecularity,
4519 false,
4520 util::MeasureUnit::PERCENT,
4521 util::MeasureUnit::PERCENT);
4522 aStrBuffer.append( '%' );
4523 aStr = aStrBuffer.makeStringAndClear();
4524 rExport.AddAttribute( XML_NAMESPACE_DRAW, XML_EXTRUSION_SPECULARITY, aStr );
4527 break;
4528 case EAS_ProjectionMode :
4530 drawing::ProjectionMode eProjectionMode;
4531 if ( rProp.Value >>= eProjectionMode )
4532 rExport.AddAttribute( XML_NAMESPACE_DR3D, XML_PROJECTION,
4533 eProjectionMode == drawing::ProjectionMode_PARALLEL ? GetXMLToken( XML_PARALLEL ) : GetXMLToken( XML_PERSPECTIVE ) );
4535 break;
4536 case EAS_ViewPoint :
4538 drawing::Position3D aExtrusionViewPoint;
4539 if ( rProp.Value >>= aExtrusionViewPoint )
4541 rUnitConverter.convertPosition3D( aStrBuffer, aExtrusionViewPoint );
4542 aStr = aStrBuffer.makeStringAndClear();
4543 rExport.AddAttribute( XML_NAMESPACE_DRAW, XML_EXTRUSION_VIEWPOINT, aStr );
4546 break;
4547 case EAS_Origin :
4549 com::sun::star::drawing::EnhancedCustomShapeParameterPair aOriginParaPair;
4550 if ( rProp.Value >>= aOriginParaPair )
4552 ExportParameter( aStrBuffer, aOriginParaPair.First );
4553 ExportParameter( aStrBuffer, aOriginParaPair.Second );
4554 aStr = aStrBuffer.makeStringAndClear();
4555 rExport.AddAttribute( XML_NAMESPACE_DRAW, XML_EXTRUSION_ORIGIN, aStr );
4558 break;
4559 case EAS_Color :
4561 bool bExtrusionColor;
4562 if ( rProp.Value >>= bExtrusionColor )
4564 rExport.AddAttribute( XML_NAMESPACE_DRAW, XML_EXTRUSION_COLOR,
4565 bExtrusionColor ? GetXMLToken( XML_TRUE ) : GetXMLToken( XML_FALSE ) );
4568 break;
4569 default:
4570 break;
4575 break;
4576 case EAS_TextPath :
4578 uno::Sequence< beans::PropertyValue > aTextPathPropSeq;
4579 if ( rGeoProp.Value >>= aTextPathPropSeq )
4581 sal_Int32 i, nCount = aTextPathPropSeq.getLength();
4582 for ( i = 0; i < nCount; i++ )
4584 const beans::PropertyValue& rProp = aTextPathPropSeq[ i ];
4585 switch( EASGet( rProp.Name ) )
4587 case EAS_TextPath :
4589 bool bTextPathOn;
4590 if ( rProp.Value >>= bTextPathOn )
4591 rExport.AddAttribute( XML_NAMESPACE_DRAW, XML_TEXT_PATH,
4592 bTextPathOn ? GetXMLToken( XML_TRUE ) : GetXMLToken( XML_FALSE ) );
4594 break;
4595 case EAS_TextPathMode :
4597 com::sun::star::drawing::EnhancedCustomShapeTextPathMode eTextPathMode;
4598 if ( rProp.Value >>= eTextPathMode )
4600 switch ( eTextPathMode )
4602 case com::sun::star::drawing::EnhancedCustomShapeTextPathMode_NORMAL: aStr = GetXMLToken( XML_NORMAL ); break;
4603 case com::sun::star::drawing::EnhancedCustomShapeTextPathMode_PATH : aStr = GetXMLToken( XML_PATH ); break;
4604 case com::sun::star::drawing::EnhancedCustomShapeTextPathMode_SHAPE : aStr = GetXMLToken( XML_SHAPE ); break;
4605 default:
4606 break;
4608 if ( !aStr.isEmpty() )
4609 rExport.AddAttribute( XML_NAMESPACE_DRAW, XML_TEXT_PATH_MODE, aStr );
4612 break;
4613 case EAS_ScaleX :
4615 bool bScaleX;
4616 if ( rProp.Value >>= bScaleX )
4618 aStr = bScaleX ? GetXMLToken( XML_SHAPE ) : GetXMLToken( XML_PATH );
4619 rExport.AddAttribute( XML_NAMESPACE_DRAW, XML_TEXT_PATH_SCALE, aStr );
4622 break;
4623 case EAS_SameLetterHeights :
4625 bool bSameLetterHeights;
4626 if ( rProp.Value >>= bSameLetterHeights )
4627 rExport.AddAttribute( XML_NAMESPACE_DRAW, XML_TEXT_PATH_SAME_LETTER_HEIGHTS,
4628 bSameLetterHeights ? GetXMLToken( XML_TRUE ) : GetXMLToken( XML_FALSE ) );
4630 break;
4631 default:
4632 break;
4637 break;
4638 case EAS_Path :
4640 uno::Sequence< beans::PropertyValue > aPathPropSeq;
4641 if ( rGeoProp.Value >>= aPathPropSeq )
4643 sal_Int32 i, nCount = aPathPropSeq.getLength();
4644 for ( i = 0; i < nCount; i++ )
4646 const beans::PropertyValue& rProp = aPathPropSeq[ i ];
4648 switch( EASGet( rProp.Name ) )
4650 case EAS_SubViewSize:
4652 uno::Sequence< awt::Size > aSubViewSizes;
4653 rProp.Value >>= aSubViewSizes;
4655 for ( int nIdx = 0; nIdx < aSubViewSizes.getLength(); nIdx++ )
4657 if ( nIdx )
4658 aStrBuffer.append(' ');
4659 ::sax::Converter::convertNumber( aStrBuffer, aSubViewSizes[nIdx].Width );
4660 aStrBuffer.append(' ');
4661 ::sax::Converter::convertNumber( aStrBuffer, aSubViewSizes[nIdx].Height );
4663 aStr = aStrBuffer.makeStringAndClear();
4664 rExport.AddAttribute( XML_NAMESPACE_DRAW_EXT, XML_SUB_VIEW_SIZE, aStr );
4666 break;
4667 case EAS_ExtrusionAllowed :
4669 bool bExtrusionAllowed;
4670 if ( rProp.Value >>= bExtrusionAllowed )
4671 rExport.AddAttribute( XML_NAMESPACE_DRAW, XML_EXTRUSION_ALLOWED,
4672 bExtrusionAllowed ? GetXMLToken( XML_TRUE ) : GetXMLToken( XML_FALSE ) );
4674 break;
4675 case EAS_ConcentricGradientFillAllowed :
4677 bool bConcentricGradientFillAllowed;
4678 if ( rProp.Value >>= bConcentricGradientFillAllowed )
4679 rExport.AddAttribute( XML_NAMESPACE_DRAW, XML_CONCENTRIC_GRADIENT_FILL_ALLOWED,
4680 bConcentricGradientFillAllowed ? GetXMLToken( XML_TRUE ) : GetXMLToken( XML_FALSE ) );
4682 break;
4683 case EAS_TextPathAllowed :
4685 bool bTextPathAllowed;
4686 if ( rProp.Value >>= bTextPathAllowed )
4687 rExport.AddAttribute( XML_NAMESPACE_DRAW, XML_TEXT_PATH_ALLOWED,
4688 bTextPathAllowed ? GetXMLToken( XML_TRUE ) : GetXMLToken( XML_FALSE ) );
4690 break;
4691 case EAS_GluePoints :
4693 com::sun::star::uno::Sequence< com::sun::star::drawing::EnhancedCustomShapeParameterPair> aGluePoints;
4694 if ( rProp.Value >>= aGluePoints )
4696 sal_Int32 k, nElements = aGluePoints.getLength();
4697 if ( nElements )
4699 for( k = 0; k < nElements; k++ )
4701 ExportParameter( aStrBuffer, aGluePoints[ k ].First );
4702 ExportParameter( aStrBuffer, aGluePoints[ k ].Second );
4704 aStr = aStrBuffer.makeStringAndClear();
4706 rExport.AddAttribute( XML_NAMESPACE_DRAW, XML_GLUE_POINTS, aStr );
4709 break;
4710 case EAS_GluePointType :
4712 sal_Int16 nGluePointType = sal_Int16();
4713 if ( rProp.Value >>= nGluePointType )
4715 switch ( nGluePointType )
4717 case com::sun::star::drawing::EnhancedCustomShapeGluePointType::NONE : aStr = GetXMLToken( XML_NONE ); break;
4718 case com::sun::star::drawing::EnhancedCustomShapeGluePointType::SEGMENTS : aStr = GetXMLToken( XML_SEGMENTS ); break;
4719 case com::sun::star::drawing::EnhancedCustomShapeGluePointType::RECT : aStr = GetXMLToken( XML_RECTANGLE ); break;
4721 if ( !aStr.isEmpty() )
4722 rExport.AddAttribute( XML_NAMESPACE_DRAW, XML_GLUE_POINT_TYPE, aStr );
4725 break;
4726 case EAS_Coordinates :
4728 bCoordinates = ( rProp.Value >>= aCoordinates );
4730 break;
4731 case EAS_Segments :
4733 rProp.Value >>= aSegments;
4735 break;
4736 case EAS_StretchX :
4738 sal_Int32 nStretchPoint = 0;
4739 if ( rProp.Value >>= nStretchPoint )
4740 rExport.AddAttribute( XML_NAMESPACE_DRAW, XML_PATH_STRETCHPOINT_X, OUString::number( nStretchPoint ) );
4742 break;
4743 case EAS_StretchY :
4745 sal_Int32 nStretchPoint = 0;
4746 if ( rProp.Value >>= nStretchPoint )
4747 rExport.AddAttribute( XML_NAMESPACE_DRAW, XML_PATH_STRETCHPOINT_Y, OUString::number( nStretchPoint ) );
4749 break;
4750 case EAS_TextFrames :
4752 com::sun::star::uno::Sequence< com::sun::star::drawing::EnhancedCustomShapeTextFrame > aPathTextFrames;
4753 if ( rProp.Value >>= aPathTextFrames )
4755 if ( (sal_uInt16)aPathTextFrames.getLength() )
4757 sal_uInt16 k, nElements = (sal_uInt16)aPathTextFrames.getLength();
4758 for ( k = 0; k < nElements; k++ )
4760 ExportParameter( aStrBuffer, aPathTextFrames[ k ].TopLeft.First );
4761 ExportParameter( aStrBuffer, aPathTextFrames[ k ].TopLeft.Second );
4762 ExportParameter( aStrBuffer, aPathTextFrames[ k ].BottomRight.First );
4763 ExportParameter( aStrBuffer, aPathTextFrames[ k ].BottomRight.Second );
4765 aStr = aStrBuffer.makeStringAndClear();
4767 rExport.AddAttribute( XML_NAMESPACE_DRAW, XML_TEXT_AREAS, aStr );
4770 break;
4771 default:
4772 break;
4777 break;
4778 case EAS_Equations :
4780 bEquations = ( rGeoProp.Value >>= aEquations );
4782 break;
4783 case EAS_Handles :
4785 bHandles = ( rGeoProp.Value >>= aHandles );
4787 break;
4788 case EAS_AdjustmentValues :
4790 rGeoProp.Value >>= aAdjustmentValues;
4792 break;
4793 default:
4794 break;
4796 } // for
4797 rExport.AddAttribute( XML_NAMESPACE_DRAW, XML_TYPE, aCustomShapeType );
4799 // adjustments
4800 sal_Int32 nAdjustmentValues = aAdjustmentValues.getLength();
4801 if ( nAdjustmentValues )
4803 sal_Int32 i, nValue = 0;
4804 for ( i = 0; i < nAdjustmentValues; i++ )
4806 if ( i )
4807 aStrBuffer.append( ' ' );
4809 const com::sun::star::drawing::EnhancedCustomShapeAdjustmentValue& rAdj = aAdjustmentValues[ i ];
4810 if ( rAdj.State == beans::PropertyState_DIRECT_VALUE )
4812 if ( rAdj.Value.getValueTypeClass() == uno::TypeClass_DOUBLE )
4814 double fValue = 0.0;
4815 rAdj.Value >>= fValue;
4816 ::sax::Converter::convertDouble(aStrBuffer, fValue);
4818 else
4820 rAdj.Value >>= nValue;
4821 ::sax::Converter::convertNumber(aStrBuffer, nValue);
4824 else
4826 // this should not be, but better than setting nothing
4827 ::sax::Converter::convertNumber( aStrBuffer, 0 );
4830 aStr = aStrBuffer.makeStringAndClear();
4831 rExport.AddAttribute( XML_NAMESPACE_DRAW, XML_MODIFIERS, aStr );
4833 if ( bCoordinates )
4834 ImpExportEnhancedPath( rExport, aCoordinates, aSegments );
4837 SvXMLElementExport aOBJ( rExport, XML_NAMESPACE_DRAW, XML_ENHANCED_GEOMETRY, true, true );
4838 if ( bEquations )
4839 ImpExportEquations( rExport, aEquations );
4840 if ( bHandles )
4841 ImpExportHandles( rExport, aHandles );
4844 void XMLShapeExport::ImpExportCustomShape(
4845 const uno::Reference< drawing::XShape >& xShape,
4846 XmlShapeType, XMLShapeExportFlags nFeatures, com::sun::star::awt::Point* pRefPoint )
4848 const uno::Reference< beans::XPropertySet > xPropSet(xShape, uno::UNO_QUERY);
4849 if ( xPropSet.is() )
4851 OUString aStr;
4852 uno::Reference< beans::XPropertySetInfo > xPropSetInfo( xPropSet->getPropertySetInfo() );
4854 // Transformation
4855 ImpExportNewTrans( xPropSet, nFeatures, pRefPoint );
4857 if ( xPropSetInfo.is() )
4859 if ( xPropSetInfo->hasPropertyByName( "CustomShapeEngine" ) )
4861 uno::Any aEngine( xPropSet->getPropertyValue( "CustomShapeEngine" ) );
4862 if ( ( aEngine >>= aStr ) && !aStr.isEmpty() )
4863 mrExport.AddAttribute( XML_NAMESPACE_DRAW, XML_ENGINE, aStr );
4865 if ( xPropSetInfo->hasPropertyByName( "CustomShapeData" ) )
4867 uno::Any aData( xPropSet->getPropertyValue( "CustomShapeData" ) );
4868 if ( ( aData >>= aStr ) && !aStr.isEmpty() )
4869 mrExport.AddAttribute( XML_NAMESPACE_DRAW, XML_DATA, aStr );
4872 bool bCreateNewline( (nFeatures & XMLShapeExportFlags::NO_WS) == XMLShapeExportFlags::NONE ); // #86116#/#92210#
4873 SvXMLElementExport aOBJ( mrExport, XML_NAMESPACE_DRAW, XML_CUSTOM_SHAPE, bCreateNewline, true );
4874 ImpExportDescription( xShape ); // #i68101#
4875 ImpExportEvents( xShape );
4876 ImpExportGluePoints( xShape );
4877 ImpExportText( xShape );
4878 ImpExportEnhancedGeometry( mrExport, xPropSet );
4882 void XMLShapeExport::ImpExportTableShape( const uno::Reference< drawing::XShape >& xShape, XmlShapeType eShapeType, XMLShapeExportFlags nFeatures, com::sun::star::awt::Point* pRefPoint )
4884 uno::Reference< beans::XPropertySet > xPropSet(xShape, uno::UNO_QUERY);
4885 uno::Reference< container::XNamed > xNamed(xShape, uno::UNO_QUERY);
4887 DBG_ASSERT( xPropSet.is() && xNamed.is(), "xmloff::XMLShapeExport::ImpExportTableShape(), tabe shape is not implementing needed interfaces");
4888 if(xPropSet.is() && xNamed.is()) try
4890 // Transformation
4891 ImpExportNewTrans(xPropSet, nFeatures, pRefPoint);
4893 bool bIsEmptyPresObj = false;
4895 // presentation settings
4896 if(eShapeType == XmlShapeTypePresTableShape)
4897 bIsEmptyPresObj = ImpExportPresentationAttributes( xPropSet, GetXMLToken(XML_PRESENTATION_TABLE) );
4899 const bool bCreateNewline( (nFeatures & XMLShapeExportFlags::NO_WS) == XMLShapeExportFlags::NONE );
4900 const bool bExportEmbedded(mrExport.getExportFlags() & SvXMLExportFlags::EMBEDDED);
4902 SvXMLElementExport aElement( mrExport, XML_NAMESPACE_DRAW, XML_FRAME, bCreateNewline, true );
4904 // do not export in ODF 1.1 or older
4905 if( mrExport.getDefaultVersion() >= SvtSaveOptions::ODFVER_012 )
4907 if( !bIsEmptyPresObj )
4909 uno::Reference< container::XNamed > xTemplate( xPropSet->getPropertyValue("TableTemplate"), uno::UNO_QUERY );
4910 if( xTemplate.is() )
4912 const OUString sTemplate( xTemplate->getName() );
4913 if( !sTemplate.isEmpty() )
4915 mrExport.AddAttribute(XML_NAMESPACE_TABLE, XML_TEMPLATE_NAME, sTemplate );
4917 for( const XMLPropertyMapEntry* pEntry = &aXMLTableShapeAttributes[0]; pEntry->msApiName; pEntry++ )
4921 bool bBool = false;
4922 const OUString sAPIPropertyName( pEntry->msApiName, pEntry->nApiNameLength, RTL_TEXTENCODING_ASCII_US );
4924 xPropSet->getPropertyValue( sAPIPropertyName ) >>= bBool;
4925 if( bBool )
4926 mrExport.AddAttribute(pEntry->mnNameSpace, pEntry->meXMLName, XML_TRUE );
4928 catch( uno::Exception& )
4930 OSL_FAIL("XMLShapeExport::ImpExportTableShape(), exception caught!");
4936 uno::Reference< table::XColumnRowRange > xRange( xPropSet->getPropertyValue( msModel ), uno::UNO_QUERY_THROW );
4937 GetShapeTableExport()->exportTable( xRange );
4941 if( !bIsEmptyPresObj )
4943 uno::Reference< graphic::XGraphic > xGraphic( xPropSet->getPropertyValue("ReplacementGraphic"), uno::UNO_QUERY );
4944 if( xGraphic.is() ) try
4946 uno::Reference< uno::XComponentContext > xContext = GetExport().getComponentContext();
4948 uno::Reference< embed::XStorage > xPictureStorage;
4949 uno::Reference< embed::XStorage > xStorage;
4950 uno::Reference< io::XStream > xPictureStream;
4952 OUString sPictureName;
4953 if( bExportEmbedded )
4955 xPictureStream.set( xContext->getServiceManager()->createInstanceWithContext( "com.sun.star.comp.MemoryStream", xContext), uno::UNO_QUERY_THROW );
4957 else
4959 xStorage.set( GetExport().GetTargetStorage(), uno::UNO_QUERY_THROW );
4961 xPictureStorage.set( xStorage->openStorageElement( "Pictures" , ::embed::ElementModes::READWRITE ), uno::UNO_QUERY_THROW );
4963 sal_Int32 nIndex = 0;
4966 sPictureName = "TablePreview";
4967 sPictureName += OUString::number( ++nIndex );
4968 sPictureName += ".svm";
4970 while( xPictureStorage->hasByName( sPictureName ) );
4972 xPictureStream.set( xPictureStorage->openStreamElement( sPictureName, ::embed::ElementModes::READWRITE ), uno::UNO_QUERY_THROW );
4975 uno::Reference< graphic::XGraphicProvider > xProvider( graphic::GraphicProvider::create(xContext) );
4976 uno::Sequence< beans::PropertyValue > aArgs( 2 );
4977 aArgs[ 0 ].Name = "MimeType";
4978 aArgs[ 0 ].Value <<= OUString( "image/x-vclgraphic" );
4979 aArgs[ 1 ].Name = "OutputStream";
4980 aArgs[ 1 ].Value <<= xPictureStream->getOutputStream();
4981 xProvider->storeGraphic( xGraphic, aArgs );
4983 if( xPictureStorage.is() )
4985 uno::Reference< embed::XTransactedObject > xTrans( xPictureStorage, uno::UNO_QUERY );
4986 if( xTrans.is() )
4987 xTrans->commit();
4990 if( !bExportEmbedded )
4992 OUString sURL( "Pictures/" );
4993 sURL += sPictureName;
4994 mrExport.AddAttribute( XML_NAMESPACE_XLINK, XML_HREF, sURL );
4995 mrExport.AddAttribute( XML_NAMESPACE_XLINK, XML_TYPE, XML_SIMPLE );
4996 mrExport.AddAttribute( XML_NAMESPACE_XLINK, XML_SHOW, XML_EMBED );
4997 mrExport.AddAttribute( XML_NAMESPACE_XLINK, XML_ACTUATE, XML_ONLOAD );
5000 SvXMLElementExport aElem( GetExport(), XML_NAMESPACE_DRAW, XML_IMAGE, false, true );
5002 if( bExportEmbedded )
5004 uno::Reference< io::XSeekableInputStream > xSeekable( xPictureStream, uno::UNO_QUERY_THROW );
5005 xSeekable->seek(0);
5007 XMLBase64Export aBase64Exp( GetExport() );
5008 aBase64Exp.exportOfficeBinaryDataElement( uno::Reference < io::XInputStream >( xPictureStream, uno::UNO_QUERY_THROW ) );
5011 catch( uno::Exception& )
5013 OSL_FAIL("xmloff::XMLShapeExport::ImpExportTableShape(), exception caught!");
5017 ImpExportEvents( xShape );
5018 ImpExportGluePoints( xShape );
5019 ImpExportDescription( xShape ); // #i68101#
5021 catch( uno::Exception& )
5023 OSL_FAIL( "xmloff::XMLShapeExport::ImpExportTableShape(), exception caught!" );
5027 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */