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