LibreOffice Module xmloff (master)  1
shapeexport.cxx
Go to the documentation of this file.
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3  * This file is part of the LibreOffice project.
4  *
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/.
8  *
9  * This file incorporates work covered by the following license notice:
10  *
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 .
18  */
19 
29 
30 #include <com/sun/star/beans/XPropertyState.hpp>
31 #include <com/sun/star/beans/PropertyValues.hpp>
32 #include <com/sun/star/container/XChild.hpp>
33 #include <com/sun/star/container/XEnumerationAccess.hpp>
34 #include <com/sun/star/container/XIdentifierAccess.hpp>
35 #include <com/sun/star/container/XNamed.hpp>
36 #include <com/sun/star/document/XEventsSupplier.hpp>
37 #include <com/sun/star/drawing/Alignment.hpp>
38 #include <com/sun/star/drawing/CameraGeometry.hpp>
39 #include <com/sun/star/drawing/CircleKind.hpp>
40 #include <com/sun/star/drawing/ConnectorType.hpp>
41 #include <com/sun/star/drawing/Direction3D.hpp>
42 #include <com/sun/star/drawing/EscapeDirection.hpp>
43 #include <com/sun/star/drawing/EnhancedCustomShapeAdjustmentValue.hpp>
44 #include <com/sun/star/drawing/EnhancedCustomShapeGluePointType.hpp>
45 #include <com/sun/star/drawing/EnhancedCustomShapeParameterPair.hpp>
46 #include <com/sun/star/drawing/EnhancedCustomShapeParameterType.hpp>
47 #include <com/sun/star/drawing/EnhancedCustomShapeSegment.hpp>
48 #include <com/sun/star/drawing/EnhancedCustomShapeSegmentCommand.hpp>
49 #include <com/sun/star/drawing/EnhancedCustomShapeTextFrame.hpp>
50 #include <com/sun/star/drawing/EnhancedCustomShapeTextPathMode.hpp>
51 #include <com/sun/star/drawing/GluePoint2.hpp>
52 #include <com/sun/star/drawing/HomogenMatrix.hpp>
53 #include <com/sun/star/drawing/HomogenMatrix3.hpp>
54 #include <com/sun/star/drawing/PolyPolygonBezierCoords.hpp>
55 #include <com/sun/star/drawing/PolyPolygonShape3D.hpp>
56 #include <com/sun/star/drawing/Position3D.hpp>
57 #include <com/sun/star/drawing/ProjectionMode.hpp>
58 #include <com/sun/star/drawing/ShadeMode.hpp>
59 #include <com/sun/star/drawing/XControlShape.hpp>
60 #include <com/sun/star/drawing/XCustomShapeEngine.hpp>
61 #include <com/sun/star/drawing/XGluePointsSupplier.hpp>
62 #include <com/sun/star/drawing/QRCode.hpp>
63 #include <com/sun/star/drawing/QRCodeErrorCorrection.hpp>
64 #include <com/sun/star/drawing/XShapes3.hpp>
65 #include <com/sun/star/embed/ElementModes.hpp>
66 #include <com/sun/star/embed/XStorage.hpp>
67 #include <com/sun/star/embed/XTransactedObject.hpp>
68 #include <com/sun/star/graphic/XGraphic.hpp>
69 #include <com/sun/star/graphic/GraphicProvider.hpp>
70 #include <com/sun/star/graphic/XGraphicProvider.hpp>
71 #include <com/sun/star/io/XSeekableInputStream.hpp>
72 #include <com/sun/star/io/XStream.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/table/XColumnRowRange.hpp>
80 #include <com/sun/star/text/XText.hpp>
81 
82 #include <comphelper/classids.hxx>
85 #include <officecfg/Office/Common.hxx>
86 
87 #include <o3tl/any.hxx>
88 #include <o3tl/typed_flags_set.hxx>
89 
90 #include <rtl/math.hxx>
91 #include <rtl/ustrbuf.hxx>
92 #include <rtl/ustring.hxx>
93 #include <sal/log.hxx>
94 
95 #include <sax/tools/converter.hxx>
96 
97 #include <tools/debug.hxx>
98 #include <tools/globname.hxx>
99 #include <tools/helpers.hxx>
100 #include <tools/diagnose_ex.h>
101 
102 #include <xmloff/contextid.hxx>
103 #include <xmloff/families.hxx>
104 #include <xmloff/namespacemap.hxx>
105 #include <xmloff/shapeexport.hxx>
107 #include <xmloff/xmlexp.hxx>
108 #include <xmloff/xmlnamespace.hxx>
109 #include <xmloff/xmltoken.hxx>
110 #include <xmloff/xmluconv.hxx>
113 
114 #include <anim.hxx>
116 #include "sdpropls.hxx"
117 #include <xexptran.hxx>
118 #include "ximpshap.hxx"
119 #include <XMLBase64Export.hxx>
120 #include <XMLImageMapExport.hxx>
121 #include <memory>
122 
123 using namespace ::com::sun::star;
124 using namespace ::xmloff::EnhancedCustomShapeToken;
125 using namespace ::xmloff::token;
126 
127 #define XML_EMBEDDEDOBJECTGRAPHIC_URL_BASE "vnd.sun.star.GraphicObject:"
128 
129 namespace {
130 
131 bool supportsText(XmlShapeType eShapeType)
132 {
133  return eShapeType != XmlShapeTypePresChartShape &&
134  eShapeType != XmlShapeTypePresOLE2Shape &&
135  eShapeType != XmlShapeTypeDrawSheetShape &&
136  eShapeType != XmlShapeTypePresSheetShape &&
137  eShapeType != XmlShapeTypeDraw3DSceneObject &&
138  eShapeType != XmlShapeTypeDraw3DCubeObject &&
139  eShapeType != XmlShapeTypeDraw3DSphereObject &&
140  eShapeType != XmlShapeTypeDraw3DLatheObject &&
141  eShapeType != XmlShapeTypeDraw3DExtrudeObject &&
142  eShapeType != XmlShapeTypeDrawPageShape &&
143  eShapeType != XmlShapeTypePresPageShape &&
144  eShapeType != XmlShapeTypeDrawGroupShape;
145 
146 }
147 
148 }
149 
150 constexpr OUStringLiteral gsZIndex( u"ZOrder" );
151 constexpr OUStringLiteral gsPrintable( u"Printable" );
152 constexpr OUStringLiteral gsVisible( u"Visible" );
153 constexpr OUStringLiteral gsModel( u"Model" );
154 constexpr OUStringLiteral gsStartShape( u"StartShape" );
155 constexpr OUStringLiteral gsEndShape( u"EndShape" );
156 constexpr OUStringLiteral gsOnClick( u"OnClick" );
157 constexpr OUStringLiteral gsEventType( u"EventType" );
158 constexpr OUStringLiteral gsPresentation( u"Presentation" );
159 constexpr OUStringLiteral gsMacroName( u"MacroName" );
160 constexpr OUStringLiteral gsScript( u"Script" );
161 constexpr OUStringLiteral gsLibrary( u"Library" );
162 constexpr OUStringLiteral gsClickAction( u"ClickAction" );
163 constexpr OUStringLiteral gsBookmark( u"Bookmark" );
164 constexpr OUStringLiteral gsEffect( u"Effect" );
165 constexpr OUStringLiteral gsPlayFull( u"PlayFull" );
166 constexpr OUStringLiteral gsVerb( u"Verb" );
167 constexpr OUStringLiteral gsSoundURL( u"SoundURL" );
168 constexpr OUStringLiteral gsSpeed( u"Speed" );
169 constexpr OUStringLiteral gsStarBasic( u"StarBasic" );
170 constexpr OUStringLiteral gsHyperlink( u"Hyperlink" );
171 
173  SvXMLExportPropertyMapper *pExtMapper )
174 : mrExport( rExp ),
175  maShapesInfos(),
176  maCurrentShapesIter(maShapesInfos.end()),
177  mbExportLayer( false ),
178  // #88546# init to sal_False
179  mbHandleProgressBar( false )
180 {
181  // construct PropertySetMapper
183  if( pExtMapper )
184  {
185  rtl::Reference < SvXMLExportPropertyMapper > xExtMapper( pExtMapper );
186  mxPropertySetMapper->ChainExportMapper( xExtMapper );
187  }
188 
189 /*
190  // chain text attributes
191  xPropertySetMapper->ChainExportMapper(XMLTextParagraphExport::CreateParaExtPropMapper(rExp));
192 */
193 
194  mrExport.GetAutoStylePool()->AddFamily(
199  mrExport.GetAutoStylePool()->AddFamily(
204 
205  // create table export helper and let him add his families in time
207 }
208 
210 {
211 }
212 
213 // sj: replacing CustomShapes with standard objects that are also supported in OpenOffice.org format
214 uno::Reference< drawing::XShape > XMLShapeExport::checkForCustomShapeReplacement( const uno::Reference< drawing::XShape >& xShape )
215 {
216  uno::Reference< drawing::XShape > xCustomShapeReplacement;
217 
218  if( !( GetExport().getExportFlags() & SvXMLExportFlags::OASIS ) )
219  {
220  OUString aType( xShape->getShapeType() );
221  if( aType == "com.sun.star.drawing.CustomShape" )
222  {
223  uno::Reference< beans::XPropertySet > xSet( xShape, uno::UNO_QUERY );
224  if( xSet.is() )
225  {
226  OUString aEngine;
227  xSet->getPropertyValue("CustomShapeEngine") >>= aEngine;
228  if ( aEngine.isEmpty() )
229  {
230  aEngine = "com.sun.star.drawing.EnhancedCustomShapeEngine";
231  }
232  uno::Reference< uno::XComponentContext > xContext( ::comphelper::getProcessComponentContext() );
233 
234  if ( !aEngine.isEmpty() )
235  {
236  uno::Sequence< uno::Any > aArgument( 1 );
237  uno::Sequence< beans::PropertyValue > aPropValues( 2 );
238  aPropValues[ 0 ].Name = "CustomShape";
239  aPropValues[ 0 ].Value <<= xShape;
240  aPropValues[ 1 ].Name = "ForceGroupWithText";
241  aPropValues[ 1 ].Value <<= true;
242  aArgument[ 0 ] <<= aPropValues;
243  uno::Reference< uno::XInterface > xInterface(
244  xContext->getServiceManager()->createInstanceWithArgumentsAndContext(aEngine, aArgument, xContext) );
245  if ( xInterface.is() )
246  {
247  uno::Reference< drawing::XCustomShapeEngine > xCustomShapeEngine(
248  uno::Reference< drawing::XCustomShapeEngine >( xInterface, uno::UNO_QUERY ) );
249  if ( xCustomShapeEngine.is() )
250  xCustomShapeReplacement = xCustomShapeEngine->render();
251  }
252  }
253  }
254  }
255  }
256  return xCustomShapeReplacement;
257 }
258 
259 // This method collects all automatic styles for the given XShape
260 void XMLShapeExport::collectShapeAutoStyles(const uno::Reference< drawing::XShape >& xShape )
261 {
262  if( maCurrentShapesIter == maShapesInfos.end() )
263  {
264  OSL_FAIL( "XMLShapeExport::collectShapeAutoStyles(): no call to seekShapes()!" );
265  return;
266  }
267  sal_Int32 nZIndex = 0;
268  uno::Reference< beans::XPropertySet > xPropSet(xShape, uno::UNO_QUERY);
269  if( xPropSet.is() )
270  xPropSet->getPropertyValue(gsZIndex) >>= nZIndex;
271 
272  ImplXMLShapeExportInfoVector& aShapeInfoVector = (*maCurrentShapesIter).second;
273 
274  if( static_cast<sal_Int32>(aShapeInfoVector.size()) <= nZIndex )
275  {
276  OSL_FAIL( "XMLShapeExport::collectShapeAutoStyles(): no shape info allocated for a given shape" );
277  return;
278  }
279 
280  ImplXMLShapeExportInfo& aShapeInfo = aShapeInfoVector[nZIndex];
281 
282  uno::Reference< drawing::XShape > xCustomShapeReplacement = checkForCustomShapeReplacement( xShape );
283  if ( xCustomShapeReplacement.is() )
284  aShapeInfo.xCustomShapeReplacement = xCustomShapeReplacement;
285 
286  // first compute the shapes type
287  ImpCalcShapeType(xShape, aShapeInfo.meShapeType);
288 
289  // #i118485# enabled XmlShapeTypeDrawChartShape and XmlShapeTypeDrawOLE2Shape
290  // to have text
291  const bool bObjSupportsText =
292  supportsText(aShapeInfo.meShapeType);
293 
294  const bool bObjSupportsStyle =
296 
297  bool bIsEmptyPresObj = false;
298 
299  if ( aShapeInfo.xCustomShapeReplacement.is() )
300  xPropSet.clear();
301 
302  // prep text styles
303  if( xPropSet.is() && bObjSupportsText )
304  {
305  uno::Reference< text::XText > xText(xShape, uno::UNO_QUERY);
306  bool bSkip = false;
307  if (xText.is())
308  {
309  try
310  {
311  bSkip = xText->getString().isEmpty();
312  }
313  catch (uno::RuntimeException const&)
314  {
315  // tdf#102479: SwXTextFrame that contains only a table will
316  // throw, but the table must be iterated so that
317  // SwXMLExport::ExportTableLines() can find its auto styles
318  // so do not skip it!
319  }
320  }
321  if (!bSkip)
322  {
323  uno::Reference< beans::XPropertySetInfo > xPropSetInfo( xPropSet->getPropertySetInfo() );
324 
325  if( xPropSetInfo.is() && xPropSetInfo->hasPropertyByName("IsEmptyPresentationObject") )
326  {
327  uno::Any aAny = xPropSet->getPropertyValue("IsEmptyPresentationObject");
328  aAny >>= bIsEmptyPresObj;
329  }
330 
331  if(!bIsEmptyPresObj)
332  {
333  GetExport().GetTextParagraphExport()->collectTextAutoStyles( xText );
334  }
335  }
336  }
337 
338  // compute the shape parent style
339  if( xPropSet.is() )
340  {
341  uno::Reference< beans::XPropertySetInfo > xPropertySetInfo( xPropSet->getPropertySetInfo() );
342 
343  OUString aParentName;
344  uno::Reference< style::XStyle > xStyle;
345 
346  if( bObjSupportsStyle )
347  {
348  if( xPropertySetInfo.is() && xPropertySetInfo->hasPropertyByName("Style") )
349  xPropSet->getPropertyValue("Style") >>= xStyle;
350 
351  if(xStyle.is())
352  {
353  // get family ID
354  uno::Reference< beans::XPropertySet > xStylePropSet(xStyle, uno::UNO_QUERY);
355  SAL_WARN_IF( !xStylePropSet.is(), "xmloff", "style without a XPropertySet?" );
356  try
357  {
358  if(xStylePropSet.is())
359  {
360  OUString aFamilyName;
361  xStylePropSet->getPropertyValue("Family") >>= aFamilyName;
362  if( !aFamilyName.isEmpty() && aFamilyName != "graphics" )
364  }
365  }
366  catch(const beans::UnknownPropertyException&)
367  {
368  // Ignored.
369  SAL_WARN( "xmloff",
370  "XMLShapeExport::collectShapeAutoStyles: style has no 'Family' property");
371  }
372 
373  // get parent-style name
375  {
376  aParentName = msPresentationStylePrefix;
377  }
378 
379  aParentName += xStyle->getName();
380  }
381  }
382 
383  if (aParentName.isEmpty() && xPropertySetInfo->hasPropertyByName("TextBox") && xPropSet->getPropertyValue("TextBox").hasValue() && xPropSet->getPropertyValue("TextBox").get<bool>())
384  {
385  // Shapes with a Writer TextBox always have a parent style.
386  // If there would be none, then assign the default one.
387  aParentName = "Frame";
388  }
389 
390  // filter propset
391  std::vector< XMLPropertyState > aPropStates;
392 
393  sal_Int32 nCount = 0;
394  if( !bIsEmptyPresObj || (aShapeInfo.meShapeType != XmlShapeTypePresPageShape) )
395  {
396  aPropStates = GetPropertySetMapper()->Filter(mrExport, xPropSet);
397 
398  if (XmlShapeTypeDrawControlShape == aShapeInfo.meShapeType)
399  {
400  // for control shapes, we additionally need the number format style (if any)
401  uno::Reference< drawing::XControlShape > xControl(xShape, uno::UNO_QUERY);
402  DBG_ASSERT(xControl.is(), "XMLShapeExport::collectShapeAutoStyles: ShapeType control, but no XControlShape!");
403  if (xControl.is())
404  {
405  uno::Reference< beans::XPropertySet > xControlModel(xControl->getControl(), uno::UNO_QUERY);
406  DBG_ASSERT(xControlModel.is(), "XMLShapeExport::collectShapeAutoStyles: no control model on the control shape!");
407 
408  OUString sNumberStyle = mrExport.GetFormExport()->getControlNumberStyle(xControlModel);
409  if (!sNumberStyle.isEmpty())
410  {
411  sal_Int32 nIndex = GetPropertySetMapper()->getPropertySetMapper()->FindEntryIndex(CTF_SD_CONTROL_SHAPE_DATA_STYLE);
412  // TODO : this retrieval of the index could be moved into the ctor, holding the index
413  // as member, thus saving time.
414  DBG_ASSERT(-1 != nIndex, "XMLShapeExport::collectShapeAutoStyles: could not obtain the index for our context id!");
415 
416  XMLPropertyState aNewState(nIndex, uno::makeAny(sNumberStyle));
417  aPropStates.push_back(aNewState);
418  }
419  }
420  }
421 
422  nCount = std::count_if(aPropStates.cbegin(), aPropStates.cend(),
423  [](const XMLPropertyState& rProp) { return rProp.mnIndex != -1; });
424  }
425 
426  if(nCount == 0)
427  {
428  // no hard attributes, use parent style name for export
429  aShapeInfo.msStyleName = aParentName;
430  }
431  else
432  {
433  // there are filtered properties -> hard attributes
434  // try to find this style in AutoStylePool
435  aShapeInfo.msStyleName = mrExport.GetAutoStylePool()->Find(aShapeInfo.mnFamily, aParentName, aPropStates);
436 
437  if(aShapeInfo.msStyleName.isEmpty())
438  {
439  // Style did not exist, add it to AutoStalePool
440  aShapeInfo.msStyleName = mrExport.GetAutoStylePool()->Add(aShapeInfo.mnFamily, aParentName, aPropStates);
441  }
442  }
443 
444  // optionally generate auto style for text attributes
445  if( (!bIsEmptyPresObj || (aShapeInfo.meShapeType != XmlShapeTypePresPageShape)) && bObjSupportsText )
446  {
447  aPropStates = GetExport().GetTextParagraphExport()->GetParagraphPropertyMapper()->Filter(mrExport, xPropSet);
448 
449  // yet more additionally, we need to care for the ParaAdjust property
450  if ( XmlShapeTypeDrawControlShape == aShapeInfo.meShapeType )
451  {
452  uno::Reference< beans::XPropertySetInfo > xPropSetInfo( xPropSet->getPropertySetInfo() );
453  uno::Reference< beans::XPropertyState > xPropState( xPropSet, uno::UNO_QUERY );
454  if ( xPropSetInfo.is() && xPropState.is() )
455  {
456  // this is because:
457  // * if controls shapes have a ParaAdjust property, then this is the Align property of the control model
458  // * control models are allowed to have an Align of "void"
459  // * the Default for control model's Align is TextAlign_LEFT
460  // * defaults for style properties are not written, but we need to write the "left",
461  // because we need to distinguish this "left" from the case where not align attribute
462  // is present which means "void"
463  if ( xPropSetInfo->hasPropertyByName( "ParaAdjust" )
464  && ( beans::PropertyState_DEFAULT_VALUE == xPropState->getPropertyState( "ParaAdjust" ) )
465  )
466  {
467  sal_Int32 nIndex = GetExport().GetTextParagraphExport()->GetParagraphPropertyMapper()->getPropertySetMapper()->FindEntryIndex( CTF_SD_SHAPE_PARA_ADJUST );
468  // TODO : this retrieval of the index should be moved into the ctor, holding the index
469  // as member, thus saving time.
470  DBG_ASSERT(-1 != nIndex, "XMLShapeExport::collectShapeAutoStyles: could not obtain the index for the ParaAdjust context id!");
471 
472  uno::Any aParaAdjustValue = xPropSet->getPropertyValue( "ParaAdjust" );
473  XMLPropertyState aAlignDefaultState( nIndex, aParaAdjustValue );
474 
475  aPropStates.push_back( aAlignDefaultState );
476  }
477  }
478  }
479 
480  nCount = std::count_if(aPropStates.cbegin(), aPropStates.cend(),
481  [](const XMLPropertyState& rProp) { return rProp.mnIndex != -1; });
482 
483  if( nCount )
484  {
485  aShapeInfo.msTextStyleName = mrExport.GetAutoStylePool()->Find( XmlStyleFamily::TEXT_PARAGRAPH, "", aPropStates );
486  if(aShapeInfo.msTextStyleName.isEmpty())
487  {
488  // Style did not exist, add it to AutoStalePool
489  aShapeInfo.msTextStyleName = mrExport.GetAutoStylePool()->Add(XmlStyleFamily::TEXT_PARAGRAPH, "", aPropStates);
490  }
491  }
492  }
493  }
494 
495  // prepare animation information if needed
496  if( mxAnimationsExporter.is() )
498 
499  // check for special shapes
500 
501  switch( aShapeInfo.meShapeType )
502  {
504  {
505  uno::Reference< uno::XInterface > xConnection;
506 
507  // create shape ids for export later
508  xPropSet->getPropertyValue( gsStartShape ) >>= xConnection;
509  if( xConnection.is() )
511 
512  xPropSet->getPropertyValue( gsEndShape ) >>= xConnection;
513  if( xConnection.is() )
515  break;
516  }
519  {
520  try
521  {
522  uno::Reference< table::XColumnRowRange > xRange( xPropSet->getPropertyValue( gsModel ), uno::UNO_QUERY_THROW );
523  GetShapeTableExport()->collectTableAutoStyles( xRange );
524  }
525  catch(const uno::Exception&)
526  {
527  DBG_UNHANDLED_EXCEPTION( "xmloff", "collecting auto styles for a table" );
528  }
529  break;
530  }
531  default:
532  break;
533  }
534 
535  // check for shape collections (group shape or 3d scene)
536  // and collect contained shapes style infos
537  const uno::Reference< drawing::XShape >& xCollection = aShapeInfo.xCustomShapeReplacement.is()
538  ? aShapeInfo.xCustomShapeReplacement : xShape;
539  {
540  uno::Reference< drawing::XShapes > xShapes( xCollection, uno::UNO_QUERY );
541  if( xShapes.is() )
542  {
543  collectShapesAutoStyles( xShapes );
544  }
545  }
546 }
547 
548 namespace
549 {
550  class NewTextListsHelper
551  {
552  public:
553  explicit NewTextListsHelper( SvXMLExport& rExp )
554  : mrExport( rExp )
555  {
556  mrExport.GetTextParagraphExport()->PushNewTextListsHelper();
557  }
558 
559  ~NewTextListsHelper()
560  {
561  mrExport.GetTextParagraphExport()->PopTextListsHelper();
562  }
563 
564  private:
565  SvXMLExport& mrExport;
566  };
567 }
568 // This method exports the given XShape
569 void XMLShapeExport::exportShape(const uno::Reference< drawing::XShape >& xShape,
570  XMLShapeExportFlags nFeatures /* = SEF_DEFAULT */,
571  css::awt::Point* pRefPoint /* = NULL */,
572  SvXMLAttributeList* pAttrList /* = NULL */ )
573 {
574  SAL_INFO("xmloff", xShape->getShapeType());
575  if( maCurrentShapesIter == maShapesInfos.end() )
576  {
577  SAL_WARN( "xmloff", "XMLShapeExport::exportShape(): no auto styles where collected before export" );
578  return;
579  }
580  sal_Int32 nZIndex = 0;
581  uno::Reference< beans::XPropertySet > xSet( xShape, uno::UNO_QUERY );
582  OUString sHyperlink;
583  try
584  {
585  xSet->getPropertyValue(gsHyperlink) >>= sHyperlink;
586  }
587  catch (beans::UnknownPropertyException)
588  {
589  }
590 
591  std::unique_ptr< SvXMLElementExport > pHyperlinkElement;
592 
593  // Need to stash the attributes that are pre-loaded for the shape export
594  // (otherwise they will become attributes of the draw:a element)
595  uno::Reference<xml::sax::XAttributeList> xSaveAttribs(
596  new SvXMLAttributeList(GetExport().GetAttrList()));
598  if( xSet.is() && (GetExport().GetModelType() == SvtModuleOptions::EFactory::DRAW) )
599  {
600  // export hyperlinks with <a><shape/></a>. Currently only in draw since draw
601  // does not support document events
602  try
603  {
604  presentation::ClickAction eAction = presentation::ClickAction_NONE;
605  xSet->getPropertyValue(gsOnClick) >>= eAction;
606 
607  if( (eAction == presentation::ClickAction_DOCUMENT) ||
608  (eAction == presentation::ClickAction_BOOKMARK) )
609  {
610  OUString sURL;
611  xSet->getPropertyValue(gsBookmark) >>= sURL;
612 
613  if( !sURL.isEmpty() )
614  {
618  pHyperlinkElement.reset( new SvXMLElementExport(mrExport, XML_NAMESPACE_DRAW, XML_A, true, true) );
619  }
620  }
621  }
622  catch(const uno::Exception&)
623  {
624  TOOLS_WARN_EXCEPTION("xmloff", "XMLShapeExport::exportShape(): exception during hyperlink export");
625  }
626  }
627  else if (xSet.is() && !sHyperlink.isEmpty())
628  {
631  pHyperlinkElement.reset( new SvXMLElementExport(mrExport, XML_NAMESPACE_DRAW, XML_A, true, true) );
632  }
633  // re-add stashed attributes
634  GetExport().AddAttributeList(xSaveAttribs);
635 
636  if( xSet.is() )
637  xSet->getPropertyValue(gsZIndex) >>= nZIndex;
638 
639  ImplXMLShapeExportInfoVector& aShapeInfoVector = (*maCurrentShapesIter).second;
640 
641  if( static_cast<sal_Int32>(aShapeInfoVector.size()) <= nZIndex )
642  {
643  SAL_WARN( "xmloff", "XMLShapeExport::exportShape(): no shape info collected for a given shape" );
644  return;
645  }
646 
647  NewTextListsHelper aNewTextListsHelper( mrExport );
648 
649  const ImplXMLShapeExportInfo& aShapeInfo = aShapeInfoVector[nZIndex];
650 
651 #ifdef DBG_UTIL
652  // check if this is the correct ShapesInfo
653  uno::Reference< container::XChild > xChild( xShape, uno::UNO_QUERY );
654  if( xChild.is() )
655  {
656  uno::Reference< drawing::XShapes > xParent( xChild->getParent(), uno::UNO_QUERY );
657  SAL_WARN_IF( !xParent.is() && xParent.get() == (*maCurrentShapesIter).first.get(), "xmloff", "XMLShapeExport::exportShape(): Wrong call to XMLShapeExport::seekShapes()" );
658  }
659 
660  // first compute the shapes type
661  {
663  ImpCalcShapeType(xShape, eShapeType);
664 
665  SAL_WARN_IF( eShapeType != aShapeInfo.meShapeType, "xmloff", "exportShape callings do not correspond to collectShapeAutoStyles calls!: " << xShape->getShapeType() );
666  }
667 #endif
668 
669  // collect animation information if needed
670  if( mxAnimationsExporter.is() )
671  mxAnimationsExporter->collect( xShape, mrExport );
672 
673  /* Export shapes name if he has one (#i51726#)
674  Export of the shape name for text documents only if the OpenDocument
675  file format is written - exceptions are group shapes.
676  Note: Writer documents in OpenOffice.org file format doesn't contain
677  any names for shapes, except for group shapes.
678  */
679  {
680  if ( ( GetExport().GetModelType() != SvtModuleOptions::EFactory::WRITER &&
681  GetExport().GetModelType() != SvtModuleOptions::EFactory::WRITERWEB &&
682  GetExport().GetModelType() != SvtModuleOptions::EFactory::WRITERGLOBAL ) ||
683  ( GetExport().getExportFlags() & SvXMLExportFlags::OASIS ) ||
684  aShapeInfo.meShapeType == XmlShapeTypeDrawGroupShape ||
685  ( aShapeInfo.meShapeType == XmlShapeTypeDrawCustomShape &&
686  aShapeInfo.xCustomShapeReplacement.is() ) )
687  {
688  uno::Reference< container::XNamed > xNamed( xShape, uno::UNO_QUERY );
689  if( xNamed.is() )
690  {
691  const OUString aName( xNamed->getName() );
692  if( !aName.isEmpty() )
694  }
695  }
696  }
697 
698  // export style name
699  if( !aShapeInfo.msStyleName.isEmpty() )
700  {
701  if(XmlStyleFamily::SD_GRAPHICS_ID == aShapeInfo.mnFamily)
703  else
705  }
706 
707  // export text style name
708  if( !aShapeInfo.msTextStyleName.isEmpty() )
709  {
711  }
712 
713  // export shapes id if needed
714  {
715  uno::Reference< uno::XInterface > xRef( xShape, uno::UNO_QUERY );
716  const OUString& rShapeId = mrExport.getInterfaceToIdentifierMapper().getIdentifier( xRef );
717  if( !rShapeId.isEmpty() )
718  {
720  }
721  }
722 
723  // export layer information
724  if( mbExportLayer )
725  {
726  // check for group or scene shape and not export layer if this is one
727  uno::Reference< drawing::XShapes > xShapes( xShape, uno::UNO_QUERY );
728  if( !xShapes.is() )
729  {
730  try
731  {
732  uno::Reference< beans::XPropertySet > xProps( xShape, uno::UNO_QUERY );
733  OUString aLayerName;
734  xProps->getPropertyValue("LayerName") >>= aLayerName;
736 
737  }
738  catch(const uno::Exception&)
739  {
740  DBG_UNHANDLED_EXCEPTION( "xmloff", "exporting layer name for shape" );
741  }
742  }
743  }
744 
745  // export draw:display (do not export in ODF 1.3 or older)
747  {
748  if( aShapeInfo.meShapeType != XmlShapeTypeDrawPageShape && aShapeInfo.meShapeType != XmlShapeTypePresPageShape &&
750  try
751  {
752  bool bVisible = true;
753  bool bPrintable = true;
754 
755  xSet->getPropertyValue(gsVisible) >>= bVisible;
756  xSet->getPropertyValue(gsPrintable) >>= bPrintable;
757 
758  XMLTokenEnum eDisplayToken = XML_TOKEN_INVALID;
759  const unsigned short nDisplay = (bVisible ? 2 : 0) | (bPrintable ? 1 : 0);
760  switch( nDisplay )
761  {
762  case 0: eDisplayToken = XML_NONE; break;
763  case 1: eDisplayToken = XML_PRINTER; break;
764  case 2: eDisplayToken = XML_SCREEN; break;
765  // case 3: eDisplayToken = XML_ALWAYS break; this is the default
766  }
767 
768  if( eDisplayToken != XML_TOKEN_INVALID )
770  }
771  catch(const uno::Exception&)
772  {
773  DBG_UNHANDLED_EXCEPTION("xmloff.draw");
774  }
775  }
776 
777  // #82003# test export count
778  // #91587# ALWAYS increment since now ALL to be exported shapes are counted.
779  if(mrExport.GetShapeExport()->IsHandleProgressBarEnabled())
780  {
782  }
783 
784  onExport( xShape );
785 
786  // export shape element
787  switch(aShapeInfo.meShapeType)
788  {
790  {
791  ImpExportRectangleShape(xShape, nFeatures, pRefPoint );
792  break;
793  }
795  {
796  ImpExportEllipseShape(xShape, nFeatures, pRefPoint );
797  break;
798  }
800  {
801  ImpExportLineShape(xShape, nFeatures, pRefPoint );
802  break;
803  }
804  case XmlShapeTypeDrawPolyPolygonShape: // closed PolyPolygon
805  case XmlShapeTypeDrawPolyLineShape: // open PolyPolygon
806  case XmlShapeTypeDrawClosedBezierShape: // closed tools::PolyPolygon containing curves
807  case XmlShapeTypeDrawOpenBezierShape: // open tools::PolyPolygon containing curves
808  {
809  ImpExportPolygonShape(xShape, aShapeInfo.meShapeType, nFeatures, pRefPoint );
810  break;
811  }
812 
822  {
823  ImpExportTextBoxShape(xShape, aShapeInfo.meShapeType, nFeatures, pRefPoint );
824  break;
825  }
826 
829  {
830  ImpExportGraphicObjectShape(xShape, aShapeInfo.meShapeType, nFeatures, pRefPoint );
831  break;
832  }
833 
836  {
837  ImpExportChartShape(xShape, aShapeInfo.meShapeType, nFeatures, pRefPoint, pAttrList );
838  break;
839  }
840 
842  {
843  ImpExportControlShape(xShape, nFeatures, pRefPoint );
844  break;
845  }
846 
848  {
849  ImpExportConnectorShape(xShape, nFeatures, pRefPoint );
850  break;
851  }
852 
854  {
855  ImpExportMeasureShape(xShape, nFeatures, pRefPoint );
856  break;
857  }
858 
863  {
864  ImpExportOLE2Shape(xShape, aShapeInfo.meShapeType, nFeatures, pRefPoint );
865  break;
866  }
867 
870  {
871  ImpExportTableShape( xShape, aShapeInfo.meShapeType, nFeatures, pRefPoint );
872  break;
873  }
874 
878  {
879  ImpExportPageShape(xShape, aShapeInfo.meShapeType, nFeatures, pRefPoint );
880  break;
881  }
882 
884  {
885  ImpExportCaptionShape(xShape, nFeatures, pRefPoint );
886  break;
887  }
888 
893  {
894  ImpExport3DShape(xShape, aShapeInfo.meShapeType);
895  break;
896  }
897 
899  {
900  ImpExport3DSceneShape( xShape, nFeatures, pRefPoint );
901  break;
902  }
903 
905  {
906  // empty group
907  ImpExportGroupShape( xShape, nFeatures, pRefPoint );
908  break;
909  }
910 
912  {
913  ImpExportFrameShape(xShape, nFeatures, pRefPoint );
914  break;
915  }
916 
918  {
919  ImpExportAppletShape(xShape, nFeatures, pRefPoint );
920  break;
921  }
922 
924  {
925  ImpExportPluginShape(xShape, nFeatures, pRefPoint );
926  break;
927  }
928 
930  {
931  if ( aShapeInfo.xCustomShapeReplacement.is() )
932  ImpExportGroupShape( aShapeInfo.xCustomShapeReplacement, nFeatures, pRefPoint );
933  else
934  ImpExportCustomShape( xShape, nFeatures, pRefPoint );
935  break;
936  }
937 
940  {
941  ImpExportMediaShape( xShape, aShapeInfo.meShapeType, nFeatures, pRefPoint );
942  break;
943  }
944 
946  case XmlShapeTypeUnknown:
948  default:
949  {
950  // this should never happen and is an error
951  OSL_FAIL("XMLEXP: WriteShape: unknown or unexpected type of shape in export!");
952  break;
953  }
954  }
955 
956  pHyperlinkElement.reset();
957 
958  // #97489# #97111#
959  // if there was an error and no element for the shape was exported
960  // we need to clear the attribute list or the attributes will be
961  // set on the next exported element, which can result in corrupt
962  // xml files due to duplicate attributes
963 
964  mrExport.CheckAttrList(); // asserts in non pro if we have attributes left
965  mrExport.ClearAttrList(); // clears the attributes
966 }
967 
968 // This method collects all automatic styles for the shapes inside the given XShapes collection
969 void XMLShapeExport::collectShapesAutoStyles( const uno::Reference < drawing::XShapes >& xShapes )
970 {
971  ShapesInfos::iterator aOldCurrentShapesIter = maCurrentShapesIter;
972  seekShapes( xShapes );
973 
974  uno::Reference< drawing::XShape > xShape;
975  const sal_Int32 nShapeCount(xShapes->getCount());
976  for(sal_Int32 nShapeId = 0; nShapeId < nShapeCount; nShapeId++)
977  {
978  xShapes->getByIndex(nShapeId) >>= xShape;
979  SAL_WARN_IF( !xShape.is(), "xmloff", "Shape without a XShape?" );
980  if(!xShape.is())
981  continue;
982 
983  collectShapeAutoStyles( xShape );
984  }
985 
986  maCurrentShapesIter = aOldCurrentShapesIter;
987 }
988 
989 // This method exports all XShape inside the given XShapes collection
990 void XMLShapeExport::exportShapes( const uno::Reference < drawing::XShapes >& xShapes, XMLShapeExportFlags nFeatures /* = SEF_DEFAULT */, awt::Point* pRefPoint /* = NULL */ )
991 {
992  ShapesInfos::iterator aOldCurrentShapesIter = maCurrentShapesIter;
993  seekShapes( xShapes );
994 
995  uno::Reference< drawing::XShape > xShape;
996  const sal_Int32 nShapeCount(xShapes->getCount());
997  for(sal_Int32 nShapeId = 0; nShapeId < nShapeCount; nShapeId++)
998  {
999  xShapes->getByIndex(nShapeId) >>= xShape;
1000  SAL_WARN_IF( !xShape.is(), "xmloff", "Shape without a XShape?" );
1001  if(!xShape.is())
1002  continue;
1003 
1004  exportShape( xShape, nFeatures, pRefPoint );
1005  }
1006 
1007  maCurrentShapesIter = aOldCurrentShapesIter;
1008 }
1009 
1010 namespace xmloff {
1011 
1012 void FixZOrder(uno::Reference<drawing::XShapes> const& xShapes,
1013  std::function<unsigned int (uno::Reference<beans::XPropertySet> const&)> const& rGetLayer)
1014 {
1015  uno::Reference<drawing::XShapes3> const xShapes3(xShapes, uno::UNO_QUERY);
1016  assert(xShapes3.is());
1017  if (!xShapes3.is())
1018  {
1019  return; // only SvxDrawPage implements this
1020  }
1021  struct Layer { std::vector<sal_Int32> shapes; sal_Int32 nMin = SAL_MAX_INT32; sal_Int32 nMax = 0; };
1022  std::vector<Layer> layers;
1023  // shapes are sorted by ZOrder
1024  sal_Int32 const nCount(xShapes->getCount());
1025  for (sal_Int32 i = 0; i < nCount; ++i)
1026  {
1027  uno::Reference<beans::XPropertySet> const xShape(xShapes->getByIndex(i), uno::UNO_QUERY);
1028  unsigned int const nLayer(rGetLayer(xShape));
1029  if (layers.size() <= nLayer)
1030  {
1031  layers.resize(nLayer + 1);
1032  }
1033  layers[nLayer].shapes.emplace_back(i);
1034  if (i < layers[nLayer].nMin)
1035  {
1036  layers[nLayer].nMin = i;
1037  }
1038  if (layers[nLayer].nMax < i)
1039  {
1040  layers[nLayer].nMax = i;
1041  }
1042  }
1043  layers.erase(std::remove_if(layers.begin(), layers.end(),
1044  [](Layer const& rLayer) { return rLayer.shapes.empty(); }),
1045  layers.end());
1046  bool isSorted(true);
1047  for (size_t i = 1; i < layers.size(); ++i)
1048  {
1049  assert(layers[i].nMin != layers[i-1].nMax); // unique!
1050  if (layers[i].nMin < layers[i-1].nMax)
1051  {
1052  isSorted = false;
1053  break;
1054  }
1055  }
1056  if (isSorted)
1057  {
1058  return; // nothing to do
1059  }
1060  uno::Sequence<sal_Int32> aNewOrder(nCount);
1061  auto iterInsert(aNewOrder.begin());
1062  for (auto const& rLayer : layers)
1063  {
1064  assert(rLayer.nMin <= rLayer.nMax); // empty layers have been removed
1065  iterInsert = std::copy(rLayer.shapes.begin(), rLayer.shapes.end(), iterInsert);
1066  }
1067  try
1068  {
1069  xShapes3->sort(aNewOrder);
1070  }
1071  catch (uno::Exception const&)
1072  {
1073  SAL_WARN("xmloff", "FixZOrder: exception");
1074  }
1075 }
1076 
1077 } // namespace xmloff
1078 
1079 void XMLShapeExport::seekShapes( const uno::Reference< drawing::XShapes >& xShapes ) noexcept
1080 {
1081  if( xShapes.is() )
1082  {
1083  maCurrentShapesIter = maShapesInfos.find( xShapes );
1084  if( maCurrentShapesIter == maShapesInfos.end() )
1085  {
1086  ImplXMLShapeExportInfoVector aNewInfoVector;
1087  aNewInfoVector.resize( static_cast<ShapesInfos::size_type>(xShapes->getCount()) );
1088  maShapesInfos[ xShapes ] = aNewInfoVector;
1089 
1090  maCurrentShapesIter = maShapesInfos.find( xShapes );
1091 
1092  SAL_WARN_IF( maCurrentShapesIter == maShapesInfos.end(), "xmloff", "XMLShapeExport::seekShapes(): insert into stl::map failed" );
1093  }
1094 
1095  SAL_WARN_IF( (*maCurrentShapesIter).second.size() != static_cast<ShapesInfos::size_type>(xShapes->getCount()), "xmloff", "XMLShapeExport::seekShapes(): XShapes size varied between calls" );
1096 
1097  }
1098  else
1099  {
1100  maCurrentShapesIter = maShapesInfos.end();
1101  }
1102 }
1103 
1105 {
1106  // export all autostyle infos
1107 
1108  // ...for graphic
1109  {
1111  }
1112 
1113  // ...for presentation
1114  {
1116  }
1117 
1118  if( mxShapeTableExport.is() )
1119  mxShapeTableExport->exportAutoStyles();
1120 }
1121 
1124  SvXMLExport& rExport )
1125 {
1128  rExport.GetTextParagraphExport(); // get or create text paragraph export
1129  SvXMLExportPropertyMapper* pResult =
1130  new XMLShapeExportPropertyMapper( xMapper, rExport );
1131  // chain text attributes
1132  return pResult;
1133 }
1134 
1135 void XMLShapeExport::ImpCalcShapeType(const uno::Reference< drawing::XShape >& xShape,
1136  XmlShapeType& eShapeType)
1137 {
1138  // set in every case, so init here
1139  eShapeType = XmlShapeTypeUnknown;
1140 
1141  if(!xShape.is())
1142  return;
1143 
1144  OUString aType(xShape->getShapeType());
1145 
1146  if(!aType.match("com.sun.star."))
1147  return;
1148 
1149  if(aType.match("drawing.", 13))
1150  {
1151  // drawing shapes
1152  if (aType.match("Rectangle", 21)) { eShapeType = XmlShapeTypeDrawRectangleShape; }
1153 
1154  // #i72177# Note: Correcting CustomShape, CustomShape->Custom, len from 9 (was wrong anyways) to 6.
1155  // As can be seen at the other compares, the appendix "Shape" is left out of the comparison.
1156  else if(aType.match("Custom", 21)) { eShapeType = XmlShapeTypeDrawCustomShape; }
1157 
1158  else if(aType.match("Ellipse", 21)) { eShapeType = XmlShapeTypeDrawEllipseShape; }
1159  else if(aType.match("Control", 21)) { eShapeType = XmlShapeTypeDrawControlShape; }
1160  else if(aType.match("Connector", 21)) { eShapeType = XmlShapeTypeDrawConnectorShape; }
1161  else if(aType.match("Measure", 21)) { eShapeType = XmlShapeTypeDrawMeasureShape; }
1162  else if(aType.match("Line", 21)) { eShapeType = XmlShapeTypeDrawLineShape; }
1163 
1164  // #i72177# Note: This covers two types by purpose, PolyPolygonShape and PolyPolygonPathShape
1165  else if(aType.match("PolyPolygon", 21)) { eShapeType = XmlShapeTypeDrawPolyPolygonShape; }
1166 
1167  // #i72177# Note: This covers two types by purpose, PolyLineShape and PolyLinePathShape
1168  else if(aType.match("PolyLine", 21)) { eShapeType = XmlShapeTypeDrawPolyLineShape; }
1169 
1170  else if(aType.match("OpenBezier", 21)) { eShapeType = XmlShapeTypeDrawOpenBezierShape; }
1171  else if(aType.match("ClosedBezier", 21)) { eShapeType = XmlShapeTypeDrawClosedBezierShape; }
1172 
1173  // #i72177# FreeHand (opened and closed) now supports the types OpenFreeHandShape and
1174  // ClosedFreeHandShape respectively. Represent them as bezier shapes
1175  else if(aType.match("OpenFreeHand", 21)) { eShapeType = XmlShapeTypeDrawOpenBezierShape; }
1176  else if(aType.match("ClosedFreeHand", 21)) { eShapeType = XmlShapeTypeDrawClosedBezierShape; }
1177 
1178  else if(aType.match("GraphicObject", 21)) { eShapeType = XmlShapeTypeDrawGraphicObjectShape; }
1179  else if(aType.match("Group", 21)) { eShapeType = XmlShapeTypeDrawGroupShape; }
1180  else if(aType.match("Text", 21)) { eShapeType = XmlShapeTypeDrawTextShape; }
1181  else if(aType.match("OLE2", 21))
1182  {
1183  eShapeType = XmlShapeTypeDrawOLE2Shape;
1184 
1185  // get info about presentation shape
1186  uno::Reference <beans::XPropertySet> xPropSet(xShape, uno::UNO_QUERY);
1187 
1188  if(xPropSet.is())
1189  {
1190  OUString sCLSID;
1191  if(xPropSet->getPropertyValue("CLSID") >>= sCLSID)
1192  {
1193  if (sCLSID == mrExport.GetChartExport()->getChartCLSID() ||
1194  sCLSID == SvGlobalName( SO3_RPTCH_CLASSID ).GetHexName() )
1195  {
1196  eShapeType = XmlShapeTypeDrawChartShape;
1197  }
1198  else if (sCLSID == SvGlobalName( SO3_SC_CLASSID ).GetHexName() )
1199  {
1200  eShapeType = XmlShapeTypeDrawSheetShape;
1201  }
1202  else
1203  {
1204  // general OLE2 Object
1205  }
1206  }
1207  }
1208  }
1209  else if(aType.match("Page", 21)) { eShapeType = XmlShapeTypeDrawPageShape; }
1210  else if(aType.match("Frame", 21)) { eShapeType = XmlShapeTypeDrawFrameShape; }
1211  else if(aType.match("Caption", 21)) { eShapeType = XmlShapeTypeDrawCaptionShape; }
1212  else if(aType.match("Plugin", 21)) { eShapeType = XmlShapeTypeDrawPluginShape; }
1213  else if(aType.match("Applet", 21)) { eShapeType = XmlShapeTypeDrawAppletShape; }
1214  else if(aType.match("MediaShape", 21)) { eShapeType = XmlShapeTypeDrawMediaShape; }
1215  else if(aType.match("TableShape", 21)) { eShapeType = XmlShapeTypeDrawTableShape; }
1216 
1217  // 3D shapes
1218  else if(aType.match("Scene", 21 + 7)) { eShapeType = XmlShapeTypeDraw3DSceneObject; }
1219  else if(aType.match("Cube", 21 + 7)) { eShapeType = XmlShapeTypeDraw3DCubeObject; }
1220  else if(aType.match("Sphere", 21 + 7)) { eShapeType = XmlShapeTypeDraw3DSphereObject; }
1221  else if(aType.match("Lathe", 21 + 7)) { eShapeType = XmlShapeTypeDraw3DLatheObject; }
1222  else if(aType.match("Extrude", 21 + 7)) { eShapeType = XmlShapeTypeDraw3DExtrudeObject; }
1223  }
1224  else if(aType.match("presentation.", 13))
1225  {
1226  // presentation shapes
1227  if (aType.match("TitleText", 26)) { eShapeType = XmlShapeTypePresTitleTextShape; }
1228  else if(aType.match("Outliner", 26)) { eShapeType = XmlShapeTypePresOutlinerShape; }
1229  else if(aType.match("Subtitle", 26)) { eShapeType = XmlShapeTypePresSubtitleShape; }
1230  else if(aType.match("GraphicObject", 26)) { eShapeType = XmlShapeTypePresGraphicObjectShape; }
1231  else if(aType.match("Page", 26)) { eShapeType = XmlShapeTypePresPageShape; }
1232  else if(aType.match("OLE2", 26))
1233  {
1234  eShapeType = XmlShapeTypePresOLE2Shape;
1235 
1236  // get info about presentation shape
1237  uno::Reference <beans::XPropertySet> xPropSet(xShape, uno::UNO_QUERY);
1238 
1239  if(xPropSet.is()) try
1240  {
1241  OUString sCLSID;
1242  if(xPropSet->getPropertyValue("CLSID") >>= sCLSID)
1243  {
1244  if( sCLSID == SvGlobalName( SO3_SC_CLASSID ).GetHexName() )
1245  {
1246  eShapeType = XmlShapeTypePresSheetShape;
1247  }
1248  }
1249  }
1250  catch(const uno::Exception&)
1251  {
1252  SAL_WARN( "xmloff", "XMLShapeExport::ImpCalcShapeType(), expected ole shape to have the CLSID property?" );
1253  }
1254  }
1255  else if(aType.match("Chart", 26)) { eShapeType = XmlShapeTypePresChartShape; }
1256  else if(aType.match("OrgChart", 26)) { eShapeType = XmlShapeTypePresOrgChartShape; }
1257  else if(aType.match("CalcShape", 26)) { eShapeType = XmlShapeTypePresSheetShape; }
1258  else if(aType.match("TableShape", 26)) { eShapeType = XmlShapeTypePresTableShape; }
1259  else if(aType.match("Notes", 26)) { eShapeType = XmlShapeTypePresNotesShape; }
1260  else if(aType.match("HandoutShape", 26)) { eShapeType = XmlShapeTypeHandoutShape; }
1261  else if(aType.match("HeaderShape", 26)) { eShapeType = XmlShapeTypePresHeaderShape; }
1262  else if(aType.match("FooterShape", 26)) { eShapeType = XmlShapeTypePresFooterShape; }
1263  else if(aType.match("SlideNumberShape", 26)) { eShapeType = XmlShapeTypePresSlideNumberShape; }
1264  else if(aType.match("DateTimeShape", 26)) { eShapeType = XmlShapeTypePresDateTimeShape; }
1265  else if(aType.match("MediaShape", 26)) { eShapeType = XmlShapeTypePresMediaShape; }
1266  }
1267 }
1268 
1270 void XMLShapeExport::ImpExportGluePoints( const uno::Reference< drawing::XShape >& xShape )
1271 {
1272  uno::Reference< drawing::XGluePointsSupplier > xSupplier( xShape, uno::UNO_QUERY );
1273  if( !xSupplier.is() )
1274  return;
1275 
1276  uno::Reference< container::XIdentifierAccess > xGluePoints( xSupplier->getGluePoints(), uno::UNO_QUERY );
1277  if( !xGluePoints.is() )
1278  return;
1279 
1280  drawing::GluePoint2 aGluePoint;
1281 
1282  uno::Sequence< sal_Int32 > aIdSequence( xGluePoints->getIdentifiers() );
1283 
1284  for( const sal_Int32 nIdentifier : aIdSequence )
1285  {
1286  if( (xGluePoints->getByIdentifier( nIdentifier ) >>= aGluePoint) && aGluePoint.IsUserDefined )
1287  {
1288  // export only user defined glue points
1289 
1290  const OUString sId( OUString::number( nIdentifier ) );
1292 
1294  aGluePoint.Position.X);
1295  mrExport.AddAttribute(XML_NAMESPACE_SVG, XML_X, msBuffer.makeStringAndClear());
1296 
1298  aGluePoint.Position.Y);
1299  mrExport.AddAttribute(XML_NAMESPACE_SVG, XML_Y, msBuffer.makeStringAndClear());
1300 
1301  if( !aGluePoint.IsRelative )
1302  {
1303  SvXMLUnitConverter::convertEnum( msBuffer, aGluePoint.PositionAlignment, aXML_GlueAlignment_EnumMap );
1304  mrExport.AddAttribute( XML_NAMESPACE_DRAW, XML_ALIGN, msBuffer.makeStringAndClear() );
1305  }
1306 
1307  if( aGluePoint.Escape != drawing::EscapeDirection_SMART )
1308  {
1311  }
1312 
1313  SvXMLElementExport aEventsElemt(mrExport, XML_NAMESPACE_DRAW, XML_GLUE_POINT, true, true);
1314  }
1315  }
1316 }
1317 
1318 void XMLShapeExport::ImpExportSignatureLine(const uno::Reference<drawing::XShape>& xShape)
1319 {
1320  uno::Reference<beans::XPropertySet> xPropSet(xShape, uno::UNO_QUERY);
1321 
1322  bool bIsSignatureLine = false;
1323  xPropSet->getPropertyValue("IsSignatureLine") >>= bIsSignatureLine;
1324  if (!bIsSignatureLine)
1325  return;
1326 
1327  OUString aSignatureLineId;
1328  xPropSet->getPropertyValue("SignatureLineId") >>= aSignatureLineId;
1329  mrExport.AddAttribute(XML_NAMESPACE_LO_EXT, XML_ID, aSignatureLineId);
1330 
1331  OUString aSuggestedSignerName;
1332  xPropSet->getPropertyValue("SignatureLineSuggestedSignerName") >>= aSuggestedSignerName;
1333  if (!aSuggestedSignerName.isEmpty())
1335 
1336  OUString aSuggestedSignerTitle;
1337  xPropSet->getPropertyValue("SignatureLineSuggestedSignerTitle") >>= aSuggestedSignerTitle;
1338  if (!aSuggestedSignerTitle.isEmpty())
1340 
1341  OUString aSuggestedSignerEmail;
1342  xPropSet->getPropertyValue("SignatureLineSuggestedSignerEmail") >>= aSuggestedSignerEmail;
1343  if (!aSuggestedSignerEmail.isEmpty())
1345 
1346  OUString aSigningInstructions;
1347  xPropSet->getPropertyValue("SignatureLineSigningInstructions") >>= aSigningInstructions;
1348  if (!aSigningInstructions.isEmpty())
1350 
1351  bool bShowSignDate = false;
1352  xPropSet->getPropertyValue("SignatureLineShowSignDate") >>= bShowSignDate;
1354  bShowSignDate ? XML_TRUE : XML_FALSE);
1355 
1356  bool bCanAddComment = false;
1357  xPropSet->getPropertyValue("SignatureLineCanAddComment") >>= bCanAddComment;
1359  bCanAddComment ? XML_TRUE : XML_FALSE);
1360 
1361  SvXMLElementExport aSignatureLineElement(mrExport, XML_NAMESPACE_LO_EXT, XML_SIGNATURELINE, true,
1362  true);
1363 }
1364 
1365 void XMLShapeExport::ImpExportQRCode(const uno::Reference<drawing::XShape>& xShape)
1366 {
1367  uno::Reference<beans::XPropertySet> xPropSet(xShape, uno::UNO_QUERY);
1368 
1369  uno::Any aAny = xPropSet->getPropertyValue("QRCodeProperties");
1370 
1371  css::drawing::QRCode aQRCode;
1372  if(!(aAny >>= aQRCode))
1373  return;
1374 
1376  /* Export QR Code as per customised schema, @see OpenDocument-schema-v1.3+libreoffice */
1377  OUString temp;
1378  switch(aQRCode.ErrorCorrection){
1379  case css::drawing::QRCodeErrorCorrection::LOW :
1380  temp = "low";
1381  break;
1382  case css::drawing::QRCodeErrorCorrection::MEDIUM:
1383  temp = "medium";
1384  break;
1385  case css::drawing::QRCodeErrorCorrection::QUARTILE:
1386  temp = "quartile";
1387  break;
1388  case css::drawing::QRCodeErrorCorrection::HIGH:
1389  temp = "high";
1390  break;
1391  }
1393  mrExport.AddAttribute(XML_NAMESPACE_LO_EXT, XML_QRCODE_BORDER, OUString::number(aQRCode.Border));
1394 
1396  true);
1397 }
1398 
1400 {
1402 
1403  // construct PropertySetMapper
1405  static_cast<XMLShapeExportPropertyMapper*>(xPropertySetMapper.get())->SetAutoStyles( false );
1406 
1407  // chain text attributes
1408  xPropertySetMapper->ChainExportMapper(XMLTextParagraphExport::CreateParaExtPropMapper(mrExport));
1409 
1410  // chain special Writer/text frame default attributes
1411  xPropertySetMapper->ChainExportMapper(XMLTextParagraphExport::CreateParaDefaultExtPropMapper(mrExport));
1412 
1413  // write graphic family default style
1414  uno::Reference< lang::XMultiServiceFactory > xFact( mrExport.GetModel(), uno::UNO_QUERY );
1415  if( !xFact.is() )
1416  return;
1417 
1418  try
1419  {
1420  uno::Reference< beans::XPropertySet > xDefaults( xFact->createInstance("com.sun.star.drawing.Defaults"), uno::UNO_QUERY );
1421  if( xDefaults.is() )
1422  {
1423  aStEx->exportDefaultStyle( xDefaults, XML_STYLE_FAMILY_SD_GRAPHICS_NAME, xPropertySetMapper );
1424 
1425  // write graphic family styles
1426  aStEx->exportStyleFamily("graphics", OUString(XML_STYLE_FAMILY_SD_GRAPHICS_NAME), xPropertySetMapper, false, XmlStyleFamily::SD_GRAPHICS_ID);
1427  }
1428  }
1429  catch(const lang::ServiceNotRegisteredException&)
1430  {
1431  }
1432 }
1433 
1434 void XMLShapeExport::onExport( const css::uno::Reference < css::drawing::XShape >& )
1435 {
1436 }
1437 
1439 {
1440  if( !mxShapeTableExport.is() )
1441  {
1443  rtl::Reference < XMLPropertySetMapper > xMapper( new XMLShapePropertySetMapper( xFactory, true ) );
1444  mrExport.GetTextParagraphExport(); // get or create text paragraph export
1446  mxShapeTableExport = new XMLTableExport( mrExport, xPropertySetMapper, xFactory );
1447  }
1448 
1449  return mxShapeTableExport;
1450 }
1451 
1452 void XMLShapeExport::ImpExportNewTrans(const uno::Reference< beans::XPropertySet >& xPropSet,
1453  XMLShapeExportFlags nFeatures, awt::Point* pRefPoint)
1454 {
1455  // get matrix
1456  ::basegfx::B2DHomMatrix aMatrix;
1457  ImpExportNewTrans_GetB2DHomMatrix(aMatrix, xPropSet);
1458 
1459  // decompose and correct about pRefPoint
1460  ::basegfx::B2DTuple aTRScale;
1461  double fTRShear(0.0);
1462  double fTRRotate(0.0);
1463  ::basegfx::B2DTuple aTRTranslate;
1464  ImpExportNewTrans_DecomposeAndRefPoint(aMatrix, aTRScale, fTRShear, fTRRotate, aTRTranslate, pRefPoint);
1465 
1466  // use features and write
1467  ImpExportNewTrans_FeaturesAndWrite(aTRScale, fTRShear, fTRRotate, aTRTranslate, nFeatures);
1468 }
1469 
1471  const uno::Reference< beans::XPropertySet >& xPropSet)
1472 {
1473  /* Get <TransformationInHoriL2R>, if it exist
1474  and if the document is exported into the OpenOffice.org file format.
1475  This property only exists at service css::text::Shape - the
1476  Writer UNO service for shapes.
1477  This code is needed, because the positioning attributes in the
1478  OpenOffice.org file format are given in horizontal left-to-right layout
1479  regardless the layout direction the shape is in. In the OASIS Open Office
1480  file format the positioning attributes are correctly given in the layout
1481  direction the shape is in. Thus, this code provides the conversion from
1482  the OASIS Open Office file format to the OpenOffice.org file format. (#i28749#)
1483  */
1484  uno::Any aAny;
1485  if ( !( GetExport().getExportFlags() & SvXMLExportFlags::OASIS ) &&
1486  xPropSet->getPropertySetInfo()->hasPropertyByName("TransformationInHoriL2R") )
1487  {
1488  aAny = xPropSet->getPropertyValue("TransformationInHoriL2R");
1489  }
1490  else
1491  {
1492  aAny = xPropSet->getPropertyValue("Transformation");
1493  }
1494  drawing::HomogenMatrix3 aMatrix;
1495  aAny >>= aMatrix;
1496 
1497  rMatrix.set(0, 0, aMatrix.Line1.Column1);
1498  rMatrix.set(0, 1, aMatrix.Line1.Column2);
1499  rMatrix.set(0, 2, aMatrix.Line1.Column3);
1500  rMatrix.set(1, 0, aMatrix.Line2.Column1);
1501  rMatrix.set(1, 1, aMatrix.Line2.Column2);
1502  rMatrix.set(1, 2, aMatrix.Line2.Column3);
1503  rMatrix.set(2, 0, aMatrix.Line3.Column1);
1504  rMatrix.set(2, 1, aMatrix.Line3.Column2);
1505  rMatrix.set(2, 2, aMatrix.Line3.Column3);
1506 }
1507 
1508 void XMLShapeExport::ImpExportNewTrans_DecomposeAndRefPoint(const ::basegfx::B2DHomMatrix& rMatrix, ::basegfx::B2DTuple& rTRScale,
1509  double& fTRShear, double& fTRRotate, ::basegfx::B2DTuple& rTRTranslate, css::awt::Point* pRefPoint)
1510 {
1511  // decompose matrix
1512  rMatrix.decompose(rTRScale, rTRTranslate, fTRRotate, fTRShear);
1513 
1514  // correct translation about pRefPoint
1515  if(pRefPoint)
1516  {
1517  rTRTranslate -= ::basegfx::B2DTuple(pRefPoint->X, pRefPoint->Y);
1518  }
1519 }
1520 
1522  double fTRRotate, ::basegfx::B2DTuple const & rTRTranslate, const XMLShapeExportFlags nFeatures)
1523 {
1524  // always write Size (rTRScale) since this statement carries the union
1525  // of the object
1526  OUString aStr;
1527  OUStringBuffer sStringBuffer;
1528  ::basegfx::B2DTuple aTRScale(rTRScale);
1529 
1530  // svg: width
1531  if(!(nFeatures & XMLShapeExportFlags::WIDTH))
1532  {
1533  aTRScale.setX(1.0);
1534  }
1535  else
1536  {
1537  if( aTRScale.getX() > 0.0 )
1538  aTRScale.setX(aTRScale.getX() - 1.0);
1539  else if( aTRScale.getX() < 0.0 )
1540  aTRScale.setX(aTRScale.getX() + 1.0);
1541  }
1542 
1544  FRound(aTRScale.getX()));
1545  aStr = sStringBuffer.makeStringAndClear();
1547 
1548  // svg: height
1549  if(!(nFeatures & XMLShapeExportFlags::HEIGHT))
1550  {
1551  aTRScale.setY(1.0);
1552  }
1553  else
1554  {
1555  if( aTRScale.getY() > 0.0 )
1556  aTRScale.setY(aTRScale.getY() - 1.0);
1557  else if( aTRScale.getY() < 0.0 )
1558  aTRScale.setY(aTRScale.getY() + 1.0);
1559  }
1560 
1562  FRound(aTRScale.getY()));
1563  aStr = sStringBuffer.makeStringAndClear();
1565 
1566  // decide if transformation is necessary
1567  bool bTransformationIsNecessary(fTRShear != 0.0 || fTRRotate != 0.0);
1568 
1569  if(bTransformationIsNecessary)
1570  {
1571  // write transformation, but WITHOUT scale which is exported as size above
1572  SdXMLImExTransform2D aTransform;
1573 
1574  aTransform.AddSkewX(atan(fTRShear));
1575 
1576  // #i78696#
1577  // fTRRotate is mathematically correct, but due to the error
1578  // we export/import it mirrored. Since the API implementation is fixed and
1579  // uses the correctly oriented angle, it is necessary for compatibility to
1580  // mirror the angle here to stay at the old behaviour. There is a follow-up
1581  // task (#i78698#) to fix this in the next ODF FileFormat version
1582  aTransform.AddRotate(-fTRRotate);
1583 
1584  aTransform.AddTranslate(rTRTranslate);
1585 
1586  // does transformation need to be exported?
1587  if(aTransform.NeedsAction())
1589  }
1590  else
1591  {
1592  // no shear, no rotate; just add object position to export and we are done
1593  if(nFeatures & XMLShapeExportFlags::X)
1594  {
1595  // svg: x
1597  FRound(rTRTranslate.getX()));
1598  aStr = sStringBuffer.makeStringAndClear();
1600  }
1601 
1602  if(nFeatures & XMLShapeExportFlags::Y)
1603  {
1604  // svg: y
1606  FRound(rTRTranslate.getY()));
1607  aStr = sStringBuffer.makeStringAndClear();
1609  }
1610  }
1611 }
1612 
1613 bool XMLShapeExport::ImpExportPresentationAttributes( const uno::Reference< beans::XPropertySet >& xPropSet, const OUString& rClass )
1614 {
1615  bool bIsEmpty = false;
1616 
1617  // write presentation class entry
1619 
1620  if( xPropSet.is() )
1621  {
1622  uno::Reference< beans::XPropertySetInfo > xPropSetInfo( xPropSet->getPropertySetInfo() );
1623 
1624 
1625  // is empty pres. shape?
1626  if( xPropSetInfo.is() && xPropSetInfo->hasPropertyByName("IsEmptyPresentationObject"))
1627  {
1628  xPropSet->getPropertyValue("IsEmptyPresentationObject") >>= bIsEmpty;
1629  if( bIsEmpty )
1631  }
1632 
1633  // is user-transformed?
1634  if( xPropSetInfo.is() && xPropSetInfo->hasPropertyByName("IsPlaceholderDependent"))
1635  {
1636  bool bTemp = false;
1637  xPropSet->getPropertyValue("IsPlaceholderDependent") >>= bTemp;
1638  if(!bTemp)
1640  }
1641  }
1642 
1643  return bIsEmpty;
1644 }
1645 
1646 void XMLShapeExport::ImpExportText( const uno::Reference< drawing::XShape >& xShape, TextPNS eExtensionNS )
1647 {
1648  if (eExtensionNS == TextPNS::EXTENSION)
1649  {
1651  {
1652  return; // do not export to ODF 1.1/1.2/1.3
1653  }
1654  }
1655  uno::Reference< text::XText > xText( xShape, uno::UNO_QUERY );
1656  if( xText.is() )
1657  {
1658  uno::Reference< container::XEnumerationAccess > xEnumAccess( xShape, uno::UNO_QUERY );
1659  if( xEnumAccess.is() && xEnumAccess->hasElements() )
1660  mrExport.GetTextParagraphExport()->exportText( xText, false, true, eExtensionNS );
1661  }
1662 }
1663 
1664 namespace {
1665 
1666 enum class Found {
1667  NONE = 0x0000,
1668  CLICKACTION = 0x0001,
1669  BOOKMARK = 0x0002,
1670  EFFECT = 0x0004,
1671  PLAYFULL = 0x0008,
1672  VERB = 0x0010,
1673  SOUNDURL = 0x0020,
1674  SPEED = 0x0040,
1675  CLICKEVENTTYPE = 0x0080,
1676  MACRO = 0x0100,
1677  LIBRARY = 0x0200,
1678 };
1679 
1680 }
1681 
1682 namespace o3tl {
1683  template<> struct typed_flags<Found> : is_typed_flags<Found, 0x03ff> {};
1684 }
1685 
1686 void XMLShapeExport::ImpExportEvents( const uno::Reference< drawing::XShape >& xShape )
1687 {
1688  uno::Reference< document::XEventsSupplier > xEventsSupplier( xShape, uno::UNO_QUERY );
1689  if( !xEventsSupplier.is() )
1690  return;
1691 
1692  uno::Reference< container::XNameAccess > xEvents = xEventsSupplier->getEvents();
1693  SAL_WARN_IF( !xEvents.is(), "xmloff", "XEventsSupplier::getEvents() returned NULL" );
1694  if( !xEvents.is() )
1695  return;
1696 
1697  Found nFound = Found::NONE;
1698 
1699  OUString aClickEventType;
1700  presentation::ClickAction eClickAction = presentation::ClickAction_NONE;
1701  presentation::AnimationEffect eEffect = presentation::AnimationEffect_NONE;
1702  presentation::AnimationSpeed eSpeed = presentation::AnimationSpeed_SLOW;
1703  OUString aStrSoundURL;
1704  bool bPlayFull = false;
1705  sal_Int32 nVerb = 0;
1706  OUString aStrMacro;
1707  OUString aStrLibrary;
1708  OUString aStrBookmark;
1709 
1710  uno::Sequence< beans::PropertyValue > aClickProperties;
1711  if( xEvents->hasByName( gsOnClick ) && (xEvents->getByName( gsOnClick ) >>= aClickProperties) )
1712  {
1713  for( const auto& rProperty : std::as_const(aClickProperties) )
1714  {
1715  if( !( nFound & Found::CLICKEVENTTYPE ) && rProperty.Name == gsEventType )
1716  {
1717  if( rProperty.Value >>= aClickEventType )
1718  nFound |= Found::CLICKEVENTTYPE;
1719  }
1720  else if( !( nFound & Found::CLICKACTION ) && rProperty.Name == gsClickAction )
1721  {
1722  if( rProperty.Value >>= eClickAction )
1723  nFound |= Found::CLICKACTION;
1724  }
1725  else if( !( nFound & Found::MACRO ) && ( rProperty.Name == gsMacroName || rProperty.Name == gsScript ) )
1726  {
1727  if( rProperty.Value >>= aStrMacro )
1728  nFound |= Found::MACRO;
1729  }
1730  else if( !( nFound & Found::LIBRARY ) && rProperty.Name == gsLibrary )
1731  {
1732  if( rProperty.Value >>= aStrLibrary )
1733  nFound |= Found::LIBRARY;
1734  }
1735  else if( !( nFound & Found::EFFECT ) && rProperty.Name == gsEffect )
1736  {
1737  if( rProperty.Value >>= eEffect )
1738  nFound |= Found::EFFECT;
1739  }
1740  else if( !( nFound & Found::BOOKMARK ) && rProperty.Name == gsBookmark )
1741  {
1742  if( rProperty.Value >>= aStrBookmark )
1743  nFound |= Found::BOOKMARK;
1744  }
1745  else if( !( nFound & Found::SPEED ) && rProperty.Name == gsSpeed )
1746  {
1747  if( rProperty.Value >>= eSpeed )
1748  nFound |= Found::SPEED;
1749  }
1750  else if( !( nFound & Found::SOUNDURL ) && rProperty.Name == gsSoundURL )
1751  {
1752  if( rProperty.Value >>= aStrSoundURL )
1753  nFound |= Found::SOUNDURL;
1754  }
1755  else if( !( nFound & Found::PLAYFULL ) && rProperty.Name == gsPlayFull )
1756  {
1757  if( rProperty.Value >>= bPlayFull )
1758  nFound |= Found::PLAYFULL;
1759  }
1760  else if( !( nFound & Found::VERB ) && rProperty.Name == gsVerb )
1761  {
1762  if( rProperty.Value >>= nVerb )
1763  nFound |= Found::VERB;
1764  }
1765  }
1766  }
1767 
1768  // create the XML elements
1769 
1770  if( aClickEventType == gsPresentation )
1771  {
1772  if( !(nFound & Found::CLICKACTION) || (eClickAction == presentation::ClickAction_NONE) )
1773  return;
1774 
1776 
1777  enum XMLTokenEnum eStrAction;
1778 
1779  switch( eClickAction )
1780  {
1781  case presentation::ClickAction_PREVPAGE: eStrAction = XML_PREVIOUS_PAGE; break;
1782  case presentation::ClickAction_NEXTPAGE: eStrAction = XML_NEXT_PAGE; break;
1783  case presentation::ClickAction_FIRSTPAGE: eStrAction = XML_FIRST_PAGE; break;
1784  case presentation::ClickAction_LASTPAGE: eStrAction = XML_LAST_PAGE; break;
1785  case presentation::ClickAction_INVISIBLE: eStrAction = XML_HIDE; break;
1786  case presentation::ClickAction_STOPPRESENTATION:eStrAction = XML_STOP; break;
1787  case presentation::ClickAction_PROGRAM: eStrAction = XML_EXECUTE; break;
1788  case presentation::ClickAction_BOOKMARK: eStrAction = XML_SHOW; break;
1789  case presentation::ClickAction_DOCUMENT: eStrAction = XML_SHOW; break;
1790  case presentation::ClickAction_MACRO: eStrAction = XML_EXECUTE_MACRO; break;
1791  case presentation::ClickAction_VERB: eStrAction = XML_VERB; break;
1792  case presentation::ClickAction_VANISH: eStrAction = XML_FADE_OUT; break;
1793  case presentation::ClickAction_SOUND: eStrAction = XML_SOUND; break;
1794  default:
1795  OSL_FAIL( "unknown presentation::ClickAction found!" );
1796  eStrAction = XML_UNKNOWN;
1797  }
1798 
1799  OUString aEventQName(
1801  XML_NAMESPACE_DOM, "click" ) );
1804 
1805  if( eClickAction == presentation::ClickAction_VANISH )
1806  {
1807  if( nFound & Found::EFFECT )
1808  {
1809  XMLEffect eKind;
1810  XMLEffectDirection eDirection;
1811  sal_Int16 nStartScale;
1812  bool bIn;
1813 
1814  SdXMLImplSetEffect( eEffect, eKind, eDirection, nStartScale, bIn );
1815 
1816  if( eKind != EK_none )
1817  {
1820  }
1821 
1822  if( eDirection != ED_none )
1823  {
1826  }
1827 
1828  if( nStartScale != -1 )
1829  {
1832  }
1833  }
1834 
1835  if( nFound & Found::SPEED && eEffect != presentation::AnimationEffect_NONE )
1836  {
1837  if( eSpeed != presentation::AnimationSpeed_MEDIUM )
1838  {
1841  }
1842  }
1843  }
1844 
1845  if( eClickAction == presentation::ClickAction_PROGRAM ||
1846  eClickAction == presentation::ClickAction_BOOKMARK ||
1847  eClickAction == presentation::ClickAction_DOCUMENT )
1848  {
1849  if( eClickAction == presentation::ClickAction_BOOKMARK )
1850  msBuffer.append( '#' );
1851 
1852  msBuffer.append( aStrBookmark );
1853  mrExport.AddAttribute(XML_NAMESPACE_XLINK, XML_HREF, GetExport().GetRelativeReference(msBuffer.makeStringAndClear()) );
1857  }
1858 
1859  if( ( nFound & Found::VERB ) && eClickAction == presentation::ClickAction_VERB )
1860  {
1861  msBuffer.append( nVerb );
1863  }
1864 
1866 
1867  if( eClickAction == presentation::ClickAction_VANISH || eClickAction == presentation::ClickAction_SOUND )
1868  {
1869  if( ( nFound & Found::SOUNDURL ) && !aStrSoundURL.isEmpty() )
1870  {
1871  mrExport.AddAttribute(XML_NAMESPACE_XLINK, XML_HREF, GetExport().GetRelativeReference(aStrSoundURL) );
1875  if( nFound & Found::PLAYFULL && bPlayFull )
1877 
1879  }
1880  }
1881  }
1882  else if( aClickEventType == gsStarBasic )
1883  {
1884  if( nFound & Found::MACRO )
1885  {
1887 
1891  "starbasic" ) );
1892  OUString aEventQName(
1894  XML_NAMESPACE_DOM, "click" ) );
1896 
1897  if( nFound & Found::LIBRARY )
1898  {
1899  const OUString& sLocation( GetXMLToken(
1900  (aStrLibrary.equalsIgnoreAsciiCase("StarOffice") ||
1901  aStrLibrary.equalsIgnoreAsciiCase("application") ) ? XML_APPLICATION
1902  : XML_DOCUMENT ) );
1904  sLocation + ":" + aStrMacro);
1905  }
1906  else
1907  {
1909  }
1910 
1912  }
1913  }
1914  else if( aClickEventType == gsScript )
1915  {
1916  if( nFound & Found::MACRO )
1917  {
1919 
1922  OUString aEventQName(
1924  XML_NAMESPACE_DOM, "click" ) );
1928 
1930  }
1931  }
1932 }
1933 
1935 void XMLShapeExport::ImpExportDescription( const uno::Reference< drawing::XShape >& xShape )
1936 {
1937  try
1938  {
1939  OUString aTitle;
1940  OUString aDescription;
1941 
1942  uno::Reference< beans::XPropertySet > xProps( xShape, uno::UNO_QUERY_THROW );
1943  xProps->getPropertyValue("Title") >>= aTitle;
1944  xProps->getPropertyValue("Description") >>= aDescription;
1945 
1946  if(!aTitle.isEmpty())
1947  {
1948  SvXMLElementExport aEventElemt(mrExport, XML_NAMESPACE_SVG, XML_TITLE, true, false);
1949  mrExport.Characters( aTitle );
1950  }
1951 
1952  if(!aDescription.isEmpty())
1953  {
1954  SvXMLElementExport aEventElemt(mrExport, XML_NAMESPACE_SVG, XML_DESC, true, false );
1955  mrExport.Characters( aDescription );
1956  }
1957  }
1958  catch( uno::Exception& )
1959  {
1960  DBG_UNHANDLED_EXCEPTION( "xmloff", "exporting Title and/or Description for shape" );
1961  }
1962 }
1963 
1964 void XMLShapeExport::ImpExportGroupShape( const uno::Reference< drawing::XShape >& xShape, XMLShapeExportFlags nFeatures, awt::Point* pRefPoint)
1965 {
1966  uno::Reference< drawing::XShapes > xShapes(xShape, uno::UNO_QUERY);
1967  if(!(xShapes.is() && xShapes->getCount()))
1968  return;
1969 
1970  // write group shape
1971  bool bCreateNewline( (nFeatures & XMLShapeExportFlags::NO_WS) == XMLShapeExportFlags::NONE ); // #86116#/#92210#
1972  SvXMLElementExport aPGR(mrExport, XML_NAMESPACE_DRAW, XML_G, bCreateNewline, true);
1973 
1974  ImpExportDescription( xShape ); // #i68101#
1975  ImpExportEvents( xShape );
1976  ImpExportGluePoints( xShape );
1977 
1978  // #89764# if export of position is suppressed for group shape,
1979  // positions of contained objects should be written relative to
1980  // the upper left edge of the group.
1981  awt::Point aUpperLeft;
1982 
1983  if(!(nFeatures & XMLShapeExportFlags::POSITION))
1984  {
1985  nFeatures |= XMLShapeExportFlags::POSITION;
1986  aUpperLeft = xShape->getPosition();
1987  pRefPoint = &aUpperLeft;
1988  }
1989 
1990  // write members
1991  exportShapes( xShapes, nFeatures, pRefPoint );
1992 }
1993 
1995  const uno::Reference< drawing::XShape >& xShape,
1996  XmlShapeType eShapeType, XMLShapeExportFlags nFeatures, awt::Point* pRefPoint)
1997 {
1998  const uno::Reference< beans::XPropertySet > xPropSet(xShape, uno::UNO_QUERY);
1999  if(!xPropSet.is())
2000  return;
2001 
2002  // presentation attribute (if presentation)
2003  bool bIsPresShape(false);
2004  bool bIsEmptyPresObj(false);
2005  OUString aStr;
2006 
2007  switch(eShapeType)
2008  {
2010  {
2011  aStr = GetXMLToken(XML_SUBTITLE);
2012  bIsPresShape = true;
2013  break;
2014  }
2016  {
2017  aStr = GetXMLToken(XML_TITLE);
2018  bIsPresShape = true;
2019  break;
2020  }
2022  {
2024  bIsPresShape = true;
2025  break;
2026  }
2028  {
2029  aStr = GetXMLToken(XML_NOTES);
2030  bIsPresShape = true;
2031  break;
2032  }
2034  {
2035  aStr = GetXMLToken(XML_HEADER);
2036  bIsPresShape = true;
2037  break;
2038  }
2040  {
2041  aStr = GetXMLToken(XML_FOOTER);
2042  bIsPresShape = true;
2043  break;
2044  }
2046  {
2047  aStr = GetXMLToken(XML_PAGE_NUMBER);
2048  bIsPresShape = true;
2049  break;
2050  }
2052  {
2053  aStr = GetXMLToken(XML_DATE_TIME);
2054  bIsPresShape = true;
2055  break;
2056  }
2057  default:
2058  break;
2059  }
2060 
2061  // Transformation
2062  ImpExportNewTrans(xPropSet, nFeatures, pRefPoint);
2063 
2064  if(bIsPresShape)
2065  bIsEmptyPresObj = ImpExportPresentationAttributes( xPropSet, aStr );
2066 
2067  bool bCreateNewline( (nFeatures & XMLShapeExportFlags::NO_WS) == XMLShapeExportFlags::NONE ); // #86116#/#92210#
2069  XML_FRAME, bCreateNewline, true );
2070 
2071  // evtl. corner radius?
2072  sal_Int32 nCornerRadius(0);
2073  xPropSet->getPropertyValue("CornerRadius") >>= nCornerRadius;
2074  if(nCornerRadius)
2075  {
2076  OUStringBuffer sStringBuffer;
2078  nCornerRadius);
2079  mrExport.AddAttribute(XML_NAMESPACE_DRAW, XML_CORNER_RADIUS, sStringBuffer.makeStringAndClear());
2080  }
2081 
2082  {
2083  // write text-box
2085  if(!bIsEmptyPresObj)
2086  ImpExportText( xShape );
2087  }
2088 
2089  ImpExportDescription( xShape ); // #i68101#
2090  ImpExportEvents( xShape );
2091  ImpExportGluePoints( xShape );
2092 
2093 }
2094 
2096  const uno::Reference< drawing::XShape >& xShape,
2097  XMLShapeExportFlags nFeatures, css::awt::Point* pRefPoint)
2098 {
2099  const uno::Reference< beans::XPropertySet > xPropSet(xShape, uno::UNO_QUERY);
2100  if(!xPropSet.is())
2101  return;
2102 
2103  // Transformation
2104  ImpExportNewTrans(xPropSet, nFeatures, pRefPoint);
2105 
2106  // evtl. corner radius?
2107  sal_Int32 nCornerRadius(0);
2108  xPropSet->getPropertyValue("CornerRadius") >>= nCornerRadius;
2109  if(nCornerRadius)
2110  {
2111  OUStringBuffer sStringBuffer;
2113  nCornerRadius);
2114  mrExport.AddAttribute(XML_NAMESPACE_DRAW, XML_CORNER_RADIUS, sStringBuffer.makeStringAndClear());
2115  }
2116 
2117  // write rectangle
2118  bool bCreateNewline( (nFeatures & XMLShapeExportFlags::NO_WS) == XMLShapeExportFlags::NONE ); // #86116#/#92210#
2119  SvXMLElementExport aOBJ(mrExport, XML_NAMESPACE_DRAW, XML_RECT, bCreateNewline, true);
2120 
2121  ImpExportDescription( xShape ); // #i68101#
2122  ImpExportEvents( xShape );
2123  ImpExportGluePoints( xShape );
2124  ImpExportText( xShape );
2125 }
2126 
2128  const uno::Reference< drawing::XShape >& xShape,
2129  XMLShapeExportFlags nFeatures, awt::Point* pRefPoint)
2130 {
2131  const uno::Reference< beans::XPropertySet > xPropSet(xShape, uno::UNO_QUERY);
2132  if(!xPropSet.is())
2133  return;
2134 
2135  OUString aStr;
2136  OUStringBuffer sStringBuffer;
2137  awt::Point aStart(0,0);
2138  awt::Point aEnd(1,1);
2139 
2140  // #85920# use 'Geometry' to get the points of the line
2141  // since this slot take anchor pos into account.
2142 
2143  // get matrix
2144  ::basegfx::B2DHomMatrix aMatrix;
2145  ImpExportNewTrans_GetB2DHomMatrix(aMatrix, xPropSet);
2146 
2147  // decompose and correct about pRefPoint
2148  ::basegfx::B2DTuple aTRScale;
2149  double fTRShear(0.0);
2150  double fTRRotate(0.0);
2151  ::basegfx::B2DTuple aTRTranslate;
2152  ImpExportNewTrans_DecomposeAndRefPoint(aMatrix, aTRScale, fTRShear, fTRRotate, aTRTranslate, pRefPoint);
2153 
2154  // create base position
2155  awt::Point aBasePosition(FRound(aTRTranslate.getX()), FRound(aTRTranslate.getY()));
2156 
2157  if (xPropSet->getPropertySetInfo()->hasPropertyByName("Geometry"))
2158  {
2159  // get the two points
2160  uno::Any aAny(xPropSet->getPropertyValue("Geometry"));
2161  if (auto pSourcePolyPolygon
2162  = o3tl::tryAccess<drawing::PointSequenceSequence>(aAny))
2163  {
2164  if (pSourcePolyPolygon->getLength() > 0)
2165  {
2166  const drawing::PointSequence& rInnerSequence = (*pSourcePolyPolygon)[0];
2167  if (rInnerSequence.hasElements())
2168  {
2169  const awt::Point& rPoint = rInnerSequence[0];
2170  aStart = awt::Point(rPoint.X + aBasePosition.X, rPoint.Y + aBasePosition.Y);
2171  }
2172  if (rInnerSequence.getLength() > 1)
2173  {
2174  const awt::Point& rPoint = rInnerSequence[1];
2175  aEnd = awt::Point(rPoint.X + aBasePosition.X, rPoint.Y + aBasePosition.Y);
2176  }
2177  }
2178  }
2179  }
2180 
2181  if( nFeatures & XMLShapeExportFlags::X )
2182  {
2183  // svg: x1
2185  aStart.X);
2186  aStr = sStringBuffer.makeStringAndClear();
2188  }
2189  else
2190  {
2191  aEnd.X -= aStart.X;
2192  }
2193 
2194  if( nFeatures & XMLShapeExportFlags::Y )
2195  {
2196  // svg: y1
2198  aStart.Y);
2199  aStr = sStringBuffer.makeStringAndClear();
2201  }
2202  else
2203  {
2204  aEnd.Y -= aStart.Y;
2205  }
2206 
2207  // svg: x2
2209  aEnd.X);
2210  aStr = sStringBuffer.makeStringAndClear();
2212 
2213  // svg: y2
2215  aEnd.Y);
2216  aStr = sStringBuffer.makeStringAndClear();
2218 
2219  // write line
2220  bool bCreateNewline( (nFeatures & XMLShapeExportFlags::NO_WS) == XMLShapeExportFlags::NONE ); // #86116#/#92210#
2221  SvXMLElementExport aOBJ(mrExport, XML_NAMESPACE_DRAW, XML_LINE, bCreateNewline, true);
2222 
2223  ImpExportDescription( xShape ); // #i68101#
2224  ImpExportEvents( xShape );
2225  ImpExportGluePoints( xShape );
2226  ImpExportText( xShape );
2227 
2228 }
2229 
2231  const uno::Reference< drawing::XShape >& xShape,
2232  XMLShapeExportFlags nFeatures, awt::Point* pRefPoint)
2233 {
2234  const uno::Reference< beans::XPropertySet > xPropSet(xShape, uno::UNO_QUERY);
2235  if(!xPropSet.is())
2236  return;
2237 
2238  // get size to decide between Circle and Ellipse
2239  awt::Size aSize = xShape->getSize();
2240  sal_Int32 nRx((aSize.Width + 1) / 2);
2241  sal_Int32 nRy((aSize.Height + 1) / 2);
2242  bool bCircle(nRx == nRy);
2243 
2244  // Transformation
2245  ImpExportNewTrans(xPropSet, nFeatures, pRefPoint);
2246 
2247  drawing::CircleKind eKind = drawing::CircleKind_FULL;
2248  xPropSet->getPropertyValue("CircleKind") >>= eKind;
2249  if( eKind != drawing::CircleKind_FULL )
2250  {
2251  OUStringBuffer sStringBuffer;
2252  sal_Int32 nStartAngle = 0;
2253  sal_Int32 nEndAngle = 0;
2254  xPropSet->getPropertyValue("CircleStartAngle") >>= nStartAngle;
2255  xPropSet->getPropertyValue("CircleEndAngle") >>= nEndAngle;
2256 
2257  const double dStartAngle = nStartAngle / 100.0;
2258  const double dEndAngle = nEndAngle / 100.0;
2259 
2260  // export circle kind
2262  mrExport.AddAttribute(XML_NAMESPACE_DRAW, XML_KIND, sStringBuffer.makeStringAndClear() );
2263 
2264  // export start angle
2265  ::sax::Converter::convertDouble( sStringBuffer, dStartAngle );
2266  mrExport.AddAttribute(XML_NAMESPACE_DRAW, XML_START_ANGLE, sStringBuffer.makeStringAndClear() );
2267 
2268  // export end angle
2269  ::sax::Converter::convertDouble( sStringBuffer, dEndAngle );
2270  mrExport.AddAttribute(XML_NAMESPACE_DRAW, XML_END_ANGLE, sStringBuffer.makeStringAndClear() );
2271  }
2272 
2273  bool bCreateNewline( (nFeatures & XMLShapeExportFlags::NO_WS) == XMLShapeExportFlags::NONE ); // #86116#/#92210#
2274 
2275  // write ellipse or circle
2277  bCircle ? XML_CIRCLE : XML_ELLIPSE,
2278  bCreateNewline, true);
2279 
2280  ImpExportDescription( xShape ); // #i68101#
2281  ImpExportEvents( xShape );
2282  ImpExportGluePoints( xShape );
2283  ImpExportText( xShape );
2284 
2285 }
2286 
2288  const uno::Reference< drawing::XShape >& xShape,
2289  XmlShapeType eShapeType, XMLShapeExportFlags nFeatures, awt::Point* pRefPoint)
2290 {
2291  const uno::Reference< beans::XPropertySet > xPropSet(xShape, uno::UNO_QUERY);
2292  if(!xPropSet.is())
2293  return;
2294 
2295  bool bBezier(eShapeType == XmlShapeTypeDrawClosedBezierShape
2296  || eShapeType == XmlShapeTypeDrawOpenBezierShape);
2297 
2298  // get matrix
2299  ::basegfx::B2DHomMatrix aMatrix;
2300  ImpExportNewTrans_GetB2DHomMatrix(aMatrix, xPropSet);
2301 
2302  // decompose and correct about pRefPoint
2303  ::basegfx::B2DTuple aTRScale;
2304  double fTRShear(0.0);
2305  double fTRRotate(0.0);
2306  ::basegfx::B2DTuple aTRTranslate;
2307  ImpExportNewTrans_DecomposeAndRefPoint(aMatrix, aTRScale, fTRShear, fTRRotate, aTRTranslate, pRefPoint);
2308 
2309  // use features and write
2310  ImpExportNewTrans_FeaturesAndWrite(aTRScale, fTRShear, fTRRotate, aTRTranslate, nFeatures);
2311 
2312  // create and export ViewBox
2313  awt::Size aSize(FRound(aTRScale.getX()), FRound(aTRScale.getY()));
2314  SdXMLImExViewBox aViewBox(0, 0, aSize.Width, aSize.Height);
2316 
2317  bool bCreateNewline( (nFeatures & XMLShapeExportFlags::NO_WS) == XMLShapeExportFlags::NONE ); // #86116#/#92210#
2318 
2319  // prepare name (with most used)
2321 
2322  if(bBezier)
2323  {
2324  // get PolygonBezier
2325  uno::Any aAny( xPropSet->getPropertyValue("Geometry") );
2326  const basegfx::B2DPolyPolygon aPolyPolygon(
2327  basegfx::utils::UnoPolyPolygonBezierCoordsToB2DPolyPolygon(*o3tl::doAccess<drawing::PolyPolygonBezierCoords>(aAny)));
2328 
2329  if(aPolyPolygon.count())
2330  {
2331  // complex polygon shape, write as svg:d
2332  const OUString aPolygonString(
2334  aPolyPolygon,
2335  true, // bUseRelativeCoordinates
2336  false, // bDetectQuadraticBeziers: not used in old, but maybe activated now
2337  true)); // bHandleRelativeNextPointCompatible
2338 
2339  // write point array
2340  mrExport.AddAttribute(XML_NAMESPACE_SVG, XML_D, aPolygonString);
2341  }
2342  }
2343  else
2344  {
2345  // get non-bezier polygon
2346  uno::Any aAny( xPropSet->getPropertyValue("Geometry") );
2347  const basegfx::B2DPolyPolygon aPolyPolygon(
2348  basegfx::utils::UnoPointSequenceSequenceToB2DPolyPolygon(*o3tl::doAccess<drawing::PointSequenceSequence>(aAny)));
2349 
2350  if(!aPolyPolygon.areControlPointsUsed() && 1 == aPolyPolygon.count())
2351  {
2352  // simple polygon shape, can be written as svg:points sequence
2353  const basegfx::B2DPolygon& aPolygon(aPolyPolygon.getB2DPolygon(0));
2354  const OUString aPointString(basegfx::utils::exportToSvgPoints(aPolygon));
2355 
2356  // write point array
2358 
2359  // set name
2360  eName = aPolygon.isClosed() ? XML_POLYGON : XML_POLYLINE;
2361  }
2362  else
2363  {
2364  // complex polygon shape, write as svg:d
2365  const OUString aPolygonString(
2367  aPolyPolygon,
2368  true, // bUseRelativeCoordinates
2369  false, // bDetectQuadraticBeziers: not used in old, but maybe activated now
2370  true)); // bHandleRelativeNextPointCompatible
2371 
2372  // write point array
2373  mrExport.AddAttribute(XML_NAMESPACE_SVG, XML_D, aPolygonString);
2374  }
2375  }
2376 
2377  // write object, but after attributes are added since this call will
2378  // consume all of these added attributes and the destructor will close the
2379  // scope. Also before text is added; this may add sub-scopes as needed
2380  SvXMLElementExport aOBJ(
2381  mrExport,
2383  eName,
2384  bCreateNewline,
2385  true);
2386 
2387  ImpExportDescription( xShape ); // #i68101#
2388  ImpExportEvents( xShape );
2389  ImpExportGluePoints( xShape );
2390  ImpExportText( xShape );
2391 
2392 }
2393 
2394 namespace
2395 {
2396 
2397 OUString getNameFromStreamURL(OUString const & rURL)
2398 {
2399  static const OUStringLiteral sPackageURL(u"vnd.sun.star.Package:");
2400 
2401  OUString sResult;
2402 
2403  if (rURL.match(sPackageURL))
2404  {
2405  OUString sRequestedName = rURL.copy(sPackageURL.getLength());
2406  sal_Int32 nLastIndex = sRequestedName.lastIndexOf('/') + 1;
2407  if ((nLastIndex > 0) && (nLastIndex < sRequestedName.getLength()))
2408  sRequestedName = sRequestedName.copy(nLastIndex);
2409  nLastIndex = sRequestedName.lastIndexOf('.');
2410  if (nLastIndex >= 0)
2411  sRequestedName = sRequestedName.copy(0, nLastIndex);
2412  if (!sRequestedName.isEmpty())
2413  sResult = sRequestedName;
2414  }
2415 
2416  return sResult;
2417 }
2418 
2419 } // end anonymous namespace
2420 
2422  const uno::Reference< drawing::XShape >& xShape,
2423  XmlShapeType eShapeType, XMLShapeExportFlags nFeatures, awt::Point* pRefPoint)
2424 {
2425  const uno::Reference< beans::XPropertySet > xPropSet(xShape, uno::UNO_QUERY);
2426  if(!xPropSet.is())
2427  return;
2428 
2429  bool bIsEmptyPresObj = false;
2430 
2431  // Transformation
2432  ImpExportNewTrans(xPropSet, nFeatures, pRefPoint);
2433 
2434  if(eShapeType == XmlShapeTypePresGraphicObjectShape)
2435  bIsEmptyPresObj = ImpExportPresentationAttributes( xPropSet, GetXMLToken(XML_GRAPHIC) );
2436 
2437  bool bCreateNewline( (nFeatures & XMLShapeExportFlags::NO_WS) == XMLShapeExportFlags::NONE ); // #86116#/#92210#
2439  XML_FRAME, bCreateNewline, true );
2440 
2441  if (!bIsEmptyPresObj)
2442  {
2443  uno::Reference<graphic::XGraphic> xGraphic;
2444  OUString sOutMimeType;
2445 
2446  {
2447  OUString aStreamURL;
2448  xPropSet->getPropertyValue("GraphicStreamURL") >>= aStreamURL;
2449  OUString sRequestedName = getNameFromStreamURL(aStreamURL);
2450 
2451  xPropSet->getPropertyValue("Graphic") >>= xGraphic;
2452 
2453  OUString sInternalURL;
2454 
2455  if (xGraphic.is())
2456  sInternalURL = mrExport.AddEmbeddedXGraphic(xGraphic, sOutMimeType, sRequestedName);
2457 
2458  if (!sInternalURL.isEmpty())
2459  {
2460  // apply possible changed stream URL to embedded image object
2461  if (!sRequestedName.isEmpty())
2462  {
2463  OUString newStreamURL = "vnd.sun.star.Package:";
2464  if (sInternalURL[0] == '#')
2465  {
2466  newStreamURL += sInternalURL.subView(1, sInternalURL.getLength() - 1);
2467  }
2468  else
2469  {
2470  newStreamURL += sInternalURL;
2471  }
2472 
2473  if (newStreamURL != aStreamURL)
2474  {
2475  xPropSet->setPropertyValue("GraphicStreamURL", uno::Any(newStreamURL));
2476  }
2477  }
2478 
2483  }
2484  }
2485 
2486  {
2487  if (GetExport().getSaneDefaultVersion() > SvtSaveOptions::ODFSVER_012)
2488  {
2489  if (sOutMimeType.isEmpty())
2490  {
2491  GetExport().GetGraphicMimeTypeFromStream(xGraphic, sOutMimeType);
2492  }
2493  if (!sOutMimeType.isEmpty())
2494  { // ODF 1.3 OFFICE-3943
2496  SvtSaveOptions::ODFSVER_013 <= GetExport().getSaneDefaultVersion()
2499  "mime-type", sOutMimeType);
2500  }
2501  }
2502 
2503  SvXMLElementExport aElement(mrExport, XML_NAMESPACE_DRAW, XML_IMAGE, true, true);
2504 
2505  // optional office:binary-data
2506  if (xGraphic.is())
2507  {
2509  }
2510  if (!bIsEmptyPresObj)
2511  ImpExportText(xShape);
2512  }
2513 
2514  //Resolves: fdo#62461 put preferred image first above, followed by
2515  //fallback here
2516  const bool bAddReplacementImages = officecfg::Office::Common::Save::Graphic::AddReplacementImages::get();
2517  if( !bIsEmptyPresObj && bAddReplacementImages)
2518  {
2519  uno::Reference<graphic::XGraphic> xReplacementGraphic;
2520  xPropSet->getPropertyValue("ReplacementGraphic") >>= xReplacementGraphic;
2521 
2522  // If there is no url, then the graphic is empty
2523  if (xReplacementGraphic.is())
2524  {
2525  OUString aMimeType;
2526  const OUString aHref = mrExport.AddEmbeddedXGraphic(xReplacementGraphic, aMimeType);
2527 
2528  if (aMimeType.isEmpty())
2529  mrExport.GetGraphicMimeTypeFromStream(xReplacementGraphic, aMimeType);
2530 
2531  if (!aHref.isEmpty())
2532  {
2537  }
2538 
2539  if (!aMimeType.isEmpty() && GetExport().getSaneDefaultVersion() > SvtSaveOptions::ODFSVER_012)
2540  { // ODF 1.3 OFFICE-3943
2542  SvtSaveOptions::ODFSVER_013 <= GetExport().getSaneDefaultVersion()
2545  "mime-type", aMimeType);
2546  }
2547 
2548  SvXMLElementExport aElement(mrExport, XML_NAMESPACE_DRAW, XML_IMAGE, true, true);
2549 
2550  // optional office:binary-data
2551  mrExport.AddEmbeddedXGraphicAsBase64(xReplacementGraphic);
2552  }
2553  }
2554  }
2555 
2556  ImpExportEvents( xShape );
2557  ImpExportGluePoints( xShape );
2558 
2559  // image map
2560  GetExport().GetImageMapExport().Export( xPropSet );
2561  ImpExportDescription( xShape ); // #i68101#
2562 
2563  // Signature Line, QR Code - needs to be after the images!
2564  if (GetExport().getSaneDefaultVersion() & SvtSaveOptions::ODFSVER_EXTENDED)
2565  {
2566  ImpExportSignatureLine(xShape);
2567  ImpExportQRCode(xShape);
2568  }
2569 }
2570 
2572  const uno::Reference< drawing::XShape >& xShape,
2573  XmlShapeType eShapeType, XMLShapeExportFlags nFeatures, awt::Point* pRefPoint,
2574  SvXMLAttributeList* pAttrList )
2575 {
2576  ImpExportOLE2Shape( xShape, eShapeType, nFeatures, pRefPoint, pAttrList );
2577 }
2578 
2580  const uno::Reference< drawing::XShape >& xShape,
2581  XMLShapeExportFlags nFeatures, awt::Point* pRefPoint)
2582 {
2583  const uno::Reference< beans::XPropertySet > xPropSet(xShape, uno::UNO_QUERY);
2584  if(xPropSet.is())
2585  {
2586  // Transformation
2587  ImpExportNewTrans(xPropSet, nFeatures, pRefPoint);
2588  }
2589 
2590  uno::Reference< drawing::XControlShape > xControl( xShape, uno::UNO_QUERY );
2591  SAL_WARN_IF( !xControl.is(), "xmloff", "Control shape is not supporting XControlShape" );
2592  if( xControl.is() )
2593  {
2594  uno::Reference< beans::XPropertySet > xControlModel( xControl->getControl(), uno::UNO_QUERY );
2595  SAL_WARN_IF( !xControlModel.is(), "xmloff", "Control shape has not XControlModel" );
2596  if( xControlModel.is() )
2597  {
2598  OUString sControlId = mrExport.GetFormExport()->getControlId( xControlModel );
2600  }
2601  }
2602 
2603  bool bCreateNewline( (nFeatures & XMLShapeExportFlags::NO_WS) == XMLShapeExportFlags::NONE ); // #86116#/#92210#
2604  SvXMLElementExport aOBJ(mrExport, XML_NAMESPACE_DRAW, XML_CONTROL, bCreateNewline, true);
2605 
2606  ImpExportDescription( xShape ); // #i68101#
2607 }
2608 
2610  const uno::Reference< drawing::XShape >& xShape,
2611  XMLShapeExportFlags nFeatures /* = SEF_DEFAULT */, awt::Point* pRefPoint /* = NULL */)
2612 {
2613  uno::Reference< beans::XPropertySet > xProps( xShape, uno::UNO_QUERY );
2614 
2615  OUString aStr;
2616  OUStringBuffer sStringBuffer;
2617 
2618  // export connection kind
2619  drawing::ConnectorType eType = drawing::ConnectorType_STANDARD;
2620  uno::Any aAny = xProps->getPropertyValue("EdgeKind");
2621  aAny >>= eType;
2622 
2623  if( eType != drawing::ConnectorType_STANDARD )
2624  {
2626  aStr = sStringBuffer.makeStringAndClear();
2628  }
2629 
2630  // export line skew
2631  sal_Int32 nDelta1 = 0, nDelta2 = 0, nDelta3 = 0;
2632 
2633  aAny = xProps->getPropertyValue("EdgeLine1Delta");
2634  aAny >>= nDelta1;
2635  aAny = xProps->getPropertyValue("EdgeLine2Delta");
2636  aAny >>= nDelta2;
2637  aAny = xProps->getPropertyValue("EdgeLine3Delta");
2638  aAny >>= nDelta3;
2639 
2640  if( nDelta1 != 0 || nDelta2 != 0 || nDelta3 != 0 )
2641  {
2643  nDelta1);
2644  if( nDelta2 != 0 || nDelta3 != 0 )
2645  {
2646  sStringBuffer.append( ' ' );
2648  nDelta2);
2649  if( nDelta3 != 0 )
2650  {
2651  sStringBuffer.append( ' ' );
2653  sStringBuffer, nDelta3);
2654  }
2655  }
2656 
2657  aStr = sStringBuffer.makeStringAndClear();
2659  }
2660 
2661  // export start and end point
2662  awt::Point aStart(0,0);
2663  awt::Point aEnd(1,1);
2664 
2665  /* Get <StartPositionInHoriL2R> and
2666  <EndPositionInHoriL2R>, if they exist and if the document is exported
2667  into the OpenOffice.org file format.
2668  These properties only exist at service css::text::Shape - the
2669  Writer UNO service for shapes.
2670  This code is needed, because the positioning attributes in the
2671  OpenOffice.org file format are given in horizontal left-to-right layout
2672  regardless the layout direction the shape is in. In the OASIS Open Office
2673  file format the positioning attributes are correctly given in the layout
2674  direction the shape is in. Thus, this code provides the conversion from
2675  the OASIS Open Office file format to the OpenOffice.org file format. (#i36248#)
2676  */
2677  if ( !( GetExport().getExportFlags() & SvXMLExportFlags::OASIS ) &&
2678  xProps->getPropertySetInfo()->hasPropertyByName("StartPositionInHoriL2R") &&
2679  xProps->getPropertySetInfo()->hasPropertyByName("EndPositionInHoriL2R") )
2680  {
2681  xProps->getPropertyValue("StartPositionInHoriL2R") >>= aStart;
2682  xProps->getPropertyValue("EndPositionInHoriL2R") >>= aEnd;
2683  }
2684  else
2685  {
2686  xProps->getPropertyValue("StartPosition") >>= aStart;
2687  xProps->getPropertyValue("EndPosition") >>= aEnd;
2688  }
2689 
2690  if( pRefPoint )
2691  {
2692  aStart.X -= pRefPoint->X;
2693  aStart.Y -= pRefPoint->Y;
2694  aEnd.X -= pRefPoint->X;
2695  aEnd.Y -= pRefPoint->Y;
2696  }
2697 
2698  if( nFeatures & XMLShapeExportFlags::X )
2699  {
2700  // svg: x1
2702  aStart.X);
2703  aStr = sStringBuffer.makeStringAndClear();
2705  }
2706  else
2707  {
2708  aEnd.X -= aStart.X;
2709  }
2710 
2711  if( nFeatures & XMLShapeExportFlags::Y )
2712  {
2713  // svg: y1
2715  aStart.Y);
2716  aStr = sStringBuffer.makeStringAndClear();
2718  }
2719  else
2720  {
2721  aEnd.Y -= aStart.Y;
2722  }
2723 
2724  // svg: x2
2725  mrExport.GetMM100UnitConverter().convertMeasureToXML(sStringBuffer, aEnd.X);
2726  aStr = sStringBuffer.makeStringAndClear();
2728 
2729  // svg: y2
2730  mrExport.GetMM100UnitConverter().convertMeasureToXML(sStringBuffer, aEnd.Y);
2731  aStr = sStringBuffer.makeStringAndClear();
2733 
2734  // #i39320#
2735  uno::Reference< uno::XInterface > xRefS;
2736  uno::Reference< uno::XInterface > xRefE;
2737 
2738  // export start connection
2739  xProps->getPropertyValue("StartShape") >>= xRefS;
2740  if( xRefS.is() )
2741  {
2742  const OUString& rShapeId = mrExport.getInterfaceToIdentifierMapper().getIdentifier( xRefS );
2744 
2745  aAny = xProps->getPropertyValue("StartGluePointIndex");
2746  sal_Int32 nGluePointId = 0;
2747  if( aAny >>= nGluePointId )
2748  {
2749  if( nGluePointId != -1 )
2750  {
2751  mrExport.AddAttribute(XML_NAMESPACE_DRAW, XML_START_GLUE_POINT, OUString::number( nGluePointId ));
2752  }
2753  }
2754  }
2755 
2756  // export end connection
2757  xProps->getPropertyValue("EndShape") >>= xRefE;
2758  if( xRefE.is() )
2759  {
2760  const OUString& rShapeId = mrExport.getInterfaceToIdentifierMapper().getIdentifier( xRefE );
2762 
2763  aAny = xProps->getPropertyValue("EndGluePointIndex");
2764  sal_Int32 nGluePointId = 0;
2765  if( aAny >>= nGluePointId )
2766  {
2767  if( nGluePointId != -1 )
2768  {
2769  mrExport.AddAttribute(XML_NAMESPACE_DRAW, XML_END_GLUE_POINT, OUString::number( nGluePointId ));
2770  }
2771  }
2772  }
2773 
2774  // get PolygonBezier
2775  aAny = xProps->getPropertyValue("PolyPolygonBezier");
2776  auto pSourcePolyPolygon = o3tl::tryAccess<drawing::PolyPolygonBezierCoords>(aAny);
2777  if(pSourcePolyPolygon && pSourcePolyPolygon->Coordinates.getLength())
2778  {
2779  const basegfx::B2DPolyPolygon aPolyPolygon(
2781  *pSourcePolyPolygon));
2782  const OUString aPolygonString(
2784  aPolyPolygon,
2785  true, // bUseRelativeCoordinates
2786  false, // bDetectQuadraticBeziers: not used in old, but maybe activated now
2787  true)); // bHandleRelativeNextPointCompatible
2788 
2789  // write point array
2790  mrExport.AddAttribute(XML_NAMESPACE_SVG, XML_D, aPolygonString);
2791  }
2792 
2793  // get matrix
2794  ::basegfx::B2DHomMatrix aMatrix;
2795  ImpExportNewTrans_GetB2DHomMatrix(aMatrix, xProps);
2796 
2797  // decompose and correct about pRefPoint
2798  ::basegfx::B2DTuple aTRScale;
2799  double fTRShear(0.0);
2800  double fTRRotate(0.0);
2801  ::basegfx::B2DTuple aTRTranslate;
2802  ImpExportNewTrans_DecomposeAndRefPoint(aMatrix, aTRScale, fTRShear,
2803  fTRRotate, aTRTranslate, pRefPoint);
2804 
2805  // fdo#49678: create and export ViewBox
2806  awt::Size aSize(FRound(aTRScale.getX()), FRound(aTRScale.getY()));
2807  SdXMLImExViewBox aViewBox(0, 0, aSize.Width, aSize.Height);
2809 
2810  // write connector shape. Add Export later.
2811  bool bCreateNewline( (nFeatures & XMLShapeExportFlags::NO_WS) == XMLShapeExportFlags::NONE ); // #86116#/#92210#
2812  SvXMLElementExport aOBJ(mrExport, XML_NAMESPACE_DRAW, XML_CONNECTOR, bCreateNewline, true);
2813 
2814  ImpExportDescription( xShape ); // #i68101#
2815  ImpExportEvents( xShape );
2816  ImpExportGluePoints( xShape );
2817  ImpExportText( xShape );
2818 }
2819 
2821  const uno::Reference< drawing::XShape >& xShape,
2822  XMLShapeExportFlags nFeatures /* = SEF_DEFAULT */, awt::Point const * pRefPoint /* = NULL */)
2823 {
2824  uno::Reference< beans::XPropertySet > xProps( xShape, uno::UNO_QUERY );
2825 
2826  OUString aStr;
2827  OUStringBuffer sStringBuffer;
2828 
2829  // export start and end point
2830  awt::Point aStart(0,0);
2831  awt::Point aEnd(1,1);
2832 
2833  /* Get <StartPositionInHoriL2R> and
2834  <EndPositionInHoriL2R>, if they exist and if the document is exported
2835  into the OpenOffice.org file format.
2836  These properties only exist at service css::text::Shape - the
2837  Writer UNO service for shapes.
2838  This code is needed, because the positioning attributes in the
2839  OpenOffice.org file format are given in horizontal left-to-right layout
2840  regardless the layout direction the shape is in. In the OASIS Open Office
2841  file format the positioning attributes are correctly given in the layout
2842  direction the shape is in. Thus, this code provides the conversion from
2843  the OASIS Open Office file format to the OpenOffice.org file format. (#i36248#)
2844  */
2845  if ( !( GetExport().getExportFlags() & SvXMLExportFlags::OASIS ) &&
2846  xProps->getPropertySetInfo()->hasPropertyByName("StartPositionInHoriL2R") &&
2847  xProps->getPropertySetInfo()->hasPropertyByName("EndPositionInHoriL2R") )
2848  {
2849  xProps->getPropertyValue("StartPositionInHoriL2R") >>= aStart;
2850  xProps->getPropertyValue("EndPositionInHoriL2R") >>= aEnd;
2851  }
2852  else
2853  {
2854  xProps->getPropertyValue("StartPosition") >>= aStart;
2855  xProps->getPropertyValue("EndPosition") >>= aEnd;
2856  }
2857 
2858  if( pRefPoint )
2859  {
2860  aStart.X -= pRefPoint->X;
2861  aStart.Y -= pRefPoint->Y;
2862  aEnd.X -= pRefPoint->X;
2863  aEnd.Y -= pRefPoint->Y;
2864  }
2865 
2866  if( nFeatures & XMLShapeExportFlags::X )
2867  {
2868  // svg: x1
2870  aStart.X);
2871  aStr = sStringBuffer.makeStringAndClear();
2873  }
2874  else
2875  {
2876  aEnd.X -= aStart.X;
2877  }
2878 
2879  if( nFeatures & XMLShapeExportFlags::Y )
2880  {
2881  // svg: y1
2883  aStart.Y);
2884  aStr = sStringBuffer.makeStringAndClear();
2886  }
2887  else
2888  {
2889  aEnd.Y -= aStart.Y;
2890  }
2891 
2892  // svg: x2
2893  mrExport.GetMM100UnitConverter().convertMeasureToXML(sStringBuffer, aEnd.X);
2894  aStr = sStringBuffer.makeStringAndClear();
2896 
2897  // svg: y2
2898  mrExport.GetMM100UnitConverter().convertMeasureToXML(sStringBuffer, aEnd.Y);
2899  aStr = sStringBuffer.makeStringAndClear();
2901 
2902  // write measure shape
2903  bool bCreateNewline( (nFeatures & XMLShapeExportFlags::NO_WS) == XMLShapeExportFlags::NONE ); // #86116#/#92210#
2904  SvXMLElementExport aOBJ(mrExport, XML_NAMESPACE_DRAW, XML_MEASURE, bCreateNewline, true);
2905 
2906  ImpExportDescription( xShape ); // #i68101#
2907  ImpExportEvents( xShape );
2908  ImpExportGluePoints( xShape );
2909 
2910  uno::Reference< text::XText > xText( xShape, uno::UNO_QUERY );
2911  if( xText.is() )
2912  mrExport.GetTextParagraphExport()->exportText( xText );
2913 }
2914 
2916  const uno::Reference< drawing::XShape >& xShape,
2917  XmlShapeType eShapeType, XMLShapeExportFlags nFeatures /* = SEF_DEFAULT */, awt::Point* pRefPoint /* = NULL */,
2918  SvXMLAttributeList* pAttrList /* = NULL */ )
2919 {
2920  uno::Reference< beans::XPropertySet > xPropSet(xShape, uno::UNO_QUERY);
2921  uno::Reference< container::XNamed > xNamed(xShape, uno::UNO_QUERY);
2922 
2923  SAL_WARN_IF( !xPropSet.is() || !xNamed.is(), "xmloff", "ole shape is not implementing needed interfaces");
2924  if(!(xPropSet.is() && xNamed.is()))
2925  return;
2926 
2927  // Transformation
2928  ImpExportNewTrans(xPropSet, nFeatures, pRefPoint);
2929 
2930  bool bIsEmptyPresObj = false;
2931 
2932  // presentation settings
2933  if(eShapeType == XmlShapeTypePresOLE2Shape)
2934  bIsEmptyPresObj = ImpExportPresentationAttributes( xPropSet, GetXMLToken(XML_OBJECT) );
2935  else if(eShapeType == XmlShapeTypePresChartShape)
2936  bIsEmptyPresObj = ImpExportPresentationAttributes( xPropSet, GetXMLToken(XML_CHART) );
2937  else if(eShapeType == XmlShapeTypePresSheetShape)
2938  bIsEmptyPresObj = ImpExportPresentationAttributes( xPropSet, GetXMLToken(XML_TABLE) );
2939 
2940  bool bCreateNewline( (nFeatures & XMLShapeExportFlags::NO_WS) == XMLShapeExportFlags::NONE ); // #86116#/#92210#
2941  bool bExportEmbedded(mrExport.getExportFlags() & SvXMLExportFlags::EMBEDDED);
2942  OUString sPersistName;
2944  XML_FRAME, bCreateNewline, true );
2945 
2946  if (!bIsEmptyPresObj)
2947  {
2948  if (pAttrList)
2949  {
2950  mrExport.AddAttributeList(pAttrList);
2951  }
2952 
2953  OUString sClassId;
2954  OUString sURL;
2955  bool bInternal = false;
2956  xPropSet->getPropertyValue("IsInternal") >>= bInternal;
2957 
2958  {
2959 
2960  if ( bInternal )
2961  {
2962  // OOo internal links have no storage persistence, URL is stored in the XML file
2963  // the result LinkURL is empty in case the object is not a link
2964  xPropSet->getPropertyValue("LinkURL") >>= sURL;
2965  }
2966 
2967  xPropSet->getPropertyValue("PersistName") >>= sPersistName;
2968  if ( sURL.isEmpty() )
2969  {
2970  if( !sPersistName.isEmpty() )
2971  {
2972  sURL = "vnd.sun.star.EmbeddedObject:" + sPersistName;
2973  }
2974  }
2975 
2976  if( !bInternal )
2977  xPropSet->getPropertyValue("CLSID") >>= sClassId;
2978 
2979  if( !sClassId.isEmpty() )
2981 
2982  if(!bExportEmbedded)
2983  {
2984  // xlink:href
2985  if( !sURL.isEmpty() )
2986  {
2987  // #96717# in theorie, if we don't have a URL we shouldn't even
2988  // export this OLE shape. But practically it's too risky right now
2989  // to change this so we better dispose this on load
2990  sURL = mrExport.AddEmbeddedObject( sURL );
2991 
2996  }
2997  }
2998  }
2999 
3000  enum XMLTokenEnum eElem = sClassId.isEmpty() ? XML_OBJECT : XML_OBJECT_OLE ;
3001  SvXMLElementExport aElem( mrExport, XML_NAMESPACE_DRAW, eElem, true, true );
3002 
3003  // tdf#112547 export text as child of draw:object, where import expects it
3004  if (!bIsEmptyPresObj && supportsText(eShapeType))
3005  {
3006  // #i118485# Add text export, the draw OLE shape allows text now
3007  ImpExportText( xShape, TextPNS::EXTENSION );
3008  }
3009 
3010  if(bExportEmbedded && !bIsEmptyPresObj)
3011  {
3012  if(bInternal)
3013  {
3014  // embedded XML
3015  uno::Reference< lang::XComponent > xComp;
3016  xPropSet->getPropertyValue("Model") >>= xComp;
3017  SAL_WARN_IF( !xComp.is(), "xmloff", "no xModel for own OLE format" );
3019  }
3020  else
3021  {
3022  // embed as Base64
3023  // this is an alien object ( currently MSOLE is the only supported type of such objects )
3024  // in case it is not an OASIS format the object should be asked to store replacement image if possible
3025 
3026  OUString sURLRequest( sURL );
3028  sURLRequest += "?oasis=false";
3029  mrExport.AddEmbeddedObjectAsBase64( sURLRequest );
3030  }
3031  }
3032  }
3033  if( !bIsEmptyPresObj )
3034  {
3035  OUString sURL = XML_EMBEDDEDOBJECTGRAPHIC_URL_BASE + sPersistName;
3036  if( !bExportEmbedded )
3037  {
3038  sURL = GetExport().AddEmbeddedObject( sURL );
3043  }
3044 
3046  XML_IMAGE, false, true );
3047 
3048  if( bExportEmbedded )
3050  }
3051 
3052  ImpExportEvents( xShape );
3053  ImpExportGluePoints( xShape );
3054  ImpExportDescription( xShape ); // #i68101#
3055 
3056 }
3057 
3059  const uno::Reference< drawing::XShape >& xShape,
3060  XmlShapeType eShapeType, XMLShapeExportFlags nFeatures /* = SEF_DEFAULT */, awt::Point* pRefPoint /* = NULL */)
3061 {
3062  const uno::Reference< beans::XPropertySet > xPropSet(xShape, uno::UNO_QUERY);
3063  if(!xPropSet.is())
3064  return;
3065 
3066  // #86163# Transformation
3067  ImpExportNewTrans(xPropSet, nFeatures, pRefPoint);
3068 
3069  // export page number used for this page
3070  uno::Reference< beans::XPropertySetInfo > xPropSetInfo( xPropSet->getPropertySetInfo() );
3071  static const OUStringLiteral aPageNumberStr(u"PageNumber");
3072  if( xPropSetInfo.is() && xPropSetInfo->hasPropertyByName(aPageNumberStr))
3073  {
3074  sal_Int32 nPageNumber = 0;
3075  xPropSet->getPropertyValue(aPageNumberStr) >>= nPageNumber;
3076  if( nPageNumber )
3077  mrExport.AddAttribute(XML_NAMESPACE_DRAW, XML_PAGE_NUMBER, OUString::number(nPageNumber));
3078  }
3079 
3080  // a presentation page shape, normally used on notes pages only. If
3081  // it is used not as presentation shape, it may have been created with
3082  // copy-paste exchange between draw and impress (this IS possible...)
3083  if(eShapeType == XmlShapeTypePresPageShape)
3084  {
3086  XML_PAGE);
3087  }
3088 
3089  // write Page shape
3090  bool bCreateNewline( (nFeatures & XMLShapeExportFlags::NO_WS) == XMLShapeExportFlags::NONE ); // #86116#/#92210#
3091  SvXMLElementExport aOBJ(mrExport, XML_NAMESPACE_DRAW, XML_PAGE_THUMBNAIL, bCreateNewline, true);
3092 }
3093 
3095  const uno::Reference< drawing::XShape >& xShape,
3096  XMLShapeExportFlags nFeatures /* = SEF_DEFAULT */, awt::Point* pRefPoint /* = NULL */)
3097 {
3098  const uno::Reference< beans::XPropertySet > xPropSet(xShape, uno::UNO_QUERY);
3099  if(!xPropSet.is())
3100  return;
3101 
3102  // Transformation
3103  ImpExportNewTrans(xPropSet, nFeatures, pRefPoint);
3104 
3105  // evtl. corner radius?
3106  sal_Int32 nCornerRadius(0);
3107  xPropSet->getPropertyValue("CornerRadius") >>= nCornerRadius;
3108  if(nCornerRadius)
3109  {
3110  OUStringBuffer sStringBuffer;
3112  nCornerRadius);
3113  mrExport.AddAttribute(XML_NAMESPACE_DRAW, XML_CORNER_RADIUS, sStringBuffer.makeStringAndClear());
3114  }
3115 
3116  awt::Point aCaptionPoint;
3117  xPropSet->getPropertyValue("CaptionPoint") >>= aCaptionPoint;
3118 
3120  aCaptionPoint.X);
3123  aCaptionPoint.Y);
3125 
3126  // write Caption shape. Add export later.
3127  bool bCreateNewline( (nFeatures & XMLShapeExportFlags::NO_WS) == XMLShapeExportFlags::NONE ); // #86116#/#92210#
3128  bool bAnnotation( (nFeatures & XMLShapeExportFlags::ANNOTATION) == XMLShapeExportFlags::ANNOTATION );
3129 
3131  (bAnnotation ? XML_NAMESPACE_OFFICE
3132  : XML_NAMESPACE_DRAW),
3133  (bAnnotation ? XML_ANNOTATION : XML_CAPTION),
3134  bCreateNewline, true );
3135 
3136  ImpExportDescription( xShape ); // #i68101#
3137  ImpExportEvents( xShape );
3138  ImpExportGluePoints( xShape );
3139  if( bAnnotation )
3140  mrExport.exportAnnotationMeta( xShape );
3141  ImpExportText( xShape );
3142 
3143 }
3144 
3146  const uno::Reference< drawing::XShape >& xShape,
3147  XMLShapeExportFlags nFeatures, css::awt::Point* pRefPoint)
3148 {
3149  const uno::Reference< beans::XPropertySet > xPropSet(xShape, uno::UNO_QUERY);
3150  if(!xPropSet.is())
3151  return;
3152 
3153  // Transformation
3154  ImpExportNewTrans(xPropSet, nFeatures, pRefPoint);
3155 
3156  bool bCreateNewline( (nFeatures & XMLShapeExportFlags::NO_WS) == XMLShapeExportFlags::NONE ); // #86116#/#92210#
3158  XML_FRAME, bCreateNewline, true );
3159 
3160  // export frame url
3161  OUString aStr;
3162  xPropSet->getPropertyValue("FrameURL") >>= aStr;
3163  mrExport.AddAttribute ( XML_NAMESPACE_XLINK, XML_HREF, GetExport().GetRelativeReference(aStr) );
3167 
3168  // export name
3169  xPropSet->getPropertyValue("FrameName") >>= aStr;
3170  if( !aStr.isEmpty() )
3172 
3173  // write floating frame
3174  {
3176  }
3177 
3178 }
3179 
3181  const uno::Reference< drawing::XShape >& xShape,
3182  XMLShapeExportFlags nFeatures, css::awt::Point* pRefPoint)
3183 {
3184  const uno::Reference< beans::XPropertySet > xPropSet(xShape, uno::UNO_QUERY);
3185  if(!xPropSet.is())
3186  return;
3187 
3188  // Transformation
3189  ImpExportNewTrans(xPropSet, nFeatures, pRefPoint);
3190 
3191  bool bCreateNewline( (nFeatures & XMLShapeExportFlags::NO_WS) == XMLShapeExportFlags::NONE ); // #86116#/#92210#
3193  XML_FRAME, bCreateNewline, true );
3194 
3195  // export frame url
3196  OUString aStr;
3197  xPropSet->getPropertyValue("AppletCodeBase") >>= aStr;
3198  mrExport.AddAttribute ( XML_NAMESPACE_XLINK, XML_HREF, GetExport().GetRelativeReference(aStr) );
3202 
3203  // export draw:applet-name
3204  xPropSet->getPropertyValue("AppletName") >>= aStr;
3205  if( !aStr.isEmpty() )
3207 
3208  // export draw:code
3209  xPropSet->getPropertyValue("AppletCode") >>= aStr;
3211 
3212  // export draw:may-script
3213  bool bIsScript = false;
3214  xPropSet->getPropertyValue("AppletIsScript") >>= bIsScript;
3216 
3217  {
3218  // write applet
3220 
3221  // export parameters
3222  uno::Sequence< beans::PropertyValue > aCommands;
3223  xPropSet->getPropertyValue("AppletCommands") >>= aCommands;
3224  for( const auto& rCommand : std::as_const(aCommands) )
3225  {
3226  rCommand.Value >>= aStr;
3227  mrExport.AddAttribute( XML_NAMESPACE_DRAW, XML_NAME, rCommand.Name );
3229  SvXMLElementExport aElem( mrExport, XML_NAMESPACE_DRAW, XML_PARAM, false, true );
3230  }
3231  }
3232 
3233 }
3234 
3236  const uno::Reference< drawing::XShape >& xShape,
3237  XMLShapeExportFlags nFeatures, css::awt::Point* pRefPoint)
3238 {
3239  const uno::Reference< beans::XPropertySet > xPropSet(xShape, uno::UNO_QUERY);
3240  if(!xPropSet.is())
3241  return;
3242 
3243  // Transformation
3244  ImpExportNewTrans(xPropSet, nFeatures, pRefPoint);
3245 
3246  bool bCreateNewline( (nFeatures & XMLShapeExportFlags::NO_WS) == XMLShapeExportFlags::NONE ); // #86116#/#92210#
3248  XML_FRAME, bCreateNewline, true );
3249 
3250  // export plugin url
3251  OUString aStr;
3252  xPropSet->getPropertyValue("PluginURL") >>= aStr;
3253  mrExport.AddAttribute ( XML_NAMESPACE_XLINK, XML_HREF, GetExport().GetRelativeReference(aStr) );
3257 
3258  // export mime-type
3259  xPropSet->getPropertyValue("PluginMimeType") >>= aStr;
3260  if(!aStr.isEmpty())
3262 
3263  {
3264  // write plugin
3266 
3267  // export parameters
3268  uno::Sequence< beans::PropertyValue > aCommands;
3269  xPropSet->getPropertyValue("PluginCommands") >>= aCommands;
3270  for( const auto& rCommand : std::as_const(aCommands) )
3271  {
3272  rCommand.Value >>= aStr;
3273  mrExport.AddAttribute( XML_NAMESPACE_DRAW, XML_NAME, rCommand.Name );
3275  SvXMLElementExport aElem( mrExport, XML_NAMESPACE_DRAW, XML_PARAM, false, true );
3276  }
3277  }
3278 
3279 }
3280 
3281 static void lcl_CopyStream(
3282  uno::Reference<io::XInputStream> const& xInStream,
3283  uno::Reference<embed::XStorage> const& xTarget,
3284  OUString const& rPath, const OUString& rMimeType)
3285 {
3287  uno::Reference<io::XStream> const xStream(
3289  embed::ElementModes::WRITE | embed::ElementModes::TRUNCATE, proxy));
3290  uno::Reference<io::XOutputStream> const xOutStream(
3291  (xStream.is()) ? xStream->getOutputStream() : nullptr);
3292  if (!xOutStream.is())
3293  {
3294  SAL_WARN("xmloff", "no output stream");
3295  throw uno::Exception("no output stream",nullptr);
3296  }
3297  uno::Reference< beans::XPropertySet > const xStreamProps(xStream,
3298  uno::UNO_QUERY);
3299  if (xStreamProps.is()) { // this is NOT supported in FileSystemStorage
3300  xStreamProps->setPropertyValue("MediaType",
3301  uno::makeAny(rMimeType));
3302  xStreamProps->setPropertyValue( // turn off compression
3303  "Compressed",
3304  uno::makeAny(false));
3305  }
3306  ::comphelper::OStorageHelper::CopyInputToOutput(xInStream, xOutStream);
3307  xOutStream->closeOutput();
3308  proxy.commitStorages();
3309 }
3310 
3311 static OUString
3313  uno::Reference<beans::XPropertySet> const& xPropSet,
3314  OUString const& rURL, const OUString& rMimeType)
3315 {
3316  OUString urlPath;
3317  if (rURL.startsWithIgnoreAsciiCase("vnd.sun.star.Package:", &urlPath))
3318  {
3319  try // video is embedded
3320  {
3321  uno::Reference<embed::XStorage> const xTarget(
3322  rExport.GetTargetStorage(), uno::UNO_SET_THROW);
3323  uno::Reference<io::XInputStream> xInStream;
3324  xPropSet->getPropertyValue("PrivateStream")
3325  >>= xInStream;
3326 
3327  if (!xInStream.is())
3328  {
3329  SAL_WARN("xmloff", "no input stream");
3330  return OUString();
3331  }
3332 
3333  lcl_CopyStream(xInStream, xTarget, rURL, rMimeType);
3334 
3335  return urlPath;
3336  }
3337  catch (uno::Exception const&)
3338  {
3339  TOOLS_INFO_EXCEPTION("xmloff", "exception while storing embedded media");
3340  }
3341  return OUString();
3342  }
3343  else
3344  {
3345  return rExport.GetRelativeReference(rURL); // linked
3346  }
3347 }
3348 
3350  const uno::Reference< drawing::XShape >& xShape,
3351  XmlShapeType eShapeType, XMLShapeExportFlags nFeatures, css::awt::Point* pRefPoint)
3352 {
3353  const uno::Reference< beans::XPropertySet > xPropSet(xShape, uno::UNO_QUERY);
3354  if(!xPropSet.is())
3355  return;
3356 
3357  // Transformation
3358  ImpExportNewTrans(xPropSet, nFeatures, pRefPoint);
3359 
3360  if(eShapeType == XmlShapeTypePresMediaShape)
3361  {
3363  }
3364  bool bCreateNewline( (nFeatures & XMLShapeExportFlags::NO_WS) == XMLShapeExportFlags::NONE ); // #86116#/#92210#
3366  XML_FRAME, bCreateNewline, true );
3367 
3368  // export media url
3369  OUString aMediaURL;
3370  xPropSet->getPropertyValue("MediaURL") >>= aMediaURL;
3371  OUString sMimeType;
3372  xPropSet->getPropertyValue("MediaMimeType") >>= sMimeType;
3373 
3374  OUString const persistentURL =
3375  lcl_StoreMediaAndGetURL(GetExport(), xPropSet, aMediaURL, sMimeType);
3376 
3377  mrExport.AddAttribute ( XML_NAMESPACE_XLINK, XML_HREF, persistentURL );
3381 
3382  // export mime-type
3384 
3385  // write plugin
3386  SvXMLElementExport aPluginOBJ(mrExport, XML_NAMESPACE_DRAW, XML_PLUGIN, !( nFeatures & XMLShapeExportFlags::NO_WS ), true);
3387 
3388  // export parameters
3389  const OUString aFalseStr( "false" ), aTrueStr( "true" );
3390 
3391  bool bLoop = false;
3392  static const OUStringLiteral aLoopStr( u"Loop" );
3393  xPropSet->getPropertyValue( aLoopStr ) >>= bLoop;
3396  delete new SvXMLElementExport( mrExport, XML_NAMESPACE_DRAW, XML_PARAM, false, true );
3397 
3398  bool bMute = false;
3399  static const OUStringLiteral aMuteStr( u"Mute" );
3400  xPropSet->getPropertyValue( aMuteStr ) >>= bMute;
3402  mrExport.AddAttribute( XML_NAMESPACE_DRAW, XML_VALUE, bMute ? aTrueStr : aFalseStr );
3403  delete new SvXMLElementExport( mrExport, XML_NAMESPACE_DRAW, XML_PARAM, false, true );
3404 
3405  sal_Int16 nVolumeDB = 0;
3406  xPropSet->getPropertyValue("VolumeDB") >>= nVolumeDB;
3408  mrExport.AddAttribute( XML_NAMESPACE_DRAW, XML_VALUE, OUString::number( nVolumeDB ) );
3409  delete new SvXMLElementExport( mrExport, XML_NAMESPACE_DRAW, XML_PARAM, false, true );
3410 
3411  media::ZoomLevel eZoom;
3412  OUString aZoomValue;
3413  xPropSet->getPropertyValue("Zoom") >>= eZoom;
3414  switch( eZoom )
3415  {
3416  case media::ZoomLevel_ZOOM_1_TO_4 : aZoomValue = "25%"; break;
3417  case media::ZoomLevel_ZOOM_1_TO_2 : aZoomValue = "50%"; break;
3418  case media::ZoomLevel_ORIGINAL : aZoomValue = "100%"; break;
3419  case media::ZoomLevel_ZOOM_2_TO_1 : aZoomValue = "200%"; break;
3420  case media::ZoomLevel_ZOOM_4_TO_1 : aZoomValue = "400%"; break;
3421  case media::ZoomLevel_FIT_TO_WINDOW: aZoomValue = "fit"; break;
3422  case media::ZoomLevel_FIT_TO_WINDOW_FIXED_ASPECT: aZoomValue = "fixedfit"; break;
3423  case media::ZoomLevel_FULLSCREEN : aZoomValue = "fullscreen"; break;
3424 
3425  default:
3426  break;
3427  }
3428 
3429  if( !aZoomValue.isEmpty() )
3430  {
3433  delete new SvXMLElementExport( mrExport, XML_NAMESPACE_DRAW, XML_PARAM, false, true );
3434  }
3435 
3436 }
3437 
3438 void XMLShapeExport::ImpExport3DSceneShape( const uno::Reference< drawing::XShape >& xShape, XMLShapeExportFlags nFeatures, awt::Point* pRefPoint)
3439 {
3440  uno::Reference< drawing::XShapes > xShapes(xShape, uno::UNO_QUERY);
3441  if(!(xShapes.is() && xShapes->getCount()))
3442  return;
3443 
3444  uno::Reference< beans::XPropertySet > xPropSet( xShape, uno::UNO_QUERY );
3445  SAL_WARN_IF( !xPropSet.is(), "xmloff", "XMLShapeExport::ImpExport3DSceneShape can't export a scene without a propertyset" );
3446  if( !xPropSet.is() )
3447  return;
3448 
3449  // Transformation
3450  ImpExportNewTrans(xPropSet, nFeatures, pRefPoint);
3451 
3452  // 3d attributes
3453  export3DSceneAttributes( xPropSet );
3454 
3455  // write 3DScene shape
3456  bool bCreateNewline( (nFeatures & XMLShapeExportFlags::NO_WS) == XMLShapeExportFlags::NONE ); // #86116#/#92210#
3457  SvXMLElementExport aOBJ( mrExport, XML_NAMESPACE_DR3D, XML_SCENE, bCreateNewline, true);
3458 
3459  ImpExportDescription( xShape ); // #i68101#
3460  ImpExportEvents( xShape );
3461 
3462  // write 3DSceneLights
3463  export3DLamps( xPropSet );
3464 
3465  // #89764# if export of position is suppressed for group shape,
3466  // positions of contained objects should be written relative to
3467  // the upper left edge of the group.
3468  awt::Point aUpperLeft;
3469 
3470  if(!(nFeatures & XMLShapeExportFlags::POSITION))
3471  {
3472  nFeatures |= XMLShapeExportFlags::POSITION;
3473  aUpperLeft = xShape->getPosition();
3474  pRefPoint = &aUpperLeft;
3475  }
3476 
3477  // write members
3478  exportShapes( xShapes, nFeatures, pRefPoint );
3479 }
3480 
3482  const uno::Reference< drawing::XShape >& xShape,
3483  XmlShapeType eShapeType)
3484 {
3485  const uno::Reference< beans::XPropertySet > xPropSet(xShape, uno::UNO_QUERY);
3486  if(!xPropSet.is())
3487  return;
3488 
3489  OUString aStr;
3490  OUStringBuffer sStringBuffer;
3491 
3492  // transformation (UNO_NAME_3D_TRANSFORM_MATRIX == "D3DTransformMatrix")
3493  uno::Any aAny = xPropSet->getPropertyValue("D3DTransformMatrix");
3494  drawing::HomogenMatrix aHomMat;
3495  aAny >>= aHomMat;
3496  SdXMLImExTransform3D aTransform;
3497  aTransform.AddHomogenMatrix(aHomMat);
3498  if(aTransform.NeedsAction())
3500 
3501  switch(eShapeType)
3502  {
3504  {
3505  // minEdge
3506  aAny = xPropSet->getPropertyValue("D3DPosition");
3507  drawing::Position3D aPosition3D;
3508  aAny >>= aPosition3D;
3509  ::basegfx::B3DVector aPos3D(aPosition3D.PositionX, aPosition3D.PositionY, aPosition3D.PositionZ);
3510 
3511  // maxEdge
3512  aAny = xPropSet->getPropertyValue("D3DSize");
3513  drawing::Direction3D aDirection3D;
3514  aAny >>= aDirection3D;
3515  ::basegfx::B3DVector aDir3D(aDirection3D.DirectionX, aDirection3D.DirectionY, aDirection3D.DirectionZ);
3516 
3517  // transform maxEdge from distance to pos
3518  aDir3D = aPos3D + aDir3D;
3519 
3520  // write minEdge
3521  if(aPos3D != ::basegfx::B3DVector(-2500.0, -2500.0, -2500.0)) // write only when not default
3522  {
3523  SvXMLUnitConverter::convertB3DVector(sStringBuffer, aPos3D);
3524  aStr = sStringBuffer.makeStringAndClear();
3526  }
3527 
3528  // write maxEdge
3529  if(aDir3D != ::basegfx::B3DVector(2500.0, 2500.0, 2500.0)) // write only when not default
3530  {
3531  SvXMLUnitConverter::convertB3DVector(sStringBuffer, aDir3D);
3532  aStr = sStringBuffer.makeStringAndClear();
3534  }
3535 
3536  // write 3DCube shape
3537  // #i123542# Do this *after* the attributes are added, else these will be lost since opening
3538  // the scope will clear the global attribute list at the exporter
3540 
3541  break;
3542  }
3544  {
3545  // Center
3546  aAny = xPropSet->getPropertyValue("D3DPosition");
3547  drawing::Position3D aPosition3D;
3548  aAny >>= aPosition3D;
3549  ::basegfx::B3DVector aPos3D(aPosition3D.PositionX, aPosition3D.PositionY, aPosition3D.PositionZ);
3550 
3551  // Size
3552  aAny = xPropSet->getPropertyValue("D3DSize");
3553  drawing::Direction3D aDirection3D;
3554  aAny >>= aDirection3D;
3555  ::basegfx::B3DVector aDir3D(aDirection3D.DirectionX, aDirection3D.DirectionY, aDirection3D.DirectionZ);
3556 
3557  // write Center
3558  if(aPos3D != ::basegfx::B3DVector(0.0, 0.0, 0.0)) // write only when not default
3559  {
3560  SvXMLUnitConverter::convertB3DVector(sStringBuffer, aPos3D);
3561  aStr = sStringBuffer.makeStringAndClear();
3563  }
3564 
3565  // write Size
3566  if(aDir3D != ::basegfx::B3DVector(5000.0, 5000.0, 5000.0)) // write only when not default
3567  {
3568  SvXMLUnitConverter::convertB3DVector(sStringBuffer, aDir3D);
3569  aStr = sStringBuffer.makeStringAndClear();
3571  }
3572 
3573  // write 3DSphere shape
3574  // #i123542# Do this *after* the attributes are added, else these will be lost since opening
3575  // the scope will clear the global attribute list at the exporter
3577 
3578  break;
3579  }
3582  {
3583  // write special 3DLathe/3DExtrude attributes, get 3D tools::PolyPolygon as drawing::PolyPolygonShape3D
3584  aAny = xPropSet->getPropertyValue("D3DPolyPolygon3D");
3585  drawing::PolyPolygonShape3D aUnoPolyPolygon3D;
3586  aAny >>= aUnoPolyPolygon3D;
3587 
3588  // convert to 3D PolyPolygon
3589  const basegfx::B3DPolyPolygon aPolyPolygon3D(
3591  aUnoPolyPolygon3D));
3592 
3593  // convert to 2D tools::PolyPolygon using identity 3D transformation (just grep X and Y)
3594  const basegfx::B3DHomMatrix aB3DHomMatrixFor2DConversion;
3595  const basegfx::B2DPolyPolygon aPolyPolygon(
3597  aPolyPolygon3D,
3598  aB3DHomMatrixFor2DConversion));
3599 
3600  // get 2D range of it
3601  const basegfx::B2DRange aPolyPolygonRange(aPolyPolygon.getB2DRange());
3602 
3603  // export ViewBox
3604  SdXMLImExViewBox aViewBox(
3605  aPolyPolygonRange.getMinX(),
3606  aPolyPolygonRange.getMinY(),
3607  aPolyPolygonRange.getWidth(),
3608  aPolyPolygonRange.getHeight());
3609 
3610  mrExport.AddAttribute(XML_NAMESPACE_SVG, XML_VIEWBOX, aViewBox.GetExportString());
3611 
3612  // prepare svg:d string
3613  const OUString aPolygonString(
3615  aPolyPolygon,
3616  true, // bUseRelativeCoordinates
3617  false, // bDetectQuadraticBeziers TTTT: not used in old, but maybe activated now
3618  true)); // bHandleRelativeNextPointCompatible
3619 
3620  // write point array
3621  mrExport.AddAttribute(XML_NAMESPACE_SVG, XML_D, aPolygonString);
3622 
3623  if(eShapeType == XmlShapeTypeDraw3DLatheObject)
3624  {
3625  // write 3DLathe shape
3627  }
3628  else
3629  {
3630  // write 3DExtrude shape
3632  }
3633  break;
3634  }
3635  default:
3636  break;
3637  }
3638 }
3639 
3641 void XMLShapeExport::export3DSceneAttributes( const css::uno::Reference< css::beans::XPropertySet >& xPropSet )
3642 {
3643  OUString aStr;
3644  OUStringBuffer sStringBuffer;
3645 
3646  // world transformation (UNO_NAME_3D_TRANSFORM_MATRIX == "D3DTransformMatrix")
3647  uno::Any aAny = xPropSet->getPropertyValue("D3DTransformMatrix");
3648  drawing::HomogenMatrix aHomMat;
3649  aAny >>= aHomMat;
3650  SdXMLImExTransform3D aTransform;
3651  aTransform.AddHomogenMatrix(aHomMat);
3652  if(aTransform.NeedsAction())
3654 
3655  // VRP, VPN, VUP
3656  aAny = xPropSet->getPropertyValue("D3DCameraGeometry");
3657  drawing::CameraGeometry aCamGeo;
3658  aAny >>= aCamGeo;
3659 
3660  ::basegfx::B3DVector aVRP(aCamGeo.vrp.PositionX, aCamGeo.vrp.PositionY, aCamGeo.vrp.PositionZ);
3661  if(aVRP != ::basegfx::B3DVector(0.0, 0.0, 1.0)) // write only when not default
3662  {
3663  SvXMLUnitConverter::convertB3DVector(sStringBuffer, aVRP);
3664  aStr = sStringBuffer.makeStringAndClear();
3666  }
3667 
3668  ::basegfx::B3DVector aVPN(aCamGeo.vpn.DirectionX, aCamGeo.vpn.DirectionY, aCamGeo.vpn.DirectionZ);
3669  if(aVPN != ::basegfx::B3DVector(0.0, 0.0, 1.0)) // write only when not default
3670  {
3671  SvXMLUnitConverter::convertB3DVector(sStringBuffer, aVPN);
3672  aStr = sStringBuffer.makeStringAndClear();
3674  }
3675 
3676  ::basegfx::B3DVector aVUP(aCamGeo.vup.DirectionX, aCamGeo.vup.DirectionY, aCamGeo.vup.DirectionZ);
3677  if(aVUP != ::basegfx::B3DVector(0.0, 1.0, 0.0)) // write only when not default
3678  {
3679  SvXMLUnitConverter::convertB3DVector(sStringBuffer, aVUP);
3680  aStr = sStringBuffer.makeStringAndClear();
3682  }
3683 
3684  // projection "D3DScenePerspective" drawing::ProjectionMode
3685  aAny = xPropSet->getPropertyValue("D3DScenePerspective");
3686  drawing::ProjectionMode aPrjMode;
3687  aAny >>= aPrjMode;
3688  if(aPrjMode == drawing::ProjectionMode_PARALLEL)
3689  aStr = GetXMLToken(XML_PARALLEL);
3690  else
3691  aStr = GetXMLToken(XML_PERSPECTIVE);
3693 
3694  // distance
3695  aAny = xPropSet->getPropertyValue("D3DSceneDistance");
3696  sal_Int32 nDistance = 0;
3697  aAny >>= nDistance;
3699  nDistance);
3700  aStr = sStringBuffer.makeStringAndClear();
3702 
3703  // focalLength
3704  aAny = xPropSet->getPropertyValue("D3DSceneFocalLength");
3705  sal_Int32 nFocalLength = 0;
3706  aAny >>= nFocalLength;
3708  nFocalLength);
3709  aStr = sStringBuffer.makeStringAndClear();
3711 
3712  // shadowSlant
3713  aAny = xPropSet->getPropertyValue("D3DSceneShadowSlant");
3714  sal_Int16 nShadowSlant = 0;
3715  aAny >>= nShadowSlant;
3716  mrExport.AddAttribute(XML_NAMESPACE_DR3D, XML_SHADOW_SLANT, OUString::number(static_cast<sal_Int32>(nShadowSlant)));
3717 
3718  // shadeMode
3719  aAny = xPropSet->getPropertyValue("D3DSceneShadeMode");
3720  drawing::ShadeMode aShadeMode;
3721  if(aAny >>= aShadeMode)
3722  {
3723  if(aShadeMode == drawing::ShadeMode_FLAT)
3724  aStr = GetXMLToken(XML_FLAT);
3725  else if(aShadeMode == drawing::ShadeMode_PHONG)
3726  aStr = GetXMLToken(XML_PHONG);
3727  else if(aShadeMode == drawing::ShadeMode_SMOOTH)
3728  aStr = GetXMLToken(XML_GOURAUD);
3729  else
3730  aStr = GetXMLToken(XML_DRAFT);
3731  }
3732  else
3733  {
3734  // ShadeMode enum not there, write default
3735  aStr = GetXMLToken(XML_GOURAUD);
3736  }
3738 
3739  // ambientColor
3740  aAny = xPropSet->getPropertyValue("D3DSceneAmbientColor");
3741  sal_Int32 nAmbientColor = 0;
3742  aAny >>= nAmbientColor;
3743  ::sax::Converter::convertColor(sStringBuffer, nAmbientColor);
3744  aStr = sStringBuffer.makeStringAndClear();
3746 
3747  // lightingMode
3748  aAny = xPropSet->getPropertyValue("D3DSceneTwoSidedLighting");
3749  bool bTwoSidedLighting = false;
3750  aAny >>= bTwoSidedLighting;
3751  ::sax::Converter::convertBool(sStringBuffer, bTwoSidedLighting);
3752  aStr = sStringBuffer.makeStringAndClear();
3754 }
3755 
3757 void XMLShapeExport::export3DLamps( const css::uno::Reference< css::beans::XPropertySet >& xPropSet )
3758 {
3759  // write lamps 1..8 as content
3760  OUString aStr;
3761  OUStringBuffer sStringBuffer;
3762 
3763  static const OUStringLiteral aColorPropName(u"D3DSceneLightColor");
3764  static const OUStringLiteral aDirectionPropName(u"D3DSceneLightDirection");
3765  static const OUStringLiteral aLightOnPropName(u"D3DSceneLightOn");
3766 
3767  ::basegfx::B3DVector aLightDirection;
3768  drawing::Direction3D aLightDir;
3769  bool bLightOnOff = false;
3770  for(sal_Int32 nLamp = 1; nLamp <= 8; nLamp++)
3771  {
3772  OUString aIndexStr = OUString::number( nLamp );
3773 
3774  // lightcolor
3775  OUString aPropName = aColorPropName + aIndexStr;
3776  sal_Int32 nLightColor = 0;
3777  xPropSet->getPropertyValue( aPropName ) >>= nLightColor;
3778  ::sax::Converter::convertColor(sStringBuffer, nLightColor);
3779  aStr = sStringBuffer.makeStringAndClear();
3781 
3782  // lightdirection
3783  aPropName = aDirectionPropName + aIndexStr;
3784  xPropSet->getPropertyValue(aPropName) >>= aLightDir;
3785  aLightDirection = ::basegfx::B3DVector(aLightDir.DirectionX, aLightDir.DirectionY, aLightDir.DirectionZ);
3786  SvXMLUnitConverter::convertB3DVector(sStringBuffer, aLightDirection);
3787  aStr = sStringBuffer.makeStringAndClear();
3789 
3790  // lighton
3791  aPropName = aLightOnPropName + aIndexStr;
3792  xPropSet->getPropertyValue(aPropName) >>= bLightOnOff;
3793  ::sax::Converter::convertBool(sStringBuffer, bLightOnOff);
3794  aStr = sStringBuffer.makeStringAndClear();
3796 
3797  // specular
3799  nLamp == 1 ? XML_TRUE : XML_FALSE);
3800 
3801  // write light entry
3803  }
3804 }
3805 
3806 
3807 // using namespace css::io;
3808 // using namespace ::xmloff::EnhancedCustomShapeToken;
3809 
3810 
3811 static void ExportParameter( OUStringBuffer& rStrBuffer, const css::drawing::EnhancedCustomShapeParameter& rParameter )
3812 {
3813  if ( !rStrBuffer.isEmpty() )
3814  rStrBuffer.append( ' ' );
3815  if ( rParameter.Value.getValueTypeClass() == uno::TypeClass_DOUBLE )
3816  {
3817  double fNumber = 0.0;
3818  rParameter.Value >>= fNumber;
3819  ::rtl::math::doubleToUStringBuffer( rStrBuffer, fNumber, rtl_math_StringFormat_Automatic, rtl_math_DecimalPlaces_Max, '.', true );
3820  }
3821  else
3822  {
3823  sal_Int32 nValue = 0;
3824  rParameter.Value >>= nValue;
3825 
3826  switch( rParameter.Type )
3827  {
3828  case css::drawing::EnhancedCustomShapeParameterType::EQUATION :
3829  {
3830  rStrBuffer.append( "?f" + OUString::number( nValue ) );
3831  }
3832  break;
3833 
3834  case css::drawing::EnhancedCustomShapeParameterType::ADJUSTMENT :
3835  {
3836  rStrBuffer.append( '$' );
3837  rStrBuffer.append( nValue );
3838  }
3839  break;
3840 
3841  case css::drawing::EnhancedCustomShapeParameterType::BOTTOM :
3842  rStrBuffer.append( GetXMLToken( XML_BOTTOM ) ); break;
3843  case css::drawing::EnhancedCustomShapeParameterType::RIGHT :
3844  rStrBuffer.append( GetXMLToken( XML_RIGHT ) ); break;
3845  case css::drawing::EnhancedCustomShapeParameterType::TOP :
3846  rStrBuffer.append( GetXMLToken( XML_TOP ) ); break;
3847  case css::drawing::EnhancedCustomShapeParameterType::LEFT :
3848  rStrBuffer.append( GetXMLToken( XML_LEFT ) ); break;
3849  case css::drawing::EnhancedCustomShapeParameterType::XSTRETCH :
3850  rStrBuffer.append( GetXMLToken( XML_XSTRETCH ) ); break;
3851  case css::drawing::EnhancedCustomShapeParameterType::YSTRETCH :
3852  rStrBuffer.append( GetXMLToken( XML_YSTRETCH ) ); break;
3853  case css::drawing::EnhancedCustomShapeParameterType::HASSTROKE :
3854  rStrBuffer.append( GetXMLToken( XML_HASSTROKE ) ); break;
3855  case css::drawing::EnhancedCustomShapeParameterType::HASFILL :
3856  rStrBuffer.append( GetXMLToken( XML_HASFILL ) ); break;
3857  case css::drawing::EnhancedCustomShapeParameterType::WIDTH :
3858  rStrBuffer.append( GetXMLToken( XML_WIDTH ) ); break;
3859  case css::drawing::EnhancedCustomShapeParameterType::HEIGHT :
3860  rStrBuffer.append( GetXMLToken( XML_HEIGHT ) ); break;
3861  case css::drawing::EnhancedCustomShapeParameterType::LOGWIDTH :
3862  rStrBuffer.append( GetXMLToken( XML_LOGWIDTH ) ); break;
3863  case css::drawing::EnhancedCustomShapeParameterType::LOGHEIGHT :
3864  rStrBuffer.append( GetXMLToken( XML_LOGHEIGHT ) ); break;
3865  default :
3866  rStrBuffer.append( nValue );
3867  }
3868  }
3869 }
3870 
3871 static void ImpExportEquations( SvXMLExport& rExport, const uno::Sequence< OUString >& rEquations )
3872 {
3873  sal_Int32 i;
3874  for ( i = 0; i < rEquations.getLength(); i++ )
3875  {
3876  OUString aStr= "f" + OUString::number( i );
3877  rExport.AddAttribute( XML_NAMESPACE_DRAW, XML_NAME, aStr );
3878 
3879  aStr = rEquations[ i ];
3880  sal_Int32 nIndex = 0;
3881  do
3882  {
3883  nIndex = aStr.indexOf( '?', nIndex );
3884  if ( nIndex != -1 )
3885  {
3886  aStr = OUString::Concat(aStr.subView(0, nIndex + 1)) + "f"
3887  + aStr.subView(nIndex + 1, aStr.getLength() - nIndex - 1);
3888  nIndex++;
3889  }
3890  } while( nIndex != -1 );
3891  rExport.AddAttribute( XML_NAMESPACE_DRAW, XML_FORMULA, aStr );
3892  SvXMLElementExport aOBJ( rExport, XML_NAMESPACE_DRAW, XML_EQUATION, true, true );
3893  }
3894 }
3895 
3896 static void ImpExportHandles( SvXMLExport& rExport, const uno::Sequence< beans::PropertyValues >& rHandles )
3897 {
3898  if ( !rHandles.hasElements() )
3899  return;
3900 
3901  OUString aStr;
3902  OUStringBuffer aStrBuffer;
3903 
3904  for ( const uno::Sequence< beans::PropertyValue >& rPropSeq : rHandles )
3905  {
3906  bool bPosition = false;
3907  for ( const beans::PropertyValue& rPropVal : rPropSeq )
3908  {
3909  switch( EASGet( rPropVal.Name ) )
3910  {
3911  case EAS_Position :
3912  {
3913  css::drawing::EnhancedCustomShapeParameterPair aPosition;
3914  if ( rPropVal.Value >>= aPosition )
3915  {
3916  ExportParameter( aStrBuffer, aPosition.First );
3917  ExportParameter( aStrBuffer, aPosition.Second );
3918  aStr = aStrBuffer.makeStringAndClear();
3920  bPosition = true;
3921  }
3922  }
3923  break;
3924  case EAS_MirroredX :
3925  {
3926  bool bMirroredX;
3927  if ( rPropVal.Value >>= bMirroredX )
3929  bMirroredX ? GetXMLToken( XML_TRUE ) : GetXMLToken( XML_FALSE ) );
3930  }
3931  break;
3932  case EAS_MirroredY :
3933  {
3934  bool bMirroredY;
3935  if ( rPropVal.Value >>= bMirroredY )
3937  bMirroredY ? GetXMLToken( XML_TRUE ) : GetXMLToken( XML_FALSE ) );
3938  }
3939  break;
3940  case EAS_Switched :
3941  {
3942  bool bSwitched;
3943  if ( rPropVal.Value >>= bSwitched )
3945  bSwitched ? GetXMLToken( XML_TRUE ) : GetXMLToken( XML_FALSE ) );
3946  }
3947  break;
3948  case EAS_Polar :
3949  {
3950  css::drawing::EnhancedCustomShapeParameterPair aPolar;
3951  if ( rPropVal.Value >>= aPolar )
3952  {
3953  ExportParameter( aStrBuffer, aPolar.First );
3954  ExportParameter( aStrBuffer, aPolar.Second );
3955  aStr = aStrBuffer.makeStringAndClear();
3957  }
3958  }
3959  break;
3960  case EAS_RadiusRangeMinimum :
3961  {
3962  css::drawing::EnhancedCustomShapeParameter aRadiusRangeMinimum;
3963  if ( rPropVal.Value >>= aRadiusRangeMinimum )
3964  {
3965  ExportParameter( aStrBuffer, aRadiusRangeMinimum );
3966  aStr = aStrBuffer.makeStringAndClear();
3968  }
3969  }
3970  break;
3971  case EAS_RadiusRangeMaximum :
3972  {
3973  css::drawing::EnhancedCustomShapeParameter aRadiusRangeMaximum;
3974  if ( rPropVal.Value >>= aRadiusRangeMaximum )
3975  {
3976  ExportParameter( aStrBuffer, aRadiusRangeMaximum );
3977  aStr = aStrBuffer.makeStringAndClear();
3979  }
3980  }
3981  break;
3982  case EAS_RangeXMinimum :
3983  {
3984  css::drawing::EnhancedCustomShapeParameter aXRangeMinimum;
3985  if ( rPropVal.Value >>= aXRangeMinimum )
3986  {
3987  ExportParameter( aStrBuffer, aXRangeMinimum );
3988  aStr = aStrBuffer.makeStringAndClear();
3990  }
3991  }
3992  break;
3993  case EAS_RangeXMaximum :
3994  {
3995  css::drawing::EnhancedCustomShapeParameter aXRangeMaximum;
3996  if ( rPropVal.Value >>= aXRangeMaximum )
3997  {
3998  ExportParameter( aStrBuffer, aXRangeMaximum );
3999  aStr = aStrBuffer.makeStringAndClear();
4001  }
4002  }
4003  break;
4004  case EAS_RangeYMinimum :
4005  {
4006  css::drawing::EnhancedCustomShapeParameter aYRangeMinimum;
4007  if ( rPropVal.Value >>= aYRangeMinimum )
4008  {
4009  ExportParameter( aStrBuffer, aYRangeMinimum );
4010  aStr = aStrBuffer.makeStringAndClear();
4012  }
4013  }
4014  break;
4015  case EAS_RangeYMaximum :
4016  {
4017  css::drawing::EnhancedCustomShapeParameter aYRangeMaximum;
4018  if ( rPropVal.Value >>= aYRangeMaximum )
4019  {
4020  ExportParameter( aStrBuffer, aYRangeMaximum );
4021  aStr = aStrBuffer.makeStringAndClear();
4023  }
4024  }
4025  break;
4026  default:
4027  break;
4028  }
4029  }
4030  if ( bPosition )
4031  SvXMLElementExport aOBJ( rExport, XML_NAMESPACE_DRAW, XML_HANDLE, true, true );
4032  else
4033  rExport.ClearAttrList();
4034  }
4035 }
4036 
4037 static void ImpExportEnhancedPath( SvXMLExport& rExport,
4038  const uno::Sequence< css::drawing::EnhancedCustomShapeParameterPair >& rCoordinates,
4039  const uno::Sequence< css::drawing::EnhancedCustomShapeSegment >& rSegments,
4040  bool bExtended = false )
4041 {
4042 
4043  OUString aStr;
4044  OUStringBuffer aStrBuffer;
4045  bool bNeedExtended = false;
4046 
4047  sal_Int32 i, j, k, l;
4048 
4049  sal_Int32 nCoords = rCoordinates.getLength();
4050  sal_Int32 nSegments = rSegments.getLength();
4051  bool bSimpleSegments = nSegments == 0;
4052  if ( bSimpleSegments )
4053  nSegments = 4;
4054  for ( j = i = 0; j < nSegments; j++ )
4055  {
4056  css::drawing::EnhancedCustomShapeSegment aSegment;
4057  if ( bSimpleSegments )
4058  {
4059  // if there are not enough segments we will default them
4060  switch( j )
4061  {
4062  case 0 :
4063  {
4064  aSegment.Count = 1;
4065  aSegment.Command = css::drawing::EnhancedCustomShapeSegmentCommand::MOVETO;
4066  }
4067  break;
4068  case 1 :
4069  {
4070  aSegment.Count = static_cast<sal_Int16>(std::min( nCoords - 1, sal_Int32(32767) ));
4071  aSegment.Command = css::drawing::EnhancedCustomShapeSegmentCommand::LINETO;
4072  }
4073  break;
4074  case 2 :
4075  {
4076  aSegment.Count = 1;
4077  aSegment.Command = css::drawing::EnhancedCustomShapeSegmentCommand::CLOSESUBPATH;
4078  }
4079  break;
4080  case 3 :
4081  {
4082  aSegment.Count = 1;
4083  aSegment.Command = css::drawing::EnhancedCustomShapeSegmentCommand::ENDSUBPATH;
4084  }
4085  break;
4086  }
4087  }
4088  else
4089  aSegment = rSegments[ j ];
4090 
4091  if ( !aStrBuffer.isEmpty() )
4092  aStrBuffer.append( ' ' );
4093 
4094  sal_Int32 nParameter = 0;
4095  switch( aSegment.Command )
4096  {
4097  case css::drawing::EnhancedCustomShapeSegmentCommand::CLOSESUBPATH :
4098  aStrBuffer.append( 'Z' ); break;
4099  case css::drawing::EnhancedCustomShapeSegmentCommand::ENDSUBPATH :
4100  aStrBuffer.append( 'N' ); break;
4101  case css::drawing::EnhancedCustomShapeSegmentCommand::NOFILL :
4102  aStrBuffer.append( 'F' ); break;
4103  case css::drawing::EnhancedCustomShapeSegmentCommand::NOSTROKE :
4104  aStrBuffer.append( 'S' ); break;
4105 
4106  case css::drawing::EnhancedCustomShapeSegmentCommand::MOVETO :
4107  aStrBuffer.append( 'M' ); nParameter = 1; break;
4108  case css::drawing::EnhancedCustomShapeSegmentCommand::LINETO :
4109  aStrBuffer.append( 'L' ); nParameter = 1; break;
4110  case css::drawing::EnhancedCustomShapeSegmentCommand::CURVETO :
4111  aStrBuffer.append( 'C' ); nParameter = 3; break;
4112  case css::drawing::EnhancedCustomShapeSegmentCommand::ANGLEELLIPSETO :
4113  aStrBuffer.append( 'T' ); nParameter = 3; break;
4114  case css::drawing::EnhancedCustomShapeSegmentCommand::ANGLEELLIPSE :
4115  aStrBuffer.append( 'U' ); nParameter = 3; break;
4116  case css::drawing::EnhancedCustomShapeSegmentCommand::ARCTO :
4117  aStrBuffer.append( 'A' ); nParameter = 4; break;
4118  case css::drawing::EnhancedCustomShapeSegmentCommand::ARC :
4119  aStrBuffer.append( 'B' ); nParameter = 4; break;
4120  case css::drawing::EnhancedCustomShapeSegmentCommand::CLOCKWISEARCTO :
4121  aStrBuffer.append( 'W' ); nParameter = 4; break;
4122  case css::drawing::EnhancedCustomShapeSegmentCommand::CLOCKWISEARC :
4123  aStrBuffer.append( 'V' ); nParameter = 4; break;
4124  case css::drawing::EnhancedCustomShapeSegmentCommand::ELLIPTICALQUADRANTX :
4125  aStrBuffer.append( 'X' ); nParameter = 1; break;
4126  case css::drawing::EnhancedCustomShapeSegmentCommand::ELLIPTICALQUADRANTY :
4127  aStrBuffer.append( 'Y' ); nParameter = 1; break;
4128  case css::drawing::EnhancedCustomShapeSegmentCommand::QUADRATICCURVETO :
4129  aStrBuffer.append( 'Q' ); nParameter = 2; break;
4130  case css::drawing::EnhancedCustomShapeSegmentCommand::ARCANGLETO :
4131  if ( bExtended ) {
4132  aStrBuffer.append( 'G' );
4133  nParameter = 2;
4134  } else {
4135  aStrBuffer.setLength( aStrBuffer.getLength() - 1);
4136  bNeedExtended = true;
4137  i += 2;
4138  }
4139  break;
4140  case css::drawing::EnhancedCustomShapeSegmentCommand::DARKEN :
4141  if ( bExtended )
4142  aStrBuffer.append( 'H' );
4143  else
4144  bNeedExtended = true;
4145  break;
4146  case css::drawing::EnhancedCustomShapeSegmentCommand::DARKENLESS :
4147  if ( bExtended )
4148  aStrBuffer.append( 'I' );
4149  else
4150  bNeedExtended = true;
4151  break;
4152  case css::drawing::EnhancedCustomShapeSegmentCommand::LIGHTEN :
4153  if ( bExtended )
4154  aStrBuffer.append( 'J' );
4155  else
4156  bNeedExtended = true;
4157  break;
4158  case css::drawing::EnhancedCustomShapeSegmentCommand::LIGHTENLESS :
4159  if ( bExtended )
4160  aStrBuffer.append( 'K' );
4161  else
4162  bNeedExtended = true;
4163  break;
4164  default : // ups, seems to be something wrong
4165  {
4166  aSegment.Count = 1;
4167  aSegment.Command = css::drawing::EnhancedCustomShapeSegmentCommand::LINETO;
4168  }
4169  break;
4170  }
4171  if ( nParameter )
4172  {
4173  for ( k = 0; k < aSegment.Count; k++ )
4174  {
4175  if ( ( i + nParameter ) <= nCoords )
4176  {
4177  for ( l = 0; l < nParameter; l++ )
4178  {
4179  ExportParameter( aStrBuffer, rCoordinates[ i ].First );
4180  ExportParameter( aStrBuffer, rCoordinates[ i++ ].Second );
4181  }
4182  }
4183  else
4184  {
4185  j = nSegments; // error -> exiting
4186  break;
4187  }
4188  }
4189  }
4190  }
4191  aStr = aStrBuffer.makeStringAndClear();
4193  if (!bExtended && bNeedExtended && (rExport.getSaneDefaultVersion() & SvtSaveOptions::ODFSVER_EXTENDED))
4194  ImpExportEnhancedPath( rExport, rCoordinates, rSegments, true );
4195 }
4196 
4197 static void ImpExportEnhancedGeometry( SvXMLExport& rExport, const uno::Reference< beans::XPropertySet >& xPropSet )
4198 {
4199  bool bEquations = false;
4200  uno::Sequence< OUString > aEquations;
4201 
4202  bool bHandles = false;
4203  uno::Sequence< beans::PropertyValues > aHandles;
4204 
4205  uno::Sequence< css::drawing::EnhancedCustomShapeSegment > aSegments;
4206  uno::Sequence< css::drawing::EnhancedCustomShapeParameterPair > aCoordinates;
4207 
4208  uno::Sequence< css::drawing::EnhancedCustomShapeAdjustmentValue > aAdjustmentValues;
4209 
4210  OUString aStr;
4211  OUStringBuffer aStrBuffer;
4212  SvXMLUnitConverter& rUnitConverter = rExport.GetMM100UnitConverter();
4213 
4214  uno::Reference< beans::XPropertySetInfo > xPropSetInfo( xPropSet->getPropertySetInfo() );
4215 
4216  // geometry
4217  static const OUStringLiteral sCustomShapeGeometry( u"CustomShapeGeometry" );
4218  if ( xPropSetInfo.is() && xPropSetInfo->hasPropertyByName( sCustomShapeGeometry ) )
4219  {
4220  uno::Any aGeoPropSet( xPropSet->getPropertyValue( sCustomShapeGeometry ) );
4221  uno::Sequence< beans::PropertyValue > aGeoPropSeq;
4222 
4223  if ( aGeoPropSet >>= aGeoPropSeq )
4224  {
4225  bool bCoordinates = false;
4226  OUString aCustomShapeType( "non-primitive" );
4227 
4228  for ( const beans::PropertyValue& rGeoProp : std::as_const(aGeoPropSeq) )
4229  {
4230  switch( EASGet( rGeoProp.Name ) )
4231  {
4232  case EAS_Type :
4233  {
4234  rGeoProp.Value >>= aCustomShapeType;
4235  }
4236  break;
4237  case EAS_MirroredX :
4238  {
4239  bool bMirroredX;
4240  if ( rGeoProp.Value >>= bMirroredX )
4242  bMirroredX ? GetXMLToken( XML_TRUE ) : GetXMLToken( XML_FALSE ) );
4243  }
4244  break;
4245  case EAS_MirroredY :
4246  {
4247  bool bMirroredY;
4248  if ( rGeoProp.Value >>= bMirroredY )
4250  bMirroredY ? GetXMLToken( XML_TRUE ) : GetXMLToken( XML_FALSE ) );
4251  }
4252  break;
4253  case EAS_ViewBox :
4254  {
4255  awt::Rectangle aRect;
4256  if ( rGeoProp.Value >>= aRect )
4257  {
4258  SdXMLImExViewBox aViewBox( aRect.X, aRect.Y, aRect.Width, aRect.Height );
4260  }
4261  }
4262  break;
4263  case EAS_TextPreRotateAngle :
4264  case EAS_TextRotateAngle :
4265  {
4266  double fTextRotateAngle = 0;
4267  if ( ( rGeoProp.Value >>= fTextRotateAngle ) && fTextRotateAngle != 0 )
4268  {
4270  aStrBuffer, fTextRotateAngle );
4271  aStr = aStrBuffer.makeStringAndClear();
4273  }
4274  }
4275  break;
4276  case EAS_Extrusion :
4277  {
4278  uno::Sequence< beans::PropertyValue > aExtrusionPropSeq;
4279  if ( rGeoProp.Value >>= aExtrusionPropSeq )
4280  {
4281  for ( const beans::PropertyValue& rProp : std::as_const(aExtrusionPropSeq) )
4282  {
4283  switch( EASGet( rProp.Name ) )
4284  {
4285  case EAS_Extrusion :
4286  {
4287  bool bExtrusionOn;
4288  if ( rProp.Value >>= bExtrusionOn )
4290  bExtrusionOn ? GetXMLToken( XML_TRUE ) : GetXMLToken( XML_FALSE ) );
4291  }
4292  break;
4293  case EAS_Brightness :
4294  {
4295  double fExtrusionBrightness = 0;
4296  if ( rProp.Value >>= fExtrusionBrightness )
4297  {
4299  aStrBuffer,
4300  fExtrusionBrightness,
4301  false,
4302  util::MeasureUnit::PERCENT,
4303  util::MeasureUnit::PERCENT);
4304  aStrBuffer.append( '%' );
4305  aStr = aStrBuffer.makeStringAndClear();
4307  }
4308  }
4309  break;
4310  case EAS_Depth :
4311  {
4312  css::drawing::EnhancedCustomShapeParameterPair aDepthParaPair;
4313  if ( rProp.Value >>= aDepthParaPair )
4314  {
4315  double fDepth = 0;
4316  if ( aDepthParaPair.First.Value >>= fDepth )
4317  {
4318  rExport.GetMM100UnitConverter().convertDouble( aStrBuffer, fDepth );
4319  ExportParameter( aStrBuffer, aDepthParaPair.Second );
4320  aStr = aStrBuffer.makeStringAndClear();
4322  }
4323  }
4324  }
4325  break;
4326  case EAS_Diffusion :
4327  {
4328  double fExtrusionDiffusion = 0;
4329  if ( rProp.Value >>= fExtrusionDiffusion )
4330  {
4332  aStrBuffer,
4333  fExtrusionDiffusion,
4334  false,
4335  util::MeasureUnit::PERCENT,
4336  util::MeasureUnit::PERCENT);
4337  aStrBuffer.append( '%' );
4338  aStr = aStrBuffer.makeStringAndClear();
4340  }
4341  }
4342  break;
4344  {
4345  sal_Int32 nExtrusionNumberOfLineSegments = 0;
4346  if ( rProp.Value >>= nExtrusionNumberOfLineSegments )
4347  rExport.AddAttribute( XML_NAMESPACE_DRAW, XML_EXTRUSION_NUMBER_OF_LINE_SEGMENTS, OUString::number( nExtrusionNumberOfLineSegments ) );
4348  }
4349  break;
4350  case EAS_LightFace :
4351  {
4352  bool bExtrusionLightFace;
4353  if ( rProp.Value >>= bExtrusionLightFace )
4355  bExtrusionLightFace ? GetXMLToken( XML_TRUE ) : GetXMLToken( XML_FALSE ) );
4356  }
4357  break;
4358  case EAS_FirstLightHarsh :
4359  {
4360  bool bExtrusionFirstLightHarsh;
4361  if ( rProp.Value >>= bExtrusionFirstLightHarsh )
4363  bExtrusionFirstLightHarsh ? GetXMLToken( XML_TRUE ) : GetXMLToken( XML_FALSE ) );
4364  }
4365  break;
4366  case EAS_SecondLightHarsh :
4367  {
4368  bool bExtrusionSecondLightHarsh;
4369  if ( rProp.Value >>= bExtrusionSecondLightHarsh )
4371  bExtrusionSecondLightHarsh ? GetXMLToken( XML_TRUE ) : GetXMLToken( XML_FALSE ) );
4372  }
4373  break;
4374  case EAS_FirstLightLevel :
4375  {
4376  double fExtrusionFirstLightLevel = 0;
4377  if ( rProp.Value >>= fExtrusionFirstLightLevel )
4378  {
4380  aStrBuffer,
4381  fExtrusionFirstLightLevel,
4382  false,
4383  util::MeasureUnit::PERCENT,
4384  util::MeasureUnit::PERCENT);
4385  aStrBuffer.append( '%' );
4386  aStr = aStrBuffer.makeStringAndClear();
4388  }
4389  }
4390  break;
4391  case EAS_SecondLightLevel :
4392  {
4393  double fExtrusionSecondLightLevel = 0;
4394  if ( rProp.Value >>= fExtrusionSecondLightLevel )
4395  {
4397  aStrBuffer,
4398  fExtrusionSecondLightLevel,
4399  false,
4400  util::MeasureUnit::PERCENT,
4401  util::MeasureUnit::PERCENT);
4402  aStrBuffer.append( '%' );
4403  aStr = aStrBuffer.makeStringAndClear();
4405  }
4406  }
4407  break;
4409  {
4410  drawing::Direction3D aExtrusionFirstLightDirection;
4411  if ( rProp.Value >>= aExtrusionFirstLightDirection )
4412  {
4413  ::basegfx::B3DVector aVec3D( aExtrusionFirstLightDirection.DirectionX, aExtrusionFirstLightDirection.DirectionY,
4414  aExtrusionFirstLightDirection.DirectionZ );
4415  SvXMLUnitConverter::convertB3DVector( aStrBuffer, aVec3D );
4416  aStr = aStrBuffer.makeStringAndClear();
4418  }
4419  }
4420  break;
4422  {
4423  drawing::Direction3D aExtrusionSecondLightDirection;
4424  if ( rProp.Value >>= aExtrusionSecondLightDirection )
4425  {
4426  ::basegfx::B3DVector aVec3D( aExtrusionSecondLightDirection.DirectionX, aExtrusionSecondLightDirection.DirectionY,
4427  aExtrusionSecondLightDirection.DirectionZ );
4428  SvXMLUnitConverter::convertB3DVector( aStrBuffer, aVec3D );
4429  aStr = aStrBuffer.makeStringAndClear();
4431  }
4432  }
4433  break;
4434  case EAS_Metal :
4435  {
4436  bool bExtrusionMetal;
4437  if ( rProp.Value >>= bExtrusionMetal )
4439  bExtrusionMetal ? GetXMLToken( XML_TRUE ) : GetXMLToken( XML_FALSE ) );
4440  }
4441  break;
4442  case EAS_ShadeMode :
4443  {
4444  // shadeMode
4445  drawing::ShadeMode eShadeMode;
4446  if( rProp.Value >>= eShadeMode )
4447  {
4448  if( eShadeMode == drawing::ShadeMode_FLAT )
4449  aStr = GetXMLToken( XML_FLAT );
4450  else if( eShadeMode == drawing::ShadeMode_PHONG )
4451  aStr = GetXMLToken( XML_PHONG );
4452  else if( eShadeMode == drawing::ShadeMode_SMOOTH )
4453  aStr = GetXMLToken( XML_GOURAUD );
4454  else
4455  aStr = GetXMLToken( XML_DRAFT );
4456  }
4457  else
4458  {
4459  // ShadeMode enum not there, write default
4460  aStr = GetXMLToken( XML_FLAT);
4461  }
4463  }
4464  break;
4465  case EAS_RotateAngle :
4466  {
4467  css::drawing::EnhancedCustomShapeParameterPair aRotateAngleParaPair;
4468  if ( rProp.Value >>= aRotateAngleParaPair )
4469  {
4470  ExportParameter( aStrBuffer, aRotateAngleParaPair.First );
4471  ExportParameter( aStrBuffer, aRotateAngleParaPair.Second );
4472  aStr = aStrBuffer.makeStringAndClear();
4474  }
4475  }
4476  break;
4477  case EAS_RotationCenter :
4478  {
4479  drawing::Direction3D aExtrusionRotationCenter;
4480  if ( rProp.Value >>= aExtrusionRotationCenter )
4481  {
4482  ::basegfx::B3DVector aVec3D( aExtrusionRotationCenter.DirectionX, aExtrusionRotationCenter.DirectionY,
4483  aExtrusionRotationCenter.DirectionZ );
4484  SvXMLUnitConverter::convertB3DVector( aStrBuffer, aVec3D );
4485  aStr = aStrBuffer.makeStringAndClear();
4487  }
4488  }
4489  break;
4490  case EAS_Shininess :
4491  {
4492  double fExtrusionShininess = 0;
4493  if ( rProp.Value >>= fExtrusionShininess )
4494  {
4496  aStrBuffer,
4497  fExtrusionShininess,
4498  false,
4499  util::MeasureUnit::PERCENT,
4500  util::MeasureUnit::PERCENT);
4501  aStrBuffer.append( '%' );
4502  aStr = aStrBuffer.makeStringAndClear();
4504  }
4505  }
4506  break;
4507  case EAS_Skew :
4508  {
4509  css::drawing::EnhancedCustomShapeParameterPair aSkewParaPair;
4510  if ( rProp.Value >>= aSkewParaPair )
4511  {
4512  ExportParameter( aStrBuffer, aSkewParaPair.First );
4513  ExportParameter( aStrBuffer, aSkewParaPair.Second );
4514  aStr = aStrBuffer.makeStringAndClear();
4516  }
4517  }
4518  break;
4519  case EAS_Specularity :
4520  {
4521  double fExtrusionSpecularity = 0;
4522  if ( rProp.Value >>= fExtrusionSpecularity )
4523  {
4525  aStrBuffer,
4526  fExtrusionSpecularity,
4527  false,
4528  util::MeasureUnit::PERCENT,
4529  util::MeasureUnit::PERCENT);
4530  aStrBuffer.append( '%' );
4531  aStr = aStrBuffer.makeStringAndClear();
4533  }
4534  }
4535  break;
4536  case EAS_ProjectionMode :
4537  {
4538  drawing::ProjectionMode eProjectionMode;
4539  if ( rProp.Value >>= eProjectionMode )
4541  eProjectionMode == drawing::ProjectionMode_PARALLEL ? GetXMLToken( XML_PARALLEL ) : GetXMLToken( XML_PERSPECTIVE ) );
4542  }
4543  break;
4544  case EAS_ViewPoint :
4545  {
4546  drawing::Position3D aExtrusionViewPoint;
4547  if ( rProp.Value >>= aExtrusionViewPoint )
4548  {
4549  rUnitConverter.convertPosition3D( aStrBuffer, aExtrusionViewPoint );
4550  aStr = aStrBuffer.makeStringAndClear();
4552  }
4553  }
4554  break;
4555  case EAS_Origin :
4556  {
4557  css::drawing::EnhancedCustomShapeParameterPair aOriginParaPair;
4558  if ( rProp.Value >>= aOriginParaPair )
4559  {
4560  ExportParameter( aStrBuffer, aOriginParaPair.First );
4561  ExportParameter( aStrBuffer, aOriginParaPair.Second );
4562  aStr = aStrBuffer.makeStringAndClear();
4564  }
4565  }
4566  break;
4567  case EAS_Color :
4568  {
4569  bool bExtrusionColor;
4570  if ( rProp.Value >>= bExtrusionColor )
4571  {
4573  bExtrusionColor ? GetXMLToken( XML_TRUE ) : GetXMLToken( XML_FALSE ) );
4574  }
4575  }
4576  break;
4577  default:
4578  break;
4579  }
4580  }
4581  }
4582  }
4583  break;
4584  case EAS_TextPath :
4585  {
4586  uno::Sequence< beans::PropertyValue > aTextPathPropSeq;
4587  if ( rGeoProp.Value >>= aTextPathPropSeq )
4588  {
4589  for ( const beans::PropertyValue& rProp : std::as_const(aTextPathPropSeq) )
4590  {
4591  switch( EASGet( rProp.Name ) )
4592  {
4593  case EAS_TextPath :
4594  {
4595  bool bTextPathOn;
4596  if ( rProp.Value >>= bTextPathOn )
4598  bTextPathOn ? GetXMLToken( XML_TRUE ) : GetXMLToken( XML_FALSE ) );
4599  }
4600  break;
4601  case EAS_TextPathMode :
4602  {
4603  css::drawing::EnhancedCustomShapeTextPathMode eTextPathMode;
4604  if ( rProp.Value >>= eTextPathMode )
4605  {
4606  switch ( eTextPathMode )
4607  {
4608  case css::drawing::EnhancedCustomShapeTextPathMode_NORMAL: aStr = GetXMLToken( XML_NORMAL ); break;
4609  case css::drawing::EnhancedCustomShapeTextPathMode_PATH : aStr = GetXMLToken( XML_PATH ); break;
4610  case css::drawing::EnhancedCustomShapeTextPathMode_SHAPE : aStr = GetXMLToken( XML_SHAPE ); break;
4611  default:
4612  break;
4613  }
4614  if ( !aStr.isEmpty() )
4616  }
4617  }
4618  break;
4619  case EAS_ScaleX :
4620  {
4621  bool bScaleX;
4622  if ( rProp.Value >>= bScaleX )
4623  {
4624  aStr = bScaleX ? GetXMLToken( XML_SHAPE ) : GetXMLToken( XML_PATH );
4626  }
4627  }
4628  break;
4629  case EAS_SameLetterHeights :
4630  {
4631  bool bSameLetterHeights;
4632  if ( rProp.Value >>= bSameLetterHeights )
4634  bSameLetterHeights ? GetXMLToken( XML_TRUE ) : GetXMLToken( XML_FALSE ) );
4635  }
4636  break;
4637  default:
4638  break;
4639  }
4640  }
4641  }
4642  }
4643  break;
4644  case EAS_Path :
4645  {
4646  uno::Sequence< beans::PropertyValue > aPathPropSeq;
4647  if ( rGeoProp.Value >>= aPathPropSeq )
4648  {
4649  for ( const beans::PropertyValue& rProp : std::as_const(aPathPropSeq) )
4650  {
4651  switch( EASGet( rProp.Name ) )
4652  {
4653  case EAS_SubViewSize:
4654  {
4655  // export draw:sub-view-size (do not export in ODF 1.3 or older)
4657  {
4658  continue;
4659  }
4660  uno::Sequence< awt::Size > aSubViewSizes;
4661  rProp.Value >>= aSubViewSizes;
4662 
4663  for ( int nIdx = 0; nIdx < aSubViewSizes.getLength(); nIdx++ )
4664  {
4665  if ( nIdx )
4666  aStrBuffer.append(' ');
4667  aStrBuffer.append( aSubViewSizes[nIdx].Width );
4668  aStrBuffer.append(' ');
4669  aStrBuffer.append( aSubViewSizes[nIdx].Height );
4670  }
4671  aStr = aStrBuffer.makeStringAndClear();
4673  }
4674  break;
4675  case EAS_ExtrusionAllowed :
4676  {
4677  bool bExtrusionAllowed;
4678  if ( rProp.Value >>= bExtrusionAllowed )
4680  bExtrusionAllowed ? GetXMLToken( XML_TRUE ) : GetXMLToken( XML_FALSE ) );
4681  }
4682  break;
4684  {
4685  bool bConcentricGradientFillAllowed;
4686  if ( rProp.Value >>= bConcentricGradientFillAllowed )
4688  bConcentricGradientFillAllowed ? GetXMLToken( XML_TRUE ) : GetXMLToken( XML_FALSE ) );
4689  }
4690  break;
4691  case EAS_TextPathAllowed :
4692  {
4693  bool bTextPathAllowed;
4694  if ( rProp.Value >>= bTextPathAllowed )
4696  bTextPathAllowed ? GetXMLToken( XML_TRUE ) : GetXMLToken( XML_FALSE ) );
4697  }
4698  break;
4699  case EAS_GluePoints :
4700  {
4701  css::uno::Sequence< css::drawing::EnhancedCustomShapeParameterPair> aGluePoints;
4702  if ( rProp.Value >>= aGluePoints )
4703  {
4704  if ( aGluePoints.hasElements() )
4705  {
4706  for( const auto& rGluePoint : std::as_const(aGluePoints) )
4707  {
4708  ExportParameter( aStrBuffer, rGluePoint.First );
4709  ExportParameter( aStrBuffer, rGluePoint.Second );
4710  }
4711  aStr = aStrBuffer.makeStringAndClear();
4712  }
4714  }
4715  }
4716  break;
4717  case EAS_GluePointType :
4718  {
4719  sal_Int16 nGluePointType = sal_Int16();
4720  if ( rProp.Value >>= nGluePointType )
4721  {
4722  switch ( nGluePointType )
4723  {
4724  case css::drawing::EnhancedCustomShapeGluePointType::NONE : aStr = GetXMLToken( XML_NONE ); break;
4725  case css::drawing::EnhancedCustomShapeGluePointType::SEGMENTS : aStr = GetXMLToken( XML_SEGMENTS ); break;
4726  case css::drawing::EnhancedCustomShapeGluePointType::RECT : aStr = GetXMLToken( XML_RECTANGLE ); break;
4727  }
4728  if ( !aStr.isEmpty() )
4730  }
4731  }
4732  break;
4733  case EAS_Coordinates :
4734  {
4735  bCoordinates = ( rProp.Value >>= aCoordinates );
4736  }
4737  break;
4738  case EAS_Segments :
4739  {
4740  rProp.Value >>= aSegments;
4741  }
4742  break;
4743  case EAS_StretchX :
4744  {
4745  sal_Int32 nStretchPoint = 0;
4746  if ( rProp.Value >>= nStretchPoint )
4747  rExport.AddAttribute( XML_NAMESPACE_DRAW, XML_PATH_STRETCHPOINT_X, OUString::number( nStretchPoint ) );
4748  }
4749  break;
4750  case EAS_StretchY :
4751  {
4752  sal_Int32 nStretchPoint = 0;
4753  if ( rProp.Value >>= nStretchPoint )
4754  rExport.AddAttribute( XML_NAMESPACE_DRAW, XML_PATH_STRETCHPOINT_Y, OUString::number( nStretchPoint ) );
4755  }
4756  break;
4757  case EAS_TextFrames :
4758  {
4759  css::uno::Sequence< css::drawing::EnhancedCustomShapeTextFrame > aPathTextFrames;
4760  if ( rProp.Value >>= aPathTextFrames )
4761  {
4762  if ( aPathTextFrames.hasElements() )
4763  {
4764  for ( const auto& rPathTextFrame : std::as_const(aPathTextFrames) )
4765  {
4766  ExportParameter( aStrBuffer, rPathTextFrame.TopLeft.First );
4767  ExportParameter( aStrBuffer, rPathTextFrame.TopLeft.Second );
4768  ExportParameter( aStrBuffer, rPathTextFrame.BottomRight.First );
4769  ExportParameter( aStrBuffer, rPathTextFrame.BottomRight.Second );
4770  }
4771  aStr = aStrBuffer.makeStringAndClear();
4772  }
4774  }
4775  }
4776  break;
4777  default:
4778  break;
4779  }
4780  }
4781  }
4782  }
4783  break;
4784  case EAS_Equations :
4785  {
4786  bEquations = ( rGeoProp.Value >>= aEquations );
4787  }
4788  break;
4789  case EAS_Handles :
4790  {
4791  bHandles = ( rGeoProp.Value >>= aHandles );
4792  }
4793  break;
4794  case EAS_AdjustmentValues :
4795  {
4796  rGeoProp.Value >>= aAdjustmentValues;
4797  }
4798  break;
4799  default:
4800  break;
4801  }
4802  } // for
4803  rExport.AddAttribute( XML_NAMESPACE_DRAW, XML_TYPE, aCustomShapeType );
4804 
4805  // adjustments
4806  sal_Int32 nAdjustmentValues = aAdjustmentValues.getLength();
4807  if ( nAdjustmentValues )
4808  {
4809  sal_Int32 i, nValue = 0;
4810  for ( i = 0; i < nAdjustmentValues; i++ )
4811  {
4812  if ( i )
4813  aStrBuffer.append( ' ' );
4814 
4815  const css::drawing::EnhancedCustomShapeAdjustmentValue& rAdj = aAdjustmentValues[ i ];
4816  if ( rAdj.State == beans::PropertyState_DIRECT_VALUE )
4817  {
4818  if ( rAdj.Value.getValueTypeClass() == uno::TypeClass_DOUBLE )
4819  {
4820  double fValue = 0.0;
4821  rAdj.Value >>= fValue;
4822  ::sax::Converter::convertDouble(aStrBuffer, fValue);
4823  }
4824  else
4825  {
4826  rAdj.Value >>= nValue;
4827  aStrBuffer.append(nValue);
4828  }
4829  }
4830  else
4831  {
4832  // this should not be, but better than setting nothing
4833  aStrBuffer.append("0");
4834  }
4835  }
4836  aStr = aStrBuffer.makeStringAndClear();
4837  rExport.AddAttribute( XML_NAMESPACE_DRAW, XML_MODIFIERS, aStr );
4838  }
4839  if ( bCoordinates )
4840  ImpExportEnhancedPath( rExport, aCoordinates, aSegments );
4841  }
4842  }
4843  SvXMLElementExport aOBJ( rExport, XML_NAMESPACE_DRAW, XML_ENHANCED_GEOMETRY, true, true );
4844  if ( bEquations )
4845  ImpExportEquations( rExport, aEquations );
4846  if ( bHandles )
4847  ImpExportHandles( rExport, aHandles );
4848 }
4849 
4851  const uno::Reference< drawing::XShape >& xShape,
4852  XMLShapeExportFlags nFeatures, css::awt::Point* pRefPoint )
4853 {
4854  const uno::Reference< beans::XPropertySet > xPropSet(xShape, uno::UNO_QUERY);
4855  if ( !xPropSet.is() )
4856  return;
4857 
4858  uno::Reference< beans::XPropertySetInfo > xPropSetInfo( xPropSet->getPropertySetInfo() );
4859 
4860  // Transformation
4861  ImpExportNewTrans( xPropSet, nFeatures, pRefPoint );
4862 
4863  if ( xPropSetInfo.is() )
4864  {
4865  OUString aStr;
4866  if ( xPropSetInfo->hasPropertyByName( "CustomShapeEngine" ) )
4867  {
4868  uno::Any aEngine( xPropSet->getPropertyValue( "CustomShapeEngine" ) );
4869  if ( ( aEngine >>= aStr ) && !aStr.isEmpty() )
4871  }
4872  if ( xPropSetInfo->hasPropertyByName( "CustomShapeData" ) )
4873  {
4874  uno::Any aData( xPropSet->getPropertyValue( "CustomShapeData" ) );
4875  if ( ( aData >>= aStr ) && !aStr.isEmpty() )
4877  }
4878  }
4879  bool bCreateNewline( (nFeatures & XMLShapeExportFlags::NO_WS) == XMLShapeExportFlags::NONE ); // #86116#/#92210#
4880  SvXMLElementExport aOBJ( mrExport, XML_NAMESPACE_DRAW, XML_CUSTOM_SHAPE, bCreateNewline, true );
4881  ImpExportDescription( xShape ); // #i68101#
4882  ImpExportEvents( xShape );
4883  ImpExportGluePoints( xShape );
4884  ImpExportText( xShape );
4885  ImpExportEnhancedGeometry( mrExport, xPropSet );
4886 
4887 }
4888 
4889 void XMLShapeExport::ImpExportTableShape( const uno::Reference< drawing::XShape >& xShape, XmlShapeType eShapeType, XMLShapeExportFlags nFeatures, css::awt::Point* pRefPoint )
4890 {
4891  uno::Reference< beans::XPropertySet > xPropSet(xShape, uno::UNO_QUERY);
4892  uno::Reference< container::XNamed > xNamed(xShape, uno::UNO_QUERY);
4893 
4894  SAL_WARN_IF( !xPropSet.is() || !xNamed.is(), "xmloff", "xmloff::XMLShapeExport::ImpExportTableShape(), table shape is not implementing needed interfaces");
4895  if(!(xPropSet.is() && xNamed.is()))
4896  return;
4897 
4898  try
4899  {
4900  // Transformation
4901  ImpExportNewTrans(xPropSet, nFeatures, pRefPoint);
4902 
4903  bool bIsEmptyPresObj = false;
4904 
4905  // presentation settings
4906  if(eShapeType == XmlShapeTypePresTableShape)
4907  bIsEmptyPresObj = ImpExportPresentationAttributes( xPropSet, GetXMLToken(XML_TABLE) );
4908 
4909  const bool bCreateNewline( (nFeatures & XMLShapeExportFlags::NO_WS) == XMLShapeExportFlags::NONE );
4910  const bool bExportEmbedded(mrExport.getExportFlags() & SvXMLExportFlags::EMBEDDED);
4911 
4912  SvXMLElementExport aElement( mrExport, XML_NAMESPACE_DRAW, XML_FRAME, bCreateNewline, true );
4913 
4914  // do not export in ODF 1.1 or older
4916  {
4917  if( !bIsEmptyPresObj )
4918  {
4919  uno::Reference< container::XNamed > xTemplate( xPropSet->getPropertyValue("TableTemplate"), uno::UNO_QUERY );
4920  if( xTemplate.is() )
4921  {
4922  const OUString sTemplate( xTemplate->getName() );
4923  if( !sTemplate.isEmpty() )
4924  {
4926 
4927  for( const XMLPropertyMapEntry* pEntry = &aXMLTableShapeAttributes[0]; pEntry->msApiName; pEntry++ )
4928  {
4929  try
4930  {
4931  bool bBool = false;
4932  const OUString sAPIPropertyName( pEntry->msApiName, pEntry->nApiNameLength, RTL_TEXTENCODING_ASCII_US );
4933 
4934  xPropSet->getPropertyValue( sAPIPropertyName ) >>= bBool;
4935  if( bBool )
4936  mrExport.AddAttribute(pEntry->mnNameSpace, pEntry->meXMLName, XML_TRUE );
4937  }
4938  catch( uno::Exception& )
4939  {
4940  DBG_UNHANDLED_EXCEPTION("xmloff.draw");
4941  }
4942  }
4943  }
4944  }
4945 
4946  uno::Reference< table::XColumnRowRange > xRange( xPropSet->getPropertyValue( gsModel ), uno::UNO_QUERY_THROW );
4947  GetShapeTableExport()->exportTable( xRange );
4948  }
4949  }
4950 
4951  if( !bIsEmptyPresObj )
4952  {
4953  uno::Reference< graphic::XGraphic > xGraphic( xPropSet->getPropertyValue("ReplacementGraphic"), uno::UNO_QUERY );
4954  if( xGraphic.is() ) try
4955  {
4956  uno::Reference< uno::XComponentContext > xContext = GetExport().getComponentContext();
4957 
4958  uno::Reference< embed::XStorage > xPictureStorage;
4959  uno::Reference< embed::XStorage > xStorage;
4960  uno::Reference< io::XStream > xPictureStream;
4961 
4962  OUString sPictureName;
4963  if( bExportEmbedded )
4964  {
4965  xPictureStream.set( xContext->getServiceManager()->createInstanceWithContext( "com.sun.star.comp.MemoryStream", xContext), uno::UNO_QUERY_THROW );
4966  }
4967  else
4968  {
4969  xStorage.set( GetExport().GetTargetStorage(), uno::UNO_SET_THROW );
4970 
4971  xPictureStorage.set( xStorage->openStorageElement( "Pictures" , ::embed::ElementModes::READWRITE ), uno::UNO_SET_THROW );
4972 
4973  sal_Int32 nIndex = 0;
4974  do
4975  {
4976  sPictureName = "TablePreview" + OUString::number( ++nIndex ) + ".svm";
4977  }
4978  while( xPictureStorage->hasByName( sPictureName ) );
4979 
4980  xPictureStream.set( xPictureStorage->openStreamElement( sPictureName, ::embed::ElementModes::READWRITE ), uno::UNO_SET_THROW );
4981  }
4982 
4983  uno::Reference< graphic::XGraphicProvider > xProvider( graphic::GraphicProvider::create(xContext) );
4984  uno::Sequence< beans::PropertyValue > aArgs( 2 );
4985  aArgs[ 0 ].Name = "MimeType";
4986  aArgs[ 0 ].Value <<= OUString( "image/x-vclgraphic" );
4987  aArgs[ 1 ].Name = "OutputStream";
4988  aArgs[ 1 ].Value <<= xPictureStream->getOutputStream();
4989  xProvider->storeGraphic( xGraphic, aArgs );
4990 
4991  if( xPictureStorage.is() )
4992  {
4993  uno::Reference< embed::XTransactedObject > xTrans( xPictureStorage, uno::UNO_QUERY );
4994  if( xTrans.is() )
4995  xTrans->commit();
4996  }
4997 
4998  if( !bExportEmbedded )
4999  {
5000  OUString sURL = "Pictures/" + sPictureName;
5005  }
5006 
5007  SvXMLElementExport aElem( GetExport(), XML_NAMESPACE_DRAW, XML_IMAGE, false, true );
5008 
5009  if( bExportEmbedded )
5010  {
5011  uno::Reference< io::XSeekableInputStream > xSeekable( xPictureStream, uno::UNO_QUERY_THROW );
5012  xSeekable->seek(0);
5013 
5014  XMLBase64Export aBase64Exp( GetExport() );
5015  aBase64Exp.exportOfficeBinaryDataElement( uno::Reference < io::XInputStream >( xPictureStream, uno::UNO_QUERY_THROW ) );
5016  }
5017  }
5018  catch( uno::Exception const & )
5019  {
5020  DBG_UNHANDLED_EXCEPTION("xmloff.draw");
5021  }
5022  }
5023 
5024  ImpExportEvents( xShape );
5025  ImpExportGluePoints( xShape );
5026  ImpExportDescription( xShape ); // #i68101#
5027  }
5028  catch( uno::Exception const & )
5029  {
5030  DBG_UNHANDLED_EXCEPTION("xmloff.draw");
5031  }
5032 }
5033 
5034 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
css::uno::Reference< css::embed::XStorage > const & GetTargetStorage() const
Definition: xmlexp.cxx:2318
#define SO3_RPTCH_CLASSID
SAL_DLLPRIVATE void ImpExportPolygonShape(const css::uno::Reference< css::drawing::XShape > &xShape, XmlShapeType eShapeType, XMLShapeExportFlags nFeatures=SEF_DEFAULT, css::awt::Point *pRefPoint=nullptr)
double getY() const
constexpr OUStringLiteral gsVerb(u"Verb")
void exportShapes(const css::uno::Reference< css::drawing::XShapes > &xShapes, XMLShapeExportFlags nFeatures=SEF_DEFAULT, css::awt::Point *pRefPoint=nullptr)
static void ExportParameter(OUStringBuffer &rStrBuffer, const css::drawing::EnhancedCustomShapeParameter &rParameter)
constexpr OUStringLiteral gsModel(u"Model")
SAL_DLLPRIVATE void ImpExportCaptionShape(const css::uno::Reference< css::drawing::XShape > &xShape, XMLShapeExportFlags nFeatures=SEF_DEFAULT, css::awt::Point *pRefPoint=nullptr)
sal_Int32 nIndex
bool bVisible
void convertDouble(OUStringBuffer &rBuffer, double fNumber) const
convert double number to string (using ::rtl::math) and DO convert to export MapUnit using meCoreMeas...
Definition: xmluconv.cxx:333
constexpr sal_uInt16 XML_NAMESPACE_OFFICE
rtl::Reference< XMLShapeExport > const & GetShapeExport()
Definition: xmlexp.hxx:574
void AddRotate(double fNew)
Definition: xexptran.cxx:228
void set(sal_uInt16 nRow, sal_uInt16 nColumn, double fValue)
bool NeedsAction() const
Definition: xexptran.hxx:55
SAL_DLLPRIVATE void ImpCalcShapeType(const css::uno::Reference< css::drawing::XShape > &xShape, XmlShapeType &eShapeType)
SAL_DLLPRIVATE bool ImpExportPresentationAttributes(const css::uno::Reference< css::beans::XPropertySet > &xPropSet, const OUString &rClass)
EnhancedCustomShapeTokenEnum EASGet(const OUString &rShapeType)
ShapesInfos maShapesInfos
XmlShapeType
Definition: shapeexport.hxx:70
constexpr sal_uInt16 XML_NAMESPACE_DR3D