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