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, 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  OUString sControlId = mrExport.GetFormExport()->getControlId( xControlModel );
2502  }
2503  }
2504 
2505  bool bCreateNewline( (nFeatures & XMLShapeExportFlags::NO_WS) == XMLShapeExportFlags::NONE ); // #86116#/#92210#
2506  SvXMLElementExport aOBJ(mrExport, XML_NAMESPACE_DRAW, XML_CONTROL, bCreateNewline, true);
2507 
2508  ImpExportDescription( xShape ); // #i68101#
2509 }
2510 
2512  const uno::Reference< drawing::XShape >& xShape,
2513  XMLShapeExportFlags nFeatures /* = SEF_DEFAULT */, awt::Point* pRefPoint /* = NULL */)
2514 {
2515  uno::Reference< beans::XPropertySet > xProps( xShape, uno::UNO_QUERY );
2516 
2517  OUString aStr;
2518  OUStringBuffer sStringBuffer;
2519 
2520  // export connection kind
2521  drawing::ConnectorType eType = drawing::ConnectorType_STANDARD;
2522  uno::Any aAny = xProps->getPropertyValue("EdgeKind");
2523  aAny >>= eType;
2524 
2525  if( eType != drawing::ConnectorType_STANDARD )
2526  {
2528  aStr = sStringBuffer.makeStringAndClear();
2530  }
2531 
2532  // export line skew
2533  sal_Int32 nDelta1 = 0, nDelta2 = 0, nDelta3 = 0;
2534 
2535  aAny = xProps->getPropertyValue("EdgeLine1Delta");
2536  aAny >>= nDelta1;
2537  aAny = xProps->getPropertyValue("EdgeLine2Delta");
2538  aAny >>= nDelta2;
2539  aAny = xProps->getPropertyValue("EdgeLine3Delta");
2540  aAny >>= nDelta3;
2541 
2542  if( nDelta1 != 0 || nDelta2 != 0 || nDelta3 != 0 )
2543  {
2545  nDelta1);
2546  if( nDelta2 != 0 || nDelta3 != 0 )
2547  {
2548  sStringBuffer.append( ' ' );
2550  nDelta2);
2551  if( nDelta3 != 0 )
2552  {
2553  sStringBuffer.append( ' ' );
2555  sStringBuffer, nDelta3);
2556  }
2557  }
2558 
2559  aStr = sStringBuffer.makeStringAndClear();
2561  }
2562 
2563  // export start and end point
2564  awt::Point aStart(0,0);
2565  awt::Point aEnd(1,1);
2566 
2567  /* Get <StartPositionInHoriL2R> and
2568  <EndPositionInHoriL2R>, if they exist and if the document is exported
2569  into the OpenOffice.org file format.
2570  These properties only exist at service css::text::Shape - the
2571  Writer UNO service for shapes.
2572  This code is needed, because the positioning attributes in the
2573  OpenOffice.org file format are given in horizontal left-to-right layout
2574  regardless the layout direction the shape is in. In the OASIS Open Office
2575  file format the positioning attributes are correctly given in the layout
2576  direction the shape is in. Thus, this code provides the conversion from
2577  the OASIS Open Office file format to the OpenOffice.org file format. (#i36248#)
2578  */
2579  if ( !( GetExport().getExportFlags() & SvXMLExportFlags::OASIS ) &&
2580  xProps->getPropertySetInfo()->hasPropertyByName("StartPositionInHoriL2R") &&
2581  xProps->getPropertySetInfo()->hasPropertyByName("EndPositionInHoriL2R") )
2582  {
2583  xProps->getPropertyValue("StartPositionInHoriL2R") >>= aStart;
2584  xProps->getPropertyValue("EndPositionInHoriL2R") >>= aEnd;
2585  }
2586  else
2587  {
2588  xProps->getPropertyValue("StartPosition") >>= aStart;
2589  xProps->getPropertyValue("EndPosition") >>= aEnd;
2590  }
2591 
2592  if( pRefPoint )
2593  {
2594  aStart.X -= pRefPoint->X;
2595  aStart.Y -= pRefPoint->Y;
2596  aEnd.X -= pRefPoint->X;
2597  aEnd.Y -= pRefPoint->Y;
2598  }
2599 
2600  if( nFeatures & XMLShapeExportFlags::X )
2601  {
2602  // svg: x1
2604  aStart.X);
2605  aStr = sStringBuffer.makeStringAndClear();
2607  }
2608  else
2609  {
2610  aEnd.X -= aStart.X;
2611  }
2612 
2613  if( nFeatures & XMLShapeExportFlags::Y )
2614  {
2615  // svg: y1
2617  aStart.Y);
2618  aStr = sStringBuffer.makeStringAndClear();
2620  }
2621  else
2622  {
2623  aEnd.Y -= aStart.Y;
2624  }
2625 
2626  // svg: x2
2627  mrExport.GetMM100UnitConverter().convertMeasureToXML(sStringBuffer, aEnd.X);
2628  aStr = sStringBuffer.makeStringAndClear();
2630 
2631  // svg: y2
2632  mrExport.GetMM100UnitConverter().convertMeasureToXML(sStringBuffer, aEnd.Y);
2633  aStr = sStringBuffer.makeStringAndClear();
2635 
2636  // #i39320#
2637  uno::Reference< uno::XInterface > xRefS;
2638  uno::Reference< uno::XInterface > xRefE;
2639 
2640  // export start connection
2641  xProps->getPropertyValue("StartShape") >>= xRefS;
2642  if( xRefS.is() )
2643  {
2644  const OUString& rShapeId = mrExport.getInterfaceToIdentifierMapper().getIdentifier( xRefS );
2646 
2647  aAny = xProps->getPropertyValue("StartGluePointIndex");
2648  sal_Int32 nGluePointId = 0;
2649  if( aAny >>= nGluePointId )
2650  {
2651  if( nGluePointId != -1 )
2652  {
2653  mrExport.AddAttribute(XML_NAMESPACE_DRAW, XML_START_GLUE_POINT, OUString::number( nGluePointId ));
2654  }
2655  }
2656  }
2657 
2658  // export end connection
2659  xProps->getPropertyValue("EndShape") >>= xRefE;
2660  if( xRefE.is() )
2661  {
2662  const OUString& rShapeId = mrExport.getInterfaceToIdentifierMapper().getIdentifier( xRefE );
2664 
2665  aAny = xProps->getPropertyValue("EndGluePointIndex");
2666  sal_Int32 nGluePointId = 0;
2667  if( aAny >>= nGluePointId )
2668  {
2669  if( nGluePointId != -1 )
2670  {
2671  mrExport.AddAttribute(XML_NAMESPACE_DRAW, XML_END_GLUE_POINT, OUString::number( nGluePointId ));
2672  }
2673  }
2674  }
2675 
2676  // get PolygonBezier
2677  aAny = xProps->getPropertyValue("PolyPolygonBezier");
2678  auto pSourcePolyPolygon = o3tl::tryAccess<drawing::PolyPolygonBezierCoords>(aAny);
2679  if(pSourcePolyPolygon && pSourcePolyPolygon->Coordinates.getLength())
2680  {
2681  const basegfx::B2DPolyPolygon aPolyPolygon(
2683  *pSourcePolyPolygon));
2684  const OUString aPolygonString(
2686  aPolyPolygon,
2687  true, // bUseRelativeCoordinates
2688  false, // bDetectQuadraticBeziers: not used in old, but maybe activated now
2689  true)); // bHandleRelativeNextPointCompatible
2690 
2691  // write point array
2692  mrExport.AddAttribute(XML_NAMESPACE_SVG, XML_D, aPolygonString);
2693  }
2694 
2695  // get matrix
2696  ::basegfx::B2DHomMatrix aMatrix;
2697  ImpExportNewTrans_GetB2DHomMatrix(aMatrix, xProps);
2698 
2699  // decompose and correct about pRefPoint
2700  ::basegfx::B2DTuple aTRScale;
2701  double fTRShear(0.0);
2702  double fTRRotate(0.0);
2703  ::basegfx::B2DTuple aTRTranslate;
2704  ImpExportNewTrans_DecomposeAndRefPoint(aMatrix, aTRScale, fTRShear,
2705  fTRRotate, aTRTranslate, pRefPoint);
2706 
2707  // fdo#49678: create and export ViewBox
2708  awt::Size aSize(FRound(aTRScale.getX()), FRound(aTRScale.getY()));
2709  SdXMLImExViewBox aViewBox(0, 0, aSize.Width, aSize.Height);
2711 
2712  // write connector shape. Add Export later.
2713  bool bCreateNewline( (nFeatures & XMLShapeExportFlags::NO_WS) == XMLShapeExportFlags::NONE ); // #86116#/#92210#
2714  SvXMLElementExport aOBJ(mrExport, XML_NAMESPACE_DRAW, XML_CONNECTOR, bCreateNewline, true);
2715 
2716  ImpExportDescription( xShape ); // #i68101#
2717  ImpExportEvents( xShape );
2718  ImpExportGluePoints( xShape );
2719  ImpExportText( xShape );
2720 }
2721 
2723  const uno::Reference< drawing::XShape >& xShape,
2724  XMLShapeExportFlags nFeatures /* = SEF_DEFAULT */, awt::Point const * pRefPoint /* = NULL */)
2725 {
2726  uno::Reference< beans::XPropertySet > xProps( xShape, uno::UNO_QUERY );
2727 
2728  OUString aStr;
2729  OUStringBuffer sStringBuffer;
2730 
2731  // export start and end point
2732  awt::Point aStart(0,0);
2733  awt::Point aEnd(1,1);
2734 
2735  /* Get <StartPositionInHoriL2R> and
2736  <EndPositionInHoriL2R>, if they exist and if the document is exported
2737  into the OpenOffice.org file format.
2738  These properties only exist at service css::text::Shape - the
2739  Writer UNO service for shapes.
2740  This code is needed, because the positioning attributes in the
2741  OpenOffice.org file format are given in horizontal left-to-right layout
2742  regardless the layout direction the shape is in. In the OASIS Open Office
2743  file format the positioning attributes are correctly given in the layout
2744  direction the shape is in. Thus, this code provides the conversion from
2745  the OASIS Open Office file format to the OpenOffice.org file format. (#i36248#)
2746  */
2747  if ( !( GetExport().getExportFlags() & SvXMLExportFlags::OASIS ) &&
2748  xProps->getPropertySetInfo()->hasPropertyByName("StartPositionInHoriL2R") &&
2749  xProps->getPropertySetInfo()->hasPropertyByName("EndPositionInHoriL2R") )
2750  {
2751  xProps->getPropertyValue("StartPositionInHoriL2R") >>= aStart;
2752  xProps->getPropertyValue("EndPositionInHoriL2R") >>= aEnd;
2753  }
2754  else
2755  {
2756  xProps->getPropertyValue("StartPosition") >>= aStart;
2757  xProps->getPropertyValue("EndPosition") >>= aEnd;
2758  }
2759 
2760  if( pRefPoint )
2761  {
2762  aStart.X -= pRefPoint->X;
2763  aStart.Y -= pRefPoint->Y;
2764  aEnd.X -= pRefPoint->X;
2765  aEnd.Y -= pRefPoint->Y;
2766  }
2767 
2768  if( nFeatures & XMLShapeExportFlags::X )
2769  {
2770  // svg: x1
2772  aStart.X);
2773  aStr = sStringBuffer.makeStringAndClear();
2775  }
2776  else
2777  {
2778  aEnd.X -= aStart.X;
2779  }
2780 
2781  if( nFeatures & XMLShapeExportFlags::Y )
2782  {
2783  // svg: y1
2785  aStart.Y);
2786  aStr = sStringBuffer.makeStringAndClear();
2788  }
2789  else
2790  {
2791  aEnd.Y -= aStart.Y;
2792  }
2793 
2794  // svg: x2
2795  mrExport.GetMM100UnitConverter().convertMeasureToXML(sStringBuffer, aEnd.X);
2796  aStr = sStringBuffer.makeStringAndClear();
2798 
2799  // svg: y2
2800  mrExport.GetMM100UnitConverter().convertMeasureToXML(sStringBuffer, aEnd.Y);
2801  aStr = sStringBuffer.makeStringAndClear();
2803 
2804  // write measure shape
2805  bool bCreateNewline( (nFeatures & XMLShapeExportFlags::NO_WS) == XMLShapeExportFlags::NONE ); // #86116#/#92210#
2806  SvXMLElementExport aOBJ(mrExport, XML_NAMESPACE_DRAW, XML_MEASURE, bCreateNewline, true);
2807 
2808  ImpExportDescription( xShape ); // #i68101#
2809  ImpExportEvents( xShape );
2810  ImpExportGluePoints( xShape );
2811 
2812  uno::Reference< text::XText > xText( xShape, uno::UNO_QUERY );
2813  if( xText.is() )
2814  mrExport.GetTextParagraphExport()->exportText( xText );
2815 }
2816 
2818  const uno::Reference< drawing::XShape >& xShape,
2819  XmlShapeType eShapeType, XMLShapeExportFlags nFeatures /* = SEF_DEFAULT */, awt::Point* pRefPoint /* = NULL */,
2820  SvXMLAttributeList* pAttrList /* = NULL */ )
2821 {
2822  uno::Reference< beans::XPropertySet > xPropSet(xShape, uno::UNO_QUERY);
2823  uno::Reference< container::XNamed > xNamed(xShape, uno::UNO_QUERY);
2824 
2825  SAL_WARN_IF( !xPropSet.is() || !xNamed.is(), "xmloff", "ole shape is not implementing needed interfaces");
2826  if(!(xPropSet.is() && xNamed.is()))
2827  return;
2828 
2829  // Transformation
2830  ImpExportNewTrans(xPropSet, nFeatures, pRefPoint);
2831 
2832  bool bIsEmptyPresObj = false;
2833 
2834  // presentation settings
2835  if(eShapeType == XmlShapeTypePresOLE2Shape)
2836  bIsEmptyPresObj = ImpExportPresentationAttributes( xPropSet, GetXMLToken(XML_OBJECT) );
2837  else if(eShapeType == XmlShapeTypePresChartShape)
2838  bIsEmptyPresObj = ImpExportPresentationAttributes( xPropSet, GetXMLToken(XML_CHART) );
2839  else if(eShapeType == XmlShapeTypePresSheetShape)
2840  bIsEmptyPresObj = ImpExportPresentationAttributes( xPropSet, GetXMLToken(XML_TABLE) );
2841 
2842  bool bCreateNewline( (nFeatures & XMLShapeExportFlags::NO_WS) == XMLShapeExportFlags::NONE ); // #86116#/#92210#
2843  bool bExportEmbedded(mrExport.getExportFlags() & SvXMLExportFlags::EMBEDDED);
2844  OUString sPersistName;
2846  XML_FRAME, bCreateNewline, true );
2847 
2848  if (!bIsEmptyPresObj)
2849  {
2850  if (pAttrList)
2851  {
2852  mrExport.AddAttributeList(pAttrList);
2853  }
2854 
2855  OUString sClassId;
2856  OUString sURL;
2857  bool bInternal = false;
2858  xPropSet->getPropertyValue("IsInternal") >>= bInternal;
2859 
2860  {
2861 
2862  if ( bInternal )
2863  {
2864  // OOo internal links have no storage persistence, URL is stored in the XML file
2865  // the result LinkURL is empty in case the object is not a link
2866  xPropSet->getPropertyValue("LinkURL") >>= sURL;
2867  }
2868 
2869  xPropSet->getPropertyValue("PersistName") >>= sPersistName;
2870  if ( sURL.isEmpty() )
2871  {
2872  if( !sPersistName.isEmpty() )
2873  {
2874  sURL = "vnd.sun.star.EmbeddedObject:" + sPersistName;
2875  }
2876  }
2877 
2878  if( !bInternal )
2879  xPropSet->getPropertyValue("CLSID") >>= sClassId;
2880 
2881  if( !sClassId.isEmpty() )
2883 
2884  if(!bExportEmbedded)
2885  {
2886  // xlink:href
2887  if( !sURL.isEmpty() )
2888  {
2889  // #96717# in theorie, if we don't have a URL we shouldn't even
2890  // export this OLE shape. But practically it's too risky right now
2891  // to change this so we better dispose this on load
2892  sURL = mrExport.AddEmbeddedObject( sURL );
2893 
2898  }
2899  }
2900  }
2901 
2902  enum XMLTokenEnum eElem = sClassId.isEmpty() ? XML_OBJECT : XML_OBJECT_OLE ;
2903  SvXMLElementExport aElem( mrExport, XML_NAMESPACE_DRAW, eElem, true, true );
2904 
2905  // tdf#112547 export text as child of draw:object, where import expects it
2906  if (!bIsEmptyPresObj && supportsText(eShapeType))
2907  {
2908  // #i118485# Add text export, the draw OLE shape allows text now
2909  ImpExportText( xShape, TextPNS::EXTENSION );
2910  }
2911 
2912  if(bExportEmbedded && !bIsEmptyPresObj)
2913  {
2914  if(bInternal)
2915  {
2916  // embedded XML
2917  uno::Reference< lang::XComponent > xComp;
2918  xPropSet->getPropertyValue("Model") >>= xComp;
2919  SAL_WARN_IF( !xComp.is(), "xmloff", "no xModel for own OLE format" );
2921  }
2922  else
2923  {
2924  // embed as Base64
2925  // this is an alien object ( currently MSOLE is the only supported type of such objects )
2926  // in case it is not an OASIS format the object should be asked to store replacement image if possible
2927 
2928  OUString sURLRequest( sURL );
2930  sURLRequest += "?oasis=false";
2931  mrExport.AddEmbeddedObjectAsBase64( sURLRequest );
2932  }
2933  }
2934  }
2935  if( !bIsEmptyPresObj )
2936  {
2937  OUString sURL = XML_EMBEDDEDOBJECTGRAPHIC_URL_BASE + sPersistName;
2938  if( !bExportEmbedded )
2939  {
2940  sURL = GetExport().AddEmbeddedObject( sURL );
2945  }
2946 
2948  XML_IMAGE, false, true );
2949 
2950  if( bExportEmbedded )
2952  }
2953 
2954  ImpExportEvents( xShape );
2955  ImpExportGluePoints( xShape );
2956  ImpExportDescription( xShape ); // #i68101#
2957 
2958 }
2959 
2961  const uno::Reference< drawing::XShape >& xShape,
2962  XmlShapeType eShapeType, XMLShapeExportFlags nFeatures /* = SEF_DEFAULT */, awt::Point* pRefPoint /* = NULL */)
2963 {
2964  const uno::Reference< beans::XPropertySet > xPropSet(xShape, uno::UNO_QUERY);
2965  if(!xPropSet.is())
2966  return;
2967 
2968  // #86163# Transformation
2969  ImpExportNewTrans(xPropSet, nFeatures, pRefPoint);
2970 
2971  // export page number used for this page
2972  uno::Reference< beans::XPropertySetInfo > xPropSetInfo( xPropSet->getPropertySetInfo() );
2973  const OUString aPageNumberStr("PageNumber");
2974  if( xPropSetInfo.is() && xPropSetInfo->hasPropertyByName(aPageNumberStr))
2975  {
2976  sal_Int32 nPageNumber = 0;
2977  xPropSet->getPropertyValue(aPageNumberStr) >>= nPageNumber;
2978  if( nPageNumber )
2979  mrExport.AddAttribute(XML_NAMESPACE_DRAW, XML_PAGE_NUMBER, OUString::number(nPageNumber));
2980  }
2981 
2982  // a presentation page shape, normally used on notes pages only. If
2983  // it is used not as presentation shape, it may have been created with
2984  // copy-paste exchange between draw and impress (this IS possible...)
2985  if(eShapeType == XmlShapeTypePresPageShape)
2986  {
2988  XML_PAGE);
2989  }
2990 
2991  // write Page shape
2992  bool bCreateNewline( (nFeatures & XMLShapeExportFlags::NO_WS) == XMLShapeExportFlags::NONE ); // #86116#/#92210#
2993  SvXMLElementExport aOBJ(mrExport, XML_NAMESPACE_DRAW, XML_PAGE_THUMBNAIL, bCreateNewline, true);
2994 }
2995 
2997  const uno::Reference< drawing::XShape >& xShape,
2998  XMLShapeExportFlags nFeatures /* = SEF_DEFAULT */, awt::Point* pRefPoint /* = NULL */)
2999 {
3000  const uno::Reference< beans::XPropertySet > xPropSet(xShape, uno::UNO_QUERY);
3001  if(!xPropSet.is())
3002  return;
3003 
3004  // Transformation
3005  ImpExportNewTrans(xPropSet, nFeatures, pRefPoint);
3006 
3007  // evtl. corner radius?
3008  sal_Int32 nCornerRadius(0);
3009  xPropSet->getPropertyValue("CornerRadius") >>= nCornerRadius;
3010  if(nCornerRadius)
3011  {
3012  OUStringBuffer sStringBuffer;
3014  nCornerRadius);
3015  mrExport.AddAttribute(XML_NAMESPACE_DRAW, XML_CORNER_RADIUS, sStringBuffer.makeStringAndClear());
3016  }
3017 
3018  awt::Point aCaptionPoint;
3019  xPropSet->getPropertyValue("CaptionPoint") >>= aCaptionPoint;
3020 
3022  aCaptionPoint.X);
3025  aCaptionPoint.Y);
3027 
3028  // write Caption shape. Add export later.
3029  bool bCreateNewline( (nFeatures & XMLShapeExportFlags::NO_WS) == XMLShapeExportFlags::NONE ); // #86116#/#92210#
3030  bool bAnnotation( (nFeatures & XMLShapeExportFlags::ANNOTATION) == XMLShapeExportFlags::ANNOTATION );
3031 
3033  (bAnnotation ? XML_NAMESPACE_OFFICE
3034  : XML_NAMESPACE_DRAW),
3035  (bAnnotation ? XML_ANNOTATION : XML_CAPTION),
3036  bCreateNewline, true );
3037 
3038  ImpExportDescription( xShape ); // #i68101#
3039  ImpExportEvents( xShape );
3040  ImpExportGluePoints( xShape );
3041  if( bAnnotation )
3042  mrExport.exportAnnotationMeta( xShape );
3043  ImpExportText( xShape );
3044 
3045 }
3046 
3048  const uno::Reference< drawing::XShape >& xShape,
3049  XMLShapeExportFlags nFeatures, css::awt::Point* pRefPoint)
3050 {
3051  const uno::Reference< beans::XPropertySet > xPropSet(xShape, uno::UNO_QUERY);
3052  if(!xPropSet.is())
3053  return;
3054 
3055  // Transformation
3056  ImpExportNewTrans(xPropSet, nFeatures, pRefPoint);
3057 
3058  bool bCreateNewline( (nFeatures & XMLShapeExportFlags::NO_WS) == XMLShapeExportFlags::NONE ); // #86116#/#92210#
3060  XML_FRAME, bCreateNewline, true );
3061 
3062  // export frame url
3063  OUString aStr;
3064  xPropSet->getPropertyValue("FrameURL") >>= aStr;
3065  mrExport.AddAttribute ( XML_NAMESPACE_XLINK, XML_HREF, GetExport().GetRelativeReference(aStr) );
3069 
3070  // export name
3071  xPropSet->getPropertyValue("FrameName") >>= aStr;
3072  if( !aStr.isEmpty() )
3074 
3075  // write floating frame
3076  {
3078  }
3079 
3080 }
3081 
3083  const uno::Reference< drawing::XShape >& xShape,
3084  XMLShapeExportFlags nFeatures, css::awt::Point* pRefPoint)
3085 {
3086  const uno::Reference< beans::XPropertySet > xPropSet(xShape, uno::UNO_QUERY);
3087  if(!xPropSet.is())
3088  return;
3089 
3090  // Transformation
3091  ImpExportNewTrans(xPropSet, nFeatures, pRefPoint);
3092 
3093  bool bCreateNewline( (nFeatures & XMLShapeExportFlags::NO_WS) == XMLShapeExportFlags::NONE ); // #86116#/#92210#
3095  XML_FRAME, bCreateNewline, true );
3096 
3097  // export frame url
3098  OUString aStr;
3099  xPropSet->getPropertyValue("AppletCodeBase") >>= aStr;
3100  mrExport.AddAttribute ( XML_NAMESPACE_XLINK, XML_HREF, GetExport().GetRelativeReference(aStr) );
3104 
3105  // export draw:applet-name
3106  xPropSet->getPropertyValue("AppletName") >>= aStr;
3107  if( !aStr.isEmpty() )
3109 
3110  // export draw:code
3111  xPropSet->getPropertyValue("AppletCode") >>= aStr;
3113 
3114  // export draw:may-script
3115  bool bIsScript = false;
3116  xPropSet->getPropertyValue("AppletIsScript") >>= bIsScript;
3118 
3119  {
3120  // write applet
3122 
3123  // export parameters
3124  uno::Sequence< beans::PropertyValue > aCommands;
3125  xPropSet->getPropertyValue("AppletCommands") >>= aCommands;
3126  for( const auto& rCommand : std::as_const(aCommands) )
3127  {
3128  rCommand.Value >>= aStr;
3129  mrExport.AddAttribute( XML_NAMESPACE_DRAW, XML_NAME, rCommand.Name );
3131  SvXMLElementExport aElem( mrExport, XML_NAMESPACE_DRAW, XML_PARAM, false, true );
3132  }
3133  }
3134 
3135 }
3136 
3138  const uno::Reference< drawing::XShape >& xShape,
3139  XMLShapeExportFlags nFeatures, css::awt::Point* pRefPoint)
3140 {
3141  const uno::Reference< beans::XPropertySet > xPropSet(xShape, uno::UNO_QUERY);
3142  if(!xPropSet.is())
3143  return;
3144 
3145  // Transformation
3146  ImpExportNewTrans(xPropSet, nFeatures, pRefPoint);
3147 
3148  bool bCreateNewline( (nFeatures & XMLShapeExportFlags::NO_WS) == XMLShapeExportFlags::NONE ); // #86116#/#92210#
3150  XML_FRAME, bCreateNewline, true );
3151 
3152  // export plugin url
3153  OUString aStr;
3154  xPropSet->getPropertyValue("PluginURL") >>= aStr;
3155  mrExport.AddAttribute ( XML_NAMESPACE_XLINK, XML_HREF, GetExport().GetRelativeReference(aStr) );
3159 
3160  // export mime-type
3161  xPropSet->getPropertyValue("PluginMimeType") >>= aStr;
3162  if(!aStr.isEmpty())
3164 
3165  {
3166  // write plugin
3168 
3169  // export parameters
3170  uno::Sequence< beans::PropertyValue > aCommands;
3171  xPropSet->getPropertyValue("PluginCommands") >>= aCommands;
3172  for( const auto& rCommand : std::as_const(aCommands) )
3173  {
3174  rCommand.Value >>= aStr;
3175  mrExport.AddAttribute( XML_NAMESPACE_DRAW, XML_NAME, rCommand.Name );
3177  SvXMLElementExport aElem( mrExport, XML_NAMESPACE_DRAW, XML_PARAM, false, true );
3178  }
3179  }
3180 
3181 }
3182 
3183 static void lcl_CopyStream(
3184  uno::Reference<io::XInputStream> const& xInStream,
3185  uno::Reference<embed::XStorage> const& xTarget,
3186  OUString const& rPath, const OUString& rMimeType)
3187 {
3189  uno::Reference<io::XStream> const xStream(
3191  embed::ElementModes::WRITE | embed::ElementModes::TRUNCATE, proxy));
3192  uno::Reference<io::XOutputStream> const xOutStream(
3193  (xStream.is()) ? xStream->getOutputStream() : nullptr);
3194  if (!xOutStream.is())
3195  {
3196  SAL_WARN("xmloff", "no output stream");
3197  throw uno::Exception("no output stream",nullptr);
3198  }
3199  uno::Reference< beans::XPropertySet > const xStreamProps(xStream,
3200  uno::UNO_QUERY);
3201  if (xStreamProps.is()) { // this is NOT supported in FileSystemStorage
3202  xStreamProps->setPropertyValue("MediaType",
3203  uno::makeAny(rMimeType));
3204  xStreamProps->setPropertyValue( // turn off compression
3205  "Compressed",
3206  uno::makeAny(false));
3207  }
3208  ::comphelper::OStorageHelper::CopyInputToOutput(xInStream, xOutStream);
3209  xOutStream->closeOutput();
3210  proxy.commitStorages();
3211 }
3212 
3213 static OUString
3215  uno::Reference<beans::XPropertySet> const& xPropSet,
3216  OUString const& rURL, const OUString& rMimeType)
3217 {
3218  OUString urlPath;
3219  if (rURL.startsWithIgnoreAsciiCase("vnd.sun.star.Package:", &urlPath))
3220  {
3221  try // video is embedded
3222  {
3223  uno::Reference<embed::XStorage> const xTarget(
3224  rExport.GetTargetStorage(), uno::UNO_SET_THROW);
3225  uno::Reference<io::XInputStream> xInStream;
3226  xPropSet->getPropertyValue("PrivateStream")
3227  >>= xInStream;
3228 
3229  if (!xInStream.is())
3230  {
3231  SAL_WARN("xmloff", "no input stream");
3232  return OUString();
3233  }
3234 
3235  lcl_CopyStream(xInStream, xTarget, rURL, rMimeType);
3236 
3237  return urlPath;
3238  }
3239  catch (uno::Exception const&)
3240  {
3241  TOOLS_INFO_EXCEPTION("xmloff", "exception while storing embedded media");
3242  }
3243  return OUString();
3244  }
3245  else
3246  {
3247  return rExport.GetRelativeReference(rURL); // linked
3248  }
3249 }
3250 
3252  const uno::Reference< drawing::XShape >& xShape,
3253  XmlShapeType eShapeType, XMLShapeExportFlags nFeatures, css::awt::Point* pRefPoint)
3254 {
3255  const uno::Reference< beans::XPropertySet > xPropSet(xShape, uno::UNO_QUERY);
3256  if(!xPropSet.is())
3257  return;
3258 
3259  // Transformation
3260  ImpExportNewTrans(xPropSet, nFeatures, pRefPoint);
3261 
3262  if(eShapeType == XmlShapeTypePresMediaShape)
3263  {
3265  }
3266  bool bCreateNewline( (nFeatures & XMLShapeExportFlags::NO_WS) == XMLShapeExportFlags::NONE ); // #86116#/#92210#
3268  XML_FRAME, bCreateNewline, true );
3269 
3270  // export media url
3271  OUString aMediaURL;
3272  xPropSet->getPropertyValue("MediaURL") >>= aMediaURL;
3273  OUString sMimeType;
3274  xPropSet->getPropertyValue("MediaMimeType") >>= sMimeType;
3275 
3276  OUString const persistentURL =
3277  lcl_StoreMediaAndGetURL(GetExport(), xPropSet, aMediaURL, sMimeType);
3278 
3279  mrExport.AddAttribute ( XML_NAMESPACE_XLINK, XML_HREF, persistentURL );
3283 
3284  // export mime-type
3286 
3287  // write plugin
3288  SvXMLElementExport aPluginOBJ(mrExport, XML_NAMESPACE_DRAW, XML_PLUGIN, !( nFeatures & XMLShapeExportFlags::NO_WS ), true);
3289 
3290  // export parameters
3291  const OUString aFalseStr( "false" ), aTrueStr( "true" );
3292 
3293  bool bLoop = false;
3294  const OUString aLoopStr( "Loop" );
3295  xPropSet->getPropertyValue( aLoopStr ) >>= bLoop;
3298  delete new SvXMLElementExport( mrExport, XML_NAMESPACE_DRAW, XML_PARAM, false, true );
3299 
3300  bool bMute = false;
3301  const OUString aMuteStr( "Mute" );
3302  xPropSet->getPropertyValue( aMuteStr ) >>= bMute;
3304  mrExport.AddAttribute( XML_NAMESPACE_DRAW, XML_VALUE, bMute ? aTrueStr : aFalseStr );
3305  delete new SvXMLElementExport( mrExport, XML_NAMESPACE_DRAW, XML_PARAM, false, true );
3306 
3307  sal_Int16 nVolumeDB = 0;
3308  xPropSet->getPropertyValue("VolumeDB") >>= nVolumeDB;
3310  mrExport.AddAttribute( XML_NAMESPACE_DRAW, XML_VALUE, OUString::number( nVolumeDB ) );
3311  delete new SvXMLElementExport( mrExport, XML_NAMESPACE_DRAW, XML_PARAM, false, true );
3312 
3313  media::ZoomLevel eZoom;
3314  OUString aZoomValue;
3315  xPropSet->getPropertyValue("Zoom") >>= eZoom;
3316  switch( eZoom )
3317  {
3318  case media::ZoomLevel_ZOOM_1_TO_4 : aZoomValue = "25%"; break;
3319  case media::ZoomLevel_ZOOM_1_TO_2 : aZoomValue = "50%"; break;
3320  case media::ZoomLevel_ORIGINAL : aZoomValue = "100%"; break;
3321  case media::ZoomLevel_ZOOM_2_TO_1 : aZoomValue = "200%"; break;
3322  case media::ZoomLevel_ZOOM_4_TO_1 : aZoomValue = "400%"; break;
3323  case media::ZoomLevel_FIT_TO_WINDOW: aZoomValue = "fit"; break;
3324  case media::ZoomLevel_FIT_TO_WINDOW_FIXED_ASPECT: aZoomValue = "fixedfit"; break;
3325  case media::ZoomLevel_FULLSCREEN : aZoomValue = "fullscreen"; break;
3326 
3327  default:
3328  break;
3329  }
3330 
3331  if( !aZoomValue.isEmpty() )
3332  {
3335  delete new SvXMLElementExport( mrExport, XML_NAMESPACE_DRAW, XML_PARAM, false, true );
3336  }
3337 
3338 }
3339 
3340 void XMLShapeExport::ImpExport3DSceneShape( const uno::Reference< drawing::XShape >& xShape, XMLShapeExportFlags nFeatures, awt::Point* pRefPoint)
3341 {
3342  uno::Reference< drawing::XShapes > xShapes(xShape, uno::UNO_QUERY);
3343  if(!(xShapes.is() && xShapes->getCount()))
3344  return;
3345 
3346  uno::Reference< beans::XPropertySet > xPropSet( xShape, uno::UNO_QUERY );
3347  SAL_WARN_IF( !xPropSet.is(), "xmloff", "XMLShapeExport::ImpExport3DSceneShape can't export a scene without a propertyset" );
3348  if( !xPropSet.is() )
3349  return;
3350 
3351  // Transformation
3352  ImpExportNewTrans(xPropSet, nFeatures, pRefPoint);
3353 
3354  // 3d attributes
3355  export3DSceneAttributes( xPropSet );
3356 
3357  // write 3DScene shape
3358  bool bCreateNewline( (nFeatures & XMLShapeExportFlags::NO_WS) == XMLShapeExportFlags::NONE ); // #86116#/#92210#
3359  SvXMLElementExport aOBJ( mrExport, XML_NAMESPACE_DR3D, XML_SCENE, bCreateNewline, true);
3360 
3361  ImpExportDescription( xShape ); // #i68101#
3362  ImpExportEvents( xShape );
3363 
3364  // write 3DSceneLights
3365  export3DLamps( xPropSet );
3366 
3367  // #89764# if export of position is suppressed for group shape,
3368  // positions of contained objects should be written relative to
3369  // the upper left edge of the group.
3370  awt::Point aUpperLeft;
3371 
3372  if(!(nFeatures & XMLShapeExportFlags::POSITION))
3373  {
3374  nFeatures |= XMLShapeExportFlags::POSITION;
3375  aUpperLeft = xShape->getPosition();
3376  pRefPoint = &aUpperLeft;
3377  }
3378 
3379  // write members
3380  exportShapes( xShapes, nFeatures, pRefPoint );
3381 }
3382 
3384  const uno::Reference< drawing::XShape >& xShape,
3385  XmlShapeType eShapeType)
3386 {
3387  const uno::Reference< beans::XPropertySet > xPropSet(xShape, uno::UNO_QUERY);
3388  if(!xPropSet.is())
3389  return;
3390 
3391  OUString aStr;
3392  OUStringBuffer sStringBuffer;
3393 
3394  // transformation (UNO_NAME_3D_TRANSFORM_MATRIX == "D3DTransformMatrix")
3395  uno::Any aAny = xPropSet->getPropertyValue("D3DTransformMatrix");
3396  drawing::HomogenMatrix aHomMat;
3397  aAny >>= aHomMat;
3398  SdXMLImExTransform3D aTransform;
3399  aTransform.AddHomogenMatrix(aHomMat);
3400  if(aTransform.NeedsAction())
3402 
3403  switch(eShapeType)
3404  {
3406  {
3407  // minEdge
3408  aAny = xPropSet->getPropertyValue("D3DPosition");
3409  drawing::Position3D aPosition3D;
3410  aAny >>= aPosition3D;
3411  ::basegfx::B3DVector aPos3D(aPosition3D.PositionX, aPosition3D.PositionY, aPosition3D.PositionZ);
3412 
3413  // maxEdge
3414  aAny = xPropSet->getPropertyValue("D3DSize");
3415  drawing::Direction3D aDirection3D;
3416  aAny >>= aDirection3D;
3417  ::basegfx::B3DVector aDir3D(aDirection3D.DirectionX, aDirection3D.DirectionY, aDirection3D.DirectionZ);
3418 
3419  // transform maxEdge from distance to pos
3420  aDir3D = aPos3D + aDir3D;
3421 
3422  // write minEdge
3423  if(aPos3D != ::basegfx::B3DVector(-2500.0, -2500.0, -2500.0)) // write only when not default
3424  {
3425  SvXMLUnitConverter::convertB3DVector(sStringBuffer, aPos3D);
3426  aStr = sStringBuffer.makeStringAndClear();
3428  }
3429 
3430  // write maxEdge
3431  if(aDir3D != ::basegfx::B3DVector(2500.0, 2500.0, 2500.0)) // write only when not default
3432  {
3433  SvXMLUnitConverter::convertB3DVector(sStringBuffer, aDir3D);
3434  aStr = sStringBuffer.makeStringAndClear();
3436  }
3437 
3438  // write 3DCube shape
3439  // #i123542# Do this *after* the attributes are added, else these will be lost since opening
3440  // the scope will clear the global attribute list at the exporter
3442 
3443  break;
3444  }
3446  {
3447  // Center
3448  aAny = xPropSet->getPropertyValue("D3DPosition");
3449  drawing::Position3D aPosition3D;
3450  aAny >>= aPosition3D;
3451  ::basegfx::B3DVector aPos3D(aPosition3D.PositionX, aPosition3D.PositionY, aPosition3D.PositionZ);
3452 
3453  // Size
3454  aAny = xPropSet->getPropertyValue("D3DSize");
3455  drawing::Direction3D aDirection3D;
3456  aAny >>= aDirection3D;
3457  ::basegfx::B3DVector aDir3D(aDirection3D.DirectionX, aDirection3D.DirectionY, aDirection3D.DirectionZ);
3458 
3459  // write Center
3460  if(aPos3D != ::basegfx::B3DVector(0.0, 0.0, 0.0)) // write only when not default
3461  {
3462  SvXMLUnitConverter::convertB3DVector(sStringBuffer, aPos3D);
3463  aStr = sStringBuffer.makeStringAndClear();
3465  }
3466 
3467  // write Size
3468  if(aDir3D != ::basegfx::B3DVector(5000.0, 5000.0, 5000.0)) // write only when not default
3469  {
3470  SvXMLUnitConverter::convertB3DVector(sStringBuffer, aDir3D);
3471  aStr = sStringBuffer.makeStringAndClear();
3473  }
3474 
3475  // write 3DSphere shape
3476  // #i123542# Do this *after* the attributes are added, else these will be lost since opening
3477  // the scope will clear the global attribute list at the exporter
3479 
3480  break;
3481  }
3484  {
3485  // write special 3DLathe/3DExtrude attributes, get 3D tools::PolyPolygon as drawing::PolyPolygonShape3D
3486  aAny = xPropSet->getPropertyValue("D3DPolyPolygon3D");
3487  drawing::PolyPolygonShape3D aUnoPolyPolygon3D;
3488  aAny >>= aUnoPolyPolygon3D;
3489 
3490  // convert to 3D PolyPolygon
3491  const basegfx::B3DPolyPolygon aPolyPolygon3D(
3493  aUnoPolyPolygon3D));
3494 
3495  // convert to 2D tools::PolyPolygon using identity 3D transformation (just grep X and Y)
3496  const basegfx::B3DHomMatrix aB3DHomMatrixFor2DConversion;
3497  const basegfx::B2DPolyPolygon aPolyPolygon(
3499  aPolyPolygon3D,
3500  aB3DHomMatrixFor2DConversion));
3501 
3502  // get 2D range of it
3503  const basegfx::B2DRange aPolyPolygonRange(aPolyPolygon.getB2DRange());
3504 
3505  // export ViewBox
3506  SdXMLImExViewBox aViewBox(
3507  aPolyPolygonRange.getMinX(),
3508  aPolyPolygonRange.getMinY(),
3509  aPolyPolygonRange.getWidth(),
3510  aPolyPolygonRange.getHeight());
3511 
3512  mrExport.AddAttribute(XML_NAMESPACE_SVG, XML_VIEWBOX, aViewBox.GetExportString());
3513 
3514  // prepare svg:d string
3515  const OUString aPolygonString(
3517  aPolyPolygon,
3518  true, // bUseRelativeCoordinates
3519  false, // bDetectQuadraticBeziers TTTT: not used in old, but maybe activated now
3520  true)); // bHandleRelativeNextPointCompatible
3521 
3522  // write point array
3523  mrExport.AddAttribute(XML_NAMESPACE_SVG, XML_D, aPolygonString);
3524 
3525  if(eShapeType == XmlShapeTypeDraw3DLatheObject)
3526  {
3527  // write 3DLathe shape
3529  }
3530  else
3531  {
3532  // write 3DExtrude shape
3534  }
3535  break;
3536  }
3537  default:
3538  break;
3539  }
3540 }
3541 
3543 void XMLShapeExport::export3DSceneAttributes( const css::uno::Reference< css::beans::XPropertySet >& xPropSet )
3544 {
3545  OUString aStr;
3546  OUStringBuffer sStringBuffer;
3547 
3548  // world transformation (UNO_NAME_3D_TRANSFORM_MATRIX == "D3DTransformMatrix")
3549  uno::Any aAny = xPropSet->getPropertyValue("D3DTransformMatrix");
3550  drawing::HomogenMatrix aHomMat;
3551  aAny >>= aHomMat;
3552  SdXMLImExTransform3D aTransform;
3553  aTransform.AddHomogenMatrix(aHomMat);
3554  if(aTransform.NeedsAction())
3556 
3557  // VRP, VPN, VUP
3558  aAny = xPropSet->getPropertyValue("D3DCameraGeometry");
3559  drawing::CameraGeometry aCamGeo;
3560  aAny >>= aCamGeo;
3561 
3562  ::basegfx::B3DVector aVRP(aCamGeo.vrp.PositionX, aCamGeo.vrp.PositionY, aCamGeo.vrp.PositionZ);
3563  if(aVRP != ::basegfx::B3DVector(0.0, 0.0, 1.0)) // write only when not default
3564  {
3565  SvXMLUnitConverter::convertB3DVector(sStringBuffer, aVRP);
3566  aStr = sStringBuffer.makeStringAndClear();
3568  }
3569 
3570  ::basegfx::B3DVector aVPN(aCamGeo.vpn.DirectionX, aCamGeo.vpn.DirectionY, aCamGeo.vpn.DirectionZ);
3571  if(aVPN != ::basegfx::B3DVector(0.0, 0.0, 1.0)) // write only when not default
3572  {
3573  SvXMLUnitConverter::convertB3DVector(sStringBuffer, aVPN);
3574  aStr = sStringBuffer.makeStringAndClear();
3576  }
3577 
3578  ::basegfx::B3DVector aVUP(aCamGeo.vup.DirectionX, aCamGeo.vup.DirectionY, aCamGeo.vup.DirectionZ);
3579  if(aVUP != ::basegfx::B3DVector(0.0, 1.0, 0.0)) // write only when not default
3580  {
3581  SvXMLUnitConverter::convertB3DVector(sStringBuffer, aVUP);
3582  aStr = sStringBuffer.makeStringAndClear();
3584  }
3585 
3586  // projection "D3DScenePerspective" drawing::ProjectionMode
3587  aAny = xPropSet->getPropertyValue("D3DScenePerspective");
3588  drawing::ProjectionMode aPrjMode;
3589  aAny >>= aPrjMode;
3590  if(aPrjMode == drawing::ProjectionMode_PARALLEL)
3591  aStr = GetXMLToken(XML_PARALLEL);
3592  else
3593  aStr = GetXMLToken(XML_PERSPECTIVE);
3595 
3596  // distance
3597  aAny = xPropSet->getPropertyValue("D3DSceneDistance");
3598  sal_Int32 nDistance = 0;
3599  aAny >>= nDistance;
3601  nDistance);
3602  aStr = sStringBuffer.makeStringAndClear();
3604 
3605  // focalLength
3606  aAny = xPropSet->getPropertyValue("D3DSceneFocalLength");
3607  sal_Int32 nFocalLength = 0;
3608  aAny >>= nFocalLength;
3610  nFocalLength);
3611  aStr = sStringBuffer.makeStringAndClear();
3613 
3614  // shadowSlant
3615  aAny = xPropSet->getPropertyValue("D3DSceneShadowSlant");
3616  sal_Int16 nShadowSlant = 0;
3617  aAny >>= nShadowSlant;
3618  mrExport.AddAttribute(XML_NAMESPACE_DR3D, XML_SHADOW_SLANT, OUString::number(static_cast<sal_Int32>(nShadowSlant)));
3619 
3620  // shadeMode
3621  aAny = xPropSet->getPropertyValue("D3DSceneShadeMode");
3622  drawing::ShadeMode aShadeMode;
3623  if(aAny >>= aShadeMode)
3624  {
3625  if(aShadeMode == drawing::ShadeMode_FLAT)
3626  aStr = GetXMLToken(XML_FLAT);
3627  else if(aShadeMode == drawing::ShadeMode_PHONG)
3628  aStr = GetXMLToken(XML_PHONG);
3629  else if(aShadeMode == drawing::ShadeMode_SMOOTH)
3630  aStr = GetXMLToken(XML_GOURAUD);
3631  else
3632  aStr = GetXMLToken(XML_DRAFT);
3633  }
3634  else
3635  {
3636  // ShadeMode enum not there, write default
3637  aStr = GetXMLToken(XML_GOURAUD);
3638  }
3640 
3641  // ambientColor
3642  aAny = xPropSet->getPropertyValue("D3DSceneAmbientColor");
3643  sal_Int32 nAmbientColor = 0;
3644  aAny >>= nAmbientColor;
3645  ::sax::Converter::convertColor(sStringBuffer, nAmbientColor);
3646  aStr = sStringBuffer.makeStringAndClear();
3648 
3649  // lightingMode
3650  aAny = xPropSet->getPropertyValue("D3DSceneTwoSidedLighting");
3651  bool bTwoSidedLighting = false;
3652  aAny >>= bTwoSidedLighting;
3653  ::sax::Converter::convertBool(sStringBuffer, bTwoSidedLighting);
3654  aStr = sStringBuffer.makeStringAndClear();
3656 }
3657 
3659 void XMLShapeExport::export3DLamps( const css::uno::Reference< css::beans::XPropertySet >& xPropSet )
3660 {
3661  // write lamps 1..8 as content
3662  OUString aStr;
3663  OUStringBuffer sStringBuffer;
3664 
3665  const OUString aColorPropName("D3DSceneLightColor");
3666  const OUString aDirectionPropName("D3DSceneLightDirection");
3667  const OUString aLightOnPropName("D3DSceneLightOn");
3668 
3669  ::basegfx::B3DVector aLightDirection;
3670  drawing::Direction3D aLightDir;
3671  bool bLightOnOff = false;
3672  for(sal_Int32 nLamp = 1; nLamp <= 8; nLamp++)
3673  {
3674  OUString aIndexStr = OUString::number( nLamp );
3675 
3676  // lightcolor
3677  OUString aPropName = aColorPropName + aIndexStr;
3678  sal_Int32 nLightColor = 0;
3679  xPropSet->getPropertyValue( aPropName ) >>= nLightColor;
3680  ::sax::Converter::convertColor(sStringBuffer, nLightColor);
3681  aStr = sStringBuffer.makeStringAndClear();
3683 
3684  // lightdirection
3685  aPropName = aDirectionPropName + aIndexStr;
3686  xPropSet->getPropertyValue(aPropName) >>= aLightDir;
3687  aLightDirection = ::basegfx::B3DVector(aLightDir.DirectionX, aLightDir.DirectionY, aLightDir.DirectionZ);
3688  SvXMLUnitConverter::convertB3DVector(sStringBuffer, aLightDirection);
3689  aStr = sStringBuffer.makeStringAndClear();
3691 
3692  // lighton
3693  aPropName = aLightOnPropName + aIndexStr;
3694  xPropSet->getPropertyValue(aPropName) >>= bLightOnOff;
3695  ::sax::Converter::convertBool(sStringBuffer, bLightOnOff);
3696  aStr = sStringBuffer.makeStringAndClear();
3698 
3699  // specular
3701  nLamp == 1 ? XML_TRUE : XML_FALSE);
3702 
3703  // write light entry
3705  }
3706 }
3707 
3708 
3709 // using namespace css::io;
3710 // using namespace ::xmloff::EnhancedCustomShapeToken;
3711 
3712 
3713 static void ExportParameter( OUStringBuffer& rStrBuffer, const css::drawing::EnhancedCustomShapeParameter& rParameter )
3714 {
3715  if ( !rStrBuffer.isEmpty() )
3716  rStrBuffer.append( ' ' );
3717  if ( rParameter.Value.getValueTypeClass() == uno::TypeClass_DOUBLE )
3718  {
3719  double fNumber = 0.0;
3720  rParameter.Value >>= fNumber;
3721  ::rtl::math::doubleToUStringBuffer( rStrBuffer, fNumber, rtl_math_StringFormat_Automatic, rtl_math_DecimalPlaces_Max, '.', true );
3722  }
3723  else
3724  {
3725  sal_Int32 nValue = 0;
3726  rParameter.Value >>= nValue;
3727 
3728  switch( rParameter.Type )
3729  {
3730  case css::drawing::EnhancedCustomShapeParameterType::EQUATION :
3731  {
3732  rStrBuffer.append( "?f" ).append(OUString::number( nValue ) );
3733  }
3734  break;
3735 
3736  case css::drawing::EnhancedCustomShapeParameterType::ADJUSTMENT :
3737  {
3738  rStrBuffer.append( '$' );
3739  rStrBuffer.append( OUString::number( nValue ) );
3740  }
3741  break;
3742 
3743  case css::drawing::EnhancedCustomShapeParameterType::BOTTOM :
3744  rStrBuffer.append( GetXMLToken( XML_BOTTOM ) ); break;
3745  case css::drawing::EnhancedCustomShapeParameterType::RIGHT :
3746  rStrBuffer.append( GetXMLToken( XML_RIGHT ) ); break;
3747  case css::drawing::EnhancedCustomShapeParameterType::TOP :
3748  rStrBuffer.append( GetXMLToken( XML_TOP ) ); break;
3749  case css::drawing::EnhancedCustomShapeParameterType::LEFT :
3750  rStrBuffer.append( GetXMLToken( XML_LEFT ) ); break;
3751  case css::drawing::EnhancedCustomShapeParameterType::XSTRETCH :
3752  rStrBuffer.append( GetXMLToken( XML_XSTRETCH ) ); break;
3753  case css::drawing::EnhancedCustomShapeParameterType::YSTRETCH :
3754  rStrBuffer.append( GetXMLToken( XML_YSTRETCH ) ); break;
3755  case css::drawing::EnhancedCustomShapeParameterType::HASSTROKE :
3756  rStrBuffer.append( GetXMLToken( XML_HASSTROKE ) ); break;
3757  case css::drawing::EnhancedCustomShapeParameterType::HASFILL :
3758  rStrBuffer.append( GetXMLToken( XML_HASFILL ) ); break;
3759  case css::drawing::EnhancedCustomShapeParameterType::WIDTH :
3760  rStrBuffer.append( GetXMLToken( XML_WIDTH ) ); break;
3761  case css::drawing::EnhancedCustomShapeParameterType::HEIGHT :
3762  rStrBuffer.append( GetXMLToken( XML_HEIGHT ) ); break;
3763  case css::drawing::EnhancedCustomShapeParameterType::LOGWIDTH :
3764  rStrBuffer.append( GetXMLToken( XML_LOGWIDTH ) ); break;
3765  case css::drawing::EnhancedCustomShapeParameterType::LOGHEIGHT :
3766  rStrBuffer.append( GetXMLToken( XML_LOGHEIGHT ) ); break;
3767  default :
3768  rStrBuffer.append( OUString::number( nValue ) );
3769  }
3770  }
3771 }
3772 
3773 static void ImpExportEquations( SvXMLExport& rExport, const uno::Sequence< OUString >& rEquations )
3774 {
3775  sal_Int32 i;
3776  for ( i = 0; i < rEquations.getLength(); i++ )
3777  {
3778  OUString aStr= "f" + OUString::number( i );
3779  rExport.AddAttribute( XML_NAMESPACE_DRAW, XML_NAME, aStr );
3780 
3781  aStr = rEquations[ i ];
3782  sal_Int32 nIndex = 0;
3783  do
3784  {
3785  nIndex = aStr.indexOf( '?', nIndex );
3786  if ( nIndex != -1 )
3787  {
3788  aStr = OUString::Concat(aStr.subView(0, nIndex + 1)) + "f"
3789  + aStr.subView(nIndex + 1, aStr.getLength() - nIndex - 1);
3790  nIndex++;
3791  }
3792  } while( nIndex != -1 );
3793  rExport.AddAttribute( XML_NAMESPACE_DRAW, XML_FORMULA, aStr );
3794  SvXMLElementExport aOBJ( rExport, XML_NAMESPACE_DRAW, XML_EQUATION, true, true );
3795  }
3796 }
3797 
3798 static void ImpExportHandles( SvXMLExport& rExport, const uno::Sequence< beans::PropertyValues >& rHandles )
3799 {
3800  if ( !rHandles.hasElements() )
3801  return;
3802 
3803  OUString aStr;
3804  OUStringBuffer aStrBuffer;
3805 
3806  for ( const uno::Sequence< beans::PropertyValue >& rPropSeq : rHandles )
3807  {
3808  bool bPosition = false;
3809  for ( const beans::PropertyValue& rPropVal : rPropSeq )
3810  {
3811  switch( EASGet( rPropVal.Name ) )
3812  {
3813  case EAS_Position :
3814  {
3815  css::drawing::EnhancedCustomShapeParameterPair aPosition;
3816  if ( rPropVal.Value >>= aPosition )
3817  {
3818  ExportParameter( aStrBuffer, aPosition.First );
3819  ExportParameter( aStrBuffer, aPosition.Second );
3820  aStr = aStrBuffer.makeStringAndClear();
3822  bPosition = true;
3823  }
3824  }
3825  break;
3826  case EAS_MirroredX :
3827  {
3828  bool bMirroredX;
3829  if ( rPropVal.Value >>= bMirroredX )
3831  bMirroredX ? GetXMLToken( XML_TRUE ) : GetXMLToken( XML_FALSE ) );
3832  }
3833  break;
3834  case EAS_MirroredY :
3835  {
3836  bool bMirroredY;
3837  if ( rPropVal.Value >>= bMirroredY )
3839  bMirroredY ? GetXMLToken( XML_TRUE ) : GetXMLToken( XML_FALSE ) );
3840  }
3841  break;
3842  case EAS_Switched :
3843  {
3844  bool bSwitched;
3845  if ( rPropVal.Value >>= bSwitched )
3847  bSwitched ? GetXMLToken( XML_TRUE ) : GetXMLToken( XML_FALSE ) );
3848  }
3849  break;
3850  case EAS_Polar :
3851  {
3852  css::drawing::EnhancedCustomShapeParameterPair aPolar;
3853  if ( rPropVal.Value >>= aPolar )
3854  {
3855  ExportParameter( aStrBuffer, aPolar.First );
3856  ExportParameter( aStrBuffer, aPolar.Second );
3857  aStr = aStrBuffer.makeStringAndClear();
3859  }
3860  }
3861  break;
3862  case EAS_RadiusRangeMinimum :
3863  {
3864  css::drawing::EnhancedCustomShapeParameter aRadiusRangeMinimum;
3865  if ( rPropVal.Value >>= aRadiusRangeMinimum )
3866  {
3867  ExportParameter( aStrBuffer, aRadiusRangeMinimum );
3868  aStr = aStrBuffer.makeStringAndClear();
3870  }
3871  }
3872  break;
3873  case EAS_RadiusRangeMaximum :
3874  {
3875  css::drawing::EnhancedCustomShapeParameter aRadiusRangeMaximum;
3876  if ( rPropVal.Value >>= aRadiusRangeMaximum )
3877  {
3878  ExportParameter( aStrBuffer, aRadiusRangeMaximum );
3879  aStr = aStrBuffer.makeStringAndClear();
3881  }
3882  }
3883  break;
3884  case EAS_RangeXMinimum :
3885  {
3886  css::drawing::EnhancedCustomShapeParameter aXRangeMinimum;
3887  if ( rPropVal.Value >>= aXRangeMinimum )
3888  {
3889  ExportParameter( aStrBuffer, aXRangeMinimum );
3890  aStr = aStrBuffer.makeStringAndClear();
3892  }
3893  }
3894  break;
3895  case EAS_RangeXMaximum :
3896  {
3897  css::drawing::EnhancedCustomShapeParameter aXRangeMaximum;
3898  if ( rPropVal.Value >>= aXRangeMaximum )
3899  {
3900  ExportParameter( aStrBuffer, aXRangeMaximum );
3901  aStr = aStrBuffer.makeStringAndClear();
3903  }
3904  }
3905  break;
3906  case EAS_RangeYMinimum :
3907  {
3908  css::drawing::EnhancedCustomShapeParameter aYRangeMinimum;
3909  if ( rPropVal.Value >>= aYRangeMinimum )
3910  {
3911  ExportParameter( aStrBuffer, aYRangeMinimum );
3912  aStr = aStrBuffer.makeStringAndClear();
3914  }
3915  }
3916  break;
3917  case EAS_RangeYMaximum :
3918  {
3919  css::drawing::EnhancedCustomShapeParameter aYRangeMaximum;
3920  if ( rPropVal.Value >>= aYRangeMaximum )
3921  {
3922  ExportParameter( aStrBuffer, aYRangeMaximum );
3923  aStr = aStrBuffer.makeStringAndClear();
3925  }
3926  }
3927  break;
3928  default:
3929  break;
3930  }
3931  }
3932  if ( bPosition )
3933  SvXMLElementExport aOBJ( rExport, XML_NAMESPACE_DRAW, XML_HANDLE, true, true );
3934  else
3935  rExport.ClearAttrList();
3936  }
3937 }
3938 
3940  const uno::Sequence< css::drawing::EnhancedCustomShapeParameterPair >& rCoordinates,
3941  const uno::Sequence< css::drawing::EnhancedCustomShapeSegment >& rSegments,
3942  bool bExtended = false )
3943 {
3944 
3945  OUString aStr;
3946  OUStringBuffer aStrBuffer;
3947  bool bNeedExtended = false;
3948 
3949  sal_Int32 i, j, k, l;
3950 
3951  sal_Int32 nCoords = rCoordinates.getLength();
3952  sal_Int32 nSegments = rSegments.getLength();
3953  bool bSimpleSegments = nSegments == 0;
3954  if ( bSimpleSegments )
3955  nSegments = 4;
3956  for ( j = i = 0; j < nSegments; j++ )
3957  {
3958  css::drawing::EnhancedCustomShapeSegment aSegment;
3959  if ( bSimpleSegments )
3960  {
3961  // if there are not enough segments we will default them
3962  switch( j )
3963  {
3964  case 0 :
3965  {
3966  aSegment.Count = 1;
3967  aSegment.Command = css::drawing::EnhancedCustomShapeSegmentCommand::MOVETO;
3968  }
3969  break;
3970  case 1 :
3971  {
3972  aSegment.Count = static_cast<sal_Int16>(std::min( nCoords - 1, sal_Int32(32767) ));
3973  aSegment.Command = css::drawing::EnhancedCustomShapeSegmentCommand::LINETO;
3974  }
3975  break;
3976  case 2 :
3977  {
3978  aSegment.Count = 1;
3979  aSegment.Command = css::drawing::EnhancedCustomShapeSegmentCommand::CLOSESUBPATH;
3980  }
3981  break;
3982  case 3 :
3983  {
3984  aSegment.Count = 1;
3985  aSegment.Command = css::drawing::EnhancedCustomShapeSegmentCommand::ENDSUBPATH;
3986  }
3987  break;
3988  }
3989  }
3990  else
3991  aSegment = rSegments[ j ];
3992 
3993  if ( !aStrBuffer.isEmpty() )
3994  aStrBuffer.append( ' ' );
3995 
3996  sal_Int32 nParameter = 0;
3997  switch( aSegment.Command )
3998  {
3999  case css::drawing::EnhancedCustomShapeSegmentCommand::CLOSESUBPATH :
4000  aStrBuffer.append( 'Z' ); break;
4001  case css::drawing::EnhancedCustomShapeSegmentCommand::ENDSUBPATH :
4002  aStrBuffer.append( 'N' ); break;
4003  case css::drawing::EnhancedCustomShapeSegmentCommand::NOFILL :
4004  aStrBuffer.append( 'F' ); break;
4005  case css::drawing::EnhancedCustomShapeSegmentCommand::NOSTROKE :
4006  aStrBuffer.append( 'S' ); break;
4007 
4008  case css::drawing::EnhancedCustomShapeSegmentCommand::MOVETO :
4009  aStrBuffer.append( 'M' ); nParameter = 1; break;
4010  case css::drawing::EnhancedCustomShapeSegmentCommand::LINETO :
4011  aStrBuffer.append( 'L' ); nParameter = 1; break;
4012  case css::drawing::EnhancedCustomShapeSegmentCommand::CURVETO :
4013  aStrBuffer.append( 'C' ); nParameter = 3; break;
4014  case css::drawing::EnhancedCustomShapeSegmentCommand::ANGLEELLIPSETO :
4015  aStrBuffer.append( 'T' ); nParameter = 3; break;
4016  case css::drawing::EnhancedCustomShapeSegmentCommand::ANGLEELLIPSE :
4017  aStrBuffer.append( 'U' ); nParameter = 3; break;
4018  case css::drawing::EnhancedCustomShapeSegmentCommand::ARCTO :
4019  aStrBuffer.append( 'A' ); nParameter = 4; break;
4020  case css::drawing::EnhancedCustomShapeSegmentCommand::ARC :
4021  aStrBuffer.append( 'B' ); nParameter = 4; break;
4022  case css::drawing::EnhancedCustomShapeSegmentCommand::CLOCKWISEARCTO :
4023  aStrBuffer.append( 'W' ); nParameter = 4; break;
4024  case css::drawing::EnhancedCustomShapeSegmentCommand::CLOCKWISEARC :
4025  aStrBuffer.append( 'V' ); nParameter = 4; break;
4026  case css::drawing::EnhancedCustomShapeSegmentCommand::ELLIPTICALQUADRANTX :
4027  aStrBuffer.append( 'X' ); nParameter = 1; break;
4028  case css::drawing::EnhancedCustomShapeSegmentCommand::ELLIPTICALQUADRANTY :
4029  aStrBuffer.append( 'Y' ); nParameter = 1; break;
4030  case css::drawing::EnhancedCustomShapeSegmentCommand::QUADRATICCURVETO :
4031  aStrBuffer.append( 'Q' ); nParameter = 2; break;
4032  case css::drawing::EnhancedCustomShapeSegmentCommand::ARCANGLETO :
4033  if ( bExtended ) {
4034  aStrBuffer.append( 'G' );
4035  nParameter = 2;
4036  } else {
4037  aStrBuffer.setLength( aStrBuffer.getLength() - 1);
4038  bNeedExtended = true;
4039  i += 2;
4040  }
4041  break;
4042  case css::drawing::EnhancedCustomShapeSegmentCommand::DARKEN :
4043  if ( bExtended )
4044  aStrBuffer.append( 'H' );
4045  else
4046  bNeedExtended = true;
4047  break;
4048  case css::drawing::EnhancedCustomShapeSegmentCommand::DARKENLESS :
4049  if ( bExtended )
4050  aStrBuffer.append( 'I' );
4051  else
4052  bNeedExtended = true;
4053  break;
4054  case css::drawing::EnhancedCustomShapeSegmentCommand::LIGHTEN :
4055  if ( bExtended )
4056  aStrBuffer.append( 'J' );
4057  else
4058  bNeedExtended = true;
4059  break;
4060  case css::drawing::EnhancedCustomShapeSegmentCommand::LIGHTENLESS :
4061  if ( bExtended )
4062  aStrBuffer.append( 'K' );
4063  else
4064  bNeedExtended = true;
4065  break;
4066  default : // ups, seems to be something wrong
4067  {
4068  aSegment.Count = 1;
4069  aSegment.Command = css::drawing::EnhancedCustomShapeSegmentCommand::LINETO;
4070  }
4071  break;
4072  }
4073  if ( nParameter )
4074  {
4075  for ( k = 0; k < aSegment.Count; k++ )
4076  {
4077  if ( ( i + nParameter ) <= nCoords )
4078  {
4079  for ( l = 0; l < nParameter; l++ )
4080  {
4081  ExportParameter( aStrBuffer, rCoordinates[ i ].First );
4082  ExportParameter( aStrBuffer, rCoordinates[ i++ ].Second );
4083  }
4084  }
4085  else
4086  {
4087  j = nSegments; // error -> exiting
4088  break;
4089  }
4090  }
4091  }
4092  }
4093  aStr = aStrBuffer.makeStringAndClear();
4095  if (!bExtended && bNeedExtended && (rExport.getSaneDefaultVersion() & SvtSaveOptions::ODFSVER_EXTENDED))
4096  ImpExportEnhancedPath( rExport, rCoordinates, rSegments, true );
4097 }
4098 
4099 static void ImpExportEnhancedGeometry( SvXMLExport& rExport, const uno::Reference< beans::XPropertySet >& xPropSet )
4100 {
4101  bool bEquations = false;
4102  uno::Sequence< OUString > aEquations;
4103 
4104  bool bHandles = false;
4105  uno::Sequence< beans::PropertyValues > aHandles;
4106 
4107  uno::Sequence< css::drawing::EnhancedCustomShapeSegment > aSegments;
4108  uno::Sequence< css::drawing::EnhancedCustomShapeParameterPair > aCoordinates;
4109 
4110  uno::Sequence< css::drawing::EnhancedCustomShapeAdjustmentValue > aAdjustmentValues;
4111 
4112  OUString aStr;
4113  OUStringBuffer aStrBuffer;
4114  SvXMLUnitConverter& rUnitConverter = rExport.GetMM100UnitConverter();
4115 
4116  uno::Reference< beans::XPropertySetInfo > xPropSetInfo( xPropSet->getPropertySetInfo() );
4117 
4118  // geometry
4119  const OUString sCustomShapeGeometry( "CustomShapeGeometry" );
4120  if ( xPropSetInfo.is() && xPropSetInfo->hasPropertyByName( sCustomShapeGeometry ) )
4121  {
4122  uno::Any aGeoPropSet( xPropSet->getPropertyValue( sCustomShapeGeometry ) );
4123  uno::Sequence< beans::PropertyValue > aGeoPropSeq;
4124 
4125  if ( aGeoPropSet >>= aGeoPropSeq )
4126  {
4127  bool bCoordinates = false;
4128  OUString aCustomShapeType( "non-primitive" );
4129 
4130  for ( const beans::PropertyValue& rGeoProp : std::as_const(aGeoPropSeq) )
4131  {
4132  switch( EASGet( rGeoProp.Name ) )
4133  {
4134  case EAS_Type :
4135  {
4136  rGeoProp.Value >>= aCustomShapeType;
4137  }
4138  break;
4139  case EAS_MirroredX :
4140  {
4141  bool bMirroredX;
4142  if ( rGeoProp.Value >>= bMirroredX )
4144  bMirroredX ? GetXMLToken( XML_TRUE ) : GetXMLToken( XML_FALSE ) );
4145  }
4146  break;
4147  case EAS_MirroredY :
4148  {
4149  bool bMirroredY;
4150  if ( rGeoProp.Value >>= bMirroredY )
4152  bMirroredY ? GetXMLToken( XML_TRUE ) : GetXMLToken( XML_FALSE ) );
4153  }
4154  break;
4155  case EAS_ViewBox :
4156  {
4157  awt::Rectangle aRect;
4158  if ( rGeoProp.Value >>= aRect )
4159  {
4160  SdXMLImExViewBox aViewBox( aRect.X, aRect.Y, aRect.Width, aRect.Height );
4162  }
4163  }
4164  break;
4165  case EAS_TextPreRotateAngle :
4166  case EAS_TextRotateAngle :
4167  {
4168  double fTextRotateAngle = 0;
4169  if ( ( rGeoProp.Value >>= fTextRotateAngle ) && fTextRotateAngle != 0 )
4170  {
4172  aStrBuffer, fTextRotateAngle );
4173  aStr = aStrBuffer.makeStringAndClear();
4175  }
4176  }
4177  break;
4178  case EAS_Extrusion :
4179  {
4180  uno::Sequence< beans::PropertyValue > aExtrusionPropSeq;
4181  if ( rGeoProp.Value >>= aExtrusionPropSeq )
4182  {
4183  for ( const beans::PropertyValue& rProp : std::as_const(aExtrusionPropSeq) )
4184  {
4185  switch( EASGet( rProp.Name ) )
4186  {
4187  case EAS_Extrusion :
4188  {
4189  bool bExtrusionOn;
4190  if ( rProp.Value >>= bExtrusionOn )
4192  bExtrusionOn ? GetXMLToken( XML_TRUE ) : GetXMLToken( XML_FALSE ) );
4193  }
4194  break;
4195  case EAS_Brightness :
4196  {
4197  double fExtrusionBrightness = 0;
4198  if ( rProp.Value >>= fExtrusionBrightness )
4199  {
4201  aStrBuffer,
4202  fExtrusionBrightness,
4203  false,
4204  util::MeasureUnit::PERCENT,
4205  util::MeasureUnit::PERCENT);
4206  aStrBuffer.append( '%' );
4207  aStr = aStrBuffer.makeStringAndClear();
4209  }
4210  }
4211  break;
4212  case EAS_Depth :
4213  {
4214  css::drawing::EnhancedCustomShapeParameterPair aDepthParaPair;
4215  if ( rProp.Value >>= aDepthParaPair )
4216  {
4217  double fDepth = 0;
4218  if ( aDepthParaPair.First.Value >>= fDepth )
4219  {
4220  rExport.GetMM100UnitConverter().convertDouble( aStrBuffer, fDepth );
4221  ExportParameter( aStrBuffer, aDepthParaPair.Second );
4222  aStr = aStrBuffer.makeStringAndClear();
4224  }
4225  }
4226  }
4227  break;
4228  case EAS_Diffusion :
4229  {
4230  double fExtrusionDiffusion = 0;
4231  if ( rProp.Value >>= fExtrusionDiffusion )
4232  {
4234  aStrBuffer,
4235  fExtrusionDiffusion,
4236  false,
4237  util::MeasureUnit::PERCENT,
4238  util::MeasureUnit::PERCENT);
4239  aStrBuffer.append( '%' );
4240  aStr = aStrBuffer.makeStringAndClear();
4242  }
4243  }
4244  break;
4246  {
4247  sal_Int32 nExtrusionNumberOfLineSegments = 0;
4248  if ( rProp.Value >>= nExtrusionNumberOfLineSegments )
4249  rExport.AddAttribute( XML_NAMESPACE_DRAW, XML_EXTRUSION_NUMBER_OF_LINE_SEGMENTS, OUString::number( nExtrusionNumberOfLineSegments ) );
4250  }
4251  break;
4252  case EAS_LightFace :
4253  {
4254  bool bExtrusionLightFace;
4255  if ( rProp.Value >>= bExtrusionLightFace )
4257  bExtrusionLightFace ? GetXMLToken( XML_TRUE ) : GetXMLToken( XML_FALSE ) );
4258  }
4259  break;
4260  case EAS_FirstLightHarsh :
4261  {
4262  bool bExtrusionFirstLightHarsh;
4263  if ( rProp.Value >>= bExtrusionFirstLightHarsh )
4265  bExtrusionFirstLightHarsh ? GetXMLToken( XML_TRUE ) : GetXMLToken( XML_FALSE ) );
4266  }
4267  break;
4268  case EAS_SecondLightHarsh :
4269  {
4270  bool bExtrusionSecondLightHarsh;
4271  if ( rProp.Value >>= bExtrusionSecondLightHarsh )
4273  bExtrusionSecondLightHarsh ? GetXMLToken( XML_TRUE ) : GetXMLToken( XML_FALSE ) );
4274  }
4275  break;
4276  case EAS_FirstLightLevel :
4277  {
4278  double fExtrusionFirstLightLevel = 0;
4279  if ( rProp.Value >>= fExtrusionFirstLightLevel )
4280  {
4282  aStrBuffer,
4283  fExtrusionFirstLightLevel,
4284  false,
4285  util::MeasureUnit::PERCENT,
4286  util::MeasureUnit::PERCENT);
4287  aStrBuffer.append( '%' );
4288  aStr = aStrBuffer.makeStringAndClear();
4290  }
4291  }
4292  break;
4293  case EAS_SecondLightLevel :
4294  {
4295  double fExtrusionSecondLightLevel = 0;
4296  if ( rProp.Value >>= fExtrusionSecondLightLevel )
4297  {
4299  aStrBuffer,
4300  fExtrusionSecondLightLevel,
4301  false,
4302  util::MeasureUnit::PERCENT,
4303  util::MeasureUnit::PERCENT);
4304  aStrBuffer.append( '%' );
4305  aStr = aStrBuffer.makeStringAndClear();
4307  }
4308  }
4309  break;
4311  {
4312  drawing::Direction3D aExtrusionFirstLightDirection;
4313  if ( rProp.Value >>= aExtrusionFirstLightDirection )
4314  {
4315  ::basegfx::B3DVector aVec3D( aExtrusionFirstLightDirection.DirectionX, aExtrusionFirstLightDirection.DirectionY,
4316  aExtrusionFirstLightDirection.DirectionZ );
4317  SvXMLUnitConverter::convertB3DVector( aStrBuffer, aVec3D );
4318  aStr = aStrBuffer.makeStringAndClear();
4320  }
4321  }
4322  break;
4324  {
4325  drawing::Direction3D aExtrusionSecondLightDirection;
4326  if ( rProp.Value >>= aExtrusionSecondLightDirection )
4327  {
4328  ::basegfx::B3DVector aVec3D( aExtrusionSecondLightDirection.DirectionX, aExtrusionSecondLightDirection.DirectionY,
4329  aExtrusionSecondLightDirection.DirectionZ );
4330  SvXMLUnitConverter::convertB3DVector( aStrBuffer, aVec3D );
4331  aStr = aStrBuffer.makeStringAndClear();
4333  }
4334  }
4335  break;
4336  case EAS_Metal :
4337  {
4338  bool bExtrusionMetal;
4339  if ( rProp.Value >>= bExtrusionMetal )
4341  bExtrusionMetal ? GetXMLToken( XML_TRUE ) : GetXMLToken( XML_FALSE ) );
4342  }
4343  break;
4344  case EAS_ShadeMode :
4345  {
4346  // shadeMode
4347  drawing::ShadeMode eShadeMode;
4348  if( rProp.Value >>= eShadeMode )
4349  {
4350  if( eShadeMode == drawing::ShadeMode_FLAT )
4351  aStr = GetXMLToken( XML_FLAT );
4352  else if( eShadeMode == drawing::ShadeMode_PHONG )
4353  aStr = GetXMLToken( XML_PHONG );
4354  else if( eShadeMode == drawing::ShadeMode_SMOOTH )
4355  aStr = GetXMLToken( XML_GOURAUD );
4356  else
4357  aStr = GetXMLToken( XML_DRAFT );
4358  }
4359  else
4360  {
4361  // ShadeMode enum not there, write default
4362  aStr = GetXMLToken( XML_FLAT);
4363  }
4365  }
4366  break;
4367  case EAS_RotateAngle :
4368  {
4369  css::drawing::EnhancedCustomShapeParameterPair aRotateAngleParaPair;
4370  if ( rProp.Value >>= aRotateAngleParaPair )
4371  {
4372  ExportParameter( aStrBuffer, aRotateAngleParaPair.First );
4373  ExportParameter( aStrBuffer, aRotateAngleParaPair.Second );
4374  aStr = aStrBuffer.makeStringAndClear();
4376  }
4377  }
4378  break;
4379  case EAS_RotationCenter :
4380  {
4381  drawing::Direction3D aExtrusionRotationCenter;
4382  if ( rProp.Value >>= aExtrusionRotationCenter )
4383  {
4384  ::basegfx::B3DVector aVec3D( aExtrusionRotationCenter.DirectionX, aExtrusionRotationCenter.DirectionY,
4385  aExtrusionRotationCenter.DirectionZ );
4386  SvXMLUnitConverter::convertB3DVector( aStrBuffer, aVec3D );
4387  aStr = aStrBuffer.makeStringAndClear();
4389  }
4390  }
4391  break;
4392  case EAS_Shininess :
4393  {
4394  double fExtrusionShininess = 0;
4395  if ( rProp.Value >>= fExtrusionShininess )
4396  {
4398  aStrBuffer,
4399  fExtrusionShininess,
4400  false,
4401  util::MeasureUnit::PERCENT,
4402  util::MeasureUnit::PERCENT);
4403  aStrBuffer.append( '%' );
4404  aStr = aStrBuffer.makeStringAndClear();
4406  }
4407  }
4408  break;
4409  case EAS_Skew :
4410  {
4411  css::drawing::EnhancedCustomShapeParameterPair aSkewParaPair;
4412  if ( rProp.Value >>= aSkewParaPair )
4413  {
4414  ExportParameter( aStrBuffer, aSkewParaPair.First );
4415  ExportParameter( aStrBuffer, aSkewParaPair.Second );
4416  aStr = aStrBuffer.makeStringAndClear();
4418  }
4419  }
4420  break;
4421  case EAS_Specularity :
4422  {
4423  double fExtrusionSpecularity = 0;
4424  if ( rProp.Value >>= fExtrusionSpecularity )
4425  {
4427  aStrBuffer,
4428  fExtrusionSpecularity,
4429  false,
4430  util::MeasureUnit::PERCENT,
4431  util::MeasureUnit::PERCENT);
4432  aStrBuffer.append( '%' );
4433  aStr = aStrBuffer.makeStringAndClear();
4435  }
4436  }
4437  break;
4438  case EAS_ProjectionMode :
4439  {
4440  drawing::ProjectionMode eProjectionMode;
4441  if ( rProp.Value >>= eProjectionMode )
4443  eProjectionMode == drawing::ProjectionMode_PARALLEL ? GetXMLToken( XML_PARALLEL ) : GetXMLToken( XML_PERSPECTIVE ) );
4444  }
4445  break;
4446  case EAS_ViewPoint :
4447  {
4448  drawing::Position3D aExtrusionViewPoint;
4449  if ( rProp.Value >>= aExtrusionViewPoint )
4450  {
4451  rUnitConverter.convertPosition3D( aStrBuffer, aExtrusionViewPoint );
4452  aStr = aStrBuffer.makeStringAndClear();
4454  }
4455  }
4456  break;
4457  case EAS_Origin :
4458  {
4459  css::drawing::EnhancedCustomShapeParameterPair aOriginParaPair;
4460  if ( rProp.Value >>= aOriginParaPair )
4461  {
4462  ExportParameter( aStrBuffer, aOriginParaPair.First );
4463  ExportParameter( aStrBuffer, aOriginParaPair.Second );
4464  aStr = aStrBuffer.makeStringAndClear();
4466  }
4467  }
4468  break;
4469  case EAS_Color :
4470  {
4471  bool bExtrusionColor;
4472  if ( rProp.Value >>= bExtrusionColor )
4473  {
4475  bExtrusionColor ? GetXMLToken( XML_TRUE ) : GetXMLToken( XML_FALSE ) );
4476  }
4477  }
4478  break;
4479  default:
4480  break;
4481  }
4482  }
4483  }
4484  }
4485  break;
4486  case EAS_TextPath :
4487  {
4488  uno::Sequence< beans::PropertyValue > aTextPathPropSeq;
4489  if ( rGeoProp.Value >>= aTextPathPropSeq )
4490  {
4491  for ( const beans::PropertyValue& rProp : std::as_const(aTextPathPropSeq) )
4492  {
4493  switch( EASGet( rProp.Name ) )
4494  {
4495  case EAS_TextPath :
4496  {
4497  bool bTextPathOn;
4498  if ( rProp.Value >>= bTextPathOn )
4500  bTextPathOn ? GetXMLToken( XML_TRUE ) : GetXMLToken( XML_FALSE ) );
4501  }
4502  break;
4503  case EAS_TextPathMode :
4504  {
4505  css::drawing::EnhancedCustomShapeTextPathMode eTextPathMode;
4506  if ( rProp.Value >>= eTextPathMode )
4507  {
4508  switch ( eTextPathMode )
4509  {
4510  case css::drawing::EnhancedCustomShapeTextPathMode_NORMAL: aStr = GetXMLToken( XML_NORMAL ); break;
4511  case css::drawing::EnhancedCustomShapeTextPathMode_PATH : aStr = GetXMLToken( XML_PATH ); break;
4512  case css::drawing::EnhancedCustomShapeTextPathMode_SHAPE : aStr = GetXMLToken( XML_SHAPE ); break;
4513  default:
4514  break;
4515  }
4516  if ( !aStr.isEmpty() )
4518  }
4519  }
4520  break;
4521  case EAS_ScaleX :
4522  {
4523  bool bScaleX;
4524  if ( rProp.Value >>= bScaleX )
4525  {
4526  aStr = bScaleX ? GetXMLToken( XML_SHAPE ) : GetXMLToken( XML_PATH );
4528  }
4529  }
4530  break;
4531  case EAS_SameLetterHeights :
4532  {
4533  bool bSameLetterHeights;
4534  if ( rProp.Value >>= bSameLetterHeights )
4536  bSameLetterHeights ? GetXMLToken( XML_TRUE ) : GetXMLToken( XML_FALSE ) );
4537  }
4538  break;
4539  default:
4540  break;
4541  }
4542  }
4543  }
4544  }
4545  break;
4546  case EAS_Path :
4547  {
4548  uno::Sequence< beans::PropertyValue > aPathPropSeq;
4549  if ( rGeoProp.Value >>= aPathPropSeq )
4550  {
4551  for ( const beans::PropertyValue& rProp : std::as_const(aPathPropSeq) )
4552  {
4553  switch( EASGet( rProp.Name ) )
4554  {
4555  case EAS_SubViewSize:
4556  {
4557  // export draw:sub-view-size (do not export in ODF 1.3 or older)
4559  {
4560  continue;
4561  }
4562  uno::Sequence< awt::Size > aSubViewSizes;
4563  rProp.Value >>= aSubViewSizes;
4564 
4565  for ( int nIdx = 0; nIdx < aSubViewSizes.getLength(); nIdx++ )
4566  {
4567  if ( nIdx )
4568  aStrBuffer.append(' ');
4569  aStrBuffer.append( aSubViewSizes[nIdx].Width );
4570  aStrBuffer.append(' ');
4571  aStrBuffer.append( aSubViewSizes[nIdx].Height );
4572  }
4573  aStr = aStrBuffer.makeStringAndClear();
4575  }
4576  break;
4577  case EAS_ExtrusionAllowed :
4578  {
4579  bool bExtrusionAllowed;
4580  if ( rProp.Value >>= bExtrusionAllowed )
4582  bExtrusionAllowed ? GetXMLToken( XML_TRUE ) : GetXMLToken( XML_FALSE ) );
4583  }
4584  break;
4586  {
4587  bool bConcentricGradientFillAllowed;
4588  if ( rProp.Value >>= bConcentricGradientFillAllowed )
4590  bConcentricGradientFillAllowed ? GetXMLToken( XML_TRUE ) : GetXMLToken( XML_FALSE ) );
4591  }
4592  break;
4593  case EAS_TextPathAllowed :
4594  {
4595  bool bTextPathAllowed;
4596  if ( rProp.Value >>= bTextPathAllowed )
4598  bTextPathAllowed ? GetXMLToken( XML_TRUE ) : GetXMLToken( XML_FALSE ) );
4599  }
4600  break;
4601  case EAS_GluePoints :
4602  {
4603  css::uno::Sequence< css::drawing::EnhancedCustomShapeParameterPair> aGluePoints;
4604  if ( rProp.Value >>= aGluePoints )
4605  {
4606  if ( aGluePoints.hasElements() )
4607  {
4608  for( const auto& rGluePoint : std::as_const(aGluePoints) )
4609  {
4610  ExportParameter( aStrBuffer, rGluePoint.First );
4611  ExportParameter( aStrBuffer, rGluePoint.Second );
4612  }
4613  aStr = aStrBuffer.makeStringAndClear();
4614  }
4616  }
4617  }
4618  break;
4619  case EAS_GluePointType :
4620  {
4621  sal_Int16 nGluePointType = sal_Int16();
4622  if ( rProp.Value >>= nGluePointType )
4623  {
4624  switch ( nGluePointType )
4625  {
4626  case css::drawing::EnhancedCustomShapeGluePointType::NONE : aStr = GetXMLToken( XML_NONE ); break;
4627  case css::drawing::EnhancedCustomShapeGluePointType::SEGMENTS : aStr = GetXMLToken( XML_SEGMENTS ); break;
4628  case css::drawing::EnhancedCustomShapeGluePointType::RECT : aStr = GetXMLToken( XML_RECTANGLE ); break;
4629  }
4630  if ( !aStr.isEmpty() )
4632  }
4633  }
4634  break;
4635  case EAS_Coordinates :
4636  {
4637  bCoordinates = ( rProp.Value >>= aCoordinates );
4638  }
4639  break;
4640  case EAS_Segments :
4641  {
4642  rProp.Value >>= aSegments;
4643  }
4644  break;
4645  case EAS_StretchX :
4646  {
4647  sal_Int32 nStretchPoint = 0;
4648  if ( rProp.Value >>= nStretchPoint )
4649  rExport.AddAttribute( XML_NAMESPACE_DRAW, XML_PATH_STRETCHPOINT_X, OUString::number( nStretchPoint ) );
4650  }
4651  break;
4652  case EAS_StretchY :
4653  {
4654  sal_Int32 nStretchPoint = 0;
4655  if ( rProp.Value >>= nStretchPoint )
4656  rExport.AddAttribute( XML_NAMESPACE_DRAW, XML_PATH_STRETCHPOINT_Y, OUString::number( nStretchPoint ) );
4657  }
4658  break;
4659  case EAS_TextFrames :
4660  {
4661  css::uno::Sequence< css::drawing::EnhancedCustomShapeTextFrame > aPathTextFrames;
4662  if ( rProp.Value >>= aPathTextFrames )
4663  {
4664  if ( aPathTextFrames.hasElements() )
4665  {
4666  for ( const auto& rPathTextFrame : std::as_const(aPathTextFrames) )
4667  {
4668  ExportParameter( aStrBuffer, rPathTextFrame.TopLeft.First );
4669  ExportParameter( aStrBuffer, rPathTextFrame.TopLeft.Second );
4670  ExportParameter( aStrBuffer, rPathTextFrame.BottomRight.First );
4671  ExportParameter( aStrBuffer, rPathTextFrame.BottomRight.Second );
4672  }
4673  aStr = aStrBuffer.makeStringAndClear();
4674  }
4676  }
4677  }
4678  break;
4679  default:
4680  break;
4681  }
4682  }
4683  }
4684  }
4685  break;
4686  case EAS_Equations :
4687  {
4688  bEquations = ( rGeoProp.Value >>= aEquations );
4689  }
4690  break;
4691  case EAS_Handles :
4692  {
4693  bHandles = ( rGeoProp.Value >>= aHandles );
4694  }
4695  break;
4696  case EAS_AdjustmentValues :
4697  {
4698  rGeoProp.Value >>= aAdjustmentValues;
4699  }
4700  break;
4701  default:
4702  break;
4703  }
4704  } // for
4705  rExport.AddAttribute( XML_NAMESPACE_DRAW, XML_TYPE, aCustomShapeType );
4706 
4707  // adjustments
4708  sal_Int32 nAdjustmentValues = aAdjustmentValues.getLength();
4709  if ( nAdjustmentValues )
4710  {
4711  sal_Int32 i, nValue = 0;
4712  for ( i = 0; i < nAdjustmentValues; i++ )
4713  {
4714  if ( i )
4715  aStrBuffer.append( ' ' );
4716 
4717  const css::drawing::EnhancedCustomShapeAdjustmentValue& rAdj = aAdjustmentValues[ i ];
4718  if ( rAdj.State == beans::PropertyState_DIRECT_VALUE )
4719  {
4720  if ( rAdj.Value.getValueTypeClass() == uno::TypeClass_DOUBLE )
4721  {
4722  double fValue = 0.0;
4723  rAdj.Value >>= fValue;
4724  ::sax::Converter::convertDouble(aStrBuffer, fValue);
4725  }
4726  else
4727  {
4728  rAdj.Value >>= nValue;
4729  aStrBuffer.append(nValue);
4730  }
4731  }
4732  else
4733  {
4734  // this should not be, but better than setting nothing
4735  aStrBuffer.append("0");
4736  }
4737  }
4738  aStr = aStrBuffer.makeStringAndClear();
4739  rExport.AddAttribute( XML_NAMESPACE_DRAW, XML_MODIFIERS, aStr );
4740  }
4741  if ( bCoordinates )
4742  ImpExportEnhancedPath( rExport, aCoordinates, aSegments );
4743  }
4744  }
4745  SvXMLElementExport aOBJ( rExport, XML_NAMESPACE_DRAW, XML_ENHANCED_GEOMETRY, true, true );
4746  if ( bEquations )
4747  ImpExportEquations( rExport, aEquations );
4748  if ( bHandles )
4749  ImpExportHandles( rExport, aHandles );
4750 }
4751 
4753  const uno::Reference< drawing::XShape >& xShape,
4754  XMLShapeExportFlags nFeatures, css::awt::Point* pRefPoint )
4755 {
4756  const uno::Reference< beans::XPropertySet > xPropSet(xShape, uno::UNO_QUERY);
4757  if ( !xPropSet.is() )
4758  return;
4759 
4760  uno::Reference< beans::XPropertySetInfo > xPropSetInfo( xPropSet->getPropertySetInfo() );
4761 
4762  // Transformation
4763  ImpExportNewTrans( xPropSet, nFeatures, pRefPoint );
4764 
4765  if ( xPropSetInfo.is() )
4766  {
4767  OUString aStr;
4768  if ( xPropSetInfo->hasPropertyByName( "CustomShapeEngine" ) )
4769  {
4770  uno::Any aEngine( xPropSet->getPropertyValue( "CustomShapeEngine" ) );
4771  if ( ( aEngine >>= aStr ) && !aStr.isEmpty() )
4773  }
4774  if ( xPropSetInfo->hasPropertyByName( "CustomShapeData" ) )
4775  {
4776  uno::Any aData( xPropSet->getPropertyValue( "CustomShapeData" ) );
4777  if ( ( aData >>= aStr ) && !aStr.isEmpty() )
4779  }
4780  }
4781  bool bCreateNewline( (nFeatures & XMLShapeExportFlags::NO_WS) == XMLShapeExportFlags::NONE ); // #86116#/#92210#
4782  SvXMLElementExport aOBJ( mrExport, XML_NAMESPACE_DRAW, XML_CUSTOM_SHAPE, bCreateNewline, true );
4783  ImpExportDescription( xShape ); // #i68101#
4784  ImpExportEvents( xShape );
4785  ImpExportGluePoints( xShape );
4786  ImpExportText( xShape );
4787  ImpExportEnhancedGeometry( mrExport, xPropSet );
4788 
4789 }
4790 
4791 void XMLShapeExport::ImpExportTableShape( const uno::Reference< drawing::XShape >& xShape, XmlShapeType eShapeType, XMLShapeExportFlags nFeatures, css::awt::Point* pRefPoint )
4792 {
4793  uno::Reference< beans::XPropertySet > xPropSet(xShape, uno::UNO_QUERY);
4794  uno::Reference< container::XNamed > xNamed(xShape, uno::UNO_QUERY);
4795 
4796  SAL_WARN_IF( !xPropSet.is() || !xNamed.is(), "xmloff", "xmloff::XMLShapeExport::ImpExportTableShape(), table shape is not implementing needed interfaces");
4797  if(!(xPropSet.is() && xNamed.is()))
4798  return;
4799 
4800  try
4801  {
4802  // Transformation
4803  ImpExportNewTrans(xPropSet, nFeatures, pRefPoint);
4804 
4805  bool bIsEmptyPresObj = false;
4806 
4807  // presentation settings
4808  if(eShapeType == XmlShapeTypePresTableShape)
4809  bIsEmptyPresObj = ImpExportPresentationAttributes( xPropSet, GetXMLToken(XML_TABLE) );
4810 
4811  const bool bCreateNewline( (nFeatures & XMLShapeExportFlags::NO_WS) == XMLShapeExportFlags::NONE );
4812  const bool bExportEmbedded(mrExport.getExportFlags() & SvXMLExportFlags::EMBEDDED);
4813 
4814  SvXMLElementExport aElement( mrExport, XML_NAMESPACE_DRAW, XML_FRAME, bCreateNewline, true );
4815 
4816  // do not export in ODF 1.1 or older
4818  {
4819  if( !bIsEmptyPresObj )
4820  {
4821  uno::Reference< container::XNamed > xTemplate( xPropSet->getPropertyValue("TableTemplate"), uno::UNO_QUERY );
4822  if( xTemplate.is() )
4823  {
4824  const OUString sTemplate( xTemplate->getName() );
4825  if( !sTemplate.isEmpty() )
4826  {
4828 
4829  for( const XMLPropertyMapEntry* pEntry = &aXMLTableShapeAttributes[0]; pEntry->msApiName; pEntry++ )
4830  {
4831  try
4832  {
4833  bool bBool = false;
4834  const OUString sAPIPropertyName( pEntry->msApiName, pEntry->nApiNameLength, RTL_TEXTENCODING_ASCII_US );
4835 
4836  xPropSet->getPropertyValue( sAPIPropertyName ) >>= bBool;
4837  if( bBool )
4838  mrExport.AddAttribute(pEntry->mnNameSpace, pEntry->meXMLName, XML_TRUE );
4839  }
4840  catch( uno::Exception& )
4841  {
4842  DBG_UNHANDLED_EXCEPTION("xmloff.draw");
4843  }
4844  }
4845  }
4846  }
4847 
4848  uno::Reference< table::XColumnRowRange > xRange( xPropSet->getPropertyValue( gsModel ), uno::UNO_QUERY_THROW );
4849  GetShapeTableExport()->exportTable( xRange );
4850  }
4851  }
4852 
4853  if( !bIsEmptyPresObj )
4854  {
4855  uno::Reference< graphic::XGraphic > xGraphic( xPropSet->getPropertyValue("ReplacementGraphic"), uno::UNO_QUERY );
4856  if( xGraphic.is() ) try
4857  {
4858  uno::Reference< uno::XComponentContext > xContext = GetExport().getComponentContext();
4859 
4860  uno::Reference< embed::XStorage > xPictureStorage;
4861  uno::Reference< embed::XStorage > xStorage;
4862  uno::Reference< io::XStream > xPictureStream;
4863 
4864  OUString sPictureName;
4865  if( bExportEmbedded )
4866  {
4867  xPictureStream.set( xContext->getServiceManager()->createInstanceWithContext( "com.sun.star.comp.MemoryStream", xContext), uno::UNO_QUERY_THROW );
4868  }
4869  else
4870  {
4871  xStorage.set( GetExport().GetTargetStorage(), uno::UNO_SET_THROW );
4872 
4873  xPictureStorage.set( xStorage->openStorageElement( "Pictures" , ::embed::ElementModes::READWRITE ), uno::UNO_SET_THROW );
4874 
4875  sal_Int32 nIndex = 0;
4876  do
4877  {
4878  sPictureName = "TablePreview" + OUString::number( ++nIndex ) + ".svm";
4879  }
4880  while( xPictureStorage->hasByName( sPictureName ) );
4881 
4882  xPictureStream.set( xPictureStorage->openStreamElement( sPictureName, ::embed::ElementModes::READWRITE ), uno::UNO_SET_THROW );
4883  }
4884 
4885  uno::Reference< graphic::XGraphicProvider > xProvider( graphic::GraphicProvider::create(xContext) );
4886  uno::Sequence< beans::PropertyValue > aArgs( 2 );
4887  aArgs[ 0 ].Name = "MimeType";
4888  aArgs[ 0 ].Value <<= OUString( "image/x-vclgraphic" );
4889  aArgs[ 1 ].Name = "OutputStream";
4890  aArgs[ 1 ].Value <<= xPictureStream->getOutputStream();
4891  xProvider->storeGraphic( xGraphic, aArgs );
4892 
4893  if( xPictureStorage.is() )
4894  {
4895  uno::Reference< embed::XTransactedObject > xTrans( xPictureStorage, uno::UNO_QUERY );
4896  if( xTrans.is() )
4897  xTrans->commit();
4898  }
4899 
4900  if( !bExportEmbedded )
4901  {
4902  OUString sURL = "Pictures/" + sPictureName;
4907  }
4908 
4909  SvXMLElementExport aElem( GetExport(), XML_NAMESPACE_DRAW, XML_IMAGE, false, true );
4910 
4911  if( bExportEmbedded )
4912  {
4913  uno::Reference< io::XSeekableInputStream > xSeekable( xPictureStream, uno::UNO_QUERY_THROW );
4914  xSeekable->seek(0);
4915 
4916  XMLBase64Export aBase64Exp( GetExport() );
4917  aBase64Exp.exportOfficeBinaryDataElement( uno::Reference < io::XInputStream >( xPictureStream, uno::UNO_QUERY_THROW ) );
4918  }
4919  }
4920  catch( uno::Exception const & )
4921  {
4922  DBG_UNHANDLED_EXCEPTION("xmloff.draw");
4923  }
4924  }
4925 
4926  ImpExportEvents( xShape );
4927  ImpExportGluePoints( xShape );
4928  ImpExportDescription( xShape ); // #i68101#
4929  }
4930  catch( uno::Exception const & )
4931  {
4932  DBG_UNHANDLED_EXCEPTION("xmloff.draw");
4933  }
4934 }
4935 
4936 /* 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:318
constexpr sal_uInt16 XML_NAMESPACE_OFFICE
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
SAL_DLLPRIVATE void ImpCalcShapeType(const css::uno::Reference< css::drawing::XShape > &xShape, XmlShapeType &eShapeType)
SAL_DLLPRIVATE bool ImpExportPresentationAttributes(const css::uno::Reference< css::beans::XPropertySet > &xPropSet, const OUString &rClass)
EnhancedCustomShapeTokenEnum EASGet(const OUString &rShapeType)
ShapesInfos maShapesInfos
XmlShapeType
Definition: shapeexport.hxx: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:80
#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
static bool convertB3DVector(::basegfx::B3DVector &rVector, std::u16string_view rValue)
convert string to basegfx::B3DVector
Definition: xmluconv.cxx:591
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
XMLShapeExport(SvXMLExport &rExp, SvXMLExportPropertyMapper *pExtMapper=nullptr)