summaryrefslogtreecommitdiffstats
path: root/xmloff/source/draw
diff options
context:
space:
mode:
Diffstat (limited to 'xmloff/source/draw')
-rw-r--r--xmloff/source/draw/EnhancedCustomShapeToken.cxx214
-rw-r--r--xmloff/source/draw/QRCodeContext.cxx91
-rw-r--r--xmloff/source/draw/QRCodeContext.hxx26
-rw-r--r--xmloff/source/draw/SignatureLineContext.cxx136
-rw-r--r--xmloff/source/draw/SignatureLineContext.hxx25
-rw-r--r--xmloff/source/draw/XMLGraphicsDefaultStyle.cxx188
-rw-r--r--xmloff/source/draw/XMLImageMapContext.cxx541
-rw-r--r--xmloff/source/draw/XMLImageMapExport.cxx339
-rw-r--r--xmloff/source/draw/XMLNumberStyles.cxx712
-rw-r--r--xmloff/source/draw/XMLNumberStylesExport.hxx40
-rw-r--r--xmloff/source/draw/XMLReplacementImageContext.cxx99
-rw-r--r--xmloff/source/draw/XMLShapePropertySetContext.cxx94
-rw-r--r--xmloff/source/draw/XMLShapeStyleContext.cxx323
-rw-r--r--xmloff/source/draw/animationexport.cxx1742
-rw-r--r--xmloff/source/draw/animationimport.cxx1356
-rw-r--r--xmloff/source/draw/animexp.cxx511
-rw-r--r--xmloff/source/draw/animimp.cxx597
-rw-r--r--xmloff/source/draw/descriptionimp.cxx75
-rw-r--r--xmloff/source/draw/descriptionimp.hxx46
-rw-r--r--xmloff/source/draw/eventimp.cxx453
-rw-r--r--xmloff/source/draw/eventimp.hxx68
-rw-r--r--xmloff/source/draw/layerexp.cxx128
-rw-r--r--xmloff/source/draw/layerexp.hxx30
-rw-r--r--xmloff/source/draw/layerimp.cxx195
-rw-r--r--xmloff/source/draw/layerimp.hxx41
-rw-r--r--xmloff/source/draw/numithdl.cxx54
-rw-r--r--xmloff/source/draw/numithdl.hxx43
-rw-r--r--xmloff/source/draw/propimp0.cxx262
-rw-r--r--xmloff/source/draw/sdpropls.cxx1923
-rw-r--r--xmloff/source/draw/sdpropls.hxx131
-rw-r--r--xmloff/source/draw/sdxmlexp.cxx2853
-rw-r--r--xmloff/source/draw/sdxmlexp_impl.hxx179
-rw-r--r--xmloff/source/draw/sdxmlimp.cxx678
-rw-r--r--xmloff/source/draw/sdxmlimp_impl.hxx135
-rw-r--r--xmloff/source/draw/shapeexport.cxx5183
-rw-r--r--xmloff/source/draw/shapeimport.cxx951
-rw-r--r--xmloff/source/draw/xexptran.cxx1056
-rw-r--r--xmloff/source/draw/ximp3dobject.cxx369
-rw-r--r--xmloff/source/draw/ximp3dobject.hxx136
-rw-r--r--xmloff/source/draw/ximp3dscene.cxx441
-rw-r--r--xmloff/source/draw/ximp3dscene.hxx52
-rw-r--r--xmloff/source/draw/ximpbody.cxx365
-rw-r--r--xmloff/source/draw/ximpbody.hxx59
-rw-r--r--xmloff/source/draw/ximpcustomshape.cxx1421
-rw-r--r--xmloff/source/draw/ximpcustomshape.hxx66
-rw-r--r--xmloff/source/draw/ximpgrp.cxx100
-rw-r--r--xmloff/source/draw/ximpgrp.hxx49
-rw-r--r--xmloff/source/draw/ximplink.cxx67
-rw-r--r--xmloff/source/draw/ximplink.hxx47
-rw-r--r--xmloff/source/draw/ximpnote.cxx92
-rw-r--r--xmloff/source/draw/ximpnote.hxx36
-rw-r--r--xmloff/source/draw/ximppage.cxx600
-rw-r--r--xmloff/source/draw/ximppage.hxx77
-rw-r--r--xmloff/source/draw/ximpshap.cxx4021
-rw-r--r--xmloff/source/draw/ximpshap.hxx648
-rw-r--r--xmloff/source/draw/ximpshow.cxx243
-rw-r--r--xmloff/source/draw/ximpshow.hxx49
-rw-r--r--xmloff/source/draw/ximpstyl.cxx1466
-rw-r--r--xmloff/source/draw/ximpstyl.hxx247
59 files changed, 32169 insertions, 0 deletions
diff --git a/xmloff/source/draw/EnhancedCustomShapeToken.cxx b/xmloff/source/draw/EnhancedCustomShapeToken.cxx
new file mode 100644
index 0000000000..d8c54a3704
--- /dev/null
+++ b/xmloff/source/draw/EnhancedCustomShapeToken.cxx
@@ -0,0 +1,214 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#include <EnhancedCustomShapeToken.hxx>
+#include <xmloff/xmlimp.hxx>
+#include <unordered_map>
+#include <memory>
+
+namespace xmloff::EnhancedCustomShapeToken {
+
+
+namespace {
+
+struct TokenTable
+{
+ const char* pS;
+ EnhancedCustomShapeTokenEnum pE;
+};
+
+}
+
+const TokenTable pTokenTableArray[] =
+{
+ { "type", EAS_type },
+ { "name", EAS_name },
+ { "mirror-horizontal", EAS_mirror_horizontal },
+ { "mirror-vertical", EAS_mirror_vertical },
+ { "viewBox", EAS_viewBox },
+ { "text-rotate-angle", EAS_text_rotate_angle },
+ { "extrusion-allowed", EAS_extrusion_allowed },
+ { "extrusion-text-path-allowed", EAS_text_path_allowed },
+ { "extrusion-concentric-gradient-fill", EAS_concentric_gradient_fill_allowed },
+ { "extrusion", EAS_extrusion },
+ { "extrusion-brightness", EAS_extrusion_brightness },
+ { "extrusion-depth", EAS_extrusion_depth },
+ { "extrusion-diffusion", EAS_extrusion_diffusion },
+ { "extrusion-number-of-line-segments", EAS_extrusion_number_of_line_segments },
+ { "extrusion-light-face", EAS_extrusion_light_face },
+ { "extrusion-first-light-harsh", EAS_extrusion_first_light_harsh },
+ { "extrusion-second-light-harsh", EAS_extrusion_second_light_harsh },
+ { "extrusion-first-light-level", EAS_extrusion_first_light_level },
+ { "extrusion-second-light-level", EAS_extrusion_second_light_level },
+ { "extrusion-first-light-direction", EAS_extrusion_first_light_direction },
+ { "extrusion-second-light-direction", EAS_extrusion_second_light_direction },
+ { "extrusion-metal", EAS_extrusion_metal },
+ { "extrusion-metal-type", EAS_extrusion_metal_type },
+ { "shade-mode", EAS_shade_mode },
+ { "extrusion-rotation-angle", EAS_extrusion_rotation_angle },
+ { "extrusion-rotation-center", EAS_extrusion_rotation_center },
+ { "extrusion-shininess", EAS_extrusion_shininess },
+ { "extrusion-skew", EAS_extrusion_skew },
+ { "extrusion-specularity", EAS_extrusion_specularity },
+ { "extrusion-specularity-loext", EAS_extrusion_specularity_loext },
+ { "projection", EAS_projection },
+ { "extrusion-viewpoint", EAS_extrusion_viewpoint },
+ { "extrusion-origin", EAS_extrusion_origin },
+ { "extrusion-color", EAS_extrusion_color },
+ { "enhanced-path", EAS_enhanced_path },
+ { "path-stretchpoint-x", EAS_path_stretchpoint_x },
+ { "path-stretchpoint-y", EAS_path_stretchpoint_y },
+ { "text-areas", EAS_text_areas },
+ { "glue-points", EAS_glue_points },
+ { "glue-point-type", EAS_glue_point_type },
+ { "glue-point-leaving-directions", EAS_glue_point_leaving_directions },
+ { "text-path", EAS_text_path },
+ { "text-path-mode", EAS_text_path_mode },
+ { "text-path-scale", EAS_text_path_scale },
+ { "text-path-same-letter-heights", EAS_text_path_same_letter_heights },
+ { "modifiers", EAS_modifiers },
+ { "equation", EAS_equation },
+ { "formula", EAS_formula },
+ { "handle", EAS_handle },
+ { "handle-mirror-horizontal", EAS_handle_mirror_horizontal },
+ { "handle-mirror-vertical", EAS_handle_mirror_vertical },
+ { "handle-switched", EAS_handle_switched },
+ { "handle-position", EAS_handle_position },
+ { "handle-range-x-minimum", EAS_handle_range_x_minimum },
+ { "handle-range-x-maximum", EAS_handle_range_x_maximum },
+ { "handle-range-y-minimum", EAS_handle_range_y_minimum },
+ { "handle-range-y-maximum", EAS_handle_range_y_maximum },
+ { "handle-polar", EAS_handle_polar },
+ { "handle-radius-range-minimum", EAS_handle_radius_range_minimum },
+ { "handle-radius-range-maximum", EAS_handle_radius_range_maximum },
+ { "sub-view-size", EAS_sub_view_size },
+
+ { "CustomShapeEngine", EAS_CustomShapeEngine },
+ { "CustomShapeData", EAS_CustomShapeData },
+ { "Type", EAS_Type },
+ { "MirroredX", EAS_MirroredX },
+ { "MirroredY", EAS_MirroredY },
+ { "ViewBox", EAS_ViewBox },
+ { "TextRotateAngle", EAS_TextRotateAngle },
+ { "TextPreRotateAngle", EAS_TextPreRotateAngle },
+ { "ExtrusionAllowed", EAS_ExtrusionAllowed },
+ { "TextPathAllowed", EAS_TextPathAllowed },
+ { "ConcentricGradientFillAllowed", EAS_ConcentricGradientFillAllowed },
+ { "Extrusion", EAS_Extrusion },
+ { "Equations", EAS_Equations },
+ { "Equation", EAS_Equation },
+ { "Path", EAS_Path },
+ { "TextPath", EAS_TextPath },
+ { "Handles", EAS_Handles },
+ { "Handle", EAS_Handle },
+ { "Brightness", EAS_Brightness },
+ { "Depth", EAS_Depth },
+ { "Diffusion", EAS_Diffusion },
+ { "NumberOfLineSegments", EAS_NumberOfLineSegments },
+ { "LightFace", EAS_LightFace },
+ { "FirstLightHarsh", EAS_FirstLightHarsh },
+ { "SecondLightHarsh", EAS_SecondLightHarsh },
+ { "FirstLightLevel", EAS_FirstLightLevel },
+ { "SecondLightLevel", EAS_SecondLightLevel },
+ { "FirstLightDirection", EAS_FirstLightDirection },
+ { "SecondLightDirection", EAS_SecondLightDirection },
+ { "Metal", EAS_Metal },
+ { "MetalType", EAS_MetalType },
+ { "ShadeMode", EAS_ShadeMode },
+ { "RotateAngle", EAS_RotateAngle },
+ { "RotationCenter", EAS_RotationCenter },
+ { "Shininess", EAS_Shininess },
+ { "Skew", EAS_Skew },
+ { "Specularity", EAS_Specularity },
+ { "ProjectionMode", EAS_ProjectionMode },
+ { "ViewPoint", EAS_ViewPoint },
+ { "Origin", EAS_Origin },
+ { "Color", EAS_Color },
+ { "Switched", EAS_Switched },
+ { "Polar", EAS_Polar },
+ { "RangeXMinimum", EAS_RangeXMinimum },
+ { "RangeXMaximum", EAS_RangeXMaximum },
+ { "RangeYMinimum", EAS_RangeYMinimum },
+ { "RangeYMaximum", EAS_RangeYMaximum },
+ { "RadiusRangeMinimum", EAS_RadiusRangeMinimum },
+ { "RadiusRangeMaximum", EAS_RadiusRangeMaximum },
+ { "Coordinates", EAS_Coordinates },
+ { "Segments", EAS_Segments },
+ { "StretchX", EAS_StretchX },
+ { "StretchY", EAS_StretchY },
+ { "TextFrames", EAS_TextFrames },
+ { "GluePoints", EAS_GluePoints },
+ { "GluePointLeavingDirections", EAS_GluePointLeavingDirections },
+ { "GluePointType", EAS_GluePointType },
+ { "TextPathMode", EAS_TextPathMode },
+ { "ScaleX", EAS_ScaleX },
+ { "SameLetterHeights", EAS_SameLetterHeights },
+ { "Position", EAS_Position },
+ { "AdjustmentValues", EAS_AdjustmentValues },
+ { "SubViewSize", EAS_SubViewSize },
+
+ { "Last", EAS_Last },
+ { "NotFound", EAS_NotFound }
+};
+
+typedef std::unordered_map< const char*, EnhancedCustomShapeTokenEnum, rtl::CStringHash, rtl::CStringEqual> TypeNameHashMap;
+static const TypeNameHashMap& GetNameHashMap()
+{
+ static TypeNameHashMap aHashMap = []()
+ { // init hash map
+ TypeNameHashMap res;
+ for (auto const & pair : pTokenTableArray)
+ res[pair.pS] = pair.pE;
+ return res;
+ }();
+
+ return aHashMap;
+}
+
+EnhancedCustomShapeTokenEnum EASGet( std::u16string_view rShapeType )
+{
+ EnhancedCustomShapeTokenEnum eRetValue = EAS_NotFound;
+ size_t i, nLen = rShapeType.size();
+ std::unique_ptr<char[]> pBuf(new char[ nLen + 1 ]);
+ for ( i = 0; i < nLen; i++ )
+ pBuf[ i ] = static_cast<char>(rShapeType[ i ]);
+ pBuf[ i ] = 0;
+ auto& rHashMap = GetNameHashMap();
+ TypeNameHashMap::const_iterator aHashIter( rHashMap.find( pBuf.get() ) );
+ if ( aHashIter != rHashMap.end() )
+ eRetValue = (*aHashIter).second;
+ return eRetValue;
+}
+
+EnhancedCustomShapeTokenEnum EASGet( sal_Int32 nToken )
+{
+ return EASGet(SvXMLImport::getNameFromToken(nToken));
+}
+
+OUString EASGet( const EnhancedCustomShapeTokenEnum eToken )
+{
+ sal_uInt32 i = eToken >= EAS_Last
+ ? sal_uInt32(EAS_NotFound)
+ : static_cast<sal_uInt32>(eToken);
+ return OUString::createFromAscii( pTokenTableArray[ i ].pS );
+}
+
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/xmloff/source/draw/QRCodeContext.cxx b/xmloff/source/draw/QRCodeContext.cxx
new file mode 100644
index 0000000000..597838f78c
--- /dev/null
+++ b/xmloff/source/draw/QRCodeContext.cxx
@@ -0,0 +1,91 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4; fill-column: 100 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ */
+
+#include "QRCodeContext.hxx"
+
+#include <com/sun/star/beans/XPropertySet.hpp>
+#include <com/sun/star/embed/XStorage.hpp>
+#include <com/sun/star/frame/XStorable.hpp>
+#include <com/sun/star/graphic/XGraphic.hpp>
+#include <com/sun/star/drawing/BarCode.hpp>
+#include <com/sun/star/drawing/BarCodeErrorCorrection.hpp>
+#include <com/sun/star/xml/sax/XAttributeList.hpp>
+
+#include <xmloff/xmltoken.hxx>
+#include <xmloff/xmlimp.hxx>
+#include <xmloff/xmlnamespace.hxx>
+#include <xmloff/namespacemap.hxx>
+#include <sax/tools/converter.hxx>
+
+#include <rtl/ustring.hxx>
+
+using namespace css;
+using namespace css::xml::sax;
+using namespace css::uno;
+using namespace css::drawing;
+using namespace css::embed;
+using namespace css::frame;
+using namespace css::io;
+using namespace css::graphic;
+using namespace xmloff::token;
+
+QRCodeContext::QRCodeContext(SvXMLImport& rImport, sal_Int32 /*nElement*/,
+ const Reference<XFastAttributeList>& xAttrList,
+ const Reference<XShape>& rxShape)
+ : SvXMLImportContext(rImport)
+{
+ Reference<beans::XPropertySet> xPropSet(rxShape, UNO_QUERY_THROW);
+
+ css::drawing::BarCode aBarCode;
+
+ for (auto& aIter : sax_fastparser::castToFastAttributeList(xAttrList))
+ {
+ switch (aIter.getToken())
+ {
+ case XML_ELEMENT(LO_EXT, XML_QRCODE_ERROR_CORRECTION):
+ {
+ OUString aErrorCorrValue = aIter.toString();
+
+ if (aErrorCorrValue == "low")
+ aBarCode.ErrorCorrection = css::drawing::BarCodeErrorCorrection::LOW;
+ else if (aErrorCorrValue == "medium")
+ aBarCode.ErrorCorrection = css::drawing::BarCodeErrorCorrection::MEDIUM;
+ else if (aErrorCorrValue == "quartile")
+ aBarCode.ErrorCorrection = css::drawing::BarCodeErrorCorrection::QUARTILE;
+ else
+ aBarCode.ErrorCorrection = css::drawing::BarCodeErrorCorrection::HIGH;
+ break;
+ }
+ case XML_ELEMENT(LO_EXT, XML_QRCODE_BORDER):
+ {
+ sal_Int32 nAttrVal;
+ if (sax::Converter::convertNumber(nAttrVal, aIter.toView(), 0))
+ aBarCode.Border = nAttrVal;
+ break;
+ }
+ case XML_ELEMENT(OFFICE, XML_STRING_VALUE):
+ {
+ aBarCode.Payload = aIter.toString();
+ break;
+ }
+ case XML_ELEMENT(LO_EXT, XML_QRCODE_TYPE):
+ {
+ sal_Int32 nAttrVal;
+ if (sax::Converter::convertNumber(nAttrVal, aIter.toView(), 0))
+ aBarCode.Type = nAttrVal;
+ break;
+ }
+ default:
+ XMLOFF_WARN_UNKNOWN("xmloff", aIter);
+ }
+ }
+ xPropSet->setPropertyValue("BarCodeProperties", Any(aBarCode));
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab cinoptions=b1,g0,N-s cinkeys+=0=break: */
diff --git a/xmloff/source/draw/QRCodeContext.hxx b/xmloff/source/draw/QRCodeContext.hxx
new file mode 100644
index 0000000000..c35c6f9bd9
--- /dev/null
+++ b/xmloff/source/draw/QRCodeContext.hxx
@@ -0,0 +1,26 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4; fill-column: 100 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ */
+
+#pragma once
+
+#include <com/sun/star/drawing/XShape.hpp>
+#include <xmloff/xmlictxt.hxx>
+
+// Used to import QR code properties from a QR code in ODF document
+// @see ximpshap
+
+class QRCodeContext : public SvXMLImportContext
+{
+public:
+ QRCodeContext(SvXMLImport& rImport, sal_Int32 nElement,
+ const css::uno::Reference<css::xml::sax::XFastAttributeList>& xAttrList,
+ const css::uno::Reference<css::drawing::XShape>& rxShape);
+};
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab cinoptions=b1,g0,N-s cinkeys+=0=break: */
diff --git a/xmloff/source/draw/SignatureLineContext.cxx b/xmloff/source/draw/SignatureLineContext.cxx
new file mode 100644
index 0000000000..0217156e35
--- /dev/null
+++ b/xmloff/source/draw/SignatureLineContext.cxx
@@ -0,0 +1,136 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4; fill-column: 100 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ */
+
+#include "SignatureLineContext.hxx"
+
+#include <com/sun/star/beans/XPropertySet.hpp>
+#include <com/sun/star/embed/XStorage.hpp>
+#include <com/sun/star/frame/XModel.hpp>
+#include <com/sun/star/frame/XStorable.hpp>
+#include <com/sun/star/graphic/XGraphic.hpp>
+#include <com/sun/star/security/DocumentDigitalSignatures.hpp>
+#include <com/sun/star/security/XDocumentDigitalSignatures.hpp>
+#include <com/sun/star/xml/sax/XAttributeList.hpp>
+
+#include <sal/log.hxx>
+#include <comphelper/processfactory.hxx>
+#include <comphelper/storagehelper.hxx>
+#include <xmloff/xmltoken.hxx>
+#include <xmloff/xmlimp.hxx>
+#include <xmloff/xmlnamespace.hxx>
+
+using namespace css;
+using namespace css::xml::sax;
+using namespace css::uno;
+using namespace css::drawing;
+using namespace css::embed;
+using namespace css::frame;
+using namespace css::io;
+using namespace css::graphic;
+using namespace css::security;
+using namespace xmloff::token;
+
+SignatureLineContext::SignatureLineContext(SvXMLImport& rImport, sal_Int32 /*nElement*/,
+ const Reference<XFastAttributeList>& xAttrList,
+ const Reference<XShape>& rxShape)
+ : SvXMLImportContext(rImport)
+{
+ Reference<beans::XPropertySet> xPropSet(rxShape, UNO_QUERY_THROW);
+
+ xPropSet->setPropertyValue("IsSignatureLine", Any(true));
+
+ xPropSet->setPropertyValue("SignatureLineId",
+ Any(xAttrList->getOptionalValue(XML_ELEMENT(LO_EXT, XML_ID))));
+ xPropSet->setPropertyValue(
+ "SignatureLineSuggestedSignerName",
+ Any(xAttrList->getOptionalValue(XML_ELEMENT(LO_EXT, XML_SUGGESTED_SIGNER_NAME))));
+ xPropSet->setPropertyValue(
+ "SignatureLineSuggestedSignerTitle",
+ Any(xAttrList->getOptionalValue(XML_ELEMENT(LO_EXT, XML_SUGGESTED_SIGNER_TITLE))));
+ xPropSet->setPropertyValue(
+ "SignatureLineSuggestedSignerEmail",
+ Any(xAttrList->getOptionalValue(XML_ELEMENT(LO_EXT, XML_SUGGESTED_SIGNER_EMAIL))));
+ xPropSet->setPropertyValue(
+ "SignatureLineSigningInstructions",
+ Any(xAttrList->getOptionalValue(XML_ELEMENT(LO_EXT, XML_SIGNING_INSTRUCTIONS))));
+
+ bool bShowSignDate = xAttrList->getOptionalValue(XML_ELEMENT(LO_EXT, XML_SHOW_SIGN_DATE))
+ == GetXMLToken(XML_TRUE);
+ bool bCanAddComment = xAttrList->getOptionalValue(XML_ELEMENT(LO_EXT, XML_CAN_ADD_COMMENT))
+ == GetXMLToken(XML_TRUE);
+ xPropSet->setPropertyValue("SignatureLineShowSignDate", Any(bShowSignDate));
+ xPropSet->setPropertyValue("SignatureLineCanAddComment", Any(bCanAddComment));
+
+ // Save unsigned graphic (need it when exporting)
+ Reference<XGraphic> xUnsignedGraphic;
+ xPropSet->getPropertyValue("Graphic") >>= xUnsignedGraphic;
+ if (xUnsignedGraphic.is())
+ xPropSet->setPropertyValue("SignatureLineUnsignedImage", Any(xUnsignedGraphic));
+
+ Reference<XGraphic> xGraphic;
+ try
+ {
+ // Get the document signatures
+ css::uno::Reference<XStorable> xStorable(GetImport().GetModel(), UNO_QUERY_THROW);
+ Reference<XStorage> xStorage = comphelper::OStorageHelper::GetStorageOfFormatFromURL(
+ ZIP_STORAGE_FORMAT_STRING, xStorable->getLocation(), ElementModes::READ);
+
+ if (!xStorage.is())
+ {
+ SAL_WARN("xmloff", "No xStorage!");
+ return;
+ }
+
+ OUString const aODFVersion(comphelper::OStorageHelper::GetODFVersionFromStorage(xStorage));
+ Reference<XDocumentDigitalSignatures> xSignatures(
+ security::DocumentDigitalSignatures::createWithVersion(
+ comphelper::getProcessComponentContext(), aODFVersion));
+
+ const Sequence<DocumentSignatureInformation> xSignatureInfo
+ = xSignatures->verifyDocumentContentSignatures(xStorage, Reference<XInputStream>());
+
+ // Try to find matching signature line image - if none exists that is fine,
+ // then the signature line is not digitally signed.
+ auto pSignatureInfo
+ = std::find_if(xSignatureInfo.begin(), xSignatureInfo.end(),
+ [&xAttrList](const DocumentSignatureInformation& rSignatureInfo) {
+ return rSignatureInfo.SignatureLineId
+ == xAttrList->getOptionalValue(XML_ELEMENT(LO_EXT, XML_ID));
+ });
+ bool bIsSigned(false);
+ if (pSignatureInfo != xSignatureInfo.end())
+ {
+ bIsSigned = true;
+ if (pSignatureInfo->SignatureIsValid)
+ {
+ // Signature is valid, use the 'valid' image
+ SAL_WARN_IF(!pSignatureInfo->ValidSignatureLineImage.is(), "xmloff",
+ "No ValidSignatureLineImage!");
+ xGraphic = pSignatureInfo->ValidSignatureLineImage;
+ }
+ else
+ {
+ // Signature is invalid, use the 'invalid' image
+ SAL_WARN_IF(!pSignatureInfo->InvalidSignatureLineImage.is(), "xmloff",
+ "No InvalidSignatureLineImage!");
+ xGraphic = pSignatureInfo->InvalidSignatureLineImage;
+ }
+
+ xPropSet->setPropertyValue("Graphic", Any(xGraphic));
+ }
+ xPropSet->setPropertyValue("SignatureLineIsSigned", Any(bIsSigned));
+ }
+ catch (css::uno::Exception&)
+ {
+ // DocumentDigitalSignatures service not available.
+ // We render the "unsigned" shape instead.
+ }
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab cinoptions=b1,g0,N-s cinkeys+=0=break: */
diff --git a/xmloff/source/draw/SignatureLineContext.hxx b/xmloff/source/draw/SignatureLineContext.hxx
new file mode 100644
index 0000000000..68a9373ae7
--- /dev/null
+++ b/xmloff/source/draw/SignatureLineContext.hxx
@@ -0,0 +1,25 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4; fill-column: 100 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ */
+
+#pragma once
+
+#include <com/sun/star/drawing/XShape.hpp>
+#include <xmloff/xmlictxt.hxx>
+
+// signatureline inside a shape
+
+class SignatureLineContext : public SvXMLImportContext
+{
+public:
+ SignatureLineContext(SvXMLImport& rImport, sal_Int32 nElement,
+ const css::uno::Reference<css::xml::sax::XFastAttributeList>& xAttrList,
+ const css::uno::Reference<css::drawing::XShape>& rxShape);
+};
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab cinoptions=b1,g0,N-s cinkeys+=0=break: */
diff --git a/xmloff/source/draw/XMLGraphicsDefaultStyle.cxx b/xmloff/source/draw/XMLGraphicsDefaultStyle.cxx
new file mode 100644
index 0000000000..de6b50a147
--- /dev/null
+++ b/xmloff/source/draw/XMLGraphicsDefaultStyle.cxx
@@ -0,0 +1,188 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#include <xmloff/XMLGraphicsDefaultStyle.hxx>
+
+#include <com/sun/star/beans/XPropertySet.hpp>
+#include <com/sun/star/frame/XModel.hpp>
+#include <com/sun/star/lang/XMultiServiceFactory.hpp>
+
+#include <tools/color.hxx>
+
+#include <xmloff/xmlimp.hxx>
+#include <xmloff/xmlnamespace.hxx>
+#include <xmloff/xmltoken.hxx>
+#include <xmloff/families.hxx>
+#include <xmloff/xmltypes.hxx>
+#include <xmloff/maptype.hxx>
+#include <xmloff/xmlimppr.hxx>
+#include <xmloff/xmlprmap.hxx>
+
+#include <XMLShapePropertySetContext.hxx>
+#include <algorithm>
+
+using namespace ::com::sun::star;
+using namespace ::com::sun::star::uno;
+using namespace ::com::sun::star::lang;
+using namespace ::com::sun::star::beans;
+using namespace ::com::sun::star::xml::sax;
+
+using ::xmloff::token::XML_TEXT_PROPERTIES;
+using ::xmloff::token::XML_GRAPHIC_PROPERTIES;
+using ::xmloff::token::XML_PARAGRAPH_PROPERTIES;
+
+
+XMLGraphicsDefaultStyle::XMLGraphicsDefaultStyle( SvXMLImport& rImport, SvXMLStylesContext& rStyles )
+: XMLPropStyleContext( rImport, rStyles, XmlStyleFamily::SD_GRAPHICS_ID, true )
+{
+}
+
+XMLGraphicsDefaultStyle::~XMLGraphicsDefaultStyle()
+{
+}
+
+css::uno::Reference< css::xml::sax::XFastContextHandler > XMLGraphicsDefaultStyle::createFastChildContext(
+ sal_Int32 nElement,
+ const css::uno::Reference< css::xml::sax::XFastAttributeList >& xAttrList )
+{
+ if( IsTokenInNamespace(nElement, XML_NAMESPACE_STYLE) ||
+ IsTokenInNamespace(nElement, XML_NAMESPACE_LO_EXT) )
+ {
+ sal_Int32 nLocalName = nElement & TOKEN_MASK;
+ sal_uInt32 nFamily = 0;
+ if( nLocalName == XML_TEXT_PROPERTIES )
+ nFamily = XML_TYPE_PROP_TEXT;
+ else if( nLocalName == XML_PARAGRAPH_PROPERTIES )
+ nFamily = XML_TYPE_PROP_PARAGRAPH;
+ else if( nLocalName == XML_GRAPHIC_PROPERTIES )
+ nFamily = XML_TYPE_PROP_GRAPHIC;
+ if( nFamily )
+ {
+ rtl::Reference < SvXMLImportPropertyMapper > xImpPrMap = GetStyles()->GetImportPropertyMapper( GetFamily() );
+ if( xImpPrMap.is() )
+ return new XMLShapePropertySetContext( GetImport(), nElement, xAttrList, nFamily, GetProperties(), xImpPrMap );
+ }
+ }
+
+ return XMLPropStyleContext::createFastChildContext( nElement, xAttrList );
+}
+
+namespace {
+
+struct XMLPropertyByIndex {
+ sal_Int32 const m_nIndex;
+ explicit XMLPropertyByIndex(sal_Int32 const nIndex) : m_nIndex(nIndex) {}
+ bool operator()(XMLPropertyState const& rProp) {
+ return m_nIndex == rProp.mnIndex;
+ }
+};
+
+}
+
+// This method is called for every default style
+void XMLGraphicsDefaultStyle::SetDefaults()
+{
+ Reference< XMultiServiceFactory > xFact( GetImport().GetModel(), UNO_QUERY );
+ if( !xFact.is() )
+ return;
+
+ Reference< XPropertySet > xDefaults( xFact->createInstance( "com.sun.star.drawing.Defaults" ), UNO_QUERY );
+ if( !xDefaults.is() )
+ return;
+ // SJ: #i114750#
+ bool bWordWrapDefault = true; // initializing with correct ODF fo:wrap-option default
+ sal_Int32 nUPD( 0 );
+ sal_Int32 nBuild( 0 );
+ const bool bBuildIdFound = GetImport().getBuildIds( nUPD, nBuild );
+ if ( bBuildIdFound && (
+ ((nUPD >= 600) && (nUPD < 700))
+ ||
+ ((nUPD == 300) && (nBuild <= 9535))
+ ||
+ ((nUPD > 300) && (nUPD <= 330))
+ ) )
+ bWordWrapDefault = false;
+
+ static constexpr OUString sTextWordWrap( u"TextWordWrap"_ustr );
+ Reference< XPropertySetInfo > xInfo( xDefaults->getPropertySetInfo() );
+ if ( xInfo->hasPropertyByName( sTextWordWrap ) )
+ xDefaults->setPropertyValue( sTextWordWrap, Any( bWordWrapDefault ) );
+
+ if (GetImport().IsOOoXML()
+ && xInfo->hasPropertyByName("IsFollowingTextFlow"))
+ {
+ // OOo 1.x only supported "true" so that is the more appropriate
+ // default for OOoXML format documents.
+ xDefaults->setPropertyValue("IsFollowingTextFlow", uno::Any(true));
+ }
+
+ // NOTE: the only reason why it's legal to check "==" (not "<") against
+ // arbitrary versions here is that the default value of these attributes
+ // is not defined by ODF, therefore it is implementation-defined
+ // (and we of course must not override any attributes that are actually
+ // in the document, so check for that)
+ bool const bIsAOO4(
+ GetImport().getGeneratorVersion() >= SvXMLImport::AOO_40x
+ && GetImport().getGeneratorVersion() <= SvXMLImport::AOO_4x);
+
+ // fdo#75872: backward compatibility for pool defaults change
+ if (GetImport().isGeneratorVersionOlderThan(
+ SvXMLImport::AOO_40x, SvXMLImport::LO_42x)
+ // argh... it turns out that LO has also changed defaults for these
+ // since LO 4.0, and so even the _new_ AOO 4.0+ default needs
+ // special handling since AOO still does _not_ write it into the file
+ || bIsAOO4)
+ {
+ rtl::Reference<XMLPropertySetMapper> const pImpPrMap(
+ GetStyles()->GetImportPropertyMapper(GetFamily())
+ ->getPropertySetMapper());
+ sal_Int32 const nStrokeIndex(
+ pImpPrMap->GetEntryIndex(XML_NAMESPACE_SVG, u"stroke-color", 0));
+ if (std::none_of(GetProperties().begin(), GetProperties().end(),
+ XMLPropertyByIndex(nStrokeIndex)))
+ {
+ Color const nStroke(
+ bIsAOO4 ? Color(128, 128, 128) : COL_BLACK);
+ xDefaults->setPropertyValue("LineColor", Any(nStroke));
+ }
+ Color const nFillColor( bIsAOO4
+ ? Color(0xCF, 0xE7, 0xF5) : Color(153, 204, 255));
+ sal_Int32 const nFillIndex(
+ pImpPrMap->GetEntryIndex(XML_NAMESPACE_DRAW, u"fill-color", 0));
+ if (std::none_of(GetProperties().begin(), GetProperties().end(),
+ XMLPropertyByIndex(nFillIndex)))
+ {
+ xDefaults->setPropertyValue("FillColor", Any(nFillColor));
+ }
+ if (xInfo->hasPropertyByName("FillColor2"))
+ {
+ sal_Int32 const nFill2Index(pImpPrMap->GetEntryIndex(
+ XML_NAMESPACE_DRAW, u"secondary-fill-color", 0));
+ if (std::none_of(GetProperties().begin(), GetProperties().end(),
+ XMLPropertyByIndex(nFill2Index)))
+ {
+ xDefaults->setPropertyValue("FillColor2", Any(sal_Int32(nFillColor)));
+ }
+ }
+ }
+
+ FillPropertySet( xDefaults );
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/xmloff/source/draw/XMLImageMapContext.cxx b/xmloff/source/draw/XMLImageMapContext.cxx
new file mode 100644
index 0000000000..e3a16c0863
--- /dev/null
+++ b/xmloff/source/draw/XMLImageMapContext.cxx
@@ -0,0 +1,541 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#include <XMLImageMapContext.hxx>
+#include <rtl/ustrbuf.hxx>
+#include <com/sun/star/uno/Reference.h>
+#include <com/sun/star/beans/XPropertySet.hpp>
+#include <com/sun/star/beans/XPropertySetInfo.hpp>
+#include <com/sun/star/frame/XModel.hpp>
+#include <com/sun/star/xml/sax/XAttributeList.hpp>
+#include <com/sun/star/container/XIndexContainer.hpp>
+#include <com/sun/star/lang/XMultiServiceFactory.hpp>
+#include <com/sun/star/document/XEventsSupplier.hpp>
+#include <com/sun/star/awt/Rectangle.hpp>
+#include <xmloff/xmltoken.hxx>
+#include <xmloff/xmlimp.hxx>
+#include <xmloff/xmltkmap.hxx>
+#include <xmloff/xmlnamespace.hxx>
+#include <xmloff/namespacemap.hxx>
+#include <xmloff/xmluconv.hxx>
+#include <xexptran.hxx>
+#include <xmloff/xmlerror.hxx>
+#include <xmloff/XMLEventsImportContext.hxx>
+#include <XMLStringBufferImportContext.hxx>
+#include <tools/debug.hxx>
+#include <basegfx/polygon/b2dpolygon.hxx>
+#include <basegfx/polygon/b2dpolygontools.hxx>
+#include <sal/log.hxx>
+
+using namespace ::com::sun::star;
+using namespace ::xmloff::token;
+
+using ::com::sun::star::beans::XPropertySet;
+using ::com::sun::star::beans::XPropertySetInfo;
+using ::com::sun::star::container::XIndexContainer;
+using ::com::sun::star::lang::XMultiServiceFactory;
+using ::com::sun::star::uno::Reference;
+using ::com::sun::star::uno::UNO_QUERY;
+using ::com::sun::star::uno::XInterface;
+using ::com::sun::star::uno::Any;
+using ::com::sun::star::document::XEventsSupplier;
+
+namespace {
+
+class XMLImageMapObjectContext : public SvXMLImportContext
+{
+
+protected:
+
+ Reference<XIndexContainer> xImageMap; /// the image map
+ Reference<XPropertySet> xMapEntry; /// one map-entry (one area)
+
+ OUString sUrl;
+ OUString sTargt;
+ OUStringBuffer sDescriptionBuffer;
+ OUStringBuffer sTitleBuffer;
+ OUString sNam;
+ bool bIsActive;
+
+ bool bValid;
+
+public:
+
+ XMLImageMapObjectContext(
+ SvXMLImport& rImport,
+ css::uno::Reference<css::container::XIndexContainer> const & xMap,
+ const char* pServiceName);
+
+ virtual void SAL_CALL startFastElement( sal_Int32 nElement,
+ const css::uno::Reference< css::xml::sax::XFastAttributeList >& xAttrList ) override;
+
+ virtual void SAL_CALL endFastElement(sal_Int32 nElement) override;
+
+ virtual css::uno::Reference< css::xml::sax::XFastContextHandler > SAL_CALL createFastChildContext(
+ sal_Int32 nElement,
+ const css::uno::Reference< css::xml::sax::XFastAttributeList >& AttrList ) override;
+
+protected:
+
+ virtual void ProcessAttribute(const sax_fastparser::FastAttributeList::FastAttributeIter &);
+
+ virtual void Prepare(
+ css::uno::Reference<css::beans::XPropertySet> & rPropertySet);
+};
+
+}
+
+XMLImageMapObjectContext::XMLImageMapObjectContext(
+ SvXMLImport& rImport,
+ Reference<XIndexContainer> const & xMap,
+ const char* pServiceName) :
+ SvXMLImportContext(rImport),
+ xImageMap(xMap),
+ bIsActive(true),
+ bValid(false)
+{
+ DBG_ASSERT(nullptr != pServiceName,
+ "Please supply the image map object service name");
+
+ Reference<XMultiServiceFactory> xFactory(GetImport().GetModel(),UNO_QUERY);
+ if( !xFactory.is() )
+ return;
+
+ Reference<XInterface> xIfc = xFactory->createInstance(
+ OUString::createFromAscii(pServiceName));
+ DBG_ASSERT(xIfc.is(), "can't create image map object!");
+ if( xIfc.is() )
+ {
+ Reference<XPropertySet> xPropertySet( xIfc, UNO_QUERY );
+
+ xMapEntry = xPropertySet;
+ }
+ // else: can't create service -> ignore
+ // else: can't even get factory -> ignore
+}
+
+void XMLImageMapObjectContext::startFastElement( sal_Int32 /*nElement*/,
+ const css::uno::Reference< css::xml::sax::XFastAttributeList >& xAttrList )
+{
+ for( auto& aIter : sax_fastparser::castToFastAttributeList(xAttrList) )
+ ProcessAttribute(aIter);
+}
+
+void XMLImageMapObjectContext::endFastElement(sal_Int32 )
+{
+ // only create and insert image map object if validity flag is set
+ // (and we actually have an image map)
+ if ( bValid && xImageMap.is() && xMapEntry.is() )
+ {
+ // set values
+ Prepare( xMapEntry );
+
+ // insert into image map
+ xImageMap->insertByIndex( xImageMap->getCount(), Any(xMapEntry) );
+ }
+ // else: not valid -> don't create and insert
+}
+
+css::uno::Reference< css::xml::sax::XFastContextHandler > XMLImageMapObjectContext::createFastChildContext(
+ sal_Int32 nElement,
+ const css::uno::Reference< css::xml::sax::XFastAttributeList >& )
+{
+ switch (nElement)
+ {
+ case XML_ELEMENT(OFFICE, XML_EVENT_LISTENERS):
+ {
+ Reference<XEventsSupplier> xEvents( xMapEntry, UNO_QUERY );
+ return new XMLEventsImportContext(
+ GetImport(), xEvents);
+ }
+ case XML_ELEMENT(SVG, XML_TITLE):
+ case XML_ELEMENT(SVG_COMPAT, XML_TITLE):
+ return new XMLStringBufferImportContext(
+ GetImport(), sTitleBuffer);
+ case XML_ELEMENT(SVG, XML_DESC):
+ case XML_ELEMENT(SVG_COMPAT, XML_DESC):
+ return new XMLStringBufferImportContext(
+ GetImport(), sDescriptionBuffer);
+ }
+ XMLOFF_WARN_UNKNOWN_ELEMENT("xmloff", nElement);
+ return nullptr;
+}
+
+void XMLImageMapObjectContext::ProcessAttribute(
+ const sax_fastparser::FastAttributeList::FastAttributeIter & aIter)
+{
+ switch (aIter.getToken())
+ {
+ case XML_ELEMENT(XLINK, XML_HREF):
+ sUrl = GetImport().GetAbsoluteReference(aIter.toString());
+ break;
+
+ case XML_ELEMENT(OFFICE, XML_TARGET_FRAME_NAME):
+ sTargt = aIter.toString();
+ break;
+
+ case XML_ELEMENT(DRAW, XML_NOHREF):
+ bIsActive = ! IsXMLToken(aIter, XML_NOHREF);
+ break;
+
+ case XML_ELEMENT(OFFICE, XML_NAME):
+ sNam = aIter.toString();
+ break;
+ default:
+ // do nothing
+ XMLOFF_WARN_UNKNOWN("xmloff", aIter);
+ break;
+ }
+}
+
+void XMLImageMapObjectContext::Prepare(
+ Reference<XPropertySet> & rPropertySet)
+{
+ rPropertySet->setPropertyValue( "URL", Any( sUrl ) );
+ rPropertySet->setPropertyValue( "Title", Any( sTitleBuffer.makeStringAndClear() ) );
+ rPropertySet->setPropertyValue( "Description", Any( sDescriptionBuffer.makeStringAndClear() ) );
+ rPropertySet->setPropertyValue( "Target", Any( sTargt ) );
+ rPropertySet->setPropertyValue( "IsActive", Any( bIsActive ) );
+ rPropertySet->setPropertyValue( "Name", Any( sNam ) );
+}
+
+namespace {
+
+class XMLImageMapRectangleContext : public XMLImageMapObjectContext
+{
+ awt::Rectangle aRectangle;
+
+ bool bXOK;
+ bool bYOK;
+ bool bWidthOK;
+ bool bHeightOK;
+
+public:
+
+ XMLImageMapRectangleContext(
+ SvXMLImport& rImport,
+ css::uno::Reference<css::container::XIndexContainer> const & xMap);
+
+protected:
+ virtual void ProcessAttribute(
+ const sax_fastparser::FastAttributeList::FastAttributeIter &) override;
+
+ virtual void Prepare(
+ css::uno::Reference<css::beans::XPropertySet> & rPropertySet) override;
+};
+
+}
+
+XMLImageMapRectangleContext::XMLImageMapRectangleContext(
+ SvXMLImport& rImport,
+ Reference<XIndexContainer> const & xMap) :
+ XMLImageMapObjectContext(rImport, xMap,
+ "com.sun.star.image.ImageMapRectangleObject"),
+ bXOK(false),
+ bYOK(false),
+ bWidthOK(false),
+ bHeightOK(false)
+{
+}
+
+void XMLImageMapRectangleContext::ProcessAttribute(
+ const sax_fastparser::FastAttributeList::FastAttributeIter & aIter)
+{
+ sal_Int32 nTmp;
+ switch (aIter.getToken())
+ {
+ case XML_ELEMENT(SVG, XML_X):
+ case XML_ELEMENT(SVG_COMPAT, XML_X):
+ if (GetImport().GetMM100UnitConverter().convertMeasureToCore(nTmp,
+ aIter.toView()))
+ {
+ aRectangle.X = nTmp;
+ bXOK = true;
+ }
+ break;
+ case XML_ELEMENT(SVG, XML_Y):
+ case XML_ELEMENT(SVG_COMPAT, XML_Y):
+ if (GetImport().GetMM100UnitConverter().convertMeasureToCore(nTmp,
+ aIter.toView()))
+ {
+ aRectangle.Y = nTmp;
+ bYOK = true;
+ }
+ break;
+ case XML_ELEMENT(SVG, XML_WIDTH):
+ case XML_ELEMENT(SVG_COMPAT, XML_WIDTH):
+ if (GetImport().GetMM100UnitConverter().convertMeasureToCore(nTmp,
+ aIter.toView()))
+ {
+ aRectangle.Width = nTmp;
+ bWidthOK = true;
+ }
+ break;
+ case XML_ELEMENT(SVG, XML_HEIGHT):
+ case XML_ELEMENT(SVG_COMPAT, XML_HEIGHT):
+ if (GetImport().GetMM100UnitConverter().convertMeasureToCore(nTmp,
+ aIter.toView()))
+ {
+ aRectangle.Height = nTmp;
+ bHeightOK = true;
+ }
+ break;
+ default:
+ XMLImageMapObjectContext::ProcessAttribute(aIter);
+ }
+
+ bValid = bHeightOK && bXOK && bYOK && bWidthOK;
+}
+
+void XMLImageMapRectangleContext::Prepare(
+ Reference<XPropertySet> & rPropertySet)
+{
+ rPropertySet->setPropertyValue( "Boundary", uno::Any(aRectangle) );
+
+ // common properties handled by super class
+ XMLImageMapObjectContext::Prepare(rPropertySet);
+}
+
+namespace {
+
+class XMLImageMapPolygonContext : public XMLImageMapObjectContext
+{
+ OUString sViewBoxString;
+ OUString sPointsString;
+
+ bool bViewBoxOK;
+ bool bPointsOK;
+
+public:
+
+ XMLImageMapPolygonContext(
+ SvXMLImport& rImport,
+ css::uno::Reference<css::container::XIndexContainer> const & xMap);
+
+protected:
+ virtual void ProcessAttribute(const sax_fastparser::FastAttributeList::FastAttributeIter &) override;
+
+ virtual void Prepare(
+ css::uno::Reference<css::beans::XPropertySet> & rPropertySet) override;
+};
+
+}
+
+XMLImageMapPolygonContext::XMLImageMapPolygonContext(
+ SvXMLImport& rImport,
+ Reference<XIndexContainer> const & xMap) :
+ XMLImageMapObjectContext(rImport, xMap,
+ "com.sun.star.image.ImageMapPolygonObject"),
+ bViewBoxOK(false),
+ bPointsOK(false)
+{
+}
+
+void XMLImageMapPolygonContext::ProcessAttribute(
+ const sax_fastparser::FastAttributeList::FastAttributeIter & aIter)
+{
+ switch (aIter.getToken())
+ {
+ case XML_ELEMENT(DRAW, XML_POINTS):
+ sPointsString = aIter.toString();
+ bPointsOK = true;
+ break;
+ case XML_ELEMENT(SVG, XML_VIEWBOX):
+ case XML_ELEMENT(SVG_COMPAT, XML_VIEWBOX):
+ sViewBoxString = aIter.toString();
+ bViewBoxOK = true;
+ break;
+ default:
+ XMLImageMapObjectContext::ProcessAttribute(aIter);
+ break;
+ }
+
+ bValid = bViewBoxOK && bPointsOK;
+}
+
+void XMLImageMapPolygonContext::Prepare(Reference<XPropertySet> & rPropertySet)
+{
+ // process view box
+ SdXMLImExViewBox aViewBox(sViewBoxString, GetImport().GetMM100UnitConverter());
+
+ // get polygon sequence
+ basegfx::B2DPolygon aPolygon;
+
+ if(basegfx::utils::importFromSvgPoints(aPolygon, sPointsString))
+ {
+ if(aPolygon.count())
+ {
+ css::drawing::PointSequence aPointSequence;
+ basegfx::utils::B2DPolygonToUnoPointSequence(aPolygon, aPointSequence);
+ rPropertySet->setPropertyValue("Polygon", Any(aPointSequence));
+ }
+ }
+
+ // parent properties
+ XMLImageMapObjectContext::Prepare(rPropertySet);
+}
+
+namespace {
+
+class XMLImageMapCircleContext : public XMLImageMapObjectContext
+{
+ awt::Point aCenter;
+ sal_Int32 nRadius;
+
+ bool bXOK;
+ bool bYOK;
+ bool bRadiusOK;
+
+public:
+
+ XMLImageMapCircleContext(
+ SvXMLImport& rImport,
+ css::uno::Reference<css::container::XIndexContainer> const & xMap);
+
+protected:
+ virtual void ProcessAttribute(
+ const sax_fastparser::FastAttributeList::FastAttributeIter &) override;
+
+ virtual void Prepare(
+ css::uno::Reference<css::beans::XPropertySet> & rPropertySet) override;
+};
+
+}
+
+XMLImageMapCircleContext::XMLImageMapCircleContext(
+ SvXMLImport& rImport,
+ Reference<XIndexContainer> const & xMap)
+ : XMLImageMapObjectContext(rImport, xMap,
+ "com.sun.star.image.ImageMapCircleObject")
+ , nRadius(0)
+ , bXOK(false)
+ , bYOK(false)
+ , bRadiusOK(false)
+{
+}
+
+void XMLImageMapCircleContext::ProcessAttribute(
+ const sax_fastparser::FastAttributeList::FastAttributeIter & aIter)
+{
+ sal_Int32 nTmp;
+ switch (aIter.getToken())
+ {
+ case XML_ELEMENT(SVG, XML_CX):
+ case XML_ELEMENT(SVG_COMPAT, XML_CX):
+ if (GetImport().GetMM100UnitConverter().convertMeasureToCore(nTmp,
+ aIter.toView()))
+ {
+ aCenter.X = nTmp;
+ bXOK = true;
+ }
+ break;
+ case XML_ELEMENT(SVG, XML_CY):
+ case XML_ELEMENT(SVG_COMPAT, XML_CY):
+ if (GetImport().GetMM100UnitConverter().convertMeasureToCore(nTmp,
+ aIter.toView()))
+ {
+ aCenter.Y = nTmp;
+ bYOK = true;
+ }
+ break;
+ case XML_ELEMENT(SVG, XML_R):
+ case XML_ELEMENT(SVG_COMPAT, XML_R):
+ if (GetImport().GetMM100UnitConverter().convertMeasureToCore(nTmp,
+ aIter.toView()))
+ {
+ nRadius = nTmp;
+ bRadiusOK = true;
+ }
+ break;
+ default:
+ XMLImageMapObjectContext::ProcessAttribute(aIter);
+ }
+
+ bValid = bRadiusOK && bXOK && bYOK;
+}
+
+void XMLImageMapCircleContext::Prepare(
+ Reference<XPropertySet> & rPropertySet)
+{
+ // center (x,y)
+ rPropertySet->setPropertyValue( "Center", uno::Any(aCenter) );
+ // radius
+ rPropertySet->setPropertyValue( "Radius", uno::Any(nRadius) );
+
+ // common properties handled by super class
+ XMLImageMapObjectContext::Prepare(rPropertySet);
+}
+
+
+constexpr OUString gsImageMap(u"ImageMap"_ustr);
+
+XMLImageMapContext::XMLImageMapContext(
+ SvXMLImport& rImport,
+ Reference<XPropertySet> const & rPropertySet) :
+ SvXMLImportContext(rImport),
+ xPropertySet(rPropertySet)
+{
+ try
+ {
+ Reference < XPropertySetInfo > xInfo =
+ xPropertySet->getPropertySetInfo();
+ if( xInfo.is() && xInfo->hasPropertyByName( gsImageMap ) )
+ xPropertySet->getPropertyValue(gsImageMap) >>= xImageMap;
+ }
+ catch(const css::uno::Exception& e)
+ {
+ rImport.SetError( XMLERROR_FLAG_WARNING | XMLERROR_API, {}, e.Message, nullptr );
+ }
+}
+
+XMLImageMapContext::~XMLImageMapContext()
+{
+}
+
+css::uno::Reference< css::xml::sax::XFastContextHandler > XMLImageMapContext::createFastChildContext(
+ sal_Int32 nElement,
+ const css::uno::Reference< css::xml::sax::XFastAttributeList >& )
+{
+ switch (nElement)
+ {
+ case XML_ELEMENT(DRAW, XML_AREA_RECTANGLE):
+ return new XMLImageMapRectangleContext(
+ GetImport(), xImageMap);
+ case XML_ELEMENT(DRAW, XML_AREA_POLYGON):
+ return new XMLImageMapPolygonContext(
+ GetImport(), xImageMap);
+ case XML_ELEMENT(DRAW, XML_AREA_CIRCLE):
+ return new XMLImageMapCircleContext(
+ GetImport(), xImageMap);
+ default:
+ XMLOFF_WARN_UNKNOWN_ELEMENT("xmloff", nElement);
+ }
+
+ return nullptr;
+}
+
+void XMLImageMapContext::endFastElement(sal_Int32 )
+{
+ Reference < XPropertySetInfo > xInfo =
+ xPropertySet->getPropertySetInfo();
+ if( xInfo.is() && xInfo->hasPropertyByName( gsImageMap ) )
+ xPropertySet->setPropertyValue(gsImageMap, uno::Any( xImageMap ) );
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/xmloff/source/draw/XMLImageMapExport.cxx b/xmloff/source/draw/XMLImageMapExport.cxx
new file mode 100644
index 0000000000..833df40af2
--- /dev/null
+++ b/xmloff/source/draw/XMLImageMapExport.cxx
@@ -0,0 +1,339 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#include <XMLImageMapExport.hxx>
+#include <o3tl/any.hxx>
+#include <rtl/ustring.hxx>
+#include <rtl/ustrbuf.hxx>
+#include <tools/debug.hxx>
+#include <com/sun/star/uno/Reference.h>
+#include <com/sun/star/uno/Sequence.h>
+#include <com/sun/star/beans/XPropertySet.hpp>
+#include <com/sun/star/lang/XServiceInfo.hpp>
+#include <com/sun/star/container/XIndexContainer.hpp>
+#include <com/sun/star/document/XEventsSupplier.hpp>
+#include <com/sun/star/awt/Rectangle.hpp>
+#include <com/sun/star/awt/Point.hpp>
+#include <com/sun/star/drawing/PointSequence.hpp>
+#include <xmloff/xmlexp.hxx>
+#include <xmloff/xmlnamespace.hxx>
+#include <xmloff/xmltoken.hxx>
+#include <xmloff/XMLEventExport.hxx>
+#include <xmloff/xmluconv.hxx>
+#include <xexptran.hxx>
+#include <basegfx/polygon/b2dpolygon.hxx>
+#include <basegfx/polygon/b2dpolygontools.hxx>
+
+using namespace ::com::sun::star;
+using namespace ::xmloff::token;
+
+using ::com::sun::star::uno::Any;
+using ::com::sun::star::uno::UNO_QUERY;
+using ::com::sun::star::uno::Sequence;
+using ::com::sun::star::uno::Reference;
+using ::com::sun::star::beans::XPropertySet;
+using ::com::sun::star::container::XIndexContainer;
+using ::com::sun::star::document::XEventsSupplier;
+using ::com::sun::star::lang::XServiceInfo;
+using ::com::sun::star::drawing::PointSequence;
+
+constexpr OUStringLiteral gsBoundary(u"Boundary");
+constexpr OUStringLiteral gsCenter(u"Center");
+constexpr OUStringLiteral gsDescription(u"Description");
+constexpr OUString gsImageMap(u"ImageMap"_ustr);
+constexpr OUStringLiteral gsIsActive(u"IsActive");
+constexpr OUStringLiteral gsName(u"Name");
+constexpr OUStringLiteral gsPolygon(u"Polygon");
+constexpr OUStringLiteral gsRadius(u"Radius");
+constexpr OUStringLiteral gsTarget(u"Target");
+constexpr OUStringLiteral gsURL(u"URL");
+constexpr OUStringLiteral gsTitle(u"Title");
+
+XMLImageMapExport::XMLImageMapExport(SvXMLExport& rExp) :
+ mrExport(rExp)
+{
+}
+
+void XMLImageMapExport::Export(
+ const Reference<XPropertySet> & rPropertySet)
+{
+ if (rPropertySet->getPropertySetInfo()->hasPropertyByName(gsImageMap))
+ {
+ Any aAny = rPropertySet->getPropertyValue(gsImageMap);
+ Reference<XIndexContainer> aContainer;
+ aAny >>= aContainer;
+
+ Export(aContainer);
+ }
+ // else: no ImageMap property -> nothing to do
+}
+
+void XMLImageMapExport::Export(
+ const Reference<XIndexContainer> & rContainer)
+{
+ if (!rContainer.is())
+ return;
+
+ if (!rContainer->hasElements())
+ return;
+
+ // image map container element
+ SvXMLElementExport aImageMapElement(
+ mrExport, XML_NAMESPACE_DRAW, XML_IMAGE_MAP,
+ true/*bWhiteSpace*/, true/*bWhiteSpace*/);
+
+ // iterate over image map elements and call ExportMapEntry(...)
+ // for each
+ sal_Int32 nLength = rContainer->getCount();
+ for(sal_Int32 i = 0; i < nLength; i++)
+ {
+ Any aAny = rContainer->getByIndex(i);
+ Reference<XPropertySet> rElement;
+ aAny >>= rElement;
+
+ DBG_ASSERT(rElement.is(), "Image map element is empty!");
+ if (rElement.is())
+ {
+ ExportMapEntry(rElement);
+ }
+ }
+ // else: container is empty -> nothing to do
+ // else: no container -> nothing to do
+}
+
+
+void XMLImageMapExport::ExportMapEntry(
+ const Reference<XPropertySet> & rPropertySet)
+{
+ Reference<XServiceInfo> xServiceInfo(rPropertySet, UNO_QUERY);
+ if (!xServiceInfo.is())
+ return;
+
+ enum XMLTokenEnum eType = XML_TOKEN_INVALID;
+
+ // distinguish map entries by their service name
+ const Sequence<OUString> sServiceNames =
+ xServiceInfo->getSupportedServiceNames();
+ for( const OUString& rName : sServiceNames )
+ {
+ if ( rName == "com.sun.star.image.ImageMapRectangleObject" )
+ {
+ eType = XML_AREA_RECTANGLE;
+ break;
+ }
+ else if ( rName == "com.sun.star.image.ImageMapCircleObject" )
+ {
+ eType = XML_AREA_CIRCLE;
+ break;
+ }
+ else if ( rName == "com.sun.star.image.ImageMapPolygonObject" )
+ {
+ eType = XML_AREA_POLYGON;
+ break;
+ }
+ }
+
+ // return from method if no proper service is found!
+ DBG_ASSERT(XML_TOKEN_INVALID != eType,
+ "Image map element doesn't support appropriate service!");
+ if (XML_TOKEN_INVALID == eType)
+ return;
+
+ // now: handle ImageMapObject properties (those for all types)
+
+ // XLINK (URL property)
+ Any aAny = rPropertySet->getPropertyValue(gsURL);
+ OUString sHref;
+ aAny >>= sHref;
+ if (!sHref.isEmpty())
+ {
+ mrExport.AddAttribute(XML_NAMESPACE_XLINK, XML_HREF, mrExport.GetRelativeReference(sHref));
+ }
+ mrExport.AddAttribute( XML_NAMESPACE_XLINK, XML_TYPE, XML_SIMPLE );
+
+ // Target property (and xlink:show)
+ aAny = rPropertySet->getPropertyValue(gsTarget);
+ OUString sTargt;
+ aAny >>= sTargt;
+ if (!sTargt.isEmpty())
+ {
+ mrExport.AddAttribute(
+ XML_NAMESPACE_OFFICE, XML_TARGET_FRAME_NAME, sTargt);
+
+ mrExport.AddAttribute(
+ XML_NAMESPACE_XLINK, XML_SHOW,
+ sTargt == "_blank" ? XML_NEW : XML_REPLACE );
+ }
+
+ // name
+ aAny = rPropertySet->getPropertyValue(gsName);
+ OUString sItemName;
+ aAny >>= sItemName;
+ if (!sItemName.isEmpty())
+ {
+ mrExport.AddAttribute(XML_NAMESPACE_OFFICE, XML_NAME, sItemName);
+ }
+
+ // is-active
+ aAny = rPropertySet->getPropertyValue(gsIsActive);
+ if (! *o3tl::doAccess<bool>(aAny))
+ {
+ mrExport.AddAttribute(XML_NAMESPACE_DRAW, XML_NOHREF, XML_NOHREF);
+ }
+
+ // call specific rectangle/circle/... method
+ // also prepare element name
+ switch (eType)
+ {
+ case XML_AREA_RECTANGLE:
+ ExportRectangle(rPropertySet);
+ break;
+ case XML_AREA_CIRCLE:
+ ExportCircle(rPropertySet);
+ break;
+ case XML_AREA_POLYGON:
+ ExportPolygon(rPropertySet);
+ break;
+ default:
+ break;
+ }
+
+ // write element
+ DBG_ASSERT(XML_TOKEN_INVALID != eType,
+ "No name?! How did this happen?");
+ SvXMLElementExport aAreaElement(mrExport, XML_NAMESPACE_DRAW, eType,
+ true/*bWhiteSpace*/, true/*bWhiteSpace*/);
+
+ // title property (as <svg:title> element)
+ OUString sTitle;
+ rPropertySet->getPropertyValue(gsTitle) >>= sTitle;
+ if(!sTitle.isEmpty())
+ {
+ SvXMLElementExport aEventElemt(mrExport, XML_NAMESPACE_SVG, XML_TITLE, true/*bWhiteSpace*/, false);
+ mrExport.Characters(sTitle);
+ }
+
+ // description property (as <svg:desc> element)
+ OUString sDescription;
+ rPropertySet->getPropertyValue(gsDescription) >>= sDescription;
+ if (!sDescription.isEmpty())
+ {
+ SvXMLElementExport aDesc(mrExport, XML_NAMESPACE_SVG, XML_DESC, true/*bWhiteSpace*/, false);
+ mrExport.Characters(sDescription);
+ }
+
+ // export events attached to this
+ Reference<XEventsSupplier> xSupplier(rPropertySet, UNO_QUERY);
+ mrExport.GetEventExport().Export(xSupplier);
+
+ // else: no service info -> can't determine type -> ignore entry
+}
+
+void XMLImageMapExport::ExportRectangle(
+ const Reference<XPropertySet> & rPropertySet)
+{
+ // get boundary rectangle
+ Any aAny = rPropertySet->getPropertyValue(gsBoundary);
+ awt::Rectangle aRectangle;
+ aAny >>= aRectangle;
+
+ // parameters svg:x, svg:y, svg:width, svg:height
+ OUStringBuffer aBuffer;
+ mrExport.GetMM100UnitConverter().convertMeasureToXML(aBuffer, aRectangle.X);
+ mrExport.AddAttribute( XML_NAMESPACE_SVG, XML_X,
+ aBuffer.makeStringAndClear() );
+ mrExport.GetMM100UnitConverter().convertMeasureToXML(aBuffer, aRectangle.Y);
+ mrExport.AddAttribute( XML_NAMESPACE_SVG, XML_Y,
+ aBuffer.makeStringAndClear() );
+ mrExport.GetMM100UnitConverter().convertMeasureToXML(aBuffer,
+ aRectangle.Width);
+ mrExport.AddAttribute( XML_NAMESPACE_SVG, XML_WIDTH,
+ aBuffer.makeStringAndClear() );
+ mrExport.GetMM100UnitConverter().convertMeasureToXML(aBuffer,
+ aRectangle.Height);
+ mrExport.AddAttribute( XML_NAMESPACE_SVG, XML_HEIGHT,
+ aBuffer.makeStringAndClear() );
+}
+
+void XMLImageMapExport::ExportCircle(
+ const Reference<XPropertySet> & rPropertySet)
+{
+ // get boundary rectangle
+ Any aAny = rPropertySet->getPropertyValue(gsCenter);
+ awt::Point aCenter;
+ aAny >>= aCenter;
+
+ // parameters svg:cx, svg:cy
+ OUStringBuffer aBuffer;
+ mrExport.GetMM100UnitConverter().convertMeasureToXML(aBuffer, aCenter.X);
+ mrExport.AddAttribute( XML_NAMESPACE_SVG, XML_CX,
+ aBuffer.makeStringAndClear() );
+ mrExport.GetMM100UnitConverter().convertMeasureToXML(aBuffer, aCenter.Y);
+ mrExport.AddAttribute( XML_NAMESPACE_SVG, XML_CY,
+ aBuffer.makeStringAndClear() );
+
+ // radius
+ aAny = rPropertySet->getPropertyValue(gsRadius);
+ sal_Int32 nRadius = 0;
+ aAny >>= nRadius;
+ mrExport.GetMM100UnitConverter().convertMeasureToXML(aBuffer, nRadius);
+ mrExport.AddAttribute( XML_NAMESPACE_SVG, XML_R,
+ aBuffer.makeStringAndClear() );
+}
+
+void XMLImageMapExport::ExportPolygon(const Reference<XPropertySet> & rPropertySet)
+{
+ // polygons get exported as bounding box, viewbox, and coordinate
+ // pair sequence. The bounding box is always the entire image.
+
+ // get polygon point sequence
+ Any aAny = rPropertySet->getPropertyValue(gsPolygon);
+ PointSequence aPoly;
+ aAny >>= aPoly;
+
+ const basegfx::B2DPolygon aPolygon(
+ basegfx::utils::UnoPointSequenceToB2DPolygon(
+ aPoly));
+ const basegfx::B2DRange aPolygonRange(aPolygon.getB2DRange());
+
+ // parameters svg:x, svg:y, svg:width, svg:height
+ OUStringBuffer aBuffer;
+
+ mrExport.GetMM100UnitConverter().convertMeasureToXML(aBuffer, 0);
+ mrExport.AddAttribute( XML_NAMESPACE_SVG, XML_X, aBuffer.makeStringAndClear() );
+ mrExport.GetMM100UnitConverter().convertMeasureToXML(aBuffer, 0);
+ mrExport.AddAttribute( XML_NAMESPACE_SVG, XML_Y, aBuffer.makeStringAndClear() );
+ mrExport.GetMM100UnitConverter().convertMeasureToXML(aBuffer, basegfx::fround(aPolygonRange.getWidth()));
+ mrExport.AddAttribute( XML_NAMESPACE_SVG, XML_WIDTH, aBuffer.makeStringAndClear() );
+ mrExport.GetMM100UnitConverter().convertMeasureToXML(aBuffer, basegfx::fround(aPolygonRange.getHeight()));
+ mrExport.AddAttribute( XML_NAMESPACE_SVG, XML_HEIGHT, aBuffer.makeStringAndClear() );
+
+ // svg:viewbox
+ SdXMLImExViewBox aViewBox(0.0, 0.0, aPolygonRange.getWidth(), aPolygonRange.getHeight());
+ mrExport.AddAttribute(XML_NAMESPACE_SVG, XML_VIEWBOX, aViewBox.GetExportString());
+
+ // export point sequence
+ const OUString aPointString(
+ basegfx::utils::exportToSvgPoints(
+ aPolygon));
+
+ mrExport.AddAttribute(XML_NAMESPACE_DRAW, XML_POINTS, aPointString);
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/xmloff/source/draw/XMLNumberStyles.cxx b/xmloff/source/draw/XMLNumberStyles.cxx
new file mode 100644
index 0000000000..e97414b914
--- /dev/null
+++ b/xmloff/source/draw/XMLNumberStyles.cxx
@@ -0,0 +1,712 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#include "XMLNumberStylesExport.hxx"
+#include <XMLNumberStylesImport.hxx>
+#include <utility>
+#include <xmloff/xmlnamespace.hxx>
+#include <xmloff/xmlimp.hxx>
+#include <xmloff/namespacemap.hxx>
+#include <xmloff/xmltoken.hxx>
+
+#include <o3tl/string_view.hxx>
+#include <sal/log.hxx>
+
+#include "sdxmlexp_impl.hxx"
+#include "sdxmlimp_impl.hxx"
+
+using namespace ::xmloff::token;
+
+namespace {
+
+struct SdXMLDataStyleNumber
+{
+ enum XMLTokenEnum meNumberStyle;
+ bool mbLong;
+ bool mbTextual;
+ bool mbDecimal02;
+ const char* mpText;
+};
+
+}
+
+SdXMLDataStyleNumber const aSdXMLDataStyleNumbers[] =
+{
+ { XML_DAY, false, false, false, nullptr },
+ { XML_DAY, true, false, false, nullptr },
+ { XML_MONTH, true, false, false, nullptr },
+ { XML_MONTH, false, true, false, nullptr },
+ { XML_MONTH, true, true, false, nullptr },
+ { XML_YEAR, false, false, false, nullptr },
+ { XML_YEAR, true, false, false, nullptr },
+ { XML_DAY_OF_WEEK, false, false, false, nullptr },
+ { XML_DAY_OF_WEEK, true, false, false, nullptr },
+ { XML_TEXT, false, false, false, "." },
+ { XML_TEXT, false, false, false, " " },
+ { XML_TEXT, false, false, false, ", " },
+ { XML_TEXT, false, false, false, ". " },
+ { XML_HOURS, false, false, false, nullptr },
+ { XML_MINUTES, false, false, false, nullptr },
+ { XML_TEXT, false, false, false, ":" },
+ { XML_AM_PM, false, false, false, nullptr },
+ { XML_SECONDS, false, false, false, nullptr },
+ { XML_SECONDS, false, false, true, nullptr },
+ { XML_TOKEN_INVALID, false, false, false, nullptr }
+};
+
+// date
+enum class DataStyleNumber : sal_uInt8
+{
+ NONE = 0,
+ Day = 1, // <number:day/>
+ DayLong = 2, // <number:day number:style="long"/>
+ MonthLong = 3, // <number:month number:style="long"/>
+ MonthText = 4, // <number:month number:textual="true"/>
+ MonthLongText = 5, // <number:month number:style="long" number:textual="true"/>
+ Year = 6, // <number:year/>
+ YearLong = 7, // <number:year number:style="long"/>
+ DayOfWeek = 8, // <number:day-of-week/>
+ DayOfWeekLong = 9, // <number:day-of-week number:style="long"/>
+ TextPoint = 10, // <number:text>.</number:text>
+ TextSpace = 11, // <number:text> </number:text>
+ TextCommaSpace = 12, // <number:text>, </number:text>
+ TextPointSpace = 13, // <number:text>. </number:text>
+ Hours = 14, // <number:hours/>
+ Minutes = 15, // <number:minutes/>
+ TextColon = 16, // <number:text>:</number:text>
+ AmPm = 17, // <number:am-pm/>
+ Seconds = 18, // <number:seconds/>
+ Seconds_02 = 19, // <number:seconds number:/>
+};
+
+struct SdXMLFixedDataStyle
+{
+ const char* mpName;
+ bool mbAutomatic;
+ bool mbDateStyle;
+ DataStyleNumber mpFormat[8];
+};
+
+const SdXMLFixedDataStyle aSdXML_Standard_Short =
+{
+ "D1", true, true,
+ {
+ DataStyleNumber::DayLong,
+ DataStyleNumber::TextPoint,
+ DataStyleNumber::MonthLong,
+ DataStyleNumber::TextPoint,
+ DataStyleNumber::YearLong,
+ DataStyleNumber::NONE, DataStyleNumber::NONE, DataStyleNumber::NONE
+ }
+};
+
+const SdXMLFixedDataStyle aSdXML_Standard_Long =
+{
+ "D2", true, true,
+ {
+ DataStyleNumber::DayOfWeekLong,
+ DataStyleNumber::TextCommaSpace,
+ DataStyleNumber::Day,
+ DataStyleNumber::TextPointSpace,
+ DataStyleNumber::MonthLongText,
+ DataStyleNumber::TextSpace,
+ DataStyleNumber::YearLong,
+ DataStyleNumber::NONE
+ }
+};
+
+const SdXMLFixedDataStyle aSdXML_DateStyle_1 =
+{
+ "D3", false, true,
+ {
+ DataStyleNumber::DayLong,
+ DataStyleNumber::TextPoint,
+ DataStyleNumber::MonthLong,
+ DataStyleNumber::TextPoint,
+ DataStyleNumber::Year,
+ DataStyleNumber::NONE, DataStyleNumber::NONE, DataStyleNumber::NONE
+ }
+};
+
+const SdXMLFixedDataStyle aSdXML_DateStyle_2 =
+{
+ "D4", false, true,
+ {
+ DataStyleNumber::DayLong,
+ DataStyleNumber::TextPoint,
+ DataStyleNumber::MonthLong,
+ DataStyleNumber::TextPoint,
+ DataStyleNumber::YearLong,
+ DataStyleNumber::NONE, DataStyleNumber::NONE, DataStyleNumber::NONE
+ }
+};
+
+const SdXMLFixedDataStyle aSdXML_DateStyle_3 =
+{
+ "D5", false, true,
+ {
+ DataStyleNumber::Day,
+ DataStyleNumber::TextPointSpace,
+ DataStyleNumber::MonthText,
+ DataStyleNumber::TextSpace,
+ DataStyleNumber::YearLong,
+ DataStyleNumber::NONE, DataStyleNumber::NONE, DataStyleNumber::NONE
+ }
+};
+
+const SdXMLFixedDataStyle aSdXML_DateStyle_4 =
+{
+ "D6", false, true,
+ {
+ DataStyleNumber::Day,
+ DataStyleNumber::TextPointSpace,
+ DataStyleNumber::MonthLongText,
+ DataStyleNumber::TextSpace,
+ DataStyleNumber::YearLong,
+ DataStyleNumber::NONE, DataStyleNumber::NONE, DataStyleNumber::NONE
+ }
+};
+
+const SdXMLFixedDataStyle aSdXML_DateStyle_5 =
+{
+ "D7", false, true,
+ {
+ DataStyleNumber::DayOfWeek,
+ DataStyleNumber::TextCommaSpace,
+ DataStyleNumber::Day,
+ DataStyleNumber::TextPointSpace,
+ DataStyleNumber::MonthLongText,
+ DataStyleNumber::TextSpace,
+ DataStyleNumber::YearLong,
+ DataStyleNumber::NONE
+ }
+};
+
+const SdXMLFixedDataStyle aSdXML_DateStyle_6 =
+{
+ "D8", false, true,
+ {
+ DataStyleNumber::DayOfWeekLong,
+ DataStyleNumber::TextCommaSpace,
+ DataStyleNumber::Day,
+ DataStyleNumber::TextPointSpace,
+ DataStyleNumber::MonthLongText,
+ DataStyleNumber::TextSpace,
+ DataStyleNumber::YearLong,
+ DataStyleNumber::NONE
+ }
+};
+
+const SdXMLFixedDataStyle aSdXML_TimeStyle_1 =
+{ "T1", true, false,
+ {
+ DataStyleNumber::Hours,
+ DataStyleNumber::TextColon,
+ DataStyleNumber::Minutes,
+ DataStyleNumber::TextColon,
+ DataStyleNumber::Seconds,
+ DataStyleNumber::AmPm,
+ DataStyleNumber::NONE, DataStyleNumber::NONE
+ }
+};
+
+const SdXMLFixedDataStyle aSdXML_TimeStyle_2 =
+{ "T2", false, false,
+ {
+ DataStyleNumber::Hours,
+ DataStyleNumber::TextColon,
+ DataStyleNumber::Minutes,
+ DataStyleNumber::NONE, DataStyleNumber::NONE, DataStyleNumber::NONE, DataStyleNumber::NONE, DataStyleNumber::NONE
+ }
+};
+
+const SdXMLFixedDataStyle aSdXML_TimeStyle_3 =
+{ "T3", false, false,
+ {
+ DataStyleNumber::Hours,
+ DataStyleNumber::TextColon,
+ DataStyleNumber::Minutes,
+ DataStyleNumber::TextColon,
+ DataStyleNumber::Seconds,
+ DataStyleNumber::NONE, DataStyleNumber::NONE, DataStyleNumber::NONE
+ }
+};
+
+const SdXMLFixedDataStyle aSdXML_TimeStyle_4 =
+{ "T4", false, false,
+ {
+ DataStyleNumber::Hours,
+ DataStyleNumber::TextColon,
+ DataStyleNumber::Minutes,
+ DataStyleNumber::TextColon,
+ DataStyleNumber::Seconds_02,
+ DataStyleNumber::NONE, DataStyleNumber::NONE, DataStyleNumber::NONE
+ }
+};
+
+const SdXMLFixedDataStyle aSdXML_TimeStyle_5 =
+{ "T5", false, false,
+ {
+ DataStyleNumber::Hours,
+ DataStyleNumber::TextColon,
+ DataStyleNumber::Minutes,
+ DataStyleNumber::AmPm,
+ DataStyleNumber::NONE, DataStyleNumber::NONE, DataStyleNumber::NONE, DataStyleNumber::NONE
+ }
+};
+
+const SdXMLFixedDataStyle aSdXML_TimeStyle_6 =
+{ "T6", false, false,
+ {
+ DataStyleNumber::Hours,
+ DataStyleNumber::TextColon,
+ DataStyleNumber::Minutes,
+ DataStyleNumber::TextColon,
+ DataStyleNumber::Seconds,
+ DataStyleNumber::AmPm,
+ DataStyleNumber::NONE, DataStyleNumber::NONE
+ }
+};
+
+const SdXMLFixedDataStyle aSdXML_TimeStyle_7 =
+{ "T7", false, false,
+ {
+ DataStyleNumber::Hours,
+ DataStyleNumber::TextColon,
+ DataStyleNumber::Minutes,
+ DataStyleNumber::TextColon,
+ DataStyleNumber::Seconds_02,
+ DataStyleNumber::AmPm,
+ DataStyleNumber::NONE, DataStyleNumber::NONE
+ }
+};
+
+const SdXMLFixedDataStyle* const aSdXMLFixedDateFormats[SdXMLDateFormatCount] =
+{
+ &aSdXML_Standard_Short,
+ &aSdXML_Standard_Long,
+ &aSdXML_DateStyle_1,
+ &aSdXML_DateStyle_2,
+ &aSdXML_DateStyle_3,
+ &aSdXML_DateStyle_4,
+ &aSdXML_DateStyle_5,
+ &aSdXML_DateStyle_6,
+};
+
+const SdXMLFixedDataStyle* const aSdXMLFixedTimeFormats[SdXMLTimeFormatCount] =
+{
+ &aSdXML_TimeStyle_1,
+ &aSdXML_TimeStyle_2,
+ &aSdXML_TimeStyle_3,
+ &aSdXML_TimeStyle_4,
+ &aSdXML_TimeStyle_5,
+ &aSdXML_TimeStyle_6,
+ &aSdXML_TimeStyle_7
+};
+
+// export
+
+static void SdXMLExportDataStyleNumber( SdXMLExport& rExport, SdXMLDataStyleNumber const & rElement )
+{
+ if( rElement.mbDecimal02 )
+ {
+ rExport.AddAttribute( XML_NAMESPACE_NUMBER, XML_DECIMAL_PLACES, XML_2 );
+ }
+
+ if( rElement.mbLong )
+ {
+ rExport.AddAttribute( XML_NAMESPACE_NUMBER, XML_STYLE, XML_LONG );
+ }
+
+ if( rElement.mbTextual )
+ {
+ rExport.AddAttribute( XML_NAMESPACE_NUMBER, XML_TEXTUAL, XML_TRUE );
+ }
+
+ SvXMLElementExport aNumberStyle( rExport, XML_NAMESPACE_NUMBER, rElement.meNumberStyle, true, false );
+ if( rElement.mpText )
+ {
+ OUString sAttrValue( OUString::createFromAscii( rElement.mpText ) );
+ rExport.GetDocHandler()->characters( sAttrValue );
+ }
+}
+
+static void SdXMLExportStyle( SdXMLExport& rExport, const SdXMLFixedDataStyle* pStyle, const SdXMLFixedDataStyle* pStyle2 = nullptr )
+{
+ // name
+ OUString sAttrValue = OUString::createFromAscii( pStyle->mpName );
+ if( pStyle2 )
+ sAttrValue += OUString::createFromAscii( pStyle2->mpName );
+
+ rExport.AddAttribute( XML_NAMESPACE_STYLE, XML_NAME, sAttrValue );
+
+ if( pStyle->mbAutomatic )
+ {
+ rExport.AddAttribute( XML_NAMESPACE_NUMBER, XML_AUTOMATIC_ORDER, XML_TRUE );
+ }
+
+ SvXMLElementExport aElement( rExport, XML_NAMESPACE_NUMBER, pStyle->mbDateStyle ? XML_DATE_STYLE : XML_TIME_STYLE, true, true );
+
+ do
+ {
+
+ const DataStyleNumber* pElements = &pStyle->mpFormat[0];
+
+ while( *pElements != DataStyleNumber::NONE )
+ {
+ SdXMLDataStyleNumber const & rElement = aSdXMLDataStyleNumbers[ static_cast<int>(*pElements++) - 1 ];
+ SdXMLExportDataStyleNumber( rExport, rElement );
+ }
+
+ if( pStyle2 )
+ {
+ SdXMLDataStyleNumber const & rElement = aSdXMLDataStyleNumbers[ static_cast<int>(DataStyleNumber::TextSpace) - 1 ];
+ SdXMLExportDataStyleNumber( rExport, rElement );
+ }
+
+ pStyle = pStyle2;
+ pStyle2 = nullptr;
+ }
+ while( pStyle );
+}
+
+void SdXMLNumberStylesExporter::exportTimeStyle( SdXMLExport& rExport, sal_Int32 nStyle )
+{
+ SAL_WARN_IF( (nStyle < 0) || (nStyle >= SdXMLTimeFormatCount), "xmloff", "Unknown time style!" );
+ if( (nStyle >= 0) && (nStyle < SdXMLTimeFormatCount) )
+ SdXMLExportStyle( rExport, aSdXMLFixedTimeFormats[ nStyle ] );
+}
+
+void SdXMLNumberStylesExporter::exportDateStyle( SdXMLExport& rExport, sal_Int32 nStyle )
+{
+ if( nStyle > 0x0f )
+ {
+ int nDateStyle = nStyle & 0x0f;
+ bool bHasDate = nDateStyle != 0;
+
+ if( nDateStyle > 1 )
+ nDateStyle -= 2;
+
+ SAL_WARN_IF(nDateStyle >= SdXMLDateFormatCount, "xmloff", "unknown date style!");
+
+ int nTimeStyle = (nStyle >> 4) & 0x0f;
+ bool bHasTime = nTimeStyle != 0;
+
+ if( nTimeStyle > 1 )
+ nTimeStyle -= 2;
+
+ SAL_WARN_IF(nTimeStyle >= SdXMLTimeFormatCount, "xmloff", "Unknown time style!");
+
+ if ((nDateStyle < SdXMLDateFormatCount) && (nTimeStyle < SdXMLTimeFormatCount))
+ {
+ if( bHasDate )
+ {
+ if( bHasTime )
+ {
+ SdXMLExportStyle( rExport, aSdXMLFixedDateFormats[ nDateStyle ], aSdXMLFixedTimeFormats[ nTimeStyle ] );
+ }
+ else
+ {
+ SdXMLExportStyle( rExport, aSdXMLFixedDateFormats[ nDateStyle ] );
+ }
+ }
+ else if( bHasTime )
+ {
+ SdXMLExportStyle( rExport, aSdXMLFixedTimeFormats[ nTimeStyle ] );
+ }
+ }
+ }
+ else
+ {
+ SAL_WARN_IF( (nStyle < 0) || (nStyle >= SdXMLDateFormatCount), "xmloff", "unknown date style!" );
+ if( (nStyle >= 0) && (nStyle < SdXMLDateFormatCount) )
+ SdXMLExportStyle( rExport, aSdXMLFixedDateFormats[ nStyle ] );
+ }
+}
+
+OUString SdXMLNumberStylesExporter::getTimeStyleName(const sal_Int32 nTimeFormat )
+{
+ sal_Int32 nFormat = nTimeFormat;
+ if( nFormat > 1 )
+ nFormat -= 2;
+
+ if( (nFormat >= 0) && (nFormat < SdXMLTimeFormatCount) )
+ {
+ return OUString::createFromAscii(aSdXMLFixedTimeFormats[nFormat]->mpName );
+ }
+ else
+ {
+ return OUString();
+ }
+}
+
+OUString SdXMLNumberStylesExporter::getDateStyleName(const sal_Int32 nDateFormat )
+{
+ sal_Int32 nFormat = nDateFormat;
+
+ if( nFormat > 0x0f )
+ {
+ OUString aStr;
+ if( nFormat & 0x0f )
+ aStr = getDateStyleName( nFormat & 0x0f );
+ aStr += getTimeStyleName( (nFormat >> 4) & 0x0f );
+ return aStr;
+ }
+
+ if( nFormat > 1 )
+ nFormat -= 2;
+
+ if( (nFormat >= 0) && (nFormat < SdXMLDateFormatCount) )
+ {
+ return OUString::createFromAscii(aSdXMLFixedDateFormats[nFormat]->mpName );
+ }
+ else
+ {
+ return OUString();
+ }
+}
+
+// import
+
+class SdXMLNumberFormatMemberImportContext : public SvXMLImportContext
+{
+private:
+ SdXMLNumberFormatImportContext* mpParent;
+
+ OUString maNumberStyle;
+ bool mbLong;
+ bool mbTextual;
+ bool mbDecimal02;
+ OUString maText;
+ SvXMLImportContextRef mxSlaveContext;
+
+public:
+
+ SdXMLNumberFormatMemberImportContext( SvXMLImport& rImport,
+ sal_Int32 nElement,
+ const css::uno::Reference< css::xml::sax::XFastAttributeList>& xAttrList,
+ SdXMLNumberFormatImportContext* pParent,
+ SvXMLImportContextRef xSlaveContext );
+
+ virtual css::uno::Reference< css::xml::sax::XFastContextHandler > SAL_CALL createFastChildContext(
+ sal_Int32 nElement, const css::uno::Reference< css::xml::sax::XFastAttributeList >& AttrList ) override;
+
+ virtual void SAL_CALL startFastElement( sal_Int32 nElement,
+ const css::uno::Reference< css::xml::sax::XFastAttributeList >& ) override;
+
+ virtual void SAL_CALL endFastElement(sal_Int32 nElement) override;
+
+ virtual void SAL_CALL characters( const OUString& rChars ) override;
+};
+
+
+SdXMLNumberFormatMemberImportContext::SdXMLNumberFormatMemberImportContext(
+ SvXMLImport& rImport,
+ sal_Int32 nElement,
+ const css::uno::Reference< css::xml::sax::XFastAttributeList>& xAttrList,
+ SdXMLNumberFormatImportContext* pParent,
+ SvXMLImportContextRef xSlaveContext )
+: SvXMLImportContext(rImport),
+ mpParent( pParent ),
+ maNumberStyle( SvXMLImport::getNameFromToken(nElement) ),
+ mxSlaveContext(std::move( xSlaveContext ))
+{
+ mbLong = false;
+ mbTextual = false;
+ mbDecimal02 = false;
+
+ for (auto &aIter : sax_fastparser::castToFastAttributeList( xAttrList ))
+ {
+ switch (aIter.getToken())
+ {
+ case XML_ELEMENT(NUMBER, XML_DECIMAL_PLACES):
+ mbDecimal02 = IsXMLToken( aIter, XML_2 );
+ break;
+ case XML_ELEMENT(NUMBER, XML_STYLE):
+ mbLong = IsXMLToken( aIter, XML_LONG );
+ break;
+ case XML_ELEMENT(NUMBER, XML_TEXTUAL):
+ mbTextual = IsXMLToken( aIter, XML_TRUE );
+ break;
+ default:
+ XMLOFF_WARN_UNKNOWN("xmloff", aIter);
+ }
+ }
+
+}
+
+css::uno::Reference< css::xml::sax::XFastContextHandler > SdXMLNumberFormatMemberImportContext::createFastChildContext(
+ sal_Int32 nElement,
+ const css::uno::Reference< css::xml::sax::XFastAttributeList >& xAttrList )
+{
+ return mxSlaveContext->createFastChildContext( nElement, xAttrList );
+}
+
+void SdXMLNumberFormatMemberImportContext::startFastElement(
+ sal_Int32 nElement,
+ const css::uno::Reference< css::xml::sax::XFastAttributeList >& xAttrList )
+{
+ mxSlaveContext->startFastElement( nElement, xAttrList );
+}
+
+void SdXMLNumberFormatMemberImportContext::endFastElement(sal_Int32 nElement)
+{
+ mxSlaveContext->endFastElement(nElement);
+
+ if( mpParent )
+ mpParent->add( maNumberStyle, mbLong, mbTextual, mbDecimal02, maText );
+}
+
+void SdXMLNumberFormatMemberImportContext::characters( const OUString& rChars )
+{
+ mxSlaveContext->characters( rChars );
+ maText += rChars;
+}
+
+
+SdXMLNumberFormatImportContext::SdXMLNumberFormatImportContext( SdXMLImport& rImport, sal_Int32 nElement, SvXMLNumImpData* pNewData, SvXMLStylesTokens nNewType, const css::uno::Reference< css::xml::sax::XFastAttributeList>& xAttrList, SvXMLStylesContext& rStyles)
+: SvXMLNumFormatContext(rImport, nElement, pNewData, nNewType, xAttrList, rStyles),
+ mbAutomatic( false ),
+ mnElements{},
+ mnIndex(0),
+ mnKey( -1 )
+{
+ mbTimeStyle = (nElement & TOKEN_MASK) == XML_TIME_STYLE;
+
+ for (auto &aIter : sax_fastparser::castToFastAttributeList( xAttrList ))
+ {
+ if( aIter.getToken() == XML_ELEMENT(NUMBER, XML_AUTOMATIC_ORDER) )
+ mbAutomatic = IsXMLToken( aIter, XML_TRUE );
+ else
+ XMLOFF_WARN_UNKNOWN("xmloff", aIter);
+ }
+}
+
+SdXMLNumberFormatImportContext::~SdXMLNumberFormatImportContext()
+{
+}
+
+void SdXMLNumberFormatImportContext::add( std::u16string_view rNumberStyle, bool bLong, bool bTextual, bool bDecimal02, std::u16string_view rText )
+{
+ if (mnIndex == 16)
+ return;
+
+ const SdXMLDataStyleNumber* pStyleMember = aSdXMLDataStyleNumbers;
+ for( sal_uInt8 nIndex = 0; pStyleMember->meNumberStyle != XML_TOKEN_INVALID; nIndex++, pStyleMember++ )
+ {
+ if( IsXMLToken(rNumberStyle, pStyleMember->meNumberStyle) &&
+ (pStyleMember->mbLong == bLong) &&
+ (pStyleMember->mbTextual == bTextual) &&
+ (pStyleMember->mbDecimal02 == bDecimal02) &&
+ ( ( (pStyleMember->mpText == nullptr) && (rText.empty()) ) ||
+ ( pStyleMember->mpText && (o3tl::equalsAscii( rText, pStyleMember->mpText ) ) ) ) )
+ {
+ mnElements[mnIndex++] = static_cast<DataStyleNumber>(nIndex + 1);
+ return;
+ }
+ }
+}
+
+bool SdXMLNumberFormatImportContext::compareStyle( const SdXMLFixedDataStyle* pStyle, sal_Int16& nIndex ) const
+{
+ if( (pStyle->mbAutomatic != mbAutomatic) && (nIndex == 0))
+ return false;
+
+ sal_Int16 nCompareIndex;
+ for( nCompareIndex = 0; nCompareIndex < 8; nIndex++, nCompareIndex++ )
+ {
+ if( pStyle->mpFormat[nCompareIndex] != mnElements[nIndex] )
+ return false;
+ }
+
+ return true;
+}
+
+void SdXMLNumberFormatImportContext::endFastElement(sal_Int32 )
+{
+ for( ; mnIndex < 16; mnIndex++ )
+ {
+ mnElements[mnIndex] = DataStyleNumber::NONE;
+ }
+
+ if( mbTimeStyle )
+ {
+ // compare import with all time styles
+ for( sal_Int16 nFormat = 0; nFormat < SdXMLTimeFormatCount; nFormat++ )
+ {
+ sal_Int16 nIndex = 0;
+ if( compareStyle( aSdXMLFixedTimeFormats[nFormat], nIndex ) )
+ {
+ mnKey = nFormat + 2;
+ break;
+ }
+ }
+ }
+ else
+ {
+ // compare import with all date styles
+ for( sal_Int16 nFormat = 0; nFormat < SdXMLDateFormatCount; nFormat++ )
+ {
+ sal_Int16 nIndex = 0;
+ if( compareStyle( aSdXMLFixedDateFormats[nFormat], nIndex ) )
+ {
+ mnKey = nFormat + 2;
+ break;
+ }
+ else if( mnElements[nIndex] == DataStyleNumber::TextSpace )
+ {
+ // if it's a valid date ending with a space, see if a time style follows
+ for( sal_Int16 nTimeFormat = 0; nTimeFormat < SdXMLTimeFormatCount; nTimeFormat++ )
+ {
+ sal_Int16 nIndex2 = nIndex + 1;
+ if( compareStyle( aSdXMLFixedTimeFormats[nTimeFormat], nIndex2 ) )
+ {
+ mnKey = (nFormat + 2) | ((nTimeFormat + 2) << 4);
+ break;
+ }
+ }
+ }
+ }
+
+ // no date style found? maybe it's an extended time style
+ if( mnKey == -1 )
+ {
+ // compare import with all time styles
+ for( sal_Int16 nFormat = 0; nFormat < SdXMLTimeFormatCount; nFormat++ )
+ {
+ sal_Int16 nIndex = 0;
+ if( compareStyle( aSdXMLFixedTimeFormats[nFormat], nIndex ) )
+ {
+ mnKey = (nFormat + 2) << 4;
+ break;
+ }
+ }
+ }
+ }
+}
+
+css::uno::Reference< css::xml::sax::XFastContextHandler > SdXMLNumberFormatImportContext::createFastChildContext(
+ sal_Int32 nElement,
+ const css::uno::Reference< css::xml::sax::XFastAttributeList >& xAttrList )
+{
+ return new SdXMLNumberFormatMemberImportContext( GetImport(), nElement, xAttrList,
+ this, static_cast<SvXMLImportContext*>(SvXMLNumFormatContext::createFastChildContext( nElement, xAttrList ).get()) );
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/xmloff/source/draw/XMLNumberStylesExport.hxx b/xmloff/source/draw/XMLNumberStylesExport.hxx
new file mode 100644
index 0000000000..8b4f39dc5a
--- /dev/null
+++ b/xmloff/source/draw/XMLNumberStylesExport.hxx
@@ -0,0 +1,40 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#pragma once
+
+#include <sal/types.h>
+#include <rtl/ustring.hxx>
+
+class SdXMLExport;
+
+const sal_Int16 SdXMLDateFormatCount = 8;
+const sal_Int16 SdXMLTimeFormatCount = 7;
+
+class SdXMLNumberStylesExporter
+{
+public:
+ static void exportTimeStyle(SdXMLExport& rExport, sal_Int32 nStyle);
+ static void exportDateStyle(SdXMLExport& rExport, sal_Int32 nStyle);
+
+ static OUString getTimeStyleName(const sal_Int32 nTimeFormat);
+ static OUString getDateStyleName(const sal_Int32 nDateFormat);
+};
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/xmloff/source/draw/XMLReplacementImageContext.cxx b/xmloff/source/draw/XMLReplacementImageContext.cxx
new file mode 100644
index 0000000000..5321d55788
--- /dev/null
+++ b/xmloff/source/draw/XMLReplacementImageContext.cxx
@@ -0,0 +1,99 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#include <com/sun/star/beans/XPropertySet.hpp>
+#include <com/sun/star/graphic/XGraphic.hpp>
+#include <osl/diagnose.h>
+#include <xmloff/xmlimp.hxx>
+#include <xmloff/xmltoken.hxx>
+#include <xmloff/xmlnamespace.hxx>
+#include <xmloff/namespacemap.hxx>
+#include <xmloff/XMLBase64ImportContext.hxx>
+#include <XMLReplacementImageContext.hxx>
+#include <sal/log.hxx>
+
+using ::com::sun::star::uno::Reference;
+using namespace ::com::sun::star::xml::sax;
+using namespace ::com::sun::star::beans;
+using namespace css;
+using namespace ::xmloff::token;
+
+XMLReplacementImageContext::XMLReplacementImageContext(
+ SvXMLImport& rImport,
+ sal_Int32 /*nElement*/,
+ const Reference< XFastAttributeList > & rAttrList,
+ const Reference< XPropertySet > & rPropSet ) :
+ SvXMLImportContext( rImport ),
+ m_xPropSet( rPropSet )
+{
+ m_sHRef = rAttrList->getOptionalValue(XML_ELEMENT(XLINK, XML_HREF));
+}
+
+XMLReplacementImageContext::~XMLReplacementImageContext()
+{
+}
+
+void XMLReplacementImageContext::endFastElement(sal_Int32 )
+{
+ OSL_ENSURE( !m_sHRef.isEmpty() || m_xBase64Stream.is(),
+ "neither URL nor base64 image data given" );
+ uno::Reference<graphic::XGraphic> xGraphic;
+
+ try
+ {
+ if( !m_sHRef.isEmpty() )
+ {
+ xGraphic = GetImport().loadGraphicByURL(m_sHRef);
+ }
+ else if( m_xBase64Stream.is() )
+ {
+ xGraphic = GetImport().loadGraphicFromBase64(m_xBase64Stream);
+ m_xBase64Stream = nullptr;
+ }
+ }
+ catch (uno::Exception const &)
+ {}
+
+ Reference < XPropertySetInfo > xPropSetInfo = m_xPropSet->getPropertySetInfo();
+
+ if (xGraphic.is() && xPropSetInfo->hasPropertyByName("Graphic"))
+ {
+ m_xPropSet->setPropertyValue("Graphic", uno::Any(xGraphic));
+ }
+}
+
+css::uno::Reference< css::xml::sax::XFastContextHandler > XMLReplacementImageContext::createFastChildContext(
+ sal_Int32 nElement,
+ const css::uno::Reference< css::xml::sax::XFastAttributeList >& )
+{
+ if( nElement == XML_ELEMENT(OFFICE, XML_BINARY_DATA) &&
+ !m_xBase64Stream.is() )
+ {
+ m_xBase64Stream = GetImport().GetStreamForGraphicObjectURLFromBase64();
+ if( m_xBase64Stream.is() )
+ return new XMLBase64ImportContext( GetImport(),
+ m_xBase64Stream );
+ }
+
+ XMLOFF_WARN_UNKNOWN_ELEMENT("xmloff", nElement);
+ return nullptr;
+}
+
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/xmloff/source/draw/XMLShapePropertySetContext.cxx b/xmloff/source/draw/XMLShapePropertySetContext.cxx
new file mode 100644
index 0000000000..79b56b37c0
--- /dev/null
+++ b/xmloff/source/draw/XMLShapePropertySetContext.cxx
@@ -0,0 +1,94 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#include <XMLShapePropertySetContext.hxx>
+#include <XMLTextColumnsContext.hxx>
+#include <xmloff/XMLComplexColorContext.hxx>
+#include <xmloff/xmlimp.hxx>
+#include <xmloff/xmlnumi.hxx>
+#include <xmltabi.hxx>
+#include <xmlsdtypes.hxx>
+#include <xmloff/txtprmap.hxx>
+#include <xmloff/xmlimppr.hxx>
+
+#include <com/sun/star/container/XIndexReplace.hpp>
+
+using namespace ::com::sun::star;
+using namespace ::com::sun::star::uno;
+
+
+XMLShapePropertySetContext::XMLShapePropertySetContext(
+ SvXMLImport& rImport, sal_Int32 nElement,
+ const Reference< xml::sax::XFastAttributeList > & xAttrList,
+ sal_uInt32 nFam,
+ ::std::vector< XMLPropertyState > &rProps,
+ const rtl::Reference < SvXMLImportPropertyMapper > &rMap ) :
+ SvXMLPropertySetContext( rImport, nElement, xAttrList, nFam,
+ rProps, rMap ),
+ mnBulletIndex(-1)
+{
+}
+
+XMLShapePropertySetContext::~XMLShapePropertySetContext()
+{
+}
+
+void XMLShapePropertySetContext::endFastElement(sal_Int32 )
+{
+ Reference< container::XIndexReplace > xNumRule;
+ if( mxBulletStyle.is() )
+ {
+ xNumRule = SvxXMLListStyleContext::CreateNumRule( GetImport().GetModel() );
+ if( xNumRule.is() )
+ mxBulletStyle->FillUnoNumRule(xNumRule);
+ }
+
+ XMLPropertyState aPropState( mnBulletIndex, Any(xNumRule) );
+ mrProperties.push_back( aPropState );
+}
+
+css::uno::Reference< css::xml::sax::XFastContextHandler > XMLShapePropertySetContext::createFastChildContext(
+ sal_Int32 nElement,
+ const css::uno::Reference< css::xml::sax::XFastAttributeList >& xAttrList,
+ ::std::vector< XMLPropertyState > &rProperties,
+ const XMLPropertyState& rProp )
+{
+ switch( mxMapper->getPropertySetMapper()->GetEntryContextId( rProp.mnIndex ) )
+ {
+ case CTF_NUMBERINGRULES:
+ mnBulletIndex = rProp.mnIndex;
+ mxBulletStyle = new SvxXMLListStyleContext( GetImport() );
+ return mxBulletStyle;
+ case CTF_TABSTOP:
+ return new SvxXMLTabStopImportContext( GetImport(), nElement,
+ rProp,
+ rProperties );
+ case CTF_TEXTCOLUMNS:
+ return new XMLTextColumnsContext(GetImport(), nElement, xAttrList, rProp, rProperties);
+
+ case CTF_COMPLEX_COLOR:
+ return new XMLPropertyComplexColorContext(GetImport(), nElement, xAttrList, rProp, rProperties);
+ }
+
+ return SvXMLPropertySetContext::createFastChildContext( nElement,
+ xAttrList,
+ rProperties, rProp );
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/xmloff/source/draw/XMLShapeStyleContext.cxx b/xmloff/source/draw/XMLShapeStyleContext.cxx
new file mode 100644
index 0000000000..da4341731b
--- /dev/null
+++ b/xmloff/source/draw/XMLShapeStyleContext.cxx
@@ -0,0 +1,323 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#include <tools/debug.hxx>
+#include <sal/log.hxx>
+#include <xmloff/XMLShapeStyleContext.hxx>
+#include <XMLShapePropertySetContext.hxx>
+#include <xmloff/contextid.hxx>
+#include <com/sun/star/drawing/FillStyle.hpp>
+#include <com/sun/star/drawing/XControlShape.hpp>
+#include <com/sun/star/beans/XPropertySet.hpp>
+#include <com/sun/star/beans/XPropertySetInfo.hpp>
+#include <com/sun/star/lang/IllegalArgumentException.hpp>
+#include <com/sun/star/container/XIndexReplace.hpp>
+#include <xmloff/xmlimp.hxx>
+#include <xmloff/xmlnumi.hxx>
+#include <xmloff/xmlnamespace.hxx>
+#include <xmloff/xmlprmap.hxx>
+#include <xmloff/xmltoken.hxx>
+#include <xmloff/xmlerror.hxx>
+#include <xmloff/maptype.hxx>
+#include <xmloff/xmlimppr.hxx>
+
+#include <xmlsdtypes.hxx>
+
+using namespace ::com::sun::star;
+using namespace ::com::sun::star::uno;
+using namespace ::com::sun::star::beans;
+using namespace ::com::sun::star::drawing;
+using namespace ::xmloff::token;
+
+
+XMLShapeStyleContext::XMLShapeStyleContext(
+ SvXMLImport& rImport,
+ SvXMLStylesContext& rStyles,
+ XmlStyleFamily nFamily)
+: XMLPropStyleContext(rImport, rStyles, nFamily ),
+ m_bIsNumRuleAlreadyConverted( false )
+{
+}
+
+XMLShapeStyleContext::~XMLShapeStyleContext()
+{
+}
+
+void XMLShapeStyleContext::SetAttribute( sal_Int32 nElement, const OUString& rValue )
+{
+ if (m_sControlDataStyleName.isEmpty() && (nElement & TOKEN_MASK) == XML_DATA_STYLE_NAME)
+ {
+ m_sControlDataStyleName = rValue;
+ }
+ else if( nElement == XML_ELEMENT(STYLE, XML_LIST_STYLE_NAME) )
+ {
+ m_sListStyleName = rValue;
+ }
+ else
+ {
+ XMLPropStyleContext::SetAttribute( nElement, rValue );
+
+ if( nElement == XML_ELEMENT(STYLE, XML_NAME) || nElement == XML_ELEMENT(STYLE, XML_DISPLAY_NAME) )
+ {
+ if( !GetName().isEmpty() && !GetDisplayName().isEmpty() && GetName() != GetDisplayName() )
+ {
+ GetImport().
+ AddStyleDisplayName( GetFamily(), GetName(), GetDisplayName() );
+ }
+ }
+ }
+}
+
+css::uno::Reference< css::xml::sax::XFastContextHandler > XMLShapeStyleContext::createFastChildContext(
+ sal_Int32 nElement,
+ const css::uno::Reference< css::xml::sax::XFastAttributeList >& xAttrList )
+{
+ if( IsTokenInNamespace(nElement, XML_NAMESPACE_STYLE) ||
+ IsTokenInNamespace(nElement, XML_NAMESPACE_LO_EXT) )
+ {
+ sal_Int32 nLocalName = nElement & TOKEN_MASK;
+ sal_uInt32 nFamily = 0;
+ if( nLocalName == XML_TEXT_PROPERTIES )
+ nFamily = XML_TYPE_PROP_TEXT;
+ else if( nLocalName == XML_PARAGRAPH_PROPERTIES )
+ nFamily = XML_TYPE_PROP_PARAGRAPH;
+ else if( nLocalName == XML_GRAPHIC_PROPERTIES )
+ nFamily = XML_TYPE_PROP_GRAPHIC;
+ if( nFamily )
+ {
+ rtl::Reference < SvXMLImportPropertyMapper > xImpPrMap =
+ GetStyles()->GetImportPropertyMapper( GetFamily() );
+ if( xImpPrMap.is() )
+ return new XMLShapePropertySetContext( GetImport(), nElement, xAttrList,
+ nFamily,
+ GetProperties(),
+ xImpPrMap );
+ }
+ }
+
+ return XMLPropStyleContext::createFastChildContext( nElement, xAttrList );
+}
+
+void XMLShapeStyleContext::FillPropertySet( const Reference< beans::XPropertySet > & rPropSet )
+{
+ if( !m_bIsNumRuleAlreadyConverted )
+ {
+ m_bIsNumRuleAlreadyConverted = true;
+
+ // for compatibility to beta files, search for CTF_SD_NUMBERINGRULES_NAME to
+ // import numbering rules from the style:properties element
+ const rtl::Reference< XMLPropertySetMapper >&rMapper = GetStyles()->GetImportPropertyMapper( GetFamily() )->getPropertySetMapper();
+
+ ::std::vector< XMLPropertyState > &rProperties = GetProperties();
+ ::std::vector< XMLPropertyState >::iterator end( rProperties.end() );
+
+ // first, look for the old format, where we had a text:list-style-name
+ // attribute in the style:properties element
+ auto property = std::find_if(rProperties.begin(), end, [&rMapper](XMLPropertyState& rProp) {
+ // find properties with context
+ return (rProp.mnIndex != -1) && (rMapper->GetEntryContextId( rProp.mnIndex ) == CTF_SD_NUMBERINGRULES_NAME); });
+
+ // if we did not find an old list-style-name in the properties, and we need one
+ // because we got a style:list-style attribute in the style-style element
+ // we generate one
+ if( (property == end) && ( !m_sListStyleName.isEmpty() ) )
+ {
+ sal_Int32 nIndex = rMapper->FindEntryIndex( CTF_SD_NUMBERINGRULES_NAME );
+ SAL_WARN_IF( -1 == nIndex, "xmloff", "can't find numbering rules property entry, can't set numbering rule!" );
+
+ XMLPropertyState aNewState( nIndex );
+ rProperties.push_back( aNewState );
+ end = rProperties.end();
+ property = end - 1;
+ }
+
+ // so, if we have an old or a new list style name, we set its value to
+ // a numbering rule
+ if( property != end )
+ {
+ if( m_sListStyleName.isEmpty() )
+ {
+ property->maValue >>= m_sListStyleName;
+ }
+
+ const SvxXMLListStyleContext *pListStyle = GetImport().GetTextImport()->FindAutoListStyle( m_sListStyleName );
+
+ SAL_WARN_IF( !pListStyle, "xmloff", "list-style not found for shape style" );
+ if( pListStyle )
+ {
+ uno::Reference< container::XIndexReplace > xNumRule( SvxXMLListStyleContext::CreateNumRule( GetImport().GetModel() ) );
+ pListStyle->FillUnoNumRule(xNumRule);
+ property->maValue <<= xNumRule;
+ }
+ else
+ {
+ property->mnIndex = -1;
+ }
+ }
+ }
+
+ struct ContextID_Index_Pair aContextIDs[] =
+ {
+ { CTF_DASHNAME, -1, drawing::FillStyle::FillStyle_MAKE_FIXED_SIZE },
+ { CTF_LINESTARTNAME, -1, drawing::FillStyle::FillStyle_MAKE_FIXED_SIZE },
+ { CTF_LINEENDNAME, -1, drawing::FillStyle::FillStyle_MAKE_FIXED_SIZE },
+ { CTF_FILLGRADIENTNAME, -1, drawing::FillStyle::FillStyle_GRADIENT },
+ { CTF_FILLTRANSNAME, -1, drawing::FillStyle::FillStyle_MAKE_FIXED_SIZE },
+ { CTF_FILLHATCHNAME, -1, drawing::FillStyle::FillStyle_HATCH },
+ { CTF_FILLBITMAPNAME, -1, drawing::FillStyle::FillStyle_BITMAP },
+ { CTF_SD_OLE_VIS_AREA_IMPORT_LEFT, -1, drawing::FillStyle::FillStyle_MAKE_FIXED_SIZE },
+ { CTF_SD_OLE_VIS_AREA_IMPORT_TOP, -1, drawing::FillStyle::FillStyle_MAKE_FIXED_SIZE },
+ { CTF_SD_OLE_VIS_AREA_IMPORT_WIDTH, -1, drawing::FillStyle::FillStyle_MAKE_FIXED_SIZE },
+ { CTF_SD_OLE_VIS_AREA_IMPORT_HEIGHT, -1, drawing::FillStyle::FillStyle_MAKE_FIXED_SIZE },
+ { -1, -1, drawing::FillStyle::FillStyle_MAKE_FIXED_SIZE }
+ };
+ static const XmlStyleFamily aFamilies[] =
+ {
+ XmlStyleFamily::SD_STROKE_DASH_ID,
+ XmlStyleFamily::SD_MARKER_ID,
+ XmlStyleFamily::SD_MARKER_ID,
+ XmlStyleFamily::SD_GRADIENT_ID,
+ XmlStyleFamily::SD_GRADIENT_ID,
+ XmlStyleFamily::SD_HATCH_ID,
+ XmlStyleFamily::SD_FILL_IMAGE_ID
+ };
+
+ rtl::Reference < SvXMLImportPropertyMapper > xImpPrMap =
+ GetStyles()->GetImportPropertyMapper( GetFamily() );
+ SAL_WARN_IF( !xImpPrMap.is(), "xmloff", "There is the import prop mapper" );
+ if( xImpPrMap.is() )
+ xImpPrMap->FillPropertySet( GetProperties(), rPropSet, aContextIDs );
+
+ Reference< XPropertySetInfo > xInfo;
+ // get property set mapper
+ rtl::Reference<XMLPropertySetMapper> xPropMapper( xImpPrMap->getPropertySetMapper() );
+
+ for( sal_uInt16 i=0; aContextIDs[i].nContextID != -1; i++ )
+ {
+ sal_Int32 nIndex = aContextIDs[i].nIndex;
+ if( nIndex != -1 ) switch( aContextIDs[i].nContextID )
+ {
+ case CTF_DASHNAME:
+ case CTF_LINESTARTNAME:
+ case CTF_LINEENDNAME:
+ case CTF_FILLGRADIENTNAME:
+ case CTF_FILLTRANSNAME:
+ case CTF_FILLHATCHNAME:
+ case CTF_FILLBITMAPNAME:
+ {
+ struct XMLPropertyState& rState = GetProperties()[nIndex];
+ OUString sStyleName;
+ rState.maValue >>= sStyleName;
+ sStyleName = GetImport().GetStyleDisplayName( aFamilies[i], sStyleName );
+ // All of these attributes refer to something with draw:name
+ // of type styleName = NCName which is non-empty.
+ // tdf#89802: for Writer frames there would be no exception here but
+ // it will fail later on attach() and take out the entire frame
+ if (sStyleName.isEmpty() &&
+ ( CTF_FILLGRADIENTNAME == aContextIDs[i].nContextID
+ || CTF_FILLTRANSNAME == aContextIDs[i].nContextID
+ || CTF_FILLHATCHNAME == aContextIDs[i].nContextID
+ || CTF_FILLBITMAPNAME == aContextIDs[i].nContextID))
+ {
+ Sequence<OUString> const seq{ sStyleName };
+ GetImport().SetError(
+ XMLERROR_STYLE_PROP_VALUE | XMLERROR_FLAG_WARNING,
+ seq, "empty style name reference", nullptr );
+ break;
+ }
+
+ if (::xmloff::IsIgnoreFillStyleNamedItem(rPropSet, aContextIDs[i].nExpectedFillStyle))
+ {
+ SAL_INFO("xmloff.style", "ShapeStyleContext: dropping fill named item: " << sStyleName);
+ break; // ignore it, it's not used
+ }
+
+ try
+ {
+
+ // set property
+ const OUString& rPropertyName = xPropMapper->GetEntryAPIName(rState.mnIndex);
+ if( !xInfo.is() )
+ xInfo = rPropSet->getPropertySetInfo();
+ if ( xInfo->hasPropertyByName( rPropertyName ) )
+ {
+ rPropSet->setPropertyValue( rPropertyName, Any( sStyleName ) );
+ }
+ }
+ catch ( const css::lang::IllegalArgumentException& e )
+ {
+ Sequence<OUString> aSeq { sStyleName };
+ GetImport().SetError(
+ XMLERROR_STYLE_PROP_VALUE | XMLERROR_FLAG_WARNING,
+ aSeq, e.Message, nullptr );
+ }
+ break;
+ }
+ case CTF_SD_OLE_VIS_AREA_IMPORT_LEFT:
+ case CTF_SD_OLE_VIS_AREA_IMPORT_TOP:
+ case CTF_SD_OLE_VIS_AREA_IMPORT_WIDTH:
+ case CTF_SD_OLE_VIS_AREA_IMPORT_HEIGHT:
+ {
+ struct XMLPropertyState& rState = GetProperties()[nIndex];
+ const OUString& rPropertyName = xPropMapper->GetEntryAPIName(rState.mnIndex);
+ try
+ {
+ if( !xInfo.is() )
+ xInfo = rPropSet->getPropertySetInfo();
+ if ( xInfo->hasPropertyByName( rPropertyName ) )
+ {
+ rPropSet->setPropertyValue( rPropertyName, rState.maValue );
+ }
+ }
+ catch ( const css::lang::IllegalArgumentException& e )
+ {
+ Sequence<OUString> aSeq;
+ GetImport().SetError(
+ XMLERROR_STYLE_PROP_VALUE | XMLERROR_FLAG_WARNING,
+ aSeq, e.Message, nullptr );
+ }
+ break;
+ }
+ }
+ }
+
+ if (m_sControlDataStyleName.isEmpty())
+ return;
+
+ // we had a data-style-name attribute
+
+ // set the formatting on the control model of the control shape
+ uno::Reference< drawing::XControlShape > xControlShape(rPropSet, uno::UNO_QUERY);
+ DBG_ASSERT(xControlShape.is(), "XMLShapeStyleContext::FillPropertySet: data style for a non-control shape!");
+ if (xControlShape.is())
+ {
+ uno::Reference< beans::XPropertySet > xControlModel(xControlShape->getControl(), uno::UNO_QUERY);
+ DBG_ASSERT(xControlModel.is(), "XMLShapeStyleContext::FillPropertySet: no control model for the shape!");
+ if (xControlModel.is())
+ {
+ GetImport().GetFormImport()->applyControlNumberStyle(xControlModel, m_sControlDataStyleName);
+ }
+ }
+}
+
+void XMLShapeStyleContext::Finish( bool /*bOverwrite*/ )
+{
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/xmloff/source/draw/animationexport.cxx b/xmloff/source/draw/animationexport.cxx
new file mode 100644
index 0000000000..fee665930b
--- /dev/null
+++ b/xmloff/source/draw/animationexport.cxx
@@ -0,0 +1,1742 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+
+#include <com/sun/star/animations/XAnimateColor.hpp>
+#include <com/sun/star/animations/XCommand.hpp>
+#include <com/sun/star/animations/Timing.hpp>
+#include <com/sun/star/animations/Event.hpp>
+#include <com/sun/star/animations/XAnimateMotion.hpp>
+#include <com/sun/star/animations/XAnimatePhysics.hpp>
+#include <com/sun/star/animations/XAnimateTransform.hpp>
+#include <com/sun/star/animations/XTransitionFilter.hpp>
+#include <com/sun/star/animations/XIterateContainer.hpp>
+#include <com/sun/star/animations/XAudio.hpp>
+#include <com/sun/star/animations/AnimationColorSpace.hpp>
+#include <com/sun/star/animations/AnimationNodeType.hpp>
+#include <com/sun/star/animations/AnimationRestart.hpp>
+#include <com/sun/star/animations/EventTrigger.hpp>
+#include <com/sun/star/animations/AnimationFill.hpp>
+#include <com/sun/star/animations/AnimationEndSync.hpp>
+#include <com/sun/star/animations/AnimationCalcMode.hpp>
+#include <com/sun/star/animations/AnimationAdditiveMode.hpp>
+#include <com/sun/star/animations/AnimationTransformType.hpp>
+#include <com/sun/star/animations/TransitionType.hpp>
+#include <com/sun/star/animations/TransitionSubType.hpp>
+#include <com/sun/star/animations/ValuePair.hpp>
+#include <com/sun/star/container/XEnumerationAccess.hpp>
+#include <com/sun/star/beans/NamedValue.hpp>
+#include <com/sun/star/beans/XPropertySet.hpp>
+#include <com/sun/star/document/XStorageBasedDocument.hpp>
+#include <com/sun/star/embed/ElementModes.hpp>
+#include <com/sun/star/embed/XTransactedObject.hpp>
+#include <com/sun/star/presentation/EffectNodeType.hpp>
+#include <com/sun/star/presentation/EffectPresetClass.hpp>
+#include <com/sun/star/presentation/ParagraphTarget.hpp>
+#include <com/sun/star/presentation/TextAnimationType.hpp>
+#include <com/sun/star/presentation/ShapeAnimationSubType.hpp>
+#include <com/sun/star/presentation/EffectCommands.hpp>
+#include <o3tl/any.hxx>
+#include <sax/tools/converter.hxx>
+#include <sal/log.hxx>
+#include <comphelper/diagnose_ex.hxx>
+
+#include <xmloff/unointerfacetouniqueidentifiermapper.hxx>
+#include "sdpropls.hxx"
+#include <xmlsdtypes.hxx>
+#include <xmloff/xmltoken.hxx>
+#include <xmloff/xmlnamespace.hxx>
+#include <xmloff/xmluconv.hxx>
+#include <xmloff/xmlexp.hxx>
+#include <xmloff/xmlement.hxx>
+#include <xmloff/xmlprhdl.hxx>
+
+#include <animations.hxx>
+#include <xmloff/animationexport.hxx>
+
+using namespace css;
+using namespace ::cppu;
+using namespace ::com::sun::star::animations;
+using namespace ::com::sun::star::presentation;
+using namespace ::com::sun::star::drawing;
+using namespace ::com::sun::star::beans;
+using namespace ::xmloff::token;
+
+using ::com::sun::star::uno::Any;
+using ::com::sun::star::uno::UNO_QUERY;
+using ::com::sun::star::uno::UNO_QUERY_THROW;
+using ::com::sun::star::uno::Reference;
+using ::com::sun::star::uno::Sequence;
+using ::com::sun::star::uno::Exception;
+using ::com::sun::star::uno::RuntimeException;
+using ::com::sun::star::uno::XInterface;
+using ::com::sun::star::beans::NamedValue;
+using ::com::sun::star::container::XEnumerationAccess;
+using ::com::sun::star::container::XEnumeration;
+
+namespace xmloff
+{
+
+const SvXMLEnumMapEntry<sal_Int16> aAnimations_EnumMap_Fill[] =
+{
+ { XML_DEFAULT, AnimationFill::DEFAULT },
+ { XML_REMOVE, AnimationFill::REMOVE },
+ { XML_FREEZE, AnimationFill::FREEZE },
+ { XML_HOLD, AnimationFill::HOLD },
+ { XML_TRANSITION, AnimationFill::TRANSITION },
+ { XML_AUTO, AnimationFill::AUTO },
+ { XML_TOKEN_INVALID, 0 }
+};
+const SvXMLEnumMapEntry<sal_Int16> aAnimations_EnumMap_FillDefault[] =
+{
+ { XML_INHERIT, AnimationFill::INHERIT },
+ { XML_REMOVE, AnimationFill::REMOVE },
+ { XML_FREEZE, AnimationFill::FREEZE },
+ { XML_HOLD, AnimationFill::HOLD },
+ { XML_TRANSITION, AnimationFill::TRANSITION },
+ { XML_AUTO, AnimationFill::AUTO },
+ { XML_TOKEN_INVALID, 0 }
+};
+const SvXMLEnumMapEntry<sal_Int16> aAnimations_EnumMap_Restart[] =
+{
+ { XML_DEFAULT, AnimationRestart::DEFAULT },
+ { XML_ALWAYS, AnimationRestart::ALWAYS },
+ { XML_WHENNOTACTIVE,AnimationRestart::WHEN_NOT_ACTIVE },
+ { XML_NEVER, AnimationRestart::NEVER },
+ { XML_TOKEN_INVALID, 0 }
+};
+const SvXMLEnumMapEntry<sal_Int16> aAnimations_EnumMap_RestartDefault[] =
+{
+ { XML_INHERIT, AnimationRestart::INHERIT },
+ { XML_ALWAYS, AnimationRestart::ALWAYS },
+ { XML_WHENNOTACTIVE,AnimationRestart::WHEN_NOT_ACTIVE },
+ { XML_NEVER, AnimationRestart::NEVER },
+ { XML_TOKEN_INVALID, 0 }
+};
+const SvXMLEnumMapEntry<sal_Int16> aAnimations_EnumMap_Endsync[] =
+{
+ { XML_FIRST, AnimationEndSync::FIRST },
+ { XML_LAST, AnimationEndSync::LAST },
+ { XML_ALL, AnimationEndSync::ALL },
+ { XML_MEDIA, AnimationEndSync::MEDIA },
+ { XML_TOKEN_INVALID, 0 }
+};
+const SvXMLEnumMapEntry<sal_Int16> aAnimations_EnumMap_CalcMode[] =
+{
+ { XML_DISCRETE, AnimationCalcMode::DISCRETE },
+ { XML_LINEAR, AnimationCalcMode::LINEAR },
+ { XML_PACED, AnimationCalcMode::PACED },
+ { XML_SPLINE, AnimationCalcMode::SPLINE },
+ { XML_TOKEN_INVALID, 0 }
+};
+const SvXMLEnumMapEntry<sal_Int16> aAnimations_EnumMap_AdditiveMode[] =
+{
+ { XML_BASE, AnimationAdditiveMode::BASE },
+ { XML_SUM, AnimationAdditiveMode::SUM },
+ { XML_REPLACE, AnimationAdditiveMode::REPLACE },
+ { XML_MULTIPLY, AnimationAdditiveMode::MULTIPLY },
+ { XML_NONE, AnimationAdditiveMode::NONE },
+ { XML_TOKEN_INVALID, 0 }
+};
+const SvXMLEnumMapEntry<sal_Int16> aAnimations_EnumMap_TransformType[] =
+{
+ { XML_TRANSLATE, AnimationTransformType::TRANSLATE },
+ { XML_SCALE, AnimationTransformType::SCALE },
+ { XML_ROTATE, AnimationTransformType::ROTATE },
+ { XML_SKEWX, AnimationTransformType::SKEWX },
+ { XML_SKEWY, AnimationTransformType::SKEWY },
+ { XML_TOKEN_INVALID, 0 }
+};
+const SvXMLEnumMapEntry<sal_Int16> aAnimations_EnumMap_TransitionType[] =
+{
+ { XML_BARWIPE, TransitionType::BARWIPE },
+ { XML_BOXWIPE, TransitionType::BOXWIPE },
+ { XML_FOURBOXWIPE, TransitionType::FOURBOXWIPE },
+ { XML_BARNDOORWIPE, TransitionType::BARNDOORWIPE },
+ { XML_DIAGONALWIPE, TransitionType::DIAGONALWIPE },
+ { XML_BOWTIEWIPE, TransitionType::BOWTIEWIPE },
+ { XML_MISCDIAGONALWIPE, TransitionType::MISCDIAGONALWIPE },
+ { XML_VEEWIPE, TransitionType::VEEWIPE },
+ { XML_BARNVEEWIPE, TransitionType::BARNVEEWIPE },
+ { XML_ZIGZAGWIPE, TransitionType::ZIGZAGWIPE },
+ { XML_BARNZIGZAGWIPE, TransitionType::BARNZIGZAGWIPE },
+ { XML_IRISWIPE, TransitionType::IRISWIPE },
+ { XML_TRIANGLEWIPE, TransitionType::TRIANGLEWIPE },
+ { XML_ARROWHEADWIPE, TransitionType::ARROWHEADWIPE },
+ { XML_PENTAGONWIPE, TransitionType::PENTAGONWIPE },
+ { XML_HEXAGONWIPE, TransitionType::HEXAGONWIPE },
+ { XML_ELLIPSEWIPE, TransitionType::ELLIPSEWIPE },
+ { XML_EYEWIPE, TransitionType::EYEWIPE },
+ { XML_ROUNDRECTWIPE, TransitionType::ROUNDRECTWIPE },
+ { XML_STARWIPE, TransitionType::STARWIPE },
+ { XML_MISCSHAPEWIPE, TransitionType::MISCSHAPEWIPE },
+ { XML_CLOCKWIPE, TransitionType::CLOCKWIPE },
+ { XML_PINWHEELWIPE, TransitionType::PINWHEELWIPE },
+ { XML_SINGLESWEEPWIPE, TransitionType::SINGLESWEEPWIPE },
+ { XML_FANWIPE, TransitionType::FANWIPE },
+ { XML_DOUBLEFANWIPE, TransitionType::DOUBLEFANWIPE },
+ { XML_DOUBLESWEEPWIPE, TransitionType::DOUBLESWEEPWIPE },
+ { XML_SALOONDOORWIPE, TransitionType::SALOONDOORWIPE },
+ { XML_WINDSHIELDWIPE, TransitionType::WINDSHIELDWIPE },
+ { XML_SNAKEWIPE, TransitionType::SNAKEWIPE },
+ { XML_SPIRALWIPE, TransitionType::SPIRALWIPE },
+ { XML_PARALLELSNAKESWIPE,TransitionType::PARALLELSNAKESWIPE },
+ { XML_BOXSNAKESWIPE, TransitionType::BOXSNAKESWIPE },
+ { XML_WATERFALLWIPE, TransitionType::WATERFALLWIPE },
+ { XML_PUSHWIPE, TransitionType::PUSHWIPE },
+ { XML_SLIDEWIPE, TransitionType::SLIDEWIPE },
+ { XML_FADE, TransitionType::FADE },
+ { XML_RANDOMBARWIPE, TransitionType::RANDOMBARWIPE },
+ { XML_CHECKERBOARDWIPE, TransitionType::CHECKERBOARDWIPE },
+ { XML_DISSOLVE, TransitionType::DISSOLVE },
+ { XML_BLINDSWIPE, TransitionType::BLINDSWIPE },
+ { XML_RANDOM, TransitionType::RANDOM },
+ { XML_ZOOM, TransitionType::ZOOM },
+ { XML_TOKEN_INVALID, 0 }
+};
+const SvXMLEnumMapEntry<sal_Int16> aAnimations_EnumMap_TransitionSubType[] =
+{
+ { XML_DEFAULT, TransitionSubType::DEFAULT },
+ { XML_LEFTTORIGHT, TransitionSubType::LEFTTORIGHT },
+ { XML_TOPTOBOTTOM, TransitionSubType::TOPTOBOTTOM },
+ { XML_TOPLEFT, TransitionSubType::TOPLEFT },
+ { XML_TOPRIGHT, TransitionSubType::TOPRIGHT },
+ { XML_BOTTOMRIGHT, TransitionSubType::BOTTOMRIGHT },
+ { XML_BOTTOMLEFT, TransitionSubType::BOTTOMLEFT },
+ { XML_TOPCENTER, TransitionSubType::TOPCENTER },
+ { XML_RIGHTCENTER, TransitionSubType::RIGHTCENTER },
+ { XML_BOTTOMCENTER, TransitionSubType::BOTTOMCENTER },
+ { XML_LEFTCENTER, TransitionSubType::LEFTCENTER },
+ { XML_CORNERSIN, TransitionSubType::CORNERSIN },
+ { XML_CORNERSOUT, TransitionSubType::CORNERSOUT },
+ { XML_VERTICAL, TransitionSubType::VERTICAL },
+ { XML_HORIZONTAL, TransitionSubType::HORIZONTAL },
+ { XML_DIAGONALBOTTOMLEFT, TransitionSubType::DIAGONALBOTTOMLEFT },
+ { XML_DIAGONALTOPLEFT, TransitionSubType::DIAGONALTOPLEFT },
+ { XML_DOUBLEBARNDOOR, TransitionSubType::DOUBLEBARNDOOR },
+ { XML_DOUBLEDIAMOND, TransitionSubType::DOUBLEDIAMOND },
+ { XML_DOWN, TransitionSubType::DOWN },
+ { XML_LEFT, TransitionSubType::LEFT },
+ { XML_UP, TransitionSubType::UP },
+ { XML_RIGHT, TransitionSubType::RIGHT },
+ { XML_RECTANGLE, TransitionSubType::RECTANGLE },
+ { XML_DIAMOND, TransitionSubType::DIAMOND },
+ { XML_CIRCLE, TransitionSubType::CIRCLE },
+ { XML_FOURPOINT, TransitionSubType::FOURPOINT },
+ { XML_FIVEPOINT, TransitionSubType::FIVEPOINT },
+ { XML_SIXPOINT, TransitionSubType::SIXPOINT },
+ { XML_HEART, TransitionSubType::HEART },
+ { XML_KEYHOLE, TransitionSubType::KEYHOLE },
+ { XML_CLOCKWISETWELVE, TransitionSubType::CLOCKWISETWELVE },
+ { XML_CLOCKWISETHREE, TransitionSubType::CLOCKWISETHREE },
+ { XML_CLOCKWISESIX, TransitionSubType::CLOCKWISESIX },
+ { XML_CLOCKWISENINE, TransitionSubType::CLOCKWISENINE },
+ { XML_TWOBLADEVERTICAL, TransitionSubType::TWOBLADEVERTICAL },
+ { XML_TWOBLADEHORIZONTAL, TransitionSubType::TWOBLADEHORIZONTAL },
+ { XML_FOURBLADE, TransitionSubType::FOURBLADE },
+ { XML_CLOCKWISETOP, TransitionSubType::CLOCKWISETOP },
+ { XML_CLOCKWISERIGHT, TransitionSubType::CLOCKWISERIGHT },
+ { XML_CLOCKWISEBOTTOM, TransitionSubType::CLOCKWISEBOTTOM },
+ { XML_CLOCKWISELEFT, TransitionSubType::CLOCKWISELEFT },
+ { XML_CLOCKWISETOPLEFT, TransitionSubType::CLOCKWISETOPLEFT },
+ { XML_COUNTERCLOCKWISEBOTTOMLEFT,TransitionSubType::COUNTERCLOCKWISEBOTTOMLEFT },
+ { XML_CLOCKWISEBOTTOMRIGHT, TransitionSubType::CLOCKWISEBOTTOMRIGHT },
+ { XML_COUNTERCLOCKWISETOPRIGHT,TransitionSubType::COUNTERCLOCKWISETOPRIGHT },
+ { XML_CENTERTOP, TransitionSubType::CENTERTOP },
+ { XML_CENTERRIGHT, TransitionSubType::CENTERRIGHT },
+ { XML_TOP, TransitionSubType::TOP },
+ { XML_BOTTOM, TransitionSubType::BOTTOM },
+ { XML_FANOUTVERTICAL, TransitionSubType::FANOUTVERTICAL },
+ { XML_FANOUTHORIZONTAL, TransitionSubType::FANOUTHORIZONTAL },
+ { XML_FANINVERTICAL, TransitionSubType::FANINVERTICAL },
+ { XML_FANINHORIZONTAL, TransitionSubType::FANINHORIZONTAL },
+ { XML_PARALLELVERTICAL, TransitionSubType::PARALLELVERTICAL },
+ { XML_PARALLELDIAGONAL, TransitionSubType::PARALLELDIAGONAL },
+ { XML_OPPOSITEVERTICAL, TransitionSubType::OPPOSITEVERTICAL },
+ { XML_OPPOSITEHORIZONTAL, TransitionSubType::OPPOSITEHORIZONTAL },
+ { XML_PARALLELDIAGONALTOPLEFT,TransitionSubType::PARALLELDIAGONALTOPLEFT },
+ { XML_PARALLELDIAGONALBOTTOMLEFT,TransitionSubType::PARALLELDIAGONALBOTTOMLEFT },
+ { XML_TOPLEFTHORIZONTAL, TransitionSubType::TOPLEFTHORIZONTAL },
+ { XML_TOPLEFTDIAGONAL, TransitionSubType::TOPLEFTDIAGONAL },
+ { XML_TOPRIGHTDIAGONAL, TransitionSubType::TOPRIGHTDIAGONAL },
+ { XML_BOTTOMRIGHTDIAGONAL, TransitionSubType::BOTTOMRIGHTDIAGONAL },
+ { XML_BOTTOMLEFTDIAGONAL, TransitionSubType::BOTTOMLEFTDIAGONAL },
+ { XML_TOPLEFTCLOCKWISE, TransitionSubType::TOPLEFTCLOCKWISE },
+ { XML_TOPRIGHTCLOCKWISE, TransitionSubType::TOPRIGHTCLOCKWISE },
+ { XML_BOTTOMRIGHTCLOCKWISE, TransitionSubType::BOTTOMRIGHTCLOCKWISE },
+ { XML_BOTTOMLEFTCLOCKWISE, TransitionSubType::BOTTOMLEFTCLOCKWISE },
+ { XML_TOPLEFTCOUNTERCLOCKWISE,TransitionSubType::TOPLEFTCOUNTERCLOCKWISE },
+ { XML_TOPRIGHTCOUNTERCLOCKWISE,TransitionSubType::TOPRIGHTCOUNTERCLOCKWISE },
+ { XML_BOTTOMRIGHTCOUNTERCLOCKWISE,TransitionSubType::BOTTOMRIGHTCOUNTERCLOCKWISE },
+ { XML_BOTTOMLEFTCOUNTERCLOCKWISE,TransitionSubType::BOTTOMLEFTCOUNTERCLOCKWISE },
+ { XML_VERTICALTOPSAME, TransitionSubType::VERTICALTOPSAME },
+ { XML_VERTICALBOTTOMSAME, TransitionSubType::VERTICALBOTTOMSAME },
+ { XML_VERTICALTOPLEFTOPPOSITE,TransitionSubType::VERTICALTOPLEFTOPPOSITE },
+ { XML_VERTICALBOTTOMLEFTOPPOSITE,TransitionSubType::VERTICALBOTTOMLEFTOPPOSITE },
+ { XML_HORIZONTALLEFTSAME, TransitionSubType::HORIZONTALLEFTSAME },
+ { XML_HORIZONTALRIGHTSAME, TransitionSubType::HORIZONTALRIGHTSAME },
+ { XML_HORIZONTALTOPLEFTOPPOSITE,TransitionSubType::HORIZONTALTOPLEFTOPPOSITE },
+ { XML_HORIZONTALTOPRIGHTOPPOSITE,TransitionSubType::HORIZONTALTOPRIGHTOPPOSITE },
+ { XML_DIAGONALBOTTOMLEFTOPPOSITE,TransitionSubType::DIAGONALBOTTOMLEFTOPPOSITE },
+ { XML_DIAGONALTOPLEFTOPPOSITE,TransitionSubType::DIAGONALTOPLEFTOPPOSITE },
+ { XML_TWOBOXTOP, TransitionSubType::TWOBOXTOP },
+ { XML_TWOBOXBOTTOM, TransitionSubType::TWOBOXBOTTOM },
+ { XML_TWOBOXLEFT, TransitionSubType::TWOBOXLEFT },
+ { XML_TWOBOXRIGHT, TransitionSubType::TWOBOXRIGHT },
+ { XML_FOURBOXVERTICAL, TransitionSubType::FOURBOXVERTICAL },
+ { XML_FOURBOXHORIZONTAL, TransitionSubType::FOURBOXHORIZONTAL },
+ { XML_VERTICALLEFT, TransitionSubType::VERTICALLEFT },
+ { XML_VERTICALRIGHT, TransitionSubType::VERTICALRIGHT },
+ { XML_HORIZONTALLEFT, TransitionSubType::HORIZONTALLEFT },
+ { XML_HORIZONTALRIGHT, TransitionSubType::HORIZONTALRIGHT },
+ { XML_FROMLEFT, TransitionSubType::FROMLEFT },
+ { XML_FROMTOP, TransitionSubType::FROMTOP },
+ { XML_FROMRIGHT, TransitionSubType::FROMRIGHT },
+ { XML_FROMBOTTOM, TransitionSubType::FROMBOTTOM },
+ { XML_CROSSFADE, TransitionSubType::CROSSFADE },
+ { XML_FADETOCOLOR, TransitionSubType::FADETOCOLOR },
+ { XML_FADEFROMCOLOR, TransitionSubType::FADEFROMCOLOR },
+ { XML_FADEOVERCOLOR, TransitionSubType::FADEOVERCOLOR },
+ { XML_THREEBLADE, TransitionSubType::THREEBLADE },
+ { XML_EIGHTBLADE, TransitionSubType::EIGHTBLADE },
+ { XML_ONEBLADE, TransitionSubType::ONEBLADE },
+ { XML_ACROSS, TransitionSubType::ACROSS },
+ { XML_TOPLEFTVERTICAL, TransitionSubType::TOPLEFTVERTICAL },
+ { XML_COMBHORIZONTAL, TransitionSubType::COMBHORIZONTAL },
+ { XML_COMBVERTICAL, TransitionSubType::COMBVERTICAL },
+ { XML_IN, TransitionSubType::IN },
+ { XML_OUT, TransitionSubType::OUT },
+ { XML_ROTATEIN, TransitionSubType::ROTATEIN },
+ { XML_ROTATEOUT, TransitionSubType::ROTATEOUT },
+ { XML_FROMTOPLEFT, TransitionSubType::FROMTOPLEFT },
+ { XML_FROMTOPRIGHT, TransitionSubType::FROMTOPRIGHT },
+ { XML_FROMBOTTOMLEFT, TransitionSubType::FROMBOTTOMLEFT },
+ { XML_FROMBOTTOMRIGHT, TransitionSubType::FROMBOTTOMRIGHT },
+
+ { XML_TOKEN_INVALID, 0 }
+};
+const SvXMLEnumMapEntry<sal_Int16> aAnimations_EnumMap_EventTrigger[] =
+{
+ { XML_ONBEGIN, EventTrigger::ON_BEGIN },
+ { XML_ONEND, EventTrigger::ON_END },
+ { XML_BEGIN, EventTrigger::BEGIN_EVENT },
+ { XML_END, EventTrigger::END_EVENT },
+ { XML_CLICK, EventTrigger::ON_CLICK },
+ { XML_DOUBLECLICK, EventTrigger::ON_DBL_CLICK },
+ { XML_MOUSEOVER, EventTrigger::ON_MOUSE_ENTER },
+ { XML_MOUSEOUT, EventTrigger::ON_MOUSE_LEAVE },
+ { XML_NEXT, EventTrigger::ON_NEXT },
+ { XML_PREVIOUS, EventTrigger::ON_PREV },
+ { XML_STOP_AUDIO, EventTrigger::ON_STOP_AUDIO },
+ { XML_REPEAT, EventTrigger::REPEAT },
+ { XML_TOKEN_INVALID, 0 }
+};
+const SvXMLEnumMapEntry<sal_Int16> aAnimations_EnumMap_EffectPresetClass[] =
+{
+ { XML_CUSTOM, EffectPresetClass::CUSTOM },
+ { XML_ENTRANCE, EffectPresetClass::ENTRANCE },
+ { XML_EXIT, EffectPresetClass::EXIT },
+ { XML_EMPHASIS, EffectPresetClass::EMPHASIS },
+ { XML_MOTION_PATH, EffectPresetClass::MOTIONPATH },
+ { XML_OLE_ACTION, EffectPresetClass::OLEACTION },
+ { XML_MEDIA_CALL, EffectPresetClass::MEDIACALL },
+ { XML_TOKEN_INVALID, 0 }
+};
+const SvXMLEnumMapEntry<sal_Int16> aAnimations_EnumMap_EffectNodeType[] =
+{
+ { XML_DEFAULT, EffectNodeType::DEFAULT },
+ { XML_ON_CLICK, EffectNodeType::ON_CLICK },
+ { XML_WITH_PREVIOUS, EffectNodeType::WITH_PREVIOUS },
+ { XML_AFTER_PREVIOUS, EffectNodeType::AFTER_PREVIOUS },
+ { XML_MAIN_SEQUENCE, EffectNodeType::MAIN_SEQUENCE },
+ { XML_TIMING_ROOT, EffectNodeType::TIMING_ROOT },
+ { XML_INTERACTIVE_SEQUENCE, EffectNodeType::INTERACTIVE_SEQUENCE },
+ { XML_TOKEN_INVALID, 0 }
+};
+const SvXMLEnumMapEntry<sal_Int16> aAnimations_EnumMap_SubItem[] =
+{
+ { XML_WHOLE, ShapeAnimationSubType::AS_WHOLE },
+ { XML_BACKGROUND, ShapeAnimationSubType::ONLY_BACKGROUND },
+ { XML_TEXT, ShapeAnimationSubType::ONLY_TEXT },
+ { XML_TOKEN_INVALID, 0 }
+};
+const SvXMLEnumMapEntry<sal_Int16> aAnimations_EnumMap_IterateType[] =
+{
+ { XML_BY_PARAGRAPH, TextAnimationType::BY_PARAGRAPH },
+ { XML_BY_WORD, TextAnimationType::BY_WORD },
+ { XML_BY_LETTER, TextAnimationType::BY_LETTER },
+ { XML_TOKEN_INVALID, 0 }
+};
+const SvXMLEnumMapEntry<sal_Int16> aAnimations_EnumMap_Command[] =
+{
+ { XML_CUSTOM, EffectCommands::CUSTOM },
+ { XML_VERB, EffectCommands::VERB },
+ { XML_PLAY, EffectCommands::PLAY },
+ { XML_TOGGLE_PAUSE, EffectCommands::TOGGLEPAUSE },
+ { XML_STOP, EffectCommands::STOP },
+ { XML_STOP_AUDIO, EffectCommands::STOPAUDIO },
+ { XML_TOKEN_INVALID, 0 }
+};
+
+const struct ImplAttributeNameConversion* getAnimationAttributeNamesConversionList()
+{
+ static const struct ImplAttributeNameConversion gImplConversionList[] =
+ {
+ { XML_X, "X" },
+ { XML_Y, "Y" },
+ { XML_WIDTH, "Width" },
+ { XML_HEIGHT, "Height" },
+ { XML_ROTATE, "Rotate" },
+ { XML_SKEWX, "SkewX" },
+ { XML_FILL_COLOR, "FillColor" },
+ { XML_FILL, "FillStyle" },
+ { XML_STROKE_COLOR, "LineColor" },
+ { XML_STROKE, "LineStyle" },
+ { XML_COLOR, "CharColor" },
+ { XML_TEXT_ROTATION_ANGLE, "CharRotation" },
+ { XML_FONT_WEIGHT, "CharWeight" },
+ { XML_TEXT_UNDERLINE, "CharUnderline" },
+ { XML_FONT_FAMILY, "CharFontName" },
+ { XML_FONT_SIZE, "CharHeight" },
+ { XML_FONT_STYLE, "CharPosture" },
+ { XML_VISIBILITY, "Visibility" },
+ { XML_OPACITY, "Opacity" },
+ { XML_DIM, "DimColor" },
+ { XML_TOKEN_INVALID, nullptr }
+ };
+
+ return gImplConversionList;
+}
+
+
+class AnimationsExporterImpl
+{
+public:
+ AnimationsExporterImpl( SvXMLExport& rExport, const Reference< XPropertySet >& xPageProps );
+
+ void prepareNode( const Reference< XAnimationNode >& xNode );
+ void exportNode( const Reference< XAnimationNode >& xNode );
+
+ void exportContainer( const Reference< XTimeContainer >& xNode, sal_Int16 nContainerNodeType );
+ void exportAnimate( const Reference< XAnimate >& xNode );
+ void exportAudio( const Reference< XAudio >& xAudio );
+ void exportCommand( const Reference< XCommand >& xCommand );
+
+ static Reference< XInterface > getParagraphTarget( const ParagraphTarget& pTarget );
+
+ static void convertPath( OUStringBuffer& sTmp, const Any& rPath );
+ void convertValue( XMLTokenEnum eAttributeName, OUStringBuffer& sTmp, const Any& rValue ) const;
+ void convertTiming( OUStringBuffer& sTmp, const Any& rTiming ) const;
+ void convertTarget( OUStringBuffer& sTmp, const Any& rTarget ) const;
+
+ void prepareValue( const Any& rValue );
+
+ void exportTransitionNode();
+ void prepareTransitionNode();
+
+ bool mbHasTransition;
+private:
+ rtl::Reference<SvXMLExport> mxExport;
+ Reference< XPropertySet > mxPageProps;
+ rtl::Reference<XMLSdPropHdlFactory> mxSdPropHdlFactory;
+};
+
+AnimationsExporterImpl::AnimationsExporterImpl( SvXMLExport& rExport, const Reference< XPropertySet >& xPageProps )
+: mbHasTransition(false)
+, mxExport( &rExport )
+, mxPageProps( xPageProps )
+, mxSdPropHdlFactory(new XMLSdPropHdlFactory( rExport.GetModel(), rExport ))
+{
+}
+
+
+/** split a uri hierarchy into first segment and rest */
+static bool splitPath(OUString const & i_rPath,
+ OUString & o_rDir, OUString& o_rRest)
+{
+ const sal_Int32 idx(i_rPath.indexOf(u'/'));
+ if (idx < 0 || idx >= i_rPath.getLength()) {
+ o_rDir = OUString();
+ o_rRest = i_rPath;
+ return true;
+ } else if (idx == 0 || idx == i_rPath.getLength() - 1) {
+ // input must not start or end with '/'
+ return false;
+ } else {
+ o_rDir = i_rPath.copy(0, idx);
+ o_rRest = i_rPath.copy(idx+1);
+ return true;
+ }
+}
+
+static void lcl_CopyStream(
+ uno::Reference<embed::XStorage> const& xSource,
+ uno::Reference<embed::XStorage> const& xTarget,
+ OUString const& rPath)
+{
+ OUString dir;
+ OUString rest;
+ if (!splitPath(rPath, dir, rest))
+ throw uno::RuntimeException();
+
+ if (dir.getLength() == 0)
+ xSource->copyElementTo(rPath, xTarget, rPath);
+ else
+ {
+ uno::Reference<embed::XStorage> const xSubSource(
+ xSource->openStorageElement(dir, embed::ElementModes::READ));
+ uno::Reference<embed::XStorage> const xSubTarget(
+ xTarget->openStorageElement(dir, embed::ElementModes::WRITE));
+ lcl_CopyStream(xSubSource, xSubTarget, rest);
+ }
+ uno::Reference<embed::XTransactedObject> const xTransaction(xTarget, uno::UNO_QUERY);
+ if (xTransaction.is())
+ xTransaction->commit();
+}
+
+char const s_PkgScheme[] = "vnd.sun.star.Package:";
+
+static OUString lcl_StoreMediaAndGetURL(SvXMLExport & rExport, OUString const& rURL)
+{
+ OUString urlPath;
+ if (rURL.startsWithIgnoreAsciiCase(s_PkgScheme, &urlPath))
+ {
+ try // video is embedded
+ {
+ // copy the media stream from document storage to target storage
+ // (not sure if this is the best way to store these?)
+ uno::Reference<document::XStorageBasedDocument> const xSBD(
+ rExport.GetModel(), uno::UNO_QUERY_THROW);
+ uno::Reference<embed::XStorage> const xSource(
+ xSBD->getDocumentStorage(), uno::UNO_SET_THROW);
+ uno::Reference<embed::XStorage> const xTarget(
+ rExport.GetTargetStorage(), uno::UNO_SET_THROW);
+
+ urlPath = rURL.copy(SAL_N_ELEMENTS(s_PkgScheme)-1);
+
+ lcl_CopyStream(xSource, xTarget, urlPath);
+
+ return urlPath;
+ }
+ catch (uno::Exception const&)
+ {
+ TOOLS_INFO_EXCEPTION("xmloff", "exception while storing embedded media");
+ }
+ return OUString();
+ }
+ else
+ {
+ return rExport.GetRelativeReference(rURL); // linked
+ }
+}
+
+void AnimationsExporterImpl::exportTransitionNode()
+{
+ if( !(mbHasTransition && mxPageProps.is()) )
+ return;
+
+ sal_Int16 nTransition = 0;
+ mxPageProps->getPropertyValue("TransitionType") >>= nTransition;
+
+ Any aSound( mxPageProps->getPropertyValue("Sound") );
+ OUString sSoundURL;
+ aSound >>= sSoundURL;
+ bool bStopSound = false;
+ if( !(aSound >>= bStopSound) )
+ bStopSound = false;
+
+
+ OUStringBuffer sTmp;
+ if( !((nTransition != 0) || !sSoundURL.isEmpty() || bStopSound) )
+ return;
+
+ Reference< XInterface > xSource( mxPageProps );
+ Event aEvent;
+ aEvent.Source <<= xSource;
+ aEvent.Trigger = EventTrigger::BEGIN_EVENT;
+ aEvent.Repeat = 0;
+
+ convertTiming( sTmp, Any( aEvent ) );
+ mxExport->AddAttribute( XML_NAMESPACE_SMIL, XML_BEGIN, sTmp.makeStringAndClear() );
+
+ SvXMLElementExport aElement( *mxExport, XML_NAMESPACE_ANIMATION, XML_PAR, true, true );
+
+ if( nTransition != 0 )
+ {
+ sal_Int16 nSubtype = 0;
+ bool bDirection = false;
+ sal_Int32 nFadeColor = 0;
+ double fDuration = 0.0;
+ mxPageProps->getPropertyValue("TransitionSubtype") >>= nSubtype;
+ mxPageProps->getPropertyValue("TransitionDirection") >>= bDirection;
+ mxPageProps->getPropertyValue("TransitionFadeColor") >>= nFadeColor;
+ mxPageProps->getPropertyValue("TransitionDuration") >>= fDuration;
+
+ ::sax::Converter::convertDouble( sTmp, fDuration );
+ sTmp.append( 's');
+ mxExport->AddAttribute( XML_NAMESPACE_SMIL, XML_DUR, sTmp.makeStringAndClear() );
+
+ SvXMLUnitConverter::convertEnum( sTmp, nTransition, aAnimations_EnumMap_TransitionType );
+ mxExport->AddAttribute( XML_NAMESPACE_SMIL, XML_TYPE, sTmp.makeStringAndClear() );
+
+ if( nSubtype != TransitionSubType::DEFAULT )
+ {
+ SvXMLUnitConverter::convertEnum( sTmp, nSubtype, aAnimations_EnumMap_TransitionSubType );
+ mxExport->AddAttribute( XML_NAMESPACE_SMIL, XML_SUBTYPE, sTmp.makeStringAndClear() );
+ }
+
+ if( !bDirection )
+ mxExport->AddAttribute( XML_NAMESPACE_SMIL, XML_DIRECTION, XML_REVERSE );
+
+ if( (nTransition == TransitionType::FADE)
+ && ((nSubtype == TransitionSubType::FADETOCOLOR) || (nSubtype == TransitionSubType::FADEFROMCOLOR)
+ || (nSubtype == TransitionSubType::FADEOVERCOLOR)))
+ {
+ ::sax::Converter::convertColor( sTmp, nFadeColor );
+ mxExport->AddAttribute( XML_NAMESPACE_SMIL, XML_FADECOLOR, sTmp.makeStringAndClear() );
+ }
+ SvXMLElementExport aElement2( *mxExport, XML_NAMESPACE_ANIMATION, XML_TRANSITIONFILTER, true, true );
+ }
+
+ if( bStopSound )
+ {
+ mxExport->AddAttribute( XML_NAMESPACE_ANIMATION, XML_COMMAND, XML_STOP_AUDIO );
+ SvXMLElementExport aElement2( *mxExport, XML_NAMESPACE_ANIMATION, XML_COMMAND, true, true );
+ }
+ else if( !sSoundURL.isEmpty())
+ {
+ sSoundURL = lcl_StoreMediaAndGetURL(*mxExport, sSoundURL);
+ mxExport->AddAttribute( XML_NAMESPACE_XLINK, XML_HREF, sSoundURL );
+
+ bool bLoopSound = false;
+ mxPageProps->getPropertyValue("LoopSound") >>= bLoopSound;
+
+ if( bLoopSound )
+ mxExport->AddAttribute( XML_NAMESPACE_SMIL, XML_REPEATCOUNT, XML_INDEFINITE );
+ SvXMLElementExport aElement2( *mxExport, XML_NAMESPACE_ANIMATION, XML_AUDIO, true, true );
+ }
+}
+
+void AnimationsExporterImpl::prepareTransitionNode()
+{
+ if( !mxPageProps.is() )
+ return;
+
+ try
+ {
+ sal_Int16 nTransition = 0;
+ mxPageProps->getPropertyValue("TransitionType") >>= nTransition;
+
+ bool bStopSound = false;
+ OUString sSoundURL;
+
+ if( nTransition == 0 )
+ {
+ Any aSound( mxPageProps->getPropertyValue("Sound") );
+ aSound >>= sSoundURL;
+
+ if( !(aSound >>= bStopSound) )
+ bStopSound = false;
+ }
+
+ if( (nTransition != 0) || !sSoundURL.isEmpty() || bStopSound )
+ {
+ mbHasTransition = true;
+ Reference< XInterface > xInt( mxPageProps );
+ mxExport->getInterfaceToIdentifierMapper().registerReference( xInt );
+ }
+ }
+ catch (const Exception&)
+ {
+ TOOLS_WARN_EXCEPTION("xmloff.draw", "");
+ }
+}
+
+void AnimationsExporterImpl::prepareNode( const Reference< XAnimationNode >& xNode )
+{
+ try
+ {
+ prepareValue( xNode->getBegin() );
+ prepareValue( xNode->getEnd() );
+
+ sal_Int16 nNodeType = xNode->getType();
+ switch( nNodeType )
+ {
+ case AnimationNodeType::ITERATE:
+ {
+ Reference< XIterateContainer > xIter( xNode, UNO_QUERY_THROW );
+ prepareValue( xIter->getTarget() );
+ [[fallthrough]];
+ }
+ case AnimationNodeType::PAR:
+ case AnimationNodeType::SEQ:
+ {
+ Reference< XEnumerationAccess > xEnumerationAccess( xNode, UNO_QUERY_THROW );
+ Reference< XEnumeration > xEnumeration( xEnumerationAccess->createEnumeration(), css::uno::UNO_SET_THROW );
+ while( xEnumeration->hasMoreElements() )
+ {
+ Reference< XAnimationNode > xChildNode( xEnumeration->nextElement(), UNO_QUERY_THROW );
+ prepareNode( xChildNode );
+ }
+ }
+ break;
+
+ case AnimationNodeType::ANIMATE:
+ case AnimationNodeType::SET:
+ case AnimationNodeType::ANIMATEMOTION:
+ case AnimationNodeType::ANIMATEPHYSICS:
+ case AnimationNodeType::ANIMATECOLOR:
+ case AnimationNodeType::ANIMATETRANSFORM:
+ case AnimationNodeType::TRANSITIONFILTER:
+ {
+ Reference< XAnimate > xAnimate( xNode, UNO_QUERY_THROW );
+ prepareValue( xAnimate->getTarget() );
+ }
+ break;
+
+ case AnimationNodeType::COMMAND:
+ {
+ Reference< XCommand > xCommand( xNode, UNO_QUERY_THROW );
+ prepareValue( xCommand->getTarget() );
+ }
+ break;
+
+ case AnimationNodeType::AUDIO:
+ {
+ Reference< XAudio > xAudio( xNode, UNO_QUERY_THROW );
+ prepareValue( xAudio->getSource() );
+ }
+ break;
+ }
+
+ const Sequence< NamedValue > aUserData( xNode->getUserData() );
+ for( const auto& rValue : aUserData )
+ {
+ if( IsXMLToken( rValue.Name, XML_MASTER_ELEMENT ) )
+ {
+ Reference< XInterface > xMaster;
+ rValue.Value >>= xMaster;
+ if( xMaster.is() )
+ mxExport->getInterfaceToIdentifierMapper().registerReference( xMaster );
+ }
+ }
+ }
+ catch (const Exception&)
+ {
+ TOOLS_WARN_EXCEPTION("xmloff.draw", "");
+ }
+}
+
+void AnimationsExporterImpl::exportNode( const Reference< XAnimationNode >& xNode )
+{
+ try
+ {
+ OUStringBuffer sTmp;
+
+ const OUString& rExportIdentifier = mxExport->getInterfaceToIdentifierMapper().getIdentifier( xNode );
+ if( !rExportIdentifier.isEmpty() )
+ {
+ mxExport->AddAttributeIdLegacy(
+ XML_NAMESPACE_ANIMATION, rExportIdentifier);
+ }
+
+ Any aTemp( xNode->getBegin() );
+ if( aTemp.hasValue() )
+ {
+ convertTiming( sTmp, aTemp );
+ mxExport->AddAttribute( XML_NAMESPACE_SMIL, XML_BEGIN, sTmp.makeStringAndClear() );
+ }
+
+ double fTemp = 0;
+ sal_Int16 nTemp;
+
+ aTemp = xNode->getDuration();
+ if( aTemp.hasValue() )
+ {
+ if( aTemp >>= fTemp )
+ {
+ ::sax::Converter::convertDouble( sTmp, fTemp );
+ sTmp.append( 's');
+ mxExport->AddAttribute( XML_NAMESPACE_SMIL, XML_DUR, sTmp.makeStringAndClear() );
+ }
+ else
+ {
+ Timing eTiming;
+ if( aTemp >>= eTiming )
+ mxExport->AddAttribute( XML_NAMESPACE_SMIL, XML_DUR, eTiming == Timing_INDEFINITE ? XML_INDEFINITE : XML_MEDIA );
+ }
+ }
+
+ aTemp = xNode->getEnd();
+ if( aTemp.hasValue() )
+ {
+ convertTiming( sTmp, aTemp );
+ mxExport->AddAttribute( XML_NAMESPACE_SMIL, XML_END, sTmp.makeStringAndClear() );
+ }
+
+ nTemp = xNode->getFill();
+ if( nTemp != AnimationFill::DEFAULT )
+ {
+ SvXMLUnitConverter::convertEnum( sTmp, nTemp, aAnimations_EnumMap_Fill );
+ mxExport->AddAttribute( XML_NAMESPACE_SMIL, XML_FILL, sTmp.makeStringAndClear() );
+ }
+
+ nTemp = xNode->getFillDefault();
+ if( nTemp != AnimationFill::INHERIT )
+ {
+ SvXMLUnitConverter::convertEnum( sTmp, nTemp, aAnimations_EnumMap_FillDefault );
+ mxExport->AddAttribute( XML_NAMESPACE_SMIL, XML_FILLDEFAULT, sTmp.makeStringAndClear() );
+ }
+
+ nTemp = xNode->getRestart();
+ if( nTemp != AnimationRestart::DEFAULT )
+ {
+ SvXMLUnitConverter::convertEnum( sTmp, nTemp, aAnimations_EnumMap_Restart );
+ mxExport->AddAttribute( XML_NAMESPACE_SMIL, XML_RESTART, sTmp.makeStringAndClear() );
+ }
+
+ nTemp = xNode->getRestartDefault();
+ if( nTemp != AnimationRestart::INHERIT )
+ {
+ SvXMLUnitConverter::convertEnum( sTmp, nTemp, aAnimations_EnumMap_RestartDefault );
+ mxExport->AddAttribute( XML_NAMESPACE_SMIL, XML_RESTARTDEFAULT, sTmp.makeStringAndClear() );
+ }
+
+ fTemp = xNode->getAcceleration();
+ if( fTemp != 0.0 )
+ {
+ ::sax::Converter::convertDouble( sTmp, fTemp );
+ mxExport->AddAttribute( XML_NAMESPACE_SMIL, XML_ACCELERATE, sTmp.makeStringAndClear() );
+ }
+
+ fTemp = xNode->getDecelerate();
+ if( fTemp != 0.0 )
+ {
+ ::sax::Converter::convertDouble( sTmp, fTemp );
+ mxExport->AddAttribute( XML_NAMESPACE_SMIL, XML_DECELERATE, sTmp.makeStringAndClear() );
+ }
+
+ bool bTemp = xNode->getAutoReverse();
+ if( bTemp )
+ {
+ ::sax::Converter::convertBool( sTmp, bTemp );
+ mxExport->AddAttribute( XML_NAMESPACE_SMIL, XML_AUTOREVERSE, sTmp.makeStringAndClear() );
+ }
+
+ aTemp = xNode->getRepeatCount();
+ if( aTemp.hasValue() )
+ {
+ Timing eTiming;
+ if( (aTemp >>= eTiming ) && (eTiming == Timing_INDEFINITE ) )
+ mxExport->AddAttribute( XML_NAMESPACE_SMIL, XML_REPEATCOUNT, XML_INDEFINITE );
+ else if( aTemp >>= fTemp )
+ {
+ ::sax::Converter::convertDouble( sTmp, fTemp );
+ mxExport->AddAttribute( XML_NAMESPACE_SMIL, XML_REPEATCOUNT, sTmp.makeStringAndClear() );
+ }
+ }
+
+ aTemp = xNode->getRepeatDuration();
+ if( aTemp.hasValue() )
+ {
+ Timing eTiming;
+ if( ( aTemp >>= eTiming ) && (eTiming == Timing_INDEFINITE) )
+ {
+ mxExport->AddAttribute( XML_NAMESPACE_SMIL, XML_REPEATDUR, XML_INDEFINITE );
+ }
+ else if( aTemp >>= fTemp )
+ {
+ ::sax::Converter::convertDouble( sTmp, fTemp );
+ mxExport->AddAttribute( XML_NAMESPACE_SMIL, XML_REPEATDUR, sTmp.makeStringAndClear() );
+ }
+ }
+
+ aTemp = xNode->getEndSync();
+ if( aTemp.hasValue() && (aTemp >>= nTemp) )
+ {
+ SvXMLUnitConverter::convertEnum( sTmp, nTemp, aAnimations_EnumMap_Endsync );
+ mxExport->AddAttribute( XML_NAMESPACE_SMIL, XML_ENDSYNC, sTmp.makeStringAndClear() );
+ }
+
+ sal_Int16 nContainerNodeType = EffectNodeType::DEFAULT;
+ OUString aPresetId;
+ const Sequence< NamedValue > aUserData( xNode->getUserData() );
+ for( const auto& rValue : aUserData )
+ {
+ if( IsXMLToken( rValue.Name, XML_NODE_TYPE ) )
+ {
+ if( (rValue.Value >>= nContainerNodeType) && (nContainerNodeType != EffectNodeType::DEFAULT) )
+ {
+ SvXMLUnitConverter::convertEnum( sTmp, nContainerNodeType, aAnimations_EnumMap_EffectNodeType );
+ mxExport->AddAttribute( XML_NAMESPACE_PRESENTATION, XML_NODE_TYPE, sTmp.makeStringAndClear() );
+ }
+ }
+ else if( IsXMLToken( rValue.Name, XML_PRESET_ID ) )
+ {
+ if( rValue.Value >>= aPresetId )
+ {
+ mxExport->AddAttribute( XML_NAMESPACE_PRESENTATION, XML_PRESET_ID, aPresetId );
+ }
+ }
+ else if( IsXMLToken( rValue.Name, XML_PRESET_SUB_TYPE ) )
+ {
+ OUString aPresetSubType;
+ if( rValue.Value >>= aPresetSubType )
+ {
+ mxExport->AddAttribute( XML_NAMESPACE_PRESENTATION, XML_PRESET_SUB_TYPE, aPresetSubType );
+ }
+ }
+ else if( IsXMLToken( rValue.Name, XML_PRESET_CLASS ) )
+ {
+ sal_Int16 nEffectPresetClass = sal_uInt16();
+ if( rValue.Value >>= nEffectPresetClass )
+ {
+ SvXMLUnitConverter::convertEnum( sTmp, nEffectPresetClass, aAnimations_EnumMap_EffectPresetClass );
+ mxExport->AddAttribute( XML_NAMESPACE_PRESENTATION, XML_PRESET_CLASS, sTmp.makeStringAndClear() );
+ }
+ }
+ else if( IsXMLToken( rValue.Name, XML_MASTER_ELEMENT ) )
+ {
+ Reference< XInterface > xMaster;
+ rValue.Value >>= xMaster;
+ if( xMaster.is() )
+ {
+ const OUString& rIdentifier = mxExport->getInterfaceToIdentifierMapper().getIdentifier(xMaster);
+ if( !rIdentifier.isEmpty() )
+ mxExport->AddAttribute( XML_NAMESPACE_PRESENTATION, XML_MASTER_ELEMENT, rIdentifier );
+ }
+ }
+ else if( IsXMLToken( rValue.Name, XML_GROUP_ID ) )
+ {
+ sal_Int32 nGroupId = 0;
+ if( rValue.Value >>= nGroupId )
+ mxExport->AddAttribute( XML_NAMESPACE_PRESENTATION, XML_GROUP_ID, OUString::number( nGroupId ) );
+ }
+ else
+ {
+ OUString aTmp;
+ if( rValue.Value >>= aTmp )
+ mxExport->AddAttribute( XML_NAMESPACE_PRESENTATION, rValue.Name, aTmp );
+ }
+ }
+
+ nTemp = xNode->getType();
+ switch( nTemp )
+ {
+ case AnimationNodeType::PAR:
+ case AnimationNodeType::SEQ:
+ case AnimationNodeType::ITERATE:
+ {
+ Reference< XTimeContainer > xContainer( xNode, UNO_QUERY_THROW );
+ exportContainer( xContainer, nContainerNodeType );
+ }
+ break;
+
+ case AnimationNodeType::ANIMATE:
+ case AnimationNodeType::SET:
+ case AnimationNodeType::ANIMATEMOTION:
+ case AnimationNodeType::ANIMATEPHYSICS:
+ case AnimationNodeType::ANIMATECOLOR:
+ case AnimationNodeType::ANIMATETRANSFORM:
+ case AnimationNodeType::TRANSITIONFILTER:
+ {
+ Reference< XAnimate > xAnimate( xNode, UNO_QUERY_THROW );
+ exportAnimate( xAnimate );
+ }
+ break;
+ case AnimationNodeType::AUDIO:
+ {
+ Reference< XAudio > xAudio( xNode, UNO_QUERY_THROW );
+ exportAudio( xAudio );
+ }
+ break;
+ case AnimationNodeType::COMMAND:
+ {
+ Reference< XCommand > xCommand( xNode, UNO_QUERY_THROW );
+ exportCommand( xCommand );
+ }
+ break;
+ default:
+ OSL_FAIL( "xmloff::AnimationsExporterImpl::exportNode(), invalid AnimationNodeType!" );
+ }
+ }
+ catch (const RuntimeException&)
+ {
+ TOOLS_WARN_EXCEPTION("xmloff.draw", "");
+ }
+
+ // if something goes wrong, its always a good idea to clear the attribute list
+ mxExport->ClearAttrList();
+}
+
+void AnimationsExporterImpl::exportContainer( const Reference< XTimeContainer >& xContainer, sal_Int16 nContainerNodeType )
+{
+ try
+ {
+ const sal_Int32 nNodeType = xContainer->getType();
+
+ if( nNodeType == AnimationNodeType::ITERATE )
+ {
+ OUStringBuffer sTmp;
+ Reference< XIterateContainer > xIter( xContainer, UNO_QUERY_THROW );
+
+ Any aTemp( xIter->getTarget() );
+ if( aTemp.hasValue() )
+ {
+ convertTarget( sTmp, aTemp );
+ mxExport->AddAttribute( XML_NAMESPACE_SMIL, XML_TARGETELEMENT, sTmp.makeStringAndClear() );
+ }
+
+ sal_Int16 nTemp = xIter->getSubItem();
+ if( nTemp )
+ {
+ SvXMLUnitConverter::convertEnum( sTmp, nTemp, aAnimations_EnumMap_SubItem );
+ mxExport->AddAttribute( XML_NAMESPACE_ANIMATION, XML_SUB_ITEM, sTmp.makeStringAndClear() );
+ }
+
+ nTemp = xIter->getIterateType();
+ if( nTemp )
+ {
+ SvXMLUnitConverter::convertEnum( sTmp, nTemp, aAnimations_EnumMap_IterateType );
+ mxExport->AddAttribute( XML_NAMESPACE_ANIMATION, XML_ITERATE_TYPE, sTmp.makeStringAndClear() );
+ }
+
+ double fTemp = xIter->getIterateInterval();
+ if( fTemp )
+ {
+ OUStringBuffer buf;
+ ::sax::Converter::convertDuration(buf, fTemp / (24*60*60));
+ mxExport->AddAttribute( XML_NAMESPACE_ANIMATION,
+ XML_ITERATE_INTERVAL, buf.makeStringAndClear());
+ }
+ }
+
+ XMLTokenEnum eElementToken;
+ switch( nNodeType )
+ {
+ case AnimationNodeType::PAR: eElementToken = XML_PAR; break;
+ case AnimationNodeType::SEQ: eElementToken = XML_SEQ; break;
+ case AnimationNodeType::ITERATE:eElementToken = XML_ITERATE; break;
+ default:
+ OSL_FAIL( "xmloff::AnimationsExporterImpl::exportContainer(), invalid TimeContainerType!" );
+ return;
+ }
+ SvXMLElementExport aElement( *mxExport, XML_NAMESPACE_ANIMATION, eElementToken, true, true );
+
+ if( nContainerNodeType == EffectNodeType::TIMING_ROOT )
+ exportTransitionNode();
+
+ Reference< XEnumerationAccess > xEnumerationAccess( xContainer, UNO_QUERY_THROW );
+ Reference< XEnumeration > xEnumeration( xEnumerationAccess->createEnumeration(), css::uno::UNO_SET_THROW );
+ while( xEnumeration->hasMoreElements() )
+ {
+ Reference< XAnimationNode > xChildNode( xEnumeration->nextElement(), UNO_QUERY_THROW );
+ exportNode( xChildNode );
+ }
+ }
+ catch (const RuntimeException&)
+ {
+ TOOLS_WARN_EXCEPTION("xmloff.draw", "");
+ }
+}
+
+void AnimationsExporterImpl::exportAnimate( const Reference< XAnimate >& xAnimate )
+{
+ try
+ {
+ const sal_Int16 nNodeType = xAnimate->getType();
+
+ OUStringBuffer sTmp;
+ sal_Int16 nTemp;
+ bool bTemp;
+
+ Any aTemp( xAnimate->getTarget() );
+ if( aTemp.hasValue() )
+ {
+ convertTarget( sTmp, aTemp );
+ mxExport->AddAttribute( XML_NAMESPACE_SMIL, XML_TARGETELEMENT, sTmp.makeStringAndClear() );
+ }
+
+ nTemp = xAnimate->getSubItem();
+ if( nTemp )
+ {
+ SvXMLUnitConverter::convertEnum( sTmp, nTemp, aAnimations_EnumMap_SubItem );
+ mxExport->AddAttribute( XML_NAMESPACE_ANIMATION, XML_SUB_ITEM, sTmp.makeStringAndClear() );
+ }
+
+ XMLTokenEnum eAttributeName = XML_TOKEN_INVALID;
+
+ if( nNodeType == AnimationNodeType::TRANSITIONFILTER )
+ {
+ eAttributeName = XML_TRANSITIONFILTER;
+ }
+ else if( nNodeType == AnimationNodeType::ANIMATETRANSFORM )
+ {
+ eAttributeName = XML_ANIMATETRANSFORM;
+ }
+ else if( nNodeType == AnimationNodeType::ANIMATEMOTION )
+ {
+ eAttributeName = XML_ANIMATEMOTION;
+ }
+ else if( nNodeType == AnimationNodeType::ANIMATEPHYSICS )
+ {
+ eAttributeName = XML_ANIMATEPHYSICS;
+ }
+ else
+ {
+ OUString sTemp( xAnimate->getAttributeName() );
+ if( !sTemp.isEmpty() )
+ {
+ const struct ImplAttributeNameConversion* p = getAnimationAttributeNamesConversionList();
+ while( p->mpAPIName )
+ {
+ if( sTemp.equalsAscii( p->mpAPIName ) )
+ {
+ sTemp = GetXMLToken( p->meXMLToken );
+ eAttributeName = p->meXMLToken;
+ break;
+ }
+
+ p++;
+ }
+
+ mxExport->AddAttribute( XML_NAMESPACE_SMIL, XML_ATTRIBUTENAME, sTemp );
+ }
+ else
+ {
+ mxExport->AddAttribute( XML_NAMESPACE_SMIL, XML_ATTRIBUTENAME, "invalid" );
+ }
+ }
+
+ Sequence< Any > aValues( xAnimate->getValues() );
+ if( aValues.hasElements() )
+ {
+ aTemp <<= aValues;
+ convertValue( eAttributeName, sTmp, aTemp );
+ mxExport->AddAttribute( XML_NAMESPACE_SMIL, XML_VALUES, sTmp.makeStringAndClear() );
+ }
+ else
+ {
+ aTemp = xAnimate->getFrom();
+ if( aTemp.hasValue() )
+ {
+ convertValue( eAttributeName, sTmp, aTemp );
+ mxExport->AddAttribute( XML_NAMESPACE_SMIL, XML_FROM, sTmp.makeStringAndClear() );
+ }
+
+ aTemp = xAnimate->getBy();
+ if( aTemp.hasValue() )
+ {
+ convertValue( eAttributeName, sTmp, aTemp );
+ mxExport->AddAttribute( XML_NAMESPACE_SMIL, XML_BY, sTmp.makeStringAndClear() );
+ }
+
+ aTemp = xAnimate->getTo();
+ if( aTemp.hasValue() )
+ {
+ convertValue( eAttributeName, sTmp, aTemp );
+ mxExport->AddAttribute( XML_NAMESPACE_SMIL, XML_TO, sTmp.makeStringAndClear() );
+ }
+ }
+
+ if(nNodeType != AnimationNodeType::SET)
+ {
+ const Sequence< double > aKeyTimes( xAnimate->getKeyTimes() );
+ if( aKeyTimes.hasElements() )
+ {
+ for( const auto& rKeyTime : aKeyTimes )
+ {
+ if( !sTmp.isEmpty() )
+ sTmp.append( ';' );
+
+ sTmp.append( rKeyTime );
+ }
+ mxExport->AddAttribute( XML_NAMESPACE_SMIL, XML_KEYTIMES, sTmp.makeStringAndClear() );
+ }
+
+ OUString sTemp( xAnimate->getFormula() );
+ if( !sTemp.isEmpty() )
+ mxExport->AddAttribute( XML_NAMESPACE_ANIMATION, XML_FORMULA, sTemp );
+
+ if( (nNodeType != AnimationNodeType::TRANSITIONFILTER) &&
+ (nNodeType != AnimationNodeType::AUDIO ) )
+ {
+ // calcMode = "discrete | linear | paced | spline"
+ nTemp = xAnimate->getCalcMode();
+ if( ((nNodeType == AnimationNodeType::ANIMATEMOTION ) && (nTemp != AnimationCalcMode::PACED)) ||
+ ((nNodeType != AnimationNodeType::ANIMATEMOTION ) && (nTemp != AnimationCalcMode::LINEAR)) )
+ {
+ SvXMLUnitConverter::convertEnum( sTmp, nTemp, aAnimations_EnumMap_CalcMode );
+ mxExport->AddAttribute( XML_NAMESPACE_SMIL, XML_CALCMODE, sTmp.makeStringAndClear() );
+ }
+
+ bTemp = xAnimate->getAccumulate();
+ if( bTemp )
+ mxExport->AddAttribute( XML_NAMESPACE_SMIL, XML_ACCUMULATE, XML_SUM );
+
+ nTemp = xAnimate->getAdditive();
+ if( nTemp != AnimationAdditiveMode::REPLACE )
+ {
+ SvXMLUnitConverter::convertEnum( sTmp, nTemp, aAnimations_EnumMap_AdditiveMode );
+ mxExport->AddAttribute( XML_NAMESPACE_SMIL, XML_ADDITIVE, sTmp.makeStringAndClear() );
+ }
+ }
+
+ const Sequence< TimeFilterPair > aTimeFilter( xAnimate->getTimeFilter() );
+ if( aTimeFilter.hasElements() )
+ {
+ for( const auto& rPair : aTimeFilter )
+ {
+ if( !sTmp.isEmpty() )
+ sTmp.append( ';' );
+
+ sTmp.append(OUString::number(rPair.Time) + "," + OUString::number(rPair.Progress));
+ }
+
+ mxExport->AddAttribute( XML_NAMESPACE_SMIL, XML_KEYSPLINES, sTmp.makeStringAndClear() );
+ }
+ }
+
+ XMLTokenEnum eElementToken = XML_ANIMATE;
+
+ switch( nNodeType )
+ {
+ case AnimationNodeType::ANIMATE:
+ eElementToken = XML_ANIMATE;
+ break;
+
+ case AnimationNodeType::SET:
+ eElementToken = XML_SET;
+ break;
+
+ case AnimationNodeType::ANIMATEMOTION:
+ {
+ eElementToken = XML_ANIMATEMOTION;
+
+ Reference< XAnimateMotion > xAnimateMotion( xAnimate, UNO_QUERY_THROW );
+
+ aTemp = xAnimateMotion->getPath();
+ if( aTemp.hasValue() )
+ {
+ convertPath( sTmp, aTemp );
+ mxExport->AddAttribute( XML_NAMESPACE_SVG, XML_PATH, sTmp.makeStringAndClear() );
+ }
+
+ // TODO: origin = ( parent | layout )
+ aTemp = xAnimateMotion->getOrigin();
+ }
+ break;
+
+ case AnimationNodeType::ANIMATEPHYSICS:
+ {
+ eElementToken = XML_ANIMATEPHYSICS;
+ double fTemp = 0;
+
+ Reference< XAnimatePhysics > xAnimatePhysics( xAnimate, UNO_QUERY_THROW );
+ aTemp = xAnimatePhysics->getStartVelocityX();
+ if( aTemp.hasValue() )
+ {
+ aTemp >>= fTemp;
+ ::sax::Converter::convertDouble( sTmp, fTemp );
+ mxExport->AddAttribute( XML_NAMESPACE_LO_EXT, XML_PHYSICS_ANIMATION_START_VELOCITY_X, sTmp.makeStringAndClear() );
+ }
+
+ aTemp = xAnimatePhysics->getStartVelocityY();
+ if( aTemp.hasValue() )
+ {
+ aTemp >>= fTemp;
+ ::sax::Converter::convertDouble( sTmp, fTemp );
+ mxExport->AddAttribute( XML_NAMESPACE_LO_EXT, XML_PHYSICS_ANIMATION_START_VELOCITY_Y, sTmp.makeStringAndClear() );
+ }
+
+ aTemp = xAnimatePhysics->getDensity();
+ if( aTemp.hasValue() )
+ {
+ aTemp >>= fTemp;
+ ::sax::Converter::convertDouble( sTmp, fTemp );
+ mxExport->AddAttribute( XML_NAMESPACE_LO_EXT, XML_PHYSICS_ANIMATION_DENSITY, sTmp.makeStringAndClear() );
+ }
+
+ aTemp = xAnimatePhysics->getBounciness();
+ if( aTemp.hasValue() )
+ {
+ aTemp >>= fTemp;
+ ::sax::Converter::convertDouble( sTmp, fTemp );
+ mxExport->AddAttribute( XML_NAMESPACE_LO_EXT, XML_PHYSICS_ANIMATION_BOUNCINESS, sTmp.makeStringAndClear() );
+ }
+ }
+ break;
+
+ case AnimationNodeType::ANIMATECOLOR:
+ {
+ eElementToken = XML_ANIMATECOLOR;
+
+ Reference< XAnimateColor > xAnimateColor( xAnimate, UNO_QUERY_THROW );
+
+ nTemp = xAnimateColor->getColorInterpolation();
+ mxExport->AddAttribute( XML_NAMESPACE_ANIMATION, XML_COLOR_INTERPOLATION, (nTemp == AnimationColorSpace::RGB) ? XML_RGB : XML_HSL );
+
+ bTemp = xAnimateColor->getDirection();
+ mxExport->AddAttribute( XML_NAMESPACE_ANIMATION, XML_COLOR_INTERPOLATION_DIRECTION, bTemp ? XML_CLOCKWISE : XML_COUNTER_CLOCKWISE );
+ }
+ break;
+
+ case AnimationNodeType::ANIMATETRANSFORM:
+ {
+ eElementToken = XML_ANIMATETRANSFORM;
+
+ mxExport->AddAttribute( XML_NAMESPACE_SMIL, XML_ATTRIBUTENAME, XML_TRANSFORM );
+
+ Reference< XAnimateTransform > xTransform( xAnimate, UNO_QUERY_THROW );
+ nTemp = xTransform->getTransformType();
+ SvXMLUnitConverter::convertEnum( sTmp, nTemp, aAnimations_EnumMap_TransformType );
+ mxExport->AddAttribute( XML_NAMESPACE_SVG, XML_TYPE, sTmp.makeStringAndClear() );
+ }
+ break;
+
+ case AnimationNodeType::TRANSITIONFILTER:
+ {
+ Reference< XTransitionFilter > xTransitionFilter( xAnimate, UNO_QUERY );
+ eElementToken = XML_TRANSITIONFILTER;
+
+ sal_Int16 nTransition = xTransitionFilter->getTransition();
+ SvXMLUnitConverter::convertEnum( sTmp, nTransition, aAnimations_EnumMap_TransitionType );
+ mxExport->AddAttribute( XML_NAMESPACE_SMIL, XML_TYPE, sTmp.makeStringAndClear() );
+
+ sal_Int16 nSubtype = xTransitionFilter->getSubtype();
+ if( nSubtype != TransitionSubType::DEFAULT )
+ {
+ SvXMLUnitConverter::convertEnum( sTmp, nSubtype, aAnimations_EnumMap_TransitionSubType );
+ mxExport->AddAttribute( XML_NAMESPACE_SMIL, XML_SUBTYPE, sTmp.makeStringAndClear() );
+ }
+
+ bTemp = xTransitionFilter->getMode();
+ if( !bTemp )
+ mxExport->AddAttribute( XML_NAMESPACE_SMIL, XML_MODE, XML_OUT );
+
+ bTemp = xTransitionFilter->getDirection();
+ if( !bTemp )
+ mxExport->AddAttribute( XML_NAMESPACE_SMIL, XML_DIRECTION, XML_REVERSE );
+
+ if( (nTransition == TransitionType::FADE) && ((nSubtype == TransitionSubType::FADETOCOLOR) || (nSubtype == TransitionSubType::FADEFROMCOLOR) ))
+ {
+ nTemp = xTransitionFilter->getFadeColor();
+ ::sax::Converter::convertColor( sTmp, nTemp );
+ mxExport->AddAttribute( XML_NAMESPACE_SMIL, XML_FADECOLOR, sTmp.makeStringAndClear() );
+ }
+ }
+ break;
+ }
+
+ if( eElementToken == XML_ANIMATEPHYSICS ) // not a standard should use the extension namespace
+ {
+ SvXMLElementExport aElement( *mxExport, XML_NAMESPACE_LO_EXT, eElementToken, true, true );
+ }
+ else
+ {
+ SvXMLElementExport aElement( *mxExport, XML_NAMESPACE_ANIMATION, eElementToken, true, true );
+ }
+
+ }
+ catch (const Exception&)
+ {
+ TOOLS_WARN_EXCEPTION("xmloff.draw", "");
+ }
+}
+
+void AnimationsExporterImpl::exportAudio( const Reference< XAudio >& xAudio )
+{
+ if( !xAudio.is() )
+ return;
+
+ try
+ {
+ OUString aSourceURL;
+ xAudio->getSource() >>= aSourceURL;
+ if( !aSourceURL.isEmpty() )
+ mxExport->AddAttribute( XML_NAMESPACE_XLINK, XML_HREF, mxExport->GetRelativeReference( aSourceURL ) );
+
+ const double fVolume = xAudio->getVolume();
+ if( fVolume != 1.0 )
+ {
+ OUStringBuffer sTmp;
+ ::sax::Converter::convertDouble( sTmp, fVolume );
+ mxExport->AddAttribute( XML_NAMESPACE_ANIMATION, XML_AUDIO_LEVEL, sTmp.makeStringAndClear() );
+ }
+
+ /* todo?
+ sal_Int32 nEndAfterSlide = 0;
+ xAudio->getEndAfterSlide() >>= nEndAfterSlide;
+ if( nEndAfterSlide != 0 )
+ mxExport->AddAttribute( );
+ */
+ SvXMLElementExport aElement( *mxExport, XML_NAMESPACE_ANIMATION, XML_AUDIO, true, true );
+
+ }
+ catch (const Exception&)
+ {
+ TOOLS_WARN_EXCEPTION("xmloff.draw", "");
+ }
+}
+
+void AnimationsExporterImpl::exportCommand( const Reference< XCommand >& xCommand )
+{
+ if( !xCommand.is() )
+ return;
+
+ try
+ {
+ OUStringBuffer sTmp;
+ Any aTemp( xCommand->getTarget() );
+ if( aTemp.hasValue() )
+ {
+ convertTarget( sTmp, aTemp );
+ mxExport->AddAttribute( XML_NAMESPACE_SMIL, XML_TARGETELEMENT, sTmp.makeStringAndClear() );
+ }
+
+ sal_Int16 nCommand = xCommand->getCommand();
+ SvXMLUnitConverter::convertEnum( sTmp, nCommand, aAnimations_EnumMap_Command );
+ mxExport->AddAttribute( XML_NAMESPACE_ANIMATION, XML_COMMAND, sTmp.makeStringAndClear() );
+
+ // todo virtual css::uno::Any SAL_CALL getParameter() throw (css::uno::RuntimeException) = 0;
+
+ SvXMLElementExport aElement( *mxExport, XML_NAMESPACE_ANIMATION, XML_COMMAND, true, true );
+
+ }
+ catch (const Exception&)
+ {
+ TOOLS_WARN_EXCEPTION("xmloff.draw", "");
+ }
+}
+
+Reference< XInterface > AnimationsExporterImpl::getParagraphTarget( const ParagraphTarget& pTarget )
+{
+ try
+ {
+ Reference< XEnumerationAccess > xParaEnumAccess( pTarget.Shape, UNO_QUERY_THROW );
+
+ Reference< XEnumeration > xEnumeration( xParaEnumAccess->createEnumeration(), css::uno::UNO_SET_THROW );
+ sal_Int32 nParagraph = pTarget.Paragraph;
+
+ while( xEnumeration->hasMoreElements() )
+ {
+ Reference< XInterface > xRef( xEnumeration->nextElement(), UNO_QUERY );
+ if( nParagraph-- == 0 )
+ return xRef;
+ }
+ }
+ catch (const RuntimeException&)
+ {
+ TOOLS_WARN_EXCEPTION("xmloff.draw", "");
+ }
+
+ Reference< XInterface > xRef;
+ return xRef;
+}
+
+void AnimationsExporterImpl::convertPath( OUStringBuffer& sTmp, const Any& rPath )
+{
+ OUString aStr;
+ rPath >>= aStr;
+
+ sTmp = aStr;
+}
+
+void AnimationsExporterImpl::convertValue( XMLTokenEnum eAttributeName, OUStringBuffer& sTmp, const Any& rValue ) const
+{
+ if( !rValue.hasValue() )
+ return;
+
+ if( auto pValuePair = o3tl::tryAccess<ValuePair>(rValue) )
+ {
+ OUStringBuffer sTmp2;
+ convertValue( eAttributeName, sTmp, pValuePair->First );
+ sTmp.append( ',' );
+ convertValue( eAttributeName, sTmp2, pValuePair->Second );
+ sTmp.append( sTmp2 );
+ }
+ else if( auto pSequence = o3tl::tryAccess<Sequence<Any>>(rValue) )
+ {
+ const sal_Int32 nLength = pSequence->getLength();
+ sal_Int32 nElement;
+ const Any* pAny = pSequence->getConstArray();
+
+ OUStringBuffer sTmp2;
+
+ for( nElement = 0; nElement < nLength; nElement++, pAny++ )
+ {
+ if( !sTmp.isEmpty() )
+ sTmp.append( ';' );
+ convertValue( eAttributeName, sTmp2, *pAny );
+ sTmp.append( sTmp2 );
+ sTmp2.setLength(0);
+ }
+ }
+ else
+ {
+ sal_Int32 nType;
+
+ switch( eAttributeName )
+ {
+ case XML_X:
+ case XML_Y:
+ case XML_WIDTH:
+ case XML_HEIGHT:
+ case XML_ANIMATETRANSFORM:
+ case XML_ANIMATEMOTION:
+ case XML_ANIMATEPHYSICS:
+ {
+ if( auto aString = o3tl::tryAccess<OUString>(rValue) )
+ {
+ sTmp.append( *aString );
+ }
+ else if( auto x = o3tl::tryAccess<double>(rValue) )
+ {
+ sTmp.append( *x );
+ }
+ else
+ {
+ OSL_FAIL( "xmloff::AnimationsExporterImpl::convertValue(), invalid value type!" );
+ }
+ return;
+ }
+
+ case XML_SKEWX:
+ case XML_ROTATE: nType = XML_TYPE_DOUBLE; break;
+ case XML_TEXT_ROTATION_ANGLE: nType = XML_TYPE_NUMBER16; break;
+ case XML_FILL_COLOR:
+ case XML_STROKE_COLOR:
+ case XML_DIM:
+ case XML_COLOR: nType = XML_TYPE_COLOR; break;
+ case XML_FILL: nType = XML_SD_TYPE_FILLSTYLE; break;
+ case XML_STROKE: nType = XML_SD_TYPE_STROKE; break;
+ case XML_FONT_WEIGHT: nType = XML_TYPE_TEXT_WEIGHT; break;
+ case XML_FONT_STYLE: nType = XML_TYPE_TEXT_POSTURE; break;
+ case XML_TEXT_UNDERLINE: nType = XML_TYPE_TEXT_UNDERLINE_STYLE; break;
+ case XML_FONT_SIZE: nType = XML_TYPE_DOUBLE_PERCENT; break;
+ case XML_VISIBILITY: nType = XML_SD_TYPE_PRESPAGE_VISIBILITY; break;
+ case XML_OPACITY:
+ case XML_TRANSITIONFILTER: nType = XML_TYPE_DOUBLE; break;
+ default:
+ OSL_FAIL( "xmloff::AnimationsExporterImpl::convertValue(), invalid AttributeName!" );
+ nType = XML_TYPE_STRING;
+ }
+
+ //const XMLPropertyHandler* pHandler = static_cast<SdXMLExport*>(&mrExport)->GetSdPropHdlFactory()->GetPropertyHandler( nType );
+ const XMLPropertyHandler* pHandler = mxSdPropHdlFactory->GetPropertyHandler( nType );
+ if( pHandler )
+ {
+ OUString aString;
+ pHandler->exportXML( aString, rValue, mxExport->GetMM100UnitConverter() );
+ sTmp.append( aString );
+ }
+ }
+}
+
+void AnimationsExporterImpl::convertTiming( OUStringBuffer& sTmp, const Any& rValue ) const
+{
+ if( !rValue.hasValue() )
+ return;
+
+ if( auto pSequence = o3tl::tryAccess<Sequence<Any>>(rValue) )
+ {
+ const sal_Int32 nLength = pSequence->getLength();
+ sal_Int32 nElement;
+ const Any* pAny = pSequence->getConstArray();
+
+ OUStringBuffer sTmp2;
+
+ for( nElement = 0; nElement < nLength; nElement++, pAny++ )
+ {
+ if( !sTmp.isEmpty() )
+ sTmp.append( ';' );
+ convertTiming( sTmp2, *pAny );
+ sTmp.append( sTmp2 );
+ sTmp2.setLength(0);
+ }
+ }
+ else if( auto x = o3tl::tryAccess<double>(rValue) )
+ {
+ sTmp.append( *x );
+ sTmp.append( 's');
+ }
+ else if( auto pTiming = o3tl::tryAccess<Timing>(rValue) )
+ {
+ sTmp.append( GetXMLToken( (*pTiming == Timing_MEDIA) ? XML_MEDIA : XML_INDEFINITE ) );
+ }
+ else if( auto pEvent = o3tl::tryAccess<Event>(rValue) )
+ {
+ OUStringBuffer sTmp2;
+
+ if( pEvent->Trigger != EventTrigger::NONE )
+ {
+ if( pEvent->Source.hasValue() )
+ {
+ convertTarget( sTmp, pEvent->Source );
+ sTmp.append( '.' );
+ }
+
+ SvXMLUnitConverter::convertEnum( sTmp2, pEvent->Trigger, aAnimations_EnumMap_EventTrigger );
+
+ sTmp.append( sTmp2 );
+ sTmp2.setLength(0);
+ }
+
+ if( pEvent->Offset.hasValue() )
+ {
+ convertTiming( sTmp2, pEvent->Offset );
+
+ if( !sTmp.isEmpty() )
+ sTmp.append( '+' );
+
+ sTmp.append( sTmp2 );
+ sTmp2.setLength(0);
+ }
+ }
+ else
+ {
+ OSL_FAIL( "xmloff::AnimationsExporterImpl::convertTiming(), invalid value type!" );
+ }
+}
+
+void AnimationsExporterImpl::convertTarget( OUStringBuffer& sTmp, const Any& rTarget ) const
+{
+ if( !rTarget.hasValue() )
+ return;
+
+ Reference< XInterface > xRef;
+
+ if( !(rTarget >>= xRef) )
+ {
+ if( auto pt = o3tl::tryAccess<ParagraphTarget>(rTarget) )
+ {
+ xRef = getParagraphTarget( *pt );
+ }
+ }
+
+ SAL_WARN_IF( !xRef.is(), "xmloff", "xmloff::AnimationsExporterImpl::convertTarget(), invalid target type!" );
+ if( xRef.is() )
+ {
+ const OUString& rIdentifier = mxExport->getInterfaceToIdentifierMapper().getIdentifier(xRef);
+ if( !rIdentifier.isEmpty() )
+ sTmp.append( rIdentifier );
+ }
+}
+
+void AnimationsExporterImpl::prepareValue( const Any& rValue )
+{
+ if( !rValue.hasValue() )
+ return;
+
+ if( auto pValuePair = o3tl::tryAccess<ValuePair>(rValue) )
+ {
+ prepareValue( pValuePair->First );
+ prepareValue( pValuePair->Second );
+ }
+ else if( auto pSequence = o3tl::tryAccess<Sequence<Any>>(rValue) )
+ {
+ const sal_Int32 nLength = pSequence->getLength();
+ sal_Int32 nElement;
+ const Any* pAny = pSequence->getConstArray();
+
+ for( nElement = 0; nElement < nLength; nElement++, pAny++ )
+ prepareValue( *pAny );
+ }
+ else if( rValue.getValueTypeClass() == css::uno::TypeClass_INTERFACE )
+ {
+ Reference< XInterface> xRef( rValue, UNO_QUERY );
+ if( xRef.is() )
+ mxExport->getInterfaceToIdentifierMapper().registerReference( xRef );
+ }
+ else if( auto pt = o3tl::tryAccess<ParagraphTarget>(rValue) )
+ {
+ Reference< XInterface> xRef( getParagraphTarget( *pt ) );
+ if( xRef.is() )
+ mxExport->getInterfaceToIdentifierMapper().registerReference( xRef );
+ }
+ else if( auto pEvent = o3tl::tryAccess<Event>(rValue) )
+ {
+ prepareValue( pEvent->Source );
+ }
+}
+
+AnimationsExporter::AnimationsExporter( SvXMLExport& rExport, const Reference< XPropertySet >& xPageProps )
+ : mpImpl( new AnimationsExporterImpl( rExport, xPageProps ) )
+{
+}
+
+AnimationsExporter::~AnimationsExporter()
+{
+}
+
+void AnimationsExporter::prepare( const Reference< XAnimationNode >& xRootNode )
+{
+ try
+ {
+ if( xRootNode.is() )
+ {
+ mpImpl->prepareTransitionNode();
+ mpImpl->prepareNode( xRootNode );
+ }
+ }
+ catch (const RuntimeException&)
+ {
+ TOOLS_WARN_EXCEPTION("xmloff.draw", "");
+ }
+}
+
+void AnimationsExporter::exportAnimations( const Reference< XAnimationNode >& xRootNode )
+{
+ try
+ {
+ if( xRootNode.is() )
+ {
+ bool bHasEffects = mpImpl->mbHasTransition;
+
+ if( !bHasEffects )
+ {
+ // first check if there are no animations
+ Reference< XEnumerationAccess > xEnumerationAccess( xRootNode, UNO_QUERY_THROW );
+ Reference< XEnumeration > xEnumeration( xEnumerationAccess->createEnumeration(), css::uno::UNO_SET_THROW );
+ if( xEnumeration->hasMoreElements() )
+ {
+ // first child node may be an empty main sequence, check this
+ Reference< XAnimationNode > xMainNode( xEnumeration->nextElement(), UNO_QUERY_THROW );
+ Reference< XEnumerationAccess > xMainEnumerationAccess( xMainNode, UNO_QUERY_THROW );
+ Reference< XEnumeration > xMainEnumeration( xMainEnumerationAccess->createEnumeration(), css::uno::UNO_SET_THROW );
+
+ // only export if the main sequence is not empty or if there are additional
+ // trigger sequences
+ bHasEffects = xMainEnumeration->hasMoreElements() || xEnumeration->hasMoreElements();
+ }
+ }
+
+ if( bHasEffects )
+ mpImpl->exportNode( xRootNode );
+ }
+ }
+ catch (const RuntimeException&)
+ {
+ TOOLS_WARN_EXCEPTION("xmloff.draw", "");
+ }
+}
+
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/xmloff/source/draw/animationimport.cxx b/xmloff/source/draw/animationimport.cxx
new file mode 100644
index 0000000000..519c3288cd
--- /dev/null
+++ b/xmloff/source/draw/animationimport.cxx
@@ -0,0 +1,1356 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#include <memory>
+#include <xmloff/unointerfacetouniqueidentifiermapper.hxx>
+#include <com/sun/star/lang/XInitialization.hpp>
+#include <com/sun/star/animations/AnimationTransformType.hpp>
+#include <com/sun/star/animations/XAnimationNodeSupplier.hpp>
+#include <com/sun/star/animations/AnimationNodeType.hpp>
+#include <com/sun/star/animations/SequenceTimeContainer.hpp>
+#include <com/sun/star/animations/XIterateContainer.hpp>
+#include <com/sun/star/animations/XAnimateMotion.hpp>
+#include <com/sun/star/animations/XAnimatePhysics.hpp>
+#include <com/sun/star/animations/XAnimateColor.hpp>
+#include <com/sun/star/animations/XAnimateTransform.hpp>
+#include <com/sun/star/animations/XTransitionFilter.hpp>
+#include <com/sun/star/animations/XCommand.hpp>
+#include <com/sun/star/animations/XAudio.hpp>
+#include <com/sun/star/animations/ValuePair.hpp>
+#include <com/sun/star/animations/AnimationColorSpace.hpp>
+#include <com/sun/star/presentation/EffectPresetClass.hpp>
+#include <com/sun/star/animations/Timing.hpp>
+#include <com/sun/star/animations/Event.hpp>
+#include <com/sun/star/beans/XPropertySet.hpp>
+#include <com/sun/star/io/WrongFormatException.hpp>
+#include <com/sun/star/xml/sax/XFastAttributeList.hpp>
+#include <com/sun/star/text/XTextCursor.hpp>
+#include <com/sun/star/text/XTextRangeCompare.hpp>
+#include <com/sun/star/presentation/ParagraphTarget.hpp>
+#include <com/sun/star/container/XEnumerationAccess.hpp>
+#include <com/sun/star/animations/EventTrigger.hpp>
+#include <com/sun/star/presentation/EffectCommands.hpp>
+#include <com/sun/star/util/Duration.hpp>
+#include <comphelper/processfactory.hxx>
+#include <comphelper/string.hxx>
+
+#include <rtl/math.h>
+#include <sal/log.hxx>
+#include <comphelper/diagnose_ex.hxx>
+#include <o3tl/string_view.hxx>
+#include <sax/tools/converter.hxx>
+
+#include <vector>
+
+#include <xmloff/xmltypes.hxx>
+#include "sdpropls.hxx"
+#include <xmloff/xmltoken.hxx>
+#include <xmloff/xmlimp.hxx>
+#include <xmloff/xmlnamespace.hxx>
+#include <xmloff/xmluconv.hxx>
+#include <xmloff/xmlprhdl.hxx>
+#include <xmlsdtypes.hxx>
+
+#include <animations.hxx>
+#include <animationimport.hxx>
+
+using namespace ::cppu;
+using namespace ::com::sun::star;
+using namespace ::com::sun::star::beans;
+using namespace ::com::sun::star::animations;
+using namespace ::com::sun::star::presentation;
+using namespace ::com::sun::star::drawing;
+using namespace ::com::sun::star::uno;
+using namespace ::xmloff::token;
+
+using ::com::sun::star::xml::sax::XFastAttributeList;
+using ::com::sun::star::beans::NamedValue;
+using ::com::sun::star::text::XTextRange;
+using ::com::sun::star::text::XTextCursor;
+using ::com::sun::star::text::XTextRangeCompare;
+using ::com::sun::star::container::XEnumerationAccess;
+using ::com::sun::star::container::XEnumeration;
+using ::com::sun::star::lang::XInitialization;
+
+static OUString
+lcl_GetMediaReference(SvXMLImport const& rImport, OUString const& rURL)
+{
+ if (rImport.IsPackageURL(rURL))
+ return "vnd.sun.star.Package:" + rURL;
+
+ return rImport.GetAbsoluteReference(rURL);
+}
+
+namespace xmloff
+{
+
+class AnimationsImportHelperImpl
+{
+private:
+ SvXMLImport& mrImport;
+
+public:
+ explicit AnimationsImportHelperImpl( SvXMLImport& rImport );
+
+ Any convertValue( XMLTokenEnum eAttributeName, const OUString& rValue );
+ Sequence< Any > convertValueSequence( XMLTokenEnum eAttributeName, std::u16string_view rValue );
+
+ Any convertTarget( const OUString& rValue );
+ static Any convertPath( const OUString& rValue );
+ Any convertTiming( const OUString& rValue );
+ static Sequence< double > convertKeyTimes( std::string_view rValue );
+ static Sequence< TimeFilterPair > convertTimeFilter( std::string_view rValue );
+};
+
+AnimationsImportHelperImpl::AnimationsImportHelperImpl( SvXMLImport& rImport )
+: mrImport( rImport )
+{
+}
+
+static bool isDouble( std::string_view rValue )
+{
+ sal_Int32 nLength = rValue.size();
+ const char * pStr = rValue.data();
+ while( nLength )
+ {
+ if( (*pStr >= '0' && *pStr <= '9') || *pStr == '-' || *pStr == '.' || *pStr == '+' || *pStr == 'e' || *pStr == 'E' )
+ {
+ pStr++;
+ nLength--;
+ }
+ else
+ {
+ return false;
+ }
+ }
+
+ return true;
+}
+
+static bool isTime( const OUString& rValue )
+{
+ sal_Int32 nLength = rValue.getLength();
+ const sal_Unicode * pStr;
+ for( pStr = rValue.getStr(); nLength; pStr++, nLength-- )
+ {
+ if( !( (*pStr >= '0' && *pStr <= '9') || *pStr == '-' || *pStr == '.' || *pStr == '+' || *pStr == 'e' || *pStr == 'E' ) )
+ break;
+ }
+
+ // return true if this is a double (if someone forgot the 's' we silently ignore it)
+ // or if it's a double that ends with a 's' or 'S'
+ return (nLength == 0) || ((*pStr == 's' || *pStr == 'S') && (nLength == 1));
+}
+
+Any AnimationsImportHelperImpl::convertTarget( const OUString& rValue )
+{
+ try
+ {
+ Reference< XInterface > xRef( mrImport.getInterfaceToIdentifierMapper().getReference( rValue ) );
+
+ Reference< XShape > _xShape( xRef, UNO_QUERY );
+ if( _xShape.is() )
+ return Any( _xShape );
+
+ Reference< XTextCursor > xTextCursor( xRef, UNO_QUERY );
+ if( xTextCursor.is() )
+ {
+ Reference< XTextRange > xStart( xTextCursor->getStart() ), xRange;
+ Reference< XShape > xShape( xTextCursor->getText(), UNO_QUERY_THROW );
+ Reference< XTextRangeCompare > xTextRangeCompare( xShape, UNO_QUERY_THROW );
+
+ Reference< XEnumerationAccess > xParaEnumAccess( xShape, UNO_QUERY_THROW );
+ Reference< XEnumeration > xEnumeration( xParaEnumAccess->createEnumeration(), UNO_SET_THROW );
+ sal_Int16 nParagraph = 0;
+
+ while( xEnumeration->hasMoreElements() )
+ {
+ xEnumeration->nextElement() >>= xRange;
+
+ // break if start of selection is prior to end of current paragraph
+ if( xRange.is() && (xTextRangeCompare->compareRegionEnds( xStart, xRange ) >= 0 ) )
+ {
+ return Any( ParagraphTarget( xShape, nParagraph ) );
+ }
+
+ nParagraph++;
+ }
+ }
+ }
+ catch (const RuntimeException&)
+ {
+ TOOLS_WARN_EXCEPTION("xmloff.draw", "");
+ }
+
+ Any aAny;
+ return aAny;
+}
+
+Any AnimationsImportHelperImpl::convertValue( XMLTokenEnum eAttributeName, const OUString& rValue )
+{
+ sal_Int32 nCommaPos = -1, nPos;
+ sal_Int32 nOpenBrackets = 0;
+ for( nPos = 0; (nPos < rValue.getLength()) && (nCommaPos == -1); nPos++ )
+ {
+ switch( rValue[nPos] )
+ {
+ case ',':
+ if( nOpenBrackets == 0 )
+ nCommaPos = nPos;
+ break;
+ case '(':
+ case '[':
+ case '{':
+ nOpenBrackets++;
+ break;
+ case ')':
+ case ']':
+ case '}':
+ nOpenBrackets--;
+ break;
+ }
+ }
+
+ if( nCommaPos >= 0 )
+ {
+ ValuePair aPair;
+ aPair.First = convertValue( eAttributeName, rValue.copy( 0, nCommaPos ) );
+ aPair.Second = convertValue( eAttributeName, rValue.copy( nCommaPos+1 ) );
+ return Any( aPair );
+ }
+ else
+ {
+ Any aAny;
+ sal_Int32 nType = XML_TYPE_STRING;
+
+ if( rValue.getLength() ) switch( eAttributeName )
+ {
+ case XML_X:
+ case XML_Y:
+ case XML_WIDTH:
+ case XML_HEIGHT:
+ case XML_TRANSLATE:
+ {
+ return Any( rValue );
+ }
+
+ case XML_SCALE:
+ case XML_SKEWY:
+ case XML_SKEWX:
+ case XML_OPACITY:
+ case XML_ROTATE: nType = XML_TYPE_DOUBLE; break;
+ case XML_TEXT_ROTATION_ANGLE:nType = XML_TYPE_TEXT_ROTATION_ANGLE; break;
+ case XML_FILL_COLOR:
+ case XML_STROKE_COLOR:
+ case XML_DIM:
+ case XML_COLOR: nType = XML_TYPE_COLOR; break;
+ case XML_FILL: nType = XML_SD_TYPE_FILLSTYLE; break;
+ case XML_STROKE: nType = XML_SD_TYPE_STROKE; break;
+ case XML_FONT_WEIGHT: nType = XML_TYPE_TEXT_WEIGHT; break;
+ case XML_FONT_STYLE: nType = XML_TYPE_TEXT_POSTURE; break;
+ case XML_TEXT_UNDERLINE: nType = XML_TYPE_TEXT_UNDERLINE_STYLE; break;
+ case XML_FONT_SIZE: nType = XML_TYPE_DOUBLE_PERCENT; break;
+ case XML_VISIBILITY: nType = XML_SD_TYPE_PRESPAGE_VISIBILITY; break;
+
+ default:
+ if( !rValue.isEmpty() )
+ aAny <<= rValue;
+ return aAny;
+ }
+
+ const XMLPropertyHandler* pHandler = mrImport.GetShapeImport()->GetSdPropHdlFactory()->GetPropertyHandler( nType );
+ if( pHandler )
+ pHandler->importXML( rValue, aAny, mrImport.GetMM100UnitConverter() );
+
+ return aAny;
+ }
+}
+
+Sequence< Any > AnimationsImportHelperImpl::convertValueSequence( XMLTokenEnum eAttributeName, std::u16string_view rValue )
+{
+ Sequence< Any > aValues;
+
+ const sal_Int32 nElements { comphelper::string::getTokenCount(rValue, ';') };
+ if ( nElements>0 )
+ {
+ // prepare the sequence
+ aValues.realloc( nElements );
+
+ // fill the sequence
+ Any* pValues = aValues.getArray();
+ for (sal_Int32 nIndex = 0; nIndex >= 0; )
+ *pValues++ = convertValue( eAttributeName, OUString(o3tl::getToken(rValue, 0, ';', nIndex )) );
+ }
+
+ return aValues;
+}
+
+Any AnimationsImportHelperImpl::convertTiming( const OUString& rValue )
+{
+ Any aAny;
+
+ const sal_Int32 nElements { comphelper::string::getTokenCount(rValue, ';') };
+ if ( nElements>0 )
+ {
+ if( nElements == 1 )
+ {
+ if( IsXMLToken( rValue, XML_MEDIA ) )
+ {
+ aAny <<= Timing_MEDIA;
+ }
+ else if( IsXMLToken( rValue, XML_INDEFINITE ) )
+ {
+ aAny <<= Timing_INDEFINITE;
+ }
+ else if( isTime( rValue ) )
+ {
+ aAny <<= rValue.toDouble();
+ }
+ else
+ {
+ Event aEvent;
+ aEvent.Repeat = 0;
+ aEvent.Trigger = 0;
+
+ OUString aEventTrigger;
+
+ sal_Int32 nPos = rValue.indexOf( '+' );
+ if( nPos == -1 )
+ {
+ aEventTrigger = rValue;
+ }
+ else
+ {
+ aEventTrigger = rValue.copy( 0, nPos );
+
+ // convert offset
+ aEvent.Offset = convertTiming( rValue.copy( nPos + 1 ) );
+ }
+
+ nPos = aEventTrigger.indexOf( '.' );
+ if( nPos != -1 )
+ {
+ aEvent.Source <<= mrImport.getInterfaceToIdentifierMapper().getReference( aEventTrigger.copy( 0, nPos ) );
+ aEventTrigger = aEventTrigger.copy( nPos + 1 );
+ }
+
+ sal_Int16 nEnum;
+ if( SvXMLUnitConverter::convertEnum( nEnum, aEventTrigger, aAnimations_EnumMap_EventTrigger ) )
+ {
+ aEvent.Trigger = nEnum;
+ }
+ else
+ {
+ OSL_FAIL("AnimationsImportHelperImpl::convertTiming(), unknown event trigger!");
+ }
+
+ aAny <<= aEvent;
+ }
+ }
+ else
+ {
+ // fill the sequence
+ Sequence< Any > aValues( nElements );
+ Any* pValues = aValues.getArray();
+ for (sal_Int32 nIndex = 0; nIndex >= 0; )
+ *pValues++ = convertTiming( rValue.getToken( 0, ';', nIndex ) );
+
+ aAny <<= aValues;
+ }
+ }
+ return aAny;
+}
+
+Sequence< double > AnimationsImportHelperImpl::convertKeyTimes( std::string_view rValue )
+{
+ const sal_Int32 nElements { comphelper::string::getTokenCount(rValue, ';') };
+
+ Sequence< double > aKeyTimes( nElements );
+
+ if( nElements )
+ {
+ double* pValues = aKeyTimes.getArray();
+ for (sal_Int32 nIndex = 0; nIndex >= 0; )
+ *pValues++ = o3tl::toDouble(o3tl::getToken(rValue, 0, ';', nIndex ));
+ }
+
+ return aKeyTimes;
+}
+
+Sequence< TimeFilterPair > AnimationsImportHelperImpl::convertTimeFilter( std::string_view rValue )
+{
+ const sal_Int32 nElements { comphelper::string::getTokenCount(rValue, ';') };
+
+ Sequence< TimeFilterPair > aTimeFilter( nElements );
+
+ if( nElements )
+ {
+ TimeFilterPair* pValues = aTimeFilter.getArray();
+ for (sal_Int32 nIndex = 0; nIndex >= 0; )
+ {
+ const std::string_view aToken( o3tl::getToken(rValue, 0, ';', nIndex ) );
+
+ size_t nPos = aToken.find( ',' );
+ if( nPos != std::string_view::npos )
+ {
+ pValues->Time = rtl_math_stringToDouble(
+ aToken.data(), aToken.data() + nPos, '.', 0, nullptr, nullptr);
+ pValues->Progress = rtl_math_stringToDouble(
+ aToken.data() + nPos + 1, aToken.data() + aToken.size(), '.', 0,
+ nullptr, nullptr);
+ }
+ pValues++;
+ }
+ }
+
+ return aTimeFilter;
+}
+
+Any AnimationsImportHelperImpl::convertPath( const OUString& rValue )
+{
+ return Any( rValue );
+}
+
+
+AnimationNodeContext::AnimationNodeContext(
+ const Reference< XAnimationNode >& xParentNode,
+ SvXMLImport& rImport, sal_Int32 nElement,
+ const css::uno::Reference< css::xml::sax::XFastAttributeList>& xAttrList,
+ const std::shared_ptr<AnimationsImportHelperImpl>& pHelper )
+: SvXMLImportContext(rImport),
+ mpHelper( pHelper )
+{
+ bool bRootContext = !pHelper;
+ try
+ {
+ if( bRootContext )
+ {
+ mpHelper = std::make_shared<AnimationsImportHelperImpl>( rImport );
+ mxNode = xParentNode;
+ }
+ else
+ {
+ sal_Int16 nPresetClass = EffectPresetClass::CUSTOM;
+
+ const char* pServiceName = nullptr;
+
+ // we see namespace ANIMATION and ANIMATION_OOO and PRESENTATION_OASIS and PRESENTATION_SO52 and PRESENTATION_OOO
+ switch( nElement & TOKEN_MASK )
+ {
+ case XML_SEQ:
+ pServiceName = "com.sun.star.animations.SequenceTimeContainer"; break;
+ case XML_ITERATE:
+ pServiceName = "com.sun.star.animations.IterateContainer"; break;
+ case XML_ANIMATE:
+ pServiceName = "com.sun.star.animations.Animate"; break;
+ case XML_SET:
+ pServiceName = "com.sun.star.animations.AnimateSet"; break;
+ case XML_ANIMATEMOTION:
+ pServiceName = "com.sun.star.animations.AnimateMotion"; break;
+ case XML_ANIMATEPHYSICS:
+ pServiceName = "com.sun.star.animations.AnimatePhysics"; break;
+ case XML_ANIMATECOLOR:
+ pServiceName = "com.sun.star.animations.AnimateColor"; break;
+ case XML_ANIMATETRANSFORM:
+ pServiceName = "com.sun.star.animations.AnimateTransform"; break;
+ case XML_TRANSITIONFILTER:
+ pServiceName = "com.sun.star.animations.TransitionFilter"; break;
+ case XML_AUDIO:
+ pServiceName = "com.sun.star.animations.Audio"; break;
+ case XML_COMMAND:
+ pServiceName = "com.sun.star.animations.Command"; break;
+ case XML_PAR:
+ {
+ for (auto &aIter : sax_fastparser::castToFastAttributeList( xAttrList ))
+ {
+ if( (aIter.getToken() & TOKEN_MASK) == XML_PRESET_ID)
+ {
+ const OUString& rValue = aIter.toString();
+ if ( rValue == "ooo-entrance-random" )
+ {
+ nPresetClass = EffectPresetClass::ENTRANCE;
+ }
+ else if ( rValue == "ooo-exit-random" )
+ {
+ nPresetClass = EffectPresetClass::EXIT;
+ }
+
+ if( nPresetClass != EffectPresetClass::CUSTOM )
+ {
+ pServiceName = "com.sun.star.comp.sd.RandomAnimationNode";
+ break;
+ }
+ }
+ }
+ if( !pServiceName )
+ pServiceName = "com.sun.star.animations.ParallelTimeContainer";
+ }
+ break;
+ default:
+ SAL_WARN("xmloff", "unexpected token '" + SvXMLImport::getNameFromToken(nElement)
+ << "' 0x" << std::hex << nElement);
+ break;
+ }
+
+ if( pServiceName )
+ {
+ Reference< XComponentContext > xContext( ::comphelper::getProcessComponentContext() );
+
+ mxNode.set(
+ xContext->getServiceManager()->createInstanceWithContext(OUString::createFromAscii(pServiceName), xContext),
+ UNO_QUERY_THROW );
+
+ if( nPresetClass != EffectPresetClass::CUSTOM )
+ {
+ Reference< XInitialization > xInit( mxNode, UNO_QUERY_THROW );
+ const Any aAny( nPresetClass );
+ Sequence< Any > aArgs( &aAny, 1 ) ;
+ xInit->initialize( aArgs );
+ }
+
+ init_node( xAttrList );
+
+ Reference< XTimeContainer > xParentContainer( xParentNode, UNO_QUERY_THROW );
+ xParentContainer->appendChild( mxNode );
+ }
+ }
+ }
+ catch (const RuntimeException&)
+ {
+ TOOLS_WARN_EXCEPTION("xmloff.draw", "");
+ }
+}
+
+void AnimationNodeContext::init_node( const css::uno::Reference< css::xml::sax::XFastAttributeList >& xAttrList )
+{
+ if( !mxNode.is() )
+ return;
+
+ try
+ {
+ const sal_Int16 nNodeType = mxNode->getType();
+
+ // query for optional interfaces that are often used later
+ Reference< XAnimate > xAnimate( mxNode, UNO_QUERY );
+ Reference< XCommand > xCommand( mxNode, UNO_QUERY );
+ Reference< XTransitionFilter > xTransitionFilter( mxNode, UNO_QUERY );
+ Reference< XIterateContainer > xIter( mxNode, UNO_QUERY );
+
+ std::vector< NamedValue > aUserData;
+ XMLTokenEnum meAttributeName = XML_TOKEN_INVALID;
+ OUString aFrom, aBy, aTo, aValues;
+ bool bHaveXmlId( false );
+ OUString sXmlId;
+
+ sal_Int16 nEnum;
+ for (auto &aIter : sax_fastparser::castToFastAttributeList( xAttrList ))
+ {
+ auto nToken = aIter.getToken();
+ switch( nToken )
+ {
+ case XML_ELEMENT(SMIL, XML_BEGIN):
+ case XML_ELEMENT(SMIL_COMPAT, XML_BEGIN):
+ case XML_ELEMENT(SMIL_SO52, XML_BEGIN):
+ {
+ mxNode->setBegin( mpHelper->convertTiming( aIter.toString() ) );
+ }
+ break;
+ case XML_ELEMENT(SMIL, XML_DUR):
+ case XML_ELEMENT(SMIL_COMPAT, XML_DUR):
+ case XML_ELEMENT(SMIL_SO52, XML_DUR):
+ {
+ mxNode->setDuration( mpHelper->convertTiming( aIter.toString() ) );
+ }
+ break;
+ case XML_ELEMENT(SMIL, XML_END):
+ case XML_ELEMENT(SMIL_COMPAT, XML_END):
+ case XML_ELEMENT(SMIL_SO52, XML_END):
+ {
+ mxNode->setEnd( mpHelper->convertTiming( aIter.toString() ) );
+ }
+ break;
+ case XML_ELEMENT(SMIL, XML_FILL):
+ case XML_ELEMENT(SMIL_COMPAT, XML_FILL):
+ case XML_ELEMENT(SMIL_SO52, XML_FILL):
+ {
+ if( SvXMLUnitConverter::convertEnum( nEnum, aIter.toView(), aAnimations_EnumMap_Fill ) )
+ mxNode->setFill( nEnum );
+ }
+ break;
+ case XML_ELEMENT(SMIL, XML_FILLDEFAULT):
+ case XML_ELEMENT(SMIL_COMPAT, XML_FILLDEFAULT):
+ case XML_ELEMENT(SMIL_SO52, XML_FILLDEFAULT):
+ {
+ if( SvXMLUnitConverter::convertEnum( nEnum, aIter.toView(), aAnimations_EnumMap_FillDefault ) )
+ mxNode->setFillDefault( nEnum );
+ }
+ break;
+ case XML_ELEMENT(SMIL, XML_RESTART):
+ case XML_ELEMENT(SMIL_COMPAT, XML_RESTART):
+ case XML_ELEMENT(SMIL_SO52, XML_RESTART):
+ {
+ if( SvXMLUnitConverter::convertEnum( nEnum, aIter.toView(), aAnimations_EnumMap_Restart ) )
+ mxNode->setRestart( nEnum );
+ }
+ break;
+ case XML_ELEMENT(SMIL, XML_RESTARTDEFAULT):
+ case XML_ELEMENT(SMIL_COMPAT, XML_RESTARTDEFAULT):
+ case XML_ELEMENT(SMIL_SO52, XML_RESTARTDEFAULT):
+ {
+ if( SvXMLUnitConverter::convertEnum( nEnum, aIter.toView(), aAnimations_EnumMap_RestartDefault ) )
+ mxNode->setRestartDefault( nEnum );
+ }
+ break;
+ case XML_ELEMENT(SMIL, XML_ACCELERATE):
+ case XML_ELEMENT(SMIL_COMPAT, XML_ACCELERATE):
+ case XML_ELEMENT(SMIL_SO52, XML_ACCELERATE):
+ {
+ if( isDouble( aIter.toView() ) )
+ mxNode->setAcceleration( aIter.toDouble() );
+ }
+ break;
+ case XML_ELEMENT(SMIL, XML_DECELERATE):
+ case XML_ELEMENT(SMIL_COMPAT, XML_DECELERATE):
+ case XML_ELEMENT(SMIL_SO52, XML_DECELERATE):
+ {
+ if( isDouble( aIter.toView() ) )
+ mxNode->setDecelerate( aIter.toDouble() );
+ }
+ break;
+ case XML_ELEMENT(SMIL, XML_AUTOREVERSE):
+ case XML_ELEMENT(SMIL_COMPAT, XML_AUTOREVERSE):
+ case XML_ELEMENT(SMIL_SO52, XML_AUTOREVERSE):
+ {
+ bool bTemp;
+ if (::sax::Converter::convertBool( bTemp, aIter.toView() ))
+ mxNode->setAutoReverse( bTemp );
+ }
+ break;
+ case XML_ELEMENT(SMIL, XML_REPEATCOUNT):
+ case XML_ELEMENT(SMIL_COMPAT, XML_REPEATCOUNT):
+ case XML_ELEMENT(SMIL_SO52, XML_REPEATCOUNT):
+ {
+ mxNode->setRepeatCount( mpHelper->convertTiming( aIter.toString() ) );
+ }
+ break;
+ case XML_ELEMENT(SMIL, XML_REPEATDUR):
+ case XML_ELEMENT(SMIL_COMPAT, XML_REPEATDUR):
+ case XML_ELEMENT(SMIL_SO52, XML_REPEATDUR):
+ {
+ mxNode->setRepeatDuration( mpHelper->convertTiming( aIter.toString() ) );
+ }
+ break;
+ case XML_ELEMENT(SMIL, XML_ENDSYNC):
+ case XML_ELEMENT(SMIL_COMPAT, XML_ENDSYNC):
+ case XML_ELEMENT(SMIL_SO52, XML_ENDSYNC):
+ {
+ if( SvXMLUnitConverter::convertEnum( nEnum, aIter.toView(), aAnimations_EnumMap_Endsync ) )
+ mxNode->setEndSync( Any( nEnum ) );
+ }
+ break;
+ case XML_ELEMENT(PRESENTATION, XML_NODE_TYPE):
+ case XML_ELEMENT(PRESENTATION_SO52, XML_NODE_TYPE):
+ case XML_ELEMENT(PRESENTATION_OOO, XML_NODE_TYPE):
+ case XML_ELEMENT(PRESENTATION_OASIS, XML_NODE_TYPE):
+ {
+ if( SvXMLUnitConverter::convertEnum( nEnum, aIter.toView(), aAnimations_EnumMap_EffectNodeType ) )
+ aUserData.emplace_back( GetXMLToken( XML_NODE_TYPE ), Any( nEnum ) );
+ }
+ break;
+ case XML_ELEMENT(PRESENTATION, XML_PRESET_ID):
+ case XML_ELEMENT(PRESENTATION_SO52, XML_PRESET_ID):
+ case XML_ELEMENT(PRESENTATION_OOO, XML_PRESET_ID):
+ case XML_ELEMENT(PRESENTATION_OASIS, XML_PRESET_ID):
+ {
+ aUserData.emplace_back( GetXMLToken( XML_PRESET_ID ), Any( aIter.toString() ) );
+ }
+ break;
+ case XML_ELEMENT(PRESENTATION, XML_PRESET_SUB_TYPE):
+ case XML_ELEMENT(PRESENTATION_SO52, XML_PRESET_SUB_TYPE):
+ case XML_ELEMENT(PRESENTATION_OOO, XML_PRESET_SUB_TYPE):
+ case XML_ELEMENT(PRESENTATION_OASIS, XML_PRESET_SUB_TYPE):
+ {
+ aUserData.emplace_back( GetXMLToken( XML_PRESET_SUB_TYPE ), Any( aIter.toString() ) );
+ }
+ break;
+ case XML_ELEMENT(PRESENTATION, XML_PRESET_CLASS):
+ case XML_ELEMENT(PRESENTATION_SO52, XML_PRESET_CLASS):
+ case XML_ELEMENT(PRESENTATION_OOO, XML_PRESET_CLASS):
+ case XML_ELEMENT(PRESENTATION_OASIS, XML_PRESET_CLASS):
+ {
+ if( SvXMLUnitConverter::convertEnum( nEnum, aIter.toView(), aAnimations_EnumMap_EffectPresetClass ) )
+ aUserData.emplace_back( GetXMLToken( XML_PRESET_CLASS ), Any( nEnum ) );
+ }
+ break;
+ case XML_ELEMENT(PRESENTATION, XML_AFTER_EFFECT):
+ case XML_ELEMENT(PRESENTATION_SO52, XML_AFTER_EFFECT):
+ case XML_ELEMENT(PRESENTATION_OOO, XML_AFTER_EFFECT):
+ {
+ bool bTemp;
+ if (::sax::Converter::convertBool( bTemp, aIter.toView() ))
+ aUserData.emplace_back( GetXMLToken( XML_AFTER_EFFECT ), Any( bTemp ) );
+ }
+ break;
+ case XML_ELEMENT(XLINK, XML_HREF):
+ {
+ if( nNodeType == AnimationNodeType::AUDIO )
+ {
+ Reference< XAudio > xAudio( mxNode, UNO_QUERY_THROW );
+ xAudio->setSource( Any(lcl_GetMediaReference(GetImport(), aIter.toString())) );
+ break;
+ }
+ [[fallthrough]];
+ }
+ case XML_ELEMENT(SMIL, XML_TARGETELEMENT):
+ case XML_ELEMENT(SMIL_COMPAT, XML_TARGETELEMENT):
+ case XML_ELEMENT(SMIL_SO52, XML_TARGETELEMENT):
+ {
+ Any aTarget( mpHelper->convertTarget( aIter.toString() ) );
+
+ if( xAnimate.is() )
+ {
+ xAnimate->setTarget( aTarget );
+ }
+ else if( xIter.is() )
+ {
+ xIter->setTarget( aTarget );
+ }
+ else if( xCommand.is() )
+ {
+ xCommand->setTarget( aTarget );
+ }
+ }
+ break;
+
+ case XML_ELEMENT(ANIMATION, XML_AUDIO_LEVEL):
+ case XML_ELEMENT(ANIMATION_OOO, XML_AUDIO_LEVEL):
+ {
+ if( nNodeType == AnimationNodeType::AUDIO )
+ {
+ if( isDouble( aIter.toView() ) )
+ {
+ Reference< XAudio > xAudio( mxNode, UNO_QUERY_THROW );
+ xAudio->setVolume( aIter.toDouble() );
+ }
+ }
+ }
+ break;
+
+ case XML_ELEMENT(PRESENTATION, XML_MASTER_ELEMENT):
+ case XML_ELEMENT(PRESENTATION_SO52, XML_MASTER_ELEMENT):
+ case XML_ELEMENT(PRESENTATION_OOO, XML_MASTER_ELEMENT):
+ {
+ Reference< XAnimationNode > xMaster( GetImport().getInterfaceToIdentifierMapper().getReference( aIter.toString() ), UNO_QUERY );
+ aUserData.emplace_back( GetXMLToken( XML_MASTER_ELEMENT ), Any( xMaster ) );
+ }
+ break;
+
+ case XML_ELEMENT(ANIMATION, XML_SUB_ITEM):
+ case XML_ELEMENT(ANIMATION_OOO, XML_SUB_ITEM):
+ {
+ if( SvXMLUnitConverter::convertEnum( nEnum, aIter.toView(), aAnimations_EnumMap_SubItem ) )
+ {
+ if( xAnimate.is() )
+ {
+ xAnimate->setSubItem( nEnum );
+ }
+ else if( xIter.is() )
+ {
+ xIter->setSubItem( nEnum );
+ }
+ }
+ }
+ break;
+
+ case XML_ELEMENT(SMIL, XML_ATTRIBUTENAME):
+ case XML_ELEMENT(SMIL_COMPAT, XML_ATTRIBUTENAME):
+ case XML_ELEMENT(SMIL_SO52, XML_ATTRIBUTENAME):
+ {
+ if( xAnimate.is() )
+ {
+ OUString aName( aIter.toString() );
+
+ const struct ImplAttributeNameConversion* p = getAnimationAttributeNamesConversionList();
+ while( p->mpAPIName )
+ {
+ if( IsXMLToken( aIter, p->meXMLToken ) )
+ {
+ aName = OUString::createFromAscii( p->mpAPIName );
+ meAttributeName = p->meXMLToken;
+ break;
+ }
+
+ p++;
+ }
+
+ xAnimate->setAttributeName( aName );
+ }
+ }
+ break;
+
+ case XML_ELEMENT(SMIL, XML_VALUES):
+ case XML_ELEMENT(SMIL_COMPAT, XML_VALUES):
+ case XML_ELEMENT(SMIL_SO52, XML_VALUES):
+ {
+ aValues = aIter.toString();
+ }
+ break;
+
+ case XML_ELEMENT(SMIL, XML_FROM):
+ case XML_ELEMENT(SMIL_COMPAT, XML_FROM):
+ case XML_ELEMENT(SMIL_SO52, XML_FROM):
+ {
+ aFrom = aIter.toString();
+ }
+ break;
+
+ case XML_ELEMENT(SMIL, XML_BY):
+ case XML_ELEMENT(SMIL_COMPAT, XML_BY):
+ case XML_ELEMENT(SMIL_SO52, XML_BY):
+ {
+ aBy = aIter.toString();
+ }
+ break;
+
+ case XML_ELEMENT(SMIL, XML_TO):
+ case XML_ELEMENT(SMIL_COMPAT, XML_TO):
+ case XML_ELEMENT(SMIL_SO52, XML_TO):
+ {
+ aTo = aIter.toString();
+ }
+ break;
+
+ case XML_ELEMENT(SMIL, XML_KEYTIMES):
+ case XML_ELEMENT(SMIL_COMPAT, XML_KEYTIMES):
+ case XML_ELEMENT(SMIL_SO52, XML_KEYTIMES):
+ {
+ if( xAnimate.is() )
+ xAnimate->setKeyTimes( AnimationsImportHelperImpl::convertKeyTimes( aIter.toView() ) );
+ }
+ break;
+
+ case XML_ELEMENT(ANIMATION, XML_FORMULA):
+ case XML_ELEMENT(ANIMATION_OOO, XML_FORMULA):
+ {
+ if( xAnimate.is() )
+ xAnimate->setFormula( aIter.toString() );
+ }
+ break;
+
+ case XML_ELEMENT(ANIMATION, XML_ID):
+ case XML_ELEMENT(ANIMATION_OOO, XML_ID):
+ {
+ if (!bHaveXmlId) { sXmlId = aIter.toString(); }
+ }
+ break;
+ case XML_ELEMENT(XML, XML_ID):
+ {
+ sXmlId = aIter.toString();
+ bHaveXmlId = true;
+ }
+ break;
+
+ case XML_ELEMENT(SMIL, XML_CALCMODE):
+ case XML_ELEMENT(SMIL_COMPAT, XML_CALCMODE):
+ case XML_ELEMENT(SMIL_SO52, XML_CALCMODE):
+ {
+ if( xAnimate.is() )
+ {
+ if( SvXMLUnitConverter::convertEnum( nEnum, aIter.toView(), aAnimations_EnumMap_CalcMode ) )
+ xAnimate->setCalcMode( nEnum );
+ }
+ }
+ break;
+
+ case XML_ELEMENT(SMIL, XML_ACCUMULATE):
+ case XML_ELEMENT(SMIL_COMPAT, XML_ACCUMULATE):
+ case XML_ELEMENT(SMIL_SO52, XML_ACCUMULATE):
+ {
+ if( xAnimate.is() )
+ xAnimate->setAccumulate( IsXMLToken( aIter, XML_SUM ) );
+ }
+ break;
+
+ case XML_ELEMENT(PRESENTATION, XML_ADDITIVE):
+ case XML_ELEMENT(PRESENTATION_SO52, XML_ADDITIVE):
+ case XML_ELEMENT(PRESENTATION_OOO, XML_ADDITIVE):
+ case XML_ELEMENT(SMIL, XML_ADDITIVE):
+ case XML_ELEMENT(SMIL_COMPAT, XML_ADDITIVE):
+ case XML_ELEMENT(SMIL_SO52, XML_ADDITIVE):
+ {
+ if( xAnimate.is() )
+ {
+ if( SvXMLUnitConverter::convertEnum( nEnum, aIter.toView(), aAnimations_EnumMap_AdditiveMode ) )
+ xAnimate->setAdditive( nEnum );
+ }
+ }
+ break;
+
+ case XML_ELEMENT(SMIL, XML_KEYSPLINES):
+ case XML_ELEMENT(SMIL_COMPAT, XML_KEYSPLINES):
+ case XML_ELEMENT(SMIL_SO52, XML_KEYSPLINES):
+ {
+ if( xAnimate.is() )
+ xAnimate->setTimeFilter( AnimationsImportHelperImpl::convertTimeFilter( aIter.toView() ) );
+ }
+ break;
+
+ case XML_ELEMENT(SVG, XML_PATH):
+ case XML_ELEMENT(SVG_COMPAT, XML_PATH):
+ {
+ Reference< XAnimateMotion > xAnimateMotion( mxNode, UNO_QUERY );
+ if( xAnimateMotion.is() )
+ xAnimateMotion->setPath( AnimationsImportHelperImpl::convertPath( aIter.toString() ) );
+ }
+ break;
+
+ case XML_ELEMENT(ANIMATION, XML_PHYSICS_ANIMATION_START_VELOCITY_X):
+ case XML_ELEMENT(ANIMATION_OOO, XML_PHYSICS_ANIMATION_START_VELOCITY_X):
+ case XML_ELEMENT(LO_EXT, XML_PHYSICS_ANIMATION_START_VELOCITY_X):
+ {
+ Reference< XAnimatePhysics > xAnimatePhysics( mxNode, UNO_QUERY );
+ if( xAnimatePhysics.is() )
+ xAnimatePhysics->setStartVelocityX( Any(aIter.toDouble()) );
+ }
+ break;
+
+ case XML_ELEMENT(ANIMATION, XML_PHYSICS_ANIMATION_START_VELOCITY_Y):
+ case XML_ELEMENT(ANIMATION_OOO, XML_PHYSICS_ANIMATION_START_VELOCITY_Y):
+ case XML_ELEMENT(LO_EXT, XML_PHYSICS_ANIMATION_START_VELOCITY_Y):
+ {
+ Reference< XAnimatePhysics > xAnimatePhysics( mxNode, UNO_QUERY );
+ if( xAnimatePhysics.is() )
+ xAnimatePhysics->setStartVelocityY( Any(aIter.toDouble()) );
+ }
+ break;
+
+ case XML_ELEMENT(ANIMATION, XML_PHYSICS_ANIMATION_DENSITY):
+ case XML_ELEMENT(ANIMATION_OOO, XML_PHYSICS_ANIMATION_DENSITY):
+ case XML_ELEMENT(LO_EXT, XML_PHYSICS_ANIMATION_DENSITY):
+ {
+ Reference< XAnimatePhysics > xAnimatePhysics( mxNode, UNO_QUERY );
+ if( xAnimatePhysics.is() )
+ xAnimatePhysics->setDensity( Any(aIter.toDouble()) );
+ }
+ break;
+
+ case XML_ELEMENT(ANIMATION, XML_PHYSICS_ANIMATION_BOUNCINESS):
+ case XML_ELEMENT(ANIMATION_OOO, XML_PHYSICS_ANIMATION_BOUNCINESS):
+ case XML_ELEMENT(LO_EXT, XML_PHYSICS_ANIMATION_BOUNCINESS):
+ {
+ Reference< XAnimatePhysics > xAnimatePhysics( mxNode, UNO_QUERY );
+ if( xAnimatePhysics.is() )
+ xAnimatePhysics->setBounciness( Any(aIter.toDouble()) );
+ }
+ break;
+
+ case XML_ELEMENT(ANIMATION, XML_COLOR_INTERPOLATION):
+ case XML_ELEMENT(ANIMATION_OOO, XML_COLOR_INTERPOLATION):
+ {
+ Reference< XAnimateColor > xAnimateColor( mxNode, UNO_QUERY );
+ if( xAnimateColor.is() )
+ xAnimateColor->setColorInterpolation( IsXMLToken( aIter, XML_HSL ) ? AnimationColorSpace::HSL : AnimationColorSpace::RGB );
+ }
+ break;
+
+ case XML_ELEMENT(ANIMATION, XML_COLOR_INTERPOLATION_DIRECTION):
+ case XML_ELEMENT(ANIMATION_OOO, XML_COLOR_INTERPOLATION_DIRECTION):
+ {
+ Reference< XAnimateColor > xAnimateColor( mxNode, UNO_QUERY );
+ if( xAnimateColor.is() )
+ xAnimateColor->setDirection( IsXMLToken( aIter, XML_CLOCKWISE ) );
+ }
+ break;
+
+ case XML_ELEMENT(SVG, XML_TYPE):
+ case XML_ELEMENT(SVG_COMPAT, XML_TYPE):
+ {
+ Reference< XAnimateTransform > xTransform( mxNode, UNO_QUERY );
+ if( xTransform.is() )
+ {
+ if( SvXMLUnitConverter::convertEnum( nEnum, aIter.toView(), aAnimations_EnumMap_TransformType ) )
+ {
+ xTransform->setTransformType( nEnum );
+ switch( nEnum )
+ {
+ case AnimationTransformType::SCALE: meAttributeName = XML_SCALE; break;
+ case AnimationTransformType::ROTATE: meAttributeName = XML_ROTATE; break;
+ case AnimationTransformType::SKEWX: meAttributeName = XML_SKEWX; break;
+ case AnimationTransformType::SKEWY: meAttributeName = XML_SKEWY; break;
+ //case AnimationTransformType::TRANSLATE:
+ default:
+ meAttributeName = XML_TRANSLATE; break;
+ }
+ }
+ }
+ }
+ break;
+
+ case XML_ELEMENT(SMIL, XML_TYPE):
+ case XML_ELEMENT(SMIL_COMPAT, XML_TYPE):
+ case XML_ELEMENT(SMIL_SO52, XML_TYPE):
+ {
+ if( xTransitionFilter.is() )
+ {
+ if( SvXMLUnitConverter::convertEnum( nEnum, aIter.toView(), aAnimations_EnumMap_TransitionType ) )
+ xTransitionFilter->setTransition( nEnum );
+ }
+ }
+ break;
+
+ case XML_ELEMENT(SMIL, XML_SUBTYPE):
+ case XML_ELEMENT(SMIL_COMPAT, XML_SUBTYPE):
+ case XML_ELEMENT(SMIL_SO52, XML_SUBTYPE):
+ {
+ if( xTransitionFilter.is() )
+ {
+ if( SvXMLUnitConverter::convertEnum( nEnum, aIter.toView(), aAnimations_EnumMap_TransitionSubType ) )
+ xTransitionFilter->setSubtype( nEnum );
+ }
+ }
+ break;
+
+ case XML_ELEMENT(SMIL, XML_MODE):
+ case XML_ELEMENT(SMIL_COMPAT, XML_MODE):
+ case XML_ELEMENT(SMIL_SO52, XML_MODE):
+ {
+ if( xTransitionFilter.is() )
+ xTransitionFilter->setMode( IsXMLToken( aIter, XML_IN ) );
+ }
+ break;
+
+ case XML_ELEMENT(SMIL, XML_DIRECTION):
+ case XML_ELEMENT(SMIL_COMPAT, XML_DIRECTION):
+ case XML_ELEMENT(SMIL_SO52, XML_DIRECTION):
+ {
+ if( xTransitionFilter.is() )
+ xTransitionFilter->setDirection( IsXMLToken( aIter, XML_FORWARD ) );
+ }
+ break;
+
+ case XML_ELEMENT(SMIL, XML_FADECOLOR):
+ case XML_ELEMENT(SMIL_COMPAT, XML_FADECOLOR):
+ case XML_ELEMENT(SMIL_SO52, XML_FADECOLOR):
+ {
+ if( xTransitionFilter.is() )
+ {
+ sal_Int32 nColor(0);
+ ::sax::Converter::convertColor(nColor, aIter.toView());
+ xTransitionFilter->setFadeColor(nColor);
+ }
+ }
+ break;
+
+ case XML_ELEMENT(ANIMATION, XML_ITERATE_TYPE):
+ case XML_ELEMENT(ANIMATION_OOO, XML_ITERATE_TYPE):
+ {
+ if( SvXMLUnitConverter::convertEnum( nEnum, aIter.toView(), aAnimations_EnumMap_IterateType ) )
+ {
+ if( xIter.is() )
+ xIter->setIterateType( nEnum );
+ }
+ }
+ break;
+
+ case XML_ELEMENT(ANIMATION, XML_ITERATE_INTERVAL):
+ case XML_ELEMENT(ANIMATION_OOO, XML_ITERATE_INTERVAL):
+ {
+ if( xIter.is() )
+ {
+ OUString rValue = aIter.toString();
+ double fInterval = 0.0;
+ if( rValue.match("P") )
+ {
+ css::util::Duration aDuration;
+ if (::sax::Converter::convertDuration(aDuration, rValue))
+ {
+ fInterval = ((((aDuration.Hours * 60)
+ + aDuration.Minutes) * 60) + aDuration.Seconds)
+ + (aDuration.NanoSeconds / 1000000000.0);
+ }
+ }
+ else
+ {
+ fInterval = aIter.toDouble();
+ }
+
+ xIter->setIterateInterval( fInterval );
+ }
+ }
+ break;
+
+ case XML_ELEMENT(PRESENTATION, XML_GROUP_ID):
+ case XML_ELEMENT(PRESENTATION_SO52, XML_GROUP_ID):
+ case XML_ELEMENT(PRESENTATION_OOO, XML_GROUP_ID):
+ {
+ aUserData.emplace_back( "group-id", Any( aIter.toInt32() ) );
+ }
+ break;
+
+ case XML_ELEMENT(ANIMATION, XML_COMMAND):
+ case XML_ELEMENT(ANIMATION_OOO, XML_COMMAND):
+ {
+ if( xCommand.is() && nNodeType == AnimationNodeType::COMMAND )
+ {
+ if( SvXMLUnitConverter::convertEnum( nEnum, aIter.toView(), aAnimations_EnumMap_Command ) )
+ {
+ xCommand->setCommand( nEnum );
+ }
+ }
+ }
+ break;
+
+ default:
+ {
+ // push all unknown attributes within the presentation namespace as user data
+ if (IsTokenInNamespace(nToken, XML_NAMESPACE_PRESENTATION)
+ || IsTokenInNamespace(nToken, XML_NAMESPACE_PRESENTATION_SO52)
+ || IsTokenInNamespace(nToken, XML_NAMESPACE_PRESENTATION_OASIS)
+ || IsTokenInNamespace(nToken, XML_NAMESPACE_PRESENTATION_OOO))
+ {
+ aUserData.emplace_back( SvXMLImport::getNameFromToken(aIter.getToken()), Any( aIter.toString() ) );
+ }
+ else
+ XMLOFF_WARN_UNKNOWN("xmloff", aIter);
+ }
+ }
+ }
+
+ if (!sXmlId.isEmpty())
+ {
+ Reference< XInterface > const xRef( mxNode, UNO_QUERY );
+ GetImport().getInterfaceToIdentifierMapper().registerReference(
+ sXmlId, xRef );
+ }
+
+ sal_Int32 nUserDataCount = aUserData.size();
+ if( nUserDataCount )
+ {
+ Sequence< NamedValue > aUnoUserData( nUserDataCount );
+ NamedValue* pData = aUnoUserData.getArray();
+ for (auto const& item : aUserData)
+ *pData++ = item;
+
+ mxNode->setUserData( aUnoUserData );
+ }
+
+ // convert values
+ if( xAnimate.is() )
+ {
+ if( !aFrom.isEmpty() )
+ xAnimate->setFrom( mpHelper->convertValue( meAttributeName, aFrom ) );
+
+ if( !aBy.isEmpty() )
+ xAnimate->setBy( mpHelper->convertValue( meAttributeName, aBy ) );
+
+ if( !aTo.isEmpty() )
+ xAnimate->setTo( mpHelper->convertValue( meAttributeName, aTo ) );
+
+ if( !aValues.isEmpty() )
+ xAnimate->setValues( mpHelper->convertValueSequence( meAttributeName, aValues ) );
+
+ if (xAnimate->getValues().getLength() != xAnimate->getKeyTimes().getLength())
+ throw css::io::WrongFormatException();
+ }
+ }
+ catch (const css::io::WrongFormatException&)
+ {
+ throw;
+ }
+ catch (const RuntimeException&)
+ {
+ TOOLS_WARN_EXCEPTION("xmloff.draw", "");
+ }
+}
+
+css::uno::Reference< css::xml::sax::XFastContextHandler > AnimationNodeContext::createFastChildContext(sal_Int32 nElement,
+ const css::uno::Reference<css::xml::sax::XFastAttributeList>& xAttrList)
+{
+ if( mxNode.is())
+ return new AnimationNodeContext( mxNode, GetImport(), nElement, xAttrList, mpHelper );
+ return nullptr;
+}
+
+namespace {
+
+class AnimationsImport: public SvXMLImport, public XAnimationNodeSupplier
+{
+public:
+ explicit AnimationsImport( const Reference< XComponentContext > & rxContext );
+
+ SvXMLImportContext* CreateFastContext(sal_Int32 nElement,
+ const Reference<XFastAttributeList>& xAttrList) override;
+
+ // XInterface
+ virtual Any SAL_CALL queryInterface( const Type& aType ) override;
+ virtual void SAL_CALL acquire() noexcept override;
+ virtual void SAL_CALL release() noexcept override;
+
+ // XAnimationNodeSupplier
+ Reference< XAnimationNode > SAL_CALL getAnimationNode() override;
+
+private:
+ Reference< XAnimationNode > mxRootNode;
+};
+
+}
+
+AnimationsImport::AnimationsImport( const Reference< XComponentContext > & rxContext )
+: SvXMLImport( rxContext, "xmloff::AnimationsImport", SvXMLImportFlags::META )
+ //FIXME: the above "IMPORT_META" used to be a nonsensical "true", question
+ // remains whether this should be IMPORT_META (same numerical value as
+ // true) or default IMPORT_ALL
+{
+ mxRootNode.set( SequenceTimeContainer::create(rxContext), UNO_QUERY_THROW );
+}
+
+// XInterface
+Any SAL_CALL AnimationsImport::queryInterface( const Type& aType )
+{
+ if ( aType == cppu::UnoType<XAnimationNodeSupplier>::get())
+ {
+ return Any( Reference<XAnimationNodeSupplier>( this ) );
+ }
+ else
+ {
+ return SvXMLImport::queryInterface( aType );
+ }
+}
+
+void SAL_CALL AnimationsImport::acquire() noexcept
+{
+ SvXMLImport::acquire();
+}
+
+void SAL_CALL AnimationsImport::release() noexcept
+{
+ SvXMLImport::release();
+}
+
+SvXMLImportContext *AnimationsImport::CreateFastContext(
+ sal_Int32 nElement,
+ const Reference<XFastAttributeList>& xAttrList)
+{
+ SvXMLImportContext* pContext = nullptr;
+
+ if( nElement == XML_ELEMENT(ANIMATION, XML_SEQ) || nElement == XML_ELEMENT(ANIMATION_OOO, XML_SEQ) )
+ {
+ pContext = new AnimationNodeContext( mxRootNode, *this, nElement, xAttrList );
+ }
+
+ return pContext;
+}
+
+// XAnimationNodeSupplier
+Reference< XAnimationNode > SAL_CALL AnimationsImport::getAnimationNode()
+{
+ return mxRootNode;
+}
+
+void AnimationNodeContext::postProcessRootNode( const Reference< XAnimationNode >& xRootNode, Reference< XPropertySet > const & xPageProps )
+{
+ if( !(xRootNode.is() && xPageProps.is()) )
+ return;
+
+ try
+ {
+ Reference< XEnumerationAccess > xEnumerationAccess( xRootNode, UNO_QUERY_THROW );
+ Reference< XEnumeration > xEnumeration( xEnumerationAccess->createEnumeration(), UNO_SET_THROW );
+ if( xEnumeration->hasMoreElements() )
+ {
+ Reference< XAnimationNode > xNode( xEnumeration->nextElement(), UNO_QUERY_THROW );
+ if( xNode->getType() == AnimationNodeType::PAR )
+ {
+ Event aEvent;
+ if( (xNode->getBegin() >>= aEvent) && (aEvent.Trigger == EventTrigger::BEGIN_EVENT) )
+ {
+ // found transition node
+ Reference< XEnumerationAccess > xChildEnumerationAccess( xNode, UNO_QUERY_THROW );
+ Reference< XEnumeration > xChildEnumeration( xChildEnumerationAccess->createEnumeration(), UNO_SET_THROW );
+ while( xChildEnumeration->hasMoreElements() )
+ {
+ Reference< XAnimationNode > xChildNode( xChildEnumeration->nextElement(), UNO_QUERY_THROW );
+ switch( xChildNode->getType() )
+ {
+ case AnimationNodeType::TRANSITIONFILTER:
+ {
+ Reference< XTransitionFilter > xTransFilter( xChildNode, UNO_QUERY_THROW );
+
+ xPageProps->setPropertyValue("TransitionType", Any( xTransFilter->getTransition() ) );
+ xPageProps->setPropertyValue("TransitionSubtype", Any( xTransFilter->getSubtype() ) );
+ xPageProps->setPropertyValue("TransitionDirection", Any( xTransFilter->getDirection() ) );
+ xPageProps->setPropertyValue("TransitionFadeColor", Any( xTransFilter->getFadeColor() ) );
+
+ double fDuration;
+ if( xTransFilter->getDuration() >>= fDuration )
+ xPageProps->setPropertyValue("TransitionDuration", Any( fDuration ) );
+
+ }
+ break;
+
+ case AnimationNodeType::COMMAND:
+ {
+ Reference< XCommand > xCommand( xChildNode, UNO_QUERY_THROW );
+ if( xCommand->getCommand() == EffectCommands::STOPAUDIO )
+ {
+ xPageProps->setPropertyValue("Sound", Any(true) );
+ }
+ }
+ break;
+
+ case AnimationNodeType::AUDIO:
+ {
+ Reference< XAudio > xAudio( xChildNode, UNO_QUERY_THROW );
+ OUString sSoundURL;
+ if( (xAudio->getSource() >>= sSoundURL) && !sSoundURL.isEmpty() )
+ {
+ xPageProps->setPropertyValue("Sound", Any(sSoundURL) );
+
+ Timing eTiming;
+ if( (xAudio->getRepeatCount() >>= eTiming) && (eTiming == Timing_INDEFINITE) )
+ xPageProps->setPropertyValue("LoopSound", Any( true ) );
+ }
+ }
+ break;
+
+ }
+ }
+
+ Reference< XTimeContainer > xRootContainer( xRootNode, UNO_QUERY_THROW );
+ xRootContainer->removeChild( xNode );
+ }
+ }
+ }
+ }
+ catch (const Exception&)
+ {
+ TOOLS_WARN_EXCEPTION("xmloff.draw", "");
+ }
+}
+
+} // namespace xmloff
+
+extern "C" SAL_DLLPUBLIC_EXPORT uno::XInterface*
+com_sun_star_comp_Xmloff_AnimationsImport(uno::XComponentContext* pCtx,
+ uno::Sequence<uno::Any> const& /*rSeq*/)
+{
+ return cppu::acquire(new xmloff::AnimationsImport(pCtx));
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/xmloff/source/draw/animexp.cxx b/xmloff/source/draw/animexp.cxx
new file mode 100644
index 0000000000..0c78f4f1d8
--- /dev/null
+++ b/xmloff/source/draw/animexp.cxx
@@ -0,0 +1,511 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+
+#include <com/sun/star/beans/XPropertySet.hpp>
+#include <com/sun/star/drawing/XShape.hpp>
+#include <com/sun/star/lang/XServiceInfo.hpp>
+#include <com/sun/star/presentation/AnimationSpeed.hpp>
+#include <xmloff/unointerfacetouniqueidentifiermapper.hxx>
+
+#include <sax/tools/converter.hxx>
+#include <sal/log.hxx>
+#include <comphelper/diagnose_ex.hxx>
+
+#include <list>
+#include <comphelper/extract.hxx>
+#include <xmloff/xmltoken.hxx>
+#include <xmloff/xmlnamespace.hxx>
+#include <xmloff/xmluconv.hxx>
+#include <xmloff/xmlexp.hxx>
+#include <anim.hxx>
+
+
+using namespace ::cppu;
+using namespace ::com::sun::star;
+using namespace ::com::sun::star::uno;
+using namespace ::com::sun::star::drawing;
+using namespace ::com::sun::star::beans;
+using namespace ::com::sun::star::lang;
+using namespace ::com::sun::star::presentation;
+using namespace ::xmloff::token;
+
+namespace {
+
+struct Effect
+{
+ XMLEffect meKind;
+ XMLEffectDirection meDirection;
+ sal_Int16 mnStartScale;
+ bool mbIn;
+};
+
+}
+
+const Effect AnimationEffectMap[] =
+{
+ { EK_none, ED_none, -1, true }, // AnimationEffect_NONE
+ { EK_fade, ED_from_left, -1, true }, // AnimationEffect_FADE_FROM_LEFT
+ { EK_fade, ED_from_top, -1, true }, // AnimationEffect_FADE_FROM_TOP
+ { EK_fade, ED_from_right, -1, true }, // AnimationEffect_FADE_FROM_RIGHT
+ { EK_fade, ED_from_bottom, -1, true }, // AnimationEffect_FADE_FROM_BOTTOM
+ { EK_fade, ED_to_center, -1, true }, // AnimationEffect_FADE_TO_CENTER
+ { EK_fade, ED_from_center, -1, true }, // AnimationEffect_FADE_FROM_CENTER
+ { EK_move, ED_from_left, -1, true }, // AnimationEffect_MOVE_FROM_LEFT
+ { EK_move, ED_from_top, -1, true }, // AnimationEffect_MOVE_FROM_TOP
+ { EK_move, ED_from_right, -1, true }, // AnimationEffect_MOVE_FROM_RIGHT
+ { EK_move, ED_from_bottom, -1, true }, // AnimationEffect_MOVE_FROM_BOTTOM
+ { EK_stripes, ED_vertical, -1, true }, // AnimationEffect_VERTICAL_STRIPES
+ { EK_stripes, ED_horizontal, -1, true }, // AnimationEffect_HORIZONTAL_STRIPES
+ { EK_fade, ED_clockwise, -1, true }, // AnimationEffect_CLOCKWISE
+ { EK_fade, ED_cclockwise, -1, true }, // AnimationEffect_COUNTERCLOCKWISE
+ { EK_fade, ED_from_upperleft, -1, true }, // AnimationEffect_FADE_FROM_UPPERLEFT
+ { EK_fade, ED_from_upperright, -1, true }, // AnimationEffect_FADE_FROM_UPPERRIGHT
+ { EK_fade, ED_from_lowerleft, -1, true }, // AnimationEffect_FADE_FROM_LOWERLEFT
+ { EK_fade, ED_from_lowerright, -1, true }, // AnimationEffect_FADE_FROM_LOWERRIGHT
+ { EK_close,ED_vertical, -1, true }, // AnimationEffect_CLOSE_VERTICAL
+ { EK_close,ED_horizontal, -1, true }, // AnimationEffect_CLOSE_HORIZONTAL
+ { EK_open, ED_vertical, -1, true }, // AnimationEffect_OPEN_VERTICAL
+ { EK_open, ED_horizontal, -1, true }, // AnimationEffect_OPEN_HORIZONTAL
+ { EK_move, ED_path, -1, true }, // AnimationEffect_PATH
+ { EK_move, ED_to_left, -1, false },// AnimationEffect_MOVE_TO_LEFT
+ { EK_move, ED_to_top, -1, false },// AnimationEffect_MOVE_TO_TOP
+ { EK_move, ED_to_right, -1, false },// AnimationEffect_MOVE_TO_RIGHT
+ { EK_move, ED_to_bottom, -1, false },// AnimationEffect_MOVE_TO_BOTTOM
+ { EK_fade, ED_spiral_inward_left, -1, true }, // AnimationEffect_SPIRALIN_LEFT
+ { EK_fade, ED_spiral_inward_right, -1, true }, // AnimationEffect_SPIRALIN_RIGHT
+ { EK_fade, ED_spiral_outward_left, -1, true }, // AnimationEffect_SPIRALOUT_LEFT
+ { EK_fade, ED_spiral_outward_right, -1, true }, // AnimationEffect_SPIRALOUT_RIGHT
+ { EK_dissolve, ED_none, -1, true }, // AnimationEffect_DISSOLVE
+ { EK_wavyline, ED_from_left, -1, true }, // AnimationEffect_WAVYLINE_FROM_LEFT
+ { EK_wavyline, ED_from_top, -1, true }, // AnimationEffect_WAVYLINE_FROM_TOP
+ { EK_wavyline, ED_from_right, -1, true }, // AnimationEffect_WAVYLINE_FROM_RIGHT
+ { EK_wavyline, ED_from_bottom, -1, true }, // AnimationEffect_WAVYLINE_FROM_BOTTOM
+ { EK_random, ED_none, -1, true }, // AnimationEffect_RANDOM
+ { EK_lines, ED_vertical, -1, true }, // AnimationEffect_VERTICAL_LINES
+ { EK_lines, ED_horizontal, -1, true }, // AnimationEffect_HORIZONTAL_LINES
+ { EK_laser, ED_from_left, -1, true }, // AnimationEffect_LASER_FROM_LEFT
+ { EK_laser, ED_from_top, -1, true }, // AnimationEffect_LASER_FROM_TOP
+ { EK_laser, ED_from_right, -1, true }, // AnimationEffect_LASER_FROM_RIGHT
+ { EK_laser, ED_from_bottom, -1, true }, // AnimationEffect_LASER_FROM_BOTTOM
+ { EK_laser, ED_from_upperleft, -1, true }, // AnimationEffect_LASER_FROM_UPPERLEFT
+ { EK_laser, ED_from_upperright, -1, true }, // AnimationEffect_LASER_FROM_UPPERRIGHT
+ { EK_laser, ED_from_lowerleft, -1, true }, // AnimationEffect_LASER_FROM_LOWERLEFT
+ { EK_laser, ED_from_lowerright, -1, true }, // AnimationEffect_LASER_FROM_LOWERRIGHT
+ { EK_appear,ED_none, -1, true }, // AnimationEffect_APPEAR
+ { EK_hide, ED_none, -1, false },// AnimationEffect_HIDE
+ { EK_move, ED_from_upperleft, -1, true }, // AnimationEffect_MOVE_FROM_UPPERLEFT
+ { EK_move, ED_from_upperright, -1, true }, // AnimationEffect_MOVE_FROM_UPPERRIGHT
+ { EK_move, ED_from_lowerright, -1, true }, // AnimationEffect_MOVE_FROM_LOWERRIGHT
+ { EK_move, ED_from_lowerleft, -1, true }, // AnimationEffect_MOVE_FROM_LOWERLEFT
+ { EK_move, ED_to_upperleft, -1, false },// AnimationEffect_MOVE_TO_UPPERLEFT
+ { EK_move, ED_to_upperright, -1, false },// AnimationEffect_MOVE_TO_UPPERRIGHT
+ { EK_move, ED_to_lowerright, -1, false },// AnimationEffect_MOVE_TO_LOWERRIGHT
+ { EK_move, ED_to_lowerleft, -1, false },// AnimationEffect_MOVE_TO_LOWERLEFT
+ { EK_move_short, ED_from_left, -1, true }, // AnimationEffect_MOVE_SHORT_FROM_LEFT
+ { EK_move_short, ED_from_upperleft, -1, true }, // AnimationEffect_MOVE_SHORT_FROM_UPPERLEFT
+ { EK_move_short, ED_from_top, -1, true }, // AnimationEffect_MOVE_SHORT_FROM_TOP
+ { EK_move_short, ED_from_upperright,-1, true }, // AnimationEffect_MOVE_SHORT_FROM_UPPERRIGHT
+ { EK_move_short, ED_from_right, -1, true }, // AnimationEffect_MOVE_SHORT_FROM_RIGHT
+ { EK_move_short, ED_from_lowerright,-1, true }, // AnimationEffect_MOVE_SHORT_FROM_LOWERRIGHT
+ { EK_move_short, ED_from_bottom, -1, true }, // AnimationEffect_MOVE_SHORT_FROM_BOTTOM
+ { EK_move_short, ED_from_lowerleft, -1, true }, // AnimationEffect_MOVE_SHORT_FROM_LOWERLEFT
+ { EK_move_short, ED_to_left, -1, false },// AnimationEffect_MOVE_SHORT_TO_LEFT
+ { EK_move_short, ED_to_upperleft, -1, false },// AnimationEffect_MOVE_SHORT_TO_UPPERLEFT
+ { EK_move_short, ED_to_top, -1, false },// AnimationEffect_MOVE_SHORT_TO_TOP
+ { EK_move_short, ED_to_upperright, -1, false },// AnimationEffect_MOVE_SHORT_TO_UPPERRIGHT
+ { EK_move_short, ED_to_right, -1, false },// AnimationEffect_MOVE_SHORT_TO_RIGHT
+ { EK_move_short, ED_to_lowerright, -1, false },// AnimationEffect_MOVE_SHORT_TO_LOWERRIGHT
+ { EK_move_short, ED_to_bottom, -1, false },// AnimationEffect_MOVE_SHORT_TO_BOTTOM
+ { EK_move_short, ED_to_lowerleft, -1, false },// AnimationEffect_MOVE_SHORT_TO_LOWERLEFT
+ { EK_checkerboard, ED_vertical, -1, true }, // AnimationEffect_VERTICAL_CHECKERBOARD
+ { EK_checkerboard, ED_horizontal, -1, true }, // AnimationEffect_HORIZONTAL_CHECKERBOARD
+ { EK_rotate, ED_horizontal, -1, true }, // AnimationEffect_HORIZONTAL_ROTATE
+ { EK_rotate, ED_vertical, -1, true }, // AnimationEffect_VERTICAL_ROTATE
+ { EK_stretch,ED_horizontal, -1, true }, // AnimationEffect_HORIZONTAL_STRETCH
+ { EK_stretch,ED_vertical, -1, true }, // AnimationEffect_VERTICAL_STRETCH
+ { EK_stretch,ED_from_left, -1, true }, // AnimationEffect_STRETCH_FROM_LEFT
+ { EK_stretch,ED_from_upperleft, -1, true }, // AnimationEffect_STRETCH_FROM_UPPERLEFT
+ { EK_stretch,ED_from_top, -1, true }, // AnimationEffect_STRETCH_FROM_TOP
+ { EK_stretch,ED_from_upperright,-1, true }, // AnimationEffect_STRETCH_FROM_UPPERRIGHT
+ { EK_stretch,ED_from_right, -1, true }, // AnimationEffect_STRETCH_FROM_RIGHT
+ { EK_stretch,ED_from_lowerright,-1, true }, // AnimationEffect_STRETCH_FROM_LOWERRIGHT
+ { EK_stretch,ED_from_bottom, -1, true }, // AnimationEffect_STRETCH_FROM_BOTTOM
+ { EK_stretch,ED_from_lowerleft, -1, true }, // AnimationEffect_STRETCH_FROM_LOWERLEFT
+ { EK_move, ED_none, 0, true }, // AnimationEffect_ZOOM_IN
+ { EK_move, ED_none, 50, true }, // AnimationEffect_ZOOM_IN_SMALL
+ { EK_move, ED_spiral_inward_left, 0, true }, // AnimationEffect_ZOOM_IN_SPIRAL
+ { EK_move, ED_none, 400, true }, // AnimationEffect_ZOOM_OUT
+ { EK_move, ED_none, 200, true }, // AnimationEffect_ZOOM_OUT_SMALL
+ { EK_move, ED_spiral_inward_left, 400, true }, // AnimationEffect_ZOOM_OUT_SPIRAL
+ { EK_move, ED_from_left, 0, true }, // AnimationEffect_ZOOM_IN_FROM_LEFT
+ { EK_move, ED_from_upperleft, 0, true }, // AnimationEffect_ZOOM_IN_FROM_UPPERLEFT
+ { EK_move, ED_from_top, 0, true }, // AnimationEffect_ZOOM_IN_FROM_TOP
+ { EK_move, ED_from_upperright, 0, true }, // AnimationEffect_ZOOM_IN_FROM_UPPERRIGHT
+ { EK_move, ED_from_right, 0, true }, // AnimationEffect_ZOOM_IN_FROM_RIGHT
+ { EK_move, ED_from_lowerright, 0, true }, // AnimationEffect_ZOOM_IN_FROM_LOWERRIGHT
+ { EK_move, ED_from_bottom, 0, true }, // AnimationEffect_ZOOM_IN_FROM_BOTTOM
+ { EK_move, ED_from_lowerleft, 0, true }, // AnimationEffect_ZOOM_IN_FROM_LOWERLEFT
+ { EK_move, ED_from_center, 0, true }, // AnimationEffect_ZOOM_IN_FROM_CENTER
+ { EK_move, ED_from_left, 400, true }, // AnimationEffect_ZOOM_OUT_FROM_LEFT
+ { EK_move, ED_from_upperleft, 400, true }, // AnimationEffect_ZOOM_OUT_FROM_UPPERLEFT
+ { EK_move, ED_from_top, 400, true }, // AnimationEffect_ZOOM_OUT_FROM_TOP
+ { EK_move, ED_from_upperright,400, true }, // AnimationEffect_ZOOM_OUT_FROM_UPPERRIGHT
+ { EK_move, ED_from_right, 400, true }, // AnimationEffect_ZOOM_OUT_FROM_RIGHT
+ { EK_move, ED_from_lowerright,400, true }, // AnimationEffect_ZOOM_OUT_FROM_LOWERRIGHT
+ { EK_move, ED_from_bottom, 400, true }, // AnimationEffect_ZOOM_OUT_FROM_BOTTOM
+ { EK_move, ED_from_lowerleft, 400, true }, // AnimationEffect_ZOOM_OUT_FROM_LOWERLEFT
+ { EK_move, ED_from_center, 400, true } // AnimationEffect_ZOOM_OUT_FROM_CENTER
+};
+
+void SdXMLImplSetEffect( AnimationEffect eEffect, XMLEffect& eKind, XMLEffectDirection& eDirection, sal_Int16& nStartScale, bool& bIn )
+{
+ if( eEffect < AnimationEffect_NONE || eEffect > AnimationEffect_ZOOM_OUT_FROM_CENTER )
+ {
+ OSL_FAIL( "unknown animation effect!" );
+ eEffect = AnimationEffect_NONE;
+ }
+
+ const Effect& rEffect = AnimationEffectMap[static_cast<int>(eEffect)];
+ eKind = rEffect.meKind;
+ eDirection = rEffect.meDirection;
+ nStartScale = rEffect.mnStartScale;
+ bIn = rEffect.mbIn;
+}
+
+namespace {
+
+enum XMLActionKind : sal_Int8
+{
+ XMLE_SHOW,
+ XMLE_HIDE,
+ XMLE_DIM,
+ XMLE_PLAY
+};
+
+struct XMLEffectHint
+{
+ Reference<XShape> mxShape;
+ XMLActionKind meKind;
+ bool mbTextEffect;
+
+ XMLEffect meEffect;
+ XMLEffectDirection meDirection;
+ sal_Int16 mnStartScale;
+
+ AnimationSpeed meSpeed;
+ OUString maSoundURL;
+ sal_Int32 maDimColor;
+ sal_Int32 mnPresId;
+ bool mbPlayFull;
+
+ bool operator<(const XMLEffectHint& rComp) const { return mnPresId < rComp.mnPresId; }
+
+ XMLEffectHint()
+ : meKind( XMLE_SHOW ), mbTextEffect( false ),
+ meEffect( EK_none ), meDirection( ED_none ), mnStartScale( -1 ),
+ meSpeed( AnimationSpeed_SLOW ), maDimColor(0),
+ mnPresId( 0 ), mbPlayFull( false )
+ {}
+};
+
+}
+
+class AnimExpImpl
+{
+public:
+ std::list<XMLEffectHint> maEffects;
+
+ static constexpr OUString gsDimColor = u"DimColor"_ustr;
+ static constexpr OUString gsDimHide = u"DimHide"_ustr;
+ static constexpr OUString gsDimPrev = u"DimPrevious"_ustr;
+ static constexpr OUString gsEffect = u"Effect"_ustr;
+ static constexpr OUString gsPlayFull = u"PlayFull"_ustr;
+ static constexpr OUString gsPresOrder = u"PresentationOrder"_ustr;
+ static constexpr OUString gsSound = u"Sound"_ustr;
+ static constexpr OUString gsSoundOn = u"SoundOn"_ustr;
+ static constexpr OUString gsSpeed = u"Speed"_ustr;
+ static constexpr OUString gsTextEffect = u"TextEffect"_ustr;
+ static constexpr OUString gsIsAnimation = u"IsAnimation"_ustr;
+ static constexpr OUString gsAnimPath = u"AnimationPath"_ustr;
+};
+
+XMLAnimationsExporter::XMLAnimationsExporter()
+ : mpImpl( new AnimExpImpl )
+{
+}
+
+XMLAnimationsExporter::~XMLAnimationsExporter()
+{
+}
+
+void XMLAnimationsExporter::prepare( const Reference< XShape >& xShape )
+{
+ try
+ {
+ // check for presentation shape service
+ {
+ Reference< XServiceInfo > xServiceInfo( xShape, UNO_QUERY );
+ if( !xServiceInfo.is() || !xServiceInfo->supportsService("com.sun.star.presentation.Shape") )
+ return;
+ }
+
+ Reference< XPropertySet > xProps( xShape, UNO_QUERY );
+ if( xProps.is() )
+ {
+ AnimationEffect eEffect;
+ xProps->getPropertyValue( AnimExpImpl::gsEffect ) >>= eEffect;
+ if( eEffect == AnimationEffect_PATH )
+ {
+ Reference< XShape > xPath;
+ xProps->getPropertyValue( AnimExpImpl::gsAnimPath ) >>= xPath;
+ }
+ }
+ }
+ catch (const Exception&)
+ {
+ TOOLS_WARN_EXCEPTION("xmloff.draw",
+ "exception caught while collection animation information!");
+ }
+}
+
+void XMLAnimationsExporter::collect( const Reference< XShape >& xShape, SvXMLExport& rExport )
+{
+ try
+ {
+ // check for presentation shape service
+ {
+ Reference< XServiceInfo > xServiceInfo( xShape, UNO_QUERY );
+ if( !xServiceInfo.is() || !xServiceInfo->supportsService("com.sun.star.presentation.Shape") )
+ return;
+ }
+
+ Reference< XPropertySet > xProps( xShape, UNO_QUERY );
+ if( xProps.is() )
+ {
+ XMLEffectHint aEffect;
+
+ if( any2bool( xProps->getPropertyValue( AnimExpImpl::gsSoundOn ) ) )
+ {
+ xProps->getPropertyValue( AnimExpImpl::gsSound ) >>= aEffect.maSoundURL;
+ xProps->getPropertyValue( AnimExpImpl::gsPlayFull ) >>= aEffect.mbPlayFull;
+ }
+
+ xProps->getPropertyValue( AnimExpImpl::gsPresOrder ) >>= aEffect.mnPresId;
+ xProps->getPropertyValue( AnimExpImpl::gsSpeed ) >>= aEffect.meSpeed;
+
+
+ bool bIsAnimation = false;
+ xProps->getPropertyValue( AnimExpImpl::gsIsAnimation ) >>= bIsAnimation;
+ if( bIsAnimation )
+ {
+ aEffect.meKind = XMLE_PLAY;
+
+ if( !aEffect.mxShape.is() )
+ {
+ rExport.getInterfaceToIdentifierMapper().registerReference( xShape );
+ aEffect.mxShape = xShape;
+ }
+
+ mpImpl->maEffects.push_back( aEffect );
+ }
+
+ {
+ AnimationEffect eEffect;
+ xProps->getPropertyValue( AnimExpImpl::gsEffect ) >>= eEffect;
+ if( eEffect != AnimationEffect_NONE )
+ {
+ bool bIn = true;
+ SdXMLImplSetEffect( eEffect, aEffect.meEffect, aEffect.meDirection, aEffect.mnStartScale, bIn );
+
+ aEffect.meKind = bIn ? XMLE_SHOW : XMLE_HIDE;
+
+ if( !aEffect.mxShape.is() )
+ {
+ rExport.getInterfaceToIdentifierMapper().registerReference( xShape );
+ aEffect.mxShape = xShape;
+ }
+
+ if( eEffect == AnimationEffect_PATH )
+ {
+ Reference< XShape > xPath;
+ xProps->getPropertyValue( AnimExpImpl::gsAnimPath ) >>= xPath;
+ if( xPath.is() )
+ {
+// strip mpImpl->mxShapeExp->createShapeId( xPath );
+// strip aEffect.mnPathShapeId = mpImpl->mxShapeExp->getShapeId( xPath );
+ }
+ }
+ mpImpl->maEffects.push_back( aEffect );
+
+ aEffect.maSoundURL.clear();
+ }
+
+ xProps->getPropertyValue( AnimExpImpl::gsTextEffect ) >>= eEffect;
+ if( eEffect != AnimationEffect_NONE )
+ {
+ bool bIn = true;
+ SdXMLImplSetEffect( eEffect, aEffect.meEffect, aEffect.meDirection, aEffect.mnStartScale, bIn );
+ aEffect.meKind = bIn ? XMLE_SHOW : XMLE_HIDE;
+ aEffect.mbTextEffect = true;
+
+ if( !aEffect.mxShape.is() )
+ {
+ rExport.getInterfaceToIdentifierMapper().registerReference( xShape );
+ aEffect.mxShape = xShape;
+ }
+
+ mpImpl->maEffects.push_back( aEffect );
+ aEffect.mbTextEffect = false;
+ aEffect.maSoundURL.clear();
+ }
+
+ bool bDimPrev = false;
+ bool bDimHide = false;
+ xProps->getPropertyValue( AnimExpImpl::gsDimPrev ) >>= bDimPrev;
+ xProps->getPropertyValue( AnimExpImpl::gsDimHide ) >>= bDimHide;
+ if( bDimPrev || bDimHide )
+ {
+ aEffect.meKind = bDimPrev ? XMLE_DIM : XMLE_HIDE;
+ aEffect.meEffect = EK_none;
+ aEffect.meDirection = ED_none;
+ aEffect.meSpeed = AnimationSpeed_MEDIUM;
+ if( bDimPrev )
+ {
+ xProps->getPropertyValue( AnimExpImpl::gsDimColor )
+ >>= aEffect.maDimColor;
+ }
+
+ if( !aEffect.mxShape.is() )
+ {
+ rExport.getInterfaceToIdentifierMapper().registerReference( xShape );
+ aEffect.mxShape = xShape;
+ }
+
+ mpImpl->maEffects.push_back( aEffect );
+ aEffect.maSoundURL.clear();
+ }
+ }
+ }
+ }
+ catch (const Exception&)
+ {
+ TOOLS_WARN_EXCEPTION("xmloff.draw",
+ "exception caught while collection animation information!");
+ }
+}
+
+void XMLAnimationsExporter::exportAnimations( SvXMLExport& rExport )
+{
+ mpImpl->maEffects.sort();
+
+ OUStringBuffer sTmp;
+
+ if( !mpImpl->maEffects.empty() )
+ {
+ SvXMLElementExport aElement( rExport, XML_NAMESPACE_PRESENTATION, XML_ANIMATIONS, true, true );
+
+ for (const auto& rEffect : mpImpl->maEffects)
+ {
+ SAL_WARN_IF( !rEffect.mxShape.is(), "xmloff", "shape id creation failed for animation effect?" );
+
+ rExport.AddAttribute( XML_NAMESPACE_DRAW, XML_SHAPE_ID, rExport.getInterfaceToIdentifierMapper().getIdentifier( rEffect.mxShape ) );
+
+ if( rEffect.meKind == XMLE_DIM )
+ {
+ // export a dim action;
+
+ ::sax::Converter::convertColor( sTmp, rEffect.maDimColor );
+ rExport.AddAttribute( XML_NAMESPACE_DRAW, XML_COLOR, sTmp.makeStringAndClear() );
+
+ SvXMLElementExport aElem( rExport, XML_NAMESPACE_PRESENTATION, XML_DIM, true, true );
+ }
+ else if( rEffect.meKind == XMLE_PLAY )
+ {
+ if( rEffect.meSpeed != AnimationSpeed_MEDIUM )
+ {
+ SvXMLUnitConverter::convertEnum( sTmp, rEffect.meSpeed, aXML_AnimationSpeed_EnumMap );
+ rExport.AddAttribute( XML_NAMESPACE_PRESENTATION, XML_SPEED, sTmp.makeStringAndClear() );
+ }
+
+ SvXMLElementExport aElem( rExport, XML_NAMESPACE_PRESENTATION, XML_PLAY, true, true );
+ }
+ else
+ {
+
+ if( rEffect.meEffect != EK_none )
+ {
+ SvXMLUnitConverter::convertEnum( sTmp, rEffect.meEffect, aXML_AnimationEffect_EnumMap );
+ rExport.AddAttribute( XML_NAMESPACE_PRESENTATION, XML_EFFECT, sTmp.makeStringAndClear() );
+ }
+
+ if( rEffect.meDirection != ED_none )
+ {
+ SvXMLUnitConverter::convertEnum( sTmp, rEffect.meDirection, aXML_AnimationDirection_EnumMap );
+ rExport.AddAttribute( XML_NAMESPACE_PRESENTATION, XML_DIRECTION, sTmp.makeStringAndClear() );
+ }
+
+ if( rEffect.mnStartScale != -1 )
+ {
+ ::sax::Converter::convertPercent(sTmp, rEffect.mnStartScale);
+ rExport.AddAttribute( XML_NAMESPACE_PRESENTATION, XML_START_SCALE, sTmp.makeStringAndClear() );
+ }
+
+ if( rEffect.meSpeed != AnimationSpeed_MEDIUM )
+ {
+ SvXMLUnitConverter::convertEnum( sTmp, rEffect.meSpeed, aXML_AnimationSpeed_EnumMap );
+ rExport.AddAttribute( XML_NAMESPACE_PRESENTATION, XML_SPEED, sTmp.makeStringAndClear() );
+ }
+
+ enum XMLTokenEnum eLocalName;
+ if( rEffect.meKind == XMLE_SHOW )
+ {
+ if( rEffect.mbTextEffect )
+ eLocalName = XML_SHOW_TEXT;
+ else
+ eLocalName = XML_SHOW_SHAPE;
+ }
+ else
+ {
+ if( rEffect.mbTextEffect )
+ eLocalName = XML_HIDE_TEXT;
+ else
+ eLocalName = XML_HIDE_SHAPE;
+ }
+
+ SvXMLElementExport aEle( rExport, XML_NAMESPACE_PRESENTATION, eLocalName, true, true );
+ if( !rEffect.maSoundURL.isEmpty() )
+ {
+ rExport.AddAttribute(XML_NAMESPACE_XLINK, XML_HREF, rExport.GetRelativeReference(rEffect.maSoundURL) );
+ rExport.AddAttribute( XML_NAMESPACE_XLINK, XML_TYPE, XML_SIMPLE );
+ rExport.AddAttribute( XML_NAMESPACE_XLINK, XML_SHOW, XML_NEW );
+ rExport.AddAttribute( XML_NAMESPACE_XLINK, XML_ACTUATE, XML_ONREQUEST );
+ if( rEffect.mbPlayFull )
+ rExport.AddAttribute( XML_NAMESPACE_PRESENTATION, XML_PLAY_FULL, XML_TRUE );
+
+ SvXMLElementExport aElem( rExport, XML_NAMESPACE_PRESENTATION, XML_SOUND, true, true );
+ }
+ }
+ }
+ }
+
+ mpImpl->maEffects.clear();
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/xmloff/source/draw/animimp.cxx b/xmloff/source/draw/animimp.cxx
new file mode 100644
index 0000000000..90f5a5a609
--- /dev/null
+++ b/xmloff/source/draw/animimp.cxx
@@ -0,0 +1,597 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#include <sal/config.h>
+
+#include <string_view>
+
+#include <xmloff/unointerfacetouniqueidentifiermapper.hxx>
+#include <com/sun/star/lang/XServiceInfo.hpp>
+#include <com/sun/star/presentation/AnimationEffect.hpp>
+#include <com/sun/star/presentation/AnimationSpeed.hpp>
+#include <com/sun/star/beans/XPropertySet.hpp>
+#include <com/sun/star/drawing/XShape.hpp>
+#include <com/sun/star/xml/sax/XAttributeList.hpp>
+
+#include <sax/tools/converter.hxx>
+#include <sal/log.hxx>
+#include <comphelper/diagnose_ex.hxx>
+
+#include <xmloff/xmltoken.hxx>
+#include <xmloff/xmlimp.hxx>
+#include <xmloff/xmlnamespace.hxx>
+#include <xmloff/xmluconv.hxx>
+#include <xmloff/namespacemap.hxx>
+#include <anim.hxx>
+#include <animimp.hxx>
+
+using namespace ::cppu;
+using namespace ::com::sun::star;
+using namespace ::com::sun::star::xml;
+using namespace ::com::sun::star::xml::sax;
+using namespace ::com::sun::star::uno;
+using namespace ::com::sun::star::drawing;
+using namespace ::com::sun::star::beans;
+using namespace ::com::sun::star::lang;
+using namespace ::com::sun::star::presentation;
+using namespace ::xmloff::token;
+
+const SvXMLEnumMapEntry<XMLEffect> aXML_AnimationEffect_EnumMap[] =
+{
+ { XML_NONE, EK_none },
+ { XML_FADE, EK_fade },
+ { XML_MOVE, EK_move },
+ { XML_STRIPES, EK_stripes },
+ { XML_OPEN, EK_open },
+ { XML_CLOSE, EK_close },
+ { XML_DISSOLVE, EK_dissolve },
+ { XML_WAVYLINE, EK_wavyline },
+ { XML_RANDOM, EK_random },
+ { XML_LINES, EK_lines },
+ { XML_LASER, EK_laser },
+ { XML_APPEAR, EK_appear },
+ { XML_HIDE, EK_hide },
+ { XML_MOVE_SHORT, EK_move_short },
+ { XML_CHECKERBOARD, EK_checkerboard },
+ { XML_ROTATE, EK_rotate },
+ { XML_STRETCH, EK_stretch },
+ { XML_TOKEN_INVALID, XMLEffect(0) }
+};
+
+const SvXMLEnumMapEntry<XMLEffectDirection> aXML_AnimationDirection_EnumMap[] =
+{
+ { XML_NONE, ED_none },
+ { XML_FROM_LEFT, ED_from_left },
+ { XML_FROM_TOP, ED_from_top },
+ { XML_FROM_RIGHT, ED_from_right },
+ { XML_FROM_BOTTOM, ED_from_bottom },
+ { XML_FROM_CENTER, ED_from_center },
+ { XML_FROM_UPPER_LEFT, ED_from_upperleft },
+ { XML_FROM_UPPER_RIGHT, ED_from_upperright },
+ { XML_FROM_LOWER_LEFT, ED_from_lowerleft },
+ { XML_FROM_LOWER_RIGHT, ED_from_lowerright },
+ { XML_TO_LEFT, ED_to_left },
+ { XML_TO_TOP, ED_to_top },
+ { XML_TO_RIGHT, ED_to_right },
+ { XML_TO_BOTTOM, ED_to_bottom },
+ { XML_TO_UPPER_LEFT, ED_to_upperleft },
+ { XML_TO_UPPER_RIGHT, ED_to_upperright },
+ { XML_TO_LOWER_RIGHT, ED_to_lowerright },
+ { XML_TO_LOWER_LEFT, ED_to_lowerleft },
+ { XML_PATH, ED_path },
+ { XML_SPIRAL_INWARD_LEFT, ED_spiral_inward_left },
+ { XML_SPIRAL_INWARD_RIGHT,ED_spiral_inward_right },
+ { XML_SPIRAL_OUTWARD_LEFT, ED_spiral_outward_left },
+ { XML_SPIRAL_OUTWARD_RIGHT, ED_spiral_outward_right },
+ { XML_VERTICAL, ED_vertical },
+ { XML_HORIZONTAL, ED_horizontal },
+ { XML_TO_CENTER, ED_to_center },
+ { XML_CLOCKWISE, ED_clockwise },
+ { XML_COUNTER_CLOCKWISE,ED_cclockwise },
+ { XML_TOKEN_INVALID, XMLEffectDirection(0) }
+};
+
+const SvXMLEnumMapEntry<AnimationSpeed> aXML_AnimationSpeed_EnumMap[] =
+{
+ { XML_SLOW, AnimationSpeed_SLOW },
+ { XML_MEDIUM, AnimationSpeed_MEDIUM },
+ { XML_FAST, AnimationSpeed_FAST },
+ { XML_TOKEN_INVALID, AnimationSpeed(0) }
+};
+
+AnimationEffect ImplSdXMLgetEffect( XMLEffect eKind, XMLEffectDirection eDirection, sal_Int16 nStartScale, bool /*bIn*/ )
+{
+ switch( eKind )
+ {
+ case EK_fade:
+ switch( eDirection )
+ {
+ case ED_from_left: return AnimationEffect_FADE_FROM_LEFT;
+ case ED_from_top: return AnimationEffect_FADE_FROM_TOP;
+ case ED_from_right: return AnimationEffect_FADE_FROM_RIGHT;
+ case ED_from_bottom: return AnimationEffect_FADE_FROM_BOTTOM;
+ case ED_from_center: return AnimationEffect_FADE_FROM_CENTER;
+ case ED_from_upperleft: return AnimationEffect_FADE_FROM_UPPERLEFT;
+ case ED_from_upperright: return AnimationEffect_FADE_FROM_UPPERRIGHT;
+ case ED_from_lowerleft: return AnimationEffect_FADE_FROM_LOWERLEFT;
+ case ED_from_lowerright: return AnimationEffect_FADE_FROM_LOWERRIGHT;
+ case ED_to_center: return AnimationEffect_FADE_TO_CENTER;
+ case ED_clockwise: return AnimationEffect_CLOCKWISE;
+ case ED_cclockwise: return AnimationEffect_COUNTERCLOCKWISE;
+ case ED_spiral_inward_left: return AnimationEffect_SPIRALIN_LEFT;
+ case ED_spiral_inward_right:return AnimationEffect_SPIRALIN_RIGHT;
+ case ED_spiral_outward_left:return AnimationEffect_SPIRALOUT_LEFT;
+ case ED_spiral_outward_right:return AnimationEffect_SPIRALOUT_RIGHT;
+ default: return AnimationEffect_FADE_FROM_LEFT;
+ }
+ case EK_move:
+ if( nStartScale == 200 )
+ {
+ return AnimationEffect_ZOOM_OUT_SMALL;
+ }
+ else if( nStartScale == 50 )
+ {
+ return AnimationEffect_ZOOM_IN_SMALL;
+ }
+ else if( nStartScale < 100 )
+ {
+ switch( eDirection )
+ {
+ case ED_from_left: return AnimationEffect_ZOOM_IN_FROM_LEFT;
+ case ED_from_top: return AnimationEffect_ZOOM_IN_FROM_TOP;
+ case ED_from_right: return AnimationEffect_ZOOM_IN_FROM_RIGHT;
+ case ED_from_bottom: return AnimationEffect_ZOOM_IN_FROM_BOTTOM;
+ case ED_from_upperleft: return AnimationEffect_ZOOM_IN_FROM_UPPERLEFT;
+ case ED_from_upperright: return AnimationEffect_ZOOM_IN_FROM_UPPERRIGHT;
+ case ED_from_lowerleft: return AnimationEffect_ZOOM_IN_FROM_LOWERLEFT;
+ case ED_from_lowerright: return AnimationEffect_ZOOM_IN_FROM_LOWERRIGHT;
+ case ED_from_center: return AnimationEffect_ZOOM_IN_FROM_CENTER;
+ case ED_spiral_inward_left: return AnimationEffect_ZOOM_IN_SPIRAL;
+ case ED_to_left: return AnimationEffect_MOVE_TO_LEFT;
+ case ED_to_top: return AnimationEffect_MOVE_TO_TOP;
+ case ED_to_right: return AnimationEffect_MOVE_TO_RIGHT;
+ case ED_to_bottom: return AnimationEffect_MOVE_TO_BOTTOM;
+ case ED_to_upperleft: return AnimationEffect_MOVE_TO_UPPERLEFT;
+ case ED_to_upperright: return AnimationEffect_MOVE_TO_UPPERRIGHT;
+ case ED_to_lowerright: return AnimationEffect_MOVE_TO_LOWERRIGHT;
+ case ED_to_lowerleft: return AnimationEffect_MOVE_TO_LOWERLEFT;
+ default: return AnimationEffect_ZOOM_IN;
+ }
+ }
+ else if( nStartScale > 100 )
+ {
+ switch( eDirection )
+ {
+ case ED_from_left: return AnimationEffect_ZOOM_OUT_FROM_LEFT;
+ case ED_from_top: return AnimationEffect_ZOOM_OUT_FROM_TOP;
+ case ED_from_right: return AnimationEffect_ZOOM_OUT_FROM_RIGHT;
+ case ED_from_bottom: return AnimationEffect_ZOOM_OUT_FROM_BOTTOM;
+ case ED_from_upperleft: return AnimationEffect_ZOOM_OUT_FROM_UPPERLEFT;
+ case ED_from_upperright: return AnimationEffect_ZOOM_OUT_FROM_UPPERRIGHT;
+ case ED_from_lowerleft: return AnimationEffect_ZOOM_OUT_FROM_LOWERLEFT;
+ case ED_from_lowerright: return AnimationEffect_ZOOM_OUT_FROM_LOWERRIGHT;
+ case ED_from_center: return AnimationEffect_ZOOM_OUT_FROM_CENTER;
+ case ED_spiral_inward_left: return AnimationEffect_ZOOM_OUT_SPIRAL;
+ default: return AnimationEffect_ZOOM_OUT;
+ }
+ }
+ else
+ {
+ switch( eDirection )
+ {
+ case ED_from_left: return AnimationEffect_MOVE_FROM_LEFT;
+ case ED_from_top: return AnimationEffect_MOVE_FROM_TOP;
+ case ED_from_right: return AnimationEffect_MOVE_FROM_RIGHT;
+ case ED_from_bottom: return AnimationEffect_MOVE_FROM_BOTTOM;
+ case ED_from_upperleft: return AnimationEffect_MOVE_FROM_UPPERLEFT;
+ case ED_from_upperright: return AnimationEffect_MOVE_FROM_UPPERRIGHT;
+ case ED_from_lowerleft: return AnimationEffect_MOVE_FROM_LOWERLEFT;
+ case ED_from_lowerright: return AnimationEffect_MOVE_FROM_LOWERRIGHT;
+ case ED_path: return AnimationEffect_PATH;
+ case ED_to_top: return AnimationEffect_MOVE_TO_TOP;
+ case ED_to_right: return AnimationEffect_MOVE_TO_RIGHT;
+ case ED_to_bottom: return AnimationEffect_MOVE_TO_BOTTOM;
+ case ED_to_upperleft: return AnimationEffect_MOVE_TO_UPPERLEFT;
+ case ED_to_upperright: return AnimationEffect_MOVE_TO_UPPERRIGHT;
+ case ED_to_lowerright: return AnimationEffect_MOVE_TO_LOWERRIGHT;
+ case ED_to_lowerleft: return AnimationEffect_MOVE_TO_LOWERLEFT;
+ default:
+ break;
+ }
+ }
+ return AnimationEffect_MOVE_FROM_LEFT;
+ case EK_stripes:
+ if( eDirection == ED_vertical )
+ return AnimationEffect_VERTICAL_STRIPES;
+ else
+ return AnimationEffect_HORIZONTAL_STRIPES;
+ case EK_open:
+ if( eDirection == ED_vertical )
+ return AnimationEffect_OPEN_VERTICAL;
+ else
+ return AnimationEffect_OPEN_HORIZONTAL;
+ case EK_close:
+ if( eDirection == ED_vertical )
+ return AnimationEffect_CLOSE_VERTICAL;
+ else
+ return AnimationEffect_CLOSE_HORIZONTAL;
+ case EK_dissolve:
+ return AnimationEffect_DISSOLVE;
+ case EK_wavyline:
+ switch( eDirection )
+ {
+ case ED_from_left: return AnimationEffect_WAVYLINE_FROM_LEFT;
+ case ED_from_top: return AnimationEffect_WAVYLINE_FROM_TOP;
+ case ED_from_right: return AnimationEffect_WAVYLINE_FROM_RIGHT;
+ case ED_from_bottom: return AnimationEffect_WAVYLINE_FROM_BOTTOM;
+ default: return AnimationEffect_WAVYLINE_FROM_LEFT;
+ }
+ case EK_random:
+ return AnimationEffect_RANDOM;
+ case EK_lines:
+ if( eDirection == ED_vertical )
+ return AnimationEffect_VERTICAL_LINES;
+ else
+ return AnimationEffect_HORIZONTAL_LINES;
+ case EK_laser:
+ switch( eDirection )
+ {
+ case ED_from_left: return AnimationEffect_LASER_FROM_LEFT;
+ case ED_from_top: return AnimationEffect_LASER_FROM_TOP;
+ case ED_from_right: return AnimationEffect_LASER_FROM_RIGHT;
+ case ED_from_bottom: return AnimationEffect_LASER_FROM_BOTTOM;
+ case ED_from_upperleft: return AnimationEffect_LASER_FROM_UPPERLEFT;
+ case ED_from_upperright: return AnimationEffect_LASER_FROM_UPPERRIGHT;
+ case ED_from_lowerleft: return AnimationEffect_LASER_FROM_LOWERLEFT;
+ case ED_from_lowerright: return AnimationEffect_LASER_FROM_LOWERRIGHT;
+ default: return AnimationEffect_LASER_FROM_LEFT;
+ }
+ case EK_appear:
+ return AnimationEffect_APPEAR;
+ case EK_hide:
+ return AnimationEffect_HIDE;
+ case EK_move_short:
+ switch( eDirection )
+ {
+ case ED_from_left: return AnimationEffect_MOVE_SHORT_FROM_LEFT;
+ case ED_from_top: return AnimationEffect_MOVE_SHORT_FROM_TOP;
+ case ED_from_right: return AnimationEffect_MOVE_SHORT_FROM_RIGHT;
+ case ED_from_bottom: return AnimationEffect_MOVE_SHORT_FROM_BOTTOM;
+ case ED_from_upperleft: return AnimationEffect_MOVE_SHORT_FROM_UPPERLEFT;
+ case ED_from_upperright: return AnimationEffect_MOVE_SHORT_FROM_UPPERRIGHT;
+ case ED_from_lowerleft: return AnimationEffect_MOVE_SHORT_FROM_LOWERLEFT;
+ case ED_from_lowerright: return AnimationEffect_MOVE_SHORT_FROM_LOWERRIGHT;
+ case ED_to_left: return AnimationEffect_MOVE_SHORT_TO_LEFT;
+ case ED_to_upperleft: return AnimationEffect_MOVE_SHORT_TO_UPPERLEFT;
+ case ED_to_top: return AnimationEffect_MOVE_SHORT_TO_TOP;
+ case ED_to_upperright: return AnimationEffect_MOVE_SHORT_TO_UPPERRIGHT;
+ case ED_to_right: return AnimationEffect_MOVE_SHORT_TO_RIGHT;
+ case ED_to_lowerright: return AnimationEffect_MOVE_SHORT_TO_LOWERRIGHT;
+ case ED_to_bottom: return AnimationEffect_MOVE_SHORT_TO_BOTTOM;
+ case ED_to_lowerleft: return AnimationEffect_MOVE_SHORT_TO_LOWERLEFT;
+ default: return AnimationEffect_MOVE_SHORT_FROM_LEFT;
+ }
+ case EK_checkerboard:
+ if( eDirection == ED_vertical )
+ return AnimationEffect_VERTICAL_CHECKERBOARD;
+ else
+ return AnimationEffect_HORIZONTAL_CHECKERBOARD;
+ case EK_rotate:
+ if( eDirection == ED_vertical )
+ return AnimationEffect_VERTICAL_ROTATE;
+ else
+ return AnimationEffect_HORIZONTAL_ROTATE;
+ case EK_stretch:
+ switch( eDirection )
+ {
+ case ED_from_left: return AnimationEffect_STRETCH_FROM_LEFT;
+ case ED_from_top: return AnimationEffect_STRETCH_FROM_TOP;
+ case ED_from_right: return AnimationEffect_STRETCH_FROM_RIGHT;
+ case ED_from_bottom: return AnimationEffect_STRETCH_FROM_BOTTOM;
+ case ED_from_upperleft: return AnimationEffect_STRETCH_FROM_UPPERLEFT;
+ case ED_from_upperright: return AnimationEffect_STRETCH_FROM_UPPERRIGHT;
+ case ED_from_lowerleft: return AnimationEffect_STRETCH_FROM_LOWERLEFT;
+ case ED_from_lowerright: return AnimationEffect_STRETCH_FROM_LOWERRIGHT;
+ case ED_vertical: return AnimationEffect_VERTICAL_STRETCH;
+ case ED_horizontal: return AnimationEffect_HORIZONTAL_STRETCH;
+ default:
+ break;
+ }
+ return AnimationEffect_STRETCH_FROM_LEFT;
+ default:
+ return AnimationEffect_NONE;
+ }
+}
+
+namespace
+{
+ constexpr OUStringLiteral gsDimColor = u"DimColor";
+ constexpr OUStringLiteral gsDimHide = u"DimHide";
+ constexpr OUStringLiteral gsDimPrev = u"DimPrevious";
+ constexpr OUStringLiteral gsEffect = u"Effect";
+ constexpr OUStringLiteral gsPlayFull = u"PlayFull";
+ constexpr OUStringLiteral gsSound = u"Sound";
+ constexpr OUStringLiteral gsSoundOn = u"SoundOn";
+ constexpr OUStringLiteral gsSpeed = u"Speed";
+ constexpr OUStringLiteral gsTextEffect = u"TextEffect";
+ constexpr OUStringLiteral gsPresShapeService = u"com.sun.star.presentation.Shape";
+ constexpr OUStringLiteral gsAnimPath = u"AnimationPath";
+ constexpr OUStringLiteral gsIsAnimation = u"IsAnimation";
+};
+
+namespace {
+
+enum XMLActionKind
+{
+ XMLE_SHOW,
+ XMLE_HIDE,
+ XMLE_DIM,
+ XMLE_PLAY
+};
+
+class XMLAnimationsEffectContext : public SvXMLImportContext
+{
+public:
+ rtl::Reference<XMLAnimationsContext> mxAnimationsContext;
+
+ XMLActionKind meKind;
+ bool mbTextEffect;
+ OUString maShapeId;
+
+ XMLEffect meEffect;
+ XMLEffectDirection meDirection;
+ sal_Int16 mnStartScale;
+
+ AnimationSpeed meSpeed;
+ sal_Int32 maDimColor;
+ OUString maSoundURL;
+ bool mbPlayFull;
+ OUString maPathShapeId;
+
+public:
+
+ XMLAnimationsEffectContext( SvXMLImport& rImport,
+ sal_Int32 nElement,
+ const Reference< XFastAttributeList >& xAttrList,
+ XMLAnimationsContext& rAnimationsContext);
+
+ virtual void SAL_CALL endFastElement(sal_Int32 nElement) override;
+
+ virtual css::uno::Reference< css::xml::sax::XFastContextHandler > SAL_CALL createFastChildContext(
+ sal_Int32 nElement, const css::uno::Reference< css::xml::sax::XFastAttributeList >& xAttrList ) override;
+};
+
+class XMLAnimationsSoundContext : public SvXMLImportContext
+{
+public:
+
+ XMLAnimationsSoundContext( SvXMLImport& rImport, sal_Int32 nElement, const Reference< XFastAttributeList >& xAttrList, XMLAnimationsEffectContext* pParent );
+};
+
+}
+
+XMLAnimationsSoundContext::XMLAnimationsSoundContext( SvXMLImport& rImport, sal_Int32 nElement, const Reference< XFastAttributeList >& xAttrList, XMLAnimationsEffectContext* pParent )
+: SvXMLImportContext( rImport )
+{
+ if( !pParent || nElement != XML_ELEMENT(PRESENTATION, XML_SOUND) )
+ return;
+
+ for (auto &aIter : sax_fastparser::castToFastAttributeList( xAttrList ))
+ {
+ switch( aIter.getToken() )
+ {
+ case XML_ELEMENT(XLINK, XML_HREF):
+ pParent->maSoundURL = rImport.GetAbsoluteReference(aIter.toString());
+ break;
+ case XML_ELEMENT(PRESENTATION, XML_PLAY_FULL):
+ pParent->mbPlayFull = IsXMLToken( aIter, XML_TRUE );
+ break;
+ default:
+ XMLOFF_WARN_UNKNOWN("xmloff", aIter);
+ }
+ }
+}
+
+XMLAnimationsEffectContext::XMLAnimationsEffectContext( SvXMLImport& rImport,
+ sal_Int32 nElement,
+ const Reference< XFastAttributeList >& xAttrList,
+ XMLAnimationsContext& rAnimationsContext )
+: SvXMLImportContext(rImport),
+ mxAnimationsContext( &rAnimationsContext ),
+ meKind( XMLE_SHOW ), mbTextEffect( false ),
+ meEffect( EK_none ), meDirection( ED_none ), mnStartScale( 100 ),
+ meSpeed( AnimationSpeed_MEDIUM ), maDimColor(0), mbPlayFull( false )
+{
+ switch(nElement & TOKEN_MASK)
+ {
+ case XML_SHOW_SHAPE:
+ meKind = XMLE_SHOW;
+ break;
+ case XML_SHOW_TEXT:
+ meKind = XMLE_SHOW;
+ mbTextEffect = true;
+ break;
+ case XML_HIDE_SHAPE:
+ meKind = XMLE_HIDE;
+ break;
+ case XML_HIDE_TEXT:
+ meKind = XMLE_HIDE;
+ mbTextEffect = true;
+ break;
+ case XML_DIM:
+ meKind = XMLE_DIM;
+ break;
+ case XML_PLAY:
+ meKind = XMLE_PLAY;
+ break;
+ default:
+ XMLOFF_WARN_UNKNOWN_ELEMENT("xmloff", nElement);
+ // unknown action, overread
+ return;
+ }
+
+ for (auto &aIter : sax_fastparser::castToFastAttributeList( xAttrList ))
+ {
+ switch( aIter.getToken() )
+ {
+ case XML_ELEMENT(DRAW, XML_SHAPE_ID):
+ maShapeId = aIter.toString();
+ break;
+ case XML_ELEMENT(DRAW, XML_COLOR):
+ ::sax::Converter::convertColor(maDimColor, aIter.toView());
+ break;
+
+ case XML_ELEMENT(PRESENTATION, XML_EFFECT):
+ SvXMLUnitConverter::convertEnum( meEffect, aIter.toView(), aXML_AnimationEffect_EnumMap );
+ break;
+ case XML_ELEMENT(PRESENTATION, XML_DIRECTION):
+ SvXMLUnitConverter::convertEnum( meDirection, aIter.toView(), aXML_AnimationDirection_EnumMap );
+ break;
+ case XML_ELEMENT(PRESENTATION, XML_START_SCALE):
+ {
+ sal_Int32 nScale;
+ if (::sax::Converter::convertPercent( nScale, aIter.toView() ))
+ mnStartScale = static_cast<sal_Int16>(nScale);
+ break;
+ }
+ case XML_ELEMENT(PRESENTATION, XML_SPEED):
+ SvXMLUnitConverter::convertEnum( meSpeed, aIter.toView(), aXML_AnimationSpeed_EnumMap );
+ break;
+ case XML_ELEMENT(PRESENTATION, XML_PATH_ID):
+ maPathShapeId = aIter.toString();
+ break;
+ default:
+ XMLOFF_WARN_UNKNOWN("xmloff", aIter);
+ }
+ }
+}
+
+css::uno::Reference< css::xml::sax::XFastContextHandler > XMLAnimationsEffectContext::createFastChildContext(
+ sal_Int32 nElement,
+ const css::uno::Reference< css::xml::sax::XFastAttributeList >& xAttrList )
+{
+ return new XMLAnimationsSoundContext( GetImport(), nElement, xAttrList, this );
+}
+
+void XMLAnimationsEffectContext::endFastElement(sal_Int32 )
+{
+ // set effect on shape
+
+ try
+ {
+ if( !maShapeId.isEmpty() )
+ {
+ Reference< XPropertySet > xSet;
+ if( mxAnimationsContext->maLastShapeId != maShapeId )
+ {
+ xSet.set( GetImport().getInterfaceToIdentifierMapper().getReference( maShapeId ), UNO_QUERY );
+ if( xSet.is() )
+ {
+ // check for presentation shape service
+ {
+ Reference< XServiceInfo > xServiceInfo( xSet, UNO_QUERY );
+ if( !xServiceInfo.is() || !xServiceInfo->supportsService( gsPresShapeService ) )
+ return;
+ }
+
+ mxAnimationsContext->maLastShapeId = maShapeId;
+ mxAnimationsContext->mxLastShape = xSet;
+ }
+ }
+ else
+ {
+ xSet = mxAnimationsContext->mxLastShape;
+ }
+
+ if( xSet.is() )
+ {
+ if( meKind == XMLE_DIM )
+ {
+ xSet->setPropertyValue( gsDimPrev, Any(true) );
+
+ xSet->setPropertyValue( gsDimColor, Any(maDimColor) );
+ }
+ else if( meKind == XMLE_PLAY )
+ {
+ xSet->setPropertyValue( gsIsAnimation, Any(true) );
+
+ // #i42894# speed is not supported for the old group animation fallback, so no need to set it
+ // aAny <<= meSpeed;
+ // xSet->setPropertyValue( mpImpl->msSpeed, aAny );
+ }
+ else
+ {
+ if( meKind == XMLE_HIDE && !mbTextEffect && meEffect == EK_none )
+ {
+ xSet->setPropertyValue( gsDimHide, Any(true) );
+ }
+ else
+ {
+ const AnimationEffect eEffect = ImplSdXMLgetEffect( meEffect, meDirection, mnStartScale, meKind == XMLE_SHOW );
+
+ if (mbTextEffect)
+ xSet->setPropertyValue( gsTextEffect, Any( eEffect ) );
+ else
+ xSet->setPropertyValue( gsEffect, Any( eEffect ) );
+ xSet->setPropertyValue( gsSpeed, Any( meSpeed ) );
+
+ if( eEffect == AnimationEffect_PATH && !maPathShapeId.isEmpty() )
+ {
+ Reference< XShape > xPath( GetImport().getInterfaceToIdentifierMapper().getReference( maPathShapeId ), UNO_QUERY );
+ if( xPath.is() )
+ xSet->setPropertyValue( gsAnimPath, Any( xPath ) );
+ }
+ }
+ }
+ }
+ if( !maSoundURL.isEmpty() )
+ {
+ if( xSet.is() )
+ {
+ xSet->setPropertyValue( gsSound, Any(maSoundURL) );
+ xSet->setPropertyValue( gsPlayFull, Any(mbPlayFull) );
+ xSet->setPropertyValue( gsSoundOn, Any(true) );
+ }
+ else
+ {
+ OSL_FAIL("XMLAnimationsEffectContext::EndElement - Sound URL without a XPropertySet!");
+ }
+ }
+ }
+ }
+ catch (const Exception&)
+ {
+ TOOLS_WARN_EXCEPTION("xmloff.draw",
+ "exception caught while importing animation information!");
+ }
+}
+
+
+XMLAnimationsContext::XMLAnimationsContext( SvXMLImport& rImport )
+: SvXMLImportContext(rImport)
+{
+}
+
+css::uno::Reference< css::xml::sax::XFastContextHandler > XMLAnimationsContext::createFastChildContext(
+ sal_Int32 nElement, const css::uno::Reference< css::xml::sax::XFastAttributeList >& xAttrList )
+{
+ return new XMLAnimationsEffectContext( GetImport(), nElement, xAttrList, *this );
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/xmloff/source/draw/descriptionimp.cxx b/xmloff/source/draw/descriptionimp.cxx
new file mode 100644
index 0000000000..c0187f9055
--- /dev/null
+++ b/xmloff/source/draw/descriptionimp.cxx
@@ -0,0 +1,75 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#include <com/sun/star/beans/XPropertySet.hpp>
+#include <com/sun/star/xml/sax/XAttributeList.hpp>
+#include <xmloff/xmltoken.hxx>
+#include <xmloff/xmlimp.hxx>
+
+#include "descriptionimp.hxx"
+
+using namespace ::cppu;
+using namespace ::com::sun::star;
+using namespace ::com::sun::star::xml;
+using namespace ::com::sun::star::xml::sax;
+using namespace ::com::sun::star::uno;
+using namespace ::com::sun::star::drawing;
+using namespace ::com::sun::star::beans;
+using namespace ::xmloff::token;
+
+
+SdXMLDescriptionContext::SdXMLDescriptionContext( SvXMLImport& rImport, sal_Int32 nElement, const Reference< XShape >& rxShape)
+: SvXMLImportContext(rImport), mxShape( rxShape ), mnElement(nElement)
+{
+}
+
+SdXMLDescriptionContext::~SdXMLDescriptionContext()
+{
+}
+
+void SdXMLDescriptionContext::endFastElement(sal_Int32 )
+{
+ if( msText.isEmpty() )
+ return;
+
+ try
+ {
+ uno::Reference< beans::XPropertySet > xPropSet(mxShape, uno::UNO_QUERY_THROW);
+ if( (mnElement & TOKEN_MASK) == XML_TITLE)
+ {
+ xPropSet->setPropertyValue("Title", Any(msText));
+ }
+ else
+ {
+ xPropSet->setPropertyValue("Description", Any(msText));
+ }
+ }
+ catch( uno::Exception& )
+ {
+ }
+}
+
+// This method is called for all characters that are contained in the
+// current element. The default is to ignore them.
+void SdXMLDescriptionContext::characters( const OUString& rChars )
+{
+ msText += rChars;
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/xmloff/source/draw/descriptionimp.hxx b/xmloff/source/draw/descriptionimp.hxx
new file mode 100644
index 0000000000..cc94507727
--- /dev/null
+++ b/xmloff/source/draw/descriptionimp.hxx
@@ -0,0 +1,46 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#pragma once
+
+#include <xmloff/xmlictxt.hxx>
+#include <com/sun/star/drawing/XShape.hpp>
+
+// office:events inside a shape
+
+class SdXMLDescriptionContext final : public SvXMLImportContext
+{
+private:
+ css::uno::Reference< css::drawing::XShape > mxShape;
+ OUString msText;
+ sal_Int32 mnElement;
+public:
+
+ SdXMLDescriptionContext( SvXMLImport& rImport, sal_Int32 mnElement,
+ const css::uno::Reference< css::drawing::XShape >& rxShape );
+ virtual ~SdXMLDescriptionContext() override;
+
+ virtual void SAL_CALL endFastElement(sal_Int32 nElement) override;
+
+ // This method is called for all characters that are contained in the
+ // current element. The default is to ignore them.
+ virtual void SAL_CALL characters( const OUString& rChars ) override;
+};
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/xmloff/source/draw/eventimp.cxx b/xmloff/source/draw/eventimp.cxx
new file mode 100644
index 0000000000..2b8921ee27
--- /dev/null
+++ b/xmloff/source/draw/eventimp.cxx
@@ -0,0 +1,453 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#include <com/sun/star/document/XEventsSupplier.hpp>
+#include <com/sun/star/container/XNameReplace.hpp>
+#include <com/sun/star/presentation/AnimationSpeed.hpp>
+#include <com/sun/star/beans/XPropertySet.hpp>
+#include <tools/urlobj.hxx>
+#include <osl/diagnose.h>
+#include <sal/log.hxx>
+#include <o3tl/string_view.hxx>
+
+#include <sax/tools/converter.hxx>
+
+#include <xmloff/xmltoken.hxx>
+#include <xmloff/xmlimp.hxx>
+#include <xmloff/xmlnamespace.hxx>
+#include <xmloff/xmluconv.hxx>
+#include <xmloff/namespacemap.hxx>
+#include "eventimp.hxx"
+
+using namespace ::cppu;
+using namespace ::com::sun::star;
+using namespace ::com::sun::star::xml;
+using namespace ::com::sun::star::xml::sax;
+using namespace ::com::sun::star::uno;
+using namespace ::com::sun::star::drawing;
+using namespace ::com::sun::star::beans;
+using namespace ::com::sun::star::lang;
+using namespace ::com::sun::star::document;
+using namespace ::com::sun::star::container;
+using namespace ::com::sun::star::presentation;
+using namespace ::xmloff::token;
+
+SvXMLEnumMapEntry<ClickAction> const aXML_EventActions_EnumMap[] =
+{
+ { XML_NONE, ClickAction_NONE },
+ { XML_PREVIOUS_PAGE, ClickAction_PREVPAGE },
+ { XML_NEXT_PAGE, ClickAction_NEXTPAGE },
+ { XML_FIRST_PAGE, ClickAction_FIRSTPAGE },
+ { XML_LAST_PAGE, ClickAction_LASTPAGE },
+ { XML_HIDE, ClickAction_INVISIBLE },
+ { XML_STOP, ClickAction_STOPPRESENTATION },
+ { XML_EXECUTE, ClickAction_PROGRAM },
+ { XML_SHOW, ClickAction_BOOKMARK },
+ { XML_SHOW, ClickAction_DOCUMENT },
+ { XML_EXECUTE_MACRO, ClickAction_MACRO },
+ { XML_VERB, ClickAction_VERB },
+ { XML_FADE_OUT, ClickAction_VANISH },
+ { XML_SOUND, ClickAction_SOUND },
+ { XML_TOKEN_INVALID, ClickAction(0) }
+};
+
+SdXMLEventContextData::SdXMLEventContextData(const Reference< XShape >& rxShape)
+ : mxShape(rxShape), mbValid(false), mbScript(false)
+ , meClickAction(ClickAction_NONE), meEffect(EK_none)
+ , meDirection(ED_none), mnStartScale(100), meSpeed(AnimationSpeed_MEDIUM)
+ , mnVerb(0), mbPlayFull(false)
+{
+}
+
+namespace {
+
+class SdXMLEventContext : public SvXMLImportContext
+{
+public:
+ SdXMLEventContextData maData;
+
+public:
+
+ SdXMLEventContext( SvXMLImport& rImport, sal_Int32 nElement, const Reference< XFastAttributeList>& xAttrList, const Reference< XShape >& rxShape );
+
+ virtual css::uno::Reference< css::xml::sax::XFastContextHandler > SAL_CALL createFastChildContext(
+ sal_Int32 nElement,
+ const css::uno::Reference< css::xml::sax::XFastAttributeList >& AttrList ) override;
+ virtual void SAL_CALL endFastElement(sal_Int32 nElement) override;
+};
+
+class XMLEventSoundContext : public SvXMLImportContext
+{
+public:
+
+ XMLEventSoundContext( SvXMLImport& rImport, const Reference< XFastAttributeList >& xAttrList, SdXMLEventContext* pParent );
+};
+
+}
+
+XMLEventSoundContext::XMLEventSoundContext( SvXMLImport& rImp, const Reference< XFastAttributeList >& xAttrList, SdXMLEventContext* pParent )
+: SvXMLImportContext( rImp )
+{
+ for( auto& aIter : sax_fastparser::castToFastAttributeList(xAttrList) )
+ {
+ switch( aIter.getToken() )
+ {
+ case XML_ELEMENT(XLINK, XML_HREF):
+ pParent->maData.msSoundURL = rImp.GetAbsoluteReference(aIter.toString());
+ break;
+ case XML_ELEMENT(PRESENTATION, XML_PLAY_FULL):
+ pParent->maData.mbPlayFull = IsXMLToken( aIter, XML_TRUE );
+ break;
+ default:
+ XMLOFF_WARN_UNKNOWN("xmloff", aIter);
+ }
+ }
+}
+
+SdXMLEventContext::SdXMLEventContext( SvXMLImport& rImp,
+ sal_Int32 nElement,
+ const Reference< XFastAttributeList >& xAttrList, const Reference< XShape >& rxShape )
+ : SvXMLImportContext(rImp)
+ , maData(rxShape)
+{
+ if( nElement == XML_ELEMENT(PRESENTATION, XML_EVENT_LISTENER) )
+ {
+ maData.mbValid = true;
+ }
+ else if( nElement == XML_ELEMENT(SCRIPT, XML_EVENT_LISTENER) )
+ {
+ maData.mbScript = true;
+ maData.mbValid = true;
+ }
+ else
+ {
+ return;
+ }
+
+ // read attributes
+ OUString sEventName;
+ for( auto& aIter : sax_fastparser::castToFastAttributeList(xAttrList) )
+ {
+ switch( aIter.getToken() )
+ {
+ case XML_ELEMENT(PRESENTATION, XML_ACTION):
+ SvXMLUnitConverter::convertEnum( maData.meClickAction, aIter.toView(), aXML_EventActions_EnumMap );
+ break;
+ case XML_ELEMENT(PRESENTATION, XML_EFFECT):
+ SvXMLUnitConverter::convertEnum( maData.meEffect, aIter.toView(), aXML_AnimationEffect_EnumMap );
+ break;
+ case XML_ELEMENT(PRESENTATION, XML_DIRECTION):
+ SvXMLUnitConverter::convertEnum( maData.meDirection, aIter.toView(), aXML_AnimationDirection_EnumMap );
+ break;
+ case XML_ELEMENT(PRESENTATION, XML_START_SCALE):
+ {
+ sal_Int32 nScale;
+ if (::sax::Converter::convertPercent( nScale, aIter.toView() ))
+ maData.mnStartScale = static_cast<sal_Int16>(nScale);
+ }
+ break;
+ case XML_ELEMENT(PRESENTATION, XML_SPEED):
+ SvXMLUnitConverter::convertEnum( maData.meSpeed, aIter.toView(), aXML_AnimationSpeed_EnumMap );
+ break;
+ case XML_ELEMENT(PRESENTATION, XML_VERB):
+ ::sax::Converter::convertNumber( maData.mnVerb, aIter.toView() );
+ break;
+ case XML_ELEMENT(SCRIPT, XML_EVENT_NAME):
+ {
+ sEventName = aIter.toString();
+ sal_uInt16 nScriptPrefix =
+ GetImport().GetNamespaceMap().GetKeyByAttrValueQName(sEventName, &sEventName);
+ maData.mbValid = XML_NAMESPACE_DOM == nScriptPrefix && sEventName == "click";
+ }
+ break;
+ case XML_ELEMENT(SCRIPT, XML_LANGUAGE):
+ {
+ // language is not evaluated!
+ OUString aScriptLanguage;
+ maData.msLanguage = aIter.toString();
+ sal_uInt16 nScriptPrefix = rImp.GetNamespaceMap().
+ GetKeyByAttrValueQName(maData.msLanguage, &aScriptLanguage);
+ if( XML_NAMESPACE_OOO == nScriptPrefix )
+ maData.msLanguage = aScriptLanguage;
+ }
+ break;
+ case XML_ELEMENT(SCRIPT, XML_MACRO_NAME):
+ maData.msMacroName = aIter.toString();
+ break;
+ case XML_ELEMENT(XLINK, XML_HREF):
+ {
+ if ( maData.mbScript )
+ {
+ maData.msMacroName = aIter.toString();
+ }
+ else
+ {
+ const OUString &rTmp =
+ rImp.GetAbsoluteReference(aIter.toString());
+ INetURLObject::translateToInternal( rTmp, maData.msBookmark,
+ INetURLObject::DecodeMechanism::Unambiguous );
+ }
+ }
+ break;
+ }
+ }
+
+ if( maData.mbValid )
+ maData.mbValid = !sEventName.isEmpty();
+}
+
+css::uno::Reference< css::xml::sax::XFastContextHandler > SdXMLEventContext::createFastChildContext(
+ sal_Int32 nElement,
+ const css::uno::Reference< css::xml::sax::XFastAttributeList >& xAttrList )
+{
+ if( nElement == XML_ELEMENT(PRESENTATION, XML_SOUND) )
+ return new XMLEventSoundContext( GetImport(), xAttrList, this );
+ else
+ XMLOFF_WARN_UNKNOWN_ELEMENT("xmloff", nElement);
+ return nullptr;
+}
+
+void SdXMLEventContext::endFastElement(sal_Int32 )
+{
+ GetImport().GetShapeImport()->addShapeEvents(maData);
+}
+
+void SdXMLEventContextData::ApplyProperties()
+{
+ if( !mbValid )
+ return;
+
+ do
+ {
+ Reference< XEventsSupplier > xEventsSupplier( mxShape, UNO_QUERY );
+ if( !xEventsSupplier.is() )
+ break;
+
+ Reference< XNameReplace > xEvents( xEventsSupplier->getEvents() );
+ SAL_WARN_IF( !xEvents.is(), "xmloff", "XEventsSupplier::getEvents() returned NULL" );
+ if( !xEvents.is() )
+ break;
+
+ OUString sAPIEventName;
+ uno::Sequence< beans::PropertyValue > aProperties;
+
+ sAPIEventName = "OnClick";
+
+ if( mbScript )
+ meClickAction = ClickAction_MACRO;
+
+ sal_Int32 nPropertyCount = 2;
+ switch( meClickAction )
+ {
+ case ClickAction_NONE:
+ case ClickAction_PREVPAGE:
+ case ClickAction_NEXTPAGE:
+ case ClickAction_FIRSTPAGE:
+ case ClickAction_LASTPAGE:
+ case ClickAction_INVISIBLE:
+ case ClickAction_STOPPRESENTATION:
+ break;
+ case ClickAction_PROGRAM:
+ case ClickAction_VERB:
+ case ClickAction_BOOKMARK:
+ case ClickAction_DOCUMENT:
+ nPropertyCount += 1;
+ break;
+ case ClickAction_MACRO:
+ if ( msLanguage.equalsIgnoreAsciiCase("starbasic") )
+ nPropertyCount += 1;
+ break;
+
+ case ClickAction_SOUND:
+ nPropertyCount += 2;
+ break;
+
+ case ClickAction_VANISH:
+ nPropertyCount += 4;
+ break;
+ default:
+ break;
+ }
+
+ aProperties.realloc( nPropertyCount );
+ beans::PropertyValue* pProperties = aProperties.getArray();
+
+ if( ClickAction_MACRO == meClickAction )
+ {
+ if ( msLanguage.equalsIgnoreAsciiCase("starbasic") )
+ {
+ OUString sLibrary;
+ const OUString& rApp = GetXMLToken( XML_APPLICATION );
+ const OUString& rDoc = GetXMLToken( XML_DOCUMENT );
+ if( msMacroName.getLength() > rApp.getLength()+1 &&
+ o3tl::equalsIgnoreAsciiCase(msMacroName.subView(0,rApp.getLength()), rApp) &&
+ ':' == msMacroName[rApp.getLength()] )
+ {
+ sLibrary = "StarOffice";
+ msMacroName = msMacroName.copy( rApp.getLength()+1 );
+ }
+ else if( msMacroName.getLength() > rDoc.getLength()+1 &&
+ o3tl::equalsIgnoreAsciiCase(msMacroName.subView(0,rDoc.getLength()), rDoc) &&
+ ':' == msMacroName[rDoc.getLength()] )
+ {
+ sLibrary = rDoc;
+ msMacroName = msMacroName.copy( rDoc.getLength()+1 );
+ }
+
+ pProperties->Name = "EventType";
+ pProperties->Handle = -1;
+ pProperties->Value <<= OUString( "StarBasic" );
+ pProperties->State = beans::PropertyState_DIRECT_VALUE;
+ pProperties++;
+
+ pProperties->Name = "MacroName";
+ pProperties->Handle = -1;
+ pProperties->Value <<= msMacroName;
+ pProperties->State = beans::PropertyState_DIRECT_VALUE;
+ pProperties++;
+
+ pProperties->Name = "Library";
+ pProperties->Handle = -1;
+ pProperties->Value <<= sLibrary;
+ pProperties->State = beans::PropertyState_DIRECT_VALUE;
+ }
+ else
+ {
+ pProperties->Name = "EventType";
+ pProperties->Handle = -1;
+ pProperties->Value <<= OUString( "Script" );
+ pProperties->State = beans::PropertyState_DIRECT_VALUE;
+ pProperties++;
+
+ pProperties->Name = "Script";
+ pProperties->Handle = -1;
+ pProperties->Value <<= msMacroName;
+ pProperties->State = beans::PropertyState_DIRECT_VALUE;
+ }
+ }
+ else
+ {
+ pProperties->Name = "EventType";
+ pProperties->Handle = -1;
+ pProperties->Value <<= OUString( "Presentation" );
+ pProperties->State = beans::PropertyState_DIRECT_VALUE;
+ pProperties++;
+
+ // ClickAction_BOOKMARK and ClickAction_DOCUMENT share the same xml event
+ // so check here if it's really a bookmark or maybe a document
+ if( meClickAction == ClickAction_BOOKMARK )
+ {
+ if( !msBookmark.startsWith( "#" ) )
+ meClickAction = ClickAction_DOCUMENT;
+ }
+
+ pProperties->Name = "ClickAction";
+ pProperties->Handle = -1;
+ pProperties->Value <<= meClickAction;
+ pProperties->State = beans::PropertyState_DIRECT_VALUE;
+ pProperties++;
+
+ switch( meClickAction )
+ {
+ case ClickAction_NONE:
+ case ClickAction_PREVPAGE:
+ case ClickAction_NEXTPAGE:
+ case ClickAction_FIRSTPAGE:
+ case ClickAction_LASTPAGE:
+ case ClickAction_INVISIBLE:
+ case ClickAction_STOPPRESENTATION:
+ break;
+
+ case ClickAction_BOOKMARK:
+ msBookmark = msBookmark.copy(1);
+
+ [[fallthrough]];
+
+ case ClickAction_DOCUMENT:
+ case ClickAction_PROGRAM:
+ pProperties->Name = "Bookmark";
+ pProperties->Handle = -1;
+ pProperties->Value <<= msBookmark;
+ pProperties->State = beans::PropertyState_DIRECT_VALUE;
+ break;
+
+ case ClickAction_VANISH:
+ pProperties->Name = "Effect";
+ pProperties->Handle = -1;
+ pProperties->Value <<= ImplSdXMLgetEffect( meEffect, meDirection, mnStartScale, true );
+ pProperties->State = beans::PropertyState_DIRECT_VALUE;
+ pProperties++;
+
+ pProperties->Name = "Speed";
+ pProperties->Handle = -1;
+ pProperties->Value <<= meSpeed;
+ pProperties->State = beans::PropertyState_DIRECT_VALUE;
+ pProperties++;
+
+ [[fallthrough]];
+
+ case ClickAction_SOUND:
+ pProperties->Name = "SoundURL";
+ pProperties->Handle = -1;
+ pProperties->Value <<= msSoundURL;
+ pProperties->State = beans::PropertyState_DIRECT_VALUE;
+ pProperties++;
+
+ pProperties->Name = "PlayFull";
+ pProperties->Handle = -1;
+ pProperties->Value <<= mbPlayFull;
+ pProperties->State = beans::PropertyState_DIRECT_VALUE;
+ break;
+
+ case ClickAction_VERB:
+ pProperties->Name = "Verb";
+ pProperties->Handle = -1;
+ pProperties->Value <<= mnVerb;
+ pProperties->State = beans::PropertyState_DIRECT_VALUE;
+ break;
+ case ClickAction_MACRO:
+ OSL_FAIL("xmloff::SdXMLEventContext::EndElement(), ClickAction_MACRO must be handled in different if case");
+ break;
+ default:
+ break;
+ }
+ }
+ xEvents->replaceByName( sAPIEventName, uno::Any( aProperties ) );
+
+ } while(false);
+}
+
+
+SdXMLEventsContext::SdXMLEventsContext( SvXMLImport& rImport, const Reference< XShape >& rxShape)
+: SvXMLImportContext(rImport), mxShape( rxShape )
+{
+}
+
+SdXMLEventsContext::~SdXMLEventsContext()
+{
+}
+
+css::uno::Reference< css::xml::sax::XFastContextHandler > SdXMLEventsContext::createFastChildContext(
+ sal_Int32 nElement,
+ const css::uno::Reference< css::xml::sax::XFastAttributeList >& xAttrList )
+{
+ return new SdXMLEventContext( GetImport(), nElement, xAttrList, mxShape );
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/xmloff/source/draw/eventimp.hxx b/xmloff/source/draw/eventimp.hxx
new file mode 100644
index 0000000000..bb14aea5ed
--- /dev/null
+++ b/xmloff/source/draw/eventimp.hxx
@@ -0,0 +1,68 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#pragma once
+
+#include <xmloff/xmlictxt.hxx>
+#include <com/sun/star/drawing/XShape.hpp>
+#include <com/sun/star/presentation/ClickAction.hpp>
+#include <com/sun/star/presentation/AnimationSpeed.hpp>
+#include <anim.hxx>
+
+// office:events inside a shape
+
+class SdXMLEventsContext : public SvXMLImportContext
+{
+private:
+ css::uno::Reference< css::drawing::XShape > mxShape;
+
+public:
+
+ SdXMLEventsContext( SvXMLImport& rImport,
+ const css::uno::Reference< css::drawing::XShape >& rxShape );
+ virtual ~SdXMLEventsContext() override;
+
+ virtual css::uno::Reference< css::xml::sax::XFastContextHandler > SAL_CALL createFastChildContext(
+ sal_Int32 nElement,
+ const css::uno::Reference< css::xml::sax::XFastAttributeList >& AttrList ) override;
+};
+
+struct SdXMLEventContextData
+{
+ SdXMLEventContextData(const css::uno::Reference<css::drawing::XShape>& rxShape);
+ void ApplyProperties();
+
+ css::uno::Reference<css::drawing::XShape> mxShape;
+
+ bool mbValid;
+ bool mbScript;
+ css::presentation::ClickAction meClickAction;
+ XMLEffect meEffect;
+ XMLEffectDirection meDirection;
+ sal_Int16 mnStartScale;
+ css::presentation::AnimationSpeed meSpeed;
+ sal_Int32 mnVerb;
+ OUString msSoundURL;
+ bool mbPlayFull;
+ OUString msMacroName;
+ OUString msBookmark;
+ OUString msLanguage;
+};
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/xmloff/source/draw/layerexp.cxx b/xmloff/source/draw/layerexp.cxx
new file mode 100644
index 0000000000..82a8dd410d
--- /dev/null
+++ b/xmloff/source/draw/layerexp.cxx
@@ -0,0 +1,128 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+
+#include <com/sun/star/drawing/XLayerSupplier.hpp>
+#include <com/sun/star/container/XIndexAccess.hpp>
+#include <com/sun/star/beans/XPropertySet.hpp>
+#include <com/sun/star/frame/XModel.hpp>
+#include <xmloff/xmltoken.hxx>
+#include <xmloff/xmlnamespace.hxx>
+#include <xmloff/xmlexp.hxx>
+#include "layerexp.hxx"
+#include <comphelper/diagnose_ex.hxx>
+
+using ::com::sun::star::uno::Reference;
+
+using namespace ::cppu;
+using namespace ::com::sun::star;
+using namespace ::com::sun::star::uno;
+using namespace ::com::sun::star::drawing;
+using namespace ::com::sun::star::beans;
+using namespace ::com::sun::star::lang;
+using namespace ::com::sun::star::container;
+using namespace ::xmloff::token;
+
+void SdXMLayerExporter::exportLayer( SvXMLExport& rExport )
+{
+ Reference< XLayerSupplier > xLayerSupplier( rExport.GetModel(), UNO_QUERY );
+ if( !xLayerSupplier.is() )
+ return;
+
+ Reference< XIndexAccess > xLayerManager( xLayerSupplier->getLayerManager(), UNO_QUERY );
+ if( !xLayerManager.is() )
+ return;
+
+ const sal_Int32 nCount = xLayerManager->getCount();
+ if( nCount == 0 )
+ return;
+
+ static constexpr OUStringLiteral strName( u"Name" );
+ static constexpr OUStringLiteral strTitle( u"Title" );
+ static constexpr OUStringLiteral strDescription( u"Description" );
+ static constexpr OUStringLiteral strIsVisible( u"IsVisible");
+ static constexpr OUStringLiteral strIsPrintable( u"IsPrintable");
+ static constexpr OUStringLiteral strIsLocked( u"IsLocked" );
+
+ OUString sTmp;
+
+
+ SvXMLElementExport aElem( rExport, XML_NAMESPACE_DRAW, XML_LAYER_SET, true, true );
+
+ for( sal_Int32 nIndex = 0; nIndex < nCount; nIndex++ )
+ {
+ try
+ {
+ Reference< XPropertySet> xLayer( xLayerManager->getByIndex( nIndex ), UNO_QUERY_THROW );
+ xLayer->getPropertyValue( strName ) >>= sTmp;
+ if(!sTmp.isEmpty())
+ rExport.AddAttribute( XML_NAMESPACE_DRAW, XML_NAME, sTmp );
+
+ bool bTmpVisible( true );
+ bool bTmpPrintable( true );
+ xLayer->getPropertyValue( strIsVisible) >>= bTmpVisible;
+ xLayer->getPropertyValue( strIsPrintable) >>= bTmpPrintable;
+ // only write non-default values, default is "always"
+ if ( bTmpVisible )
+ {
+ if ( !bTmpPrintable )
+ rExport.AddAttribute( XML_NAMESPACE_DRAW, XML_DISPLAY, OUString("screen") );
+ }
+ else
+ {
+ if ( bTmpPrintable)
+ rExport.AddAttribute( XML_NAMESPACE_DRAW, XML_DISPLAY, OUString("printer") );
+ else
+ rExport.AddAttribute( XML_NAMESPACE_DRAW, XML_DISPLAY, OUString("none") );
+ }
+
+ bool bTmpLocked( false );
+ xLayer->getPropertyValue( strIsLocked ) >>= bTmpLocked;
+ // only write non-default value, default is "false"
+ if ( bTmpLocked )
+ {
+ rExport.AddAttribute( XML_NAMESPACE_DRAW, XML_PROTECTED, OUString("true") );
+ }
+
+ SvXMLElementExport aEle( rExport, XML_NAMESPACE_DRAW, XML_LAYER, true, true );
+
+ // title property (as <svg:title> element)
+ xLayer->getPropertyValue(strTitle) >>= sTmp;
+ if(!sTmp.isEmpty())
+ {
+ SvXMLElementExport aEventElemt(rExport, XML_NAMESPACE_SVG, XML_TITLE, true, false);
+ rExport.Characters(sTmp);
+ }
+
+ // description property (as <svg:desc> element)
+ xLayer->getPropertyValue(strDescription) >>= sTmp;
+ if(!sTmp.isEmpty())
+ {
+ SvXMLElementExport aDesc(rExport, XML_NAMESPACE_SVG, XML_DESC, true, false);
+ rExport.Characters(sTmp);
+ }
+ }
+ catch( Exception& )
+ {
+ TOOLS_WARN_EXCEPTION("xmloff.draw", "exception caught during export of one layer!");
+ }
+ }
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/xmloff/source/draw/layerexp.hxx b/xmloff/source/draw/layerexp.hxx
new file mode 100644
index 0000000000..76c04e1570
--- /dev/null
+++ b/xmloff/source/draw/layerexp.hxx
@@ -0,0 +1,30 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#pragma once
+
+class SvXMLExport;
+
+class SdXMLayerExporter
+{
+public:
+ static void exportLayer(SvXMLExport& rExport);
+};
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/xmloff/source/draw/layerimp.cxx b/xmloff/source/draw/layerimp.cxx
new file mode 100644
index 0000000000..eeffae04e9
--- /dev/null
+++ b/xmloff/source/draw/layerimp.cxx
@@ -0,0 +1,195 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#include <sal/config.h>
+
+#include <sal/log.hxx>
+#include <comphelper/diagnose_ex.hxx>
+#include <com/sun/star/drawing/XLayerManager.hpp>
+#include <com/sun/star/beans/XPropertySet.hpp>
+#include <com/sun/star/frame/XModel.hpp>
+#include <com/sun/star/xml/sax/XAttributeList.hpp>
+#include <com/sun/star/drawing/XLayerSupplier.hpp>
+#include <xmloff/xmltoken.hxx>
+#include <xmloff/xmlimp.hxx>
+#include <xmloff/xmlnamespace.hxx>
+#include <xmloff/namespacemap.hxx>
+#include "layerimp.hxx"
+
+
+#include <XMLStringBufferImportContext.hxx>
+
+using namespace ::cppu;
+using namespace ::xmloff::token;
+using namespace ::com::sun::star;
+using namespace ::com::sun::star::xml;
+using namespace ::com::sun::star::xml::sax;
+using namespace ::com::sun::star::uno;
+using namespace ::com::sun::star::drawing;
+using namespace ::com::sun::star::beans;
+using namespace ::com::sun::star::lang;
+using namespace ::com::sun::star::container;
+
+namespace {
+
+class SdXMLLayerContext : public SvXMLImportContext
+{
+public:
+ SdXMLLayerContext( SvXMLImport& rImport, const Reference< XFastAttributeList >& xAttrList, const Reference< XNameAccess >& xLayerManager );
+
+ virtual css::uno::Reference< css::xml::sax::XFastContextHandler > SAL_CALL createFastChildContext(
+ sal_Int32 nElement,
+ const css::uno::Reference< css::xml::sax::XFastAttributeList >& AttrList ) override;
+ virtual void SAL_CALL endFastElement(sal_Int32 nElement) override;
+
+private:
+ css::uno::Reference< css::container::XNameAccess > mxLayerManager;
+ OUString msName;
+ OUStringBuffer sDescriptionBuffer;
+ OUStringBuffer sTitleBuffer;
+ OUString msDisplay;
+ OUString msProtected;
+};
+
+}
+
+SdXMLLayerContext::SdXMLLayerContext( SvXMLImport& rImport, const Reference< XFastAttributeList >& xAttrList, const Reference< XNameAccess >& xLayerManager )
+: SvXMLImportContext(rImport)
+, mxLayerManager( xLayerManager )
+{
+ for( auto& aIter : sax_fastparser::castToFastAttributeList(xAttrList) )
+ {
+ OUString sValue = aIter.toString();
+ switch(aIter.getToken())
+ {
+ case XML_ELEMENT(DRAW, XML_NAME):
+ msName = sValue;
+ break;
+ case XML_ELEMENT(DRAW, XML_DISPLAY):
+ msDisplay = sValue;
+ break;
+ case XML_ELEMENT(DRAW, XML_PROTECTED):
+ msProtected = sValue;
+ break;
+ default:
+ XMLOFF_WARN_UNKNOWN("xmloff", aIter);
+ }
+ }
+
+}
+
+css::uno::Reference< css::xml::sax::XFastContextHandler > SdXMLLayerContext::createFastChildContext(
+ sal_Int32 nElement,
+ const css::uno::Reference< css::xml::sax::XFastAttributeList >& )
+{
+ if( nElement == XML_ELEMENT(SVG, XML_TITLE) )
+ {
+ return new XMLStringBufferImportContext( GetImport(), sTitleBuffer);
+ }
+ else if( nElement == XML_ELEMENT(SVG, XML_DESC) )
+ {
+ return new XMLStringBufferImportContext( GetImport(), sDescriptionBuffer);
+ }
+ else
+ XMLOFF_WARN_UNKNOWN_ELEMENT("xmloff", nElement);
+ return nullptr;
+}
+
+void SdXMLLayerContext::endFastElement(sal_Int32 )
+{
+ SAL_WARN_IF( msName.isEmpty(), "xmloff", "xmloff::SdXMLLayerContext::EndElement(), draw:layer element without draw:name!" );
+ if( msName.isEmpty() )
+ return;
+
+ try
+ {
+ Reference< XPropertySet > xLayer;
+
+ if( mxLayerManager->hasByName( msName ) )
+ {
+ mxLayerManager->getByName( msName ) >>= xLayer;
+ SAL_WARN_IF( !xLayer.is(), "xmloff", "xmloff::SdXMLLayerContext::EndElement(), failed to get existing XLayer!" );
+ }
+ else
+ {
+ Reference< XLayerManager > xLayerManager( mxLayerManager, UNO_QUERY );
+ if( xLayerManager.is() )
+ xLayer = xLayerManager->insertNewByIndex( xLayerManager->getCount() );
+ SAL_WARN_IF( !xLayer.is(), "xmloff", "xmloff::SdXMLLayerContext::EndElement(), failed to create new XLayer!" );
+
+ if( xLayer.is() )
+ xLayer->setPropertyValue("Name", Any( msName ) );
+ }
+
+ if( xLayer.is() )
+ {
+ xLayer->setPropertyValue("Title", Any( sTitleBuffer.makeStringAndClear() ) );
+ xLayer->setPropertyValue("Description", Any( sDescriptionBuffer.makeStringAndClear() ) );
+ bool bIsVisible( true );
+ bool bIsPrintable( true );
+ if ( !msDisplay.isEmpty() )
+ {
+ bIsVisible = (msDisplay == "always") || (msDisplay == "screen");
+ bIsPrintable = (msDisplay == "always") || (msDisplay == "printer");
+ }
+ xLayer->setPropertyValue("IsVisible", Any( bIsVisible ) );
+ xLayer->setPropertyValue("IsPrintable", Any( bIsPrintable ) );
+ bool bIsLocked( false );
+ if ( !msProtected.isEmpty() )
+ bIsLocked = (msProtected == "true");
+ xLayer->setPropertyValue("IsLocked", Any( bIsLocked ) );
+
+ // tdf#129898 repair layer "DrawnInSlideshow", which was wrongly written
+ // in LO 6.2 to 6.4. It should always have ODF defaults.
+ if (msName == "DrawnInSlideshow")
+ {
+ xLayer->setPropertyValue("IsVisible", Any(true));
+ xLayer->setPropertyValue("IsPrintable", Any(true));
+ xLayer->setPropertyValue("IsLocked", Any(false));
+ }
+ }
+ }
+ catch( Exception& )
+ {
+ TOOLS_WARN_EXCEPTION("xmloff.draw", "");
+ }
+}
+
+
+SdXMLLayerSetContext::SdXMLLayerSetContext( SvXMLImport& rImport )
+: SvXMLImportContext(rImport)
+{
+ Reference< XLayerSupplier > xLayerSupplier( rImport.GetModel(), UNO_QUERY );
+ SAL_WARN_IF( !xLayerSupplier.is(), "xmloff", "xmloff::SdXMLLayerSetContext::SdXMLLayerSetContext(), XModel is not supporting XLayerSupplier!" );
+ if( xLayerSupplier.is() )
+ mxLayerManager = xLayerSupplier->getLayerManager();
+}
+
+SdXMLLayerSetContext::~SdXMLLayerSetContext()
+{
+}
+
+css::uno::Reference< css::xml::sax::XFastContextHandler > SdXMLLayerSetContext::createFastChildContext(
+ sal_Int32 /*nElement*/,
+ const css::uno::Reference< css::xml::sax::XFastAttributeList >& xAttrList )
+{
+ return new SdXMLLayerContext( GetImport(), xAttrList, mxLayerManager );
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/xmloff/source/draw/layerimp.hxx b/xmloff/source/draw/layerimp.hxx
new file mode 100644
index 0000000000..4d3b899419
--- /dev/null
+++ b/xmloff/source/draw/layerimp.hxx
@@ -0,0 +1,41 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#pragma once
+
+#include <xmloff/xmlictxt.hxx>
+#include <com/sun/star/container/XNameAccess.hpp>
+
+// presentations:animations
+
+class SdXMLLayerSetContext : public SvXMLImportContext
+{
+private:
+ css::uno::Reference< css::container::XNameAccess > mxLayerManager;
+
+public:
+ SdXMLLayerSetContext( SvXMLImport& rImport );
+ virtual ~SdXMLLayerSetContext() override;
+
+ virtual css::uno::Reference< css::xml::sax::XFastContextHandler > SAL_CALL createFastChildContext(
+ sal_Int32 nElement,
+ const css::uno::Reference< css::xml::sax::XFastAttributeList >& AttrList ) override;
+};
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/xmloff/source/draw/numithdl.cxx b/xmloff/source/draw/numithdl.cxx
new file mode 100644
index 0000000000..4797f6edf9
--- /dev/null
+++ b/xmloff/source/draw/numithdl.cxx
@@ -0,0 +1,54 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#include <utility>
+
+#include "numithdl.hxx"
+
+using namespace ::com::sun::star;
+
+
+
+
+XMLNumRulePropHdl::XMLNumRulePropHdl( css::uno::Reference< css::ucb::XAnyCompare > xNumRuleCompare )
+: mxNumRuleCompare(std::move( xNumRuleCompare ))
+{
+}
+
+XMLNumRulePropHdl::~XMLNumRulePropHdl()
+{
+ // Nothing to do
+}
+
+bool XMLNumRulePropHdl::equals( const uno::Any& r1, const uno::Any& r2 ) const
+{
+ return mxNumRuleCompare.is() && mxNumRuleCompare->compare( r1, r2 ) == 0;
+}
+
+bool XMLNumRulePropHdl::importXML( const OUString& /*rStrImpValue*/, css::uno::Any& /*rValue*/, const SvXMLUnitConverter& /*rUnitConverter*/ ) const
+{
+ return false;
+}
+
+bool XMLNumRulePropHdl::exportXML( OUString& /*rStrExpValue*/, const css::uno::Any& /*rValue*/, const SvXMLUnitConverter& /*rUnitConverter*/ ) const
+{
+ return false;
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/xmloff/source/draw/numithdl.hxx b/xmloff/source/draw/numithdl.hxx
new file mode 100644
index 0000000000..503c4c7b6c
--- /dev/null
+++ b/xmloff/source/draw/numithdl.hxx
@@ -0,0 +1,43 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#pragma once
+
+#include <com/sun/star/ucb/XAnyCompare.hpp>
+#include <xmloff/xmlprhdl.hxx>
+
+/**
+ PropertyHandler for the list-style
+*/
+class XMLNumRulePropHdl : public XMLPropertyHandler
+{
+private:
+ css::uno::Reference< css::ucb::XAnyCompare > mxNumRuleCompare;
+public:
+ explicit XMLNumRulePropHdl( css::uno::Reference< css::ucb::XAnyCompare > xNumRuleCompare );
+ virtual ~XMLNumRulePropHdl() override;
+
+ virtual bool equals( const css::uno::Any& r1, const css::uno::Any& r2 ) const override;
+
+ /// NumRules will be imported/exported as XML-Elements. So the Import/Export-work must be done at another place.
+ virtual bool importXML( const OUString& rStrImpValue, css::uno::Any& rValue, const SvXMLUnitConverter& rUnitConverter ) const override;
+ virtual bool exportXML( OUString& rStrExpValue, const css::uno::Any& rValue, const SvXMLUnitConverter& rUnitConverter ) const override;
+};
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/xmloff/source/draw/propimp0.cxx b/xmloff/source/draw/propimp0.cxx
new file mode 100644
index 0000000000..92bb46bdac
--- /dev/null
+++ b/xmloff/source/draw/propimp0.cxx
@@ -0,0 +1,262 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#include <rtl/ustrbuf.hxx>
+#include <sal/log.hxx>
+#include <propimp0.hxx>
+#include <com/sun/star/util/Duration.hpp>
+#include <com/sun/star/uno/Any.hxx>
+
+#include <sax/tools/converter.hxx>
+
+#include <xmloff/xmlexp.hxx>
+#include <xmloff/xmluconv.hxx>
+#include <xmloff/xmlimp.hxx>
+
+#include <tools/time.hxx>
+
+using namespace ::com::sun::star;
+
+// implementation of graphic property Stroke
+
+// implementation of presentation page property Change
+
+// implementation of an effect duration property handler
+
+XMLDurationPropertyHdl::~XMLDurationPropertyHdl()
+{
+}
+
+bool XMLDurationPropertyHdl::importXML(
+ const OUString& rStrImpValue,
+ css::uno::Any& rValue,
+ const SvXMLUnitConverter& ) const
+{
+ util::Duration aDuration;
+
+ if (::sax::Converter::convertDuration(aDuration, rStrImpValue))
+ {
+ const double fSeconds = ((aDuration.Days * 24 + aDuration.Hours) * 60
+ + aDuration.Minutes) * 60
+ + aDuration.Seconds
+ + aDuration.NanoSeconds / static_cast<double>(::tools::Time::nanoSecPerSec);
+ rValue <<= fSeconds;
+
+ return true;
+ }
+
+ SAL_WARN_IF(!rStrImpValue.isEmpty(), "xmloff", "Invalid duration: " << rStrImpValue);
+
+ return false;
+}
+
+bool XMLDurationPropertyHdl::exportXML(
+ OUString& rStrExpValue,
+ const css::uno::Any& rValue,
+ const SvXMLUnitConverter& ) const
+{
+ double nVal = 0;
+
+ if(rValue >>= nVal)
+ {
+ util::Duration aDuration;
+ aDuration.Seconds = static_cast<sal_uInt16>(nVal);
+ aDuration.NanoSeconds = static_cast<sal_uInt32>((nVal - aDuration.Seconds) * ::tools::Time::nanoSecPerSec);
+
+ OUStringBuffer aOut;
+ ::sax::Converter::convertDuration(aOut, aDuration);
+ rStrExpValue = aOut.makeStringAndClear();
+ return true;
+ }
+
+ return false;
+}
+
+// implementation of an opacity property handler
+
+XMLOpacityPropertyHdl::XMLOpacityPropertyHdl( SvXMLImport* pImport )
+: mpImport( pImport )
+{
+}
+
+XMLOpacityPropertyHdl::~XMLOpacityPropertyHdl()
+{
+}
+
+bool XMLOpacityPropertyHdl::importXML(
+ const OUString& rStrImpValue,
+ css::uno::Any& rValue,
+ const SvXMLUnitConverter& ) const
+{
+ bool bRet = false;
+ sal_Int32 nValue = 0;
+
+ if( rStrImpValue.indexOf( '%' ) != -1 )
+ {
+ if (::sax::Converter::convertPercent( nValue, rStrImpValue ))
+ bRet = true;
+ }
+ else
+ {
+ nValue = sal_Int32( rStrImpValue.toDouble() * 100.0 );
+ bRet = true;
+ }
+
+ if( bRet )
+ {
+ // check ranges
+ if( nValue < 0 )
+ nValue = 0;
+ if( nValue > 100 )
+ nValue = 100;
+
+ // convert xml opacity to api transparency
+ nValue = 100 - nValue;
+
+ // #i42959#
+ if( mpImport )
+ {
+ sal_Int32 nUPD, nBuild;
+ if( mpImport->getBuildIds( nUPD, nBuild ) )
+ {
+ // correct import of documents written prior to StarOffice 8/OOO 2.0 final
+ if( (nUPD == 680) && (nBuild < 8951) )
+ nValue = 100 - nValue;
+ }
+ }
+
+ rValue <<= sal_uInt16(nValue);
+ }
+
+ return bRet;
+}
+
+bool XMLOpacityPropertyHdl::exportXML(
+ OUString& rStrExpValue,
+ const css::uno::Any& rValue,
+ const SvXMLUnitConverter& ) const
+{
+ bool bRet = false;
+ sal_uInt16 nVal = sal_uInt16();
+
+ if( rValue >>= nVal )
+ {
+ OUStringBuffer aOut;
+
+ nVal = 100 - nVal;
+ ::sax::Converter::convertPercent( aOut, nVal );
+ rStrExpValue = aOut.makeStringAndClear();
+ bRet = true;
+ }
+
+ return bRet;
+}
+
+// implementation of a text animation step amount
+
+XMLTextAnimationStepPropertyHdl::~XMLTextAnimationStepPropertyHdl()
+{
+}
+
+bool XMLTextAnimationStepPropertyHdl::importXML(
+ const OUString& rStrImpValue,
+ css::uno::Any& rValue,
+ const SvXMLUnitConverter& rUnitConverter ) const
+{
+ bool bRet = false;
+ sal_Int32 nValue = 0;
+
+ sal_Int32 nPos = rStrImpValue.indexOf( "px" );
+ if( nPos != -1 )
+ {
+ if (::sax::Converter::convertNumber(nValue, rStrImpValue.subView(0, nPos)))
+ {
+ rValue <<= sal_Int16( -nValue );
+ bRet = true;
+ }
+ }
+ else
+ {
+ if (rUnitConverter.convertMeasureToCore( nValue, rStrImpValue ))
+ {
+ rValue <<= sal_Int16( nValue );
+ bRet = true;
+ }
+ }
+
+ return bRet;
+}
+
+bool XMLTextAnimationStepPropertyHdl::exportXML(
+ OUString& rStrExpValue,
+ const css::uno::Any& rValue,
+ const SvXMLUnitConverter& rUnitConverter ) const
+{
+ bool bRet = false;
+ sal_Int16 nVal = sal_Int16();
+
+ if( rValue >>= nVal )
+ {
+ OUStringBuffer aOut;
+
+ if( nVal < 0 )
+ {
+ aOut.append( OUString::number(static_cast<sal_Int32>(-nVal) ) + "px" );
+ }
+ else
+ {
+ rUnitConverter.convertMeasureToXML( aOut, nVal );
+ }
+
+ rStrExpValue = aOut.makeStringAndClear();
+ bRet = true;
+ }
+
+ return bRet;
+}
+
+XMLDateTimeFormatHdl::XMLDateTimeFormatHdl( SvXMLExport* pExport )
+: mpExport( pExport )
+{
+}
+
+XMLDateTimeFormatHdl::~XMLDateTimeFormatHdl()
+{
+}
+
+bool XMLDateTimeFormatHdl::importXML( const OUString& rStrImpValue, css::uno::Any& rValue, const SvXMLUnitConverter& ) const
+{
+ rValue <<= rStrImpValue;
+ return true;
+}
+
+bool XMLDateTimeFormatHdl::exportXML( OUString& rStrExpValue, const css::uno::Any& rValue, const SvXMLUnitConverter& ) const
+{
+ sal_Int32 nNumberFormat = 0;
+ if( mpExport && (rValue >>= nNumberFormat) )
+ {
+ mpExport->addDataStyle( nNumberFormat );
+ rStrExpValue = mpExport->getDataStyleName( nNumberFormat );
+ return true;
+ }
+
+ return false;
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/xmloff/source/draw/sdpropls.cxx b/xmloff/source/draw/sdpropls.cxx
new file mode 100644
index 0000000000..50ccd70a49
--- /dev/null
+++ b/xmloff/source/draw/sdpropls.cxx
@@ -0,0 +1,1923 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#include <com/sun/star/animations/TransitionType.hpp>
+#include <com/sun/star/ucb/XAnyCompareFactory.hpp>
+#include <com/sun/star/container/XIndexReplace.hpp>
+#include <com/sun/star/drawing/LineStyle.hpp>
+#include <com/sun/star/drawing/LineJoint.hpp>
+#include <com/sun/star/drawing/LineCap.hpp>
+#include <com/sun/star/presentation/AnimationSpeed.hpp>
+#include <com/sun/star/presentation/FadeEffect.hpp>
+
+#include <com/sun/star/text/WritingMode.hpp>
+#include <com/sun/star/text/WritingMode2.hpp>
+#include <utility>
+#include <xmloff/EnumPropertyHdl.hxx>
+#include <xmloff/NamedBoolPropertyHdl.hxx>
+#include <WordWrapPropertyHdl.hxx>
+#include <enummaps.hxx>
+#include "numithdl.hxx"
+#include <XMLBitmapRepeatOffsetPropertyHandler.hxx>
+#include <XMLFillBitmapSizePropertyHandler.hxx>
+#include <XMLBitmapLogicalSizePropertyHandler.hxx>
+#include <com/sun/star/drawing/TextAnimationKind.hpp>
+#include <com/sun/star/drawing/TextAnimationDirection.hpp>
+#include <com/sun/star/drawing/TextHorizontalAdjust.hpp>
+#include <com/sun/star/drawing/TextVerticalAdjust.hpp>
+#include <com/sun/star/drawing/TextFitToSizeType.hpp>
+#include <com/sun/star/drawing/MeasureTextHorzPos.hpp>
+#include <com/sun/star/drawing/MeasureTextVertPos.hpp>
+#include <xmloff/controlpropertyhdl.hxx>
+#include <xmloff/xmltoken.hxx>
+#include "sdpropls.hxx"
+#include <propimp0.hxx>
+#include <xmloff/xmlexp.hxx>
+#include <xmloff/xmlnamespace.hxx>
+#include <com/sun/star/drawing/NormalsKind.hpp>
+#include <com/sun/star/drawing/TextureProjectionMode.hpp>
+#include <com/sun/star/drawing/TextureKind.hpp>
+#include <com/sun/star/drawing/TextureMode.hpp>
+#include <com/sun/star/beans/XPropertySet.hpp>
+#include <xmloff/txtprmap.hxx>
+#include <XMLClipPropertyHandler.hxx>
+#include <XMLIsPercentagePropertyHandler.hxx>
+#include <XMLPercentOrMeasurePropertyHandler.hxx>
+#include <XMLTextColumnsPropertyHandler.hxx>
+#include <xmloff/XMLComplexColorHandler.hxx>
+#include <animations.hxx>
+#include <sax/tools/converter.hxx>
+#include <xmlsdtypes.hxx>
+#include <xmlprop.hxx>
+
+using ::com::sun::star::uno::Any;
+
+using namespace ::com::sun::star;
+using namespace ::xmloff::token;
+
+#define MAP_(name,prefix,token,type,context) { name, prefix, token, type, context, SvtSaveOptions::ODFSVER_010, false }
+#define MAPV_(name,prefix,token,type,context,version) { name, prefix, token, type, context, version, false }
+#define GMAP(name,prefix,token,type,context) MAP_(name,prefix,token,type|XML_TYPE_PROP_GRAPHIC,context)
+#define GMAP_D(name,prefix,token,type,context) MAP_(name,prefix,token,type|XML_TYPE_PROP_GRAPHIC|MID_FLAG_DEFAULT_ITEM_EXPORT,context)
+#define GMAPV(name,prefix,token,type,context,version) MAPV_(name,prefix,token,type|XML_TYPE_PROP_GRAPHIC,context,version)
+#define DPMAP(name,prefix,token,type,context) MAP_(name,prefix,token,type|XML_TYPE_PROP_DRAWING_PAGE,context)
+#define TMAP(name,prefix,token,type,context) MAP_(name,prefix,token,type|XML_TYPE_PROP_TEXT,context)
+#define PMAP(name,prefix,token,type,context) MAP_(name,prefix,token,type|XML_TYPE_PROP_PARAGRAPH,context)
+#define MAP_END() { nullptr }
+
+// entry list for graphic properties
+
+const XMLPropertyMapEntry aXMLSDProperties[] =
+{
+ // this entry must be first! this is needed for XMLShapeImportHelper::CreateExternalShapePropMapper
+
+ // ^^^though CreateExternalShapePropMapper is gone now, hmm^^^
+ GMAP( PROP_UserDefinedAttributes, XML_NAMESPACE_TEXT, XML_XMLNS, XML_TYPE_ATTRIBUTE_CONTAINER | MID_FLAG_SPECIAL_ITEM, 0 ),
+
+ // stroke attributes
+ GMAP( PROP_LineStyle, XML_NAMESPACE_DRAW, XML_STROKE, XML_SD_TYPE_STROKE, 0 ),
+ GMAP( PROP_LineDashName, XML_NAMESPACE_DRAW, XML_STROKE_DASH, XML_TYPE_STYLENAME|MID_FLAG_NO_PROPERTY_IMPORT , CTF_DASHNAME ),
+ GMAP( PROP_LineWidth, XML_NAMESPACE_SVG, XML_STROKE_WIDTH, XML_TYPE_MEASURE, 0 ),
+ GMAP_D( PROP_LineColor, XML_NAMESPACE_SVG, XML_STROKE_COLOR, XML_TYPE_COLOR, 0),
+ GMAPV( PROP_LineComplexColor, XML_NAMESPACE_LO_EXT, XML_STROKE_COMPLEX_COLOR, XML_TYPE_COMPLEX_COLOR|MID_FLAG_ELEMENT_ITEM, CTF_COMPLEX_COLOR, SvtSaveOptions::ODFSVER_FUTURE_EXTENDED),
+ GMAP( PROP_LineStartName, XML_NAMESPACE_DRAW, XML_MARKER_START, XML_TYPE_STYLENAME|MID_FLAG_NO_PROPERTY_IMPORT, CTF_LINESTARTNAME ),
+ GMAP( PROP_LineStartWidth, XML_NAMESPACE_DRAW, XML_MARKER_START_WIDTH, XML_TYPE_MEASURE, 0 ),
+ GMAP( PROP_LineStartCenter, XML_NAMESPACE_DRAW, XML_MARKER_START_CENTER, XML_TYPE_BOOL, 0 ),
+ GMAP( PROP_LineEndName, XML_NAMESPACE_DRAW, XML_MARKER_END, XML_TYPE_STYLENAME|MID_FLAG_NO_PROPERTY_IMPORT, CTF_LINEENDNAME ),
+ GMAP( PROP_LineEndWidth, XML_NAMESPACE_DRAW, XML_MARKER_END_WIDTH, XML_TYPE_MEASURE, 0 ),
+ GMAP( PROP_LineEndCenter, XML_NAMESPACE_DRAW, XML_MARKER_END_CENTER, XML_TYPE_BOOL, 0 ),
+ GMAP( PROP_LineTransparence, XML_NAMESPACE_SVG, XML_STROKE_OPACITY, XML_SD_TYPE_OPACITY, 0 ),
+ GMAP( PROP_LineJoint, XML_NAMESPACE_DRAW, XML_STROKE_LINEJOIN, XML_SD_TYPE_LINEJOIN, 0 ),
+ GMAP( PROP_LineCap, XML_NAMESPACE_SVG , XML_STROKE_LINECAP, XML_SD_TYPE_LINECAP, 0 ),
+
+ // fill attributes
+ GMAP( PROP_FillStyle, XML_NAMESPACE_DRAW, XML_FILL, XML_SD_TYPE_FILLSTYLE, CTF_FILLSTYLE ),
+ GMAP_D(PROP_FillColor, XML_NAMESPACE_DRAW, XML_FILL_COLOR, XML_TYPE_COLOR, CTF_FILLCOLOR ),
+ GMAP_D(PROP_FillColor2, XML_NAMESPACE_DRAW, XML_SECONDARY_FILL_COLOR, XML_TYPE_COLOR, 0),
+ GMAPV( PROP_FillComplexColor, XML_NAMESPACE_LO_EXT, XML_FILL_COMPLEX_COLOR, XML_TYPE_COMPLEX_COLOR|MID_FLAG_ELEMENT_ITEM, CTF_COMPLEX_COLOR, SvtSaveOptions::ODFSVER_FUTURE_EXTENDED),
+ GMAP( PROP_FillGradientName, XML_NAMESPACE_DRAW, XML_FILL_GRADIENT_NAME, XML_TYPE_STYLENAME|MID_FLAG_NO_PROPERTY_IMPORT, CTF_FILLGRADIENTNAME ),
+ GMAP( PROP_FillGradientStepCount, XML_NAMESPACE_DRAW, XML_GRADIENT_STEP_COUNT, XML_TYPE_NUMBER16, 0 ),
+ GMAP( PROP_FillHatchName, XML_NAMESPACE_DRAW, XML_FILL_HATCH_NAME, XML_TYPE_STYLENAME|MID_FLAG_NO_PROPERTY_IMPORT, CTF_FILLHATCHNAME ),
+ GMAP( PROP_FillBackground, XML_NAMESPACE_DRAW, XML_FILL_HATCH_SOLID, XML_TYPE_BOOL, 0 ),
+ GMAPV( PROP_FillUseSlideBackground, XML_NAMESPACE_LO_EXT, XML_FILL_USE_SLIDE_BACKGROUND, XML_TYPE_BOOL, 0, SvtSaveOptions::ODFSVER_FUTURE_EXTENDED),
+ GMAP( PROP_FillBitmapName, XML_NAMESPACE_DRAW, XML_FILL_IMAGE_NAME, XML_TYPE_STYLENAME|MID_FLAG_NO_PROPERTY_IMPORT, CTF_FILLBITMAPNAME ),
+ GMAP( PROP_FillTransparence, XML_NAMESPACE_DRAW, XML_OPACITY, XML_TYPE_NEG_PERCENT16|MID_FLAG_MULTI_PROPERTY, 0 ), // exists in SW, too
+ GMAP( PROP_FillTransparenceGradientName, XML_NAMESPACE_DRAW, XML_OPACITY_NAME, XML_TYPE_STYLENAME|MID_FLAG_NO_PROPERTY_IMPORT, CTF_FILLTRANSNAME ),
+ GMAP( PROP_FillBitmapSizeX, XML_NAMESPACE_DRAW, XML_FILL_IMAGE_WIDTH, XML_SD_TYPE_FILLBITMAPSIZE|MID_FLAG_MULTI_PROPERTY, 0 ),
+ GMAP( PROP_FillBitmapLogicalSize, XML_NAMESPACE_DRAW, XML_FILL_IMAGE_WIDTH, XML_SD_TYPE_LOGICAL_SIZE|MID_FLAG_MULTI_PROPERTY, 0 ),
+ GMAP( PROP_FillBitmapSizeY, XML_NAMESPACE_DRAW, XML_FILL_IMAGE_HEIGHT, XML_SD_TYPE_FILLBITMAPSIZE|MID_FLAG_MULTI_PROPERTY, 0 ),
+ GMAP( PROP_FillBitmapLogicalSize, XML_NAMESPACE_DRAW, XML_FILL_IMAGE_HEIGHT, XML_SD_TYPE_LOGICAL_SIZE|MID_FLAG_MULTI_PROPERTY, 0 ),
+ GMAP( PROP_FillBitmapMode, XML_NAMESPACE_STYLE,XML_REPEAT, XML_SD_TYPE_BITMAP_MODE|MID_FLAG_MULTI_PROPERTY, 0 ),
+ GMAP( PROP_FillBitmapPositionOffsetX, XML_NAMESPACE_DRAW, XML_FILL_IMAGE_REF_POINT_X, XML_TYPE_PERCENT, 0 ),
+ GMAP( PROP_FillBitmapPositionOffsetY, XML_NAMESPACE_DRAW, XML_FILL_IMAGE_REF_POINT_Y, XML_TYPE_PERCENT, 0 ),
+ GMAP( PROP_FillBitmapRectanglePoint, XML_NAMESPACE_DRAW, XML_FILL_IMAGE_REF_POINT, XML_SD_TYPE_BITMAP_REFPOINT, 0 ),
+ GMAP( PROP_FillBitmapOffsetX, XML_NAMESPACE_DRAW, XML_TILE_REPEAT_OFFSET, XML_SD_TYPE_BITMAPREPOFFSETX|MID_FLAG_MULTI_PROPERTY, CTF_REPEAT_OFFSET_X ),
+ GMAP( PROP_FillBitmapOffsetY, XML_NAMESPACE_DRAW, XML_TILE_REPEAT_OFFSET, XML_SD_TYPE_BITMAPREPOFFSETY|MID_FLAG_MULTI_PROPERTY, CTF_REPEAT_OFFSET_Y ),
+
+ // text frame attributes
+ GMAP( PROP_TextHorizontalAdjust, XML_NAMESPACE_DRAW, XML_TEXTAREA_HORIZONTAL_ALIGN, XML_SD_TYPE_TEXT_ALIGN, 0 ),
+ GMAP( PROP_TextVerticalAdjust, XML_NAMESPACE_DRAW, XML_TEXTAREA_VERTICAL_ALIGN, XML_SD_TYPE_VERTICAL_ALIGN, 0 ),
+ GMAP( PROP_TextAutoGrowHeight, XML_NAMESPACE_DRAW, XML_AUTO_GROW_HEIGHT, XML_TYPE_BOOL, 0 ),
+ GMAP( PROP_TextAutoGrowWidth, XML_NAMESPACE_DRAW, XML_AUTO_GROW_WIDTH, XML_TYPE_BOOL, 0 ),
+ GMAP( PROP_TextFitToSize, XML_NAMESPACE_DRAW, XML_FIT_TO_SIZE, XML_SD_TYPE_FITTOSIZE|MID_FLAG_MERGE_PROPERTY, 0),
+ GMAPV( PROP_TextFitToSize, XML_NAMESPACE_STYLE, XML_SHRINK_TO_FIT, XML_SD_TYPE_FITTOSIZE_AUTOFIT|MID_FLAG_MERGE_PROPERTY, 0, SvtSaveOptions::ODFSVER_012 ),
+ GMAP( PROP_TextContourFrame, XML_NAMESPACE_DRAW, XML_FIT_TO_CONTOUR, XML_TYPE_BOOL, 0 ),
+ GMAP( PROP_TextMaximumFrameHeight, XML_NAMESPACE_FO, XML_MAX_HEIGHT, XML_TYPE_MEASURE, 0 ),
+ GMAP( PROP_TextMaximumFrameWidth, XML_NAMESPACE_FO, XML_MAX_WIDTH, XML_TYPE_MEASURE, 0 ),
+ GMAP( PROP_TextMinimumFrameHeight, XML_NAMESPACE_FO, XML_MIN_HEIGHT, XML_TYPE_MEASURE|MID_FLAG_MULTI_PROPERTY, 0 ), // exists in SW, too
+ GMAP( PROP_TextMinimumFrameWidth, XML_NAMESPACE_FO, XML_MIN_WIDTH, XML_TYPE_MEASURE|MID_FLAG_MULTI_PROPERTY, 0 ),
+ GMAP( PROP_TextUpperDistance, XML_NAMESPACE_FO, XML_PADDING_TOP, XML_TYPE_MEASURE|MID_FLAG_MULTI_PROPERTY, 0 ), // exists in SW, too
+ GMAP( PROP_TextLowerDistance, XML_NAMESPACE_FO, XML_PADDING_BOTTOM, XML_TYPE_MEASURE|MID_FLAG_MULTI_PROPERTY, 0 ), // exists in SW, too
+ GMAP( PROP_TextLeftDistance, XML_NAMESPACE_FO, XML_PADDING_LEFT, XML_TYPE_MEASURE|MID_FLAG_MULTI_PROPERTY, 0 ), // exists in SW, too
+ GMAP( PROP_TextRightDistance, XML_NAMESPACE_FO, XML_PADDING_RIGHT, XML_TYPE_MEASURE|MID_FLAG_MULTI_PROPERTY, 0 ), // exists in SW, too
+ PMAP( PROP_TextWritingMode, XML_NAMESPACE_STYLE,XML_WRITING_MODE, XML_SD_TYPE_WRITINGMODE|MID_FLAG_MULTI_PROPERTY, CTF_WRITINGMODE ),
+ GMAP( PROP_NumberingRules, XML_NAMESPACE_TEXT, XML_LIST_STYLE, XML_SD_TYPE_NUMBULLET|MID_FLAG_ELEMENT_ITEM, CTF_NUMBERINGRULES ),
+ GMAP( PROP_NumberingRules, XML_NAMESPACE_TEXT, XML_LIST_STYLE_NAME, XML_TYPE_STRING, CTF_SD_NUMBERINGRULES_NAME ),
+ GMAP( PROP_TextWordWrap, XML_NAMESPACE_FO, XML_WRAP_OPTION, XML_TYPE_WRAP_OPTION, 0 ),
+ GMAP( PROP_TextChainNextName, XML_NAMESPACE_DRAW, XML_CHAIN_NEXT_NAME, XML_TYPE_STRING, 0 ),
+ GMAP( PROP_TextClipVerticalOverflow, XML_NAMESPACE_STYLE, XML_OVERFLOW_BEHAVIOR, XML_TYPE_TEXT_OVERFLOW_BEHAVIOR, 0 ),
+
+ GMAP( PROP_TextColumns, XML_NAMESPACE_STYLE, XML_COLUMNS, XML_TYPE_TEXT_COLUMNS|MID_FLAG_ELEMENT_ITEM, CTF_TEXTCOLUMNS ),
+
+ // shadow attributes
+ GMAP( PROP_Shadow, XML_NAMESPACE_DRAW, XML_SHADOW, XML_SD_TYPE_VISIBLE_HIDDEN, 0 ),
+ GMAP( PROP_ShadowXDistance, XML_NAMESPACE_DRAW, XML_SHADOW_OFFSET_X, XML_TYPE_MEASURE, 0 ),
+ GMAP( PROP_ShadowYDistance, XML_NAMESPACE_DRAW, XML_SHADOW_OFFSET_Y, XML_TYPE_MEASURE, 0 ),
+ GMAP( PROP_ShadowColor, XML_NAMESPACE_DRAW, XML_SHADOW_COLOR, XML_TYPE_COLOR, 0 ),
+ GMAP( PROP_ShadowTransparence, XML_NAMESPACE_DRAW, XML_SHADOW_OPACITY, XML_TYPE_NEG_PERCENT, 0 ),
+ GMAPV( PROP_ShadowBlur, XML_NAMESPACE_LO_EXT, XML_SHADOW_BLUR, XML_TYPE_MEASURE, 0, SvtSaveOptions::ODFSVER_FUTURE_EXTENDED),
+
+ // glow attributes
+ GMAPV( PROP_GlowEffectRadius, XML_NAMESPACE_LO_EXT, XML_GLOW_RADIUS, XML_TYPE_MEASURE , 0, SvtSaveOptions::ODFSVER_FUTURE_EXTENDED),
+ GMAPV( PROP_GlowEffectColor, XML_NAMESPACE_LO_EXT, XML_GLOW_COLOR, XML_TYPE_COLOR , 0, SvtSaveOptions::ODFSVER_FUTURE_EXTENDED),
+ GMAPV( PROP_GlowEffectTransparency, XML_NAMESPACE_LO_EXT, XML_GLOW_TRANSPARENCY, XML_TYPE_PERCENT16, 0, SvtSaveOptions::ODFSVER_FUTURE_EXTENDED),
+
+ // soft edge attributes
+ GMAPV( PROP_SoftEdgeRadius, XML_NAMESPACE_LO_EXT, XML_SOFTEDGE_RADIUS, XML_TYPE_MEASURE , 0, SvtSaveOptions::ODFSVER_FUTURE_EXTENDED),
+
+ // graphic attributes
+ GMAP( PROP_GraphicColorMode, XML_NAMESPACE_DRAW, XML_COLOR_MODE, XML_TYPE_COLOR_MODE, 0 ), // exists in SW, too, with same property name
+ GMAP( PROP_AdjustLuminance, XML_NAMESPACE_DRAW, XML_LUMINANCE, XML_TYPE_PERCENT16, 0 ), // signed? exists in SW, too, with same property name
+ GMAP( PROP_AdjustContrast, XML_NAMESPACE_DRAW, XML_CONTRAST, XML_TYPE_PERCENT16, 0 ), // signed? exists in SW, too, with same property name
+ GMAP( PROP_Gamma, XML_NAMESPACE_DRAW, XML_GAMMA, XML_TYPE_DOUBLE_PERCENT, 0 ), // signed? exists in SW, too, with same property name
+ GMAP( PROP_AdjustRed, XML_NAMESPACE_DRAW, XML_RED, XML_TYPE_PERCENT16, 0 ), // signed? exists in SW, too, with same property name
+ GMAP( PROP_AdjustGreen, XML_NAMESPACE_DRAW, XML_GREEN, XML_TYPE_PERCENT16, 0 ), // signed? exists in SW, too, with same property name
+ GMAP( PROP_AdjustBlue, XML_NAMESPACE_DRAW, XML_BLUE, XML_TYPE_PERCENT16, 0 ), // signed? exists in SW, too, with same property name
+ GMAPV( PROP_GraphicCrop, XML_NAMESPACE_FO, XML_CLIP, XML_TYPE_TEXT_CLIP, CTF_TEXT_CLIP, SvtSaveOptions::ODFSVER_012), // exists in SW, too, with same property name
+ GMAP( PROP_GraphicCrop, XML_NAMESPACE_FO, XML_CLIP, XML_TYPE_TEXT_CLIP11, CTF_TEXT_CLIP11 ), // exists in SW, too, with same property name
+ GMAP( PROP_Transparency, XML_NAMESPACE_DRAW, XML_IMAGE_OPACITY, XML_TYPE_NEG_PERCENT16|MID_FLAG_MULTI_PROPERTY, 0 ), // exists in SW, too, with same property name // #i25616#
+ GMAP( PROP_IsMirrored, XML_NAMESPACE_STYLE, XML_MIRROR, XML_TYPE_SD_MIRROR|MID_FLAG_MULTI_PROPERTY, 0 ), // exists in SW, too // #i40214#
+
+ // animation text attributes
+ TMAP( PROP_TextAnimationKind, XML_NAMESPACE_STYLE,XML_TEXT_BLINKING, XML_TYPE_TEXT_ANIMATION_BLINKING, CTF_TEXTANIMATION_BLINKING ),
+ GMAP( PROP_TextAnimationKind, XML_NAMESPACE_TEXT, XML_ANIMATION, XML_TYPE_TEXT_ANIMATION, CTF_TEXTANIMATION_KIND ),
+ GMAP( PROP_TextAnimationDirection, XML_NAMESPACE_TEXT, XML_ANIMATION_DIRECTION, XML_TYPE_TEXT_ANIMATION_DIRECTION, 0 ),
+ GMAP( PROP_TextAnimationStartInside, XML_NAMESPACE_TEXT, XML_ANIMATION_START_INSIDE, XML_TYPE_BOOL, 0 ),
+ GMAP( PROP_TextAnimationStopInside, XML_NAMESPACE_TEXT, XML_ANIMATION_STOP_INSIDE, XML_TYPE_BOOL, 0 ),
+ GMAP( PROP_TextAnimationCount, XML_NAMESPACE_TEXT, XML_ANIMATION_REPEAT, XML_TYPE_NUMBER16, 0 ),
+ GMAP( PROP_TextAnimationDelay, XML_NAMESPACE_TEXT, XML_ANIMATION_DELAY, XML_TYPE_DURATION16_MS, 0 ),
+ GMAP( PROP_TextAnimationAmount, XML_NAMESPACE_TEXT, XML_ANIMATION_STEPS, XML_TYPE_TEXT_ANIMATION_STEPS, 0 ),
+
+ // connector attributes
+ GMAP( PROP_EdgeNode1HorzDist, XML_NAMESPACE_DRAW, XML_START_LINE_SPACING_HORIZONTAL, XML_TYPE_MEASURE, 0 ),
+ GMAP( PROP_EdgeNode1VertDist, XML_NAMESPACE_DRAW, XML_START_LINE_SPACING_VERTICAL, XML_TYPE_MEASURE, 0 ),
+ GMAP( PROP_EdgeNode2HorzDist, XML_NAMESPACE_DRAW, XML_END_LINE_SPACING_HORIZONTAL, XML_TYPE_MEASURE, 0 ),
+ GMAP( PROP_EdgeNode2VertDist, XML_NAMESPACE_DRAW, XML_END_LINE_SPACING_VERTICAL, XML_TYPE_MEASURE, 0 ),
+
+ // measure attributes
+ GMAP( PROP_MeasureLineDistance, XML_NAMESPACE_DRAW, XML_LINE_DISTANCE, XML_TYPE_MEASURE, 0 ),
+ GMAP( PROP_MeasureHelpLineOverhang, XML_NAMESPACE_DRAW, XML_GUIDE_OVERHANG, XML_TYPE_MEASURE, 0 ),
+ GMAP( PROP_MeasureHelpLineDistance, XML_NAMESPACE_DRAW, XML_GUIDE_DISTANCE, XML_TYPE_MEASURE, 0 ),
+ GMAP( PROP_MeasureHelpLine1Length, XML_NAMESPACE_DRAW, XML_START_GUIDE, XML_TYPE_MEASURE, 0 ),
+ GMAP( PROP_MeasureHelpLine2Length, XML_NAMESPACE_DRAW, XML_END_GUIDE, XML_TYPE_MEASURE, 0 ),
+ GMAP( PROP_MeasureTextHorizontalPosition, XML_NAMESPACE_DRAW, XML_MEASURE_ALIGN, XML_SD_TYPE_MEASURE_HALIGN, 0 ),
+ GMAP( PROP_MeasureTextVerticalPosition, XML_NAMESPACE_DRAW, XML_MEASURE_VERTICAL_ALIGN, XML_SD_TYPE_MEASURE_VALIGN, 0 ),
+ GMAP( PROP_MeasureUnit, XML_NAMESPACE_DRAW, XML_UNIT, XML_SD_TYPE_MEASURE_UNIT, 0 ),
+ GMAP( PROP_MeasureShowUnit, XML_NAMESPACE_DRAW, XML_SHOW_UNIT, XML_TYPE_BOOL, 0 ),
+ GMAP( PROP_MeasureBelowReferenceEdge, XML_NAMESPACE_DRAW, XML_PLACING, XML_SD_TYPE_MEASURE_PLACING, 0 ),
+ GMAP( PROP_MeasureTextRotate90, XML_NAMESPACE_DRAW, XML_PARALLEL, XML_TYPE_BOOL, 0 ),
+ GMAP( PROP_MeasureDecimalPlaces, XML_NAMESPACE_DRAW, XML_DECIMAL_PLACES, XML_TYPE_NUMBER16, 0 ),
+
+ // 3D geometry attributes
+ GMAP( PROP_D3DHorizontalSegments, XML_NAMESPACE_DR3D, XML_HORIZONTAL_SEGMENTS, XML_TYPE_NUMBER, 0 ),
+ GMAP( PROP_D3DVerticalSegments, XML_NAMESPACE_DR3D, XML_VERTICAL_SEGMENTS, XML_TYPE_NUMBER, 0 ),
+ GMAP( PROP_D3DPercentDiagonal, XML_NAMESPACE_DR3D, XML_EDGE_ROUNDING, XML_TYPE_PERCENT, 0 ),
+ GMAP( PROP_D3DBackscale, XML_NAMESPACE_DR3D, XML_BACK_SCALE, XML_TYPE_PERCENT, 0 ),
+ GMAP( PROP_D3DEndAngle, XML_NAMESPACE_DR3D, XML_END_ANGLE, XML_TYPE_NUMBER, 0 ),
+ GMAP( PROP_D3DDepth, XML_NAMESPACE_DR3D, XML_DEPTH, XML_TYPE_MEASURE, 0 ),
+ GMAP( PROP_D3DDoubleSided, XML_NAMESPACE_DR3D, XML_BACKFACE_CULLING, XML_SD_TYPE_BACKFACE_CULLING, 0 ),
+
+ // #107245# New 3D properties which are possible for lathe and extrude 3d objects
+ GMAP( PROP_D3DCloseFront, XML_NAMESPACE_DR3D, XML_CLOSE_FRONT, XML_TYPE_BOOL, 0 ),
+ GMAP( PROP_D3DCloseBack, XML_NAMESPACE_DR3D, XML_CLOSE_BACK, XML_TYPE_BOOL, 0 ),
+
+ // 3D lighting attributes
+ GMAP( PROP_D3DNormalsKind, XML_NAMESPACE_DR3D, XML_NORMALS_KIND, XML_SD_TYPE_NORMALS_KIND, 0 ),
+ GMAP( PROP_D3DNormalsInvert, XML_NAMESPACE_DR3D, XML_NORMALS_DIRECTION, XML_SD_TYPE_NORMALS_DIRECTION, 0 ),
+
+ // 3D texture attributes
+ GMAP( PROP_D3DTextureProjectionX, XML_NAMESPACE_DR3D, XML_TEX_GENERATION_MODE_X, XML_SD_TYPE_TEX_GENERATION_MODE_X, 0 ),
+ GMAP( PROP_D3DTextureProjectionY, XML_NAMESPACE_DR3D, XML_TEX_GENERATION_MODE_Y, XML_SD_TYPE_TEX_GENERATION_MODE_Y, 0 ),
+ GMAP( PROP_D3DTextureKind, XML_NAMESPACE_DR3D, XML_TEX_KIND, XML_SD_TYPE_TEX_KIND, 0 ),
+ GMAP( PROP_D3DTextureMode, XML_NAMESPACE_DR3D, XML_TEX_MODE, XML_SD_TYPE_TEX_MODE, 0 ),
+ GMAP( PROP_D3DTextureFilter, XML_NAMESPACE_DR3D, XML_TEX_FILTER, XML_SD_TYPE_BACKFACE_CULLING, 0 ),
+
+ // 3D material attributes
+ GMAP( PROP_D3DMaterialColor, XML_NAMESPACE_DR3D, XML_DIFFUSE_COLOR, XML_TYPE_COLOR, 0 ),
+ GMAP( PROP_D3DMaterialEmission, XML_NAMESPACE_DR3D, XML_EMISSIVE_COLOR, XML_TYPE_COLOR, 0 ),
+ GMAP( PROP_D3DMaterialSpecular, XML_NAMESPACE_DR3D, XML_SPECULAR_COLOR, XML_TYPE_COLOR, 0 ),
+ GMAP( PROP_D3DMaterialSpecularIntensity, XML_NAMESPACE_DR3D, XML_SHININESS, XML_TYPE_PERCENT, 0 ),
+
+ // 3D shadow attributes
+ GMAP( PROP_D3DShadow3D, XML_NAMESPACE_DR3D, XML_SHADOW, XML_SD_TYPE_VISIBLE_HIDDEN, 0 ),
+
+ // #FontWork# attributes
+ GMAP( PROP_FontWorkStyle, XML_NAMESPACE_DRAW, XML_FONTWORK_STYLE, XML_SD_TYPE_FONTWORK_STYLE| MID_FLAG_ELEMENT_ITEM_EXPORT, CTF_FONTWORK_STYLE ),
+ GMAP( PROP_FontWorkAdjust, XML_NAMESPACE_DRAW, XML_FONTWORK_ADJUST, XML_SD_TYPE_FONTWORK_ADJUST | MID_FLAG_ELEMENT_ITEM_EXPORT,CTF_FONTWORK_ADJUST ),
+ GMAP( PROP_FontWorkDistance, XML_NAMESPACE_DRAW, XML_FONTWORK_DISTANCE, XML_TYPE_MEASURE | MID_FLAG_ELEMENT_ITEM_EXPORT, CTF_FONTWORK_DISTANCE ),
+ GMAP( PROP_FontWorkStart, XML_NAMESPACE_DRAW, XML_FONTWORK_START, XML_TYPE_MEASURE | MID_FLAG_ELEMENT_ITEM_EXPORT, CTF_FONTWORK_START ),
+ GMAP( PROP_FontWorkMirror, XML_NAMESPACE_DRAW, XML_FONTWORK_MIRROR, XML_TYPE_BOOL | MID_FLAG_ELEMENT_ITEM_EXPORT, CTF_FONTWORK_MIRROR ),
+ GMAP( PROP_FontWorkOutline, XML_NAMESPACE_DRAW, XML_FONTWORK_OUTLINE, XML_TYPE_BOOL | MID_FLAG_ELEMENT_ITEM_EXPORT, CTF_FONTWORK_OUTLINE ),
+ GMAP( PROP_FontWorkShadow, XML_NAMESPACE_DRAW, XML_FONTWORK_SHADOW, XML_SD_TYPE_FONTWORK_SHADOW | MID_FLAG_ELEMENT_ITEM_EXPORT,CTF_FONTWORK_SHADOW ),
+ GMAP( PROP_FontWorkShadowColor, XML_NAMESPACE_DRAW, XML_FONTWORK_SHADOW_COLOR, XML_TYPE_COLOR | MID_FLAG_ELEMENT_ITEM_EXPORT, CTF_FONTWORK_SHADOWCOLOR ),
+ GMAP( PROP_FontWorkShadowOffsetX, XML_NAMESPACE_DRAW, XML_FONTWORK_SHADOW_OFFSET_X, XML_TYPE_MEASURE | MID_FLAG_ELEMENT_ITEM_EXPORT, CTF_FONTWORK_SHADOWOFFSETX ),
+ GMAP( PROP_FontWorkShadowOffsetY, XML_NAMESPACE_DRAW, XML_FONTWORK_SHADOW_OFFSET_Y, XML_TYPE_MEASURE | MID_FLAG_ELEMENT_ITEM_EXPORT, CTF_FONTWORK_SHADOWOFFSETY ),
+ GMAP( PROP_FontWorkForm, XML_NAMESPACE_DRAW, XML_FONTWORK_FORM, XML_SD_TYPE_FONTWORK_FORM | MID_FLAG_ELEMENT_ITEM_EXPORT, CTF_FONTWORK_FORM ),
+ GMAP( PROP_FontWorkHideForm, XML_NAMESPACE_DRAW, XML_FONTWORK_HIDE_FORM, XML_TYPE_BOOL | MID_FLAG_ELEMENT_ITEM_EXPORT, CTF_FONTWORK_HIDEFORM ),
+ GMAP( PROP_FontWorkShadowTransparence, XML_NAMESPACE_DRAW, XML_FONTWORK_SHADOW_TRANSPARENCE, XML_TYPE_PERCENT | MID_FLAG_ELEMENT_ITEM_EXPORT, CTF_FONTWORK_SHADOWTRANSPARENCE ),
+
+ // #FontWork# attributes
+ GMAPV( PROP_FontWorkStyle, XML_NAMESPACE_DRAW_EXT, XML_FONTWORK_STYLE, XML_SD_TYPE_FONTWORK_STYLE, CTF_FONTWORK_STYLE, SvtSaveOptions::ODFSVER_FUTURE_EXTENDED),
+ GMAPV( PROP_FontWorkAdjust, XML_NAMESPACE_DRAW_EXT, XML_FONTWORK_ADJUST, XML_SD_TYPE_FONTWORK_ADJUST,CTF_FONTWORK_ADJUST, SvtSaveOptions::ODFSVER_FUTURE_EXTENDED),
+ GMAPV( PROP_FontWorkDistance, XML_NAMESPACE_DRAW_EXT, XML_FONTWORK_DISTANCE, XML_TYPE_MEASURE, CTF_FONTWORK_DISTANCE, SvtSaveOptions::ODFSVER_FUTURE_EXTENDED),
+ GMAPV( PROP_FontWorkStart, XML_NAMESPACE_DRAW_EXT, XML_FONTWORK_START, XML_TYPE_MEASURE, CTF_FONTWORK_START, SvtSaveOptions::ODFSVER_FUTURE_EXTENDED),
+ GMAPV( PROP_FontWorkMirror, XML_NAMESPACE_DRAW_EXT, XML_FONTWORK_MIRROR, XML_TYPE_BOOL, CTF_FONTWORK_MIRROR, SvtSaveOptions::ODFSVER_FUTURE_EXTENDED),
+ GMAPV( PROP_FontWorkOutline, XML_NAMESPACE_DRAW_EXT, XML_FONTWORK_OUTLINE, XML_TYPE_BOOL, CTF_FONTWORK_OUTLINE, SvtSaveOptions::ODFSVER_FUTURE_EXTENDED),
+ GMAPV( PROP_FontWorkShadow, XML_NAMESPACE_DRAW_EXT, XML_FONTWORK_SHADOW, XML_SD_TYPE_FONTWORK_SHADOW,CTF_FONTWORK_SHADOW, SvtSaveOptions::ODFSVER_FUTURE_EXTENDED),
+ GMAPV( PROP_FontWorkShadowColor, XML_NAMESPACE_DRAW_EXT, XML_FONTWORK_SHADOW_COLOR, XML_TYPE_COLOR, CTF_FONTWORK_SHADOWCOLOR, SvtSaveOptions::ODFSVER_FUTURE_EXTENDED),
+ GMAPV( PROP_FontWorkShadowOffsetX, XML_NAMESPACE_DRAW_EXT, XML_FONTWORK_SHADOW_OFFSET_X, XML_TYPE_MEASURE, CTF_FONTWORK_SHADOWOFFSETX, SvtSaveOptions::ODFSVER_FUTURE_EXTENDED),
+ GMAPV( PROP_FontWorkShadowOffsetY, XML_NAMESPACE_DRAW_EXT, XML_FONTWORK_SHADOW_OFFSET_Y, XML_TYPE_MEASURE, CTF_FONTWORK_SHADOWOFFSETY, SvtSaveOptions::ODFSVER_FUTURE_EXTENDED),
+ GMAPV( PROP_FontWorkForm, XML_NAMESPACE_DRAW_EXT, XML_FONTWORK_FORM, XML_SD_TYPE_FONTWORK_FORM, CTF_FONTWORK_FORM, SvtSaveOptions::ODFSVER_FUTURE_EXTENDED),
+ GMAPV( PROP_FontWorkHideForm, XML_NAMESPACE_DRAW_EXT, XML_FONTWORK_HIDE_FORM, XML_TYPE_BOOL, CTF_FONTWORK_HIDEFORM, SvtSaveOptions::ODFSVER_FUTURE_EXTENDED),
+ GMAPV( PROP_FontWorkShadowTransparence, XML_NAMESPACE_DRAW_EXT, XML_FONTWORK_SHADOW_TRANSPARENCE, XML_TYPE_PERCENT, CTF_FONTWORK_SHADOWTRANSPARENCE, SvtSaveOptions::ODFSVER_FUTURE_EXTENDED),
+
+ // control attributes (border exists one more time for the text additions of shapes)
+ GMAP( PROP_ControlSymbolColor, XML_NAMESPACE_DRAW, XML_SYMBOL_COLOR, XML_TYPE_COLOR, 0 ),
+ GMAP( PROP_ControlBackground, XML_NAMESPACE_FO, XML_BACKGROUND_COLOR, XML_TYPE_COLOR|MID_FLAG_MULTI_PROPERTY, 0 ),
+ GMAP( PROP_ControlBorder, XML_NAMESPACE_FO, XML_BORDER, XML_SD_TYPE_CONTROL_BORDER|MID_FLAG_MULTI_PROPERTY|MID_FLAG_MERGE_ATTRIBUTE, 0 ),
+ GMAP( PROP_ControlBorderColor, XML_NAMESPACE_FO, XML_BORDER, XML_SD_TYPE_CONTROL_BORDER_COLOR|MID_FLAG_MULTI_PROPERTY|MID_FLAG_MERGE_ATTRIBUTE, 0 ),
+ GMAP( PROP_ControlDataStyle, XML_NAMESPACE_STYLE,XML_DATA_STYLE_NAME, XML_TYPE_STRING|MID_FLAG_NO_PROPERTY_EXPORT|MID_FLAG_SPECIAL_ITEM, CTF_SD_CONTROL_SHAPE_DATA_STYLE ),
+ GMAP( PROP_ControlTextEmphasis, XML_NAMESPACE_STYLE,XML_TEXT_EMPHASIZE, XML_TYPE_CONTROL_TEXT_EMPHASIZE, 0 ),
+ GMAP( PROP_ImageScaleMode, XML_NAMESPACE_STYLE,XML_REPEAT, XML_SD_TYPE_IMAGE_SCALE_MODE|MID_FLAG_MULTI_PROPERTY, 0 ),
+ GMAP( PROP_ControlWritingMode, XML_NAMESPACE_STYLE,XML_WRITING_MODE, XML_TYPE_TEXT_WRITING_MODE_WITH_DEFAULT|MID_FLAG_MULTI_PROPERTY, CTF_CONTROLWRITINGMODE ),
+
+ // special entries for floating frames
+ GMAP( PROP_FrameIsAutoScroll, XML_NAMESPACE_DRAW, XML_FRAME_DISPLAY_SCROLLBAR, XML_TYPE_BOOL|MID_FLAG_MULTI_PROPERTY, CTF_FRAME_DISPLAY_SCROLLBAR ),
+ GMAP( PROP_FrameIsBorder, XML_NAMESPACE_DRAW, XML_FRAME_DISPLAY_BORDER, XML_TYPE_BOOL|MID_FLAG_MULTI_PROPERTY, CTF_FRAME_DISPLAY_BORDER ),
+ GMAP( PROP_FrameMarginWidth, XML_NAMESPACE_DRAW, XML_FRAME_MARGIN_HORIZONTAL, XML_TYPE_MEASURE_PX|MID_FLAG_MULTI_PROPERTY, CTF_FRAME_MARGIN_HORI ),
+ GMAP( PROP_FrameMarginHeight, XML_NAMESPACE_DRAW, XML_FRAME_MARGIN_VERTICAL, XML_TYPE_MEASURE_PX|MID_FLAG_MULTI_PROPERTY, CTF_FRAME_MARGIN_VERT ),
+ GMAP( PROP_VisibleArea, XML_NAMESPACE_DRAW, XML_VISIBLE_AREA_LEFT, XML_TYPE_RECTANGLE_LEFT|MID_FLAG_MERGE_PROPERTY|MID_FLAG_MULTI_PROPERTY|MID_FLAG_NO_PROPERTY, CTF_SD_OLE_VIS_AREA_IMPORT_LEFT ),
+ GMAP( PROP_VisibleArea, XML_NAMESPACE_DRAW, XML_VISIBLE_AREA_TOP, XML_TYPE_RECTANGLE_TOP|MID_FLAG_MERGE_PROPERTY|MID_FLAG_MULTI_PROPERTY|MID_FLAG_NO_PROPERTY, CTF_SD_OLE_VIS_AREA_IMPORT_TOP ),
+ GMAP( PROP_VisibleArea, XML_NAMESPACE_DRAW, XML_VISIBLE_AREA_WIDTH, XML_TYPE_RECTANGLE_WIDTH|MID_FLAG_MERGE_PROPERTY|MID_FLAG_MULTI_PROPERTY|MID_FLAG_NO_PROPERTY, CTF_SD_OLE_VIS_AREA_IMPORT_WIDTH ),
+ GMAP( PROP_VisibleArea, XML_NAMESPACE_DRAW, XML_VISIBLE_AREA_HEIGHT, XML_TYPE_RECTANGLE_HEIGHT|MID_FLAG_MERGE_PROPERTY|MID_FLAG_MULTI_PROPERTY|MID_FLAG_NO_PROPERTY, CTF_SD_OLE_VIS_AREA_IMPORT_HEIGHT ),
+ GMAP( PROP_IsInternal, XML_NAMESPACE_DRAW, XML__EMPTY, XML_TYPE_BUILDIN_CMP_ONLY, CTF_SD_OLE_ISINTERNAL ),
+ GMAP( PROP_IsInternal, XML_NAMESPACE_DRAW, XML_VISIBLE_AREA_LEFT, XML_TYPE_RECTANGLE_LEFT|MID_FLAG_MERGE_PROPERTY|MID_FLAG_MULTI_PROPERTY|MID_FLAG_NO_PROPERTY_IMPORT, CTF_SD_OLE_VIS_AREA_EXPORT_LEFT ),
+ GMAP( PROP_IsInternal, XML_NAMESPACE_DRAW, XML_VISIBLE_AREA_TOP, XML_TYPE_RECTANGLE_TOP|MID_FLAG_MERGE_PROPERTY|MID_FLAG_MULTI_PROPERTY|MID_FLAG_NO_PROPERTY_IMPORT, CTF_SD_OLE_VIS_AREA_EXPORT_TOP ),
+ GMAP( PROP_IsInternal, XML_NAMESPACE_DRAW, XML_VISIBLE_AREA_WIDTH, XML_TYPE_RECTANGLE_WIDTH|MID_FLAG_MERGE_PROPERTY|MID_FLAG_MULTI_PROPERTY|MID_FLAG_NO_PROPERTY_IMPORT, CTF_SD_OLE_VIS_AREA_EXPORT_WIDTH ),
+ GMAP( PROP_IsInternal, XML_NAMESPACE_DRAW, XML_VISIBLE_AREA_HEIGHT, XML_TYPE_RECTANGLE_HEIGHT|MID_FLAG_MERGE_PROPERTY|MID_FLAG_MULTI_PROPERTY|MID_FLAG_NO_PROPERTY_IMPORT, CTF_SD_OLE_VIS_AREA_EXPORT_HEIGHT ),
+
+ GMAP( PROP_Aspect, XML_NAMESPACE_DRAW, XML_DRAW_ASPECT, XML_TYPE_TEXT_DRAW_ASPECT|MID_FLAG_MULTI_PROPERTY, CTF_SD_OLE_ASPECT ),
+
+ // caption properties
+ GMAP( PROP_CaptionType, XML_NAMESPACE_DRAW, XML_CAPTION_TYPE, XML_SD_TYPE_CAPTION_TYPE, 0 ),
+ GMAP( PROP_CaptionIsFixedAngle, XML_NAMESPACE_DRAW, XML_CAPTION_ANGLE_TYPE, XML_SD_TYPE_CAPTION_ANGLE_TYPE, 0 ),
+ GMAP( PROP_CaptionAngle, XML_NAMESPACE_DRAW, XML_CAPTION_ANGLE, XML_TYPE_NUMBER, 0 ),
+ GMAP( PROP_CaptionGap, XML_NAMESPACE_DRAW, XML_CAPTION_GAP, XML_TYPE_MEASURE, 0 ),
+ GMAP( PROP_CaptionEscapeDirection, XML_NAMESPACE_DRAW, XML_CAPTION_ESCAPE_DIRECTION, XML_SD_TYPE_CAPTION_ESC_DIR, 0 ),
+ GMAP( PROP_CaptionIsEscapeRelative, XML_NAMESPACE_DRAW, XML_CAPTION_ESCAPE, XML_SD_TYPE_CAPTION_IS_ESC_REL|MID_FLAG_MULTI_PROPERTY, CTF_CAPTION_ISESCREL ),
+ GMAP( PROP_CaptionEscapeRelative, XML_NAMESPACE_DRAW, XML_CAPTION_ESCAPE, XML_SD_TYPE_CAPTION_ESC_REL|MID_FLAG_MULTI_PROPERTY, CTF_CAPTION_ESCREL ),
+ GMAP( PROP_CaptionEscapeAbsolute, XML_NAMESPACE_DRAW, XML_CAPTION_ESCAPE, XML_SD_TYPE_CAPTION_ESC_ABS|MID_FLAG_MULTI_PROPERTY, CTF_CAPTION_ESCABS ),
+ GMAP( PROP_CaptionLineLength, XML_NAMESPACE_DRAW, XML_CAPTION_LINE_LENGTH, XML_TYPE_MEASURE, 0 ),
+ GMAP( PROP_CaptionIsFitLineLength, XML_NAMESPACE_DRAW, XML_CAPTION_FIT_LINE_LENGTH, XML_TYPE_BOOL, 0 ),
+
+ // misc object properties
+ GMAP( PROP_MoveProtect, XML_NAMESPACE_STYLE, XML_PROTECT, XML_SD_TYPE_MOVE_PROTECT|MID_FLAG_MULTI_PROPERTY|MID_FLAG_MERGE_ATTRIBUTE, CTF_SD_MOVE_PROTECT ),
+ GMAP( PROP_SizeProtect, XML_NAMESPACE_STYLE, XML_PROTECT, XML_SD_TYPE_SIZE_PROTECT|MID_FLAG_MULTI_PROPERTY|MID_FLAG_MERGE_ATTRIBUTE, CTF_SD_SIZE_PROTECT ),
+ GMAP( PROP_WritingMode, XML_NAMESPACE_STYLE, XML_WRITING_MODE, XML_SD_TYPE_WRITINGMODE2, CTF_WRITINGMODE2 ),
+ { PROP_WritingMode, XML_NAMESPACE_LO_EXT, XML_WRITING_MODE, XML_SD_TYPE_WRITINGMODE2|XML_TYPE_PROP_GRAPHIC, 0, SvtSaveOptions::ODFSVER_FUTURE_EXTENDED, true},
+ { PROP_Decorative, XML_NAMESPACE_LO_EXT, XML_DECORATIVE, XML_TYPE_BOOL|XML_TYPE_PROP_GRAPHIC, 0, SvtSaveOptions::ODFSVER_FUTURE_EXTENDED, false },
+
+ MAP_END()
+};
+
+// entry list for presentation page properties
+
+const XMLPropertyMapEntry aXMLSDPresPageProps[] =
+{
+ DPMAP( PROP_UserDefinedAttributes, XML_NAMESPACE_TEXT, XML_XMLNS, XML_TYPE_ATTRIBUTE_CONTAINER | MID_FLAG_SPECIAL_ITEM, 0 ),
+
+ DPMAP( PROP_Change, XML_NAMESPACE_PRESENTATION, XML_TRANSITION_TYPE, XML_SD_TYPE_PRESPAGE_TYPE, CTF_PAGE_TRANS_TYPE ),
+ DPMAP( PROP_Effect, XML_NAMESPACE_PRESENTATION, XML_TRANSITION_STYLE, XML_SD_TYPE_PRESPAGE_STYLE, CTF_PAGE_TRANS_STYLE ),
+ DPMAP( PROP_Speed, XML_NAMESPACE_PRESENTATION, XML_TRANSITION_SPEED, XML_SD_TYPE_PRESPAGE_SPEED, CTF_PAGE_TRANS_SPEED ),
+ DPMAP( PROP_HighResDuration, XML_NAMESPACE_PRESENTATION, XML_DURATION, XML_SD_TYPE_PRESPAGE_DURATION, CTF_PAGE_TRANS_DURATION ),
+ DPMAP( PROP_Visible, XML_NAMESPACE_PRESENTATION, XML_VISIBILITY, XML_SD_TYPE_PRESPAGE_VISIBILITY, CTF_PAGE_VISIBLE ),
+ DPMAP( PROP_Sound, XML_NAMESPACE_PRESENTATION, XML_SOUND, XML_TYPE_STRING|MID_FLAG_ELEMENT_ITEM, CTF_PAGE_SOUND_URL ),
+ DPMAP( PROP_BackgroundFullSize, XML_NAMESPACE_DRAW, XML_BACKGROUND_SIZE, XML_SD_TYPE_PRESPAGE_BACKSIZE, CTF_PAGE_BACKSIZE ),
+
+ DPMAP( PROP_IsBackgroundVisible, XML_NAMESPACE_PRESENTATION, XML_BACKGROUND_VISIBLE, XML_TYPE_BOOL, 0 ),
+ DPMAP( PROP_IsBackgroundObjectsVisible, XML_NAMESPACE_PRESENTATION, XML_BACKGROUND_OBJECTS_VISIBLE, XML_TYPE_BOOL, 0 ),
+
+ DPMAP( PROP_FillStyle, XML_NAMESPACE_DRAW, XML_FILL, XML_SD_TYPE_FILLSTYLE, 0 ),
+ DPMAP( PROP_FillColor, XML_NAMESPACE_DRAW, XML_FILL_COLOR, XML_TYPE_COLOR, 0 ),
+ DPMAP( PROP_FillGradientName, XML_NAMESPACE_DRAW, XML_FILL_GRADIENT_NAME, XML_TYPE_STYLENAME|MID_FLAG_NO_PROPERTY_IMPORT, CTF_FILLGRADIENTNAME ),
+ DPMAP( PROP_FillGradientStepCount, XML_NAMESPACE_DRAW, XML_GRADIENT_STEP_COUNT, XML_TYPE_NUMBER, 0 ),
+ DPMAP( PROP_FillHatchName, XML_NAMESPACE_DRAW, XML_FILL_HATCH_NAME, XML_TYPE_STYLENAME|MID_FLAG_NO_PROPERTY_IMPORT, CTF_FILLHATCHNAME ),
+ GMAP( PROP_FillBackground, XML_NAMESPACE_DRAW, XML_FILL_HATCH_SOLID, XML_TYPE_BOOL, 0 ),
+ DPMAP( PROP_FillBitmapName, XML_NAMESPACE_DRAW, XML_FILL_IMAGE_NAME, XML_TYPE_STYLENAME|MID_FLAG_NO_PROPERTY_IMPORT, CTF_FILLBITMAPNAME ),
+ DPMAP( PROP_FillTransparence, XML_NAMESPACE_DRAW, XML_OPACITY, XML_TYPE_NEG_PERCENT|MID_FLAG_MULTI_PROPERTY, 0 ),
+ DPMAP( PROP_FillTransparenceGradientName, XML_NAMESPACE_DRAW, XML_OPACITY_NAME, XML_TYPE_STYLENAME|MID_FLAG_NO_PROPERTY_IMPORT, CTF_FILLTRANSNAME ),
+ DPMAP( PROP_FillBitmapSizeX, XML_NAMESPACE_DRAW, XML_FILL_IMAGE_WIDTH, XML_SD_TYPE_FILLBITMAPSIZE|MID_FLAG_MULTI_PROPERTY, 0 ),
+ DPMAP( PROP_FillBitmapLogicalSize, XML_NAMESPACE_DRAW, XML_FILL_IMAGE_WIDTH, XML_SD_TYPE_LOGICAL_SIZE|MID_FLAG_MULTI_PROPERTY, 0 ),
+ DPMAP( PROP_FillBitmapSizeY, XML_NAMESPACE_DRAW, XML_FILL_IMAGE_HEIGHT, XML_SD_TYPE_FILLBITMAPSIZE|MID_FLAG_MULTI_PROPERTY, 0 ),
+ DPMAP( PROP_FillBitmapLogicalSize, XML_NAMESPACE_DRAW, XML_FILL_IMAGE_HEIGHT, XML_SD_TYPE_LOGICAL_SIZE|MID_FLAG_MULTI_PROPERTY, 0 ),
+ DPMAP( PROP_FillBitmapMode, XML_NAMESPACE_STYLE,XML_REPEAT, XML_SD_TYPE_BITMAP_MODE, 0 ),
+ DPMAP( PROP_FillBitmapPositionOffsetX, XML_NAMESPACE_DRAW, XML_FILL_IMAGE_REF_POINT_X, XML_TYPE_PERCENT, 0 ),
+ DPMAP( PROP_FillBitmapPositionOffsetY, XML_NAMESPACE_DRAW, XML_FILL_IMAGE_REF_POINT_Y, XML_TYPE_PERCENT, 0 ),
+ DPMAP( PROP_FillBitmapRectanglePoint, XML_NAMESPACE_DRAW, XML_FILL_IMAGE_REF_POINT, XML_SD_TYPE_BITMAP_REFPOINT, 0 ),
+ DPMAP( PROP_FillBitmapOffsetX, XML_NAMESPACE_DRAW, XML_TILE_REPEAT_OFFSET, XML_SD_TYPE_BITMAPREPOFFSETX|MID_FLAG_MULTI_PROPERTY, CTF_REPEAT_OFFSET_X ),
+ DPMAP( PROP_FillBitmapOffsetY, XML_NAMESPACE_DRAW, XML_TILE_REPEAT_OFFSET, XML_SD_TYPE_BITMAPREPOFFSETY|MID_FLAG_MULTI_PROPERTY, CTF_REPEAT_OFFSET_Y ),
+
+ DPMAP( PROP_IsHeaderVisible, XML_NAMESPACE_PRESENTATION, XML_DISPLAY_HEADER, XML_SD_TYPE_HEADER_FOOTER_VISIBILITY_TYPE, CTF_HEADER_VISIBLE ),
+ DPMAP( PROP_IsFooterVisible, XML_NAMESPACE_PRESENTATION, XML_DISPLAY_FOOTER, XML_SD_TYPE_HEADER_FOOTER_VISIBILITY_TYPE, CTF_FOOTER_VISIBLE ),
+ DPMAP( PROP_IsPageNumberVisible, XML_NAMESPACE_PRESENTATION, XML_DISPLAY_PAGE_NUMBER, XML_SD_TYPE_HEADER_FOOTER_VISIBILITY_TYPE, CTF_PAGE_NUMBER_VISIBLE ),
+ DPMAP( PROP_IsDateTimeVisible, XML_NAMESPACE_PRESENTATION, XML_DISPLAY_DATE_TIME, XML_SD_TYPE_HEADER_FOOTER_VISIBILITY_TYPE, CTF_DATE_TIME_VISIBLE ),
+
+ DPMAP( PROP_TransitionType, XML_NAMESPACE_SMIL, XML_TYPE, XML_SD_TYPE_TRANSITION_TYPE, CTF_PAGE_TRANSITION_TYPE ),
+ DPMAP( PROP_TransitionSubtype, XML_NAMESPACE_SMIL, XML_SUBTYPE, XML_SD_TYPE_TRANSTIION_SUBTYPE, CTF_PAGE_TRANSITION_SUBTYPE ),
+ DPMAP( PROP_TransitionDirection, XML_NAMESPACE_SMIL, XML_DIRECTION, XML_SD_TYPE_TRANSTIION_DIRECTION, CTF_PAGE_TRANSITION_DIRECTION ),
+ DPMAP( PROP_TransitionFadeColor, XML_NAMESPACE_SMIL, XML_FADECOLOR, XML_TYPE_COLOR, CTF_PAGE_TRANSITION_FADECOLOR ),
+ MAP_END()
+};
+
+/** contains the attribute to property mapping for a drawing layer table
+ WARNING: if attributes are added, SdXMLTableShapeContext::processAttribute needs to be updated!
+*/
+const XMLPropertyMapEntry aXMLTableShapeAttributes[] =
+{
+ MAP_( PROP_UseFirstRowStyle, XML_NAMESPACE_TABLE, XML_USE_FIRST_ROW_STYLES, XML_TYPE_BOOL, 0 ),
+ MAP_( PROP_UseLastRowStyle, XML_NAMESPACE_TABLE, XML_USE_LAST_ROW_STYLES, XML_TYPE_BOOL, 0 ),
+ MAP_( PROP_UseFirstColumnStyle, XML_NAMESPACE_TABLE, XML_USE_FIRST_COLUMN_STYLES, XML_TYPE_BOOL, 0 ),
+ MAP_( PROP_UseLastColumnStyle, XML_NAMESPACE_TABLE, XML_USE_LAST_COLUMN_STYLES, XML_TYPE_BOOL, 0 ),
+ MAP_( PROP_UseBandingRowStyle, XML_NAMESPACE_TABLE, XML_USE_BANDING_ROWS_STYLES, XML_TYPE_BOOL, 0 ),
+ MAP_( PROP_UseBandingColumnStyle, XML_NAMESPACE_TABLE, XML_USE_BANDING_COLUMNS_STYLES, XML_TYPE_BOOL, 0 ),
+ MAP_END()
+};
+
+// implementation of factory for own graphic properties
+
+SvXMLEnumMapEntry<drawing::LineStyle> const aXML_LineStyle_EnumMap[] =
+{
+ { XML_NONE, drawing::LineStyle_NONE },
+ { XML_SOLID, drawing::LineStyle_SOLID },
+ { XML_DASH, drawing::LineStyle_DASH },
+ { XML_TOKEN_INVALID, drawing::LineStyle(0) }
+};
+
+SvXMLEnumMapEntry<drawing::LineJoint> const aXML_LineJoint_EnumMap[] =
+{
+ { XML_NONE, drawing::LineJoint_NONE },
+ { XML_MITER, drawing::LineJoint_MITER },
+ { XML_ROUND, drawing::LineJoint_ROUND },
+ { XML_BEVEL, drawing::LineJoint_BEVEL },
+ { XML_MIDDLE, drawing::LineJoint_MIDDLE },
+ { XML_TOKEN_INVALID, drawing::LineJoint(0) }
+};
+
+SvXMLEnumMapEntry<drawing::LineCap> const aXML_LineCap_EnumMap[] =
+{
+ { XML_BUTT, drawing::LineCap_BUTT },
+ { XML_ROUND, drawing::LineCap_ROUND },
+ // use XML_GRADIENTSTYLE_SQUARE as XML_SQUARE, is defined as "square" already
+ { XML_GRADIENTSTYLE_SQUARE, drawing::LineCap_SQUARE },
+ { XML_TOKEN_INVALID, drawing::LineCap(0) }
+};
+
+SvXMLEnumMapEntry<drawing::FillStyle> const aXML_FillStyle_EnumMap[] =
+{
+ { XML_NONE, drawing::FillStyle_NONE },
+ { XML_SOLID, drawing::FillStyle_SOLID },
+ { XML_BITMAP, drawing::FillStyle_BITMAP },
+ { XML_GRADIENT, drawing::FillStyle_GRADIENT },
+ { XML_HATCH, drawing::FillStyle_HATCH },
+ { XML_TOKEN_INVALID, drawing::FillStyle(0) }
+};
+
+SvXMLEnumMapEntry<sal_Int32> const aXML_PresChange_EnumMap[] =
+{
+ { XML_MANUAL, 0 },
+ { XML_AUTOMATIC, 1 },
+ { XML_SEMI_AUTOMATIC, 2 },
+ { XML_TOKEN_INVALID, 0 }
+};
+
+SvXMLEnumMapEntry<presentation::AnimationSpeed> const aXML_TransSpeed_EnumMap[] =
+{
+ { XML_FAST, presentation::AnimationSpeed_FAST },
+ { XML_MEDIUM, presentation::AnimationSpeed_MEDIUM },
+ { XML_SLOW, presentation::AnimationSpeed_SLOW },
+ { XML_TOKEN_INVALID, presentation::AnimationSpeed(0) }
+};
+
+SvXMLEnumMapEntry<presentation::FadeEffect> const aXML_FadeEffect_EnumMap[] =
+{
+ { XML_NONE, presentation::FadeEffect_NONE },
+ { XML_FADE_FROM_LEFT, presentation::FadeEffect_FADE_FROM_LEFT },
+ { XML_FADE_FROM_TOP, presentation::FadeEffect_FADE_FROM_TOP },
+ { XML_FADE_FROM_RIGHT, presentation::FadeEffect_FADE_FROM_RIGHT },
+ { XML_FADE_FROM_BOTTOM, presentation::FadeEffect_FADE_FROM_BOTTOM },
+ { XML_FADE_TO_CENTER, presentation::FadeEffect_FADE_TO_CENTER },
+ { XML_FADE_FROM_CENTER, presentation::FadeEffect_FADE_FROM_CENTER },
+ { XML_MOVE_FROM_LEFT, presentation::FadeEffect_MOVE_FROM_LEFT },
+ { XML_MOVE_FROM_TOP, presentation::FadeEffect_MOVE_FROM_TOP },
+ { XML_MOVE_FROM_RIGHT, presentation::FadeEffect_MOVE_FROM_RIGHT },
+ { XML_MOVE_FROM_BOTTOM, presentation::FadeEffect_MOVE_FROM_BOTTOM },
+ { XML_ROLL_FROM_TOP, presentation::FadeEffect_ROLL_FROM_TOP },
+ { XML_ROLL_FROM_LEFT, presentation::FadeEffect_ROLL_FROM_LEFT },
+ { XML_ROLL_FROM_RIGHT, presentation::FadeEffect_ROLL_FROM_RIGHT },
+ { XML_ROLL_FROM_BOTTOM, presentation::FadeEffect_ROLL_FROM_BOTTOM },
+ { XML_VERTICAL_STRIPES, presentation::FadeEffect_VERTICAL_STRIPES },
+ { XML_HORIZONTAL_STRIPES, presentation::FadeEffect_HORIZONTAL_STRIPES },
+ { XML_CLOCKWISE, presentation::FadeEffect_CLOCKWISE },
+ { XML_COUNTERCLOCKWISE, presentation::FadeEffect_COUNTERCLOCKWISE },
+ { XML_FADE_FROM_UPPERLEFT, presentation::FadeEffect_FADE_FROM_UPPERLEFT },
+ { XML_FADE_FROM_UPPERRIGHT, presentation::FadeEffect_FADE_FROM_UPPERRIGHT },
+ { XML_FADE_FROM_LOWERLEFT, presentation::FadeEffect_FADE_FROM_LOWERLEFT },
+ { XML_FADE_FROM_LOWERRIGHT, presentation::FadeEffect_FADE_FROM_LOWERRIGHT },
+ { XML_CLOSE_VERTICAL, presentation::FadeEffect_CLOSE_VERTICAL },
+ { XML_CLOSE_HORIZONTAL, presentation::FadeEffect_CLOSE_HORIZONTAL },
+ { XML_OPEN_VERTICAL, presentation::FadeEffect_OPEN_VERTICAL },
+ { XML_OPEN_HORIZONTAL, presentation::FadeEffect_OPEN_HORIZONTAL },
+ { XML_SPIRALIN_LEFT, presentation::FadeEffect_SPIRALIN_LEFT },
+ { XML_SPIRALIN_RIGHT, presentation::FadeEffect_SPIRALIN_RIGHT },
+ { XML_SPIRALOUT_LEFT, presentation::FadeEffect_SPIRALOUT_LEFT },
+ { XML_SPIRALOUT_RIGHT, presentation::FadeEffect_SPIRALOUT_RIGHT },
+ { XML_DISSOLVE, presentation::FadeEffect_DISSOLVE },
+ { XML_WAVYLINE_FROM_LEFT, presentation::FadeEffect_WAVYLINE_FROM_LEFT },
+ { XML_WAVYLINE_FROM_TOP, presentation::FadeEffect_WAVYLINE_FROM_TOP },
+ { XML_WAVYLINE_FROM_RIGHT, presentation::FadeEffect_WAVYLINE_FROM_RIGHT },
+ { XML_WAVYLINE_FROM_BOTTOM, presentation::FadeEffect_WAVYLINE_FROM_BOTTOM },
+ { XML_RANDOM, presentation::FadeEffect_RANDOM },
+ { XML_STRETCH_FROM_LEFT, presentation::FadeEffect_STRETCH_FROM_LEFT },
+ { XML_STRETCH_FROM_TOP, presentation::FadeEffect_STRETCH_FROM_TOP },
+ { XML_STRETCH_FROM_RIGHT, presentation::FadeEffect_STRETCH_FROM_RIGHT },
+ { XML_STRETCH_FROM_BOTTOM, presentation::FadeEffect_STRETCH_FROM_BOTTOM },
+ { XML_VERTICAL_LINES, presentation::FadeEffect_VERTICAL_LINES },
+ { XML_HORIZONTAL_LINES, presentation::FadeEffect_HORIZONTAL_LINES },
+ { XML_MOVE_FROM_UPPERLEFT, presentation::FadeEffect_MOVE_FROM_UPPERLEFT },
+ { XML_MOVE_FROM_UPPERRIGHT, presentation::FadeEffect_MOVE_FROM_UPPERRIGHT },
+ { XML_MOVE_FROM_LOWERRIGHT, presentation::FadeEffect_MOVE_FROM_LOWERRIGHT },
+ { XML_MOVE_FROM_LOWERLEFT, presentation::FadeEffect_MOVE_FROM_LOWERLEFT },
+ { XML_UNCOVER_TO_LEFT, presentation::FadeEffect_UNCOVER_TO_LEFT },
+ { XML_UNCOVER_TO_UPPERLEFT, presentation::FadeEffect_UNCOVER_TO_UPPERLEFT },
+ { XML_UNCOVER_TO_TOP, presentation::FadeEffect_UNCOVER_TO_TOP },
+ { XML_UNCOVER_TO_UPPERRIGHT,presentation::FadeEffect_UNCOVER_TO_UPPERRIGHT },
+ { XML_UNCOVER_TO_RIGHT, presentation::FadeEffect_UNCOVER_TO_RIGHT },
+ { XML_UNCOVER_TO_LOWERRIGHT,presentation::FadeEffect_UNCOVER_TO_LOWERRIGHT },
+ { XML_UNCOVER_TO_BOTTOM, presentation::FadeEffect_UNCOVER_TO_BOTTOM },
+ { XML_UNCOVER_TO_LOWERLEFT, presentation::FadeEffect_UNCOVER_TO_LOWERLEFT },
+ { XML_VERTICAL_CHECKERBOARD,presentation::FadeEffect_VERTICAL_CHECKERBOARD },
+ { XML_HORIZONTAL_CHECKERBOARD,presentation::FadeEffect_HORIZONTAL_CHECKERBOARD },
+ { XML_TOKEN_INVALID, presentation::FadeEffect(0) }
+};
+
+SvXMLEnumMapEntry<drawing::ConnectorType> const aXML_ConnectionKind_EnumMap[] =
+{
+ { XML_STANDARD, drawing::ConnectorType_STANDARD },
+ { XML_CURVE, drawing::ConnectorType_CURVE },
+ { XML_LINE, drawing::ConnectorType_LINE },
+ { XML_LINES, drawing::ConnectorType_LINES },
+ { XML_TOKEN_INVALID, drawing::ConnectorType(0) }
+};
+
+SvXMLEnumMapEntry<drawing::BitmapMode> const aXML_BitmapMode_EnumMap[] =
+{
+ { XML_REPEAT, drawing::BitmapMode_REPEAT },
+ { XML_STRETCH, drawing::BitmapMode_STRETCH },
+ { XML_BACKGROUND_NO_REPEAT, drawing::BitmapMode_NO_REPEAT },
+ { XML_TOKEN_INVALID, drawing::BitmapMode(0) }
+};
+
+// 3D EnumMaps
+
+SvXMLEnumMapEntry<drawing::NormalsKind> const aXML_NormalsKind_EnumMap[] =
+{
+ { XML_OBJECT, drawing::NormalsKind_SPECIFIC },
+ { XML_FLAT, drawing::NormalsKind_FLAT },
+ { XML_SPHERE, drawing::NormalsKind_SPHERE },
+ { XML_TOKEN_INVALID, drawing::NormalsKind(0) }
+};
+
+SvXMLEnumMapEntry<drawing::TextureProjectionMode> const aXML_TexGenerationX_EnumMap[] =
+{
+ { XML_OBJECT, drawing::TextureProjectionMode_OBJECTSPECIFIC },
+ { XML_PARALLEL, drawing::TextureProjectionMode_PARALLEL },
+ { XML_SPHERE, drawing::TextureProjectionMode_SPHERE },
+ { XML_TOKEN_INVALID, drawing::TextureProjectionMode(0) }
+};
+
+SvXMLEnumMapEntry<drawing::TextureProjectionMode> const aXML_TexGenerationY_EnumMap[] =
+{
+ { XML_OBJECT, drawing::TextureProjectionMode_OBJECTSPECIFIC },
+ { XML_PARALLEL, drawing::TextureProjectionMode_PARALLEL },
+ { XML_SPHERE, drawing::TextureProjectionMode_SPHERE },
+ { XML_TOKEN_INVALID, drawing::TextureProjectionMode(0) }
+};
+
+SvXMLEnumMapEntry<drawing::TextureKind> const aXML_TexKind_EnumMap[] =
+{
+ { XML_LUMINANCE, drawing::TextureKind_LUMINANCE },
+ { XML_COLOR, drawing::TextureKind_COLOR },
+ { XML_TOKEN_INVALID, drawing::TextureKind(0) }
+};
+
+SvXMLEnumMapEntry<drawing::TextureMode> const aXML_TexMode_EnumMap[] =
+{
+ { XML_REPLACE, drawing::TextureMode_REPLACE },
+ { XML_MODULATE, drawing::TextureMode_MODULATE },
+ { XML_BLEND, drawing::TextureMode_BLEND },
+ { XML_TOKEN_INVALID, drawing::TextureMode(0) }
+};
+
+SvXMLEnumMapEntry<drawing::RectanglePoint> const aXML_RefPoint_EnumMap[] =
+{
+ { XML_TOP_LEFT, drawing::RectanglePoint_LEFT_TOP },
+ { XML_TOP, drawing::RectanglePoint_MIDDLE_TOP },
+ { XML_TOP_RIGHT, drawing::RectanglePoint_RIGHT_TOP },
+ { XML_LEFT, drawing::RectanglePoint_LEFT_MIDDLE },
+ { XML_CENTER, drawing::RectanglePoint_MIDDLE_MIDDLE },
+ { XML_RIGHT, drawing::RectanglePoint_RIGHT_MIDDLE },
+ { XML_BOTTOM_LEFT, drawing::RectanglePoint_LEFT_BOTTOM },
+ { XML_BOTTOM, drawing::RectanglePoint_MIDDLE_BOTTOM },
+ { XML_BOTTOM_RIGHT, drawing::RectanglePoint_RIGHT_BOTTOM },
+ { XML_TOKEN_INVALID, drawing::RectanglePoint(0) }
+};
+
+SvXMLEnumMapEntry<drawing::CircleKind> const aXML_CircleKind_EnumMap[] =
+{
+ { XML_FULL, drawing::CircleKind_FULL },
+ { XML_SECTION, drawing::CircleKind_SECTION },
+ { XML_CUT, drawing::CircleKind_CUT },
+ { XML_ARC, drawing::CircleKind_ARC },
+ { XML_TOKEN_INVALID, drawing::CircleKind(0) }
+};
+
+SvXMLEnumMapEntry<text::WritingMode> const aXML_WritingMode_EnumMap[] =
+{
+ { XML_TB_RL, text::WritingMode_TB_RL },
+ { XML_LR_TB, text::WritingMode_LR_TB },
+ { XML_TOKEN_INVALID, text::WritingMode(0) }
+};
+
+SvXMLEnumMapEntry<sal_Int16> const aXML_WritingMode2_EnumMap[] =
+{
+ { XML_LR_TB, text::WritingMode2::LR_TB },
+ { XML_RL_TB, text::WritingMode2::RL_TB },
+ { XML_TB_RL, text::WritingMode2::TB_RL },
+ { XML_TB_LR, text::WritingMode2::TB_LR },
+ { XML_PAGE, text::WritingMode2::CONTEXT },
+ { XML_BT_LR, text::WritingMode2::BT_LR },
+ { XML_TB_RL90, text::WritingMode2::TB_RL90 },
+ { XML_TOKEN_INVALID, text::WritingMode2::LR_TB }
+};
+
+SvXMLEnumMapEntry<drawing::TextAnimationKind> const pXML_TextAnimation_Enum[] =
+{
+ { XML_NONE, drawing::TextAnimationKind_NONE },
+ { XML_BLINKING, drawing::TextAnimationKind_BLINK }, // will be filtered
+ { XML_SCROLL, drawing::TextAnimationKind_SCROLL },
+ { XML_ALTERNATE, drawing::TextAnimationKind_ALTERNATE },
+ { XML_SLIDE, drawing::TextAnimationKind_SLIDE },
+ { XML_TOKEN_INVALID, drawing::TextAnimationKind(0) }
+};
+
+SvXMLEnumMapEntry<drawing::TextAnimationKind> const pXML_TextAnimation_Blinking_Enum[] =
+{
+ { XML_FALSE, drawing::TextAnimationKind_NONE },
+ { XML_TRUE, drawing::TextAnimationKind_BLINK },
+ { XML_FALSE, drawing::TextAnimationKind_SCROLL },
+ { XML_FALSE, drawing::TextAnimationKind_ALTERNATE },
+ { XML_FALSE, drawing::TextAnimationKind_SLIDE },
+ { XML_TOKEN_INVALID, drawing::TextAnimationKind(0) }
+};
+
+SvXMLEnumMapEntry<drawing::TextAnimationDirection> const pXML_TextAnimationDirection_Enum[] =
+{
+ { XML_LEFT, drawing::TextAnimationDirection_LEFT },
+ { XML_RIGHT, drawing::TextAnimationDirection_RIGHT }, // will be filtered
+ { XML_UP, drawing::TextAnimationDirection_UP },
+ { XML_DOWN, drawing::TextAnimationDirection_DOWN },
+ { XML_TOKEN_INVALID, drawing::TextAnimationDirection(0) }
+};
+
+SvXMLEnumMapEntry<drawing::TextHorizontalAdjust> const pXML_TextAlign_Enum[] =
+{
+ { XML_LEFT, drawing::TextHorizontalAdjust_LEFT },
+ { XML_CENTER, drawing::TextHorizontalAdjust_CENTER },
+ { XML_RIGHT, drawing::TextHorizontalAdjust_RIGHT },
+ { XML_JUSTIFY, drawing::TextHorizontalAdjust_BLOCK },
+ { XML_TOKEN_INVALID, drawing::TextHorizontalAdjust(0) }
+};
+
+SvXMLEnumMapEntry<drawing::TextVerticalAdjust> const pXML_VerticalAlign_Enum[] =
+{
+ { XML_TOP, drawing::TextVerticalAdjust_TOP },
+ { XML_MIDDLE, drawing::TextVerticalAdjust_CENTER },
+ { XML_BOTTOM, drawing::TextVerticalAdjust_BOTTOM },
+ { XML_JUSTIFY, drawing::TextVerticalAdjust_BLOCK },
+ { XML_TOKEN_INVALID, drawing::TextVerticalAdjust(0) }
+};
+
+// note: PROPORTIONAL and ALLLINES are the same thing now!
+SvXMLEnumMapEntry<drawing::TextFitToSizeType> const pXML_FitToSize_Enum_Odf12[] =
+{
+ { XML_FALSE, drawing::TextFitToSizeType_NONE },
+ { XML_TRUE, drawing::TextFitToSizeType_PROPORTIONAL },
+ { XML_TRUE, drawing::TextFitToSizeType_ALLLINES },
+ { XML_FALSE, drawing::TextFitToSizeType_AUTOFIT },
+ { XML_TOKEN_INVALID, drawing::TextFitToSizeType(0) }
+};
+
+SvXMLEnumMapEntry<drawing::TextFitToSizeType> const pXML_FitToSize_Enum[] =
+{
+ { XML_FALSE, drawing::TextFitToSizeType_NONE },
+ { XML_TRUE, drawing::TextFitToSizeType_PROPORTIONAL },
+ { XML_ALL, drawing::TextFitToSizeType_ALLLINES },
+ { XML_SHRINK_TO_FIT,drawing::TextFitToSizeType_AUTOFIT },
+ { XML_TOKEN_INVALID, drawing::TextFitToSizeType(0) }
+};
+
+SvXMLEnumMapEntry<drawing::TextFitToSizeType> const pXML_ShrinkToFit_Enum[] =
+{
+ { XML_FALSE, drawing::TextFitToSizeType_NONE },
+ { XML_FALSE, drawing::TextFitToSizeType_PROPORTIONAL },
+ { XML_FALSE, drawing::TextFitToSizeType_ALLLINES },
+ { XML_TRUE, drawing::TextFitToSizeType_AUTOFIT },
+ { XML_TOKEN_INVALID, drawing::TextFitToSizeType(0) }
+};
+
+SvXMLEnumMapEntry<sal_Int32> const pXML_MeasureUnit_Enum[] =
+{
+ { XML_AUTOMATIC, 0 },
+ { XML_MM, 1 },
+ { XML_UNIT_CM, 2 },
+ { XML_UNIT_M, 3 },
+ { XML_KM, 4 },
+ { XML_UNIT_PT, 6 },
+ { XML_UNIT_PC, 7 },
+ { XML_IN, 8 },
+ { XML_UNIT_FOOT, 9 },
+ { XML_MI, 10 },
+ { XML_TOKEN_INVALID,0 }
+};
+
+SvXMLEnumMapEntry<drawing::MeasureTextHorzPos> const pXML_Measure_HAlign_Enum[] =
+{
+ { XML_AUTOMATIC, drawing::MeasureTextHorzPos_AUTO },
+ { XML_LEFT_OUTSIDE, drawing::MeasureTextHorzPos_LEFTOUTSIDE },
+ { XML_INSIDE, drawing::MeasureTextHorzPos_INSIDE },
+ { XML_RIGHT_OUTSIDE, drawing::MeasureTextHorzPos_RIGHTOUTSIDE},
+ { XML_TOKEN_INVALID, drawing::MeasureTextHorzPos(0) }
+};
+
+SvXMLEnumMapEntry<drawing::MeasureTextVertPos> const pXML_Measure_VAlign_Enum[] =
+{
+ { XML_AUTOMATIC, drawing::MeasureTextVertPos_AUTO },
+ { XML_ABOVE, drawing::MeasureTextVertPos_EAST },
+ { XML_BELOW, drawing::MeasureTextVertPos_WEST },
+ { XML_CENTER, drawing::MeasureTextVertPos_CENTERED },
+ { XML_TOKEN_INVALID, drawing::MeasureTextVertPos(0) }
+};
+
+// #FontWork#
+SvXMLEnumMapEntry<sal_Int32> const pXML_Fontwork_Style_Enum[] =
+{
+ { XML_ROTATE, 0 }, //XFormTextStyle::Rotate,
+ { XML_UPRIGHT, 1 }, //XFormTextStyle::Upright,
+ { XML_SLANT_X, 2 }, //XFormTextStyle::SlantX,
+ { XML_SLANT_Y, 3 }, //XFormTextStyle::SlantY,
+ { XML_NONE, 4 }, //XFormTextStyle::NONE
+ { XML_TOKEN_INVALID,0 }
+};
+
+SvXMLEnumMapEntry<sal_Int32> const pXML_Fontwork_Adjust_Enum[] =
+{
+ { XML_LEFT, 0 }, //XFormTextAdjust::Left,
+ { XML_RIGHT, 1 }, //XFormTextAdjust::Right,
+ { XML_AUTOSIZE, 2 }, //XFormTextAdjust::AutoSize,
+ { XML_CENTER, 3 }, //XFormTextAdjust::Center
+ { XML_TOKEN_INVALID,0 }
+};
+
+SvXMLEnumMapEntry<sal_Int32> const pXML_Fontwork_Shadow_Enum[] =
+{
+ { XML_NORMAL, 0 }, //XFormTextShadow::Normal,
+ { XML_SLANT, 1 }, //XFormTextShadow::Slant,
+ { XML_NONE, 2 }, //XFormTextShadow::NONE
+ { XML_TOKEN_INVALID,0 }
+};
+
+SvXMLEnumMapEntry<sal_Int32> const pXML_Fontwork_Form_Enum[] =
+{
+ { XML_NONE, 0 }, //XFTFORM_NONE,
+ { XML_TOPCIRCLE, 1 }, //XFTFORM_TOPCIRC,
+ { XML_BOTTOMCIRCLE, 2 }, //XFTFORM_BOTCIRC,
+ { XML_LEFTCIRCLE, 3 }, //XFTFORM_LFTCIRC,
+ { XML_RIGHTCIRCLE, 4 }, //XFTFORM_RGTCIRC,
+ { XML_TOPARC, 5 }, //XFTFORM_TOPARC,
+ { XML_BOTTOMARC, 6 }, //XFTFORM_BOTARC,
+ { XML_LEFTARC, 7 }, //XFTFORM_LFTARC,
+ { XML_RIGHTARC, 8 }, //XFTFORM_RGTARC,
+ { XML_BUTTON1, 9 }, //XFTFORM_BUTTON1,
+ { XML_BUTTON2, 10 }, //XFTFORM_BUTTON2,
+ { XML_BUTTON3, 11 }, //XFTFORM_BUTTON3,
+ { XML_BUTTON4, 12 }, //XFTFORM_BUTTON4
+ { XML_TOKEN_INVALID,0 }
+};
+
+SvXMLEnumMapEntry<sal_Int32> const pXML_Caption_Esc_Dir_Enum[] =
+{
+ { XML_HORIZONTAL, 0 }, //SdrCaptionEscDir::Horizontal,
+ { XML_VERTICAL, 1 }, //SdrCaptionEscDir::Vertical,
+ { XML_AUTO, 2 }, //SdrCaptionEscDir::BestFit,
+ { XML_TOKEN_INVALID,0 }
+};
+
+SvXMLEnumMapEntry<sal_Int32> const pXML_Caption_Type_Enum[] =
+{
+ { XML_STRAIGHT_LINE, 0 }, //SdrCaptionType::Type1,
+ { XML_ANGLED_LINE, 1 }, //SdrCaptionType::Type2,
+ { XML_ANGLED_CONNECTOR_LINE, 2 }, //SdrCaptionType::Type3,
+ { XML_TOKEN_INVALID,0 }
+};
+
+namespace {
+
+class XMLCaptionEscapeRelative : public XMLPropertyHandler
+{
+public:
+ virtual bool importXML(
+ const OUString& rStrImpValue,
+ css::uno::Any& rValue,
+ const SvXMLUnitConverter& rUnitConverter ) const override;
+ virtual bool exportXML(
+ OUString& rStrExpValue,
+ const css::uno::Any& rValue,
+ const SvXMLUnitConverter& rUnitConverter ) const override;
+};
+
+}
+
+bool XMLCaptionEscapeRelative::importXML( const OUString& rStrImpValue, Any& rValue, const SvXMLUnitConverter& ) const
+{
+ sal_Int32 nValue;
+
+ if (!::sax::Converter::convertPercent( nValue, rStrImpValue ))
+ return false;
+
+ nValue *= 100;
+ rValue <<= nValue;
+ return true;
+}
+
+bool XMLCaptionEscapeRelative::exportXML( OUString& rStrExpValue, const Any& rValue, const SvXMLUnitConverter& ) const
+{
+ sal_Int32 nValue = 0;
+ if( !(rValue >>= nValue ) )
+ return false;
+
+ nValue /= 100;
+ OUStringBuffer aOut;
+ ::sax::Converter::convertPercent( aOut, nValue );
+ rStrExpValue = aOut.makeStringAndClear();
+ return true;
+}
+
+namespace {
+
+class XMLMoveSizeProtectHdl : public XMLPropertyHandler
+{
+public:
+ explicit XMLMoveSizeProtectHdl( sal_Int32 nType ) : mnType( nType ) {}
+
+ virtual bool importXML(
+ const OUString& rStrImpValue,
+ css::uno::Any& rValue,
+ const SvXMLUnitConverter& rUnitConverter ) const override;
+ virtual bool exportXML(
+ OUString& rStrExpValue,
+ const css::uno::Any& rValue,
+ const SvXMLUnitConverter& rUnitConverter ) const override;
+private:
+ const sal_Int32 mnType;
+};
+
+}
+
+bool XMLMoveSizeProtectHdl::importXML( const OUString& rStrImpValue, Any& rValue, const SvXMLUnitConverter& ) const
+{
+ const bool bValue = rStrImpValue.indexOf( GetXMLToken( mnType == XML_SD_TYPE_MOVE_PROTECT ? XML_POSITION : XML_SIZE ) ) != -1;
+ rValue <<= bValue;
+ return true;
+}
+
+bool XMLMoveSizeProtectHdl::exportXML( OUString& rStrExpValue, const Any& rValue, const SvXMLUnitConverter& ) const
+{
+ bool bValue;
+ if( !(rValue >>= bValue ) )
+ return false;
+
+ if( bValue )
+ {
+ if( !rStrExpValue.isEmpty() )
+ rStrExpValue += " ";
+
+ rStrExpValue += GetXMLToken( mnType == XML_SD_TYPE_MOVE_PROTECT ? XML_POSITION : XML_SIZE );
+ }
+
+ return true;
+}
+
+namespace {
+
+class XMLSdHeaderFooterVisibilityTypeHdl : public XMLPropertyHandler
+{
+public:
+ virtual bool importXML( const OUString& rStrImpValue, css::uno::Any& rValue, const SvXMLUnitConverter& rUnitConverter ) const override;
+ virtual bool exportXML( OUString& rStrExpValue, const css::uno::Any& rValue, const SvXMLUnitConverter& rUnitConverter ) const override;
+};
+
+}
+
+bool XMLSdHeaderFooterVisibilityTypeHdl::importXML(
+ const OUString& rStrImpValue,
+ css::uno::Any& rValue,
+ const SvXMLUnitConverter& ) const
+{
+ // #i38644#
+ // attributes with this type where saved with VISIBLE|HIDDEN prior
+ // to src680m67. So we have to import that correctly
+ const bool bBool = IsXMLToken(rStrImpValue, XML_TRUE) || IsXMLToken(rStrImpValue, XML_VISIBLE);
+ rValue <<= bBool;
+ return bBool || IsXMLToken(rStrImpValue, XML_FALSE) || IsXMLToken(rStrImpValue, XML_HIDDEN);
+}
+
+bool XMLSdHeaderFooterVisibilityTypeHdl::exportXML(
+ OUString& rStrExpValue,
+ const Any& rValue,
+ const SvXMLUnitConverter& ) const
+{
+ bool bRet = false;
+ bool bValue;
+
+ if (rValue >>= bValue)
+ {
+ OUStringBuffer aOut;
+ ::sax::Converter::convertBool( aOut, bValue );
+ rStrExpValue = aOut.makeStringAndClear();
+
+ bRet = true;
+ }
+
+ return bRet;
+}
+
+namespace {
+
+class XMLSdRotationAngleTypeHdl : public XMLPropertyHandler
+{
+public:
+ virtual bool importXML(const OUString& rStrImpValue, css::uno::Any& rValue, const SvXMLUnitConverter& rUnitConverter) const override;
+ virtual bool exportXML(OUString& rStrExpValue, const css::uno::Any& rValue, const SvXMLUnitConverter& rUnitConverter) const override;
+};
+
+}
+
+bool XMLSdRotationAngleTypeHdl::importXML(
+ const OUString& rStrImpValue,
+ css::uno::Any& rValue,
+ const SvXMLUnitConverter&) const
+{
+ sal_Int32 nValue;
+ bool const bRet = ::sax::Converter::convertNumber(nValue, rStrImpValue);
+ if (bRet)
+ {
+ nValue = (nValue % 360);
+ if (nValue < 0)
+ nValue = 360 + nValue;
+ sal_Int32 nAngle;
+ if (nValue < 45 || nValue > 315)
+ nAngle = 0;
+ else if (nValue < 180)
+ nAngle = 9000;
+ else /* if nValue <= 315 ) */
+ nAngle = 27000;
+
+ rValue <<= nAngle;
+ }
+ return bRet;
+}
+
+bool XMLSdRotationAngleTypeHdl::exportXML(
+ OUString& rStrExpValue,
+ const Any& rValue,
+ const SvXMLUnitConverter&) const
+{
+ sal_Int32 nAngle;
+ bool bRet = (rValue >>= nAngle) && nAngle != 0;
+ if (bRet)
+ {
+ rStrExpValue = OUString::number(nAngle / 100);
+ }
+ return bRet;
+}
+
+namespace {
+
+class XMLFitToSizeEnumPropertyHdl : public XMLEnumPropertyHdl
+{
+public:
+ XMLFitToSizeEnumPropertyHdl(
+ const SvXMLEnumMapEntry<drawing::TextFitToSizeType> *const pMap)
+ : XMLEnumPropertyHdl(pMap) {}
+
+ virtual bool importXML(const OUString& rStrImpValue, uno::Any& rValue,
+ const SvXMLUnitConverter& rUC) const override
+ {
+ // we don't know here what the actual attribute name is -
+ // but we can combine the 2 attributes by just taking the
+ // "largest" result value; this can never result in ALLLINES
+ // so the implementation has to interpret PROPORTIONAL as ALLLINES;
+ // both "true" is invalid anyway.
+ Any any;
+ auto const bRet = XMLEnumPropertyHdl::importXML(rStrImpValue, any, rUC);
+ if (!bRet)
+ {
+ return false;
+ }
+ assert(any.hasValue());
+ if (!rValue.hasValue() ||
+ rValue.get<drawing::TextFitToSizeType>() < any.get<drawing::TextFitToSizeType>())
+ {
+ rValue = any;
+ }
+ return true;
+ }
+};
+
+}
+
+XMLSdPropHdlFactory::XMLSdPropHdlFactory( uno::Reference< frame::XModel > xModel, SvXMLImport& rImport )
+: mxModel(std::move( xModel )), mpExport(nullptr), mpImport( &rImport )
+{
+}
+
+XMLSdPropHdlFactory::XMLSdPropHdlFactory( uno::Reference< frame::XModel > xModel, SvXMLExport& rExport )
+: mxModel(std::move( xModel )), mpExport( &rExport ), mpImport(nullptr)
+{
+}
+
+XMLSdPropHdlFactory::~XMLSdPropHdlFactory()
+{
+}
+
+const XMLPropertyHandler* XMLSdPropHdlFactory::GetPropertyHandler( sal_Int32 nType ) const
+{
+ const XMLPropertyHandler* pHdl = XMLPropertyHandlerFactory::GetPropertyHandler( nType );
+ if(!pHdl)
+ {
+ switch(nType)
+ {
+ case XML_SD_TYPE_STROKE :
+ {
+ pHdl = new XMLEnumPropertyHdl( aXML_LineStyle_EnumMap);
+ break;
+ }
+ case XML_SD_TYPE_LINEJOIN :
+ {
+ pHdl = new XMLEnumPropertyHdl( aXML_LineJoint_EnumMap);
+ break;
+ }
+ case XML_SD_TYPE_LINECAP :
+ {
+ pHdl = new XMLEnumPropertyHdl( aXML_LineCap_EnumMap );
+ break;
+ }
+ case XML_SD_TYPE_FILLSTYLE :
+ {
+ pHdl = new XMLEnumPropertyHdl( aXML_FillStyle_EnumMap );
+ break;
+ }
+ case XML_SD_TYPE_PRESPAGE_TYPE :
+ {
+ pHdl = new XMLEnumPropertyHdl( aXML_PresChange_EnumMap );
+ break;
+ }
+ case XML_SD_TYPE_VISIBLE_HIDDEN:
+ {
+ pHdl = new XMLNamedBoolPropertyHdl( GetXMLToken(XML_VISIBLE), GetXMLToken(XML_HIDDEN) );
+ break;
+ }
+ case XML_TYPE_SD_MIRROR:
+ {
+ pHdl = new XMLNamedBoolPropertyHdl( GetXMLToken(XML_HORIZONTAL), GetXMLToken(XML_NONE) );
+ break;
+ }
+ case XML_SD_TYPE_PRESPAGE_STYLE :
+ {
+ pHdl = new XMLEnumPropertyHdl( aXML_FadeEffect_EnumMap );
+ break;
+ }
+ case XML_SD_TYPE_PRESPAGE_SPEED :
+ {
+ pHdl = new XMLEnumPropertyHdl( aXML_TransSpeed_EnumMap );
+ break;
+ }
+ case XML_SD_TYPE_PRESPAGE_DURATION :
+ {
+ pHdl = new XMLDurationPropertyHdl;
+ break;
+ }
+ case XML_SD_TYPE_TEXT_CROSSEDOUT :
+ {
+ pHdl = new XMLNamedBoolPropertyHdl( GetXMLToken(XML_SOLID), GetXMLToken(XML_NONE) );
+ break;
+ }
+ case XML_SD_TYPE_OPACITY :
+ {
+ pHdl = new XMLOpacityPropertyHdl(mpImport);
+ break;
+ }
+ case XML_SD_TYPE_WRITINGMODE :
+ {
+ pHdl = new XMLEnumPropertyHdl( aXML_WritingMode_EnumMap );
+ break;
+ }
+ case XML_SD_TYPE_WRITINGMODE2 :
+ {
+ pHdl = new XMLConstantsPropertyHandler ( aXML_WritingMode2_EnumMap, XML_LR_TB );
+ break;
+ }
+ case XML_SD_TYPE_PRESPAGE_VISIBILITY :
+ {
+ pHdl = new XMLNamedBoolPropertyHdl( GetXMLToken(XML_VISIBLE), GetXMLToken(XML_HIDDEN) );
+ break;
+ }
+ case XML_SD_TYPE_PRESPAGE_BACKSIZE:
+ {
+ pHdl = new XMLNamedBoolPropertyHdl( GetXMLToken(XML_FULL), GetXMLToken(XML_BORDER) );
+ break;
+ }
+
+ // 3D Properties
+
+ case XML_SD_TYPE_BACKFACE_CULLING:
+ {
+ // #87922# DoubleSided -> BackfaceCulling
+ // This sal_Bool needs to be flipped, DoubleSided sal_True -> NO Backface culling
+ // and vice versa.
+ pHdl = new XMLNamedBoolPropertyHdl( GetXMLToken(XML_DISABLED), GetXMLToken(XML_ENABLED) );
+ break;
+ }
+
+ case XML_SD_TYPE_NORMALS_KIND:
+ {
+ pHdl = new XMLEnumPropertyHdl( aXML_NormalsKind_EnumMap );
+ break;
+ }
+ case XML_SD_TYPE_NORMALS_DIRECTION:
+ {
+ pHdl = new XMLNamedBoolPropertyHdl( GetXMLToken(XML_NORMAL), GetXMLToken(XML_INVERSE) );
+ break;
+ }
+ case XML_SD_TYPE_TEX_GENERATION_MODE_X:
+ {
+ pHdl = new XMLEnumPropertyHdl( aXML_TexGenerationX_EnumMap );
+ break;
+ }
+ case XML_SD_TYPE_TEX_GENERATION_MODE_Y:
+ {
+ pHdl = new XMLEnumPropertyHdl( aXML_TexGenerationY_EnumMap );
+ break;
+ }
+ case XML_SD_TYPE_TEX_KIND:
+ {
+ pHdl = new XMLEnumPropertyHdl( aXML_TexKind_EnumMap );
+ break;
+ }
+ case XML_SD_TYPE_TEX_MODE:
+ {
+ pHdl = new XMLEnumPropertyHdl( aXML_TexMode_EnumMap );
+ break;
+ }
+ case XML_SD_TYPE_NUMBULLET:
+ {
+ uno::Reference<ucb::XAnyCompareFactory> xCompareFac( mxModel, uno::UNO_QUERY );
+ uno::Reference<ucb::XAnyCompare> xCompare;
+ if( xCompareFac.is() )
+ xCompare = xCompareFac->createAnyCompareByName( "NumberingRules" );
+
+ pHdl = new XMLNumRulePropHdl( xCompare );
+ break;
+ }
+ case XML_SD_TYPE_BITMAP_MODE:
+ {
+ pHdl = new XMLEnumPropertyHdl( aXML_BitmapMode_EnumMap );
+ break;
+ }
+ case XML_SD_TYPE_BITMAPREPOFFSETX:
+ case XML_SD_TYPE_BITMAPREPOFFSETY:
+ {
+ pHdl = new XMLBitmapRepeatOffsetPropertyHandler( nType == XML_SD_TYPE_BITMAPREPOFFSETX );
+ break;
+ }
+ case XML_SD_TYPE_FILLBITMAPSIZE:
+ {
+ pHdl = new XMLFillBitmapSizePropertyHandler();
+ break;
+ }
+ case XML_SD_TYPE_LOGICAL_SIZE:
+ {
+ pHdl = new XMLBitmapLogicalSizePropertyHandler();
+ break;
+ }
+ case XML_SD_TYPE_BITMAP_REFPOINT:
+ {
+ pHdl = new XMLEnumPropertyHdl( aXML_RefPoint_EnumMap);
+ break;
+ }
+ case XML_TYPE_TEXT_ANIMATION:
+ pHdl = new XMLEnumPropertyHdl( pXML_TextAnimation_Enum);
+ break;
+ case XML_TYPE_TEXT_ANIMATION_BLINKING:
+ pHdl = new XMLEnumPropertyHdl( pXML_TextAnimation_Blinking_Enum);
+ break;
+ case XML_TYPE_TEXT_ANIMATION_DIRECTION:
+ pHdl = new XMLEnumPropertyHdl( pXML_TextAnimationDirection_Enum);
+ break;
+ case XML_TYPE_TEXT_ANIMATION_STEPS:
+ pHdl = new XMLTextAnimationStepPropertyHdl;
+ break;
+ case XML_SD_TYPE_TEXT_ALIGN:
+ pHdl = new XMLEnumPropertyHdl( pXML_TextAlign_Enum);
+ break;
+ case XML_SD_TYPE_VERTICAL_ALIGN:
+ pHdl = new XMLEnumPropertyHdl( pXML_VerticalAlign_Enum);
+ break;
+ case XML_SD_TYPE_FITTOSIZE:
+ {
+ if (mpExport
+ && (mpExport->getSaneDefaultVersion() // tdf#97630
+ != SvtSaveOptions::ODFSVER_012_EXT_COMPAT))
+ {
+ pHdl = new XMLFitToSizeEnumPropertyHdl(pXML_FitToSize_Enum_Odf12);
+ }
+ else
+ { // import all values written by old LO
+ pHdl = new XMLFitToSizeEnumPropertyHdl(pXML_FitToSize_Enum);
+ }
+ }
+ break;
+ case XML_SD_TYPE_FITTOSIZE_AUTOFIT:
+ {
+ pHdl = new XMLFitToSizeEnumPropertyHdl(pXML_ShrinkToFit_Enum);
+ }
+ break;
+ case XML_SD_TYPE_MEASURE_UNIT:
+ pHdl = new XMLEnumPropertyHdl( pXML_MeasureUnit_Enum );
+ break;
+ case XML_SD_TYPE_MEASURE_HALIGN:
+ pHdl = new XMLEnumPropertyHdl( pXML_Measure_HAlign_Enum);
+ break;
+ case XML_SD_TYPE_MEASURE_VALIGN:
+ pHdl = new XMLEnumPropertyHdl( pXML_Measure_VAlign_Enum);
+ break;
+ case XML_SD_TYPE_MEASURE_PLACING:
+ {
+ pHdl = new XMLNamedBoolPropertyHdl( GetXMLToken(XML_BELOW), GetXMLToken(XML_ABOVE) );
+ }
+ break;
+ case XML_TYPE_TEXT_CLIP11:
+ pHdl = new XMLClipPropertyHandler( true );
+ break;
+ case XML_TYPE_TEXT_CLIP:
+ pHdl = new XMLClipPropertyHandler( false );
+ break;
+
+ // #FontWork#
+ case XML_SD_TYPE_FONTWORK_STYLE :
+ pHdl = new XMLEnumPropertyHdl( pXML_Fontwork_Style_Enum );
+ break;
+ case XML_SD_TYPE_FONTWORK_ADJUST :
+ pHdl = new XMLEnumPropertyHdl( pXML_Fontwork_Adjust_Enum );
+ break;
+ case XML_SD_TYPE_FONTWORK_SHADOW :
+ pHdl = new XMLEnumPropertyHdl( pXML_Fontwork_Shadow_Enum );
+ break;
+ case XML_SD_TYPE_FONTWORK_FORM :
+ pHdl = new XMLEnumPropertyHdl( pXML_Fontwork_Form_Enum );
+ break;
+
+ case XML_SD_TYPE_CONTROL_BORDER:
+ pHdl = new ::xmloff::OControlBorderHandler( ::xmloff::OControlBorderHandler::STYLE );
+ break;
+ case XML_SD_TYPE_CONTROL_BORDER_COLOR:
+ pHdl = new ::xmloff::OControlBorderHandler( ::xmloff::OControlBorderHandler::COLOR );
+ break;
+ case XML_SD_TYPE_IMAGE_SCALE_MODE:
+ pHdl = new ::xmloff::ImageScaleModeHandler;
+ break;
+ case XML_TYPE_CONTROL_TEXT_EMPHASIZE:
+ pHdl = new ::xmloff::OControlTextEmphasisHandler;
+ break;
+
+ case XML_SD_TYPE_CAPTION_ANGLE_TYPE:
+ {
+ pHdl = new XMLNamedBoolPropertyHdl( GetXMLToken(XML_FIXED), GetXMLToken(XML_FREE) );
+ break;
+ }
+ case XML_SD_TYPE_CAPTION_IS_ESC_REL:
+ pHdl = new XMLIsPercentagePropertyHandler;
+ break;
+ case XML_SD_TYPE_CAPTION_ESC_REL:
+ pHdl = new XMLCaptionEscapeRelative;
+ break;
+ case XML_SD_TYPE_CAPTION_ESC_ABS:
+ pHdl = new XMLPercentOrMeasurePropertyHandler;
+ break;
+ case XML_SD_TYPE_CAPTION_ESC_DIR:
+ pHdl = new XMLEnumPropertyHdl( pXML_Caption_Esc_Dir_Enum );
+ break;
+ case XML_SD_TYPE_CAPTION_TYPE:
+ pHdl = new XMLEnumPropertyHdl( pXML_Caption_Type_Enum );
+ break;
+ case XML_SD_TYPE_DATETIMEUPDATE:
+ pHdl = new XMLNamedBoolPropertyHdl( GetXMLToken(XML_FIXED), GetXMLToken(XML_VARIABLE) );
+ break;
+ case XML_SD_TYPE_DATETIME_FORMAT:
+ pHdl = new XMLDateTimeFormatHdl( mpExport );
+ break;
+ case XML_SD_TYPE_TRANSITION_TYPE:
+ pHdl = new XMLEnumPropertyHdl( xmloff::aAnimations_EnumMap_TransitionType );
+ break;
+ case XML_SD_TYPE_TRANSTIION_SUBTYPE:
+ pHdl = new XMLEnumPropertyHdl( xmloff::aAnimations_EnumMap_TransitionSubType );
+ break;
+ case XML_SD_TYPE_TRANSTIION_DIRECTION:
+ pHdl = new XMLNamedBoolPropertyHdl( GetXMLToken(XML_FORWARD), GetXMLToken(XML_REVERSE) );
+ break;
+ case XML_TYPE_WRAP_OPTION:
+ pHdl = new XMLWordWrapPropertyHdl( mpImport );
+ break;
+
+ case XML_SD_TYPE_MOVE_PROTECT:
+ case XML_SD_TYPE_SIZE_PROTECT:
+ pHdl = new XMLMoveSizeProtectHdl( nType );
+ break;
+ case XML_SD_TYPE_HEADER_FOOTER_VISIBILITY_TYPE:
+ pHdl = new XMLSdHeaderFooterVisibilityTypeHdl;
+ break;
+ case XML_SD_TYPE_CELL_ROTATION_ANGLE:
+ pHdl = new XMLSdRotationAngleTypeHdl;
+ break;
+ case XML_TYPE_TEXT_COLUMNS:
+ pHdl = new XMLTextColumnsPropertyHandler;
+ break;
+ case XML_TYPE_COMPLEX_COLOR:
+ pHdl = new XMLComplexColorHandler;
+ break;
+ }
+
+ if(pHdl)
+ PutHdlCache(nType, pHdl);
+ }
+
+ return pHdl;
+}
+
+XMLShapePropertySetMapper::XMLShapePropertySetMapper(const rtl::Reference< XMLPropertyHandlerFactory >& rFactoryRef,
+ bool bForExport)
+: XMLPropertySetMapper( aXMLSDProperties, rFactoryRef, bForExport )
+{
+}
+
+XMLShapePropertySetMapper::~XMLShapePropertySetMapper()
+{
+}
+
+XMLShapeExportPropertyMapper::XMLShapeExportPropertyMapper( const rtl::Reference< XMLPropertySetMapper >& rMapper, SvXMLExport& rExport )
+: SvXMLExportPropertyMapper( rMapper )
+, maNumRuleExp( rExport )
+, mbIsInAutoStyles( true )
+{
+}
+
+XMLShapeExportPropertyMapper::~XMLShapeExportPropertyMapper()
+{
+}
+
+void XMLShapeExportPropertyMapper::ContextFilter(
+ bool bEnableFoFontFamily,
+ std::vector< XMLPropertyState >& rProperties,
+ const uno::Reference< beans::XPropertySet >& rPropSet ) const
+{
+ XMLPropertyState* pRepeatOffsetX = nullptr;
+ XMLPropertyState* pRepeatOffsetY = nullptr;
+ XMLPropertyState* pTextAnimationBlinking = nullptr;
+ XMLPropertyState* pTextAnimationKind = nullptr;
+
+ // #FontWork#
+ XMLPropertyState* pFontWorkStyle = nullptr;
+ XMLPropertyState* pFontWorkAdjust = nullptr;
+ XMLPropertyState* pFontWorkDistance = nullptr;
+ XMLPropertyState* pFontWorkStart = nullptr;
+ XMLPropertyState* pFontWorkMirror = nullptr;
+ XMLPropertyState* pFontWorkOutline = nullptr;
+ XMLPropertyState* pFontWorkShadow = nullptr;
+ XMLPropertyState* pFontWorkShadowColor = nullptr;
+ XMLPropertyState* pFontWorkShadowOffsetx = nullptr;
+ XMLPropertyState* pFontWorkShadowOffsety = nullptr;
+ XMLPropertyState* pFontWorkForm = nullptr;
+ XMLPropertyState* pFontWorkHideform = nullptr;
+ XMLPropertyState* pFontWorkShadowTransparence = nullptr;
+
+ // OLE
+ XMLPropertyState* pOLEVisAreaLeft = nullptr;
+ XMLPropertyState* pOLEVisAreaTop = nullptr;
+ XMLPropertyState* pOLEVisAreaWidth = nullptr;
+ XMLPropertyState* pOLEVisAreaHeight = nullptr;
+ XMLPropertyState* pOLEIsInternal = nullptr;
+
+ // caption
+ XMLPropertyState* pCaptionIsEscRel = nullptr;
+ XMLPropertyState* pCaptionEscRel = nullptr;
+ XMLPropertyState* pCaptionEscAbs = nullptr;
+
+ // filter fo:clip
+ XMLPropertyState* pClip11State = nullptr;
+ XMLPropertyState* pClipState = nullptr;
+
+ XMLPropertyState* pGraphicWritingMode2 = nullptr;
+ XMLPropertyState* pShapeWritingMode = nullptr;
+ XMLPropertyState* pTextWritingMode = nullptr;
+ XMLPropertyState* pControlWritingMode = nullptr;
+
+ // filter properties
+ for( auto& rProp : rProperties )
+ {
+ XMLPropertyState *property = &rProp;
+ if( property->mnIndex == -1 )
+ continue;
+
+ // find properties with context
+ // to prevent writing this property set mnIndex member to -1
+ switch( getPropertySetMapper()->GetEntryContextId( property->mnIndex ))
+ {
+ case CTF_NUMBERINGRULES:
+ {
+ if( mbIsInAutoStyles )
+ property->mnIndex = -1;
+ }
+ break;
+ case CTF_SD_NUMBERINGRULES_NAME:
+ {
+ // this property is not exported in the style:properties element
+ // because it's an XIndexAccess and not a string.
+ // This will be handled in SvXMLAutoStylePoolP::exportStyleAttributes
+ // This is suboptimal
+ if( !mbIsInAutoStyles )
+ property->mnIndex = -1;
+ }
+ break;
+ case CTF_WRITINGMODE2:
+ pGraphicWritingMode2 = property;
+ break;
+ case CTF_WRITINGMODE:
+ pShapeWritingMode = property;
+ break;
+ case CTF_CONTROLWRITINGMODE:
+ pControlWritingMode = property;
+ break;
+ case CTF_TEXTWRITINGMODE:
+ pTextWritingMode = property;
+ break;
+ case CTF_REPEAT_OFFSET_X:
+ pRepeatOffsetX = property;
+ break;
+
+ case CTF_REPEAT_OFFSET_Y:
+ pRepeatOffsetY = property;
+ break;
+
+ case CTF_DASHNAME:
+ case CTF_FILLGRADIENTNAME:
+ case CTF_FILLHATCHNAME:
+ case CTF_FILLBITMAPNAME:
+ {
+ OUString aStr;
+ if( (property->maValue >>= aStr) && aStr.isEmpty() )
+ property->mnIndex = -1;
+ }
+ break;
+ case CTF_TEXTANIMATION_BLINKING:
+ pTextAnimationBlinking = property;
+ break;
+ case CTF_TEXTANIMATION_KIND:
+ pTextAnimationKind = property;
+ break;
+
+ // #FontWork#
+ case CTF_FONTWORK_STYLE: pFontWorkStyle = property; break;
+ case CTF_FONTWORK_ADJUST: pFontWorkAdjust = property; break;
+ case CTF_FONTWORK_DISTANCE: pFontWorkDistance = property; break;
+ case CTF_FONTWORK_START: pFontWorkStart = property; break;
+ case CTF_FONTWORK_MIRROR: pFontWorkMirror = property; break;
+ case CTF_FONTWORK_OUTLINE: pFontWorkOutline = property; break;
+ case CTF_FONTWORK_SHADOW: pFontWorkShadow = property; break;
+ case CTF_FONTWORK_SHADOWCOLOR: pFontWorkShadowColor = property; break;
+ case CTF_FONTWORK_SHADOWOFFSETX: pFontWorkShadowOffsetx = property; break;
+ case CTF_FONTWORK_SHADOWOFFSETY: pFontWorkShadowOffsety = property; break;
+ case CTF_FONTWORK_FORM: pFontWorkForm = property; break;
+ case CTF_FONTWORK_HIDEFORM: pFontWorkHideform = property; break;
+ case CTF_FONTWORK_SHADOWTRANSPARENCE: pFontWorkShadowTransparence = property; break;
+
+ // OLE
+ case CTF_SD_OLE_VIS_AREA_EXPORT_LEFT: pOLEVisAreaLeft = property; break;
+ case CTF_SD_OLE_VIS_AREA_EXPORT_TOP: pOLEVisAreaTop = property; break;
+ case CTF_SD_OLE_VIS_AREA_EXPORT_WIDTH: pOLEVisAreaWidth = property; break;
+ case CTF_SD_OLE_VIS_AREA_EXPORT_HEIGHT: pOLEVisAreaHeight = property; break;
+ case CTF_SD_OLE_ISINTERNAL: pOLEIsInternal = property; break;
+
+ case CTF_FRAME_DISPLAY_SCROLLBAR:
+ {
+ if( !property->maValue.hasValue() )
+ property->mnIndex = -1;
+ }
+ break;
+ case CTF_FRAME_MARGIN_HORI:
+ case CTF_FRAME_MARGIN_VERT:
+ {
+ sal_Int32 nValue = 0;
+ if( (property->maValue >>= nValue) && (nValue < 0) )
+ property->mnIndex = -1;
+ }
+ break;
+
+ case CTF_SD_MOVE_PROTECT:
+ {
+ bool bProtected;
+ if( (property->maValue >>= bProtected) && !bProtected )
+ property->mnIndex = -1;
+ }
+ break;
+ case CTF_SD_SIZE_PROTECT:
+ {
+ bool bProtected;
+ if( (property->maValue >>= bProtected) && !bProtected )
+ property->mnIndex = -1;
+ }
+ break;
+ case CTF_CAPTION_ISESCREL: pCaptionIsEscRel = property; break;
+ case CTF_CAPTION_ESCREL: pCaptionEscRel = property; break;
+ case CTF_CAPTION_ESCABS: pCaptionEscAbs = property; break;
+ case CTF_TEXT_CLIP11: pClip11State = property; break;
+ case CTF_TEXT_CLIP: pClipState = property; break;
+ }
+ }
+
+ if (pGraphicWritingMode2)
+ {
+ // A style:writing-mode attribute G in graphic-properties is only evaluated if there is no
+ // style:writing-mode attribute P in the paragraph-properties of the same graphic style.
+ // Otherwise the value of P is used. For values lr-tb, rl-tb and tb-rl the values G and P
+ // should be the same. But other values in G cannot be expressed in P and would produce default
+ // 0 value in P, preventing evaluation of G.
+ sal_Int16 eGraphicWritingMode;
+ if ((pGraphicWritingMode2->maValue >>= eGraphicWritingMode)
+ && eGraphicWritingMode >= text::WritingMode2::TB_LR && pShapeWritingMode)
+ pShapeWritingMode->mnIndex = -1;
+ }
+
+ // check for duplicate writing mode
+ if( pShapeWritingMode && (pTextWritingMode || pControlWritingMode) )
+ {
+ if( pTextWritingMode )
+ pTextWritingMode->mnIndex = -1;
+ if( pControlWritingMode )
+ pControlWritingMode->mnIndex = -1;
+
+ text::WritingMode eWritingMode;
+ if( pShapeWritingMode->maValue >>= eWritingMode )
+ {
+ if( text::WritingMode_LR_TB == eWritingMode )
+ {
+ pShapeWritingMode->mnIndex = -1;
+ pShapeWritingMode = nullptr;
+ }
+ }
+ }
+ else if( pTextWritingMode && pControlWritingMode )
+ {
+ pControlWritingMode->mnIndex = -1;
+
+ sal_Int32 eWritingMode;
+ if (pTextWritingMode->maValue >>= eWritingMode)
+ {
+ if (text::WritingMode2::LR_TB == eWritingMode)
+ {
+ pTextWritingMode->mnIndex = -1;
+ pTextWritingMode = nullptr;
+ }
+ }
+ }
+
+ // do not export visual area for internal ole objects
+ if( pOLEIsInternal )
+ {
+ bool bInternal;
+ if( (pOLEIsInternal->maValue >>= bInternal) && !bInternal )
+ {
+ try
+ {
+ awt::Rectangle aRect;
+ if( rPropSet->getPropertyValue( "VisibleArea" ) >>= aRect )
+ {
+ if( pOLEVisAreaLeft )
+ {
+ pOLEVisAreaLeft->mnIndex = getPropertySetMapper()->FindEntryIndex( CTF_SD_OLE_VIS_AREA_IMPORT_LEFT );
+ pOLEVisAreaLeft->maValue <<= aRect;
+ }
+ if( pOLEVisAreaTop )
+ {
+ pOLEVisAreaTop->mnIndex = getPropertySetMapper()->FindEntryIndex( CTF_SD_OLE_VIS_AREA_IMPORT_TOP );
+ pOLEVisAreaTop->maValue <<= aRect;
+ }
+ if( pOLEVisAreaWidth )
+ {
+ pOLEVisAreaWidth->mnIndex = getPropertySetMapper()->FindEntryIndex( CTF_SD_OLE_VIS_AREA_IMPORT_WIDTH );
+ pOLEVisAreaWidth->maValue <<= aRect;
+ }
+ if( pOLEVisAreaHeight )
+ {
+ pOLEVisAreaHeight->mnIndex = getPropertySetMapper()->FindEntryIndex( CTF_SD_OLE_VIS_AREA_IMPORT_HEIGHT );
+ pOLEVisAreaHeight->maValue <<= aRect;
+ }
+ }
+ }
+ catch( uno::Exception& )
+ {
+ }
+ }
+ else
+ {
+ if( pOLEVisAreaLeft ) pOLEVisAreaLeft->mnIndex = -1;
+ if( pOLEVisAreaTop ) pOLEVisAreaTop->mnIndex = -1;
+ if( pOLEVisAreaWidth ) pOLEVisAreaWidth->mnIndex = -1;
+ if( pOLEVisAreaHeight ) pOLEVisAreaHeight->mnIndex = -1;
+ }
+
+ pOLEIsInternal->mnIndex = -1;
+ }
+
+ if( pTextAnimationBlinking && pTextAnimationKind )
+ {
+ drawing::TextAnimationKind eKind;
+ if( (pTextAnimationKind->maValue >>= eKind) && eKind != drawing::TextAnimationKind_BLINK )
+ {
+ pTextAnimationBlinking->mnIndex = -1;
+ }
+ else
+ {
+ pTextAnimationKind->mnIndex = -1;
+ }
+ }
+
+ if( pRepeatOffsetX && pRepeatOffsetY )
+ {
+ sal_Int32 nOffset = 0;
+ if( ( pRepeatOffsetX->maValue >>= nOffset ) && ( nOffset == 0 ) )
+ pRepeatOffsetX->mnIndex = -1;
+ else
+ pRepeatOffsetY->mnIndex = -1;
+ }
+
+ if(pFontWorkStyle)
+ {
+ // #FontWork#
+ sal_Int32 nStyle = 0;
+
+ if(pFontWorkStyle->maValue >>= nStyle)
+ {
+ if(/*XFormTextStyle::NONE*/4 == nStyle)
+ {
+ pFontWorkStyle->mnIndex = -1;
+ if(pFontWorkAdjust)
+ pFontWorkAdjust->mnIndex = -1;
+ if(pFontWorkDistance)
+ pFontWorkDistance->mnIndex = -1;
+ if(pFontWorkStart)
+ pFontWorkStart->mnIndex = -1;
+ if(pFontWorkMirror)
+ pFontWorkMirror->mnIndex = -1;
+ if(pFontWorkOutline)
+ pFontWorkOutline->mnIndex = -1;
+ if(pFontWorkShadow)
+ pFontWorkShadow->mnIndex = -1;
+ if(pFontWorkShadowColor)
+ pFontWorkShadowColor->mnIndex = -1;
+ if(pFontWorkShadowOffsetx)
+ pFontWorkShadowOffsetx->mnIndex = -1;
+ if(pFontWorkShadowOffsety)
+ pFontWorkShadowOffsety->mnIndex = -1;
+ if(pFontWorkForm)
+ pFontWorkForm->mnIndex = -1;
+ if(pFontWorkHideform)
+ pFontWorkHideform->mnIndex = -1;
+ if(pFontWorkShadowTransparence)
+ pFontWorkShadowTransparence->mnIndex = -1;
+ }
+ }
+ }
+
+ if( pCaptionIsEscRel )
+ {
+ bool bIsRel = false;
+ pCaptionIsEscRel->maValue >>= bIsRel;
+
+ if( bIsRel )
+ {
+ if( pCaptionEscAbs )
+ pCaptionEscAbs->mnIndex = -1;
+ }
+ else
+ {
+ if( pCaptionEscRel )
+ pCaptionEscRel->mnIndex = -1;
+ }
+
+ pCaptionIsEscRel->mnIndex = -1;
+ }
+
+ if( pClipState != nullptr && pClip11State != nullptr )
+ pClip11State->mnIndex = -1;
+
+ SvXMLExportPropertyMapper::ContextFilter(bEnableFoFontFamily, rProperties, rPropSet);
+}
+
+void XMLShapeExportPropertyMapper::handleSpecialItem(
+ comphelper::AttributeList& rAttrList,
+ const XMLPropertyState& rProperty,
+ const SvXMLUnitConverter& rUnitConverter,
+ const SvXMLNamespaceMap& rNamespaceMap,
+ const ::std::vector< XMLPropertyState > *pProperties,
+ sal_uInt32 nIdx ) const
+{
+ switch( getPropertySetMapper()->GetEntryContextId( rProperty.mnIndex ) )
+ {
+ case CTF_SD_CONTROL_SHAPE_DATA_STYLE:
+ // not to be handled by the base class
+ break;
+
+ default:
+ SvXMLExportPropertyMapper::handleSpecialItem( rAttrList, rProperty, rUnitConverter, rNamespaceMap, pProperties, nIdx );
+ break;
+ }
+}
+
+void XMLShapeExportPropertyMapper::handleElementItem(
+ SvXMLExport& rExport,
+ const XMLPropertyState& rProperty,
+ SvXmlExportFlags nFlags,
+ const ::std::vector< XMLPropertyState > *pProperties,
+ sal_uInt32 nIdx) const
+{
+ switch( getPropertySetMapper()->GetEntryContextId( rProperty.mnIndex ) )
+ {
+ case CTF_NUMBERINGRULES:
+ {
+ // only export list-styles as elements in styles section
+ if( !mbIsInAutoStyles )
+ {
+ uno::Reference< container::XIndexReplace > xNumRule( rProperty.maValue, uno::UNO_QUERY );
+ if( xNumRule.is() )
+ const_cast<XMLShapeExportPropertyMapper*>(this)->maNumRuleExp.exportNumberingRule(GetStyleName(), false, xNumRule);
+ }
+ }
+ break;
+ default:
+ SvXMLExportPropertyMapper::handleElementItem( rExport, rProperty, nFlags, pProperties, nIdx );
+ break;
+ }
+}
+
+XMLPageExportPropertyMapper::XMLPageExportPropertyMapper( const rtl::Reference< XMLPropertySetMapper >& rMapper, SvXMLExport& rExport ) :
+ SvXMLExportPropertyMapper( rMapper ),
+ mrExport( rExport )
+{
+}
+
+XMLPageExportPropertyMapper::~XMLPageExportPropertyMapper()
+{
+}
+
+void XMLPageExportPropertyMapper::ContextFilter(
+ bool bEnableFoFontFamily,
+ std::vector< XMLPropertyState >& rProperties,
+ const uno::Reference< beans::XPropertySet >& rPropSet ) const
+{
+ XMLPropertyState* pRepeatOffsetX = nullptr;
+ XMLPropertyState* pRepeatOffsetY = nullptr;
+ XMLPropertyState* pTransType = nullptr;
+ XMLPropertyState* pTransDuration = nullptr;
+ XMLPropertyState* pDateTimeUpdate = nullptr;
+ XMLPropertyState* pDateTimeFormat = nullptr;
+ XMLPropertyState* pTransitionFadeColor = nullptr;
+
+ sal_Int16 nTransitionType = 0;
+
+ // filter properties
+ for( auto& rProp : rProperties )
+ {
+ XMLPropertyState *property = &rProp;
+ if( property->mnIndex == -1 )
+ continue;
+
+ // find properties with context
+ // to prevent writing this property set mnIndex member to -1
+ switch( getPropertySetMapper()->GetEntryContextId( property->mnIndex ))
+ {
+
+ case CTF_REPEAT_OFFSET_X:
+ pRepeatOffsetX = property;
+ break;
+
+ case CTF_REPEAT_OFFSET_Y:
+ pRepeatOffsetY = property;
+ break;
+ case CTF_PAGE_TRANS_TYPE:
+ pTransType = property;
+ break;
+ case CTF_PAGE_TRANS_STYLE:
+ if( mrExport.getExportFlags() & SvXMLExportFlags::OASIS )
+ (*property).mnIndex = -1;
+ break;
+ case CTF_PAGE_TRANSITION_TYPE:
+ {
+ if( (!(mrExport.getExportFlags() & SvXMLExportFlags::OASIS)) ||
+ (((*property).maValue >>= nTransitionType) && (nTransitionType == 0)) )
+ (*property).mnIndex = -1;
+ }
+ break;
+ case CTF_PAGE_TRANSITION_SUBTYPE:
+ {
+ sal_Int16 nTransitionSubtype = sal_Int16();
+ if( (!(mrExport.getExportFlags() & SvXMLExportFlags::OASIS)) ||
+ (((*property).maValue >>= nTransitionSubtype) && (nTransitionSubtype == 0)) )
+ (*property).mnIndex = -1;
+
+ }
+ break;
+ case CTF_PAGE_TRANSITION_DIRECTION:
+ {
+ bool bDirection;
+ if( (!(mrExport.getExportFlags() & SvXMLExportFlags::OASIS)) ||
+ (((*property).maValue >>= bDirection) && bDirection) )
+ (*property).mnIndex = -1;
+ }
+ break;
+ case CTF_PAGE_TRANSITION_FADECOLOR:
+ if( !(mrExport.getExportFlags() & SvXMLExportFlags::OASIS) )
+ (*property).mnIndex = -1;
+ else
+ pTransitionFadeColor = property;
+ break;
+ case CTF_PAGE_TRANS_SPEED:
+ {
+ presentation::AnimationSpeed aEnum;
+ if( ((*property).maValue >>= aEnum) && aEnum == presentation::AnimationSpeed_MEDIUM )
+ (*property).mnIndex = -1;
+ }
+ break;
+ case CTF_PAGE_VISIBLE:
+ {
+ bool bVisible = false;
+ (*property).maValue >>= bVisible;
+ if( bVisible )
+ (*property).mnIndex = -1;
+ }
+ break;
+ case CTF_PAGE_TRANS_DURATION:
+ pTransDuration = property;
+ break;
+ case CTF_HEADER_TEXT:
+ case CTF_FOOTER_TEXT:
+ case CTF_DATE_TIME_TEXT:
+ {
+ OUString aValue;
+ (*property).maValue >>= aValue;
+ if( aValue.isEmpty() )
+ (*property).mnIndex = -1;
+ }
+ break;
+
+ case CTF_DATE_TIME_UPDATE:
+ pDateTimeUpdate = property;
+ break;
+
+ case CTF_DATE_TIME_FORMAT:
+ pDateTimeFormat = property;
+ break;
+ }
+ }
+
+ if( pTransitionFadeColor && nTransitionType != css::animations::TransitionType::FADE )
+ pTransitionFadeColor->mnIndex = -1;
+
+ if( pDateTimeFormat && pDateTimeUpdate )
+ {
+ bool bIsFixed = false;
+ pDateTimeUpdate->maValue >>= bIsFixed;
+ if( bIsFixed )
+ pDateTimeFormat->mnIndex = -1;
+ }
+
+ if( pRepeatOffsetX && pRepeatOffsetY )
+ {
+ sal_Int32 nOffset = 0;
+ if( ( pRepeatOffsetX->maValue >>= nOffset ) && ( nOffset == 0 ) )
+ pRepeatOffsetX->mnIndex = -1;
+ else
+ pRepeatOffsetY->mnIndex = -1;
+ }
+
+ if( pTransType && pTransDuration )
+ {
+ sal_Int32 nChange = 0;
+ pTransType->maValue >>= nChange;
+
+ // only export duration for automatic
+ if( nChange != 1 )
+ pTransDuration->mnIndex = -1;
+
+ // do not export default transition change
+ if( nChange == 0 )
+ pTransType->mnIndex = -1;
+ }
+
+ SvXMLExportPropertyMapper::ContextFilter(bEnableFoFontFamily, rProperties, rPropSet);
+}
+
+void XMLPageExportPropertyMapper::handleElementItem(
+ SvXMLExport& rExport,
+ const XMLPropertyState& rProperty,
+ SvXmlExportFlags nFlags,
+ const ::std::vector< XMLPropertyState > *pProperties,
+ sal_uInt32 nIdx) const
+{
+ switch( getPropertySetMapper()->GetEntryContextId( rProperty.mnIndex ) )
+ {
+ case CTF_PAGE_SOUND_URL:
+ {
+ OUString aSoundURL;
+ if( (rProperty.maValue >>= aSoundURL) && !aSoundURL.isEmpty() )
+ {
+ mrExport.AddAttribute(XML_NAMESPACE_XLINK, XML_HREF, mrExport.GetRelativeReference(aSoundURL) );
+ mrExport.AddAttribute( XML_NAMESPACE_XLINK, XML_TYPE, XML_SIMPLE );
+ mrExport.AddAttribute( XML_NAMESPACE_XLINK, XML_SHOW, XML_NEW );
+ mrExport.AddAttribute( XML_NAMESPACE_XLINK, XML_ACTUATE, XML_ONREQUEST );
+ SvXMLElementExport aElem( mrExport, XML_NAMESPACE_PRESENTATION, XML_SOUND, true, true );
+ }
+ }
+ break;
+ default:
+ SvXMLExportPropertyMapper::handleElementItem( rExport, rProperty, nFlags, pProperties, nIdx );
+ break;
+ }
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/xmloff/source/draw/sdpropls.hxx b/xmloff/source/draw/sdpropls.hxx
new file mode 100644
index 0000000000..607fa3ace7
--- /dev/null
+++ b/xmloff/source/draw/sdpropls.hxx
@@ -0,0 +1,131 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#pragma once
+
+#include <com/sun/star/frame/XModel.hpp>
+#include <com/sun/star/drawing/ConnectorType.hpp>
+#include <com/sun/star/drawing/CircleKind.hpp>
+#include <xmloff/xmlnume.hxx>
+#include <xmloff/maptype.hxx>
+#include <xmloff/xmlement.hxx>
+#include <xmloff/prhdlfac.hxx>
+#include <xmloff/xmlprmap.hxx>
+#include <xmloff/xmlexppr.hxx>
+
+// entry list for graphic properties
+
+extern const XMLPropertyMapEntry aXMLSDProperties[];
+
+// entry list for presentation page properties
+
+extern const XMLPropertyMapEntry aXMLSDPresPageProps[];
+
+// enum maps for attributes
+
+extern SvXMLEnumMapEntry<css::drawing::ConnectorType> const aXML_ConnectionKind_EnumMap[];
+extern SvXMLEnumMapEntry<css::drawing::CircleKind> const aXML_CircleKind_EnumMap[];
+
+/** contains the attribute to property mapping for a drawing layer table */
+extern const XMLPropertyMapEntry aXMLTableShapeAttributes[];
+
+// factory for own graphic properties
+
+class SvXMLExport;
+class SvXMLImport;
+
+class XMLSdPropHdlFactory : public XMLPropertyHandlerFactory
+{
+private:
+ css::uno::Reference< css::frame::XModel > mxModel;
+ SvXMLExport* mpExport;
+ SvXMLImport* mpImport;
+
+public:
+ XMLSdPropHdlFactory( css::uno::Reference< css::frame::XModel > xModel, SvXMLExport& rExport );
+ XMLSdPropHdlFactory( css::uno::Reference< css::frame::XModel > xModel, SvXMLImport& rImport );
+ virtual ~XMLSdPropHdlFactory() override;
+ virtual const XMLPropertyHandler* GetPropertyHandler( sal_Int32 nType ) const override;
+};
+
+class XMLShapePropertySetMapper : public XMLPropertySetMapper
+{
+public:
+ XMLShapePropertySetMapper(const rtl::Reference< XMLPropertyHandlerFactory >& rFactoryRef, bool bForExport);
+ virtual ~XMLShapePropertySetMapper() override;
+};
+
+class XMLShapeExportPropertyMapper : public SvXMLExportPropertyMapper
+{
+private:
+ SvxXMLNumRuleExport maNumRuleExp;
+ bool mbIsInAutoStyles;
+
+protected:
+ virtual void ContextFilter(
+ bool bEnableFoFontFamily,
+ ::std::vector< XMLPropertyState >& rProperties,
+ const css::uno::Reference< css::beans::XPropertySet >& rPropSet ) const override;
+public:
+ XMLShapeExportPropertyMapper( const rtl::Reference< XMLPropertySetMapper >& rMapper, SvXMLExport& rExport );
+ virtual ~XMLShapeExportPropertyMapper() override;
+
+ virtual void handleElementItem(
+ SvXMLExport& rExport,
+ const XMLPropertyState& rProperty,
+ SvXmlExportFlags nFlags,
+ const ::std::vector< XMLPropertyState >* pProperties,
+ sal_uInt32 nIdx
+ ) const override;
+
+ void SetAutoStyles( bool bIsInAutoStyles ) { mbIsInAutoStyles = bIsInAutoStyles; }
+
+ virtual void handleSpecialItem(
+ comphelper::AttributeList& rAttrList,
+ const XMLPropertyState& rProperty,
+ const SvXMLUnitConverter& rUnitConverter,
+ const SvXMLNamespaceMap& rNamespaceMap,
+ const ::std::vector< XMLPropertyState > *pProperties,
+ sal_uInt32 nIdx ) const override;
+};
+
+class XMLPageExportPropertyMapper : public SvXMLExportPropertyMapper
+{
+private:
+ SvXMLExport& mrExport;
+
+protected:
+ virtual void ContextFilter(
+ bool bEnableFoFontFamily,
+ ::std::vector< XMLPropertyState >& rProperties,
+ const css::uno::Reference< css::beans::XPropertySet >& rPropSet ) const override;
+public:
+ XMLPageExportPropertyMapper( const rtl::Reference< XMLPropertySetMapper >& rMapper, SvXMLExport& rExport );
+ virtual ~XMLPageExportPropertyMapper() override;
+
+ virtual void handleElementItem(
+ SvXMLExport& rExport,
+ const XMLPropertyState& rProperty,
+ SvXmlExportFlags nFlags,
+ const ::std::vector< XMLPropertyState >* pProperties,
+ sal_uInt32 nIdx
+ ) const override;
+};
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/xmloff/source/draw/sdxmlexp.cxx b/xmloff/source/draw/sdxmlexp.cxx
new file mode 100644
index 0000000000..289f1a542e
--- /dev/null
+++ b/xmloff/source/draw/sdxmlexp.cxx
@@ -0,0 +1,2853 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#include <sal/config.h>
+
+#include <string_view>
+
+#include <xmloff/autolayout.hxx>
+#include <xmloff/unointerfacetouniqueidentifiermapper.hxx>
+#include <xmloff/namespacemap.hxx>
+#include <xmloff/xmlnamespace.hxx>
+#include <xmloff/xmluconv.hxx>
+#include <xmloff/xmltoken.hxx>
+#include <com/sun/star/lang/XMultiServiceFactory.hpp>
+#include <com/sun/star/presentation/XPresentationSupplier.hpp>
+#include <com/sun/star/presentation/XCustomPresentationSupplier.hpp>
+#include <com/sun/star/geometry/RealPoint2D.hpp>
+#include <com/sun/star/office/XAnnotationAccess.hpp>
+#include <com/sun/star/uno/Any.hxx>
+#include "sdxmlexp_impl.hxx"
+#include <com/sun/star/drawing/XDrawPagesSupplier.hpp>
+#include <com/sun/star/drawing/XMasterPagesSupplier.hpp>
+#include <com/sun/star/presentation/XHandoutMasterSupplier.hpp>
+#include <com/sun/star/container/XIndexContainer.hpp>
+#include <com/sun/star/view/PaperOrientation.hpp>
+#include <com/sun/star/style/XStyleFamiliesSupplier.hpp>
+
+#include <com/sun/star/form/XFormsSupplier2.hpp>
+#include <com/sun/star/presentation/XPresentationPage.hpp>
+#include <com/sun/star/drawing/XMasterPageTarget.hpp>
+#include <com/sun/star/text/XText.hpp>
+#include <com/sun/star/animations/XAnimationNodeSupplier.hpp>
+#include <com/sun/star/container/XNamed.hpp>
+#include <com/sun/star/util/Duration.hpp>
+#include <com/sun/star/util/MeasureUnit.hpp>
+#include <rtl/ustrbuf.hxx>
+#include <sal/log.hxx>
+#include <comphelper/diagnose_ex.hxx>
+#include <tools/gen.hxx>
+#include <sax/tools/converter.hxx>
+#include <xmloff/xmlaustp.hxx>
+#include <xmloff/families.hxx>
+#include <xmloff/styleexp.hxx>
+#include <xmloff/settingsstore.hxx>
+#include <xmloff/table/XMLTableExport.hxx>
+#include <xmloff/ProgressBarHelper.hxx>
+#include "sdpropls.hxx"
+#include <xmloff/xmlexppr.hxx>
+
+#include <PropertySetMerger.hxx>
+#include "layerexp.hxx"
+
+#include "XMLNumberStylesExport.hxx"
+
+#include <xmloff/animationexport.hxx>
+
+#include <com/sun/star/document/XDocumentProperties.hpp>
+#include <com/sun/star/document/XDocumentPropertiesSupplier.hpp>
+#include <com/sun/star/util/Color.hpp>
+#include <docmodel/uno/UnoTheme.hxx>
+#include <docmodel/theme/Theme.hxx>
+#include <o3tl/enumrange.hxx>
+
+using namespace ::com::sun::star;
+using namespace ::com::sun::star::uno;
+using namespace ::com::sun::star::beans;
+using namespace ::com::sun::star::util;
+using namespace ::com::sun::star::container;
+using namespace ::com::sun::star::drawing;
+using namespace ::com::sun::star::office;
+using namespace ::com::sun::star::presentation;
+using namespace ::com::sun::star::geometry;
+using namespace ::com::sun::star::text;
+using namespace ::xmloff::token;
+
+class ImpXMLEXPPageMasterInfo
+{
+ sal_Int32 mnBorderBottom;
+ sal_Int32 mnBorderLeft;
+ sal_Int32 mnBorderRight;
+ sal_Int32 mnBorderTop;
+ sal_Int32 mnWidth;
+ sal_Int32 mnHeight;
+ view::PaperOrientation meOrientation;
+ OUString msName;
+ OUString msMasterPageName;
+
+public:
+ ImpXMLEXPPageMasterInfo(const SdXMLExport& rExp, const Reference<XDrawPage>& xPage);
+ bool operator==(const ImpXMLEXPPageMasterInfo& rInfo) const;
+ void SetName(const OUString& rStr);
+
+ const OUString& GetName() const { return msName; }
+ const OUString& GetMasterPageName() const { return msMasterPageName; }
+
+ sal_Int32 GetBorderBottom() const { return mnBorderBottom; }
+ sal_Int32 GetBorderLeft() const { return mnBorderLeft; }
+ sal_Int32 GetBorderRight() const { return mnBorderRight; }
+ sal_Int32 GetBorderTop() const { return mnBorderTop; }
+ sal_Int32 GetWidth() const { return mnWidth; }
+ sal_Int32 GetHeight() const { return mnHeight; }
+ view::PaperOrientation GetOrientation() const { return meOrientation; }
+};
+
+ImpXMLEXPPageMasterInfo::ImpXMLEXPPageMasterInfo(
+ const SdXMLExport& rExp,
+ const Reference<XDrawPage>& xPage)
+: mnBorderBottom(0),
+ mnBorderLeft(0),
+ mnBorderRight(0),
+ mnBorderTop(0),
+ mnWidth(0),
+ mnHeight(0),
+ meOrientation(rExp.IsDraw() ? view::PaperOrientation_PORTRAIT : view::PaperOrientation_LANDSCAPE)
+{
+ Reference <beans::XPropertySet> xPropSet(xPage, UNO_QUERY);
+ if(xPropSet.is())
+ {
+ Any aAny;
+
+ Reference< beans::XPropertySetInfo > xPropsInfo( xPropSet->getPropertySetInfo() );
+ if( xPropsInfo.is() && xPropsInfo->hasPropertyByName("BorderBottom"))
+ {
+ aAny = xPropSet->getPropertyValue("BorderBottom");
+ aAny >>= mnBorderBottom;
+
+ aAny = xPropSet->getPropertyValue("BorderLeft");
+ aAny >>= mnBorderLeft;
+
+ aAny = xPropSet->getPropertyValue("BorderRight");
+ aAny >>= mnBorderRight;
+
+ aAny = xPropSet->getPropertyValue("BorderTop");
+ aAny >>= mnBorderTop;
+ }
+
+ if( xPropsInfo.is() && xPropsInfo->hasPropertyByName("Width"))
+ {
+ aAny = xPropSet->getPropertyValue("Width");
+ aAny >>= mnWidth;
+
+ aAny = xPropSet->getPropertyValue("Height");
+ aAny >>= mnHeight;
+ }
+
+ if( xPropsInfo.is() && xPropsInfo->hasPropertyByName("Orientation"))
+ {
+ aAny = xPropSet->getPropertyValue("Orientation");
+ aAny >>= meOrientation;
+ }
+ }
+
+ Reference <container::XNamed> xMasterNamed(xPage, UNO_QUERY);
+ if(xMasterNamed.is())
+ {
+ msMasterPageName = xMasterNamed->getName();
+ }
+}
+
+bool ImpXMLEXPPageMasterInfo::operator==(const ImpXMLEXPPageMasterInfo& rInfo) const
+{
+ return ((mnBorderBottom == rInfo.mnBorderBottom)
+ && (mnBorderLeft == rInfo.mnBorderLeft)
+ && (mnBorderRight == rInfo.mnBorderRight)
+ && (mnBorderTop == rInfo.mnBorderTop)
+ && (mnWidth == rInfo.mnWidth)
+ && (mnHeight == rInfo.mnHeight)
+ && (meOrientation == rInfo.meOrientation));
+}
+
+void ImpXMLEXPPageMasterInfo::SetName(const OUString& rStr)
+{
+ msName = rStr;
+}
+
+#define IMP_AUTOLAYOUT_INFO_MAX (35L)
+
+class ImpXMLAutoLayoutInfo
+{
+ sal_uInt16 mnType;
+ ImpXMLEXPPageMasterInfo* mpPageMasterInfo;
+ OUString msLayoutName;
+ tools::Rectangle maTitleRect;
+ tools::Rectangle maPresRect;
+ sal_Int32 mnGapX;
+ sal_Int32 mnGapY;
+
+public:
+ ImpXMLAutoLayoutInfo(sal_uInt16 nTyp, ImpXMLEXPPageMasterInfo* pInf);
+
+ sal_uInt16 GetLayoutType() const { return mnType; }
+ ImpXMLEXPPageMasterInfo* GetPageMasterInfo() const { return mpPageMasterInfo; }
+ sal_Int32 GetGapX() const { return mnGapX; }
+ sal_Int32 GetGapY() const { return mnGapY; }
+
+ const OUString& GetLayoutName() const { return msLayoutName; }
+ void SetLayoutName(const OUString& rNew) { msLayoutName = rNew; }
+
+ const tools::Rectangle& GetTitleRectangle() const { return maTitleRect; }
+ const tools::Rectangle& GetPresRectangle() const { return maPresRect; }
+
+ static bool IsCreateNecessary(sal_uInt16 nTyp);
+};
+
+bool ImpXMLAutoLayoutInfo::IsCreateNecessary(sal_uInt16 nTyp)
+{
+ if(nTyp == 5 /* AUTOLAYOUT_ORG */
+ || nTyp == 20 /* AUTOLAYOUT_NONE */
+ || nTyp >= IMP_AUTOLAYOUT_INFO_MAX)
+ return false;
+ return true;
+}
+
+ImpXMLAutoLayoutInfo::ImpXMLAutoLayoutInfo(sal_uInt16 nTyp, ImpXMLEXPPageMasterInfo* pInf)
+ : mnType(nTyp)
+ , mpPageMasterInfo(pInf)
+ , mnGapX(0)
+ , mnGapY(0)
+{
+ // create full info (initialize with typical values)
+ Point aPagePos(0,0);
+ Size aPageSize(28000, 21000);
+ Size aPageInnerSize(28000, 21000);
+
+ if(mpPageMasterInfo)
+ {
+ aPagePos = Point(mpPageMasterInfo->GetBorderLeft(), mpPageMasterInfo->GetBorderTop());
+ aPageSize = Size(mpPageMasterInfo->GetWidth(), mpPageMasterInfo->GetHeight());
+ aPageInnerSize = aPageSize;
+ aPageInnerSize.AdjustWidth(-(mpPageMasterInfo->GetBorderLeft() + mpPageMasterInfo->GetBorderRight()));
+ aPageInnerSize.AdjustHeight(-(mpPageMasterInfo->GetBorderTop() + mpPageMasterInfo->GetBorderBottom()));
+ }
+
+ // title rectangle aligning
+ Point aTitlePos(aPagePos);
+ Size aTitleSize(aPageInnerSize);
+
+ if(mnType == 21 /* AUTOLAYOUT_NOTES */)
+ {
+ aTitleSize.setHeight(static_cast<tools::Long>(aTitleSize.Height() / 2.5));
+ Point aPos = aTitlePos;
+ aPos.AdjustY( tools::Long( aTitleSize.Height() * 0.083 ) );
+ Size aPartArea = aTitleSize;
+ Size aSize;
+
+ // scale handout rectangle using actual page size
+ double fH = static_cast<double>(aPartArea.Width()) / aPageSize.Width();
+ double fV = static_cast<double>(aPartArea.Height()) / aPageSize.Height();
+
+ if ( fH > fV )
+ fH = fV;
+ aSize.setWidth( static_cast<tools::Long>(fH * aPageSize.Width()) );
+ aSize.setHeight( static_cast<tools::Long>(fH * aPageSize.Height()) );
+
+ aPos.AdjustX((aPartArea.Width() - aSize.Width()) / 2);
+ aPos.AdjustY((aPartArea.Height()- aSize.Height())/ 2);
+
+ aTitlePos = aPos;
+ aTitleSize = aSize;
+ }
+ else if(mnType == AUTOLAYOUT_VTITLE_VCONTENT_OVER_VCONTENT || mnType == AUTOLAYOUT_VTITLE_VCONTENT)
+ {
+ Point aClassicTPos(
+ aTitlePos.X() + tools::Long( aTitleSize.Width() * 0.0735 ),
+ aTitlePos.Y() + tools::Long( aTitleSize.Height() * 0.083 ));
+ Size aClassicTSize(
+ tools::Long( aTitleSize.Width() * 0.854 ),
+ tools::Long( aTitleSize.Height() * 0.167 ));
+ Point aLPos(aPagePos);
+ Size aLSize(aPageInnerSize);
+ Point aClassicLPos(
+ aLPos.X() + tools::Long( aLSize.Width() * 0.0735 ),
+ aLPos.Y() + tools::Long( aLSize.Height() * 0.472 ));
+ Size aClassicLSize(
+ tools::Long( aLSize.Width() * 0.854 ),
+ tools::Long( aLSize.Height() * 0.444 ));
+
+ aTitlePos.setX( (aClassicTPos.X() + aClassicTSize.Width()) - aClassicTSize.Height() );
+ aTitlePos.setY( aClassicTPos.Y() );
+ aTitleSize.setWidth( aClassicTSize.Height() );
+ aTitleSize.setHeight( (aClassicLPos.Y() + aClassicLSize.Height()) - aClassicTPos.Y() );
+ }
+ else
+ {
+ aTitlePos.AdjustX( tools::Long( aTitleSize.Width() * 0.0735 ) );
+ aTitlePos.AdjustY( tools::Long( aTitleSize.Height() * 0.083 ) );
+ aTitleSize.setWidth( tools::Long( aTitleSize.Width() * 0.854 ) );
+ aTitleSize.setHeight( tools::Long( aTitleSize.Height() * 0.167 ) );
+ }
+
+ maTitleRect.SetPos(aTitlePos);
+ maTitleRect.SetSize(aTitleSize);
+
+ // layout rectangle aligning
+ Point aLayoutPos(aPagePos);
+ Size aLayoutSize(aPageInnerSize);
+
+ if(mnType == 21 /* AUTOLAYOUT_NOTES */)
+ {
+ aLayoutPos.AdjustX( tools::Long( aLayoutSize.Width() * 0.0735 ) );
+ aLayoutPos.AdjustY( tools::Long( aLayoutSize.Height() * 0.472 ) );
+ aLayoutSize.setWidth( tools::Long( aLayoutSize.Width() * 0.854 ) );
+ aLayoutSize.setHeight( tools::Long( aLayoutSize.Height() * 0.444 ) );
+ }
+ else if((mnType >= 22 && mnType <= 26) || (mnType == 31)) // AUTOLAYOUT_HANDOUT*
+ {
+ // keep info for inner area in maPresRect, put info for gap size
+ // to maTitleRect position
+ mnGapX = (aPageSize.Width() - aPageInnerSize.Width()) / 2;
+ mnGapY = (aPageSize.Height() - aPageInnerSize.Height()) / 2;
+
+ if(!mnGapX)
+ mnGapX = aPageSize.Width() / 10;
+
+ if(!mnGapY)
+ mnGapY = aPageSize.Height() / 10;
+
+ if(mnGapX < aPageInnerSize.Width() / 10)
+ mnGapX = aPageInnerSize.Width() / 10;
+
+ if(mnGapY < aPageInnerSize.Height() / 10)
+ mnGapY = aPageInnerSize.Height() / 10;
+ }
+ else if(mnType == AUTOLAYOUT_VTITLE_VCONTENT_OVER_VCONTENT || mnType == AUTOLAYOUT_VTITLE_VCONTENT)
+ {
+ Point aClassicTPos(
+ aTitlePos.X() + tools::Long( aTitleSize.Width() * 0.0735 ),
+ aTitlePos.Y() + tools::Long( aTitleSize.Height() * 0.083 ));
+ Size aClassicTSize(
+ tools::Long( aTitleSize.Width() * 0.854 ),
+ tools::Long( aTitleSize.Height() * 0.167 ));
+ Point aClassicLPos(
+ aLayoutPos.X() + tools::Long( aLayoutSize.Width() * 0.0735 ),
+ aLayoutPos.Y() + tools::Long( aLayoutSize.Height() * 0.472 ));
+ Size aClassicLSize(
+ tools::Long( aLayoutSize.Width() * 0.854 ),
+ tools::Long( aLayoutSize.Height() * 0.444 ));
+
+ aLayoutPos.setX( aClassicLPos.X() );
+ aLayoutPos.setY( aClassicTPos.Y() );
+ aLayoutSize.setWidth( (aClassicLPos.X() + aClassicLSize.Width())
+ - (aClassicTSize.Height() + (aClassicLPos.Y() - (aClassicTPos.Y() + aClassicTSize.Height()))));
+ aLayoutSize.setHeight( (aClassicLPos.Y() + aClassicLSize.Height()) - aClassicTPos.Y() );
+ }
+ else if( mnType == AUTOLAYOUT_ONLY_TEXT )
+ {
+ aLayoutPos = aTitlePos;
+ aLayoutSize.setWidth( aTitleSize.Width() );
+ aLayoutSize.setHeight( tools::Long( aLayoutSize.Height() * 0.825 ) );
+ }
+ else
+ {
+ aLayoutPos.AdjustX( tools::Long( aLayoutSize.Width() * 0.0735 ) );
+ aLayoutPos.AdjustY( tools::Long( aLayoutSize.Height() * 0.278 ) );
+ aLayoutSize.setWidth( tools::Long( aLayoutSize.Width() * 0.854 ) );
+ aLayoutSize.setHeight( tools::Long( aLayoutSize.Height() * 0.630 ) );
+ }
+
+ maPresRect.SetPos(aLayoutPos);
+ maPresRect.SetSize(aLayoutSize);
+}
+
+constexpr OUString gsPageLayoutNames( u"PageLayoutNames"_ustr );
+
+SdXMLExport::SdXMLExport(
+ const css::uno::Reference< css::uno::XComponentContext >& xContext,
+ OUString const & implementationName,
+ bool bIsDraw, SvXMLExportFlags nExportFlags )
+: SvXMLExport( xContext, implementationName, util::MeasureUnit::CM,
+ bIsDraw ? XML_GRAPHICS : XML_PRESENTATION, nExportFlags ),
+ mnDocMasterPageCount(0),
+ mnDocDrawPageCount(0),
+ mnObjectCount(0),
+ mpHandoutPageMaster(nullptr),
+ mbIsDraw(bIsDraw)
+{
+
+}
+
+// XExporter
+void SAL_CALL SdXMLExport::setSourceDocument( const Reference< lang::XComponent >& xDoc )
+{
+ SvXMLExport::setSourceDocument( xDoc );
+
+ // prepare factory parts
+ mpSdPropHdlFactory = new XMLSdPropHdlFactory( GetModel(), *this );
+
+ // construct PropertySetMapper
+ rtl::Reference < XMLPropertySetMapper > xMapper = new XMLShapePropertySetMapper( mpSdPropHdlFactory, true);
+
+ // get or create text paragraph export
+ GetTextParagraphExport();
+ mpPropertySetMapper = new XMLShapeExportPropertyMapper( xMapper, *this );
+
+ // chain text attributes
+ mpPropertySetMapper->ChainExportMapper(XMLTextParagraphExport::CreateParaExtPropMapper(*this));
+
+ // construct PresPagePropsMapper
+ xMapper = new XMLPropertySetMapper(aXMLSDPresPageProps, mpSdPropHdlFactory, true);
+
+ mpPresPagePropsMapper = new XMLPageExportPropertyMapper( xMapper, *this );
+
+ // add family name
+ GetAutoStylePool()->AddFamily(
+ XmlStyleFamily::SD_GRAPHICS_ID,
+ XML_STYLE_FAMILY_SD_GRAPHICS_NAME,
+ GetPropertySetMapper(),
+ XML_STYLE_FAMILY_SD_GRAPHICS_PREFIX);
+ GetAutoStylePool()->AddFamily(
+ XmlStyleFamily::SD_PRESENTATION_ID,
+ XML_STYLE_FAMILY_SD_PRESENTATION_NAME,
+ GetPropertySetMapper(),
+ XML_STYLE_FAMILY_SD_PRESENTATION_PREFIX);
+ GetAutoStylePool()->AddFamily(
+ XmlStyleFamily::SD_DRAWINGPAGE_ID,
+ XML_STYLE_FAMILY_SD_DRAWINGPAGE_NAME,
+ GetPresPagePropsMapper(),
+ XML_STYLE_FAMILY_SD_DRAWINGPAGE_PREFIX);
+ // prepare access to styles
+ Reference< style::XStyleFamiliesSupplier > xFamSup( GetModel(), UNO_QUERY );
+ if(xFamSup.is())
+ {
+ mxDocStyleFamilies = xFamSup->getStyleFamilies();
+ }
+
+ // prepare access to master pages
+ Reference < drawing::XMasterPagesSupplier > xMasterPagesSupplier(GetModel(), UNO_QUERY);
+ if(xMasterPagesSupplier.is())
+ {
+ mxDocMasterPages = xMasterPagesSupplier->getMasterPages();
+ if(mxDocMasterPages.is())
+ {
+ mnDocMasterPageCount = mxDocMasterPages->getCount();
+ maMasterPagesStyleNames.insert( maMasterPagesStyleNames.begin(), mnDocMasterPageCount, "" );
+ }
+ }
+
+ // prepare access to draw pages
+ Reference <XDrawPagesSupplier> xDrawPagesSupplier(GetModel(), UNO_QUERY);
+ if(xDrawPagesSupplier.is())
+ {
+ mxDocDrawPages = xDrawPagesSupplier->getDrawPages();
+ if(mxDocDrawPages.is())
+ {
+ mnDocDrawPageCount = mxDocDrawPages->getCount();
+ maDrawPagesStyleNames.insert( maDrawPagesStyleNames.begin(), mnDocDrawPageCount, "" );
+ maDrawNotesPagesStyleNames.insert( maDrawNotesPagesStyleNames.begin(), mnDocDrawPageCount, "" );
+ if( !mbIsDraw )
+ maDrawPagesAutoLayoutNames.realloc( mnDocDrawPageCount + 1 );
+
+ HeaderFooterPageSettingsImpl aEmptySettings;
+ maDrawPagesHeaderFooterSettings.insert( maDrawPagesHeaderFooterSettings.begin(), mnDocDrawPageCount, aEmptySettings );
+ maDrawNotesPagesHeaderFooterSettings.insert( maDrawNotesPagesHeaderFooterSettings.begin(), mnDocDrawPageCount, aEmptySettings );
+ }
+ }
+
+ // #82003# count all draw objects for use with progress bar.
+ // #88245# init mnObjectCount once, use counter itself as flag. It
+ // is initialized to 0.
+ if(!mnObjectCount)
+ {
+ if( IsImpress() )
+ {
+ // #91587# add handout master count
+ Reference<presentation::XHandoutMasterSupplier> xHandoutSupp(GetModel(), UNO_QUERY);
+ if(xHandoutSupp.is())
+ {
+ Reference<XDrawPage> xHandoutPage(xHandoutSupp->getHandoutMasterPage());
+ if(xHandoutPage.is() && xHandoutPage->getCount())
+ mnObjectCount += ImpRecursiveObjectCount(xHandoutPage);
+ }
+ }
+
+ if(mxDocMasterPages.is())
+ {
+ for(sal_Int32 a(0); a < mnDocMasterPageCount; a++)
+ {
+ Any aAny(mxDocMasterPages->getByIndex(a));
+ Reference< drawing::XShapes > xMasterPage;
+
+ if((aAny >>= xMasterPage) && xMasterPage.is())
+ {
+ mnObjectCount += ImpRecursiveObjectCount(xMasterPage);
+ }
+
+ if( IsImpress() )
+ {
+ // #91587# take notes pages from master pages into account
+ Reference<presentation::XPresentationPage> xPresPage;
+ if((aAny >>= xPresPage) && xPresPage.is())
+ {
+ Reference<XDrawPage> xNotesPage(xPresPage->getNotesPage());
+ if(xNotesPage.is() && xNotesPage->getCount())
+ mnObjectCount += ImpRecursiveObjectCount(xNotesPage);
+ }
+ }
+ }
+ }
+
+ if(mxDocDrawPages.is())
+ {
+ for(sal_Int32 a(0); a < mnDocDrawPageCount; a++)
+ {
+ Any aAny(mxDocDrawPages->getByIndex(a));
+ Reference< drawing::XShapes > xPage;
+
+ if((aAny >>= xPage) && xPage.is())
+ {
+ mnObjectCount += ImpRecursiveObjectCount(xPage);
+ }
+
+ if( IsImpress() )
+ {
+ // #91587# take notes pages from draw pages into account
+ Reference<presentation::XPresentationPage> xPresPage;
+ if((aAny >>= xPresPage) && xPresPage.is())
+ {
+ Reference<XDrawPage> xNotesPage(xPresPage->getNotesPage());
+ if(xNotesPage.is() && xNotesPage->getCount())
+ mnObjectCount += ImpRecursiveObjectCount(xNotesPage);
+ }
+ }
+ }
+ }
+
+ // #82003# init progress bar
+ GetProgressBarHelper()->SetReference(mnObjectCount);
+ }
+
+ // add namespaces
+ GetNamespaceMap_().Add(
+ GetXMLToken(XML_NP_PRESENTATION),
+ GetXMLToken(XML_N_PRESENTATION),
+ XML_NAMESPACE_PRESENTATION);
+
+ GetNamespaceMap_().Add(
+ GetXMLToken(XML_NP_SMIL),
+ GetXMLToken(XML_N_SMIL_COMPAT),
+ XML_NAMESPACE_SMIL);
+
+ GetNamespaceMap_().Add(
+ GetXMLToken(XML_NP_ANIMATION),
+ GetXMLToken(XML_N_ANIMATION),
+ XML_NAMESPACE_ANIMATION);
+
+ if (getSaneDefaultVersion() & SvtSaveOptions::ODFSVER_EXTENDED)
+ {
+ GetNamespaceMap_().Add(
+ GetXMLToken(XML_NP_OFFICE_EXT),
+ GetXMLToken(XML_N_OFFICE_EXT),
+ XML_NAMESPACE_OFFICE_EXT);
+ }
+
+ GetShapeExport()->enableLayerExport();
+
+ // #88546# enable progress bar increments
+ GetShapeExport()->enableHandleProgressBar();
+}
+
+// #82003# helper function for recursive object count
+sal_uInt32 SdXMLExport::ImpRecursiveObjectCount(const Reference< drawing::XShapes >& xShapes)
+{
+ sal_uInt32 nRetval(0);
+
+ if(xShapes.is())
+ {
+ sal_Int32 nCount = xShapes->getCount();
+
+ for(sal_Int32 a(0); a < nCount; a++)
+ {
+ Any aAny(xShapes->getByIndex(a));
+ Reference< drawing::XShapes > xGroup;
+
+ if((aAny >>= xGroup) && xGroup.is())
+ {
+ // #93180# count group objects, too.
+ nRetval += 1 + ImpRecursiveObjectCount(xGroup);
+ }
+ else
+ {
+ nRetval++;
+ }
+ }
+ }
+
+ return nRetval;
+}
+
+SdXMLExport::~SdXMLExport()
+{
+ // cleanup factory, decrease refcount. Should lead to destruction.
+ mpSdPropHdlFactory.clear();
+
+ // cleanup mapper, decrease refcount. Should lead to destruction.
+ mpPropertySetMapper.clear();
+
+ // cleanup presPage mapper, decrease refcount. Should lead to destruction.
+ mpPresPagePropsMapper.clear();
+
+ mvPageMasterInfoList.clear();
+
+ // clear auto-layout infos
+ mvAutoLayoutInfoList.clear();
+}
+
+void SdXMLExport::ImpPrepAutoLayoutInfos()
+{
+ if(!IsImpress())
+ return;
+
+ OUString aStr;
+ auto DrawPagesAutoLayoutNamesRange = asNonConstRange(maDrawPagesAutoLayoutNames);
+ Reference< presentation::XHandoutMasterSupplier > xHandoutSupp( GetModel(), UNO_QUERY );
+ if( xHandoutSupp.is() )
+ {
+ Reference< XDrawPage > xHandoutPage( xHandoutSupp->getHandoutMasterPage() );
+ if( xHandoutPage.is() )
+ {
+ if(ImpPrepAutoLayoutInfo(xHandoutPage, aStr))
+ DrawPagesAutoLayoutNamesRange[0] = aStr;
+ }
+ }
+
+ // prepare name creation
+ for (sal_Int32 nCnt = 0; nCnt < mnDocDrawPageCount; nCnt++)
+ {
+ Any aAny(mxDocDrawPages->getByIndex(nCnt));
+ Reference<XDrawPage> xDrawPage;
+
+ if((aAny >>= xDrawPage) && xDrawPage.is())
+ {
+ if(ImpPrepAutoLayoutInfo(xDrawPage, aStr))
+ DrawPagesAutoLayoutNamesRange[nCnt+1] = aStr;
+ }
+ }
+}
+
+bool SdXMLExport::ImpPrepAutoLayoutInfo(const Reference<XDrawPage>& xPage, OUString& rName)
+{
+ rName.clear();
+ bool bRetval(false);
+
+ Reference <beans::XPropertySet> xPropSet(xPage, UNO_QUERY);
+ if(xPropSet.is())
+ {
+ sal_uInt16 nType = sal_uInt16();
+ Any aAny = xPropSet->getPropertyValue("Layout");
+ if(aAny >>= nType)
+ {
+ if(ImpXMLAutoLayoutInfo::IsCreateNecessary(nType))
+ {
+ ImpXMLEXPPageMasterInfo* pInfo = nullptr;
+
+ // get master-page info
+ Reference < drawing::XMasterPageTarget > xMasterPageInt(xPage, UNO_QUERY);
+ if(xMasterPageInt.is())
+ {
+ Reference<XDrawPage> xUsedMasterPage(xMasterPageInt->getMasterPage());
+ if(xUsedMasterPage.is())
+ {
+ Reference < container::XNamed > xMasterNamed(xUsedMasterPage, UNO_QUERY);
+ if(xMasterNamed.is())
+ {
+ OUString sMasterPageName = xMasterNamed->getName();
+ pInfo = ImpGetPageMasterInfoByName(sMasterPageName);
+ }
+ }
+ }
+
+ // create entry and look for existence
+ ImpXMLAutoLayoutInfo* pNew;
+ auto it = std::find_if(mvAutoLayoutInfoList.begin(), mvAutoLayoutInfoList.end(),
+ [=](std::unique_ptr<ImpXMLAutoLayoutInfo> const & rInfo) { return nType == rInfo->GetLayoutType() && pInfo == rInfo->GetPageMasterInfo(); });
+ if (it != mvAutoLayoutInfoList.end())
+ {
+ pNew = it->get();
+ }
+ else
+ {
+ pNew = new ImpXMLAutoLayoutInfo(nType, pInfo);
+ mvAutoLayoutInfoList.emplace_back( pNew );
+ OUString sNewName =
+ "AL" + OUString::number(mvAutoLayoutInfoList.size() - 1) +
+ "T" + OUString::number(nType);
+ pNew->SetLayoutName(sNewName);
+ }
+
+ rName = pNew->GetLayoutName();
+ bRetval = true;
+ }
+ }
+ }
+
+ return bRetval;
+}
+
+void SdXMLExport::ImpWriteAutoLayoutInfos()
+{
+ for(const auto & pInfo : mvAutoLayoutInfoList)
+ {
+ if(pInfo)
+ {
+ // prepare presentation-page layout attributes, style-name
+ AddAttribute(XML_NAMESPACE_STYLE, XML_NAME, pInfo->GetLayoutName());
+
+ // write draw-style attributes
+ SvXMLElementExport aDSE(*this, XML_NAMESPACE_STYLE, XML_PRESENTATION_PAGE_LAYOUT, true, true);
+
+ // write presentation placeholders
+ switch(pInfo->GetLayoutType())
+ {
+ case AUTOLAYOUT_TITLE :
+ {
+ ImpWriteAutoLayoutPlaceholder(XmlPlaceholderTitle, pInfo->GetTitleRectangle());
+ ImpWriteAutoLayoutPlaceholder(XmlPlaceholderSubtitle, pInfo->GetPresRectangle());
+ break;
+ }
+ case AUTOLAYOUT_TITLE_CONTENT :
+ {
+ ImpWriteAutoLayoutPlaceholder(XmlPlaceholderTitle, pInfo->GetTitleRectangle());
+ ImpWriteAutoLayoutPlaceholder(XmlPlaceholderOutline, pInfo->GetPresRectangle());
+ break;
+ }
+ case AUTOLAYOUT_CHART :
+ {
+ ImpWriteAutoLayoutPlaceholder(XmlPlaceholderTitle, pInfo->GetTitleRectangle());
+ ImpWriteAutoLayoutPlaceholder(XmlPlaceholderChart, pInfo->GetPresRectangle());
+ break;
+ }
+ case AUTOLAYOUT_TITLE_2CONTENT :
+ {
+ tools::Rectangle aLeft(pInfo->GetPresRectangle());
+ aLeft.setWidth(tools::Long(aLeft.GetWidth() * 0.488));
+ tools::Rectangle aRight(aLeft);
+ aRight.AdjustLeft(aRight.GetWidth() * 1.05);
+
+ ImpWriteAutoLayoutPlaceholder(XmlPlaceholderTitle, pInfo->GetTitleRectangle());
+ ImpWriteAutoLayoutPlaceholder(XmlPlaceholderOutline, aLeft);
+ ImpWriteAutoLayoutPlaceholder(XmlPlaceholderOutline, aRight);
+ break;
+ }
+ case AUTOLAYOUT_TEXTCHART :
+ {
+ tools::Rectangle aLeft(pInfo->GetPresRectangle());
+ aLeft.setWidth(tools::Long(aLeft.GetWidth() * 0.488));
+ tools::Rectangle aRight(aLeft);
+ aRight.AdjustLeft(aRight.GetWidth() * 1.05);
+
+ ImpWriteAutoLayoutPlaceholder(XmlPlaceholderTitle, pInfo->GetTitleRectangle());
+ ImpWriteAutoLayoutPlaceholder(XmlPlaceholderOutline, aLeft);
+ ImpWriteAutoLayoutPlaceholder(XmlPlaceholderChart, aRight);
+ break;
+ }
+ case AUTOLAYOUT_TEXTCLIP :
+ {
+ tools::Rectangle aLeft(pInfo->GetPresRectangle());
+ aLeft.setWidth(tools::Long(aLeft.GetWidth() * 0.488));
+ tools::Rectangle aRight(aLeft);
+ aRight.AdjustLeft(aRight.GetWidth() * 1.05);
+
+ ImpWriteAutoLayoutPlaceholder(XmlPlaceholderTitle, pInfo->GetTitleRectangle());
+ ImpWriteAutoLayoutPlaceholder(XmlPlaceholderOutline, aLeft);
+ ImpWriteAutoLayoutPlaceholder(XmlPlaceholderGraphic, aRight);
+ break;
+ }
+ case AUTOLAYOUT_CHARTTEXT :
+ {
+ tools::Rectangle aLeft(pInfo->GetPresRectangle());
+ aLeft.setWidth(tools::Long(aLeft.GetWidth() * 0.488));
+ tools::Rectangle aRight(aLeft);
+ aRight.AdjustLeft(aRight.GetWidth() * 1.05);
+
+ ImpWriteAutoLayoutPlaceholder(XmlPlaceholderTitle, pInfo->GetTitleRectangle());
+ ImpWriteAutoLayoutPlaceholder(XmlPlaceholderChart, aLeft);
+ ImpWriteAutoLayoutPlaceholder(XmlPlaceholderOutline, aRight);
+ break;
+ }
+ case AUTOLAYOUT_TAB :
+ {
+ ImpWriteAutoLayoutPlaceholder(XmlPlaceholderTitle, pInfo->GetTitleRectangle());
+ ImpWriteAutoLayoutPlaceholder(XmlPlaceholderTable, pInfo->GetPresRectangle());
+ break;
+ }
+ case AUTOLAYOUT_CLIPTEXT :
+ {
+ tools::Rectangle aLeft(pInfo->GetPresRectangle());
+ aLeft.setWidth(tools::Long(aLeft.GetWidth() * 0.488));
+ tools::Rectangle aRight(aLeft);
+ aRight.AdjustLeft(aRight.GetWidth() * 1.05);
+
+ ImpWriteAutoLayoutPlaceholder(XmlPlaceholderTitle, pInfo->GetTitleRectangle());
+ ImpWriteAutoLayoutPlaceholder(XmlPlaceholderGraphic, aLeft);
+ ImpWriteAutoLayoutPlaceholder(XmlPlaceholderOutline, aRight);
+ break;
+ }
+ case AUTOLAYOUT_TEXTOBJ :
+ {
+ tools::Rectangle aLeft(pInfo->GetPresRectangle());
+ aLeft.setWidth(tools::Long(aLeft.GetWidth() * 0.488));
+ tools::Rectangle aRight(aLeft);
+ aRight.AdjustLeft(aRight.GetWidth() * 1.05);
+
+ ImpWriteAutoLayoutPlaceholder(XmlPlaceholderTitle, pInfo->GetTitleRectangle());
+ ImpWriteAutoLayoutPlaceholder(XmlPlaceholderOutline, aLeft);
+ ImpWriteAutoLayoutPlaceholder(XmlPlaceholderObject, aRight);
+ break;
+ }
+ case AUTOLAYOUT_OBJ :
+ {
+ ImpWriteAutoLayoutPlaceholder(XmlPlaceholderTitle, pInfo->GetTitleRectangle());
+ ImpWriteAutoLayoutPlaceholder(XmlPlaceholderObject, pInfo->GetPresRectangle());
+ break;
+ }
+ case AUTOLAYOUT_TITLE_CONTENT_2CONTENT :
+ {
+ tools::Rectangle aLeft(pInfo->GetPresRectangle());
+ aLeft.setWidth(tools::Long(aLeft.GetWidth() * 0.488));
+ tools::Rectangle aRightTop(aLeft);
+ aRightTop.AdjustLeft(aRightTop.GetWidth() * 1.05);
+ aRightTop.setHeight(tools::Long(aRightTop.GetHeight() * 0.477));
+ tools::Rectangle aRightBottom(aRightTop);
+ aRightBottom.AdjustTop(aRightBottom.GetHeight() * 1.095);
+
+ ImpWriteAutoLayoutPlaceholder(XmlPlaceholderTitle, pInfo->GetTitleRectangle());
+ ImpWriteAutoLayoutPlaceholder(XmlPlaceholderOutline, aLeft);
+ ImpWriteAutoLayoutPlaceholder(XmlPlaceholderObject, aRightTop);
+ ImpWriteAutoLayoutPlaceholder(XmlPlaceholderObject, aRightBottom);
+ break;
+ }
+ case AUTOLAYOUT_OBJTEXT :
+ {
+ tools::Rectangle aLeft(pInfo->GetPresRectangle());
+ aLeft.setWidth(tools::Long(aLeft.GetWidth() * 0.488));
+ tools::Rectangle aRight(aLeft);
+ aRight.AdjustLeft(aRight.GetWidth() * 1.05);
+
+ ImpWriteAutoLayoutPlaceholder(XmlPlaceholderTitle, pInfo->GetTitleRectangle());
+ ImpWriteAutoLayoutPlaceholder(XmlPlaceholderObject, aLeft);
+ ImpWriteAutoLayoutPlaceholder(XmlPlaceholderOutline, aRight);
+ break;
+ }
+ case AUTOLAYOUT_TITLE_CONTENT_OVER_CONTENT :
+ {
+ tools::Rectangle aTop(pInfo->GetPresRectangle());
+ aTop.setHeight(tools::Long(aTop.GetHeight() * 0.477));
+ tools::Rectangle aBottom(aTop);
+ aBottom.AdjustTop(aBottom.GetHeight() * 1.095);
+
+ ImpWriteAutoLayoutPlaceholder(XmlPlaceholderTitle, pInfo->GetTitleRectangle());
+ ImpWriteAutoLayoutPlaceholder(XmlPlaceholderObject, aTop);
+ ImpWriteAutoLayoutPlaceholder(XmlPlaceholderOutline, aBottom);
+ break;
+ }
+ case AUTOLAYOUT_TITLE_2CONTENT_CONTENT :
+ {
+ tools::Rectangle aLeftTop(pInfo->GetPresRectangle());
+ aLeftTop.setWidth(tools::Long(aLeftTop.GetWidth() * 0.488));
+ tools::Rectangle aRight(aLeftTop);
+ aRight.AdjustLeft(aRight.GetWidth() * 1.05);
+ aLeftTop.setHeight(tools::Long(aLeftTop.GetHeight() * 0.477));
+ tools::Rectangle aLeftBottom(aLeftTop);
+ aLeftBottom.AdjustTop(aLeftBottom.GetHeight() * 1.095);
+
+ ImpWriteAutoLayoutPlaceholder(XmlPlaceholderTitle, pInfo->GetTitleRectangle());
+ ImpWriteAutoLayoutPlaceholder(XmlPlaceholderObject, aLeftTop);
+ ImpWriteAutoLayoutPlaceholder(XmlPlaceholderObject, aLeftBottom);
+ ImpWriteAutoLayoutPlaceholder(XmlPlaceholderOutline, aRight);
+ break;
+ }
+ case AUTOLAYOUT_TITLE_2CONTENT_OVER_CONTENT :
+ {
+ tools::Rectangle aTopLeft(pInfo->GetPresRectangle());
+ aTopLeft.setHeight(tools::Long(aTopLeft.GetHeight() * 0.477));
+ tools::Rectangle aBottom(aTopLeft);
+ aBottom.AdjustTop(aBottom.GetHeight() * 1.095);
+ aTopLeft.setWidth(tools::Long(aTopLeft.GetWidth() * 0.488));
+ tools::Rectangle aTopRight(aTopLeft);
+ aTopRight.AdjustLeft(aTopRight.GetWidth() * 1.05);
+
+ ImpWriteAutoLayoutPlaceholder(XmlPlaceholderTitle, pInfo->GetTitleRectangle());
+ ImpWriteAutoLayoutPlaceholder(XmlPlaceholderObject, aTopLeft);
+ ImpWriteAutoLayoutPlaceholder(XmlPlaceholderObject, aTopRight);
+ ImpWriteAutoLayoutPlaceholder(XmlPlaceholderOutline, aBottom);
+ break;
+ }
+ case AUTOLAYOUT_TEXTOVEROBJ :
+ {
+ tools::Rectangle aTop(pInfo->GetPresRectangle());
+ aTop.setHeight(tools::Long(aTop.GetHeight() * 0.477));
+ tools::Rectangle aBottom(aTop);
+ aBottom.AdjustTop(aBottom.GetHeight() * 1.095);
+
+ ImpWriteAutoLayoutPlaceholder(XmlPlaceholderTitle, pInfo->GetTitleRectangle());
+ ImpWriteAutoLayoutPlaceholder(XmlPlaceholderOutline, aTop);
+ ImpWriteAutoLayoutPlaceholder(XmlPlaceholderObject, aBottom);
+ break;
+ }
+ case AUTOLAYOUT_TITLE_4CONTENT :
+ {
+ tools::Rectangle aTopLeft(pInfo->GetPresRectangle());
+ aTopLeft.setHeight(tools::Long(aTopLeft.GetHeight() * 0.477));
+ aTopLeft.setWidth(tools::Long(aTopLeft.GetWidth() * 0.488));
+ tools::Rectangle aBottomLeft(aTopLeft);
+ aBottomLeft.AdjustTop(aBottomLeft.GetHeight() * 1.095);
+ tools::Rectangle aTopRight(aTopLeft);
+ aTopRight.AdjustLeft(aTopRight.GetWidth() * 1.05);
+ tools::Rectangle aBottomRight(aTopRight);
+ aBottomRight.AdjustTop(aBottomRight.GetHeight() * 1.095);
+
+ ImpWriteAutoLayoutPlaceholder(XmlPlaceholderTitle, pInfo->GetTitleRectangle());
+ ImpWriteAutoLayoutPlaceholder(XmlPlaceholderObject, aTopLeft);
+ ImpWriteAutoLayoutPlaceholder(XmlPlaceholderObject, aTopRight);
+ ImpWriteAutoLayoutPlaceholder(XmlPlaceholderObject, aBottomLeft);
+ ImpWriteAutoLayoutPlaceholder(XmlPlaceholderObject, aBottomRight);
+ break;
+ }
+ case AUTOLAYOUT_TITLE_ONLY :
+ {
+ ImpWriteAutoLayoutPlaceholder(XmlPlaceholderTitle, pInfo->GetTitleRectangle());
+ break;
+ }
+ case AUTOLAYOUT_NOTES :
+ {
+ ImpWriteAutoLayoutPlaceholder(XmlPlaceholderPage, pInfo->GetTitleRectangle());
+ ImpWriteAutoLayoutPlaceholder(XmlPlaceholderNotes, pInfo->GetPresRectangle());
+ break;
+ }
+ case AUTOLAYOUT_HANDOUT1 :
+ case AUTOLAYOUT_HANDOUT2 :
+ case AUTOLAYOUT_HANDOUT3 :
+ case AUTOLAYOUT_HANDOUT4 :
+ case AUTOLAYOUT_HANDOUT6 :
+ case AUTOLAYOUT_HANDOUT9 :
+ {
+ sal_Int32 nColCnt, nRowCnt;
+ sal_Int32 nGapX = pInfo->GetGapX();
+ sal_Int32 nGapY = pInfo->GetGapY();
+
+ switch(pInfo->GetLayoutType())
+ {
+ case 22 : nColCnt = 1; nRowCnt = 1; break;
+ case 23 : nColCnt = 1; nRowCnt = 2; break;
+ case 24 : nColCnt = 1; nRowCnt = 3; break;
+ case 25 : nColCnt = 2; nRowCnt = 2; break;
+ case 26 : nColCnt = 3; nRowCnt = 2; break;
+ case 31 : nColCnt = 3; nRowCnt = 3; break;
+ default: nColCnt = 0; nRowCnt = 0; break; // FIXME - What is correct values?
+ }
+
+ Size aPartSize(pInfo->GetTitleRectangle().GetSize());
+ Point aPartPos(pInfo->GetTitleRectangle().TopLeft());
+
+ if(aPartSize.Width() > aPartSize.Height())
+ {
+ sal_Int32 nZwi(nColCnt);
+ nColCnt = nRowCnt;
+ nRowCnt = nZwi;
+ }
+
+ if (nColCnt == 0 || nRowCnt == 0)
+ break;
+
+ aPartSize.setWidth( (aPartSize.Width() - ((nColCnt - 1) * nGapX)) / nColCnt );
+ aPartSize.setHeight( (aPartSize.Height() - ((nRowCnt - 1) * nGapY)) / nRowCnt );
+
+ Point aTmpPos(aPartPos);
+
+ for (sal_Int32 a = 0; a < nRowCnt; a++)
+ {
+ aTmpPos.setX(aPartPos.X());
+
+ for (sal_Int32 b = 0; b < nColCnt; b++)
+ {
+ tools::Rectangle aTmpRect(aTmpPos, aPartSize);
+
+ ImpWriteAutoLayoutPlaceholder(XmlPlaceholderHandout, aTmpRect);
+ aTmpPos.AdjustX( aPartSize.Width() + nGapX );
+ }
+
+ aTmpPos.AdjustY( aPartSize.Height() + nGapY );
+ }
+ break;
+ }
+ case AUTOLAYOUT_VTITLE_VCONTENT_OVER_VCONTENT :
+ {
+ tools::Rectangle aTop(pInfo->GetPresRectangle());
+ aTop.setHeight(tools::Long(aTop.GetHeight() * 0.488));
+ tools::Rectangle aBottom(aTop);
+ aBottom.AdjustTop(aBottom.GetHeight() * 1.05);
+
+ ImpWriteAutoLayoutPlaceholder(XmlPlaceholderVerticalTitle, pInfo->GetTitleRectangle());
+ ImpWriteAutoLayoutPlaceholder(XmlPlaceholderVerticalOutline, aTop);
+ ImpWriteAutoLayoutPlaceholder(XmlPlaceholderChart, aBottom);
+ break;
+ }
+ case AUTOLAYOUT_VTITLE_VCONTENT :
+ {
+ ImpWriteAutoLayoutPlaceholder(XmlPlaceholderVerticalTitle, pInfo->GetTitleRectangle());
+ ImpWriteAutoLayoutPlaceholder(XmlPlaceholderVerticalOutline, pInfo->GetPresRectangle());
+ break;
+ }
+ case AUTOLAYOUT_TITLE_VCONTENT :
+ {
+ ImpWriteAutoLayoutPlaceholder(XmlPlaceholderTitle, pInfo->GetTitleRectangle());
+ ImpWriteAutoLayoutPlaceholder(XmlPlaceholderVerticalOutline, pInfo->GetPresRectangle());
+ break;
+ }
+ case AUTOLAYOUT_TITLE_2VTEXT :
+ {
+ tools::Rectangle aLeft(pInfo->GetPresRectangle());
+ aLeft.setWidth(tools::Long(aLeft.GetWidth() * 0.488));
+ tools::Rectangle aRight(aLeft);
+ aRight.AdjustLeft(aRight.GetWidth() * 1.05);
+
+ ImpWriteAutoLayoutPlaceholder(XmlPlaceholderTitle, pInfo->GetTitleRectangle());
+ ImpWriteAutoLayoutPlaceholder(XmlPlaceholderGraphic, aLeft);
+ ImpWriteAutoLayoutPlaceholder(XmlPlaceholderVerticalOutline, aRight);
+ break;
+ }
+ case AUTOLAYOUT_ONLY_TEXT :
+ {
+ ImpWriteAutoLayoutPlaceholder(XmlPlaceholderSubtitle, pInfo->GetPresRectangle());
+ break;
+ }
+
+ case AUTOLAYOUT_4CLIPART :
+ {
+ tools::Rectangle aTopLeft(pInfo->GetPresRectangle());
+ aTopLeft.setHeight(tools::Long(aTopLeft.GetHeight() * 0.477));
+ aTopLeft.setWidth(tools::Long(aTopLeft.GetWidth() * 0.488));
+ tools::Rectangle aBottomLeft(aTopLeft);
+ aBottomLeft.AdjustTop(aBottomLeft.GetHeight() * 1.095);
+ tools::Rectangle aTopRight(aTopLeft);
+ aTopRight.AdjustLeft(aTopRight.GetWidth() * 1.05);
+ tools::Rectangle aBottomRight(aTopRight);
+ aBottomRight.AdjustTop(aBottomRight.GetHeight() * 1.095);
+
+ ImpWriteAutoLayoutPlaceholder(XmlPlaceholderTitle, pInfo->GetTitleRectangle());
+ ImpWriteAutoLayoutPlaceholder(XmlPlaceholderGraphic, aTopLeft);
+ ImpWriteAutoLayoutPlaceholder(XmlPlaceholderGraphic, aTopRight);
+ ImpWriteAutoLayoutPlaceholder(XmlPlaceholderGraphic, aBottomLeft);
+ ImpWriteAutoLayoutPlaceholder(XmlPlaceholderGraphic, aBottomRight);
+ break;
+ }
+
+ case AUTOLAYOUT_TITLE_6CONTENT :
+ {
+ tools::Rectangle aTopLeft(pInfo->GetPresRectangle());
+ aTopLeft.setHeight(tools::Long(aTopLeft.GetHeight() * 0.477));
+ aTopLeft.setWidth(tools::Long(aTopLeft.GetWidth() * 0.322));
+ tools::Rectangle aTopCenter(aTopLeft);
+ aTopCenter.AdjustLeft(aTopCenter.GetWidth() * 1.05);
+ tools::Rectangle aTopRight(aTopLeft);
+ aTopRight.AdjustLeft(aTopRight.GetWidth() * 2 * 1.05);
+
+ tools::Rectangle aBottomLeft(aTopLeft);
+ aBottomLeft.AdjustTop(aBottomLeft.GetHeight() * 1.095);
+ tools::Rectangle aBottomCenter(aTopCenter);
+ aBottomCenter.AdjustTop(aBottomCenter.GetHeight() * 1.095);
+ tools::Rectangle aBottomRight(aTopRight);
+ aBottomRight.AdjustTop(aBottomRight.GetHeight() * 1.095);
+
+ ImpWriteAutoLayoutPlaceholder(XmlPlaceholderTitle, pInfo->GetTitleRectangle());
+ ImpWriteAutoLayoutPlaceholder(XmlPlaceholderGraphic, aTopLeft);
+ ImpWriteAutoLayoutPlaceholder(XmlPlaceholderGraphic, aTopCenter);
+ ImpWriteAutoLayoutPlaceholder(XmlPlaceholderGraphic, aTopRight);
+ ImpWriteAutoLayoutPlaceholder(XmlPlaceholderGraphic, aBottomLeft);
+ ImpWriteAutoLayoutPlaceholder(XmlPlaceholderGraphic, aBottomCenter);
+ ImpWriteAutoLayoutPlaceholder(XmlPlaceholderGraphic, aBottomRight);
+ break;
+ }
+ default:
+ {
+ OSL_FAIL("XMLEXP: unknown autolayout export");
+ break;
+ }
+ }
+ }
+ }
+}
+
+void SdXMLExport::ImpWriteAutoLayoutPlaceholder(XmlPlaceholder ePl, const tools::Rectangle& rRect)
+{
+ OUString aStr;
+ OUStringBuffer sStringBuffer;
+
+ // prepare presentation-placeholder attributes, presentation:object
+ switch(ePl)
+ {
+ case XmlPlaceholderTitle: aStr = "title"; break;
+ case XmlPlaceholderOutline: aStr = "outline"; break;
+ case XmlPlaceholderSubtitle: aStr = "subtitle"; break;
+ case XmlPlaceholderGraphic: aStr = "graphic"; break;
+ case XmlPlaceholderObject: aStr = "object"; break;
+ case XmlPlaceholderChart: aStr = "chart"; break;
+ case XmlPlaceholderTable: aStr = "table"; break;
+ case XmlPlaceholderPage: aStr = "page"; break;
+ case XmlPlaceholderNotes: aStr = "notes"; break;
+ case XmlPlaceholderHandout: aStr = "handout"; break;
+ case XmlPlaceholderVerticalTitle: aStr = "vertical_title"; break;
+ case XmlPlaceholderVerticalOutline: aStr = "vertical_outline"; break;
+ }
+
+ AddAttribute(XML_NAMESPACE_PRESENTATION, XML_OBJECT, aStr);
+
+ // svg:x,y,width,height
+ GetMM100UnitConverter().convertMeasureToXML(sStringBuffer, rRect.Left());
+ aStr = sStringBuffer.makeStringAndClear();
+ AddAttribute(XML_NAMESPACE_SVG, XML_X, aStr);
+
+ GetMM100UnitConverter().convertMeasureToXML(sStringBuffer, rRect.Top());
+ aStr = sStringBuffer.makeStringAndClear();
+ AddAttribute(XML_NAMESPACE_SVG, XML_Y, aStr);
+
+ GetMM100UnitConverter().convertMeasureToXML(sStringBuffer,
+ rRect.GetWidth());
+ aStr = sStringBuffer.makeStringAndClear();
+ AddAttribute(XML_NAMESPACE_SVG, XML_WIDTH, aStr);
+
+ GetMM100UnitConverter().convertMeasureToXML(sStringBuffer,
+ rRect.GetHeight());
+ aStr = sStringBuffer.makeStringAndClear();
+ AddAttribute(XML_NAMESPACE_SVG, XML_HEIGHT, aStr);
+
+ // write presentation-placeholder
+ SvXMLElementExport aPPL(*this, XML_NAMESPACE_PRESENTATION, XML_PLACEHOLDER, true, true);
+}
+
+ImpXMLEXPPageMasterInfo* SdXMLExport::ImpGetOrCreatePageMasterInfo( const Reference< XDrawPage >& xMasterPage )
+{
+ bool bDoesExist = false;
+
+ ImpXMLEXPPageMasterInfo* pNewInfo = new ImpXMLEXPPageMasterInfo(*this, xMasterPage);
+
+ // compare with prev page-master infos
+ for( size_t a = 0; !bDoesExist && a < mvPageMasterInfoList.size(); a++)
+ {
+ if ( mvPageMasterInfoList.at(a)
+ && *mvPageMasterInfoList.at(a) == *pNewInfo
+ )
+ {
+ delete pNewInfo;
+ pNewInfo = mvPageMasterInfoList.at(a).get();
+ bDoesExist = true;
+ }
+ }
+ // add entry when not found same page-master infos
+ if(!bDoesExist)
+ mvPageMasterInfoList.emplace_back( pNewInfo );
+
+ return pNewInfo;
+}
+
+void SdXMLExport::ImpPrepPageMasterInfos()
+{
+ if( IsImpress() )
+ {
+ // create page master info for handout master page
+
+ Reference< XHandoutMasterSupplier > xHMS( GetModel(), UNO_QUERY );
+ if( xHMS.is() )
+ {
+ Reference< XDrawPage > xMasterPage( xHMS->getHandoutMasterPage() );
+ if( xMasterPage.is() )
+ mpHandoutPageMaster = ImpGetOrCreatePageMasterInfo(xMasterPage);
+ }
+ }
+
+ // create page master infos for master pages
+ if(!mnDocMasterPageCount)
+ return;
+
+ // look for needed page-masters, create these
+ for (sal_Int32 nMPageId = 0; nMPageId < mnDocMasterPageCount; nMPageId++)
+ {
+ Reference< XDrawPage > xMasterPage( mxDocMasterPages->getByIndex(nMPageId), UNO_QUERY );
+ ImpXMLEXPPageMasterInfo* pNewInfo = nullptr;
+
+ if(xMasterPage.is())
+ pNewInfo = ImpGetOrCreatePageMasterInfo(xMasterPage);
+
+ mvPageMasterUsageList.push_back( pNewInfo );
+
+ // look for page master of handout page
+ if(IsImpress())
+ {
+ pNewInfo = nullptr;
+ Reference< presentation::XPresentationPage > xPresPage(xMasterPage, UNO_QUERY);
+ if(xPresPage.is())
+ {
+ Reference< XDrawPage > xNotesPage(xPresPage->getNotesPage());
+ if(xNotesPage.is())
+ {
+ pNewInfo = ImpGetOrCreatePageMasterInfo(xNotesPage);
+ }
+ }
+ mvNotesPageMasterUsageList.push_back( pNewInfo );
+ }
+ }
+}
+
+void SdXMLExport::ImpWritePageMasterInfos()
+{
+ // write created page-masters, create names for these
+ for( size_t nCnt = 0; nCnt < mvPageMasterInfoList.size(); nCnt++)
+ {
+ ImpXMLEXPPageMasterInfo* pInfo = mvPageMasterInfoList.at(nCnt).get();
+ if(pInfo)
+ {
+ // create name
+ OUString sNewName = "PM" + OUString::number(nCnt);
+ pInfo->SetName(sNewName);
+
+ // prepare page-master attributes
+ OUString sString;
+ OUStringBuffer sStringBuffer;
+
+ sString = sNewName;
+ AddAttribute(XML_NAMESPACE_STYLE, XML_NAME, sString);
+
+ // write page-layout
+ SvXMLElementExport aPME(*this, XML_NAMESPACE_STYLE, XML_PAGE_LAYOUT, true, true);
+
+ // prepare style:properties inside page-master
+ GetMM100UnitConverter().convertMeasureToXML(sStringBuffer,
+ pInfo->GetBorderTop());
+ sString = sStringBuffer.makeStringAndClear();
+ AddAttribute(XML_NAMESPACE_FO, XML_MARGIN_TOP, sString);
+
+ GetMM100UnitConverter().convertMeasureToXML(sStringBuffer,
+ pInfo->GetBorderBottom());
+ sString = sStringBuffer.makeStringAndClear();
+ AddAttribute(XML_NAMESPACE_FO, XML_MARGIN_BOTTOM, sString);
+
+ GetMM100UnitConverter().convertMeasureToXML(sStringBuffer,
+ pInfo->GetBorderLeft());
+ sString = sStringBuffer.makeStringAndClear();
+ AddAttribute(XML_NAMESPACE_FO, XML_MARGIN_LEFT, sString);
+
+ GetMM100UnitConverter().convertMeasureToXML(sStringBuffer,
+ pInfo->GetBorderRight());
+ sString = sStringBuffer.makeStringAndClear();
+ AddAttribute(XML_NAMESPACE_FO, XML_MARGIN_RIGHT, sString);
+
+ GetMM100UnitConverter().convertMeasureToXML(sStringBuffer,
+ pInfo->GetWidth());
+ sString = sStringBuffer.makeStringAndClear();
+ AddAttribute(XML_NAMESPACE_FO, XML_PAGE_WIDTH, sString);
+
+ GetMM100UnitConverter().convertMeasureToXML(sStringBuffer,
+ pInfo->GetHeight());
+ sString = sStringBuffer.makeStringAndClear();
+ AddAttribute(XML_NAMESPACE_FO, XML_PAGE_HEIGHT, sString);
+
+ if(pInfo->GetOrientation() == view::PaperOrientation_PORTRAIT)
+ AddAttribute(XML_NAMESPACE_STYLE, XML_PRINT_ORIENTATION, XML_PORTRAIT);
+ else
+ AddAttribute(XML_NAMESPACE_STYLE, XML_PRINT_ORIENTATION, XML_LANDSCAPE);
+
+ // write style:properties
+ SvXMLElementExport aPMF(*this, XML_NAMESPACE_STYLE, XML_PAGE_LAYOUT_PROPERTIES, true, true);
+ }
+ }
+}
+
+ImpXMLEXPPageMasterInfo* SdXMLExport::ImpGetPageMasterInfoByName(std::u16string_view rName)
+{
+ if(!rName.empty())
+ {
+ for(const auto & pInfo : mvPageMasterInfoList)
+ {
+ if(pInfo)
+ {
+ if(!pInfo->GetMasterPageName().isEmpty() && rName == pInfo->GetMasterPageName())
+ {
+ return pInfo.get();
+ }
+ }
+ }
+ }
+ return nullptr;
+}
+
+void SdXMLExport::ImpPrepDrawPageInfos()
+{
+ // create draw:style-name entries for page export
+ // containing presentation page attributes AND background attributes
+ // fixed family for page-styles is "drawing-page" (XML_STYLE_FAMILY_SD_DRAWINGPAGE_NAME)
+
+ sal_Int32 nCnt;
+ for(nCnt = 0; nCnt < mnDocDrawPageCount; nCnt++)
+ {
+ Reference<XDrawPage> xDrawPage;
+ mxDocDrawPages->getByIndex(nCnt) >>= xDrawPage;
+ maDrawPagesStyleNames[nCnt] = ImpCreatePresPageStyleName( xDrawPage );
+
+ Reference< presentation::XPresentationPage > xPresPage(xDrawPage, UNO_QUERY);
+ if(xPresPage.is())
+ {
+ maDrawNotesPagesStyleNames[nCnt] = ImpCreatePresPageStyleName( xPresPage->getNotesPage(), false );
+
+ maDrawPagesHeaderFooterSettings[nCnt] = ImpPrepDrawPageHeaderFooterDecls( xDrawPage );
+ maDrawNotesPagesHeaderFooterSettings[nCnt] = ImpPrepDrawPageHeaderFooterDecls( xPresPage->getNotesPage() );
+ }
+ }
+}
+
+static OUString findOrAppendImpl( std::vector< OUString >& rVector, const OUString& rText, std::u16string_view pPrefix )
+{
+ // search rVector if there is already a string that equals rText
+ auto aIter = std::find(rVector.begin(), rVector.end(), rText);
+ sal_Int32 nIndex = std::distance(rVector.begin(), aIter) + 1;
+
+ // if nothing is found, append the string at the end of rVector
+ if( aIter == rVector.end() )
+ rVector.push_back( rText );
+
+ // create a reference string with pPrefix and the index of the
+ // found or created rText
+ return pPrefix + OUString::number( nIndex );
+}
+
+static OUString findOrAppendImpl( std::vector< DateTimeDeclImpl >& rVector, const OUString& rText, bool bFixed, sal_Int32 nFormat, std::u16string_view pPrefix )
+{
+ // search rVector if there is already a DateTimeDeclImpl with rText,bFixed and nFormat
+ auto aIter = std::find_if(rVector.begin(), rVector.end(),
+ [bFixed, &rText, nFormat](const DateTimeDeclImpl& rDecl) {
+ return (rDecl.mbFixed == bFixed) &&
+ (!bFixed || (rDecl.maStrText == rText)) &&
+ (bFixed || (rDecl.mnFormat == nFormat));
+ });
+ sal_Int32 nIndex = std::distance(rVector.begin(), aIter) + 1;
+
+ // if nothing is found, append a new DateTimeDeclImpl
+ if( aIter == rVector.end() )
+ {
+ DateTimeDeclImpl aDecl;
+ aDecl.maStrText = rText;
+ aDecl.mbFixed = bFixed;
+ aDecl.mnFormat = nFormat;
+ rVector.push_back( aDecl );
+ }
+
+ // create a reference string with pPrefix and the index of the
+ // found or created DateTimeDeclImpl
+ return pPrefix + OUString::number( nIndex );
+}
+
+constexpr OUString gpStrHeaderTextPrefix = u"hdr"_ustr;
+constexpr OUString gpStrFooterTextPrefix = u"ftr"_ustr;
+constexpr OUString gpStrDateTimeTextPrefix = u"dtd"_ustr;
+
+HeaderFooterPageSettingsImpl SdXMLExport::ImpPrepDrawPageHeaderFooterDecls( const Reference<XDrawPage>& xDrawPage )
+{
+ HeaderFooterPageSettingsImpl aSettings;
+
+ if( xDrawPage.is() ) try
+ {
+ Reference< XPropertySet > xSet( xDrawPage, UNO_QUERY_THROW );
+ Reference< XPropertySetInfo > xInfo( xSet->getPropertySetInfo() );
+
+ OUString aStrText;
+
+ static constexpr OUString aStrHeaderTextProp( u"HeaderText"_ustr );
+ if( xInfo->hasPropertyByName( aStrHeaderTextProp ) )
+ {
+ xSet->getPropertyValue( aStrHeaderTextProp ) >>= aStrText;
+ if( !aStrText.isEmpty() )
+ aSettings.maStrHeaderDeclName = findOrAppendImpl( maHeaderDeclsVector, aStrText, gpStrHeaderTextPrefix );
+ }
+
+ static constexpr OUString aStrFooterTextProp( u"FooterText"_ustr );
+ if( xInfo->hasPropertyByName( aStrFooterTextProp ) )
+ {
+ xSet->getPropertyValue( aStrFooterTextProp ) >>= aStrText;
+ if( !aStrText.isEmpty() )
+ aSettings.maStrFooterDeclName = findOrAppendImpl( maFooterDeclsVector, aStrText, gpStrFooterTextPrefix );
+ }
+
+ static constexpr OUString aStrDateTimeTextProp( u"DateTimeText"_ustr );
+ if( xInfo->hasPropertyByName( aStrDateTimeTextProp ) )
+ {
+ bool bFixed = false;
+ sal_Int32 nFormat = 0;
+ xSet->getPropertyValue( aStrDateTimeTextProp ) >>= aStrText;
+ xSet->getPropertyValue("IsDateTimeFixed") >>= bFixed;
+ xSet->getPropertyValue("DateTimeFormat") >>= nFormat;
+
+ if( !bFixed || !aStrText.isEmpty() )
+ {
+ aSettings.maStrDateTimeDeclName = findOrAppendImpl( maDateTimeDeclsVector, aStrText, bFixed, nFormat, gpStrDateTimeTextPrefix );
+ if( !bFixed )
+ addDataStyle( nFormat );
+ }
+ }
+ }
+ catch(const Exception&)
+ {
+ TOOLS_WARN_EXCEPTION("xmloff.draw", "");
+ }
+
+ return aSettings;
+}
+
+void SdXMLExport::ImpWriteHeaderFooterDecls()
+{
+ OUStringBuffer sBuffer;
+
+ if( !maHeaderDeclsVector.empty() )
+ {
+ // export header decls
+ const OUString aPrefix( gpStrHeaderTextPrefix );
+ sal_Int32 nIndex = 1;
+ for( const auto& rDecl : maHeaderDeclsVector )
+ {
+ sBuffer.append( aPrefix + OUString::number( nIndex ) );
+ AddAttribute(XML_NAMESPACE_PRESENTATION, XML_NAME, sBuffer.makeStringAndClear());
+
+ SvXMLElementExport aElem(*this, XML_NAMESPACE_PRESENTATION, XML_HEADER_DECL, true, true);
+ Characters(rDecl);
+ ++nIndex;
+ }
+ }
+
+ if( !maFooterDeclsVector.empty() )
+ {
+ // export footer decls
+ const OUString aPrefix( gpStrFooterTextPrefix );
+ sal_Int32 nIndex = 1;
+ for( const auto& rDecl : maFooterDeclsVector )
+ {
+ sBuffer.append( aPrefix + OUString::number( nIndex ) );
+ AddAttribute(XML_NAMESPACE_PRESENTATION, XML_NAME, sBuffer.makeStringAndClear());
+
+ SvXMLElementExport aElem(*this, XML_NAMESPACE_PRESENTATION, XML_FOOTER_DECL, false, false);
+ Characters(rDecl);
+ ++nIndex;
+ }
+ }
+
+ if( maDateTimeDeclsVector.empty() )
+ return;
+
+ // export footer decls
+ const OUString aPrefix( gpStrDateTimeTextPrefix );
+ sal_Int32 nIndex = 1;
+ for( const auto& rDecl : maDateTimeDeclsVector )
+ {
+ sBuffer.append( aPrefix + OUString::number( nIndex ) );
+ AddAttribute( XML_NAMESPACE_PRESENTATION, XML_NAME, sBuffer.makeStringAndClear());
+
+ AddAttribute( XML_NAMESPACE_PRESENTATION, XML_SOURCE, rDecl.mbFixed ? XML_FIXED : XML_CURRENT_DATE );
+
+ if( !rDecl.mbFixed )
+ AddAttribute( XML_NAMESPACE_STYLE, XML_DATA_STYLE_NAME, getDataStyleName( rDecl.mnFormat ) );
+
+ SvXMLElementExport aElem(*this, XML_NAMESPACE_PRESENTATION, XML_DATE_TIME_DECL, false, false);
+ if( rDecl.mbFixed )
+ Characters(rDecl.maStrText);
+
+ ++nIndex;
+ }
+}
+
+void SdXMLExport::ImplExportHeaderFooterDeclAttributes( const HeaderFooterPageSettingsImpl& aSettings )
+{
+ if( !aSettings.maStrHeaderDeclName.isEmpty() )
+ AddAttribute( XML_NAMESPACE_PRESENTATION, XML_USE_HEADER_NAME, aSettings.maStrHeaderDeclName );
+
+ if( !aSettings.maStrFooterDeclName.isEmpty() )
+ AddAttribute( XML_NAMESPACE_PRESENTATION, XML_USE_FOOTER_NAME, aSettings.maStrFooterDeclName );
+
+ if( !aSettings.maStrDateTimeDeclName.isEmpty() )
+ AddAttribute( XML_NAMESPACE_PRESENTATION, XML_USE_DATE_TIME_NAME, aSettings.maStrDateTimeDeclName );
+}
+
+OUString SdXMLExport::ImpCreatePresPageStyleName( const Reference<XDrawPage>& xDrawPage, bool bExportBackground /* = true */ )
+{
+ // create name
+ OUString sStyleName;
+
+ // create style for this page and add to auto style pool
+
+ Reference< beans::XPropertySet > xPropSet1(xDrawPage, UNO_QUERY);
+ if(xPropSet1.is())
+ {
+ Reference< beans::XPropertySet > xPropSet;
+
+ if( bExportBackground )
+ {
+ // since the background items are in a different propertyset
+ // which itself is a property of the pages property set
+ // we now merge these two propertysets if possible to simulate
+ // a single propertyset with all draw page properties
+ static constexpr OUString aBackground(u"Background"_ustr);
+ Reference< beans::XPropertySet > xPropSet2;
+ Reference< beans::XPropertySetInfo > xInfo( xPropSet1->getPropertySetInfo() );
+ if( xInfo.is() && xInfo->hasPropertyByName( aBackground ) )
+ {
+ Any aAny( xPropSet1->getPropertyValue( aBackground ) );
+ aAny >>= xPropSet2;
+ }
+
+ if( xPropSet2.is() )
+ xPropSet = PropertySetMerger_CreateInstance( xPropSet1, xPropSet2 );
+ else
+ xPropSet = xPropSet1;
+ }
+ else
+ {
+ xPropSet = xPropSet1;
+ }
+
+ const rtl::Reference< SvXMLExportPropertyMapper > aMapperRef( GetPresPagePropsMapper() );
+
+ std::vector<XMLPropertyState> aPropStates(aMapperRef->Filter(*this, xPropSet));
+
+ if( !aPropStates.empty() )
+ {
+ // there are filtered properties -> hard attributes
+ // try to find this style in AutoStylePool
+ sStyleName = GetAutoStylePool()->Find(XmlStyleFamily::SD_DRAWINGPAGE_ID, sStyleName, aPropStates);
+
+ if(sStyleName.isEmpty())
+ {
+ // Style did not exist, add it to AutoStalePool
+ sStyleName = GetAutoStylePool()->Add(XmlStyleFamily::SD_DRAWINGPAGE_ID, sStyleName, std::move(aPropStates));
+ }
+ }
+ }
+
+ return sStyleName;
+}
+
+void SdXMLExport::ImpPrepMasterPageInfos()
+{
+ // create draw:style-name entries for master page export
+ // containing only background attributes
+ // fixed family for page-styles is "drawing-page" (XML_STYLE_FAMILY_SD_DRAWINGPAGE_NAME)
+
+ sal_Int32 nCnt;
+ for( nCnt = 0; nCnt < mnDocMasterPageCount; nCnt++)
+ {
+ Reference<XDrawPage> xDrawPage;
+ mxDocMasterPages->getByIndex(nCnt) >>= xDrawPage;
+ maMasterPagesStyleNames[nCnt] = ImpCreatePresPageStyleName( xDrawPage );
+ }
+
+ if( !IsImpress() )
+ return;
+
+ Reference< presentation::XHandoutMasterSupplier > xHandoutSupp( GetModel(), UNO_QUERY );
+ if( xHandoutSupp.is() )
+ {
+ Reference< XDrawPage > xHandoutPage( xHandoutSupp->getHandoutMasterPage() );
+ if( xHandoutPage.is() )
+ {
+ maHandoutPageHeaderFooterSettings = ImpPrepDrawPageHeaderFooterDecls( xHandoutPage );
+ maHandoutMasterStyleName = ImpCreatePresPageStyleName( xHandoutPage, false );
+ }
+ }
+}
+
+void SdXMLExport::ImpWritePresentationStyles()
+{
+ if(!IsImpress())
+ return;
+
+ for (sal_Int32 nCnt = 0; nCnt < mnDocMasterPageCount; nCnt++)
+ {
+ Any aAny(mxDocMasterPages->getByIndex(nCnt));
+ Reference<container::XNamed> xNamed;
+
+ if(aAny >>= xNamed)
+ {
+ // write presentation styles (ONLY if presentation)
+ if(IsImpress() && mxDocStyleFamilies.is() && xNamed.is())
+ {
+ rtl::Reference<XMLStyleExport> aStEx(new XMLStyleExport(*this, GetAutoStylePool().get()));
+ const rtl::Reference< SvXMLExportPropertyMapper > aMapperRef( GetPropertySetMapper() );
+
+ OUString aPrefix( xNamed->getName() + "-" );
+
+ aStEx->exportStyleFamily(xNamed->getName(),
+ XML_STYLE_FAMILY_SD_PRESENTATION_NAME,
+ aMapperRef, false,
+ XmlStyleFamily::SD_PRESENTATION_ID, &aPrefix);
+ }
+ }
+ }
+}
+
+void SdXMLExport::ExportMeta_()
+{
+ uno::Sequence<beans::NamedValue> stats { { "ObjectCount", uno::Any(mnObjectCount) } };
+
+ // update document statistics at the model
+ uno::Reference<document::XDocumentPropertiesSupplier> xPropSup(GetModel(),
+ uno::UNO_QUERY_THROW);
+ uno::Reference<document::XDocumentProperties> xDocProps(
+ xPropSup->getDocumentProperties());
+ if (xDocProps.is()) {
+ xDocProps->setDocumentStatistics(stats);
+ }
+
+ // call parent
+ SvXMLExport::ExportMeta_();
+}
+
+void SdXMLExport::ExportFontDecls_()
+{
+ GetFontAutoStylePool(); // make sure the pool is created
+ SvXMLExport::ExportFontDecls_();
+}
+
+void SdXMLExport::ExportContent_()
+{
+ // export <pres:header-decl>, <pres:footer-decl> and <pres:date-time-decl> elements
+ ImpWriteHeaderFooterDecls();
+
+ // page export
+ for(sal_Int32 nPageInd(0); nPageInd < mnDocDrawPageCount; nPageInd++)
+ {
+ uno::Reference<drawing::XDrawPage> xDrawPage( mxDocDrawPages->getByIndex(nPageInd), uno::UNO_QUERY );
+
+ // set progress view
+ if(GetStatusIndicator().is())
+ GetStatusIndicator()->setValue(((nPageInd + 1) * 100) / mnDocDrawPageCount);
+
+ if(xDrawPage.is())
+ {
+ // prepare page attributes, name of page
+ Reference < container::XNamed > xNamed(xDrawPage, UNO_QUERY);
+ if(xNamed.is())
+ AddAttribute(XML_NAMESPACE_DRAW, XML_NAME, xNamed->getName());
+
+ // draw:style-name (presentation page attributes AND background attributes)
+ if( !maDrawPagesStyleNames[nPageInd].isEmpty() )
+ AddAttribute(XML_NAMESPACE_DRAW, XML_STYLE_NAME,
+ maDrawPagesStyleNames[nPageInd]);
+
+ // draw:master-page-name
+ Reference < drawing::XMasterPageTarget > xMasterPageInt(xDrawPage, UNO_QUERY);
+ if(xMasterPageInt.is())
+ {
+ Reference<XDrawPage> xUsedMasterPage(xMasterPageInt->getMasterPage());
+ if(xUsedMasterPage.is())
+ {
+ Reference < container::XNamed > xMasterNamed(xUsedMasterPage, UNO_QUERY);
+ if(xMasterNamed.is())
+ {
+ AddAttribute(XML_NAMESPACE_DRAW, XML_MASTER_PAGE_NAME,
+ EncodeStyleName( xMasterNamed->getName()) );
+ }
+ }
+ }
+
+ // presentation:page-layout-name
+ if( IsImpress() && !maDrawPagesAutoLayoutNames[nPageInd+1].isEmpty())
+ {
+ AddAttribute(XML_NAMESPACE_PRESENTATION, XML_PRESENTATION_PAGE_LAYOUT_NAME, maDrawPagesAutoLayoutNames[nPageInd+1] );
+ }
+
+ Reference< beans::XPropertySet > xProps( xDrawPage, UNO_QUERY );
+ if( xProps.is() )
+ {
+ try
+ {
+ OUString aBookmarkURL;
+ xProps->getPropertyValue("BookmarkURL") >>= aBookmarkURL;
+
+ if( !aBookmarkURL.isEmpty() )
+ {
+ sal_Int32 nIndex = aBookmarkURL.lastIndexOf( '#' );
+ if( nIndex != -1 )
+ {
+ OUString aFileName( aBookmarkURL.copy( 0, nIndex ) );
+ std::u16string_view aBookmarkName( aBookmarkURL.subView( nIndex+1 ) );
+
+ aBookmarkURL = GetRelativeReference( aFileName ) + "#" + aBookmarkName;
+ }
+
+ AddAttribute ( XML_NAMESPACE_XLINK, XML_HREF, aBookmarkURL);
+ AddAttribute ( XML_NAMESPACE_XLINK, XML_TYPE, XML_SIMPLE );
+ AddAttribute ( XML_NAMESPACE_XLINK, XML_SHOW, XML_REPLACE );
+ AddAttribute ( XML_NAMESPACE_XLINK, XML_ACTUATE, XML_ONREQUEST );
+ }
+ }
+ catch(const Exception&)
+ {
+ OSL_FAIL(" no \"BookmarkURL\" property at page?" );
+ }
+ }
+
+ if( IsImpress() )
+ ImplExportHeaderFooterDeclAttributes( maDrawPagesHeaderFooterSettings[nPageInd] );
+
+ OUString sNavigationOrder( getNavigationOrder( xDrawPage ) );
+ if( !sNavigationOrder.isEmpty() )
+ AddAttribute ( XML_NAMESPACE_DRAW, XML_NAV_ORDER, sNavigationOrder );
+
+ rtl::Reference< xmloff::AnimationsExporter > xAnimationsExporter;
+ uno::Reference< css::animations::XAnimationNodeSupplier > xAnimNodeSupplier;
+
+ // prepare animation export
+ if(IsImpress())
+ {
+ if( getExportFlags() & SvXMLExportFlags::OASIS )
+ {
+ // export new animations for oasis format
+ xAnimNodeSupplier.set( xDrawPage, UNO_QUERY );
+
+ // prepare animations exporter if impress
+ if(xAnimNodeSupplier.is())
+ {
+ xAnimationsExporter = new xmloff::AnimationsExporter( *this, xProps );
+ xAnimationsExporter->prepare( xAnimNodeSupplier->getAnimationNode() );
+ }
+ }
+ else
+ {
+ // export old animations for ooo format
+ rtl::Reference< XMLAnimationsExporter > xAnimExport = new XMLAnimationsExporter();
+ GetShapeExport()->setAnimationsExporter( xAnimExport );
+ }
+ }
+
+ // write draw:id
+ const OUString aPageId = getInterfaceToIdentifierMapper().getIdentifier( xDrawPage );
+ if( !aPageId.isEmpty() )
+ {
+ AddAttributeIdLegacy(XML_NAMESPACE_DRAW, aPageId);
+ }
+
+ // write page
+ SvXMLElementExport aDPG(*this, XML_NAMESPACE_DRAW, XML_PAGE, true, true);
+
+ // write optional office:forms
+ exportFormsElement( xDrawPage );
+
+ // write graphic objects on this page (if any)
+ if(xDrawPage.is() && xDrawPage->getCount())
+ GetShapeExport()->exportShapes( xDrawPage );
+
+ // write animations and presentation notes (ONLY if presentation)
+ if(IsImpress())
+ {
+ if(xAnimNodeSupplier.is())
+ {
+ xAnimationsExporter->exportAnimations( xAnimNodeSupplier->getAnimationNode() );
+ }
+ else
+ {
+ // animations
+ rtl::Reference< XMLAnimationsExporter > xAnimExport( GetShapeExport()->getAnimationsExporter() );
+ if( xAnimExport.is() )
+ xAnimExport->exportAnimations( *this );
+
+ xAnimExport = nullptr;
+ GetShapeExport()->setAnimationsExporter( xAnimExport );
+ }
+
+ // presentations
+ Reference< presentation::XPresentationPage > xPresPage(xDrawPage, UNO_QUERY);
+ if(xPresPage.is())
+ {
+ Reference< XDrawPage > xNotesPage(xPresPage->getNotesPage());
+ if(xNotesPage.is())
+ {
+ if( !maDrawNotesPagesStyleNames[nPageInd].isEmpty() )
+ AddAttribute(XML_NAMESPACE_DRAW, XML_STYLE_NAME, maDrawNotesPagesStyleNames[nPageInd]);
+
+ ImplExportHeaderFooterDeclAttributes( maDrawNotesPagesHeaderFooterSettings[nPageInd] );
+
+ // write presentation notes
+ SvXMLElementExport aPSY(*this, XML_NAMESPACE_PRESENTATION, XML_NOTES, true, true);
+
+ // write optional office:forms
+ exportFormsElement( xNotesPage );
+
+ // write shapes per se
+ GetShapeExport()->exportShapes( xNotesPage );
+ }
+ }
+ }
+
+ exportAnnotations( xDrawPage );
+ }
+ }
+
+ if( IsImpress() )
+ exportPresentationSettings();
+}
+
+void SdXMLExport::exportPresentationSettings()
+{
+ try
+ {
+ Reference< XPresentationSupplier > xPresSupplier( GetModel(), UNO_QUERY );
+ if( !xPresSupplier.is() )
+ return;
+
+ Reference< XPropertySet > xPresProps( xPresSupplier->getPresentation(), UNO_QUERY );
+ if( !xPresProps.is() )
+ return;
+
+ bool bHasAttr = false;
+
+ bool bTemp = false;
+
+ // export range
+ xPresProps->getPropertyValue("IsShowAll") >>= bTemp;
+ if( !bTemp )
+ {
+ OUString aFirstPage;
+ xPresProps->getPropertyValue("FirstPage") >>= aFirstPage;
+ if( !aFirstPage.isEmpty() )
+ {
+ AddAttribute(XML_NAMESPACE_PRESENTATION, XML_START_PAGE, aFirstPage );
+ bHasAttr = true;
+ }
+ else
+ {
+ OUString aCustomShow;
+ xPresProps->getPropertyValue("CustomShow") >>= aCustomShow;
+ if( !aCustomShow.isEmpty() )
+ {
+ AddAttribute(XML_NAMESPACE_PRESENTATION, XML_SHOW, aCustomShow );
+ bHasAttr = true;
+ }
+ }
+ }
+
+ xPresProps->getPropertyValue("IsEndless") >>= bTemp;
+ if( bTemp )
+ {
+ AddAttribute(XML_NAMESPACE_PRESENTATION, XML_ENDLESS, XML_TRUE );
+ bHasAttr = true;
+
+ sal_Int32 nPause = 0;
+ xPresProps->getPropertyValue("Pause") >>= nPause;
+
+ util::Duration aDuration;
+ aDuration.Seconds = static_cast<sal_uInt16>(nPause);
+
+ OUStringBuffer aOut;
+ ::sax::Converter::convertDuration(aOut, aDuration);
+ AddAttribute(XML_NAMESPACE_PRESENTATION, XML_PAUSE, aOut.makeStringAndClear() );
+ }
+
+ xPresProps->getPropertyValue("AllowAnimations") >>= bTemp;
+ if( !bTemp )
+ {
+ AddAttribute(XML_NAMESPACE_PRESENTATION, XML_ANIMATIONS, XML_DISABLED );
+ bHasAttr = true;
+ }
+
+ xPresProps->getPropertyValue("IsAlwaysOnTop") >>= bTemp;
+ if( bTemp )
+ {
+ AddAttribute(XML_NAMESPACE_PRESENTATION, XML_STAY_ON_TOP, XML_TRUE );
+ bHasAttr = true;
+ }
+
+ xPresProps->getPropertyValue("IsAutomatic") >>= bTemp;
+ if( bTemp )
+ {
+ AddAttribute(XML_NAMESPACE_PRESENTATION, XML_FORCE_MANUAL, XML_TRUE );
+ bHasAttr = true;
+ }
+
+ xPresProps->getPropertyValue("IsFullScreen") >>= bTemp;
+ if( !bTemp )
+ {
+ AddAttribute(XML_NAMESPACE_PRESENTATION, XML_FULL_SCREEN, XML_FALSE );
+ bHasAttr = true;
+ }
+
+ // We need to always export this attribute, because the import had the wrong default (tdf#108824)
+ xPresProps->getPropertyValue("IsMouseVisible") >>= bTemp;
+ AddAttribute(XML_NAMESPACE_PRESENTATION, XML_MOUSE_VISIBLE, bTemp ? XML_TRUE : XML_FALSE);
+ bHasAttr = true;
+
+ xPresProps->getPropertyValue("StartWithNavigator") >>= bTemp;
+ if( bTemp )
+ {
+ AddAttribute(XML_NAMESPACE_PRESENTATION, XML_START_WITH_NAVIGATOR, XML_TRUE );
+ bHasAttr = true;
+ }
+
+ xPresProps->getPropertyValue("UsePen") >>= bTemp;
+ if( bTemp )
+ {
+ AddAttribute(XML_NAMESPACE_PRESENTATION, XML_MOUSE_AS_PEN, XML_TRUE );
+ bHasAttr = true;
+ }
+
+ xPresProps->getPropertyValue("IsTransitionOnClick") >>= bTemp;
+ if( !bTemp )
+ {
+ AddAttribute(XML_NAMESPACE_PRESENTATION, XML_TRANSITION_ON_CLICK, XML_DISABLED );
+ bHasAttr = true;
+ }
+
+ xPresProps->getPropertyValue("IsShowLogo") >>= bTemp;
+ if( bTemp )
+ {
+ AddAttribute(XML_NAMESPACE_PRESENTATION, XML_SHOW_LOGO, XML_TRUE );
+ bHasAttr = true;
+ }
+
+ Reference< container::XNameContainer > xShows;
+ Sequence< OUString > aShowNames;
+ bool bHasNames = false;
+
+ Reference< XCustomPresentationSupplier > xSup( GetModel(), UNO_QUERY );
+ if( xSup.is() )
+ {
+ xShows = xSup->getCustomPresentations();
+ if( xShows.is() )
+ {
+ aShowNames = xShows->getElementNames();
+ bHasNames = aShowNames.hasElements();
+ }
+ }
+
+ if( bHasAttr || bHasNames )
+ {
+ SvXMLElementExport aSettings(*this, XML_NAMESPACE_PRESENTATION, XML_SETTINGS, true, true);
+
+ if( !bHasNames )
+ return;
+
+ Reference< XIndexContainer > xShow;
+ Reference< XNamed > xPageName;
+
+ OUStringBuffer sTmp;
+
+ for( const auto& rShowName : std::as_const(aShowNames) )
+ {
+ AddAttribute(XML_NAMESPACE_PRESENTATION, XML_NAME, rShowName );
+
+ xShows->getByName( rShowName ) >>= xShow;
+ SAL_WARN_IF( !xShow.is(), "xmloff", "invalid custom show!" );
+ if( !xShow.is() )
+ continue;
+
+ const sal_Int32 nPageCount = xShow->getCount();
+ for( sal_Int32 nPage = 0; nPage < nPageCount; nPage++ )
+ {
+ xShow->getByIndex( nPage ) >>= xPageName;
+
+ if( !xPageName.is() )
+ continue;
+
+ if( !sTmp.isEmpty() )
+ sTmp.append( ',' );
+ sTmp.append( xPageName->getName() );
+
+ }
+
+ if( !sTmp.isEmpty() )
+ AddAttribute(XML_NAMESPACE_PRESENTATION, XML_PAGES, sTmp.makeStringAndClear() );
+
+ SvXMLElementExport aShows(*this, XML_NAMESPACE_PRESENTATION, XML_SHOW, true, true);
+ }
+ }
+ }
+ catch(const uno::Exception&)
+ {
+ TOOLS_WARN_EXCEPTION("xmloff.draw", "while exporting <presentation:settings>");
+ }
+}
+
+void SdXMLExport::ExportStyles_(bool bUsed)
+{
+ GetPropertySetMapper()->SetAutoStyles( false );
+
+ // export fill styles
+ SvXMLExport::ExportStyles_( bUsed );
+
+ // write draw:style-name for object graphic-styles
+ GetShapeExport()->ExportGraphicDefaults();
+
+ // do not export in ODF 1.1 or older
+ if (getSaneDefaultVersion() >= SvtSaveOptions::ODFSVER_012)
+ GetShapeExport()->GetShapeTableExport()->exportTableStyles();
+
+ // write presentation styles
+ ImpWritePresentationStyles();
+
+ // prepare draw:auto-layout-name for page export
+ ImpPrepAutoLayoutInfos();
+
+ // write draw:auto-layout-name for page export
+ ImpWriteAutoLayoutInfos();
+
+ Reference< beans::XPropertySet > xInfoSet( getExportInfo() );
+ if( xInfoSet.is() )
+ {
+ Reference< beans::XPropertySetInfo > xInfoSetInfo( xInfoSet->getPropertySetInfo() );
+
+ if( xInfoSetInfo->hasPropertyByName( gsPageLayoutNames ) )
+ {
+ xInfoSet->setPropertyValue( gsPageLayoutNames, Any(maDrawPagesAutoLayoutNames) );
+ }
+ }
+}
+
+void SdXMLExport::collectAutoStyles()
+{
+ SvXMLExport::collectAutoStyles();
+ if (mbAutoStylesCollected)
+ return;
+
+ Reference< beans::XPropertySet > xInfoSet( getExportInfo() );
+ if( xInfoSet.is() )
+ {
+ Reference< beans::XPropertySetInfo > xInfoSetInfo( xInfoSet->getPropertySetInfo() );
+
+ if( xInfoSetInfo->hasPropertyByName( gsPageLayoutNames ) )
+ {
+ xInfoSet->getPropertyValue( gsPageLayoutNames ) >>= maDrawPagesAutoLayoutNames;
+ }
+ }
+
+ GetPropertySetMapper()->SetAutoStyles( true );
+
+ if( getExportFlags() & SvXMLExportFlags::STYLES )
+ {
+ // #80012# PageMaster export moved from _ExportStyles
+ // prepare page-master infos
+ ImpPrepPageMasterInfos();
+
+ // prepare draw:style-name for master page export
+ ImpPrepMasterPageInfos();
+ }
+
+ if( getExportFlags() & SvXMLExportFlags::CONTENT )
+ {
+ // prepare draw:style-name for page export
+ ImpPrepDrawPageInfos();
+ }
+
+ if( getExportFlags() & SvXMLExportFlags::STYLES )
+ {
+ // create auto style infos for shapes on master handout page
+ if( IsImpress() )
+ {
+ Reference< presentation::XHandoutMasterSupplier > xHandoutSupp( GetModel(), UNO_QUERY );
+ if( xHandoutSupp.is() )
+ {
+ Reference< XDrawPage > xHandoutPage( xHandoutSupp->getHandoutMasterPage() );
+ if( xHandoutPage.is() && xHandoutPage->getCount())
+ GetShapeExport()->collectShapesAutoStyles( xHandoutPage );
+ }
+ }
+
+ // create auto style infos for objects on master pages
+ for(sal_Int32 nMPageId(0); nMPageId < mnDocMasterPageCount; nMPageId++)
+ {
+ Reference< XDrawPage > xMasterPage(mxDocMasterPages->getByIndex(nMPageId), UNO_QUERY );
+
+ if( xMasterPage.is() )
+ {
+ // collect layer information
+ GetFormExport()->examineForms( xMasterPage );
+
+ // get MasterPage Name
+ OUString aMasterPageNamePrefix;
+ Reference < container::XNamed > xNamed(xMasterPage, UNO_QUERY);
+ if(xNamed.is())
+ {
+ aMasterPageNamePrefix = xNamed->getName();
+ }
+ if(!aMasterPageNamePrefix.isEmpty())
+ {
+ aMasterPageNamePrefix += "-";
+ }
+ GetShapeExport()->setPresentationStylePrefix( aMasterPageNamePrefix );
+
+ if(xMasterPage.is() && xMasterPage->getCount())
+ GetShapeExport()->collectShapesAutoStyles( xMasterPage );
+
+ if(IsImpress())
+ {
+ Reference< presentation::XPresentationPage > xPresPage(xMasterPage, UNO_QUERY);
+ if(xPresPage.is())
+ {
+ Reference< XDrawPage > xNotesPage(xPresPage->getNotesPage());
+ if(xNotesPage.is())
+ {
+ // collect layer information
+ GetFormExport()->examineForms( xNotesPage );
+
+ if(xNotesPage->getCount())
+ GetShapeExport()->collectShapesAutoStyles( xNotesPage );
+ }
+ }
+ }
+ collectAnnotationAutoStyles(xMasterPage);
+ }
+ }
+ }
+
+ if( getExportFlags() & SvXMLExportFlags::CONTENT )
+ {
+ // prepare animations exporter if impress
+ if(IsImpress() && (!(getExportFlags() & SvXMLExportFlags::OASIS)) )
+ {
+ rtl::Reference< XMLAnimationsExporter > xAnimExport = new XMLAnimationsExporter();
+ GetShapeExport()->setAnimationsExporter( xAnimExport );
+ }
+
+ // create auto style infos for objects on pages
+ for(sal_Int32 nPageInd(0); nPageInd < mnDocDrawPageCount; nPageInd++)
+ {
+ Reference<XDrawPage> xDrawPage( mxDocDrawPages->getByIndex(nPageInd), UNO_QUERY );
+ if( xDrawPage.is() )
+ {
+ // collect layer information
+ GetFormExport()->examineForms( xDrawPage );
+
+ // get MasterPage Name
+ OUString aMasterPageNamePrefix;
+ Reference < drawing::XMasterPageTarget > xMasterPageInt(xDrawPage, UNO_QUERY);
+ if(xMasterPageInt.is())
+ {
+ Reference<XDrawPage> xUsedMasterPage(xMasterPageInt->getMasterPage());
+ if(xUsedMasterPage.is())
+ {
+ Reference < container::XNamed > xMasterNamed(xUsedMasterPage, UNO_QUERY);
+ if(xMasterNamed.is())
+ {
+ aMasterPageNamePrefix = xMasterNamed->getName();
+ }
+ }
+ }
+ if(!aMasterPageNamePrefix.isEmpty())
+ {
+ aMasterPageNamePrefix += "-";
+ }
+
+ GetShapeExport()->setPresentationStylePrefix( aMasterPageNamePrefix );
+
+ // prepare object infos
+ if(xDrawPage.is() && xDrawPage->getCount())
+ GetShapeExport()->collectShapesAutoStyles( xDrawPage );
+
+ // prepare presentation notes page object infos (ONLY if presentation)
+ if(IsImpress())
+ {
+ Reference< presentation::XPresentationPage > xPresPage(xDrawPage, UNO_QUERY);
+ if(xPresPage.is())
+ {
+ Reference< XDrawPage > xNotesPage(xPresPage->getNotesPage());
+ if(xNotesPage.is())
+ {
+ // collect layer information
+ GetFormExport()->examineForms( xNotesPage );
+
+ if(xNotesPage->getCount())
+ GetShapeExport()->collectShapesAutoStyles( xNotesPage );
+ }
+ }
+ }
+
+ collectAnnotationAutoStyles( xDrawPage );
+ }
+ }
+ if (IsImpress())
+ {
+ rtl::Reference< XMLAnimationsExporter > xAnimExport;
+ GetShapeExport()->setAnimationsExporter( xAnimExport );
+ }
+ }
+
+ mbAutoStylesCollected = true;
+}
+
+void SdXMLExport::ExportAutoStyles_()
+{
+ collectAutoStyles();
+
+ if( getExportFlags() & SvXMLExportFlags::STYLES )
+ {
+ // write page-master infos
+ ImpWritePageMasterInfos();
+ }
+
+ // export draw-page styles
+ GetAutoStylePool()->exportXML( XmlStyleFamily::SD_DRAWINGPAGE_ID );
+
+ exportAutoDataStyles();
+
+ GetShapeExport()->exportAutoStyles();
+
+ SvXMLExportFlags nContentAutostyles = SvXMLExportFlags::CONTENT | SvXMLExportFlags::AUTOSTYLES;
+ if ( ( getExportFlags() & nContentAutostyles ) == nContentAutostyles )
+ GetFormExport()->exportAutoStyles( );
+
+ // ...for text
+ GetTextParagraphExport()->exportTextAutoStyles();
+}
+
+void SdXMLExport::ExportMasterStyles_()
+{
+ // export layer
+ SdXMLayerExporter::exportLayer( *this );
+
+ // export handout master page if impress
+ if( IsImpress() )
+ {
+ Reference< presentation::XHandoutMasterSupplier > xHandoutSupp( GetModel(), UNO_QUERY );
+ if( xHandoutSupp.is() )
+ {
+ Reference< XDrawPage > xHandoutPage( xHandoutSupp->getHandoutMasterPage() );
+ if( xHandoutPage.is() )
+ {
+ // presentation:page-layout-name
+ if( IsImpress() && !maDrawPagesAutoLayoutNames[0].isEmpty())
+ {
+ AddAttribute(XML_NAMESPACE_PRESENTATION, XML_PRESENTATION_PAGE_LAYOUT_NAME, EncodeStyleName( maDrawPagesAutoLayoutNames[0] ));
+ }
+
+ ImpXMLEXPPageMasterInfo* pInfo = mpHandoutPageMaster;
+ if(pInfo)
+ {
+ const OUString& sString = pInfo->GetName();
+ AddAttribute(XML_NAMESPACE_STYLE, XML_PAGE_LAYOUT_NAME, sString );
+ }
+
+ // draw:style-name
+ if( !maHandoutMasterStyleName.isEmpty() )
+ AddAttribute(XML_NAMESPACE_DRAW, XML_STYLE_NAME, maHandoutMasterStyleName);
+
+ ImplExportHeaderFooterDeclAttributes( maHandoutPageHeaderFooterSettings );
+
+ // write masterpage
+ SvXMLElementExport aMPG(*this, XML_NAMESPACE_STYLE, XML_HANDOUT_MASTER, true, true);
+
+ // write graphic objects on this master page (if any)
+ if(xHandoutPage.is() && xHandoutPage->getCount())
+ GetShapeExport()->exportShapes( xHandoutPage );
+ }
+ }
+ }
+
+ // export MasterPages in master-styles section
+ for (sal_Int32 nMPageId = 0; nMPageId < mnDocMasterPageCount; nMPageId++)
+ {
+ Reference< XDrawPage > xMasterPage( mxDocMasterPages->getByIndex(nMPageId), UNO_QUERY );
+ if(xMasterPage.is())
+ {
+ // prepare masterpage attributes
+ Reference < container::XNamed > xNamed(xMasterPage, UNO_QUERY);
+ if(xNamed.is())
+ {
+ bool bEncoded = false;
+ OUString sMasterPageName = xNamed->getName();
+ AddAttribute(XML_NAMESPACE_STYLE, XML_NAME,
+ EncodeStyleName( sMasterPageName, &bEncoded ));
+ if( bEncoded )
+ AddAttribute(
+ XML_NAMESPACE_STYLE, XML_DISPLAY_NAME,
+ sMasterPageName );
+ }
+
+ ImpXMLEXPPageMasterInfo* pInfo = mvPageMasterUsageList.at( nMPageId );
+ if(pInfo)
+ {
+ const OUString& sString = pInfo->GetName();
+ AddAttribute(XML_NAMESPACE_STYLE, XML_PAGE_LAYOUT_NAME, sString );
+ }
+
+ // draw:style-name (background attributes)
+ if( !maMasterPagesStyleNames[nMPageId].isEmpty() )
+ AddAttribute(XML_NAMESPACE_DRAW, XML_STYLE_NAME,
+ maMasterPagesStyleNames[nMPageId]);
+
+ // write masterpage
+ SvXMLElementExport aMPG(*this, XML_NAMESPACE_STYLE, XML_MASTER_PAGE, true, true);
+
+ // write optional office:forms
+ exportFormsElement( xMasterPage );
+
+ // write optional loext:theme
+ exportTheme(xMasterPage);
+
+ // write graphic objects on this master page (if any)
+ if(xMasterPage.is() && xMasterPage->getCount())
+ GetShapeExport()->exportShapes( xMasterPage );
+
+ // write presentation notes (ONLY if presentation)
+ if(IsImpress())
+ {
+ Reference< presentation::XPresentationPage > xPresPage(xMasterPage, UNO_QUERY);
+ if(xPresPage.is())
+ {
+ Reference< XDrawPage > xNotesPage(xPresPage->getNotesPage());
+ if(xNotesPage.is())
+ {
+ ImpXMLEXPPageMasterInfo* pMasterInfo = mvNotesPageMasterUsageList.at( nMPageId );
+ if(pMasterInfo)
+ {
+ const OUString& sString = pMasterInfo->GetName();
+ AddAttribute(XML_NAMESPACE_STYLE, XML_PAGE_LAYOUT_NAME, sString);
+ }
+
+ // write presentation notes
+ SvXMLElementExport aPSY(*this, XML_NAMESPACE_PRESENTATION, XML_NOTES, true, true);
+
+ // write optional office:forms
+ exportFormsElement( xNotesPage );
+
+ // write shapes per se
+ GetShapeExport()->exportShapes( xNotesPage );
+ }
+ }
+ }
+ exportAnnotations( xMasterPage );
+ }
+ }
+}
+
+void SdXMLExport::exportFormsElement( const Reference< XDrawPage >& xDrawPage )
+{
+ if( !xDrawPage.is() )
+ return;
+
+ Reference< form::XFormsSupplier2 > xFormsSupplier( xDrawPage, UNO_QUERY );
+ if ( xFormsSupplier.is() && xFormsSupplier->hasForms() )
+ {
+ // write masterpage
+ ::xmloff::OOfficeFormsExport aForms(*this);
+ GetFormExport()->exportForms( xDrawPage );
+ }
+
+ if(! GetFormExport()->seekPage( xDrawPage ) )
+ {
+ OSL_FAIL( "OFormLayerXMLExport::seekPage failed!" );
+ }
+}
+
+void SdXMLExport::exportTheme(const uno::Reference<drawing::XDrawPage>& xDrawPage)
+{
+ if ((getSaneDefaultVersion() & SvtSaveOptions::ODFSVER_EXTENDED) == 0)
+ {
+ // Do not export in standard ODF 1.3 or older.
+ return;
+ }
+
+ uno::Reference<beans::XPropertySet> xPropertySet(xDrawPage, uno::UNO_QUERY);
+ if (!xPropertySet.is())
+ return;
+
+ uno::Reference<util::XTheme> xTheme;
+ xPropertySet->getPropertyValue("Theme") >>= xTheme;
+ if (!xTheme.is())
+ return;
+
+ auto* pUnoTheme = dynamic_cast<UnoTheme*>(xTheme.get());
+ if (!pUnoTheme)
+ return;
+
+ auto pTheme = pUnoTheme->getTheme();
+ if (!pTheme)
+ return;
+
+ ExportThemeElement(pTheme);
+}
+
+void SdXMLExport::GetViewSettings(uno::Sequence<beans::PropertyValue>& rProps)
+{
+ Reference< beans::XPropertySet > xPropSet( GetModel(), UNO_QUERY );
+ if( !xPropSet.is() )
+ return;
+
+ awt::Rectangle aVisArea;
+ xPropSet->getPropertyValue("VisibleArea") >>= aVisArea;
+
+ rProps.realloc(4);
+ beans::PropertyValue* pProps = rProps.getArray();
+
+ pProps[0].Name = "VisibleAreaTop";
+ pProps[0].Value <<= aVisArea.Y;
+ pProps[1].Name = "VisibleAreaLeft";
+ pProps[1].Value <<= aVisArea.X;
+ pProps[2].Name = "VisibleAreaWidth";
+ pProps[2].Value <<= aVisArea.Width;
+ pProps[3].Name = "VisibleAreaHeight";
+ pProps[3].Value <<= aVisArea.Height;
+
+}
+
+void SdXMLExport::GetConfigurationSettings(uno::Sequence<beans::PropertyValue>& rProps)
+{
+ Reference< lang::XMultiServiceFactory > xFac( GetModel(), UNO_QUERY );
+ if( !xFac.is() )
+ return;
+
+ Reference< beans::XPropertySet > xProps( xFac->createInstance("com.sun.star.document.Settings"), UNO_QUERY );
+ if( xProps.is() )
+ SvXMLUnitConverter::convertPropertySet( rProps, xProps );
+ DocumentSettingsSerializer *pFilter(dynamic_cast<DocumentSettingsSerializer *>(xProps.get()));
+ if (!pFilter)
+ return;
+ const uno::Reference< embed::XStorage > xStorage(GetTargetStorage());
+ if (!xStorage.is())
+ return;
+ rProps = pFilter->filterStreamsToStorage(xStorage, rProps);
+}
+
+void SdXMLExport::addDataStyle(const sal_Int32 nNumberFormat, bool bTimeFormat )
+{
+ sal_Int32 nFormat = nNumberFormat;
+ if( (nNumberFormat > 1) && (nNumberFormat <= 0x0f) )
+ nFormat -= 2;
+
+ if( bTimeFormat )
+ {
+ maUsedTimeStyles.insert( nFormat );
+ }
+ else
+ {
+ maUsedDateStyles.insert( nFormat );
+ }
+}
+
+void SdXMLExport::exportDataStyles()
+{
+ // there are no data styles to export in draw/impress yet
+}
+
+void SdXMLExport::exportAutoDataStyles()
+{
+ for( const auto& rUsedDateStyle : maUsedDateStyles )
+ SdXMLNumberStylesExporter::exportDateStyle( *this, rUsedDateStyle );
+
+ for( const auto& rUsedTimeStyle : maUsedTimeStyles )
+ SdXMLNumberStylesExporter::exportTimeStyle( *this, rUsedTimeStyle );
+
+ if(HasFormExport())
+ GetFormExport()->exportAutoControlNumberStyles();
+}
+
+OUString SdXMLExport::getDataStyleName(const sal_Int32 nNumberFormat, bool bTimeFormat ) const
+{
+ if( bTimeFormat )
+ {
+ return SdXMLNumberStylesExporter::getTimeStyleName( nNumberFormat );
+ }
+ else
+ {
+ return SdXMLNumberStylesExporter::getDateStyleName( nNumberFormat );
+ }
+}
+
+OUString SdXMLExport::getNavigationOrder( const Reference< XDrawPage >& xDrawPage )
+{
+ OUStringBuffer sNavOrder;
+ try
+ {
+ Reference< XPropertySet > xSet( xDrawPage, UNO_QUERY_THROW );
+ Reference< XIndexAccess > xNavOrder( xSet->getPropertyValue("NavigationOrder"), UNO_QUERY_THROW );
+
+ Reference< XIndexAccess > xZOrderAccess = xDrawPage;
+
+ // only export navigation order if it is different from the z-order
+ if( (xNavOrder.get() != xZOrderAccess.get()) && (xNavOrder->getCount() == xDrawPage->getCount()) )
+ {
+ sal_Int32 nIndex;
+ const sal_Int32 nCount = xNavOrder->getCount();
+ for( nIndex = 0; nIndex < nCount; ++nIndex )
+ {
+ OUString sId( getInterfaceToIdentifierMapper().registerReference( Reference< XInterface >( xNavOrder->getByIndex( nIndex ), UNO_QUERY ) ) );
+ if( !sId.isEmpty() )
+ {
+ if( !sNavOrder.isEmpty() )
+ sNavOrder.append( ' ' );
+ sNavOrder.append( sId );
+ }
+ }
+ }
+ }
+ catch(const Exception&)
+ {
+ }
+ return sNavOrder.makeStringAndClear();
+}
+
+void SdXMLExport::collectAnnotationAutoStyles( const Reference<XDrawPage>& xDrawPage )
+{
+ Reference< XAnnotationAccess > xAnnotationAccess( xDrawPage, UNO_QUERY );
+ if( !xAnnotationAccess.is() ) return;
+
+ try
+ {
+ Reference< XAnnotationEnumeration > xAnnotationEnumeration( xAnnotationAccess->createAnnotationEnumeration() );
+ if( xAnnotationEnumeration.is() )
+ {
+ while( xAnnotationEnumeration->hasMoreElements() )
+ {
+ Reference< XAnnotation > xAnnotation( xAnnotationEnumeration->nextElement(), UNO_SET_THROW );
+ Reference< XText > xText( xAnnotation->getTextRange() );
+ if(xText.is() && !xText->getString().isEmpty())
+ GetTextParagraphExport()->collectTextAutoStyles( xText );
+ }
+ }
+ }
+ catch(const Exception&)
+ {
+ TOOLS_WARN_EXCEPTION("xmloff.draw",
+ "exception caught during export of annotation auto styles");
+ }
+}
+
+void SdXMLExport::exportAnnotations( const Reference<XDrawPage>& xDrawPage )
+{
+ // do not export in standard ODF 1.3 or older
+ if ((getSaneDefaultVersion() & SvtSaveOptions::ODFSVER_EXTENDED) == 0)
+ {
+ return;
+ }
+
+ Reference< XAnnotationAccess > xAnnotationAccess( xDrawPage, UNO_QUERY );
+ if( !xAnnotationAccess.is() )
+ return;
+
+ try
+ {
+ Reference< XAnnotationEnumeration > xAnnotationEnumeration( xAnnotationAccess->createAnnotationEnumeration() );
+ if( xAnnotationEnumeration.is() && xAnnotationEnumeration->hasMoreElements() )
+ {
+ bool bRemovePersonalInfo = SvtSecurityOptions::IsOptionSet(
+ SvtSecurityOptions::EOption::DocWarnRemovePersonalInfo ) && !SvtSecurityOptions::IsOptionSet(
+ SvtSecurityOptions::EOption::DocWarnKeepNoteAuthorDateInfo);
+
+ OUStringBuffer sStringBuffer;
+ do
+ {
+ Reference< XAnnotation > xAnnotation( xAnnotationEnumeration->nextElement(), UNO_SET_THROW );
+
+ RealPoint2D aPosition( xAnnotation->getPosition() );
+
+ GetMM100UnitConverter().convertMeasureToXML(sStringBuffer,
+ static_cast<sal_Int32>( aPosition.X * 100 ) );
+ AddAttribute(XML_NAMESPACE_SVG, XML_X, sStringBuffer.makeStringAndClear());
+
+ GetMM100UnitConverter().convertMeasureToXML(sStringBuffer,
+ static_cast<sal_Int32>( aPosition.Y * 100 ) );
+ AddAttribute(XML_NAMESPACE_SVG, XML_Y, sStringBuffer.makeStringAndClear());
+
+ RealSize2D aSize( xAnnotation->getSize() );
+
+ if( aSize.Width || aSize.Height )
+ {
+ GetMM100UnitConverter().convertMeasureToXML(sStringBuffer,
+ static_cast<sal_Int32>( aSize.Width * 100 ) );
+ AddAttribute(XML_NAMESPACE_SVG, XML_WIDTH, sStringBuffer.makeStringAndClear());
+ GetMM100UnitConverter().convertMeasureToXML(sStringBuffer,
+ static_cast<sal_Int32>( aSize.Height * 100 ) );
+ AddAttribute(XML_NAMESPACE_SVG, XML_HEIGHT, sStringBuffer.makeStringAndClear());
+ }
+
+ // annotation element + content
+ SvXMLElementExport aElem(*this, XML_NAMESPACE_OFFICE_EXT, XML_ANNOTATION, false, true);
+
+ // author
+ OUString aAuthor( xAnnotation->getAuthor() );
+ if( !aAuthor.isEmpty() )
+ {
+ SvXMLElementExport aCreatorElem( *this, XML_NAMESPACE_DC, XML_CREATOR, true, false );
+ Characters( bRemovePersonalInfo
+ ? "Author" + OUString::number( SvXMLExport::GetInfoID(aAuthor) )
+ : aAuthor );
+ }
+
+ // initials
+ OUString aInitials( xAnnotation->getInitials() );
+ if( !aInitials.isEmpty() )
+ {
+ // OFFICE-3776 export meta:creator-initials for ODF 1.3
+ SvXMLElementExport aInitialsElem( *this,
+ (SvtSaveOptions::ODFSVER_013 <= getSaneDefaultVersion())
+ ? XML_NAMESPACE_META
+ : XML_NAMESPACE_LO_EXT,
+ (SvtSaveOptions::ODFSVER_013 <= getSaneDefaultVersion())
+ ? XML_CREATOR_INITIALS
+ : XML_SENDER_INITIALS,
+ true, false );
+ Characters( bRemovePersonalInfo
+ ? OUString::number( SvXMLExport::GetInfoID(aInitials) )
+ : aInitials );
+ }
+
+ {
+ // date time
+ css::util::DateTime aDate( bRemovePersonalInfo
+ ? css::util::DateTime(0, 0, 0, 0, 1, 1, 1970, true) // Epoch time
+ : xAnnotation->getDateTime() );
+ ::sax::Converter::convertDateTime(sStringBuffer, aDate, nullptr, true);
+ SvXMLElementExport aDateElem( *this, XML_NAMESPACE_DC, XML_DATE, true, false );
+ Characters( sStringBuffer.makeStringAndClear() );
+ }
+
+ css::uno::Reference < css::text::XText > xText( xAnnotation->getTextRange() );
+ if( xText.is() )
+ GetTextParagraphExport()->exportText( xText );
+ }
+ while( xAnnotationEnumeration->hasMoreElements() );
+ }
+ }
+ catch(const Exception&)
+ {
+ TOOLS_WARN_EXCEPTION("xmloff.draw", "exception caught during export of annotations");
+ }
+}
+
+extern "C" SAL_DLLPUBLIC_EXPORT uno::XInterface*
+com_sun_star_comp_Impress_XMLOasisExporter_get_implementation(
+ uno::XComponentContext* pCtx, uno::Sequence<uno::Any> const& /*rSeq*/)
+{
+ return cppu::acquire(new SdXMLExport(
+ pCtx, "XMLImpressExportOasis", false,
+ SvXMLExportFlags::OASIS | SvXMLExportFlags::META | SvXMLExportFlags::STYLES
+ | SvXMLExportFlags::MASTERSTYLES | SvXMLExportFlags::AUTOSTYLES
+ | SvXMLExportFlags::CONTENT | SvXMLExportFlags::SCRIPTS | SvXMLExportFlags::SETTINGS
+ | SvXMLExportFlags::FONTDECLS | SvXMLExportFlags::EMBEDDED));
+}
+
+extern "C" SAL_DLLPUBLIC_EXPORT uno::XInterface*
+com_sun_star_comp_Impress_XMLOasisStylesExporter_get_implementation(
+ uno::XComponentContext* pCtx, uno::Sequence<uno::Any> const& /*rSeq*/)
+{
+ return cppu::acquire(new SdXMLExport(
+ pCtx, "XMLImpressStylesExportOasis", false,
+ SvXMLExportFlags::OASIS | SvXMLExportFlags::STYLES | SvXMLExportFlags::MASTERSTYLES
+ | SvXMLExportFlags::AUTOSTYLES | SvXMLExportFlags::FONTDECLS));
+}
+
+extern "C" SAL_DLLPUBLIC_EXPORT uno::XInterface*
+com_sun_star_comp_Impress_XMLOasisContentExporter_get_implementation(
+ uno::XComponentContext* pCtx, uno::Sequence<uno::Any> const& /*rSeq*/)
+{
+ return cppu::acquire(new SdXMLExport(pCtx, "XMLImpressContentExportOasis", false,
+ SvXMLExportFlags::OASIS | SvXMLExportFlags::AUTOSTYLES
+ | SvXMLExportFlags::CONTENT | SvXMLExportFlags::SCRIPTS
+ | SvXMLExportFlags::FONTDECLS));
+}
+
+extern "C" SAL_DLLPUBLIC_EXPORT uno::XInterface*
+com_sun_star_comp_Impress_XMLOasisMetaExporter_get_implementation(
+ uno::XComponentContext* pCtx, uno::Sequence<uno::Any> const& /*rSeq*/)
+{
+ return cppu::acquire(new SdXMLExport(pCtx, "XMLImpressMetaExportOasis", false,
+ SvXMLExportFlags::OASIS | SvXMLExportFlags::META));
+}
+
+extern "C" SAL_DLLPUBLIC_EXPORT uno::XInterface*
+com_sun_star_comp_Impress_XMLOasisSettingsExporter_get_implementation(
+ uno::XComponentContext* pCtx, uno::Sequence<uno::Any> const& /*rSeq*/)
+{
+ return cppu::acquire(new SdXMLExport(pCtx, "XMLImpressSettingsExportOasis", false,
+ SvXMLExportFlags::OASIS | SvXMLExportFlags::SETTINGS));
+}
+
+extern "C" SAL_DLLPUBLIC_EXPORT uno::XInterface*
+com_sun_star_comp_Impress_XMLExporter_get_implementation(uno::XComponentContext* pCtx,
+ uno::Sequence<uno::Any> const& /*rSeq*/)
+{
+ return cppu::acquire(new SdXMLExport(
+ pCtx, "XMLImpressExportOOO", false,
+ SvXMLExportFlags::META | SvXMLExportFlags::STYLES | SvXMLExportFlags::MASTERSTYLES
+ | SvXMLExportFlags::AUTOSTYLES | SvXMLExportFlags::CONTENT | SvXMLExportFlags::SCRIPTS
+ | SvXMLExportFlags::SETTINGS | SvXMLExportFlags::FONTDECLS
+ | SvXMLExportFlags::EMBEDDED));
+}
+
+extern "C" SAL_DLLPUBLIC_EXPORT uno::XInterface*
+com_sun_star_comp_Draw_XMLExporter_get_implementation(uno::XComponentContext* pCtx,
+ uno::Sequence<uno::Any> const& /*rSeq*/)
+{
+ return cppu::acquire(new SdXMLExport(
+ pCtx, "XMLDrawExportOOO", true,
+ SvXMLExportFlags::META | SvXMLExportFlags::STYLES | SvXMLExportFlags::MASTERSTYLES
+ | SvXMLExportFlags::AUTOSTYLES | SvXMLExportFlags::CONTENT | SvXMLExportFlags::SCRIPTS
+ | SvXMLExportFlags::SETTINGS | SvXMLExportFlags::FONTDECLS
+ | SvXMLExportFlags::EMBEDDED));
+}
+
+extern "C" SAL_DLLPUBLIC_EXPORT uno::XInterface*
+com_sun_star_comp_Draw_XMLOasisSettingsExporter_get_implementation(
+ uno::XComponentContext* pCtx, uno::Sequence<uno::Any> const& /*rSeq*/)
+{
+ return cppu::acquire(new SdXMLExport(pCtx, "XMLDrawSettingsExportOasis", true,
+ SvXMLExportFlags::OASIS | SvXMLExportFlags::SETTINGS));
+}
+
+extern "C" SAL_DLLPUBLIC_EXPORT uno::XInterface*
+com_sun_star_comp_Draw_XMLOasisMetaExporter_get_implementation(
+ uno::XComponentContext* pCtx, uno::Sequence<uno::Any> const& /*rSeq*/)
+{
+ return cppu::acquire(new SdXMLExport(pCtx, "XMLDrawMetaExportOasis", true,
+ SvXMLExportFlags::OASIS | SvXMLExportFlags::META));
+}
+
+extern "C" SAL_DLLPUBLIC_EXPORT uno::XInterface*
+com_sun_star_comp_Draw_XMLOasisContentExporter_get_implementation(
+ uno::XComponentContext* pCtx, uno::Sequence<uno::Any> const& /*rSeq*/)
+{
+ return cppu::acquire(new SdXMLExport(pCtx, "XMLDrawContentExportOasis", true,
+ SvXMLExportFlags::OASIS | SvXMLExportFlags::AUTOSTYLES
+ | SvXMLExportFlags::CONTENT | SvXMLExportFlags::SCRIPTS
+ | SvXMLExportFlags::FONTDECLS));
+}
+
+extern "C" SAL_DLLPUBLIC_EXPORT uno::XInterface*
+com_sun_star_comp_Draw_XMLOasisStylesExporter_get_implementation(
+ uno::XComponentContext* pCtx, uno::Sequence<uno::Any> const& /*rSeq*/)
+{
+ return cppu::acquire(new SdXMLExport(
+ pCtx, "XMLDrawStylesExportOasis", true,
+ SvXMLExportFlags::OASIS | SvXMLExportFlags::STYLES | SvXMLExportFlags::MASTERSTYLES
+ | SvXMLExportFlags::AUTOSTYLES | SvXMLExportFlags::FONTDECLS));
+}
+
+extern "C" SAL_DLLPUBLIC_EXPORT uno::XInterface*
+com_sun_star_comp_Draw_XMLOasisExporter_get_implementation(uno::XComponentContext* pCtx,
+ uno::Sequence<uno::Any> const& /*rSeq*/)
+{
+ return cppu::acquire(new SdXMLExport(
+ pCtx, "XMLDrawExportOasis", true,
+ SvXMLExportFlags::OASIS | SvXMLExportFlags::META | SvXMLExportFlags::STYLES
+ | SvXMLExportFlags::MASTERSTYLES | SvXMLExportFlags::AUTOSTYLES
+ | SvXMLExportFlags::CONTENT | SvXMLExportFlags::SCRIPTS | SvXMLExportFlags::SETTINGS
+ | SvXMLExportFlags::FONTDECLS | SvXMLExportFlags::EMBEDDED));
+}
+
+extern "C" SAL_DLLPUBLIC_EXPORT uno::XInterface*
+com_sun_star_comp_DrawingLayer_XMLExporter_get_implementation(
+ uno::XComponentContext* pCtx, uno::Sequence<uno::Any> const& /*rSeq*/)
+{
+ return cppu::acquire(
+ new SdXMLExport(pCtx, "XMLDrawingLayerExport", true,
+ SvXMLExportFlags::OASIS | SvXMLExportFlags::STYLES
+ | SvXMLExportFlags::AUTOSTYLES | SvXMLExportFlags::CONTENT
+ | SvXMLExportFlags::FONTDECLS | SvXMLExportFlags::EMBEDDED));
+}
+
+extern "C" SAL_DLLPUBLIC_EXPORT uno::XInterface*
+com_sun_star_comp_Impress_XMLClipboardExporter_get_implementation(
+ uno::XComponentContext* pCtx, uno::Sequence<uno::Any> const& /*rSeq*/)
+{
+ return cppu::acquire(
+ new SdXMLExport(pCtx, "XMLImpressClipboardExport", /*bIsDraw=*/false,
+ SvXMLExportFlags::OASIS | SvXMLExportFlags::STYLES
+ | SvXMLExportFlags::AUTOSTYLES | SvXMLExportFlags::CONTENT
+ | SvXMLExportFlags::FONTDECLS | SvXMLExportFlags::EMBEDDED));
+}
+
+XMLFontAutoStylePool* SdXMLExport::CreateFontAutoStylePool()
+{
+ bool bEmbedFonts = false;
+ bool bEmbedUsedOnly = false;
+ bool bEmbedLatinScript = true;
+ bool bEmbedAsianScript = true;
+ bool bEmbedComplexScript = true;
+
+ if (getExportFlags() & SvXMLExportFlags::CONTENT)
+ {
+ try
+ {
+ Reference<lang::XMultiServiceFactory> xFactory(GetModel(), UNO_QUERY);
+ Reference<beans::XPropertySet> xProps;
+ Reference<beans::XPropertySetInfo> xInfo;
+
+ if (xFactory.is())
+ xProps.set(xFactory->createInstance("com.sun.star.document.Settings"), UNO_QUERY);
+ if (xProps.is())
+ xInfo = xProps->getPropertySetInfo();
+ if (xInfo.is() && xProps.is())
+ {
+ if (xInfo->hasPropertyByName("EmbedFonts"))
+ xProps->getPropertyValue("EmbedFonts") >>= bEmbedFonts;
+ if (xInfo->hasPropertyByName("EmbedOnlyUsedFonts"))
+ xProps->getPropertyValue("EmbedOnlyUsedFonts") >>= bEmbedUsedOnly;
+ if (xInfo->hasPropertyByName("EmbedLatinScriptFonts"))
+ xProps->getPropertyValue("EmbedLatinScriptFonts") >>= bEmbedLatinScript;
+ if (xInfo->hasPropertyByName("EmbedAsianScriptFonts"))
+ xProps->getPropertyValue("EmbedAsianScriptFonts") >>= bEmbedAsianScript;
+ if (xInfo->hasPropertyByName("EmbedComplexScriptFonts"))
+ xProps->getPropertyValue("EmbedComplexScriptFonts") >>= bEmbedComplexScript;
+ }
+ } catch(...)
+ {
+ // clipboard document doesn't have shell so throws from getPropertyValue
+ // gallery elements may not support com.sun.star.document.Settings so throws from createInstance
+ }
+ }
+
+ XMLFontAutoStylePool *pPool = new XMLFontAutoStylePool( *this, bEmbedFonts );
+ pPool->setEmbedOnlyUsedFonts(bEmbedUsedOnly);
+ pPool->setEmbedFontScripts(bEmbedLatinScript, bEmbedAsianScript, bEmbedComplexScript);
+
+ Reference< beans::XPropertySet > xProps( GetModel(), UNO_QUERY );
+ if ( xProps.is() ) {
+ Sequence<Any> aAnySeq;
+ if( xProps->getPropertyValue("Fonts") >>= aAnySeq )
+ {
+ if( aAnySeq.getLength() % 5 == 0 )
+ {
+ int nLen = aAnySeq.getLength() / 5;
+ int nSeqIndex = 0;
+ for( int i = 0; i < nLen; i++ )
+ {
+ OUString sFamilyName, sStyleName;
+ sal_Int16 eFamily(FAMILY_DONTKNOW),
+ ePitch(PITCH_DONTKNOW),
+ eCharSet(RTL_TEXTENCODING_DONTKNOW);
+
+ aAnySeq[nSeqIndex++] >>= sFamilyName;
+ aAnySeq[nSeqIndex++] >>= sStyleName;
+ aAnySeq[nSeqIndex++] >>= eFamily;
+ aAnySeq[nSeqIndex++] >>= ePitch;
+ aAnySeq[nSeqIndex++] >>= eCharSet;
+
+ pPool->Add( sFamilyName, sStyleName, FontFamily( eFamily ), FontPitch( ePitch ), rtl_TextEncoding( eCharSet ) );
+ }
+ }
+ }
+ }
+
+ return pPool;
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/xmloff/source/draw/sdxmlexp_impl.hxx b/xmloff/source/draw/sdxmlexp_impl.hxx
new file mode 100644
index 0000000000..8207d64e3b
--- /dev/null
+++ b/xmloff/source/draw/sdxmlexp_impl.hxx
@@ -0,0 +1,179 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#pragma once
+
+#include <xmloff/xmlexp.hxx>
+
+#include <com/sun/star/container/XNameAccess.hpp>
+#include <com/sun/star/drawing/XDrawPage.hpp>
+
+#include <o3tl/sorted_vector.hxx>
+#include <vector>
+
+namespace tools { class Rectangle; }
+
+class ImpXMLEXPPageMasterInfo;
+class ImpXMLAutoLayoutInfo;
+class XMLSdPropHdlFactory;
+class XMLShapeExportPropertyMapper;
+class XMLPageExportPropertyMapper;
+
+typedef ::std::vector< ImpXMLEXPPageMasterInfo* > ImpXMLEXPPageMasterList;
+
+enum XmlPlaceholder
+{
+ XmlPlaceholderTitle,
+ XmlPlaceholderOutline,
+ XmlPlaceholderSubtitle,
+ XmlPlaceholderGraphic,
+ XmlPlaceholderObject,
+ XmlPlaceholderChart,
+ XmlPlaceholderTable,
+ XmlPlaceholderPage,
+ XmlPlaceholderNotes,
+ XmlPlaceholderHandout,
+ XmlPlaceholderVerticalTitle,
+ XmlPlaceholderVerticalOutline
+};
+
+typedef o3tl::sorted_vector<sal_Int32> SdXMLFormatMap;
+
+struct HeaderFooterPageSettingsImpl
+{
+ OUString maStrHeaderDeclName;
+ OUString maStrFooterDeclName;
+ OUString maStrDateTimeDeclName;
+};
+
+struct DateTimeDeclImpl
+{
+ OUString maStrText;
+ bool mbFixed;
+ sal_Int32 mnFormat;
+};
+
+class SdXMLExport : public SvXMLExport
+{
+ css::uno::Reference< css::container::XNameAccess > mxDocStyleFamilies;
+ css::uno::Reference< css::container::XIndexAccess > mxDocMasterPages;
+ css::uno::Reference< css::container::XIndexAccess > mxDocDrawPages;
+ sal_Int32 mnDocMasterPageCount;
+ sal_Int32 mnDocDrawPageCount;
+ sal_uInt32 mnObjectCount;
+
+ // temporary infos
+ std::vector< std::unique_ptr<ImpXMLEXPPageMasterInfo> > mvPageMasterInfoList;
+ ImpXMLEXPPageMasterList mvPageMasterUsageList;
+ ImpXMLEXPPageMasterList mvNotesPageMasterUsageList;
+ ImpXMLEXPPageMasterInfo* mpHandoutPageMaster;
+ std::vector< std::unique_ptr<ImpXMLAutoLayoutInfo> > mvAutoLayoutInfoList;
+
+ css::uno::Sequence< OUString > maDrawPagesAutoLayoutNames;
+
+ ::std::vector< OUString > maDrawPagesStyleNames;
+ ::std::vector< OUString > maDrawNotesPagesStyleNames;
+ ::std::vector< OUString > maMasterPagesStyleNames;
+ OUString maHandoutMasterStyleName;
+ ::std::vector< HeaderFooterPageSettingsImpl > maDrawPagesHeaderFooterSettings;
+ ::std::vector< HeaderFooterPageSettingsImpl > maDrawNotesPagesHeaderFooterSettings;
+
+ ::std::vector< OUString > maHeaderDeclsVector;
+ ::std::vector< OUString > maFooterDeclsVector;
+ ::std::vector< DateTimeDeclImpl > maDateTimeDeclsVector;
+
+ HeaderFooterPageSettingsImpl maHandoutPageHeaderFooterSettings;
+
+ rtl::Reference<XMLSdPropHdlFactory> mpSdPropHdlFactory;
+ rtl::Reference<XMLShapeExportPropertyMapper> mpPropertySetMapper;
+ rtl::Reference<XMLPageExportPropertyMapper> mpPresPagePropsMapper;
+
+ SdXMLFormatMap maUsedDateStyles; // this is a vector with the used formattings for date fields
+ SdXMLFormatMap maUsedTimeStyles; // this is a vector with the used formattings for time fields
+
+ bool mbIsDraw;
+
+ virtual void ExportStyles_(bool bUsed) override;
+ virtual void ExportAutoStyles_() override;
+ virtual void ExportFontDecls_() override;
+ virtual void ExportMasterStyles_() override;
+ virtual void ExportContent_() override;
+ virtual void ExportMeta_() override;
+
+ ImpXMLEXPPageMasterInfo* ImpGetOrCreatePageMasterInfo( const css::uno::Reference< css::drawing::XDrawPage >& xMasterPage );
+ void ImpPrepPageMasterInfos();
+ void ImpWritePageMasterInfos();
+ void ImpPrepAutoLayoutInfos();
+ HeaderFooterPageSettingsImpl ImpPrepDrawPageHeaderFooterDecls( const css::uno::Reference< css::drawing::XDrawPage >& xDrawPage );
+ ImpXMLEXPPageMasterInfo* ImpGetPageMasterInfoByName(std::u16string_view rName);
+
+ void ImpPrepDrawPageInfos();
+ void ImpPrepMasterPageInfos();
+ void ImpWritePresentationStyles();
+ OUString ImpCreatePresPageStyleName( const css::uno::Reference<css::drawing::XDrawPage>& xDrawPage, bool bExportBackground = true );
+
+ bool ImpPrepAutoLayoutInfo(const css::uno::Reference< css::drawing::XDrawPage >& xPage, OUString& rName);
+ void ImpWriteAutoLayoutInfos();
+ void ImpWriteAutoLayoutPlaceholder(XmlPlaceholder ePl, const tools::Rectangle& rRect);
+ void ImpWriteHeaderFooterDecls();
+ void ImplExportHeaderFooterDeclAttributes( const HeaderFooterPageSettingsImpl& aSettings );
+
+ void exportFormsElement( const css::uno::Reference< css::drawing::XDrawPage >& xDrawPage );
+ void exportTheme(const css::uno::Reference<css::drawing::XDrawPage>& xDrawPage);
+ void exportPresentationSettings();
+
+ // #82003# helper function for recursive object count
+ sal_uInt32 ImpRecursiveObjectCount( const css::uno::Reference< css::drawing::XShapes >& xShapes);
+
+ OUString getNavigationOrder( const css::uno::Reference< css::drawing::XDrawPage >& xDrawPage );
+
+ void collectAnnotationAutoStyles( const css::uno::Reference< css::drawing::XDrawPage >& xDrawPage );
+ void exportAnnotations( const css::uno::Reference< css::drawing::XDrawPage >& xDrawPage );
+
+protected:
+ virtual void GetViewSettings(css::uno::Sequence<css::beans::PropertyValue>& aProps) override;
+ virtual void GetConfigurationSettings(css::uno::Sequence<css::beans::PropertyValue>& aProps) override;
+ virtual XMLFontAutoStylePool* CreateFontAutoStylePool() override;
+
+public:
+ SdXMLExport(
+ const css::uno::Reference< css::uno::XComponentContext >& xContext,
+ OUString const & implementationName,
+ bool bIsDraw, SvXMLExportFlags nExportFlags );
+ virtual ~SdXMLExport() override;
+
+ void collectAutoStyles() override;
+
+ // XExporter
+ virtual void SAL_CALL setSourceDocument( const css::uno::Reference< css::lang::XComponent >& xDoc ) override;
+
+ // get factories and mappers
+ XMLShapeExportPropertyMapper* GetPropertySetMapper() const { return mpPropertySetMapper.get(); }
+ XMLPageExportPropertyMapper* GetPresPagePropsMapper() const { return mpPresPagePropsMapper.get(); }
+
+ bool IsDraw() const { return mbIsDraw; }
+ bool IsImpress() const { return !mbIsDraw; }
+
+ virtual void addDataStyle(const sal_Int32 nNumberFormat, bool bTimeFormat = false ) override;
+ virtual void exportDataStyles() override;
+ virtual void exportAutoDataStyles() override;
+ virtual OUString getDataStyleName(const sal_Int32 nNumberFormat, bool bTimeFormat = false ) const override;
+};
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/xmloff/source/draw/sdxmlimp.cxx b/xmloff/source/draw/sdxmlimp.cxx
new file mode 100644
index 0000000000..19fd66d5a3
--- /dev/null
+++ b/xmloff/source/draw/sdxmlimp.cxx
@@ -0,0 +1,678 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#include <osl/thread.h>
+#include <sal/log.hxx>
+#include <comphelper/processfactory.hxx>
+#include <comphelper/sequence.hxx>
+
+#include <xmloff/xmlscripti.hxx>
+#include "sdxmlimp_impl.hxx"
+#include "ximpbody.hxx"
+
+#include <xmloff/xmlmetai.hxx>
+#include "ximpstyl.hxx"
+#include <xmloff/xmlnamespace.hxx>
+#include <xmloff/xmltoken.hxx>
+#include <xmloff/DocumentSettingsContext.hxx>
+#include <com/sun/star/awt/Rectangle.hpp>
+#include <com/sun/star/form/XFormsSupplier.hpp>
+#include <com/sun/star/frame/XModel.hpp>
+#include <com/sun/star/lang/XMultiServiceFactory.hpp>
+#include <com/sun/star/style/XStyleFamiliesSupplier.hpp>
+#include <com/sun/star/drawing/XMasterPagesSupplier.hpp>
+#include <com/sun/star/drawing/XDrawPagesSupplier.hpp>
+#include <xmloff/settingsstore.hxx>
+#include <xmloff/ProgressBarHelper.hxx>
+
+#include <xmloff/XMLFontStylesContext.hxx>
+
+#include <com/sun/star/document/XDocumentProperties.hpp>
+#include <com/sun/star/document/XDocumentPropertiesSupplier.hpp>
+
+using namespace ::com::sun::star;
+using namespace ::xmloff::token;
+
+namespace {
+
+class SdXMLBodyContext_Impl : public SvXMLImportContext
+{
+ SdXMLImport& GetSdImport() { return static_cast<SdXMLImport&>(GetImport()); }
+
+public:
+
+ SdXMLBodyContext_Impl( SdXMLImport& rImport );
+
+ virtual css::uno::Reference< css::xml::sax::XFastContextHandler > SAL_CALL createFastChildContext(
+ sal_Int32 nElement, const css::uno::Reference< css::xml::sax::XFastAttributeList >& AttrList ) override;
+};
+
+}
+
+SdXMLBodyContext_Impl::SdXMLBodyContext_Impl( SdXMLImport& rImport ) :
+ SvXMLImportContext( rImport )
+{
+}
+
+css::uno::Reference< css::xml::sax::XFastContextHandler > SdXMLBodyContext_Impl::createFastChildContext(
+ sal_Int32 /*nElement*/,
+ const uno::Reference< xml::sax::XFastAttributeList > & /*xAttrList*/ )
+{
+ return new SdXMLBodyContext(GetSdImport());
+}
+
+namespace {
+
+// NB: virtually inherit so we can multiply inherit properly
+// in SdXMLFlatDocContext_Impl
+class SdXMLDocContext_Impl : public virtual SvXMLImportContext
+{
+protected:
+ SdXMLImport& GetSdImport() { return static_cast<SdXMLImport&>(GetImport()); }
+
+public:
+ SdXMLDocContext_Impl( SdXMLImport& rImport );
+
+ virtual css::uno::Reference< css::xml::sax::XFastContextHandler > SAL_CALL createFastChildContext(
+ sal_Int32 nElement, const css::uno::Reference< css::xml::sax::XFastAttributeList >& xAttrList ) override;
+};
+
+}
+
+SdXMLDocContext_Impl::SdXMLDocContext_Impl(
+ SdXMLImport& rImport )
+: SvXMLImportContext(rImport)
+{
+}
+
+uno::Reference< xml::sax::XFastContextHandler > SAL_CALL SdXMLDocContext_Impl::createFastChildContext(
+ sal_Int32 nElement, const uno::Reference< xml::sax::XFastAttributeList >& /*xAttrList*/ )
+{
+ switch (nElement)
+ {
+ case XML_ELEMENT(OFFICE, XML_SCRIPTS):
+ {
+ if( GetImport().getImportFlags() & SvXMLImportFlags::SCRIPTS )
+ {
+ // office:script inside office:document
+ return new XMLScriptContext( GetSdImport(), GetSdImport().GetModel() );
+ }
+ break;
+ }
+ case XML_ELEMENT(OFFICE, XML_MASTER_STYLES):
+ {
+ if( GetImport().getImportFlags() & SvXMLImportFlags::MASTERSTYLES )
+ {
+ // office:master-styles inside office:document
+ return GetSdImport().CreateMasterStylesContext();
+ }
+ break;
+ }
+ case XML_ELEMENT(OFFICE, XML_BODY):
+ {
+ if( GetImport().getImportFlags() & SvXMLImportFlags::CONTENT )
+ {
+ // office:body inside office:document
+ return new SdXMLBodyContext_Impl(GetSdImport());
+ }
+ break;
+ }
+ case XML_ELEMENT(OFFICE, XML_SETTINGS):
+ {
+ if( GetImport().getImportFlags() & SvXMLImportFlags::SETTINGS )
+ {
+ return new XMLDocumentSettingsContext(GetImport());
+ }
+ break;
+ }
+ case XML_ELEMENT(OFFICE, XML_STYLES):
+ {
+ if( GetImport().getImportFlags() & SvXMLImportFlags::STYLES )
+ {
+ // office:styles inside office:document
+ return GetSdImport().CreateStylesContext();
+ }
+ break;
+ }
+ case XML_ELEMENT(OFFICE, XML_AUTOMATIC_STYLES):
+ {
+ if( GetImport().getImportFlags() & SvXMLImportFlags::AUTOSTYLES )
+ {
+ // office:automatic-styles inside office:document
+ return GetSdImport().CreateAutoStylesContext();
+ }
+ break;
+ }
+ case XML_ELEMENT(OFFICE, XML_FONT_FACE_DECLS):
+ {
+ return GetSdImport().CreateFontDeclsContext();
+ }
+ case XML_ELEMENT(OFFICE, XML_META):
+ {
+ SAL_INFO("xmloff.draw", "XML_ELEMENT(OFFICE, XML_META): should not have come here, maybe document is invalid?");
+ break;
+ }
+ }
+ return nullptr;
+}
+
+namespace {
+
+// context for flat file xml format
+class SdXMLFlatDocContext_Impl
+ : public SdXMLDocContext_Impl, public SvXMLMetaDocumentContext
+{
+public:
+ SdXMLFlatDocContext_Impl( SdXMLImport& i_rImport,
+ const uno::Reference<document::XDocumentProperties>& i_xDocProps );
+
+ virtual css::uno::Reference< css::xml::sax::XFastContextHandler > SAL_CALL createFastChildContext(
+ sal_Int32 nElement, const css::uno::Reference< css::xml::sax::XFastAttributeList >& xAttrList ) override;
+};
+
+}
+
+SdXMLFlatDocContext_Impl::SdXMLFlatDocContext_Impl( SdXMLImport& i_rImport,
+ const uno::Reference<document::XDocumentProperties>& i_xDocProps) :
+ SvXMLImportContext(i_rImport),
+ SdXMLDocContext_Impl(i_rImport),
+ SvXMLMetaDocumentContext(i_rImport, i_xDocProps)
+{
+}
+
+uno::Reference< xml::sax::XFastContextHandler > SAL_CALL SdXMLFlatDocContext_Impl::createFastChildContext(
+ sal_Int32 nElement, const uno::Reference< xml::sax::XFastAttributeList >& xAttrList )
+{
+ // behave like meta base class iff we encounter office:meta
+ if ( nElement == XML_ELEMENT( OFFICE, XML_META ) ) {
+ return SvXMLMetaDocumentContext::createFastChildContext(
+ nElement, xAttrList );
+ } else {
+ return SdXMLDocContext_Impl::createFastChildContext(
+ nElement, xAttrList );
+ }
+}
+
+extern "C" SAL_DLLPUBLIC_EXPORT uno::XInterface*
+com_sun_star_comp_Impress_XMLOasisImporter_get_implementation(
+ uno::XComponentContext* pCtx, uno::Sequence<uno::Any> const& /*rSeq*/)
+{
+ return cppu::acquire(
+ new SdXMLImport(pCtx, "XMLImpressImportOasis", false, SvXMLImportFlags::ALL));
+}
+
+extern "C" SAL_DLLPUBLIC_EXPORT uno::XInterface*
+com_sun_star_comp_Draw_XMLOasisImporter_get_implementation(uno::XComponentContext* pCtx,
+ uno::Sequence<uno::Any> const& /*rSeq*/)
+{
+ return cppu::acquire(new SdXMLImport(pCtx, "XMLDrawImportOasis", true, SvXMLImportFlags::ALL));
+}
+
+extern "C" SAL_DLLPUBLIC_EXPORT uno::XInterface*
+com_sun_star_comp_Draw_XMLOasisStylesImporter_get_implementation(uno::XComponentContext* pCtx,
+ uno::Sequence<uno::Any> const& /*rSeq*/)
+{
+ return cppu::acquire(new SdXMLImport(pCtx, "XMLDrawStylesImportOasis", true,
+ SvXMLImportFlags::STYLES | SvXMLImportFlags::AUTOSTYLES
+ | SvXMLImportFlags::MASTERSTYLES));
+}
+
+extern "C" SAL_DLLPUBLIC_EXPORT uno::XInterface*
+com_sun_star_comp_Draw_XMLOasisContentImporter_get_implementation(
+ uno::XComponentContext* pCtx, uno::Sequence<uno::Any> const& /*rSeq*/)
+{
+ return cppu::acquire(new SdXMLImport(pCtx, "XMLDrawContentImportOasis", true,
+ SvXMLImportFlags::AUTOSTYLES | SvXMLImportFlags::CONTENT
+ | SvXMLImportFlags::SCRIPTS
+ | SvXMLImportFlags::FONTDECLS));
+}
+
+extern "C" SAL_DLLPUBLIC_EXPORT uno::XInterface*
+com_sun_star_comp_Draw_XMLOasisMetaImporter_get_implementation(
+ uno::XComponentContext* pCtx, uno::Sequence<uno::Any> const& /*rSeq*/)
+{
+ return cppu::acquire(
+ new SdXMLImport(pCtx, "XMLDrawMetaImportOasis", true, SvXMLImportFlags::META));
+}
+
+extern "C" SAL_DLLPUBLIC_EXPORT uno::XInterface*
+com_sun_star_comp_Draw_XMLOasisSettingsImporter_get_implementation(
+ uno::XComponentContext* pCtx, uno::Sequence<uno::Any> const& /*rSeq*/)
+{
+ return cppu::acquire(
+ new SdXMLImport(pCtx, "XMLDrawSettingsImportOasis", true, SvXMLImportFlags::SETTINGS));
+}
+
+extern "C" SAL_DLLPUBLIC_EXPORT uno::XInterface*
+com_sun_star_comp_Impress_XMLOasisStylesImporter_get_implementation(
+ uno::XComponentContext* pCtx, uno::Sequence<uno::Any> const& /*rSeq*/)
+{
+ return cppu::acquire(new SdXMLImport(pCtx, "XMLImpressStylesImportOasis", false,
+ SvXMLImportFlags::STYLES | SvXMLImportFlags::AUTOSTYLES
+ | SvXMLImportFlags::MASTERSTYLES));
+}
+
+extern "C" SAL_DLLPUBLIC_EXPORT uno::XInterface*
+com_sun_star_comp_Impress_XMLOasisContentImporter_get_implementation(
+ uno::XComponentContext* pCtx, uno::Sequence<uno::Any> const& /*rSeq*/)
+{
+ return cppu::acquire(new SdXMLImport(pCtx, "XMLImpressContentImportOasis", false,
+ SvXMLImportFlags::AUTOSTYLES | SvXMLImportFlags::CONTENT
+ | SvXMLImportFlags::SCRIPTS
+ | SvXMLImportFlags::FONTDECLS));
+}
+
+extern "C" SAL_DLLPUBLIC_EXPORT uno::XInterface*
+com_sun_star_comp_Impress_XMLOasisMetaImporter_get_implementation(
+ uno::XComponentContext* pCtx, uno::Sequence<uno::Any> const& /*rSeq*/)
+{
+ return cppu::acquire(
+ new SdXMLImport(pCtx, "XMLImpressMetaImportOasis", false, SvXMLImportFlags::META));
+}
+
+extern "C" SAL_DLLPUBLIC_EXPORT uno::XInterface*
+com_sun_star_comp_Impress_XMLOasisSettingsImporter_get_implementation(
+ uno::XComponentContext* pCtx, uno::Sequence<uno::Any> const& /*rSeq*/)
+{
+ return cppu::acquire(
+ new SdXMLImport(pCtx, "XMLImpressSettingsImportOasis", false, SvXMLImportFlags::SETTINGS));
+}
+
+SdXMLImport::SdXMLImport(
+ const css::uno::Reference< css::uno::XComponentContext >& xContext,
+ OUString const & implementationName,
+ bool bIsDraw, SvXMLImportFlags nImportFlags )
+: SvXMLImport( xContext, implementationName, nImportFlags ),
+ mnNewPageCount(0),
+ mnNewMasterPageCount(0),
+ mbIsDraw(bIsDraw),
+ mbLoadDoc(true),
+ mbPreview(false)
+{
+ // add namespaces
+ GetNamespaceMap().Add(
+ GetXMLToken(XML_NP_PRESENTATION),
+ GetXMLToken(XML_N_PRESENTATION),
+ XML_NAMESPACE_PRESENTATION);
+
+ GetNamespaceMap().Add(
+ GetXMLToken(XML_NP_SMIL),
+ GetXMLToken(XML_N_SMIL_COMPAT),
+ XML_NAMESPACE_SMIL);
+}
+
+// XImporter
+void SAL_CALL SdXMLImport::setTargetDocument( const uno::Reference< lang::XComponent >& xDoc )
+{
+ SvXMLImport::setTargetDocument( xDoc );
+
+ uno::Reference< lang::XServiceInfo > xDocServices( GetModel(), uno::UNO_QUERY );
+ if( !xDocServices.is() )
+ throw lang::IllegalArgumentException();
+
+ mbIsDraw = !xDocServices->supportsService("com.sun.star.presentation.PresentationDocument");
+
+ // prepare access to styles
+ uno::Reference< style::XStyleFamiliesSupplier > xFamSup( GetModel(), uno::UNO_QUERY );
+ if(xFamSup.is())
+ mxDocStyleFamilies = xFamSup->getStyleFamilies();
+
+ if (!mbLoadDoc)
+ return;
+
+ // prepare access to master pages
+ uno::Reference < drawing::XMasterPagesSupplier > xMasterPagesSupplier(GetModel(), uno::UNO_QUERY);
+ if(xMasterPagesSupplier.is())
+ mxDocMasterPages = xMasterPagesSupplier->getMasterPages();
+
+ // prepare access to draw pages
+ uno::Reference <drawing::XDrawPagesSupplier> xDrawPagesSupplier(GetModel(), uno::UNO_QUERY);
+ if(!xDrawPagesSupplier.is())
+ throw lang::IllegalArgumentException();
+
+ mxDocDrawPages = xDrawPagesSupplier->getDrawPages();
+ if(!mxDocDrawPages.is())
+ throw lang::IllegalArgumentException();
+
+ if( mxDocDrawPages.is() && mxDocDrawPages->getCount() > 0 )
+ {
+ uno::Reference< form::XFormsSupplier > xFormsSupp;
+ mxDocDrawPages->getByIndex(0) >>= xFormsSupp;
+ mbIsFormsSupported = xFormsSupp.is();
+ }
+
+ // #88546# enable progress bar increments, SdXMLImport is only used for
+ // draw/impress import
+ GetShapeImport()->enableHandleProgressBar();
+
+ uno::Reference< lang::XMultiServiceFactory > xFac( GetModel(), uno::UNO_QUERY );
+ if( xFac.is() )
+ {
+ uno::Sequence< OUString > sSNS( xFac->getAvailableServiceNames() );
+ if (comphelper::findValue(sSNS, "com.sun.star.drawing.TableShape") != -1)
+ mbIsTableShapeSupported = true;
+ }
+}
+
+// XInitialization
+void SAL_CALL SdXMLImport::initialize( const uno::Sequence< uno::Any >& aArguments )
+{
+ SvXMLImport::initialize( aArguments );
+
+ static constexpr OUString sOrganizerMode(u"OrganizerMode"_ustr);
+ bool bStyleOnly(false);
+
+ css::beans::PropertyValue aPropValue;
+ if (aArguments.hasElements() && (aArguments[0] >>= aPropValue) && aPropValue.Name == sOrganizerMode)
+ {
+ aPropValue.Value >>= bStyleOnly;
+ mbLoadDoc = !bStyleOnly;
+ }
+
+ uno::Reference< beans::XPropertySet > xInfoSet( getImportInfo() );
+ if( !xInfoSet.is() )
+ return;
+
+ uno::Reference< beans::XPropertySetInfo > xInfoSetInfo( xInfoSet->getPropertySetInfo() );
+
+ if( xInfoSetInfo->hasPropertyByName( gsPageLayouts ) )
+ xInfoSet->getPropertyValue( gsPageLayouts ) >>= mxPageLayouts;
+
+ if( xInfoSetInfo->hasPropertyByName( gsPreview ) )
+ xInfoSet->getPropertyValue( gsPreview ) >>= mbPreview;
+
+ if (xInfoSetInfo->hasPropertyByName(sOrganizerMode))
+ {
+ if (xInfoSet->getPropertyValue(sOrganizerMode) >>= bStyleOnly)
+ {
+ mbLoadDoc = !bStyleOnly;
+ }
+ }
+}
+
+SvXMLImportContext *SdXMLImport::CreateFastContext( sal_Int32 nElement,
+ const uno::Reference< xml::sax::XFastAttributeList >& xAttrList )
+{
+ SvXMLImportContext* pContext = nullptr;
+
+ switch (nElement)
+ {
+ case XML_ELEMENT( OFFICE, XML_DOCUMENT_STYLES ):
+ case XML_ELEMENT( OFFICE, XML_DOCUMENT_CONTENT ):
+ case XML_ELEMENT( OFFICE, XML_DOCUMENT_SETTINGS ):
+ pContext = new SdXMLDocContext_Impl(*this);
+ break;
+ case XML_ELEMENT( OFFICE, XML_DOCUMENT_META ):
+ pContext = CreateMetaContext(nElement, xAttrList);
+ break;
+ case XML_ELEMENT( OFFICE, XML_DOCUMENT ):
+ {
+ uno::Reference<document::XDocumentPropertiesSupplier> xDPS(
+ GetModel(), uno::UNO_QUERY_THROW);
+ // flat OpenDocument file format
+ pContext = new SdXMLFlatDocContext_Impl( *this, xDPS->getDocumentProperties());
+ }
+ break;
+ case XML_ELEMENT( OFFICE, XML_STYLES ):
+ // internal xml file for built in styles
+ if (!mbLoadDoc)
+ pContext = CreateStylesContext();
+ break;
+ }
+ return pContext;
+}
+
+SvXMLImportContext *SdXMLImport::CreateMetaContext(const sal_Int32 /*nElement*/,
+ const uno::Reference<xml::sax::XFastAttributeList>&)
+{
+ SvXMLImportContext* pContext = nullptr;
+
+ if (getImportFlags() & SvXMLImportFlags::META)
+ {
+ uno::Reference<document::XDocumentPropertiesSupplier> xDPS(
+ GetModel(), uno::UNO_QUERY_THROW);
+ uno::Reference<document::XDocumentProperties> const xDocProps(
+ !mbLoadDoc ? nullptr : xDPS->getDocumentProperties());
+ pContext = new SvXMLMetaDocumentContext(*this, xDocProps);
+ }
+
+ return pContext;
+}
+
+SvXMLStylesContext *SdXMLImport::CreateStylesContext()
+{
+ if(GetShapeImport()->GetStylesContext())
+ return GetShapeImport()->GetStylesContext();
+
+ GetShapeImport()->SetStylesContext(new SdXMLStylesContext(
+ *this, false));
+
+ return GetShapeImport()->GetStylesContext();
+}
+
+SvXMLStylesContext *SdXMLImport::CreateAutoStylesContext()
+{
+ if(GetShapeImport()->GetAutoStylesContext())
+ return GetShapeImport()->GetAutoStylesContext();
+
+ GetShapeImport()->SetAutoStylesContext(new SdXMLStylesContext(
+ *this, true));
+
+ return GetShapeImport()->GetAutoStylesContext();
+}
+
+SvXMLImportContext* SdXMLImport::CreateMasterStylesContext()
+{
+ if (!mxMasterStylesContext.is())
+ mxMasterStylesContext.set(new SdXMLMasterStylesContext(*this));
+ return mxMasterStylesContext.get();
+}
+
+SvXMLImportContext *SdXMLImport::CreateFontDeclsContext()
+{
+ XMLFontStylesContext *pFSContext =
+ new XMLFontStylesContext( *this, osl_getThreadTextEncoding() );
+ SetFontDecls( pFSContext );
+ return pFSContext;
+}
+
+void SdXMLImport::SetViewSettings(const css::uno::Sequence<css::beans::PropertyValue>& aViewProps)
+{
+ uno::Reference< beans::XPropertySet > xPropSet( GetModel(), uno::UNO_QUERY );
+ if( !xPropSet.is() )
+ return;
+
+ awt::Rectangle aVisArea( 0,0, 28000, 21000 );
+
+ for( const auto& rViewProp : aViewProps )
+ {
+ const OUString& rName = rViewProp.Name;
+ const uno::Any rValue = rViewProp.Value;
+
+ if ( rName == "VisibleAreaTop" )
+ {
+ rValue >>= aVisArea.Y;
+ }
+ else if ( rName == "VisibleAreaLeft" )
+ {
+ rValue >>= aVisArea.X;
+ }
+ else if ( rName == "VisibleAreaWidth" )
+ {
+ rValue >>= aVisArea.Width;
+ }
+ else if ( rName == "VisibleAreaHeight" )
+ {
+ rValue >>= aVisArea.Height;
+ }
+ }
+
+ try
+ {
+ xPropSet->setPropertyValue("VisibleArea", uno::Any( aVisArea ) );
+ }
+ catch(const css::uno::Exception&)
+ {
+/* #i79978# since old documents may contain invalid view settings, this is nothing to worry the user about.
+ SetError( XMLERROR_FLAG_WARNING | XMLERROR_API, {}, e.Message, NULL );
+*/
+ }
+}
+
+void SdXMLImport::SetConfigurationSettings(const css::uno::Sequence<css::beans::PropertyValue>& aConfigProps)
+{
+ uno::Reference< lang::XMultiServiceFactory > xFac( GetModel(), uno::UNO_QUERY );
+ if( !xFac.is() )
+ return;
+
+ uno::Reference< beans::XPropertySet > xProps( xFac->createInstance("com.sun.star.document.Settings"), uno::UNO_QUERY );
+ if( !xProps.is() )
+ return;
+
+ uno::Reference< beans::XPropertySetInfo > xInfo( xProps->getPropertySetInfo() );
+ if( !xInfo.is() )
+ return;
+
+ const uno::Sequence<beans::PropertyValue>* pValues = &aConfigProps;
+
+ DocumentSettingsSerializer *pFilter;
+ pFilter = dynamic_cast<DocumentSettingsSerializer *>(xProps.get());
+ uno::Sequence<beans::PropertyValue> aFiltered;
+ if( pFilter )
+ {
+ aFiltered = pFilter->filterStreamsFromStorage( GetDocumentBase(), GetSourceStorage(), aConfigProps );
+ pValues = &aFiltered;
+ }
+
+ for( const auto& rValue : *pValues )
+ {
+ try
+ {
+ const OUString& rProperty = rValue.Name;
+ if( xInfo->hasPropertyByName( rProperty ) )
+ xProps->setPropertyValue( rProperty, rValue.Value );
+ }
+ catch(const uno::Exception&)
+ {
+ SAL_INFO("xmloff.draw", "#SdXMLImport::SetConfigurationSettings: Exception!" );
+ }
+ }
+}
+
+// #80365# override this method to read and use the hint value from the
+// written meta information. If no info is found, guess 10 draw objects
+//void SdXMLImport::SetStatisticAttributes(const uno::Reference<xml::sax::XAttributeList>& xAttrList)
+void SdXMLImport::SetStatistics(
+ const uno::Sequence<beans::NamedValue> & i_rStats)
+{
+ static const char* s_stats[] =
+ { "ObjectCount", nullptr };
+
+ SvXMLImport::SetStatistics(i_rStats);
+
+ sal_uInt32 nCount(10);
+ for (const auto& rStat : i_rStats) {
+ for (const char** pStat = s_stats; *pStat != nullptr; ++pStat) {
+ if (rStat.Name.equalsAscii(*pStat)) {
+ sal_Int32 val = 0;
+ if (rStat.Value >>= val) {
+ nCount = val;
+ } else {
+ SAL_WARN("xmloff.draw", "SdXMLImport::SetStatistics: invalid entry");
+ }
+ }
+ }
+ }
+
+ if(nCount)
+ {
+ GetProgressBarHelper()->SetReference(nCount);
+ GetProgressBarHelper()->SetValue(0);
+ }
+}
+
+void SdXMLImport::AddHeaderDecl( const OUString& rName, const OUString& rText )
+{
+ if( !rName.isEmpty() && !rText.isEmpty() )
+ maHeaderDeclsMap[rName] = rText;
+}
+
+void SdXMLImport::AddFooterDecl( const OUString& rName, const OUString& rText )
+{
+ if( !rName.isEmpty() && !rText.isEmpty() )
+ maFooterDeclsMap[rName] = rText;
+}
+
+void SdXMLImport::AddDateTimeDecl( const OUString& rName, const OUString& rText, bool bFixed, const OUString& rDateTimeFormat )
+{
+ if( !rName.isEmpty() && (!rText.isEmpty() || !bFixed) )
+ {
+ DateTimeDeclContextImpl aDecl;
+ aDecl.maStrText = rText;
+ aDecl.mbFixed = bFixed;
+ aDecl.maStrDateTimeFormat = rDateTimeFormat;
+ maDateTimeDeclsMap[rName] = aDecl;
+ }
+}
+
+OUString SdXMLImport::GetHeaderDecl( const OUString& rName ) const
+{
+ OUString aRet;
+ HeaderFooterDeclMap::const_iterator aIter( maHeaderDeclsMap.find( rName ) );
+ if( aIter != maHeaderDeclsMap.end() )
+ aRet = (*aIter).second;
+
+ return aRet;
+}
+
+OUString SdXMLImport::GetFooterDecl( const OUString& rName ) const
+{
+ OUString aRet;
+ HeaderFooterDeclMap::const_iterator aIter( maFooterDeclsMap.find( rName ) );
+ if( aIter != maFooterDeclsMap.end() )
+ aRet = (*aIter).second;
+
+ return aRet;
+}
+
+OUString SdXMLImport::GetDateTimeDecl( const OUString& rName, bool& rbFixed, OUString& rDateTimeFormat )
+{
+ DateTimeDeclContextImpl aDecl;
+
+ DateTimeDeclMap::const_iterator aIter( maDateTimeDeclsMap.find( rName ) );
+ if( aIter != maDateTimeDeclsMap.end() )
+ aDecl = (*aIter).second;
+
+ rbFixed = aDecl.mbFixed;
+ rDateTimeFormat = aDecl.maStrDateTimeFormat;
+ return aDecl.maStrText;
+}
+
+void SdXMLImport::NotifyContainsEmbeddedFont()
+{
+ uno::Reference< lang::XMultiServiceFactory > xFac( GetModel(), uno::UNO_QUERY );
+ if( xFac.is() )
+ {
+ uno::Reference< beans::XPropertySet > xProps( xFac->createInstance("com.sun.star.document.Settings"), uno::UNO_QUERY );
+ if( xProps.is() )
+ xProps->setPropertyValue("EmbedFonts", uno::Any( true ) );
+ }
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/xmloff/source/draw/sdxmlimp_impl.hxx b/xmloff/source/draw/sdxmlimp_impl.hxx
new file mode 100644
index 0000000000..60641601a9
--- /dev/null
+++ b/xmloff/source/draw/sdxmlimp_impl.hxx
@@ -0,0 +1,135 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#pragma once
+
+#include <com/sun/star/drawing/XDrawPage.hpp>
+#include <com/sun/star/task/XStatusIndicator.hpp>
+#include <xmloff/xmltkmap.hxx>
+#include <com/sun/star/container/XNameAccess.hpp>
+
+#include <map>
+#include <memory>
+#include <vector>
+#include <xmloff/xmlimp.hxx>
+
+class SvXMLUnitConverter;
+class SvXMLTokenMap;
+class SdXMLMasterStylesContext;
+
+struct DateTimeDeclContextImpl
+{
+ OUString maStrText;
+ bool mbFixed;
+ OUString maStrDateTimeFormat;
+
+ DateTimeDeclContextImpl() : mbFixed(true) {}
+};
+
+typedef std::map<OUString, OUString> HeaderFooterDeclMap;
+typedef std::map<OUString, DateTimeDeclContextImpl> DateTimeDeclMap;
+
+class SdXMLImport: public SvXMLImport
+{
+ css::uno::Reference< css::container::XNameAccess > mxDocStyleFamilies;
+ css::uno::Reference< css::container::XIndexAccess > mxDocMasterPages;
+ css::uno::Reference< css::container::XIndexAccess > mxDocDrawPages;
+ css::uno::Reference< css::container::XNameAccess > mxPageLayouts;
+
+ // contexts for Style and AutoStyle import
+ rtl::Reference<SdXMLMasterStylesContext> mxMasterStylesContext;
+
+ sal_Int32 mnNewPageCount;
+ sal_Int32 mnNewMasterPageCount;
+
+ bool mbIsDraw;
+ bool mbLoadDoc;
+ bool mbPreview;
+
+ static constexpr OUString gsPageLayouts = u"PageLayouts"_ustr;
+ static constexpr OUString gsPreview = u"Preview"_ustr;
+
+ HeaderFooterDeclMap maHeaderDeclsMap;
+ HeaderFooterDeclMap maFooterDeclsMap;
+ DateTimeDeclMap maDateTimeDeclsMap;
+
+protected:
+
+ // This method is called after the namespace map has been updated, but
+ // before a context for the current element has been pushed.
+ virtual SvXMLImportContext *CreateFastContext( sal_Int32 nElement,
+ const ::css::uno::Reference< ::css::xml::sax::XFastAttributeList >& xAttrList ) override;
+
+public:
+ SdXMLImport(
+ const css::uno::Reference< css::uno::XComponentContext >& xContext,
+ OUString const & implementationName,
+ bool bIsDraw, SvXMLImportFlags nImportFlags );
+
+ // XImporter
+ virtual void SAL_CALL setTargetDocument( const css::uno::Reference< css::lang::XComponent >& xDoc ) override;
+
+ // XInitialization
+ virtual void SAL_CALL initialize( const css::uno::Sequence< css::uno::Any >& aArguments ) override;
+
+ virtual void SetViewSettings(const css::uno::Sequence<css::beans::PropertyValue>& aViewProps) override;
+ virtual void SetConfigurationSettings(const css::uno::Sequence<css::beans::PropertyValue>& aConfigProps) override;
+
+ // namespace office
+ // NB: in contrast to other CreateFooContexts, this particular one handles
+ // the root element (i.e. office:document-meta)
+ SvXMLImportContext* CreateMetaContext(const sal_Int32 nElement,
+ const css::uno::Reference< css::xml::sax::XFastAttributeList >& xAttrList);
+ SvXMLStylesContext* CreateStylesContext();
+ SvXMLStylesContext* CreateAutoStylesContext();
+ SvXMLImportContext* CreateMasterStylesContext();
+ SvXMLImportContext *CreateFontDeclsContext();
+
+ // export local parameters concerning page access and similar
+ const css::uno::Reference< css::container::XNameAccess >& GetLocalDocStyleFamilies() const { return mxDocStyleFamilies; }
+ const css::uno::Reference< css::container::XIndexAccess >& GetLocalMasterPages() const { return mxDocMasterPages; }
+ const css::uno::Reference< css::container::XIndexAccess >& GetLocalDrawPages() const { return mxDocDrawPages; }
+
+ sal_Int32 GetNewPageCount() const { return mnNewPageCount; }
+ void IncrementNewPageCount() { mnNewPageCount++; }
+ sal_Int32 GetNewMasterPageCount() const { return mnNewMasterPageCount; }
+ void IncrementNewMasterPageCount() { mnNewMasterPageCount++; }
+
+ const css::uno::Reference< css::container::XNameAccess >& getPageLayouts() const { return mxPageLayouts; }
+
+ bool IsDraw() const { return mbIsDraw; }
+ bool IsImpress() const { return !mbIsDraw; }
+
+ virtual void SetStatistics(
+ const css::uno::Sequence< css::beans::NamedValue> & i_rStats) override;
+
+ bool IsPreview() const { return mbPreview; }
+
+ void AddHeaderDecl( const OUString& rName, const OUString& rText );
+ void AddFooterDecl( const OUString& rName, const OUString& rText );
+ void AddDateTimeDecl( const OUString& rName, const OUString& rText, bool bFixed, const OUString& rDateTimeFormat );
+
+ OUString GetHeaderDecl( const OUString& rName ) const;
+ OUString GetFooterDecl( const OUString& rName ) const;
+ OUString GetDateTimeDecl( const OUString& rName, bool& rbFixed, OUString& rDateTimeFormat );
+
+ virtual void NotifyContainsEmbeddedFont() override;
+};
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/xmloff/source/draw/shapeexport.cxx b/xmloff/source/draw/shapeexport.cxx
new file mode 100644
index 0000000000..cbb0278297
--- /dev/null
+++ b/xmloff/source/draw/shapeexport.cxx
@@ -0,0 +1,5183 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#include <config_wasm_strip.h>
+
+#include <basegfx/matrix/b2dhommatrix.hxx>
+#include <basegfx/matrix/b3dhommatrix.hxx>
+#include <basegfx/polygon/b2dpolypolygon.hxx>
+#include <basegfx/polygon/b2dpolypolygontools.hxx>
+#include <basegfx/polygon/b2dpolygontools.hxx>
+#include <basegfx/polygon/b3dpolypolygon.hxx>
+#include <basegfx/polygon/b3dpolypolygontools.hxx>
+#include <basegfx/tuple/b2dtuple.hxx>
+#include <basegfx/vector/b3dvector.hxx>
+
+#include <com/sun/star/beans/XPropertyState.hpp>
+#include <com/sun/star/beans/PropertyValues.hpp>
+#include <com/sun/star/container/XChild.hpp>
+#include <com/sun/star/container/XEnumerationAccess.hpp>
+#include <com/sun/star/container/XIdentifierAccess.hpp>
+#include <com/sun/star/container/XNamed.hpp>
+#include <com/sun/star/document/XEventsSupplier.hpp>
+#include <com/sun/star/drawing/Alignment.hpp>
+#include <com/sun/star/drawing/CameraGeometry.hpp>
+#include <com/sun/star/drawing/CircleKind.hpp>
+#include <com/sun/star/drawing/ConnectorType.hpp>
+#include <com/sun/star/drawing/Direction3D.hpp>
+#include <com/sun/star/drawing/EscapeDirection.hpp>
+#include <com/sun/star/drawing/EnhancedCustomShapeAdjustmentValue.hpp>
+#include <com/sun/star/drawing/EnhancedCustomShapeGluePointType.hpp>
+#include <com/sun/star/drawing/EnhancedCustomShapeParameterPair.hpp>
+#include <com/sun/star/drawing/EnhancedCustomShapeParameterType.hpp>
+#include <com/sun/star/drawing/EnhancedCustomShapeMetalType.hpp>
+#include <com/sun/star/drawing/EnhancedCustomShapeSegment.hpp>
+#include <com/sun/star/drawing/EnhancedCustomShapeSegmentCommand.hpp>
+#include <com/sun/star/drawing/EnhancedCustomShapeTextFrame.hpp>
+#include <com/sun/star/drawing/EnhancedCustomShapeTextPathMode.hpp>
+#include <com/sun/star/drawing/GluePoint2.hpp>
+#include <com/sun/star/drawing/HomogenMatrix.hpp>
+#include <com/sun/star/drawing/HomogenMatrix3.hpp>
+#include <com/sun/star/drawing/PolyPolygonBezierCoords.hpp>
+#include <com/sun/star/drawing/PolyPolygonShape3D.hpp>
+#include <com/sun/star/drawing/Position3D.hpp>
+#include <com/sun/star/drawing/ProjectionMode.hpp>
+#include <com/sun/star/drawing/ShadeMode.hpp>
+#include <com/sun/star/drawing/XControlShape.hpp>
+#include <com/sun/star/drawing/XCustomShapeEngine.hpp>
+#include <com/sun/star/drawing/XGluePointsSupplier.hpp>
+#include <com/sun/star/drawing/BarCode.hpp>
+#include <com/sun/star/drawing/BarCodeErrorCorrection.hpp>
+#include <com/sun/star/drawing/XShapes3.hpp>
+#include <com/sun/star/embed/ElementModes.hpp>
+#include <com/sun/star/embed/XStorage.hpp>
+#include <com/sun/star/embed/XTransactedObject.hpp>
+#include <com/sun/star/graphic/XGraphic.hpp>
+#include <com/sun/star/graphic/GraphicProvider.hpp>
+#include <com/sun/star/graphic/XGraphicProvider.hpp>
+#include <com/sun/star/io/XSeekableInputStream.hpp>
+#include <com/sun/star/io/XStream.hpp>
+#include <com/sun/star/lang/ServiceNotRegisteredException.hpp>
+#include <com/sun/star/lang/XMultiServiceFactory.hpp>
+#include <com/sun/star/media/ZoomLevel.hpp>
+#include <com/sun/star/presentation/AnimationSpeed.hpp>
+#include <com/sun/star/presentation/ClickAction.hpp>
+#include <com/sun/star/style/XStyle.hpp>
+#include <com/sun/star/table/XColumnRowRange.hpp>
+#include <com/sun/star/text/WritingMode2.hpp>
+#include <com/sun/star/text/XText.hpp>
+
+#include <comphelper/classids.hxx>
+#include <comphelper/processfactory.hxx>
+#include <comphelper/propertyvalue.hxx>
+#include <comphelper/storagehelper.hxx>
+#include <officecfg/Office/Common.hxx>
+
+#include <o3tl/any.hxx>
+#include <o3tl/typed_flags_set.hxx>
+#include <o3tl/string_view.hxx>
+
+#include <rtl/math.hxx>
+#include <rtl/ustrbuf.hxx>
+#include <rtl/ustring.hxx>
+#include <sal/log.hxx>
+
+#include <sax/tools/converter.hxx>
+
+#include <tools/debug.hxx>
+#include <tools/globname.hxx>
+#include <tools/helpers.hxx>
+#include <comphelper/diagnose_ex.hxx>
+#include <vcl/graph.hxx>
+
+#include <xmloff/contextid.hxx>
+#include <xmloff/families.hxx>
+#include <xmloff/namespacemap.hxx>
+#include <xmloff/shapeexport.hxx>
+#include <xmloff/unointerfacetouniqueidentifiermapper.hxx>
+#include <xmloff/xmlexp.hxx>
+#include <xmloff/xmlnamespace.hxx>
+#include <xmloff/xmltoken.hxx>
+#include <xmloff/xmluconv.hxx>
+#include <xmloff/table/XMLTableExport.hxx>
+#include <xmloff/ProgressBarHelper.hxx>
+
+#include <anim.hxx>
+#include <EnhancedCustomShapeToken.hxx>
+#include "sdpropls.hxx"
+#include <xexptran.hxx>
+#include "ximpshap.hxx"
+#include <XMLBase64Export.hxx>
+#include <XMLImageMapExport.hxx>
+#include <memory>
+
+using namespace ::com::sun::star;
+using namespace ::xmloff::EnhancedCustomShapeToken;
+using namespace ::xmloff::token;
+
+constexpr OUStringLiteral XML_EMBEDDEDOBJECTGRAPHIC_URL_BASE = u"vnd.sun.star.GraphicObject:";
+
+namespace {
+
+bool supportsText(XmlShapeType eShapeType)
+{
+ return eShapeType != XmlShapeType::PresChartShape &&
+ eShapeType != XmlShapeType::PresOLE2Shape &&
+ eShapeType != XmlShapeType::DrawSheetShape &&
+ eShapeType != XmlShapeType::PresSheetShape &&
+ eShapeType != XmlShapeType::Draw3DSceneObject &&
+ eShapeType != XmlShapeType::Draw3DCubeObject &&
+ eShapeType != XmlShapeType::Draw3DSphereObject &&
+ eShapeType != XmlShapeType::Draw3DLatheObject &&
+ eShapeType != XmlShapeType::Draw3DExtrudeObject &&
+ eShapeType != XmlShapeType::DrawPageShape &&
+ eShapeType != XmlShapeType::PresPageShape &&
+ eShapeType != XmlShapeType::DrawGroupShape;
+
+}
+
+}
+
+constexpr OUString gsZIndex( u"ZOrder"_ustr );
+constexpr OUStringLiteral gsPrintable( u"Printable" );
+constexpr OUStringLiteral gsVisible( u"Visible" );
+constexpr OUString gsModel( u"Model"_ustr );
+constexpr OUStringLiteral gsStartShape( u"StartShape" );
+constexpr OUStringLiteral gsEndShape( u"EndShape" );
+constexpr OUString gsOnClick( u"OnClick"_ustr );
+constexpr OUStringLiteral gsEventType( u"EventType" );
+constexpr OUStringLiteral gsPresentation( u"Presentation" );
+constexpr OUStringLiteral gsMacroName( u"MacroName" );
+constexpr OUString gsScript( u"Script"_ustr );
+constexpr OUStringLiteral gsLibrary( u"Library" );
+constexpr OUStringLiteral gsClickAction( u"ClickAction" );
+constexpr OUString gsBookmark( u"Bookmark"_ustr );
+constexpr OUStringLiteral gsEffect( u"Effect" );
+constexpr OUStringLiteral gsPlayFull( u"PlayFull" );
+constexpr OUStringLiteral gsVerb( u"Verb" );
+constexpr OUStringLiteral gsSoundURL( u"SoundURL" );
+constexpr OUStringLiteral gsSpeed( u"Speed" );
+constexpr OUStringLiteral gsStarBasic( u"StarBasic" );
+constexpr OUStringLiteral gsHyperlink( u"Hyperlink" );
+
+XMLShapeExport::XMLShapeExport(SvXMLExport& rExp,
+ SvXMLExportPropertyMapper *pExtMapper )
+: mrExport( rExp ),
+ maCurrentShapesIter(maShapesInfos.end()),
+ mbExportLayer( false ),
+ // #88546# init to sal_False
+ mbHandleProgressBar( false )
+{
+ // construct PropertySetMapper
+ mxPropertySetMapper = CreateShapePropMapper( mrExport );
+ if( pExtMapper )
+ {
+ rtl::Reference < SvXMLExportPropertyMapper > xExtMapper( pExtMapper );
+ mxPropertySetMapper->ChainExportMapper( xExtMapper );
+ }
+
+/*
+ // chain text attributes
+ xPropertySetMapper->ChainExportMapper(XMLTextParagraphExport::CreateParaExtPropMapper(rExp));
+*/
+
+ mrExport.GetAutoStylePool()->AddFamily(
+ XmlStyleFamily::SD_GRAPHICS_ID,
+ XML_STYLE_FAMILY_SD_GRAPHICS_NAME,
+ GetPropertySetMapper(),
+ XML_STYLE_FAMILY_SD_GRAPHICS_PREFIX);
+ mrExport.GetAutoStylePool()->AddFamily(
+ XmlStyleFamily::SD_PRESENTATION_ID,
+ XML_STYLE_FAMILY_SD_PRESENTATION_NAME,
+ GetPropertySetMapper(),
+ XML_STYLE_FAMILY_SD_PRESENTATION_PREFIX);
+
+ // create table export helper and let him add his families in time
+ GetShapeTableExport();
+}
+
+XMLShapeExport::~XMLShapeExport()
+{
+}
+
+// sj: replacing CustomShapes with standard objects that are also supported in OpenOffice.org format
+uno::Reference< drawing::XShape > XMLShapeExport::checkForCustomShapeReplacement( const uno::Reference< drawing::XShape >& xShape )
+{
+ uno::Reference< drawing::XShape > xCustomShapeReplacement;
+
+ if( !( GetExport().getExportFlags() & SvXMLExportFlags::OASIS ) )
+ {
+ OUString aType( xShape->getShapeType() );
+ if( aType == "com.sun.star.drawing.CustomShape" )
+ {
+ uno::Reference< beans::XPropertySet > xSet( xShape, uno::UNO_QUERY );
+ if( xSet.is() )
+ {
+ OUString aEngine;
+ xSet->getPropertyValue("CustomShapeEngine") >>= aEngine;
+ if ( aEngine.isEmpty() )
+ {
+ aEngine = "com.sun.star.drawing.EnhancedCustomShapeEngine";
+ }
+ uno::Reference< uno::XComponentContext > xContext( ::comphelper::getProcessComponentContext() );
+
+ if ( !aEngine.isEmpty() )
+ {
+ uno::Sequence< beans::PropertyValue > aPropValues{
+ comphelper::makePropertyValue("CustomShape", xShape),
+ comphelper::makePropertyValue("ForceGroupWithText", true)
+ };
+ uno::Sequence< uno::Any > aArgument = { uno::Any(aPropValues) };
+ uno::Reference< uno::XInterface > xInterface(
+ xContext->getServiceManager()->createInstanceWithArgumentsAndContext(aEngine, aArgument, xContext) );
+ if ( xInterface.is() )
+ {
+ uno::Reference< drawing::XCustomShapeEngine > xCustomShapeEngine(
+ uno::Reference< drawing::XCustomShapeEngine >( xInterface, uno::UNO_QUERY ) );
+ if ( xCustomShapeEngine.is() )
+ xCustomShapeReplacement = xCustomShapeEngine->render();
+ }
+ }
+ }
+ }
+ }
+ return xCustomShapeReplacement;
+}
+
+// This method collects all automatic styles for the given XShape
+void XMLShapeExport::collectShapeAutoStyles(const uno::Reference< drawing::XShape >& xShape )
+{
+ if( maCurrentShapesIter == maShapesInfos.end() )
+ {
+ OSL_FAIL( "XMLShapeExport::collectShapeAutoStyles(): no call to seekShapes()!" );
+ return;
+ }
+ sal_Int32 nZIndex = 0;
+ uno::Reference< beans::XPropertySet > xPropSet(xShape, uno::UNO_QUERY);
+ if( xPropSet.is() )
+ xPropSet->getPropertyValue(gsZIndex) >>= nZIndex;
+
+ ImplXMLShapeExportInfoVector& aShapeInfoVector = (*maCurrentShapesIter).second;
+
+ if( static_cast<sal_Int32>(aShapeInfoVector.size()) <= nZIndex )
+ {
+ OSL_FAIL( "XMLShapeExport::collectShapeAutoStyles(): no shape info allocated for a given shape" );
+ return;
+ }
+
+ ImplXMLShapeExportInfo& aShapeInfo = aShapeInfoVector[nZIndex];
+
+ uno::Reference< drawing::XShape > xCustomShapeReplacement = checkForCustomShapeReplacement( xShape );
+ if ( xCustomShapeReplacement.is() )
+ aShapeInfo.xCustomShapeReplacement = xCustomShapeReplacement;
+
+ // first compute the shapes type
+ ImpCalcShapeType(xShape, aShapeInfo.meShapeType);
+
+ // #i118485# enabled XmlShapeType::DrawChartShape and XmlShapeType::DrawOLE2Shape
+ // to have text
+ const bool bObjSupportsText =
+ supportsText(aShapeInfo.meShapeType);
+
+ const bool bObjSupportsStyle =
+ aShapeInfo.meShapeType != XmlShapeType::DrawGroupShape;
+
+ bool bIsEmptyPresObj = false;
+
+ if ( aShapeInfo.xCustomShapeReplacement.is() )
+ xPropSet.clear();
+
+ // prep text styles
+ if( xPropSet.is() && bObjSupportsText )
+ {
+ uno::Reference< text::XText > xText(xShape, uno::UNO_QUERY);
+ if (xText.is())
+ {
+ try
+ {
+ // tdf#153161: it seems that the call to XTextRange::getString flushes the changes
+ // for some objects, that otherwise fail to get exported correctly. Maybe at some
+ // point it would make sense to find a better place for more targeted flush.
+ xText->getString();
+ }
+ catch (uno::RuntimeException const&)
+ {
+ // E.g., SwXTextFrame that contains only a table will throw; this is not an error
+ }
+
+ uno::Reference< beans::XPropertySetInfo > xPropSetInfo( xPropSet->getPropertySetInfo() );
+
+ if( xPropSetInfo.is() && xPropSetInfo->hasPropertyByName("IsEmptyPresentationObject") )
+ {
+ uno::Any aAny = xPropSet->getPropertyValue("IsEmptyPresentationObject");
+ aAny >>= bIsEmptyPresObj;
+ }
+
+ if(!bIsEmptyPresObj)
+ {
+ GetExport().GetTextParagraphExport()->collectTextAutoStyles( xText );
+ }
+ }
+ }
+
+ // compute the shape parent style
+ if( xPropSet.is() )
+ {
+ uno::Reference< beans::XPropertySetInfo > xPropertySetInfo( xPropSet->getPropertySetInfo() );
+
+ OUString aParentName;
+ uno::Reference< style::XStyle > xStyle;
+
+ if( bObjSupportsStyle )
+ {
+ if( xPropertySetInfo.is() && xPropertySetInfo->hasPropertyByName("Style") )
+ xPropSet->getPropertyValue("Style") >>= xStyle;
+
+ if(xStyle.is())
+ {
+ // get family ID
+ uno::Reference< beans::XPropertySet > xStylePropSet(xStyle, uno::UNO_QUERY);
+ SAL_WARN_IF( !xStylePropSet.is(), "xmloff", "style without a XPropertySet?" );
+ try
+ {
+ if(xStylePropSet.is())
+ {
+ OUString aFamilyName;
+ xStylePropSet->getPropertyValue("Family") >>= aFamilyName;
+ if( !aFamilyName.isEmpty() && aFamilyName != "graphics" )
+ aShapeInfo.mnFamily = XmlStyleFamily::SD_PRESENTATION_ID;
+ }
+ }
+ catch(const beans::UnknownPropertyException&)
+ {
+ // Ignored.
+ SAL_WARN( "xmloff",
+ "XMLShapeExport::collectShapeAutoStyles: style has no 'Family' property");
+ }
+
+ // get parent-style name
+ if(XmlStyleFamily::SD_PRESENTATION_ID == aShapeInfo.mnFamily)
+ {
+ aParentName = msPresentationStylePrefix;
+ }
+
+ aParentName += xStyle->getName();
+ }
+ }
+
+ if (aParentName.isEmpty() && xPropertySetInfo->hasPropertyByName("TextBox") && xPropSet->getPropertyValue("TextBox").hasValue() && xPropSet->getPropertyValue("TextBox").get<bool>())
+ {
+ // Shapes with a Writer TextBox always have a parent style.
+ // If there would be none, then assign the default one.
+ aParentName = "Frame";
+ }
+
+ // filter propset
+ std::vector< XMLPropertyState > aPropStates;
+
+ sal_Int32 nCount = 0;
+ if( !bIsEmptyPresObj || (aShapeInfo.meShapeType != XmlShapeType::PresPageShape) )
+ {
+ aPropStates = GetPropertySetMapper()->Filter(mrExport, xPropSet);
+
+ if (XmlShapeType::DrawControlShape == aShapeInfo.meShapeType)
+ {
+ // for control shapes, we additionally need the number format style (if any)
+ uno::Reference< drawing::XControlShape > xControl(xShape, uno::UNO_QUERY);
+ DBG_ASSERT(xControl.is(), "XMLShapeExport::collectShapeAutoStyles: ShapeType control, but no XControlShape!");
+ if (xControl.is())
+ {
+ uno::Reference< beans::XPropertySet > xControlModel(xControl->getControl(), uno::UNO_QUERY);
+ DBG_ASSERT(xControlModel.is(), "XMLShapeExport::collectShapeAutoStyles: no control model on the control shape!");
+
+ OUString sNumberStyle = mrExport.GetFormExport()->getControlNumberStyle(xControlModel);
+ if (!sNumberStyle.isEmpty())
+ {
+ sal_Int32 nIndex = GetPropertySetMapper()->getPropertySetMapper()->FindEntryIndex(CTF_SD_CONTROL_SHAPE_DATA_STYLE);
+ // TODO : this retrieval of the index could be moved into the ctor, holding the index
+ // as member, thus saving time.
+ DBG_ASSERT(-1 != nIndex, "XMLShapeExport::collectShapeAutoStyles: could not obtain the index for our context id!");
+
+ XMLPropertyState aNewState(nIndex, uno::Any(sNumberStyle));
+ aPropStates.push_back(aNewState);
+ }
+ }
+ }
+
+ nCount = std::count_if(aPropStates.cbegin(), aPropStates.cend(),
+ [](const XMLPropertyState& rProp) { return rProp.mnIndex != -1; });
+ }
+
+ if(nCount == 0)
+ {
+ // no hard attributes, use parent style name for export
+ aShapeInfo.msStyleName = aParentName;
+ }
+ else
+ {
+ // there are filtered properties -> hard attributes
+ // try to find this style in AutoStylePool
+ aShapeInfo.msStyleName = mrExport.GetAutoStylePool()->Find(aShapeInfo.mnFamily, aParentName, aPropStates);
+
+ if(aShapeInfo.msStyleName.isEmpty())
+ {
+ // Style did not exist, add it to AutoStalePool
+ aShapeInfo.msStyleName = mrExport.GetAutoStylePool()->Add(aShapeInfo.mnFamily, aParentName, std::move(aPropStates));
+ }
+ }
+
+ // optionally generate auto style for text attributes
+ if( (!bIsEmptyPresObj || (aShapeInfo.meShapeType != XmlShapeType::PresPageShape)) && bObjSupportsText )
+ {
+ aPropStates = GetExport().GetTextParagraphExport()->GetParagraphPropertyMapper()->Filter(mrExport, xPropSet);
+
+ // yet more additionally, we need to care for the ParaAdjust property
+ if ( XmlShapeType::DrawControlShape == aShapeInfo.meShapeType )
+ {
+ uno::Reference< beans::XPropertySetInfo > xPropSetInfo( xPropSet->getPropertySetInfo() );
+ uno::Reference< beans::XPropertyState > xPropState( xPropSet, uno::UNO_QUERY );
+ if ( xPropSetInfo.is() && xPropState.is() )
+ {
+ // this is because:
+ // * if controls shapes have a ParaAdjust property, then this is the Align property of the control model
+ // * control models are allowed to have an Align of "void"
+ // * the Default for control model's Align is TextAlign_LEFT
+ // * defaults for style properties are not written, but we need to write the "left",
+ // because we need to distinguish this "left" from the case where not align attribute
+ // is present which means "void"
+ if ( xPropSetInfo->hasPropertyByName( "ParaAdjust" )
+ && ( beans::PropertyState_DEFAULT_VALUE == xPropState->getPropertyState( "ParaAdjust" ) )
+ )
+ {
+ sal_Int32 nIndex = GetExport().GetTextParagraphExport()->GetParagraphPropertyMapper()->getPropertySetMapper()->FindEntryIndex( CTF_SD_SHAPE_PARA_ADJUST );
+ // TODO : this retrieval of the index should be moved into the ctor, holding the index
+ // as member, thus saving time.
+ DBG_ASSERT(-1 != nIndex, "XMLShapeExport::collectShapeAutoStyles: could not obtain the index for the ParaAdjust context id!");
+
+ uno::Any aParaAdjustValue = xPropSet->getPropertyValue( "ParaAdjust" );
+ XMLPropertyState aAlignDefaultState( nIndex, aParaAdjustValue );
+
+ aPropStates.push_back( aAlignDefaultState );
+ }
+ }
+ }
+
+ nCount = std::count_if(aPropStates.cbegin(), aPropStates.cend(),
+ [](const XMLPropertyState& rProp) { return rProp.mnIndex != -1; });
+
+ if( nCount )
+ {
+ aShapeInfo.msTextStyleName = mrExport.GetAutoStylePool()->Find( XmlStyleFamily::TEXT_PARAGRAPH, "", aPropStates );
+ if(aShapeInfo.msTextStyleName.isEmpty())
+ {
+ // Style did not exist, add it to AutoStalePool
+ aShapeInfo.msTextStyleName = mrExport.GetAutoStylePool()->Add(XmlStyleFamily::TEXT_PARAGRAPH, "", std::move(aPropStates));
+ }
+ }
+ }
+ }
+
+ // prepare animation information if needed
+ if( mxAnimationsExporter.is() )
+ XMLAnimationsExporter::prepare( xShape );
+
+ // check for special shapes
+
+ switch( aShapeInfo.meShapeType )
+ {
+ case XmlShapeType::DrawConnectorShape:
+ {
+ uno::Reference< uno::XInterface > xConnection;
+
+ // create shape ids for export later
+ xPropSet->getPropertyValue( gsStartShape ) >>= xConnection;
+ if( xConnection.is() )
+ mrExport.getInterfaceToIdentifierMapper().registerReference( xConnection );
+
+ xPropSet->getPropertyValue( gsEndShape ) >>= xConnection;
+ if( xConnection.is() )
+ mrExport.getInterfaceToIdentifierMapper().registerReference( xConnection );
+ break;
+ }
+ case XmlShapeType::PresTableShape:
+ case XmlShapeType::DrawTableShape:
+ {
+ try
+ {
+ uno::Reference< table::XColumnRowRange > xRange( xPropSet->getPropertyValue( gsModel ), uno::UNO_QUERY_THROW );
+ GetShapeTableExport()->collectTableAutoStyles( xRange );
+ }
+ catch(const uno::Exception&)
+ {
+ DBG_UNHANDLED_EXCEPTION( "xmloff", "collecting auto styles for a table" );
+ }
+ break;
+ }
+ default:
+ break;
+ }
+
+ // check for shape collections (group shape or 3d scene)
+ // and collect contained shapes style infos
+ const uno::Reference< drawing::XShape >& xCollection = aShapeInfo.xCustomShapeReplacement.is()
+ ? aShapeInfo.xCustomShapeReplacement : xShape;
+ {
+ uno::Reference< drawing::XShapes > xShapes( xCollection, uno::UNO_QUERY );
+ if( xShapes.is() )
+ {
+ collectShapesAutoStyles( xShapes );
+ }
+ }
+}
+
+namespace
+{
+ class NewTextListsHelper
+ {
+ public:
+ explicit NewTextListsHelper( SvXMLExport& rExp )
+ : mrExport( rExp )
+ {
+ mrExport.GetTextParagraphExport()->PushNewTextListsHelper();
+ }
+
+ ~NewTextListsHelper()
+ {
+ mrExport.GetTextParagraphExport()->PopTextListsHelper();
+ }
+
+ private:
+ SvXMLExport& mrExport;
+ };
+}
+// This method exports the given XShape
+void XMLShapeExport::exportShape(const uno::Reference< drawing::XShape >& xShape,
+ XMLShapeExportFlags nFeatures /* = SEF_DEFAULT */,
+ css::awt::Point* pRefPoint /* = NULL */,
+ comphelper::AttributeList* pAttrList /* = NULL */ )
+{
+ SAL_INFO("xmloff", xShape->getShapeType());
+ if( maCurrentShapesIter == maShapesInfos.end() )
+ {
+ SAL_WARN( "xmloff", "XMLShapeExport::exportShape(): no auto styles where collected before export" );
+ return;
+ }
+ sal_Int32 nZIndex = 0;
+ uno::Reference< beans::XPropertySet > xSet( xShape, uno::UNO_QUERY );
+ OUString sHyperlink;
+ try
+ {
+ xSet->getPropertyValue(gsHyperlink) >>= sHyperlink;
+ }
+ catch (beans::UnknownPropertyException)
+ {
+ }
+
+ std::unique_ptr< SvXMLElementExport > pHyperlinkElement;
+
+ // Need to stash the attributes that are pre-loaded for the shape export
+ // (otherwise they will become attributes of the draw:a element)
+ uno::Reference<xml::sax::XAttributeList> xSaveAttribs(
+ new comphelper::AttributeList(GetExport().GetAttrList()));
+ GetExport().ClearAttrList();
+ if( xSet.is() && (GetExport().GetModelType() == SvtModuleOptions::EFactory::DRAW) )
+ {
+ // export hyperlinks with <a><shape/></a>. Currently only in draw since draw
+ // does not support document events
+ try
+ {
+ presentation::ClickAction eAction = presentation::ClickAction_NONE;
+ xSet->getPropertyValue(gsOnClick) >>= eAction;
+
+ if( (eAction == presentation::ClickAction_DOCUMENT) ||
+ (eAction == presentation::ClickAction_BOOKMARK) )
+ {
+ OUString sURL;
+ xSet->getPropertyValue(gsBookmark) >>= sURL;
+
+ if( !sURL.isEmpty() )
+ {
+ mrExport.AddAttribute( XML_NAMESPACE_XLINK, XML_HREF, sURL );
+ mrExport.AddAttribute( XML_NAMESPACE_XLINK, XML_TYPE, XML_SIMPLE );
+ mrExport.AddAttribute( XML_NAMESPACE_XLINK, XML_SHOW, XML_EMBED );
+ pHyperlinkElement.reset( new SvXMLElementExport(mrExport, XML_NAMESPACE_DRAW, XML_A, true, true) );
+ }
+ }
+ }
+ catch(const uno::Exception&)
+ {
+ TOOLS_WARN_EXCEPTION("xmloff", "XMLShapeExport::exportShape(): exception during hyperlink export");
+ }
+ }
+ else if (xSet.is() && !sHyperlink.isEmpty())
+ {
+ mrExport.AddAttribute( XML_NAMESPACE_XLINK, XML_HREF, sHyperlink );
+ mrExport.AddAttribute( XML_NAMESPACE_XLINK, XML_TYPE, XML_SIMPLE );
+ pHyperlinkElement.reset( new SvXMLElementExport(mrExport, XML_NAMESPACE_DRAW, XML_A, true, true) );
+ }
+ // re-add stashed attributes
+ GetExport().AddAttributeList(xSaveAttribs);
+
+ if( xSet.is() )
+ xSet->getPropertyValue(gsZIndex) >>= nZIndex;
+
+ ImplXMLShapeExportInfoVector& aShapeInfoVector = (*maCurrentShapesIter).second;
+
+ if( static_cast<sal_Int32>(aShapeInfoVector.size()) <= nZIndex )
+ {
+ SAL_WARN( "xmloff", "XMLShapeExport::exportShape(): no shape info collected for a given shape" );
+ return;
+ }
+
+ NewTextListsHelper aNewTextListsHelper( mrExport );
+
+ const ImplXMLShapeExportInfo& aShapeInfo = aShapeInfoVector[nZIndex];
+
+#ifdef DBG_UTIL
+ // check if this is the correct ShapesInfo
+ uno::Reference< container::XChild > xChild( xShape, uno::UNO_QUERY );
+ if( xChild.is() )
+ {
+ uno::Reference< drawing::XShapes > xParent( xChild->getParent(), uno::UNO_QUERY );
+ SAL_WARN_IF( !xParent.is() && xParent.get() == (*maCurrentShapesIter).first.get(), "xmloff", "XMLShapeExport::exportShape(): Wrong call to XMLShapeExport::seekShapes()" );
+ }
+
+ // first compute the shapes type
+ {
+ XmlShapeType eShapeType(XmlShapeType::NotYetSet);
+ ImpCalcShapeType(xShape, eShapeType);
+
+ SAL_WARN_IF( eShapeType != aShapeInfo.meShapeType, "xmloff", "exportShape callings do not correspond to collectShapeAutoStyles calls!: " << xShape->getShapeType() );
+ }
+#endif
+
+ // collect animation information if needed
+ if( mxAnimationsExporter.is() )
+ mxAnimationsExporter->collect( xShape, mrExport );
+
+ /* Export shapes name if he has one (#i51726#)
+ Export of the shape name for text documents only if the OpenDocument
+ file format is written - exceptions are group shapes.
+ Note: Writer documents in OpenOffice.org file format doesn't contain
+ any names for shapes, except for group shapes.
+ */
+ {
+ if ( ( GetExport().GetModelType() != SvtModuleOptions::EFactory::WRITER &&
+ GetExport().GetModelType() != SvtModuleOptions::EFactory::WRITERWEB &&
+ GetExport().GetModelType() != SvtModuleOptions::EFactory::WRITERGLOBAL ) ||
+ ( GetExport().getExportFlags() & SvXMLExportFlags::OASIS ) ||
+ aShapeInfo.meShapeType == XmlShapeType::DrawGroupShape ||
+ ( aShapeInfo.meShapeType == XmlShapeType::DrawCustomShape &&
+ aShapeInfo.xCustomShapeReplacement.is() ) )
+ {
+ uno::Reference< container::XNamed > xNamed( xShape, uno::UNO_QUERY );
+ if( xNamed.is() )
+ {
+ const OUString aName( xNamed->getName() );
+ if( !aName.isEmpty() )
+ mrExport.AddAttribute(XML_NAMESPACE_DRAW, XML_NAME, aName );
+ }
+ }
+ }
+
+ // export style name
+ if( !aShapeInfo.msStyleName.isEmpty() )
+ {
+ if(XmlStyleFamily::SD_GRAPHICS_ID == aShapeInfo.mnFamily)
+ mrExport.AddAttribute(XML_NAMESPACE_DRAW, XML_STYLE_NAME, mrExport.EncodeStyleName( aShapeInfo.msStyleName) );
+ else
+ mrExport.AddAttribute(XML_NAMESPACE_PRESENTATION, XML_STYLE_NAME, mrExport.EncodeStyleName( aShapeInfo.msStyleName) );
+ }
+
+ // export text style name
+ if( !aShapeInfo.msTextStyleName.isEmpty() )
+ {
+ mrExport.AddAttribute(XML_NAMESPACE_DRAW, XML_TEXT_STYLE_NAME, aShapeInfo.msTextStyleName );
+ }
+
+ // export shapes id if needed
+ {
+ uno::Reference< uno::XInterface > xRef( xShape, uno::UNO_QUERY );
+ const OUString& rShapeId = mrExport.getInterfaceToIdentifierMapper().getIdentifier( xRef );
+ if( !rShapeId.isEmpty() )
+ {
+ mrExport.AddAttributeIdLegacy(XML_NAMESPACE_DRAW, rShapeId);
+ }
+ }
+
+ // export layer information
+ if( mbExportLayer )
+ {
+ // check for group or scene shape and not export layer if this is one
+ uno::Reference< drawing::XShapes > xShapes( xShape, uno::UNO_QUERY );
+ if( !xShapes.is() )
+ {
+ try
+ {
+ uno::Reference< beans::XPropertySet > xProps( xShape, uno::UNO_QUERY );
+ OUString aLayerName;
+ xProps->getPropertyValue("LayerName") >>= aLayerName;
+ mrExport.AddAttribute(XML_NAMESPACE_DRAW, XML_LAYER, aLayerName );
+
+ }
+ catch(const uno::Exception&)
+ {
+ DBG_UNHANDLED_EXCEPTION( "xmloff", "exporting layer name for shape" );
+ }
+ }
+ }
+
+ // export draw:display (do not export in ODF 1.3 or older)
+ if (xSet.is() && (mrExport.getSaneDefaultVersion() & SvtSaveOptions::ODFSVER_EXTENDED))
+ {
+ if( aShapeInfo.meShapeType != XmlShapeType::DrawPageShape && aShapeInfo.meShapeType != XmlShapeType::PresPageShape &&
+ aShapeInfo.meShapeType != XmlShapeType::HandoutShape && aShapeInfo.meShapeType != XmlShapeType::DrawChartShape )
+ try
+ {
+ bool bVisible = true;
+ bool bPrintable = true;
+
+ xSet->getPropertyValue(gsVisible) >>= bVisible;
+ xSet->getPropertyValue(gsPrintable) >>= bPrintable;
+
+ XMLTokenEnum eDisplayToken = XML_TOKEN_INVALID;
+ const unsigned short nDisplay = (bVisible ? 2 : 0) | (bPrintable ? 1 : 0);
+ switch( nDisplay )
+ {
+ case 0: eDisplayToken = XML_NONE; break;
+ case 1: eDisplayToken = XML_PRINTER; break;
+ case 2: eDisplayToken = XML_SCREEN; break;
+ // case 3: eDisplayToken = XML_ALWAYS break; this is the default
+ }
+
+ if( eDisplayToken != XML_TOKEN_INVALID )
+ mrExport.AddAttribute(XML_NAMESPACE_DRAW_EXT, XML_DISPLAY, eDisplayToken );
+ }
+ catch(const uno::Exception&)
+ {
+ DBG_UNHANDLED_EXCEPTION("xmloff.draw");
+ }
+ }
+
+ // #82003# test export count
+ // #91587# ALWAYS increment since now ALL to be exported shapes are counted.
+ if(mrExport.GetShapeExport()->IsHandleProgressBarEnabled())
+ {
+ mrExport.GetProgressBarHelper()->Increment();
+ }
+
+ onExport( xShape );
+
+ // export shape element
+ switch(aShapeInfo.meShapeType)
+ {
+ case XmlShapeType::DrawRectangleShape:
+ {
+ ImpExportRectangleShape(xShape, nFeatures, pRefPoint );
+ break;
+ }
+ case XmlShapeType::DrawEllipseShape:
+ {
+ ImpExportEllipseShape(xShape, nFeatures, pRefPoint );
+ break;
+ }
+ case XmlShapeType::DrawLineShape:
+ {
+ ImpExportLineShape(xShape, nFeatures, pRefPoint );
+ break;
+ }
+ case XmlShapeType::DrawPolyPolygonShape: // closed PolyPolygon
+ case XmlShapeType::DrawPolyLineShape: // open PolyPolygon
+ case XmlShapeType::DrawClosedBezierShape: // closed tools::PolyPolygon containing curves
+ case XmlShapeType::DrawOpenBezierShape: // open tools::PolyPolygon containing curves
+ {
+ ImpExportPolygonShape(xShape, aShapeInfo.meShapeType, nFeatures, pRefPoint );
+ break;
+ }
+
+ case XmlShapeType::DrawTextShape:
+ case XmlShapeType::PresTitleTextShape:
+ case XmlShapeType::PresOutlinerShape:
+ case XmlShapeType::PresSubtitleShape:
+ case XmlShapeType::PresNotesShape:
+ case XmlShapeType::PresHeaderShape:
+ case XmlShapeType::PresFooterShape:
+ case XmlShapeType::PresSlideNumberShape:
+ case XmlShapeType::PresDateTimeShape:
+ {
+ ImpExportTextBoxShape(xShape, aShapeInfo.meShapeType, nFeatures, pRefPoint );
+ break;
+ }
+
+ case XmlShapeType::DrawGraphicObjectShape:
+ case XmlShapeType::PresGraphicObjectShape:
+ {
+ ImpExportGraphicObjectShape(xShape, aShapeInfo.meShapeType, nFeatures, pRefPoint );
+ break;
+ }
+
+ case XmlShapeType::DrawChartShape:
+ case XmlShapeType::PresChartShape:
+ {
+ ImpExportChartShape(xShape, aShapeInfo.meShapeType, nFeatures, pRefPoint, pAttrList );
+ break;
+ }
+
+ case XmlShapeType::DrawControlShape:
+ {
+ ImpExportControlShape(xShape, nFeatures, pRefPoint );
+ break;
+ }
+
+ case XmlShapeType::DrawConnectorShape:
+ {
+ ImpExportConnectorShape(xShape, nFeatures, pRefPoint );
+ break;
+ }
+
+ case XmlShapeType::DrawMeasureShape:
+ {
+ ImpExportMeasureShape(xShape, nFeatures, pRefPoint );
+ break;
+ }
+
+ case XmlShapeType::DrawOLE2Shape:
+ case XmlShapeType::PresOLE2Shape:
+ case XmlShapeType::DrawSheetShape:
+ case XmlShapeType::PresSheetShape:
+ {
+ ImpExportOLE2Shape(xShape, aShapeInfo.meShapeType, nFeatures, pRefPoint );
+ break;
+ }
+
+ case XmlShapeType::PresTableShape:
+ case XmlShapeType::DrawTableShape:
+ {
+ ImpExportTableShape( xShape, aShapeInfo.meShapeType, nFeatures, pRefPoint );
+ break;
+ }
+
+ case XmlShapeType::DrawPageShape:
+ case XmlShapeType::PresPageShape:
+ case XmlShapeType::HandoutShape:
+ {
+ ImpExportPageShape(xShape, aShapeInfo.meShapeType, nFeatures, pRefPoint );
+ break;
+ }
+
+ case XmlShapeType::DrawCaptionShape:
+ {
+ ImpExportCaptionShape(xShape, nFeatures, pRefPoint );
+ break;
+ }
+
+ case XmlShapeType::Draw3DCubeObject:
+ case XmlShapeType::Draw3DSphereObject:
+ case XmlShapeType::Draw3DLatheObject:
+ case XmlShapeType::Draw3DExtrudeObject:
+ {
+ ImpExport3DShape(xShape, aShapeInfo.meShapeType);
+ break;
+ }
+
+ case XmlShapeType::Draw3DSceneObject:
+ {
+ ImpExport3DSceneShape( xShape, nFeatures, pRefPoint );
+ break;
+ }
+
+ case XmlShapeType::DrawGroupShape:
+ {
+ // empty group
+ ImpExportGroupShape( xShape, nFeatures, pRefPoint );
+ break;
+ }
+
+ case XmlShapeType::DrawFrameShape:
+ {
+ ImpExportFrameShape(xShape, nFeatures, pRefPoint );
+ break;
+ }
+
+ case XmlShapeType::DrawAppletShape:
+ {
+ ImpExportAppletShape(xShape, nFeatures, pRefPoint );
+ break;
+ }
+
+ case XmlShapeType::DrawPluginShape:
+ {
+ ImpExportPluginShape(xShape, nFeatures, pRefPoint );
+ break;
+ }
+
+ case XmlShapeType::DrawCustomShape:
+ {
+ if ( aShapeInfo.xCustomShapeReplacement.is() )
+ ImpExportGroupShape( aShapeInfo.xCustomShapeReplacement, nFeatures, pRefPoint );
+ else
+ ImpExportCustomShape( xShape, nFeatures, pRefPoint );
+ break;
+ }
+
+ case XmlShapeType::PresMediaShape:
+ case XmlShapeType::DrawMediaShape:
+ {
+ ImpExportMediaShape( xShape, aShapeInfo.meShapeType, nFeatures, pRefPoint );
+ break;
+ }
+
+ case XmlShapeType::PresOrgChartShape:
+ case XmlShapeType::Unknown:
+ case XmlShapeType::NotYetSet:
+ default:
+ {
+ // this should never happen and is an error
+ OSL_FAIL("XMLEXP: WriteShape: unknown or unexpected type of shape in export!");
+ break;
+ }
+ }
+
+ pHyperlinkElement.reset();
+
+ // #97489# #97111#
+ // if there was an error and no element for the shape was exported
+ // we need to clear the attribute list or the attributes will be
+ // set on the next exported element, which can result in corrupt
+ // xml files due to duplicate attributes
+
+ mrExport.CheckAttrList(); // asserts in non pro if we have attributes left
+ mrExport.ClearAttrList(); // clears the attributes
+}
+
+// This method collects all automatic styles for the shapes inside the given XShapes collection
+void XMLShapeExport::collectShapesAutoStyles( const uno::Reference < drawing::XShapes >& xShapes )
+{
+ ShapesInfos::iterator aOldCurrentShapesIter = maCurrentShapesIter;
+ seekShapes( xShapes );
+
+ uno::Reference< drawing::XShape > xShape;
+ const sal_Int32 nShapeCount(xShapes->getCount());
+ for(sal_Int32 nShapeId = 0; nShapeId < nShapeCount; nShapeId++)
+ {
+ xShapes->getByIndex(nShapeId) >>= xShape;
+ SAL_WARN_IF( !xShape.is(), "xmloff", "Shape without a XShape?" );
+ if(!xShape.is())
+ continue;
+
+ collectShapeAutoStyles( xShape );
+ }
+
+ maCurrentShapesIter = aOldCurrentShapesIter;
+}
+
+// This method exports all XShape inside the given XShapes collection
+void XMLShapeExport::exportShapes( const uno::Reference < drawing::XShapes >& xShapes, XMLShapeExportFlags nFeatures /* = SEF_DEFAULT */, awt::Point* pRefPoint /* = NULL */ )
+{
+ ShapesInfos::iterator aOldCurrentShapesIter = maCurrentShapesIter;
+ seekShapes( xShapes );
+
+ uno::Reference< drawing::XShape > xShape;
+ const sal_Int32 nShapeCount(xShapes->getCount());
+ for(sal_Int32 nShapeId = 0; nShapeId < nShapeCount; nShapeId++)
+ {
+ xShapes->getByIndex(nShapeId) >>= xShape;
+ SAL_WARN_IF( !xShape.is(), "xmloff", "Shape without a XShape?" );
+ if(!xShape.is())
+ continue;
+
+ exportShape( xShape, nFeatures, pRefPoint );
+ }
+
+ maCurrentShapesIter = aOldCurrentShapesIter;
+}
+
+namespace xmloff {
+
+void FixZOrder(uno::Reference<drawing::XShapes> const& xShapes,
+ std::function<unsigned int (uno::Reference<beans::XPropertySet> const&)> const& rGetLayer)
+{
+ uno::Reference<drawing::XShapes3> const xShapes3(xShapes, uno::UNO_QUERY);
+ assert(xShapes3.is());
+ if (!xShapes3.is())
+ {
+ return; // only SvxDrawPage implements this
+ }
+ struct Layer { std::vector<sal_Int32> shapes; sal_Int32 nMin = SAL_MAX_INT32; sal_Int32 nMax = 0; };
+ std::vector<Layer> layers;
+ // shapes are sorted by ZOrder
+ sal_Int32 const nCount(xShapes->getCount());
+ for (sal_Int32 i = 0; i < nCount; ++i)
+ {
+ uno::Reference<beans::XPropertySet> const xShape(xShapes->getByIndex(i), uno::UNO_QUERY);
+ if (!xShape.is())
+ {
+ SAL_WARN("xmloff", "FixZOrder: null shape, cannot sort");
+ return;
+ }
+ unsigned int const nLayer(rGetLayer(xShape));
+ if (layers.size() <= nLayer)
+ {
+ layers.resize(nLayer + 1);
+ }
+ layers[nLayer].shapes.emplace_back(i);
+ if (i < layers[nLayer].nMin)
+ {
+ layers[nLayer].nMin = i;
+ }
+ if (layers[nLayer].nMax < i)
+ {
+ layers[nLayer].nMax = i;
+ }
+ }
+ std::erase_if(layers, [](Layer const& rLayer) { return rLayer.shapes.empty(); });
+ bool isSorted(true);
+ for (size_t i = 1; i < layers.size(); ++i)
+ {
+ assert(layers[i].nMin != layers[i-1].nMax); // unique!
+ if (layers[i].nMin < layers[i-1].nMax)
+ {
+ isSorted = false;
+ break;
+ }
+ }
+ if (isSorted)
+ {
+ return; // nothing to do
+ }
+ uno::Sequence<sal_Int32> aNewOrder(nCount);
+ auto iterInsert(aNewOrder.getArray());
+ for (auto const& rLayer : layers)
+ {
+ assert(rLayer.nMin <= rLayer.nMax); // empty layers have been removed
+ iterInsert = std::copy(rLayer.shapes.begin(), rLayer.shapes.end(), iterInsert);
+ }
+ try
+ {
+ xShapes3->sort(aNewOrder);
+ }
+ catch (uno::Exception const&)
+ {
+ SAL_WARN("xmloff", "FixZOrder: exception");
+ }
+}
+
+} // namespace xmloff
+
+void XMLShapeExport::seekShapes( const uno::Reference< drawing::XShapes >& xShapes ) noexcept
+{
+ if( xShapes.is() )
+ {
+ maCurrentShapesIter = maShapesInfos.find( xShapes );
+ if( maCurrentShapesIter == maShapesInfos.end() )
+ {
+ auto itPair = maShapesInfos.emplace( xShapes, ImplXMLShapeExportInfoVector( static_cast<ShapesInfos::size_type>(xShapes->getCount()) ) );
+
+ maCurrentShapesIter = itPair.first;
+
+ SAL_WARN_IF( maCurrentShapesIter == maShapesInfos.end(), "xmloff", "XMLShapeExport::seekShapes(): insert into stl::map failed" );
+ }
+
+ SAL_WARN_IF( (*maCurrentShapesIter).second.size() != static_cast<ShapesInfos::size_type>(xShapes->getCount()), "xmloff", "XMLShapeExport::seekShapes(): XShapes size varied between calls" );
+
+ }
+ else
+ {
+ maCurrentShapesIter = maShapesInfos.end();
+ }
+}
+
+void XMLShapeExport::exportAutoStyles()
+{
+ // export all autostyle infos
+
+ // ...for graphic
+ {
+ GetExport().GetAutoStylePool()->exportXML( XmlStyleFamily::SD_GRAPHICS_ID );
+ }
+
+ // ...for presentation
+ {
+ GetExport().GetAutoStylePool()->exportXML( XmlStyleFamily::SD_PRESENTATION_ID );
+ }
+
+ if( mxShapeTableExport.is() )
+ mxShapeTableExport->exportAutoStyles();
+}
+
+/// returns the export property mapper for external chaining
+SvXMLExportPropertyMapper* XMLShapeExport::CreateShapePropMapper(
+ SvXMLExport& rExport )
+{
+ rtl::Reference< XMLPropertyHandlerFactory > xFactory = new XMLSdPropHdlFactory( rExport.GetModel(), rExport );
+ rtl::Reference < XMLPropertySetMapper > xMapper = new XMLShapePropertySetMapper( xFactory, true );
+ rExport.GetTextParagraphExport(); // get or create text paragraph export
+ SvXMLExportPropertyMapper* pResult =
+ new XMLShapeExportPropertyMapper( xMapper, rExport );
+ // chain text attributes
+ return pResult;
+}
+
+void XMLShapeExport::ImpCalcShapeType(const uno::Reference< drawing::XShape >& xShape,
+ XmlShapeType& eShapeType)
+{
+ // set in every case, so init here
+ eShapeType = XmlShapeType::Unknown;
+
+ if(!xShape.is())
+ return;
+
+ OUString aType(xShape->getShapeType());
+
+ if(!aType.match("com.sun.star."))
+ return;
+
+ if(aType.match("drawing.", 13))
+ {
+ // drawing shapes
+ if (aType.match("Rectangle", 21)) { eShapeType = XmlShapeType::DrawRectangleShape; }
+
+ // #i72177# Note: Correcting CustomShape, CustomShape->Custom, len from 9 (was wrong anyways) to 6.
+ // As can be seen at the other compares, the appendix "Shape" is left out of the comparison.
+ else if(aType.match("Custom", 21)) { eShapeType = XmlShapeType::DrawCustomShape; }
+
+ else if(aType.match("Ellipse", 21)) { eShapeType = XmlShapeType::DrawEllipseShape; }
+ else if(aType.match("Control", 21)) { eShapeType = XmlShapeType::DrawControlShape; }
+ else if(aType.match("Connector", 21)) { eShapeType = XmlShapeType::DrawConnectorShape; }
+ else if(aType.match("Measure", 21)) { eShapeType = XmlShapeType::DrawMeasureShape; }
+ else if(aType.match("Line", 21)) { eShapeType = XmlShapeType::DrawLineShape; }
+
+ // #i72177# Note: This covers two types by purpose, PolyPolygonShape and PolyPolygonPathShape
+ else if(aType.match("PolyPolygon", 21)) { eShapeType = XmlShapeType::DrawPolyPolygonShape; }
+
+ // #i72177# Note: This covers two types by purpose, PolyLineShape and PolyLinePathShape
+ else if(aType.match("PolyLine", 21)) { eShapeType = XmlShapeType::DrawPolyLineShape; }
+
+ else if(aType.match("OpenBezier", 21)) { eShapeType = XmlShapeType::DrawOpenBezierShape; }
+ else if(aType.match("ClosedBezier", 21)) { eShapeType = XmlShapeType::DrawClosedBezierShape; }
+
+ // #i72177# FreeHand (opened and closed) now supports the types OpenFreeHandShape and
+ // ClosedFreeHandShape respectively. Represent them as bezier shapes
+ else if(aType.match("OpenFreeHand", 21)) { eShapeType = XmlShapeType::DrawOpenBezierShape; }
+ else if(aType.match("ClosedFreeHand", 21)) { eShapeType = XmlShapeType::DrawClosedBezierShape; }
+
+ else if(aType.match("GraphicObject", 21)) { eShapeType = XmlShapeType::DrawGraphicObjectShape; }
+ else if(aType.match("Group", 21)) { eShapeType = XmlShapeType::DrawGroupShape; }
+ else if(aType.match("Text", 21)) { eShapeType = XmlShapeType::DrawTextShape; }
+ else if(aType.match("OLE2", 21))
+ {
+ eShapeType = XmlShapeType::DrawOLE2Shape;
+
+ // get info about presentation shape
+ uno::Reference <beans::XPropertySet> xPropSet(xShape, uno::UNO_QUERY);
+
+ if(xPropSet.is())
+ {
+ OUString sCLSID;
+ if(xPropSet->getPropertyValue("CLSID") >>= sCLSID)
+ {
+#if !ENABLE_WASM_STRIP_CHART
+ // WASM_CHART change
+ // TODO: With Chart extracted this cannot really happen since
+ // no Chart could've been added at all
+ if (sCLSID == mrExport.GetChartExport()->getChartCLSID() ||
+#else
+ if(
+#endif
+ sCLSID == SvGlobalName( SO3_RPTCH_CLASSID ).GetHexName() )
+ {
+ eShapeType = XmlShapeType::DrawChartShape;
+ }
+ else if (sCLSID == SvGlobalName( SO3_SC_CLASSID ).GetHexName() )
+ {
+ eShapeType = XmlShapeType::DrawSheetShape;
+ }
+ else
+ {
+ // general OLE2 Object
+ }
+ }
+ }
+ }
+ else if(aType.match("Page", 21)) { eShapeType = XmlShapeType::DrawPageShape; }
+ else if(aType.match("Frame", 21)) { eShapeType = XmlShapeType::DrawFrameShape; }
+ else if(aType.match("Caption", 21)) { eShapeType = XmlShapeType::DrawCaptionShape; }
+ else if(aType.match("Plugin", 21)) { eShapeType = XmlShapeType::DrawPluginShape; }
+ else if(aType.match("Applet", 21)) { eShapeType = XmlShapeType::DrawAppletShape; }
+ else if(aType.match("MediaShape", 21)) { eShapeType = XmlShapeType::DrawMediaShape; }
+ else if(aType.match("TableShape", 21)) { eShapeType = XmlShapeType::DrawTableShape; }
+
+ // 3D shapes
+ else if(aType.match("Scene", 21 + 7)) { eShapeType = XmlShapeType::Draw3DSceneObject; }
+ else if(aType.match("Cube", 21 + 7)) { eShapeType = XmlShapeType::Draw3DCubeObject; }
+ else if(aType.match("Sphere", 21 + 7)) { eShapeType = XmlShapeType::Draw3DSphereObject; }
+ else if(aType.match("Lathe", 21 + 7)) { eShapeType = XmlShapeType::Draw3DLatheObject; }
+ else if(aType.match("Extrude", 21 + 7)) { eShapeType = XmlShapeType::Draw3DExtrudeObject; }
+ }
+ else if(aType.match("presentation.", 13))
+ {
+ // presentation shapes
+ if (aType.match("TitleText", 26)) { eShapeType = XmlShapeType::PresTitleTextShape; }
+ else if(aType.match("Outliner", 26)) { eShapeType = XmlShapeType::PresOutlinerShape; }
+ else if(aType.match("Subtitle", 26)) { eShapeType = XmlShapeType::PresSubtitleShape; }
+ else if(aType.match("GraphicObject", 26)) { eShapeType = XmlShapeType::PresGraphicObjectShape; }
+ else if(aType.match("Page", 26)) { eShapeType = XmlShapeType::PresPageShape; }
+ else if(aType.match("OLE2", 26))
+ {
+ eShapeType = XmlShapeType::PresOLE2Shape;
+
+ // get info about presentation shape
+ uno::Reference <beans::XPropertySet> xPropSet(xShape, uno::UNO_QUERY);
+
+ if(xPropSet.is()) try
+ {
+ OUString sCLSID;
+ if(xPropSet->getPropertyValue("CLSID") >>= sCLSID)
+ {
+ if( sCLSID == SvGlobalName( SO3_SC_CLASSID ).GetHexName() )
+ {
+ eShapeType = XmlShapeType::PresSheetShape;
+ }
+ }
+ }
+ catch(const uno::Exception&)
+ {
+ SAL_WARN( "xmloff", "XMLShapeExport::ImpCalcShapeType(), expected ole shape to have the CLSID property?" );
+ }
+ }
+ else if(aType.match("Chart", 26)) { eShapeType = XmlShapeType::PresChartShape; }
+ else if(aType.match("OrgChart", 26)) { eShapeType = XmlShapeType::PresOrgChartShape; }
+ else if(aType.match("CalcShape", 26)) { eShapeType = XmlShapeType::PresSheetShape; }
+ else if(aType.match("TableShape", 26)) { eShapeType = XmlShapeType::PresTableShape; }
+ else if(aType.match("Notes", 26)) { eShapeType = XmlShapeType::PresNotesShape; }
+ else if(aType.match("HandoutShape", 26)) { eShapeType = XmlShapeType::HandoutShape; }
+ else if(aType.match("HeaderShape", 26)) { eShapeType = XmlShapeType::PresHeaderShape; }
+ else if(aType.match("FooterShape", 26)) { eShapeType = XmlShapeType::PresFooterShape; }
+ else if(aType.match("SlideNumberShape", 26)) { eShapeType = XmlShapeType::PresSlideNumberShape; }
+ else if(aType.match("DateTimeShape", 26)) { eShapeType = XmlShapeType::PresDateTimeShape; }
+ else if(aType.match("MediaShape", 26)) { eShapeType = XmlShapeType::PresMediaShape; }
+ }
+}
+
+/** exports all user defined gluepoints */
+void XMLShapeExport::ImpExportGluePoints( const uno::Reference< drawing::XShape >& xShape )
+{
+ uno::Reference< drawing::XGluePointsSupplier > xSupplier( xShape, uno::UNO_QUERY );
+ if( !xSupplier.is() )
+ return;
+
+ uno::Reference< container::XIdentifierAccess > xGluePoints( xSupplier->getGluePoints(), uno::UNO_QUERY );
+ if( !xGluePoints.is() )
+ return;
+
+ drawing::GluePoint2 aGluePoint;
+
+ const uno::Sequence< sal_Int32 > aIdSequence( xGluePoints->getIdentifiers() );
+
+ for( const sal_Int32 nIdentifier : aIdSequence )
+ {
+ if( (xGluePoints->getByIdentifier( nIdentifier ) >>= aGluePoint) && aGluePoint.IsUserDefined )
+ {
+ // export only user defined gluepoints
+
+ const OUString sId( OUString::number( nIdentifier ) );
+ mrExport.AddAttribute(XML_NAMESPACE_DRAW, XML_ID, sId );
+
+ mrExport.GetMM100UnitConverter().convertMeasureToXML(msBuffer,
+ aGluePoint.Position.X);
+ mrExport.AddAttribute(XML_NAMESPACE_SVG, XML_X, msBuffer.makeStringAndClear());
+
+ mrExport.GetMM100UnitConverter().convertMeasureToXML(msBuffer,
+ aGluePoint.Position.Y);
+ mrExport.AddAttribute(XML_NAMESPACE_SVG, XML_Y, msBuffer.makeStringAndClear());
+
+ if( !aGluePoint.IsRelative )
+ {
+ SvXMLUnitConverter::convertEnum( msBuffer, aGluePoint.PositionAlignment, aXML_GlueAlignment_EnumMap );
+ mrExport.AddAttribute( XML_NAMESPACE_DRAW, XML_ALIGN, msBuffer.makeStringAndClear() );
+ }
+
+ if( aGluePoint.Escape != drawing::EscapeDirection_SMART )
+ {
+ SvXMLUnitConverter::convertEnum( msBuffer, aGluePoint.Escape, aXML_GlueEscapeDirection_EnumMap );
+ mrExport.AddAttribute( XML_NAMESPACE_DRAW, XML_ESCAPE_DIRECTION, msBuffer.makeStringAndClear() );
+ }
+
+ SvXMLElementExport aEventsElemt(mrExport, XML_NAMESPACE_DRAW, XML_GLUE_POINT, true, true);
+ }
+ }
+}
+
+void XMLShapeExport::ImpExportSignatureLine(const uno::Reference<drawing::XShape>& xShape)
+{
+ uno::Reference<beans::XPropertySet> xPropSet(xShape, uno::UNO_QUERY);
+
+ bool bIsSignatureLine = false;
+ xPropSet->getPropertyValue("IsSignatureLine") >>= bIsSignatureLine;
+ if (!bIsSignatureLine)
+ return;
+
+ OUString aSignatureLineId;
+ xPropSet->getPropertyValue("SignatureLineId") >>= aSignatureLineId;
+ mrExport.AddAttribute(XML_NAMESPACE_LO_EXT, XML_ID, aSignatureLineId);
+
+ OUString aSuggestedSignerName;
+ xPropSet->getPropertyValue("SignatureLineSuggestedSignerName") >>= aSuggestedSignerName;
+ if (!aSuggestedSignerName.isEmpty())
+ mrExport.AddAttribute(XML_NAMESPACE_LO_EXT, XML_SUGGESTED_SIGNER_NAME, aSuggestedSignerName);
+
+ OUString aSuggestedSignerTitle;
+ xPropSet->getPropertyValue("SignatureLineSuggestedSignerTitle") >>= aSuggestedSignerTitle;
+ if (!aSuggestedSignerTitle.isEmpty())
+ mrExport.AddAttribute(XML_NAMESPACE_LO_EXT, XML_SUGGESTED_SIGNER_TITLE, aSuggestedSignerTitle);
+
+ OUString aSuggestedSignerEmail;
+ xPropSet->getPropertyValue("SignatureLineSuggestedSignerEmail") >>= aSuggestedSignerEmail;
+ if (!aSuggestedSignerEmail.isEmpty())
+ mrExport.AddAttribute(XML_NAMESPACE_LO_EXT, XML_SUGGESTED_SIGNER_EMAIL, aSuggestedSignerEmail);
+
+ OUString aSigningInstructions;
+ xPropSet->getPropertyValue("SignatureLineSigningInstructions") >>= aSigningInstructions;
+ if (!aSigningInstructions.isEmpty())
+ mrExport.AddAttribute(XML_NAMESPACE_LO_EXT, XML_SIGNING_INSTRUCTIONS, aSigningInstructions);
+
+ bool bShowSignDate = false;
+ xPropSet->getPropertyValue("SignatureLineShowSignDate") >>= bShowSignDate;
+ mrExport.AddAttribute(XML_NAMESPACE_LO_EXT, XML_SHOW_SIGN_DATE,
+ bShowSignDate ? XML_TRUE : XML_FALSE);
+
+ bool bCanAddComment = false;
+ xPropSet->getPropertyValue("SignatureLineCanAddComment") >>= bCanAddComment;
+ mrExport.AddAttribute(XML_NAMESPACE_LO_EXT, XML_CAN_ADD_COMMENT,
+ bCanAddComment ? XML_TRUE : XML_FALSE);
+
+ SvXMLElementExport aSignatureLineElement(mrExport, XML_NAMESPACE_LO_EXT, XML_SIGNATURELINE, true,
+ true);
+}
+
+void XMLShapeExport::ImpExportQRCode(const uno::Reference<drawing::XShape>& xShape)
+{
+ uno::Reference<beans::XPropertySet> xPropSet(xShape, uno::UNO_QUERY);
+
+ uno::Any aAny = xPropSet->getPropertyValue("BarCodeProperties");
+
+ css::drawing::BarCode aBarCode;
+ if(!(aAny >>= aBarCode))
+ return;
+
+ mrExport.AddAttribute(XML_NAMESPACE_OFFICE, XML_STRING_VALUE, aBarCode.Payload);
+ /* Export QR Code as per customised schema, @see OpenDocument-schema-v1.3+libreoffice */
+ OUString temp;
+ switch(aBarCode.ErrorCorrection){
+ case css::drawing::BarCodeErrorCorrection::LOW :
+ temp = "low";
+ break;
+ case css::drawing::BarCodeErrorCorrection::MEDIUM:
+ temp = "medium";
+ break;
+ case css::drawing::BarCodeErrorCorrection::QUARTILE:
+ temp = "quartile";
+ break;
+ case css::drawing::BarCodeErrorCorrection::HIGH:
+ temp = "high";
+ break;
+ }
+ mrExport.AddAttribute(XML_NAMESPACE_LO_EXT, XML_QRCODE_ERROR_CORRECTION, temp);
+ mrExport.AddAttribute(XML_NAMESPACE_LO_EXT, XML_QRCODE_BORDER, OUStringBuffer(20).append(aBarCode.Border).makeStringAndClear());
+ mrExport.AddAttribute(XML_NAMESPACE_LO_EXT, XML_QRCODE_TYPE, OUStringBuffer(20).append(aBarCode.Type).makeStringAndClear());
+
+ SvXMLElementExport aBarCodeElement(mrExport, XML_NAMESPACE_LO_EXT, XML_QRCODE, true,
+ true);
+}
+
+void XMLShapeExport::ExportGraphicDefaults()
+{
+ rtl::Reference<XMLStyleExport> aStEx(new XMLStyleExport(mrExport, mrExport.GetAutoStylePool().get()));
+
+ // construct PropertySetMapper
+ rtl::Reference< SvXMLExportPropertyMapper > xPropertySetMapper( CreateShapePropMapper( mrExport ) );
+ static_cast<XMLShapeExportPropertyMapper*>(xPropertySetMapper.get())->SetAutoStyles( false );
+
+ // chain text attributes
+ xPropertySetMapper->ChainExportMapper(XMLTextParagraphExport::CreateParaExtPropMapper(mrExport));
+
+ // chain special Writer/text frame default attributes
+ xPropertySetMapper->ChainExportMapper(XMLTextParagraphExport::CreateParaDefaultExtPropMapper(mrExport));
+
+ // write graphic family default style
+ uno::Reference< lang::XMultiServiceFactory > xFact( mrExport.GetModel(), uno::UNO_QUERY );
+ if( !xFact.is() )
+ return;
+
+ try
+ {
+ uno::Reference< beans::XPropertySet > xDefaults( xFact->createInstance("com.sun.star.drawing.Defaults"), uno::UNO_QUERY );
+ if( xDefaults.is() )
+ {
+ aStEx->exportDefaultStyle( xDefaults, XML_STYLE_FAMILY_SD_GRAPHICS_NAME, xPropertySetMapper );
+
+ // write graphic styles (family name differs depending on the module)
+ aStEx->exportStyleFamily("graphics", XML_STYLE_FAMILY_SD_GRAPHICS_NAME, xPropertySetMapper, false, XmlStyleFamily::SD_GRAPHICS_ID);
+ aStEx->exportStyleFamily("GraphicStyles", XML_STYLE_FAMILY_SD_GRAPHICS_NAME, xPropertySetMapper, false, XmlStyleFamily::SD_GRAPHICS_ID);
+ }
+ }
+ catch(const lang::ServiceNotRegisteredException&)
+ {
+ }
+}
+
+void XMLShapeExport::onExport( const css::uno::Reference < css::drawing::XShape >& )
+{
+}
+
+const rtl::Reference< XMLTableExport >& XMLShapeExport::GetShapeTableExport()
+{
+ if( !mxShapeTableExport.is() )
+ {
+ rtl::Reference< XMLPropertyHandlerFactory > xFactory( new XMLSdPropHdlFactory( mrExport.GetModel(), mrExport ) );
+ rtl::Reference < XMLPropertySetMapper > xMapper( new XMLShapePropertySetMapper( xFactory, true ) );
+ mrExport.GetTextParagraphExport(); // get or create text paragraph export
+ rtl::Reference< SvXMLExportPropertyMapper > xPropertySetMapper( new XMLShapeExportPropertyMapper( xMapper, mrExport ) );
+ mxShapeTableExport = new XMLTableExport( mrExport, xPropertySetMapper, xFactory );
+ }
+
+ return mxShapeTableExport;
+}
+
+void XMLShapeExport::ImpExportNewTrans(const uno::Reference< beans::XPropertySet >& xPropSet,
+ XMLShapeExportFlags nFeatures, awt::Point* pRefPoint)
+{
+ // get matrix
+ ::basegfx::B2DHomMatrix aMatrix;
+ ImpExportNewTrans_GetB2DHomMatrix(aMatrix, xPropSet);
+
+ // decompose and correct about pRefPoint
+ ::basegfx::B2DTuple aTRScale;
+ double fTRShear(0.0);
+ double fTRRotate(0.0);
+ ::basegfx::B2DTuple aTRTranslate;
+ ImpExportNewTrans_DecomposeAndRefPoint(aMatrix, aTRScale, fTRShear, fTRRotate, aTRTranslate, pRefPoint);
+
+ // use features and write
+ ImpExportNewTrans_FeaturesAndWrite(aTRScale, fTRShear, fTRRotate, aTRTranslate, nFeatures);
+}
+
+void XMLShapeExport::ImpExportNewTrans_GetB2DHomMatrix(::basegfx::B2DHomMatrix& rMatrix,
+ const uno::Reference< beans::XPropertySet >& xPropSet)
+{
+ /* Get <TransformationInHoriL2R>, if it exist
+ and if the document is exported into the OpenOffice.org file format.
+ This property only exists at service css::text::Shape - the
+ Writer UNO service for shapes.
+ This code is needed, because the positioning attributes in the
+ OpenOffice.org file format are given in horizontal left-to-right layout
+ regardless the layout direction the shape is in. In the OASIS Open Office
+ file format the positioning attributes are correctly given in the layout
+ direction the shape is in. Thus, this code provides the conversion from
+ the OASIS Open Office file format to the OpenOffice.org file format. (#i28749#)
+ */
+ uno::Any aAny;
+ if ( !( GetExport().getExportFlags() & SvXMLExportFlags::OASIS ) &&
+ xPropSet->getPropertySetInfo()->hasPropertyByName("TransformationInHoriL2R") )
+ {
+ aAny = xPropSet->getPropertyValue("TransformationInHoriL2R");
+ }
+ else
+ {
+ aAny = xPropSet->getPropertyValue("Transformation");
+ }
+ drawing::HomogenMatrix3 aMatrix;
+ aAny >>= aMatrix;
+
+ rMatrix.set(0, 0, aMatrix.Line1.Column1);
+ rMatrix.set(0, 1, aMatrix.Line1.Column2);
+ rMatrix.set(0, 2, aMatrix.Line1.Column3);
+ rMatrix.set(1, 0, aMatrix.Line2.Column1);
+ rMatrix.set(1, 1, aMatrix.Line2.Column2);
+ rMatrix.set(1, 2, aMatrix.Line2.Column3);
+ // For this to be a valid 2D transform matrix, the last row must be [0,0,1]
+ assert( aMatrix.Line3.Column1 == 0 );
+ assert( aMatrix.Line3.Column2 == 0 );
+ assert( aMatrix.Line3.Column3 == 1 );
+}
+
+void XMLShapeExport::ImpExportNewTrans_DecomposeAndRefPoint(const ::basegfx::B2DHomMatrix& rMatrix, ::basegfx::B2DTuple& rTRScale,
+ double& fTRShear, double& fTRRotate, ::basegfx::B2DTuple& rTRTranslate, css::awt::Point* pRefPoint)
+{
+ // decompose matrix
+ rMatrix.decompose(rTRScale, rTRTranslate, fTRRotate, fTRShear);
+
+ // correct translation about pRefPoint
+ if(pRefPoint)
+ {
+ rTRTranslate -= ::basegfx::B2DTuple(pRefPoint->X, pRefPoint->Y);
+ }
+}
+
+void XMLShapeExport::ImpExportNewTrans_FeaturesAndWrite(::basegfx::B2DTuple const & rTRScale, double fTRShear,
+ double fTRRotate, ::basegfx::B2DTuple const & rTRTranslate, const XMLShapeExportFlags nFeatures)
+{
+ // always write Size (rTRScale) since this statement carries the union
+ // of the object
+ OUString aStr;
+ OUStringBuffer sStringBuffer;
+ ::basegfx::B2DTuple aTRScale(rTRScale);
+
+ // svg: width
+ if(!(nFeatures & XMLShapeExportFlags::WIDTH))
+ {
+ aTRScale.setX(1.0);
+ }
+ else
+ {
+ if( aTRScale.getX() > 0.0 )
+ aTRScale.setX(aTRScale.getX() - 1.0);
+ else if( aTRScale.getX() < 0.0 )
+ aTRScale.setX(aTRScale.getX() + 1.0);
+ }
+
+ mrExport.GetMM100UnitConverter().convertMeasureToXML(sStringBuffer,
+ FRound(aTRScale.getX()));
+ aStr = sStringBuffer.makeStringAndClear();
+ mrExport.AddAttribute(XML_NAMESPACE_SVG, XML_WIDTH, aStr);
+
+ // svg: height
+ if(!(nFeatures & XMLShapeExportFlags::HEIGHT))
+ {
+ aTRScale.setY(1.0);
+ }
+ else
+ {
+ if( aTRScale.getY() > 0.0 )
+ aTRScale.setY(aTRScale.getY() - 1.0);
+ else if( aTRScale.getY() < 0.0 )
+ aTRScale.setY(aTRScale.getY() + 1.0);
+ }
+
+ mrExport.GetMM100UnitConverter().convertMeasureToXML(sStringBuffer,
+ FRound(aTRScale.getY()));
+ aStr = sStringBuffer.makeStringAndClear();
+ mrExport.AddAttribute(XML_NAMESPACE_SVG, XML_HEIGHT, aStr);
+
+ // decide if transformation is necessary
+ bool bTransformationIsNecessary(fTRShear != 0.0 || fTRRotate != 0.0);
+
+ if(bTransformationIsNecessary)
+ {
+ // write transformation, but WITHOUT scale which is exported as size above
+ SdXMLImExTransform2D aTransform;
+
+ aTransform.AddSkewX(atan(fTRShear));
+
+ // #i78696#
+ // fTRRotate is mathematically correct, but due to the error
+ // we export/import it mirrored. Since the API implementation is fixed and
+ // uses the correctly oriented angle, it is necessary for compatibility to
+ // mirror the angle here to stay at the old behaviour. There is a follow-up
+ // task (#i78698#) to fix this in the next ODF FileFormat version
+ aTransform.AddRotate(-fTRRotate);
+
+ aTransform.AddTranslate(rTRTranslate);
+
+ // does transformation need to be exported?
+ if(aTransform.NeedsAction())
+ mrExport.AddAttribute(XML_NAMESPACE_DRAW, XML_TRANSFORM, aTransform.GetExportString(mrExport.GetMM100UnitConverter()));
+ }
+ else
+ {
+ // no shear, no rotate; just add object position to export and we are done
+ if(nFeatures & XMLShapeExportFlags::X)
+ {
+ // svg: x
+ mrExport.GetMM100UnitConverter().convertMeasureToXML(sStringBuffer,
+ FRound(rTRTranslate.getX()));
+ aStr = sStringBuffer.makeStringAndClear();
+ mrExport.AddAttribute(XML_NAMESPACE_SVG, XML_X, aStr);
+ }
+
+ if(nFeatures & XMLShapeExportFlags::Y)
+ {
+ // svg: y
+ mrExport.GetMM100UnitConverter().convertMeasureToXML(sStringBuffer,
+ FRound(rTRTranslate.getY()));
+ aStr = sStringBuffer.makeStringAndClear();
+ mrExport.AddAttribute(XML_NAMESPACE_SVG, XML_Y, aStr);
+ }
+ }
+}
+
+bool XMLShapeExport::ImpExportPresentationAttributes( const uno::Reference< beans::XPropertySet >& xPropSet, const OUString& rClass )
+{
+ bool bIsEmpty = false;
+
+ // write presentation class entry
+ mrExport.AddAttribute(XML_NAMESPACE_PRESENTATION, XML_CLASS, rClass);
+
+ if( xPropSet.is() )
+ {
+ uno::Reference< beans::XPropertySetInfo > xPropSetInfo( xPropSet->getPropertySetInfo() );
+
+
+ // is empty pres. shape?
+ if( xPropSetInfo.is() && xPropSetInfo->hasPropertyByName("IsEmptyPresentationObject"))
+ {
+ xPropSet->getPropertyValue("IsEmptyPresentationObject") >>= bIsEmpty;
+ if( bIsEmpty )
+ mrExport.AddAttribute(XML_NAMESPACE_PRESENTATION, XML_PLACEHOLDER, XML_TRUE);
+ }
+
+ // is user-transformed?
+ if( xPropSetInfo.is() && xPropSetInfo->hasPropertyByName("IsPlaceholderDependent"))
+ {
+ bool bTemp = false;
+ xPropSet->getPropertyValue("IsPlaceholderDependent") >>= bTemp;
+ if(!bTemp)
+ mrExport.AddAttribute(XML_NAMESPACE_PRESENTATION, XML_USER_TRANSFORMED, XML_TRUE);
+ }
+ }
+
+ return bIsEmpty;
+}
+
+void XMLShapeExport::ImpExportText( const uno::Reference< drawing::XShape >& xShape, TextPNS eExtensionNS )
+{
+ if (eExtensionNS == TextPNS::EXTENSION)
+ {
+ if ((mrExport.getSaneDefaultVersion() & SvtSaveOptions::ODFSVER_EXTENDED) == 0)
+ {
+ return; // do not export to ODF 1.1/1.2/1.3
+ }
+ }
+ uno::Reference< text::XText > xText( xShape, uno::UNO_QUERY );
+ if( xText.is() )
+ {
+ uno::Reference< container::XEnumerationAccess > xEnumAccess( xShape, uno::UNO_QUERY );
+ if( xEnumAccess.is() && xEnumAccess->hasElements() )
+ mrExport.GetTextParagraphExport()->exportText( xText, false, true, eExtensionNS );
+ }
+}
+
+namespace {
+
+enum class Found {
+ NONE = 0x0000,
+ CLICKACTION = 0x0001,
+ BOOKMARK = 0x0002,
+ EFFECT = 0x0004,
+ PLAYFULL = 0x0008,
+ VERB = 0x0010,
+ SOUNDURL = 0x0020,
+ SPEED = 0x0040,
+ CLICKEVENTTYPE = 0x0080,
+ MACRO = 0x0100,
+ LIBRARY = 0x0200,
+};
+
+}
+
+namespace o3tl {
+ template<> struct typed_flags<Found> : is_typed_flags<Found, 0x03ff> {};
+}
+
+void XMLShapeExport::ImpExportEvents( const uno::Reference< drawing::XShape >& xShape )
+{
+ uno::Reference< document::XEventsSupplier > xEventsSupplier( xShape, uno::UNO_QUERY );
+ if( !xEventsSupplier.is() )
+ return;
+
+ uno::Reference< container::XNameAccess > xEvents = xEventsSupplier->getEvents();
+ SAL_WARN_IF( !xEvents.is(), "xmloff", "XEventsSupplier::getEvents() returned NULL" );
+ if( !xEvents.is() )
+ return;
+
+ Found nFound = Found::NONE;
+
+ OUString aClickEventType;
+ presentation::ClickAction eClickAction = presentation::ClickAction_NONE;
+ presentation::AnimationEffect eEffect = presentation::AnimationEffect_NONE;
+ presentation::AnimationSpeed eSpeed = presentation::AnimationSpeed_SLOW;
+ OUString aStrSoundURL;
+ bool bPlayFull = false;
+ sal_Int32 nVerb = 0;
+ OUString aStrMacro;
+ OUString aStrLibrary;
+ OUString aStrBookmark;
+
+ uno::Sequence< beans::PropertyValue > aClickProperties;
+ if( xEvents->hasByName( gsOnClick ) && (xEvents->getByName( gsOnClick ) >>= aClickProperties) )
+ {
+ for( const auto& rProperty : std::as_const(aClickProperties) )
+ {
+ if( !( nFound & Found::CLICKEVENTTYPE ) && rProperty.Name == gsEventType )
+ {
+ if( rProperty.Value >>= aClickEventType )
+ nFound |= Found::CLICKEVENTTYPE;
+ }
+ else if( !( nFound & Found::CLICKACTION ) && rProperty.Name == gsClickAction )
+ {
+ if( rProperty.Value >>= eClickAction )
+ nFound |= Found::CLICKACTION;
+ }
+ else if( !( nFound & Found::MACRO ) && ( rProperty.Name == gsMacroName || rProperty.Name == gsScript ) )
+ {
+ if( rProperty.Value >>= aStrMacro )
+ nFound |= Found::MACRO;
+ }
+ else if( !( nFound & Found::LIBRARY ) && rProperty.Name == gsLibrary )
+ {
+ if( rProperty.Value >>= aStrLibrary )
+ nFound |= Found::LIBRARY;
+ }
+ else if( !( nFound & Found::EFFECT ) && rProperty.Name == gsEffect )
+ {
+ if( rProperty.Value >>= eEffect )
+ nFound |= Found::EFFECT;
+ }
+ else if( !( nFound & Found::BOOKMARK ) && rProperty.Name == gsBookmark )
+ {
+ if( rProperty.Value >>= aStrBookmark )
+ nFound |= Found::BOOKMARK;
+ }
+ else if( !( nFound & Found::SPEED ) && rProperty.Name == gsSpeed )
+ {
+ if( rProperty.Value >>= eSpeed )
+ nFound |= Found::SPEED;
+ }
+ else if( !( nFound & Found::SOUNDURL ) && rProperty.Name == gsSoundURL )
+ {
+ if( rProperty.Value >>= aStrSoundURL )
+ nFound |= Found::SOUNDURL;
+ }
+ else if( !( nFound & Found::PLAYFULL ) && rProperty.Name == gsPlayFull )
+ {
+ if( rProperty.Value >>= bPlayFull )
+ nFound |= Found::PLAYFULL;
+ }
+ else if( !( nFound & Found::VERB ) && rProperty.Name == gsVerb )
+ {
+ if( rProperty.Value >>= nVerb )
+ nFound |= Found::VERB;
+ }
+ }
+ }
+
+ // create the XML elements
+
+ if( aClickEventType == gsPresentation )
+ {
+ if( !(nFound & Found::CLICKACTION) || (eClickAction == presentation::ClickAction_NONE) )
+ return;
+
+ SvXMLElementExport aEventsElemt(mrExport, XML_NAMESPACE_OFFICE, XML_EVENT_LISTENERS, true, true);
+
+ enum XMLTokenEnum eStrAction;
+
+ switch( eClickAction )
+ {
+ case presentation::ClickAction_PREVPAGE: eStrAction = XML_PREVIOUS_PAGE; break;
+ case presentation::ClickAction_NEXTPAGE: eStrAction = XML_NEXT_PAGE; break;
+ case presentation::ClickAction_FIRSTPAGE: eStrAction = XML_FIRST_PAGE; break;
+ case presentation::ClickAction_LASTPAGE: eStrAction = XML_LAST_PAGE; break;
+ case presentation::ClickAction_INVISIBLE: eStrAction = XML_HIDE; break;
+ case presentation::ClickAction_STOPPRESENTATION:eStrAction = XML_STOP; break;
+ case presentation::ClickAction_PROGRAM: eStrAction = XML_EXECUTE; break;
+ case presentation::ClickAction_BOOKMARK: eStrAction = XML_SHOW; break;
+ case presentation::ClickAction_DOCUMENT: eStrAction = XML_SHOW; break;
+ case presentation::ClickAction_MACRO: eStrAction = XML_EXECUTE_MACRO; break;
+ case presentation::ClickAction_VERB: eStrAction = XML_VERB; break;
+ case presentation::ClickAction_VANISH: eStrAction = XML_FADE_OUT; break;
+ case presentation::ClickAction_SOUND: eStrAction = XML_SOUND; break;
+ default:
+ OSL_FAIL( "unknown presentation::ClickAction found!" );
+ eStrAction = XML_UNKNOWN;
+ }
+
+ OUString aEventQName(
+ mrExport.GetNamespaceMap().GetQNameByKey(
+ XML_NAMESPACE_DOM, "click" ) );
+ mrExport.AddAttribute( XML_NAMESPACE_SCRIPT, XML_EVENT_NAME, aEventQName );
+ mrExport.AddAttribute( XML_NAMESPACE_PRESENTATION, XML_ACTION, eStrAction );
+
+ if( eClickAction == presentation::ClickAction_VANISH )
+ {
+ if( nFound & Found::EFFECT )
+ {
+ XMLEffect eKind;
+ XMLEffectDirection eDirection;
+ sal_Int16 nStartScale;
+ bool bIn;
+
+ SdXMLImplSetEffect( eEffect, eKind, eDirection, nStartScale, bIn );
+
+ if( eKind != EK_none )
+ {
+ SvXMLUnitConverter::convertEnum( msBuffer, eKind, aXML_AnimationEffect_EnumMap );
+ mrExport.AddAttribute( XML_NAMESPACE_PRESENTATION, XML_EFFECT, msBuffer.makeStringAndClear() );
+ }
+
+ if( eDirection != ED_none )
+ {
+ SvXMLUnitConverter::convertEnum( msBuffer, eDirection, aXML_AnimationDirection_EnumMap );
+ mrExport.AddAttribute( XML_NAMESPACE_PRESENTATION, XML_DIRECTION, msBuffer.makeStringAndClear() );
+ }
+
+ if( nStartScale != -1 )
+ {
+ ::sax::Converter::convertPercent( msBuffer, nStartScale );
+ mrExport.AddAttribute( XML_NAMESPACE_PRESENTATION, XML_START_SCALE, msBuffer.makeStringAndClear() );
+ }
+ }
+
+ if( nFound & Found::SPEED && eEffect != presentation::AnimationEffect_NONE )
+ {
+ if( eSpeed != presentation::AnimationSpeed_MEDIUM )
+ {
+ SvXMLUnitConverter::convertEnum( msBuffer, eSpeed, aXML_AnimationSpeed_EnumMap );
+ mrExport.AddAttribute( XML_NAMESPACE_PRESENTATION, XML_SPEED, msBuffer.makeStringAndClear() );
+ }
+ }
+ }
+
+ if( eClickAction == presentation::ClickAction_PROGRAM ||
+ eClickAction == presentation::ClickAction_BOOKMARK ||
+ eClickAction == presentation::ClickAction_DOCUMENT )
+ {
+ if( eClickAction == presentation::ClickAction_BOOKMARK )
+ msBuffer.append( '#' );
+
+ msBuffer.append( aStrBookmark );
+ mrExport.AddAttribute(XML_NAMESPACE_XLINK, XML_HREF, GetExport().GetRelativeReference(msBuffer.makeStringAndClear()) );
+ mrExport.AddAttribute( XML_NAMESPACE_XLINK, XML_TYPE, XML_SIMPLE );
+ mrExport.AddAttribute( XML_NAMESPACE_XLINK, XML_SHOW, XML_EMBED );
+ mrExport.AddAttribute( XML_NAMESPACE_XLINK, XML_ACTUATE, XML_ONREQUEST );
+ }
+
+ if( ( nFound & Found::VERB ) && eClickAction == presentation::ClickAction_VERB )
+ {
+ msBuffer.append( nVerb );
+ mrExport.AddAttribute(XML_NAMESPACE_PRESENTATION, XML_VERB, msBuffer.makeStringAndClear());
+ }
+
+ SvXMLElementExport aEventElemt(mrExport, XML_NAMESPACE_PRESENTATION, XML_EVENT_LISTENER, true, true);
+
+ if( eClickAction == presentation::ClickAction_VANISH || eClickAction == presentation::ClickAction_SOUND )
+ {
+ if( ( nFound & Found::SOUNDURL ) && !aStrSoundURL.isEmpty() )
+ {
+ mrExport.AddAttribute(XML_NAMESPACE_XLINK, XML_HREF, GetExport().GetRelativeReference(aStrSoundURL) );
+ mrExport.AddAttribute( XML_NAMESPACE_XLINK, XML_TYPE, XML_SIMPLE );
+ mrExport.AddAttribute( XML_NAMESPACE_XLINK, XML_SHOW, XML_NEW );
+ mrExport.AddAttribute( XML_NAMESPACE_XLINK, XML_ACTUATE, XML_ONREQUEST );
+ if( nFound & Found::PLAYFULL && bPlayFull )
+ mrExport.AddAttribute( XML_NAMESPACE_PRESENTATION, XML_PLAY_FULL, XML_TRUE );
+
+ SvXMLElementExport aElem( mrExport, XML_NAMESPACE_PRESENTATION, XML_SOUND, true, true );
+ }
+ }
+ }
+ else if( aClickEventType == gsStarBasic )
+ {
+ if( nFound & Found::MACRO )
+ {
+ SvXMLElementExport aEventsElemt(mrExport, XML_NAMESPACE_OFFICE, XML_EVENT_LISTENERS, true, true);
+
+ mrExport.AddAttribute( XML_NAMESPACE_SCRIPT, XML_LANGUAGE,
+ mrExport.GetNamespaceMap().GetQNameByKey(
+ XML_NAMESPACE_OOO,
+ "starbasic" ) );
+ OUString aEventQName(
+ mrExport.GetNamespaceMap().GetQNameByKey(
+ XML_NAMESPACE_DOM, "click" ) );
+ mrExport.AddAttribute( XML_NAMESPACE_SCRIPT, XML_EVENT_NAME, aEventQName );
+
+ if( nFound & Found::LIBRARY )
+ {
+ const OUString& sLocation( GetXMLToken(
+ (aStrLibrary.equalsIgnoreAsciiCase("StarOffice") ||
+ aStrLibrary.equalsIgnoreAsciiCase("application") ) ? XML_APPLICATION
+ : XML_DOCUMENT ) );
+ mrExport.AddAttribute(XML_NAMESPACE_SCRIPT, XML_MACRO_NAME,
+ sLocation + ":" + aStrMacro);
+ }
+ else
+ {
+ mrExport.AddAttribute( XML_NAMESPACE_SCRIPT, XML_MACRO_NAME, aStrMacro );
+ }
+
+ SvXMLElementExport aEventElemt(mrExport, XML_NAMESPACE_SCRIPT, XML_EVENT_LISTENER, true, true);
+ }
+ }
+ else if( aClickEventType == gsScript )
+ {
+ if( nFound & Found::MACRO )
+ {
+ SvXMLElementExport aEventsElemt(mrExport, XML_NAMESPACE_OFFICE, XML_EVENT_LISTENERS, true, true);
+
+ mrExport.AddAttribute( XML_NAMESPACE_SCRIPT, XML_LANGUAGE, mrExport.GetNamespaceMap().GetQNameByKey(
+ XML_NAMESPACE_OOO, GetXMLToken(XML_SCRIPT) ) );
+ OUString aEventQName(
+ mrExport.GetNamespaceMap().GetQNameByKey(
+ XML_NAMESPACE_DOM, "click" ) );
+ mrExport.AddAttribute( XML_NAMESPACE_SCRIPT, XML_EVENT_NAME, aEventQName );
+ mrExport.AddAttribute( XML_NAMESPACE_XLINK, XML_HREF, aStrMacro );
+ mrExport.AddAttribute( XML_NAMESPACE_XLINK, XML_TYPE, "simple" );
+
+ SvXMLElementExport aEventElemt(mrExport, XML_NAMESPACE_SCRIPT, XML_EVENT_LISTENER, true, true);
+ }
+ }
+}
+
+/** #i68101# export shape Title and Description */
+void XMLShapeExport::ImpExportDescription( const uno::Reference< drawing::XShape >& xShape )
+{
+ try
+ {
+ OUString aTitle;
+ OUString aDescription;
+
+ uno::Reference< beans::XPropertySet > xProps( xShape, uno::UNO_QUERY_THROW );
+ xProps->getPropertyValue("Title") >>= aTitle;
+ xProps->getPropertyValue("Description") >>= aDescription;
+
+ if(!aTitle.isEmpty())
+ {
+ SvXMLElementExport aEventElemt(mrExport, XML_NAMESPACE_SVG, XML_TITLE, true, false);
+ mrExport.Characters( aTitle );
+ }
+
+ if(!aDescription.isEmpty())
+ {
+ SvXMLElementExport aEventElemt(mrExport, XML_NAMESPACE_SVG, XML_DESC, true, false );
+ mrExport.Characters( aDescription );
+ }
+ }
+ catch( uno::Exception& )
+ {
+ DBG_UNHANDLED_EXCEPTION( "xmloff", "exporting Title and/or Description for shape" );
+ }
+}
+
+void XMLShapeExport::ImpExportGroupShape( const uno::Reference< drawing::XShape >& xShape, XMLShapeExportFlags nFeatures, awt::Point* pRefPoint)
+{
+ uno::Reference< drawing::XShapes > xShapes(xShape, uno::UNO_QUERY);
+ if(!(xShapes.is() && xShapes->getCount()))
+ return;
+
+ // write group shape
+ bool bCreateNewline( (nFeatures & XMLShapeExportFlags::NO_WS) == XMLShapeExportFlags::NONE ); // #86116#/#92210#
+ SvXMLElementExport aPGR(mrExport, XML_NAMESPACE_DRAW, XML_G, bCreateNewline, true);
+
+ ImpExportDescription( xShape ); // #i68101#
+ ImpExportEvents( xShape );
+ ImpExportGluePoints( xShape );
+
+ // #89764# if export of position is suppressed for group shape,
+ // positions of contained objects should be written relative to
+ // the upper left edge of the group.
+ awt::Point aUpperLeft;
+
+ if(!(nFeatures & XMLShapeExportFlags::POSITION))
+ {
+ nFeatures |= XMLShapeExportFlags::POSITION;
+ aUpperLeft = xShape->getPosition();
+ pRefPoint = &aUpperLeft;
+ }
+
+ // write members
+ exportShapes( xShapes, nFeatures, pRefPoint );
+}
+
+void XMLShapeExport::ImpExportTextBoxShape(
+ const uno::Reference< drawing::XShape >& xShape,
+ XmlShapeType eShapeType, XMLShapeExportFlags nFeatures, awt::Point* pRefPoint)
+{
+ const uno::Reference< beans::XPropertySet > xPropSet(xShape, uno::UNO_QUERY);
+ if(!xPropSet.is())
+ return;
+
+ // presentation attribute (if presentation)
+ bool bIsPresShape(false);
+ bool bIsEmptyPresObj(false);
+ OUString aStr;
+
+ switch(eShapeType)
+ {
+ case XmlShapeType::PresSubtitleShape:
+ {
+ aStr = GetXMLToken(XML_SUBTITLE);
+ bIsPresShape = true;
+ break;
+ }
+ case XmlShapeType::PresTitleTextShape:
+ {
+ aStr = GetXMLToken(XML_TITLE);
+ bIsPresShape = true;
+ break;
+ }
+ case XmlShapeType::PresOutlinerShape:
+ {
+ aStr = GetXMLToken(XML_PRESENTATION_OUTLINE);
+ bIsPresShape = true;
+ break;
+ }
+ case XmlShapeType::PresNotesShape:
+ {
+ aStr = GetXMLToken(XML_NOTES);
+ bIsPresShape = true;
+ break;
+ }
+ case XmlShapeType::PresHeaderShape:
+ {
+ aStr = GetXMLToken(XML_HEADER);
+ bIsPresShape = true;
+ break;
+ }
+ case XmlShapeType::PresFooterShape:
+ {
+ aStr = GetXMLToken(XML_FOOTER);
+ bIsPresShape = true;
+ break;
+ }
+ case XmlShapeType::PresSlideNumberShape:
+ {
+ aStr = GetXMLToken(XML_PAGE_NUMBER);
+ bIsPresShape = true;
+ break;
+ }
+ case XmlShapeType::PresDateTimeShape:
+ {
+ aStr = GetXMLToken(XML_DATE_TIME);
+ bIsPresShape = true;
+ break;
+ }
+ default:
+ break;
+ }
+
+ // Transformation
+ ImpExportNewTrans(xPropSet, nFeatures, pRefPoint);
+
+ if(bIsPresShape)
+ bIsEmptyPresObj = ImpExportPresentationAttributes( xPropSet, aStr );
+
+ bool bCreateNewline( (nFeatures & XMLShapeExportFlags::NO_WS) == XMLShapeExportFlags::NONE ); // #86116#/#92210#
+ SvXMLElementExport aElem( mrExport, XML_NAMESPACE_DRAW,
+ XML_FRAME, bCreateNewline, true );
+
+ // evtl. corner radius?
+ sal_Int32 nCornerRadius(0);
+ xPropSet->getPropertyValue("CornerRadius") >>= nCornerRadius;
+ if(nCornerRadius)
+ {
+ OUStringBuffer sStringBuffer;
+ mrExport.GetMM100UnitConverter().convertMeasureToXML(sStringBuffer,
+ nCornerRadius);
+ mrExport.AddAttribute(XML_NAMESPACE_DRAW, XML_CORNER_RADIUS, sStringBuffer.makeStringAndClear());
+ }
+
+ {
+ // write text-box
+ SvXMLElementExport aOBJ(mrExport, XML_NAMESPACE_DRAW, XML_TEXT_BOX, true, true);
+ if(!bIsEmptyPresObj)
+ ImpExportText( xShape );
+ }
+
+ ImpExportDescription( xShape ); // #i68101#
+ ImpExportEvents( xShape );
+ ImpExportGluePoints( xShape );
+
+}
+
+void XMLShapeExport::ImpExportRectangleShape(
+ const uno::Reference< drawing::XShape >& xShape,
+ XMLShapeExportFlags nFeatures, css::awt::Point* pRefPoint)
+{
+ const uno::Reference< beans::XPropertySet > xPropSet(xShape, uno::UNO_QUERY);
+ if(!xPropSet.is())
+ return;
+
+ // Transformation
+ ImpExportNewTrans(xPropSet, nFeatures, pRefPoint);
+
+ // evtl. corner radius?
+ sal_Int32 nCornerRadius(0);
+ xPropSet->getPropertyValue("CornerRadius") >>= nCornerRadius;
+ if(nCornerRadius)
+ {
+ OUStringBuffer sStringBuffer;
+ mrExport.GetMM100UnitConverter().convertMeasureToXML(sStringBuffer,
+ nCornerRadius);
+ mrExport.AddAttribute(XML_NAMESPACE_DRAW, XML_CORNER_RADIUS, sStringBuffer.makeStringAndClear());
+ }
+
+ // write rectangle
+ bool bCreateNewline( (nFeatures & XMLShapeExportFlags::NO_WS) == XMLShapeExportFlags::NONE ); // #86116#/#92210#
+ SvXMLElementExport aOBJ(mrExport, XML_NAMESPACE_DRAW, XML_RECT, bCreateNewline, true);
+
+ ImpExportDescription( xShape ); // #i68101#
+ ImpExportEvents( xShape );
+ ImpExportGluePoints( xShape );
+ ImpExportText( xShape );
+}
+
+void XMLShapeExport::ImpExportLineShape(
+ const uno::Reference< drawing::XShape >& xShape,
+ XMLShapeExportFlags nFeatures, awt::Point* pRefPoint)
+{
+ const uno::Reference< beans::XPropertySet > xPropSet(xShape, uno::UNO_QUERY);
+ if(!xPropSet.is())
+ return;
+
+ OUString aStr;
+ OUStringBuffer sStringBuffer;
+ awt::Point aStart(0,0);
+ awt::Point aEnd(1,1);
+
+ // #85920# use 'Geometry' to get the points of the line
+ // since this slot take anchor pos into account.
+
+ // get matrix
+ ::basegfx::B2DHomMatrix aMatrix;
+ ImpExportNewTrans_GetB2DHomMatrix(aMatrix, xPropSet);
+
+ // decompose and correct about pRefPoint
+ ::basegfx::B2DTuple aTRScale;
+ double fTRShear(0.0);
+ double fTRRotate(0.0);
+ ::basegfx::B2DTuple aTRTranslate;
+ ImpExportNewTrans_DecomposeAndRefPoint(aMatrix, aTRScale, fTRShear, fTRRotate, aTRTranslate, pRefPoint);
+
+ // create base position
+ awt::Point aBasePosition(FRound(aTRTranslate.getX()), FRound(aTRTranslate.getY()));
+
+ if (xPropSet->getPropertySetInfo()->hasPropertyByName("Geometry"))
+ {
+ // get the two points
+ uno::Any aAny(xPropSet->getPropertyValue("Geometry"));
+ if (auto pSourcePolyPolygon
+ = o3tl::tryAccess<drawing::PointSequenceSequence>(aAny))
+ {
+ if (pSourcePolyPolygon->getLength() > 0)
+ {
+ const drawing::PointSequence& rInnerSequence = (*pSourcePolyPolygon)[0];
+ if (rInnerSequence.hasElements())
+ {
+ const awt::Point& rPoint = rInnerSequence[0];
+ aStart = awt::Point(rPoint.X + aBasePosition.X, rPoint.Y + aBasePosition.Y);
+ }
+ if (rInnerSequence.getLength() > 1)
+ {
+ const awt::Point& rPoint = rInnerSequence[1];
+ aEnd = awt::Point(rPoint.X + aBasePosition.X, rPoint.Y + aBasePosition.Y);
+ }
+ }
+ }
+ }
+
+ if( nFeatures & XMLShapeExportFlags::X )
+ {
+ // svg: x1
+ mrExport.GetMM100UnitConverter().convertMeasureToXML(sStringBuffer,
+ aStart.X);
+ aStr = sStringBuffer.makeStringAndClear();
+ mrExport.AddAttribute(XML_NAMESPACE_SVG, XML_X1, aStr);
+ }
+ else
+ {
+ aEnd.X -= aStart.X;
+ }
+
+ if( nFeatures & XMLShapeExportFlags::Y )
+ {
+ // svg: y1
+ mrExport.GetMM100UnitConverter().convertMeasureToXML(sStringBuffer,
+ aStart.Y);
+ aStr = sStringBuffer.makeStringAndClear();
+ mrExport.AddAttribute(XML_NAMESPACE_SVG, XML_Y1, aStr);
+ }
+ else
+ {
+ aEnd.Y -= aStart.Y;
+ }
+
+ // svg: x2
+ mrExport.GetMM100UnitConverter().convertMeasureToXML(sStringBuffer,
+ aEnd.X);
+ aStr = sStringBuffer.makeStringAndClear();
+ mrExport.AddAttribute(XML_NAMESPACE_SVG, XML_X2, aStr);
+
+ // svg: y2
+ mrExport.GetMM100UnitConverter().convertMeasureToXML(sStringBuffer,
+ aEnd.Y);
+ aStr = sStringBuffer.makeStringAndClear();
+ mrExport.AddAttribute(XML_NAMESPACE_SVG, XML_Y2, aStr);
+
+ // write line
+ bool bCreateNewline( (nFeatures & XMLShapeExportFlags::NO_WS) == XMLShapeExportFlags::NONE ); // #86116#/#92210#
+ SvXMLElementExport aOBJ(mrExport, XML_NAMESPACE_DRAW, XML_LINE, bCreateNewline, true);
+
+ ImpExportDescription( xShape ); // #i68101#
+ ImpExportEvents( xShape );
+ ImpExportGluePoints( xShape );
+ ImpExportText( xShape );
+
+}
+
+void XMLShapeExport::ImpExportEllipseShape(
+ const uno::Reference< drawing::XShape >& xShape,
+ XMLShapeExportFlags nFeatures, awt::Point* pRefPoint)
+{
+ const uno::Reference< beans::XPropertySet > xPropSet(xShape, uno::UNO_QUERY);
+ if(!xPropSet.is())
+ return;
+
+ // get size to decide between Circle and Ellipse
+ awt::Size aSize = xShape->getSize();
+ sal_Int32 nRx((aSize.Width + 1) / 2);
+ sal_Int32 nRy((aSize.Height + 1) / 2);
+ bool bCircle(nRx == nRy);
+
+ // Transformation
+ ImpExportNewTrans(xPropSet, nFeatures, pRefPoint);
+
+ drawing::CircleKind eKind = drawing::CircleKind_FULL;
+ xPropSet->getPropertyValue("CircleKind") >>= eKind;
+ if( eKind != drawing::CircleKind_FULL )
+ {
+ OUStringBuffer sStringBuffer;
+ sal_Int32 nStartAngle = 0;
+ sal_Int32 nEndAngle = 0;
+ xPropSet->getPropertyValue("CircleStartAngle") >>= nStartAngle;
+ xPropSet->getPropertyValue("CircleEndAngle") >>= nEndAngle;
+
+ const double dStartAngle = nStartAngle / 100.0;
+ const double dEndAngle = nEndAngle / 100.0;
+
+ // export circle kind
+ SvXMLUnitConverter::convertEnum( sStringBuffer, eKind, aXML_CircleKind_EnumMap );
+ mrExport.AddAttribute(XML_NAMESPACE_DRAW, XML_KIND, sStringBuffer.makeStringAndClear() );
+
+ // export start angle
+ ::sax::Converter::convertDouble( sStringBuffer, dStartAngle );
+ mrExport.AddAttribute(XML_NAMESPACE_DRAW, XML_START_ANGLE, sStringBuffer.makeStringAndClear() );
+
+ // export end angle
+ ::sax::Converter::convertDouble( sStringBuffer, dEndAngle );
+ mrExport.AddAttribute(XML_NAMESPACE_DRAW, XML_END_ANGLE, sStringBuffer.makeStringAndClear() );
+ }
+
+ bool bCreateNewline( (nFeatures & XMLShapeExportFlags::NO_WS) == XMLShapeExportFlags::NONE ); // #86116#/#92210#
+
+ // write ellipse or circle
+ SvXMLElementExport aOBJ(mrExport, XML_NAMESPACE_DRAW,
+ bCircle ? XML_CIRCLE : XML_ELLIPSE,
+ bCreateNewline, true);
+
+ ImpExportDescription( xShape ); // #i68101#
+ ImpExportEvents( xShape );
+ ImpExportGluePoints( xShape );
+ ImpExportText( xShape );
+
+}
+
+void XMLShapeExport::ImpExportPolygonShape(
+ const uno::Reference< drawing::XShape >& xShape,
+ XmlShapeType eShapeType, XMLShapeExportFlags nFeatures, awt::Point* pRefPoint)
+{
+ const uno::Reference< beans::XPropertySet > xPropSet(xShape, uno::UNO_QUERY);
+ if(!xPropSet.is())
+ return;
+
+ bool bBezier(eShapeType == XmlShapeType::DrawClosedBezierShape
+ || eShapeType == XmlShapeType::DrawOpenBezierShape);
+
+ // get matrix
+ ::basegfx::B2DHomMatrix aMatrix;
+ ImpExportNewTrans_GetB2DHomMatrix(aMatrix, xPropSet);
+
+ // decompose and correct about pRefPoint
+ ::basegfx::B2DTuple aTRScale;
+ double fTRShear(0.0);
+ double fTRRotate(0.0);
+ ::basegfx::B2DTuple aTRTranslate;
+ ImpExportNewTrans_DecomposeAndRefPoint(aMatrix, aTRScale, fTRShear, fTRRotate, aTRTranslate, pRefPoint);
+
+ // use features and write
+ ImpExportNewTrans_FeaturesAndWrite(aTRScale, fTRShear, fTRRotate, aTRTranslate, nFeatures);
+
+ // create and export ViewBox
+ awt::Size aSize(FRound(aTRScale.getX()), FRound(aTRScale.getY()));
+ SdXMLImExViewBox aViewBox(0, 0, aSize.Width, aSize.Height);
+ mrExport.AddAttribute(XML_NAMESPACE_SVG, XML_VIEWBOX, aViewBox.GetExportString());
+
+ bool bCreateNewline( (nFeatures & XMLShapeExportFlags::NO_WS) == XMLShapeExportFlags::NONE ); // #86116#/#92210#
+
+ // prepare name (with most used)
+ enum ::xmloff::token::XMLTokenEnum eName(XML_PATH);
+
+ uno::Any aAny( xPropSet->getPropertyValue("Geometry") );
+ basegfx::B2DPolyPolygon aPolyPolygon;
+
+ // tdf#145240 the Any can contain PolyPolygonBezierCoords or PointSequenceSequence
+ // (see OWN_ATTR_BASE_GEOMETRY in SvxShapePolyPolygon::getPropertyValueImpl),
+ // so be more flexible in interpreting it. Try to access bezier first:
+ {
+ auto pSourcePolyPolygon = o3tl::tryAccess<drawing::PolyPolygonBezierCoords>(aAny);
+
+ if(pSourcePolyPolygon && pSourcePolyPolygon->Coordinates.getLength())
+ {
+ aPolyPolygon = basegfx::utils::UnoPolyPolygonBezierCoordsToB2DPolyPolygon(*pSourcePolyPolygon);
+ }
+ }
+
+ // if received no data, try to access point sequence second:
+ if(0 == aPolyPolygon.count())
+ {
+ auto pSourcePolyPolygon = o3tl::tryAccess<drawing::PointSequenceSequence>(aAny);
+
+ if(pSourcePolyPolygon)
+ {
+ aPolyPolygon = basegfx::utils::UnoPointSequenceSequenceToB2DPolyPolygon(*pSourcePolyPolygon);
+ }
+ }
+
+ if(aPolyPolygon.count())
+ {
+ if(!bBezier && !aPolyPolygon.areControlPointsUsed() && 1 == aPolyPolygon.count())
+ {
+ // simple polygon shape, can be written as svg:points sequence
+ const basegfx::B2DPolygon& aPolygon(aPolyPolygon.getB2DPolygon(0));
+ const OUString aPointString(basegfx::utils::exportToSvgPoints(aPolygon));
+
+ // write point array
+ mrExport.AddAttribute(XML_NAMESPACE_DRAW, XML_POINTS, aPointString);
+
+ // set name
+ eName = aPolygon.isClosed() ? XML_POLYGON : XML_POLYLINE;
+ }
+ else
+ {
+ // complex polygon shape, write as svg:d
+ const OUString aPolygonString(
+ basegfx::utils::exportToSvgD(
+ aPolyPolygon,
+ true, // bUseRelativeCoordinates
+ false, // bDetectQuadraticBeziers: not used in old, but maybe activated now
+ true)); // bHandleRelativeNextPointCompatible
+
+ // write point array
+ mrExport.AddAttribute(XML_NAMESPACE_SVG, XML_D, aPolygonString);
+ }
+ }
+
+ // write object, but after attributes are added since this call will
+ // consume all of these added attributes and the destructor will close the
+ // scope. Also before text is added; this may add sub-scopes as needed
+ SvXMLElementExport aOBJ(
+ mrExport,
+ XML_NAMESPACE_DRAW,
+ eName,
+ bCreateNewline,
+ true);
+
+ ImpExportDescription( xShape ); // #i68101#
+ ImpExportEvents( xShape );
+ ImpExportGluePoints( xShape );
+ ImpExportText( xShape );
+
+}
+
+namespace
+{
+
+OUString getNameFromStreamURL(std::u16string_view rURL)
+{
+ static constexpr std::u16string_view sPackageURL(u"vnd.sun.star.Package:");
+
+ OUString sResult;
+
+ if (o3tl::starts_with(rURL, sPackageURL))
+ {
+ std::u16string_view sRequestedName = rURL.substr(sPackageURL.size());
+ size_t nLastIndex = sRequestedName.rfind('/') + 1;
+ if ((nLastIndex > 0) && (nLastIndex < sRequestedName.size()))
+ sRequestedName = sRequestedName.substr(nLastIndex);
+ nLastIndex = sRequestedName.rfind('.');
+ if (nLastIndex != std::u16string_view::npos)
+ sRequestedName = sRequestedName.substr(0, nLastIndex);
+ if (!sRequestedName.empty())
+ sResult = sRequestedName;
+ }
+
+ return sResult;
+}
+
+} // end anonymous namespace
+
+void XMLShapeExport::ImpExportGraphicObjectShape(
+ const uno::Reference< drawing::XShape >& xShape,
+ XmlShapeType eShapeType, XMLShapeExportFlags nFeatures, awt::Point* pRefPoint)
+{
+ const uno::Reference< beans::XPropertySet > xPropSet(xShape, uno::UNO_QUERY);
+ if(!xPropSet.is())
+ return;
+
+ bool bIsEmptyPresObj = false;
+
+ // Transformation
+ ImpExportNewTrans(xPropSet, nFeatures, pRefPoint);
+
+ if(eShapeType == XmlShapeType::PresGraphicObjectShape)
+ bIsEmptyPresObj = ImpExportPresentationAttributes( xPropSet, GetXMLToken(XML_GRAPHIC) );
+
+ bool bCreateNewline( (nFeatures & XMLShapeExportFlags::NO_WS) == XMLShapeExportFlags::NONE ); // #86116#/#92210#
+ SvXMLElementExport aElem( mrExport, XML_NAMESPACE_DRAW,
+ XML_FRAME, bCreateNewline, true );
+
+ if (!bIsEmptyPresObj)
+ {
+ uno::Reference<graphic::XGraphic> xGraphic;
+ OUString sOutMimeType;
+
+ {
+ OUString aStreamURL;
+ xPropSet->getPropertyValue("GraphicStreamURL") >>= aStreamURL;
+ OUString sRequestedName = getNameFromStreamURL(aStreamURL);
+
+ xPropSet->getPropertyValue("Graphic") >>= xGraphic;
+
+ OUString sInternalURL;
+
+ if (xGraphic.is())
+ sInternalURL = mrExport.AddEmbeddedXGraphic(xGraphic, sOutMimeType, sRequestedName);
+
+ if (!sInternalURL.isEmpty())
+ {
+ // apply possible changed stream URL to embedded image object
+ if (!sRequestedName.isEmpty())
+ {
+ OUString newStreamURL = "vnd.sun.star.Package:";
+ if (sInternalURL[0] == '#')
+ {
+ newStreamURL += sInternalURL.subView(1, sInternalURL.getLength() - 1);
+ }
+ else
+ {
+ newStreamURL += sInternalURL;
+ }
+
+ if (newStreamURL != aStreamURL)
+ {
+ xPropSet->setPropertyValue("GraphicStreamURL", uno::Any(newStreamURL));
+ }
+ }
+
+ mrExport.AddAttribute(XML_NAMESPACE_XLINK, XML_HREF, sInternalURL);
+ mrExport.AddAttribute(XML_NAMESPACE_XLINK, XML_TYPE, XML_SIMPLE);
+ mrExport.AddAttribute(XML_NAMESPACE_XLINK, XML_SHOW, XML_EMBED);
+ mrExport.AddAttribute(XML_NAMESPACE_XLINK, XML_ACTUATE, XML_ONLOAD);
+ }
+ }
+
+ {
+ if (GetExport().getSaneDefaultVersion() > SvtSaveOptions::ODFSVER_012)
+ {
+ if (sOutMimeType.isEmpty())
+ {
+ GetExport().GetGraphicMimeTypeFromStream(xGraphic, sOutMimeType);
+ }
+ if (!sOutMimeType.isEmpty())
+ { // ODF 1.3 OFFICE-3943
+ GetExport().AddAttribute(
+ SvtSaveOptions::ODFSVER_013 <= GetExport().getSaneDefaultVersion()
+ ? XML_NAMESPACE_DRAW
+ : XML_NAMESPACE_LO_EXT,
+ "mime-type", sOutMimeType);
+ }
+ }
+
+ SvXMLElementExport aElement(mrExport, XML_NAMESPACE_DRAW, XML_IMAGE, true, true);
+
+ // optional office:binary-data
+ if (xGraphic.is())
+ {
+ mrExport.AddEmbeddedXGraphicAsBase64(xGraphic);
+ }
+ if (!bIsEmptyPresObj)
+ ImpExportText(xShape);
+ }
+
+ //Resolves: fdo#62461 put preferred image first above, followed by
+ //fallback here
+ const bool bAddReplacementImages = officecfg::Office::Common::Save::Graphic::AddReplacementImages::get();
+ if( !bIsEmptyPresObj && bAddReplacementImages)
+ {
+ uno::Reference<graphic::XGraphic> xReplacementGraphic;
+ xPropSet->getPropertyValue("ReplacementGraphic") >>= xReplacementGraphic;
+
+ // If there is no url, then the graphic is empty
+ if (xReplacementGraphic.is())
+ {
+ OUString aMimeType;
+ const OUString aHref = mrExport.AddEmbeddedXGraphic(xReplacementGraphic, aMimeType);
+
+ if (aMimeType.isEmpty())
+ mrExport.GetGraphicMimeTypeFromStream(xReplacementGraphic, aMimeType);
+
+ if (!aHref.isEmpty())
+ {
+ mrExport.AddAttribute(XML_NAMESPACE_XLINK, XML_HREF, aHref);
+ mrExport.AddAttribute(XML_NAMESPACE_XLINK, XML_TYPE, XML_SIMPLE );
+ mrExport.AddAttribute(XML_NAMESPACE_XLINK, XML_SHOW, XML_EMBED );
+ mrExport.AddAttribute(XML_NAMESPACE_XLINK, XML_ACTUATE, XML_ONLOAD );
+ }
+
+ if (!aMimeType.isEmpty() && GetExport().getSaneDefaultVersion() > SvtSaveOptions::ODFSVER_012)
+ { // ODF 1.3 OFFICE-3943
+ mrExport.AddAttribute(
+ SvtSaveOptions::ODFSVER_013 <= GetExport().getSaneDefaultVersion()
+ ? XML_NAMESPACE_DRAW
+ : XML_NAMESPACE_LO_EXT,
+ "mime-type", aMimeType);
+ }
+
+ SvXMLElementExport aElement(mrExport, XML_NAMESPACE_DRAW, XML_IMAGE, true, true);
+
+ // optional office:binary-data
+ mrExport.AddEmbeddedXGraphicAsBase64(xReplacementGraphic);
+ }
+ }
+ }
+
+ ImpExportEvents( xShape );
+ ImpExportGluePoints( xShape );
+
+ // image map
+ GetExport().GetImageMapExport().Export( xPropSet );
+ ImpExportDescription( xShape ); // #i68101#
+
+ // Signature Line, QR Code - needs to be after the images!
+ if (GetExport().getSaneDefaultVersion() & SvtSaveOptions::ODFSVER_EXTENDED)
+ {
+ ImpExportSignatureLine(xShape);
+ ImpExportQRCode(xShape);
+ }
+}
+
+void XMLShapeExport::ImpExportChartShape(
+ const uno::Reference< drawing::XShape >& xShape,
+ XmlShapeType eShapeType, XMLShapeExportFlags nFeatures, awt::Point* pRefPoint,
+ comphelper::AttributeList* pAttrList )
+{
+ ImpExportOLE2Shape( xShape, eShapeType, nFeatures, pRefPoint, pAttrList );
+}
+
+void XMLShapeExport::ImpExportControlShape(
+ const uno::Reference< drawing::XShape >& xShape,
+ XMLShapeExportFlags nFeatures, awt::Point* pRefPoint)
+{
+ const uno::Reference< beans::XPropertySet > xPropSet(xShape, uno::UNO_QUERY);
+ if(xPropSet.is())
+ {
+ // Transformation
+ ImpExportNewTrans(xPropSet, nFeatures, pRefPoint);
+ }
+
+ uno::Reference< drawing::XControlShape > xControl( xShape, uno::UNO_QUERY );
+ SAL_WARN_IF( !xControl.is(), "xmloff", "Control shape is not supporting XControlShape" );
+ if( xControl.is() )
+ {
+ uno::Reference< beans::XPropertySet > xControlModel( xControl->getControl(), uno::UNO_QUERY );
+ SAL_WARN_IF( !xControlModel.is(), "xmloff", "Control shape has not XControlModel" );
+ if( xControlModel.is() )
+ {
+ OUString sControlId = mrExport.GetFormExport()->getControlId( xControlModel );
+ mrExport.AddAttribute( XML_NAMESPACE_DRAW, XML_CONTROL, sControlId );
+ }
+ }
+
+ bool bCreateNewline( (nFeatures & XMLShapeExportFlags::NO_WS) == XMLShapeExportFlags::NONE ); // #86116#/#92210#
+ SvXMLElementExport aOBJ(mrExport, XML_NAMESPACE_DRAW, XML_CONTROL, bCreateNewline, true);
+
+ ImpExportDescription( xShape ); // #i68101#
+}
+
+void XMLShapeExport::ImpExportConnectorShape(
+ const uno::Reference< drawing::XShape >& xShape,
+ XMLShapeExportFlags nFeatures /* = SEF_DEFAULT */, awt::Point* pRefPoint /* = NULL */)
+{
+ uno::Reference< beans::XPropertySet > xProps( xShape, uno::UNO_QUERY );
+
+ OUString aStr;
+ OUStringBuffer sStringBuffer;
+
+ // export connection kind
+ drawing::ConnectorType eType = drawing::ConnectorType_STANDARD;
+ uno::Any aAny = xProps->getPropertyValue("EdgeKind");
+ aAny >>= eType;
+
+ if( eType != drawing::ConnectorType_STANDARD )
+ {
+ SvXMLUnitConverter::convertEnum( sStringBuffer, eType, aXML_ConnectionKind_EnumMap );
+ aStr = sStringBuffer.makeStringAndClear();
+ mrExport.AddAttribute(XML_NAMESPACE_DRAW, XML_TYPE, aStr);
+ }
+
+ // export line skew
+ sal_Int32 nDelta1 = 0, nDelta2 = 0, nDelta3 = 0;
+
+ aAny = xProps->getPropertyValue("EdgeLine1Delta");
+ aAny >>= nDelta1;
+ aAny = xProps->getPropertyValue("EdgeLine2Delta");
+ aAny >>= nDelta2;
+ aAny = xProps->getPropertyValue("EdgeLine3Delta");
+ aAny >>= nDelta3;
+
+ if( nDelta1 != 0 || nDelta2 != 0 || nDelta3 != 0 )
+ {
+ mrExport.GetMM100UnitConverter().convertMeasureToXML(sStringBuffer,
+ nDelta1);
+ if( nDelta2 != 0 || nDelta3 != 0 )
+ {
+ sStringBuffer.append( ' ' );
+ mrExport.GetMM100UnitConverter().convertMeasureToXML(sStringBuffer,
+ nDelta2);
+ if( nDelta3 != 0 )
+ {
+ sStringBuffer.append( ' ' );
+ mrExport.GetMM100UnitConverter().convertMeasureToXML(
+ sStringBuffer, nDelta3);
+ }
+ }
+
+ aStr = sStringBuffer.makeStringAndClear();
+ mrExport.AddAttribute(XML_NAMESPACE_DRAW, XML_LINE_SKEW, aStr);
+ }
+
+ // export start and end point
+ awt::Point aStart(0,0);
+ awt::Point aEnd(1,1);
+
+ /* Get <StartPositionInHoriL2R> and
+ <EndPositionInHoriL2R>, if they exist and if the document is exported
+ into the OpenOffice.org file format.
+ These properties only exist at service css::text::Shape - the
+ Writer UNO service for shapes.
+ This code is needed, because the positioning attributes in the
+ OpenOffice.org file format are given in horizontal left-to-right layout
+ regardless the layout direction the shape is in. In the OASIS Open Office
+ file format the positioning attributes are correctly given in the layout
+ direction the shape is in. Thus, this code provides the conversion from
+ the OASIS Open Office file format to the OpenOffice.org file format. (#i36248#)
+ */
+ if ( !( GetExport().getExportFlags() & SvXMLExportFlags::OASIS ) &&
+ xProps->getPropertySetInfo()->hasPropertyByName("StartPositionInHoriL2R") &&
+ xProps->getPropertySetInfo()->hasPropertyByName("EndPositionInHoriL2R") )
+ {
+ xProps->getPropertyValue("StartPositionInHoriL2R") >>= aStart;
+ xProps->getPropertyValue("EndPositionInHoriL2R") >>= aEnd;
+ }
+ else
+ {
+ xProps->getPropertyValue("StartPosition") >>= aStart;
+ xProps->getPropertyValue("EndPosition") >>= aEnd;
+ }
+
+ if( pRefPoint )
+ {
+ aStart.X -= pRefPoint->X;
+ aStart.Y -= pRefPoint->Y;
+ aEnd.X -= pRefPoint->X;
+ aEnd.Y -= pRefPoint->Y;
+ }
+
+ if( nFeatures & XMLShapeExportFlags::X )
+ {
+ // svg: x1
+ mrExport.GetMM100UnitConverter().convertMeasureToXML(sStringBuffer,
+ aStart.X);
+ aStr = sStringBuffer.makeStringAndClear();
+ mrExport.AddAttribute(XML_NAMESPACE_SVG, XML_X1, aStr);
+ }
+ else
+ {
+ aEnd.X -= aStart.X;
+ }
+
+ if( nFeatures & XMLShapeExportFlags::Y )
+ {
+ // svg: y1
+ mrExport.GetMM100UnitConverter().convertMeasureToXML(sStringBuffer,
+ aStart.Y);
+ aStr = sStringBuffer.makeStringAndClear();
+ mrExport.AddAttribute(XML_NAMESPACE_SVG, XML_Y1, aStr);
+ }
+ else
+ {
+ aEnd.Y -= aStart.Y;
+ }
+
+ // svg: x2
+ mrExport.GetMM100UnitConverter().convertMeasureToXML(sStringBuffer, aEnd.X);
+ aStr = sStringBuffer.makeStringAndClear();
+ mrExport.AddAttribute(XML_NAMESPACE_SVG, XML_X2, aStr);
+
+ // svg: y2
+ mrExport.GetMM100UnitConverter().convertMeasureToXML(sStringBuffer, aEnd.Y);
+ aStr = sStringBuffer.makeStringAndClear();
+ mrExport.AddAttribute(XML_NAMESPACE_SVG, XML_Y2, aStr);
+
+ // #i39320#
+ uno::Reference< uno::XInterface > xRefS;
+ uno::Reference< uno::XInterface > xRefE;
+
+ // export start connection
+ xProps->getPropertyValue("StartShape") >>= xRefS;
+ if( xRefS.is() )
+ {
+ const OUString& rShapeId = mrExport.getInterfaceToIdentifierMapper().getIdentifier( xRefS );
+ mrExport.AddAttribute(XML_NAMESPACE_DRAW, XML_START_SHAPE, rShapeId);
+
+ aAny = xProps->getPropertyValue("StartGluePointIndex");
+ sal_Int32 nGluePointId = 0;
+ if( aAny >>= nGluePointId )
+ {
+ if( nGluePointId != -1 )
+ {
+ mrExport.AddAttribute(XML_NAMESPACE_DRAW, XML_START_GLUE_POINT, OUString::number( nGluePointId ));
+ }
+ }
+ }
+
+ // export end connection
+ xProps->getPropertyValue("EndShape") >>= xRefE;
+ if( xRefE.is() )
+ {
+ const OUString& rShapeId = mrExport.getInterfaceToIdentifierMapper().getIdentifier( xRefE );
+ mrExport.AddAttribute(XML_NAMESPACE_DRAW, XML_END_SHAPE, rShapeId);
+
+ aAny = xProps->getPropertyValue("EndGluePointIndex");
+ sal_Int32 nGluePointId = 0;
+ if( aAny >>= nGluePointId )
+ {
+ if( nGluePointId != -1 )
+ {
+ mrExport.AddAttribute(XML_NAMESPACE_DRAW, XML_END_GLUE_POINT, OUString::number( nGluePointId ));
+ }
+ }
+ }
+
+ // get PolygonBezier
+ aAny = xProps->getPropertyValue("PolyPolygonBezier");
+ auto pSourcePolyPolygon = o3tl::tryAccess<drawing::PolyPolygonBezierCoords>(aAny);
+ if(pSourcePolyPolygon && pSourcePolyPolygon->Coordinates.getLength())
+ {
+ const basegfx::B2DPolyPolygon aPolyPolygon(
+ basegfx::utils::UnoPolyPolygonBezierCoordsToB2DPolyPolygon(
+ *pSourcePolyPolygon));
+ const OUString aPolygonString(
+ basegfx::utils::exportToSvgD(
+ aPolyPolygon,
+ true, // bUseRelativeCoordinates
+ false, // bDetectQuadraticBeziers: not used in old, but maybe activated now
+ true)); // bHandleRelativeNextPointCompatible
+
+ // write point array
+ mrExport.AddAttribute(XML_NAMESPACE_SVG, XML_D, aPolygonString);
+ }
+
+ // get matrix
+ ::basegfx::B2DHomMatrix aMatrix;
+ ImpExportNewTrans_GetB2DHomMatrix(aMatrix, xProps);
+
+ // decompose and correct about pRefPoint
+ ::basegfx::B2DTuple aTRScale;
+ double fTRShear(0.0);
+ double fTRRotate(0.0);
+ ::basegfx::B2DTuple aTRTranslate;
+ ImpExportNewTrans_DecomposeAndRefPoint(aMatrix, aTRScale, fTRShear,
+ fTRRotate, aTRTranslate, pRefPoint);
+
+ // fdo#49678: create and export ViewBox
+ awt::Size aSize(FRound(aTRScale.getX()), FRound(aTRScale.getY()));
+ SdXMLImExViewBox aViewBox(0, 0, aSize.Width, aSize.Height);
+ mrExport.AddAttribute(XML_NAMESPACE_SVG, XML_VIEWBOX, aViewBox.GetExportString());
+
+ // write connector shape. Add Export later.
+ bool bCreateNewline( (nFeatures & XMLShapeExportFlags::NO_WS) == XMLShapeExportFlags::NONE ); // #86116#/#92210#
+ SvXMLElementExport aOBJ(mrExport, XML_NAMESPACE_DRAW, XML_CONNECTOR, bCreateNewline, true);
+
+ ImpExportDescription( xShape ); // #i68101#
+ ImpExportEvents( xShape );
+ ImpExportGluePoints( xShape );
+ ImpExportText( xShape );
+}
+
+void XMLShapeExport::ImpExportMeasureShape(
+ const uno::Reference< drawing::XShape >& xShape,
+ XMLShapeExportFlags nFeatures /* = SEF_DEFAULT */, awt::Point const * pRefPoint /* = NULL */)
+{
+ uno::Reference< beans::XPropertySet > xProps( xShape, uno::UNO_QUERY );
+
+ OUString aStr;
+ OUStringBuffer sStringBuffer;
+
+ // export start and end point
+ awt::Point aStart(0,0);
+ awt::Point aEnd(1,1);
+
+ /* Get <StartPositionInHoriL2R> and
+ <EndPositionInHoriL2R>, if they exist and if the document is exported
+ into the OpenOffice.org file format.
+ These properties only exist at service css::text::Shape - the
+ Writer UNO service for shapes.
+ This code is needed, because the positioning attributes in the
+ OpenOffice.org file format are given in horizontal left-to-right layout
+ regardless the layout direction the shape is in. In the OASIS Open Office
+ file format the positioning attributes are correctly given in the layout
+ direction the shape is in. Thus, this code provides the conversion from
+ the OASIS Open Office file format to the OpenOffice.org file format. (#i36248#)
+ */
+ if ( !( GetExport().getExportFlags() & SvXMLExportFlags::OASIS ) &&
+ xProps->getPropertySetInfo()->hasPropertyByName("StartPositionInHoriL2R") &&
+ xProps->getPropertySetInfo()->hasPropertyByName("EndPositionInHoriL2R") )
+ {
+ xProps->getPropertyValue("StartPositionInHoriL2R") >>= aStart;
+ xProps->getPropertyValue("EndPositionInHoriL2R") >>= aEnd;
+ }
+ else
+ {
+ xProps->getPropertyValue("StartPosition") >>= aStart;
+ xProps->getPropertyValue("EndPosition") >>= aEnd;
+ }
+
+ if( pRefPoint )
+ {
+ aStart.X -= pRefPoint->X;
+ aStart.Y -= pRefPoint->Y;
+ aEnd.X -= pRefPoint->X;
+ aEnd.Y -= pRefPoint->Y;
+ }
+
+ if( nFeatures & XMLShapeExportFlags::X )
+ {
+ // svg: x1
+ mrExport.GetMM100UnitConverter().convertMeasureToXML(sStringBuffer,
+ aStart.X);
+ aStr = sStringBuffer.makeStringAndClear();
+ mrExport.AddAttribute(XML_NAMESPACE_SVG, XML_X1, aStr);
+ }
+ else
+ {
+ aEnd.X -= aStart.X;
+ }
+
+ if( nFeatures & XMLShapeExportFlags::Y )
+ {
+ // svg: y1
+ mrExport.GetMM100UnitConverter().convertMeasureToXML(sStringBuffer,
+ aStart.Y);
+ aStr = sStringBuffer.makeStringAndClear();
+ mrExport.AddAttribute(XML_NAMESPACE_SVG, XML_Y1, aStr);
+ }
+ else
+ {
+ aEnd.Y -= aStart.Y;
+ }
+
+ // svg: x2
+ mrExport.GetMM100UnitConverter().convertMeasureToXML(sStringBuffer, aEnd.X);
+ aStr = sStringBuffer.makeStringAndClear();
+ mrExport.AddAttribute(XML_NAMESPACE_SVG, XML_X2, aStr);
+
+ // svg: y2
+ mrExport.GetMM100UnitConverter().convertMeasureToXML(sStringBuffer, aEnd.Y);
+ aStr = sStringBuffer.makeStringAndClear();
+ mrExport.AddAttribute(XML_NAMESPACE_SVG, XML_Y2, aStr);
+
+ // write measure shape
+ bool bCreateNewline( (nFeatures & XMLShapeExportFlags::NO_WS) == XMLShapeExportFlags::NONE ); // #86116#/#92210#
+ SvXMLElementExport aOBJ(mrExport, XML_NAMESPACE_DRAW, XML_MEASURE, bCreateNewline, true);
+
+ ImpExportDescription( xShape ); // #i68101#
+ ImpExportEvents( xShape );
+ ImpExportGluePoints( xShape );
+
+ uno::Reference< text::XText > xText( xShape, uno::UNO_QUERY );
+ if( xText.is() )
+ mrExport.GetTextParagraphExport()->exportText( xText );
+}
+
+void XMLShapeExport::ImpExportOLE2Shape(
+ const uno::Reference< drawing::XShape >& xShape,
+ XmlShapeType eShapeType, XMLShapeExportFlags nFeatures /* = SEF_DEFAULT */, awt::Point* pRefPoint /* = NULL */,
+ comphelper::AttributeList* pAttrList /* = NULL */ )
+{
+ uno::Reference< beans::XPropertySet > xPropSet(xShape, uno::UNO_QUERY);
+ uno::Reference< container::XNamed > xNamed(xShape, uno::UNO_QUERY);
+
+ SAL_WARN_IF( !xPropSet.is() || !xNamed.is(), "xmloff", "ole shape is not implementing needed interfaces");
+ if(!(xPropSet.is() && xNamed.is()))
+ return;
+
+ // Transformation
+ ImpExportNewTrans(xPropSet, nFeatures, pRefPoint);
+
+ bool bIsEmptyPresObj = false;
+
+ // presentation settings
+ if(eShapeType == XmlShapeType::PresOLE2Shape)
+ bIsEmptyPresObj = ImpExportPresentationAttributes( xPropSet, GetXMLToken(XML_OBJECT) );
+ else if(eShapeType == XmlShapeType::PresChartShape)
+ bIsEmptyPresObj = ImpExportPresentationAttributes( xPropSet, GetXMLToken(XML_CHART) );
+ else if(eShapeType == XmlShapeType::PresSheetShape)
+ bIsEmptyPresObj = ImpExportPresentationAttributes( xPropSet, GetXMLToken(XML_TABLE) );
+
+ bool bCreateNewline( (nFeatures & XMLShapeExportFlags::NO_WS) == XMLShapeExportFlags::NONE ); // #86116#/#92210#
+ bool bExportEmbedded(mrExport.getExportFlags() & SvXMLExportFlags::EMBEDDED);
+ OUString sPersistName;
+ SvXMLElementExport aElement( mrExport, XML_NAMESPACE_DRAW,
+ XML_FRAME, bCreateNewline, true );
+
+ if (!bIsEmptyPresObj)
+ {
+ if (pAttrList)
+ {
+ mrExport.AddAttributeList(pAttrList);
+ }
+
+ OUString sClassId;
+ OUString sURL;
+ bool bInternal = false;
+ xPropSet->getPropertyValue("IsInternal") >>= bInternal;
+
+ {
+
+ if ( bInternal )
+ {
+ // OOo internal links have no storage persistence, URL is stored in the XML file
+ // the result LinkURL is empty in case the object is not a link
+ xPropSet->getPropertyValue("LinkURL") >>= sURL;
+ }
+
+ xPropSet->getPropertyValue("PersistName") >>= sPersistName;
+ if ( sURL.isEmpty() )
+ {
+ if( !sPersistName.isEmpty() )
+ {
+ sURL = "vnd.sun.star.EmbeddedObject:" + sPersistName;
+ }
+ }
+
+ if( !bInternal )
+ xPropSet->getPropertyValue("CLSID") >>= sClassId;
+
+ if( !sClassId.isEmpty() )
+ mrExport.AddAttribute(XML_NAMESPACE_DRAW, XML_CLASS_ID, sClassId );
+
+ if(!bExportEmbedded)
+ {
+ // xlink:href
+ if( !sURL.isEmpty() )
+ {
+ // #96717# in theorie, if we don't have a URL we shouldn't even
+ // export this OLE shape. But practically it's too risky right now
+ // to change this so we better dispose this on load
+ sURL = mrExport.AddEmbeddedObject( sURL );
+
+ mrExport.AddAttribute(XML_NAMESPACE_XLINK, XML_HREF, sURL );
+ mrExport.AddAttribute( XML_NAMESPACE_XLINK, XML_TYPE, XML_SIMPLE );
+ mrExport.AddAttribute( XML_NAMESPACE_XLINK, XML_SHOW, XML_EMBED );
+ mrExport.AddAttribute( XML_NAMESPACE_XLINK, XML_ACTUATE, XML_ONLOAD );
+ }
+ else
+ {
+ // tdf#153179 Export the preview graphic of the object if the object is missing.
+ uno::Reference<graphic::XGraphic> xGraphic;
+ xPropSet->getPropertyValue("Graphic") >>= xGraphic;
+
+ if (xGraphic.is())
+ {
+ OUString aMimeType;
+ const OUString aHref = mrExport.AddEmbeddedXGraphic(xGraphic, aMimeType);
+
+ if (aMimeType.isEmpty())
+ mrExport.GetGraphicMimeTypeFromStream(xGraphic, aMimeType);
+
+ if (!aHref.isEmpty())
+ {
+ mrExport.AddAttribute(XML_NAMESPACE_XLINK, XML_HREF, aHref);
+ mrExport.AddAttribute(XML_NAMESPACE_XLINK, XML_TYPE, XML_SIMPLE);
+ mrExport.AddAttribute(XML_NAMESPACE_XLINK, XML_SHOW, XML_EMBED);
+ mrExport.AddAttribute(XML_NAMESPACE_XLINK, XML_ACTUATE, XML_ONLOAD);
+ }
+
+ if (!aMimeType.isEmpty()
+ && GetExport().getSaneDefaultVersion() > SvtSaveOptions::ODFSVER_012)
+ { // ODF 1.3 OFFICE-3943
+ mrExport.AddAttribute(SvtSaveOptions::ODFSVER_013
+ <= GetExport().getSaneDefaultVersion()
+ ? XML_NAMESPACE_DRAW
+ : XML_NAMESPACE_LO_EXT,
+ "mime-type", aMimeType);
+ }
+
+ SvXMLElementExport aImageElem(mrExport, XML_NAMESPACE_DRAW, XML_IMAGE, true,
+ true);
+
+ // optional office:binary-data
+ mrExport.AddEmbeddedXGraphicAsBase64(xGraphic);
+
+ ImpExportEvents(xShape);
+ ImpExportGluePoints(xShape);
+ ImpExportDescription(xShape);
+
+ return;
+ }
+ }
+ }
+ }
+
+ enum XMLTokenEnum eElem = sClassId.isEmpty() ? XML_OBJECT : XML_OBJECT_OLE ;
+ SvXMLElementExport aElem( mrExport, XML_NAMESPACE_DRAW, eElem, true, true );
+
+ // tdf#112547 export text as child of draw:object, where import expects it
+ if (!bIsEmptyPresObj && supportsText(eShapeType))
+ {
+ // #i118485# Add text export, the draw OLE shape allows text now
+ ImpExportText( xShape, TextPNS::EXTENSION );
+ }
+
+ if(bExportEmbedded && !bIsEmptyPresObj)
+ {
+ if(bInternal)
+ {
+ // embedded XML
+ uno::Reference< lang::XComponent > xComp;
+ xPropSet->getPropertyValue("Model") >>= xComp;
+ SAL_WARN_IF( !xComp.is(), "xmloff", "no xModel for own OLE format" );
+ mrExport.ExportEmbeddedOwnObject( xComp );
+ }
+ else
+ {
+ // embed as Base64
+ // this is an alien object ( currently MSOLE is the only supported type of such objects )
+ // in case it is not an OASIS format the object should be asked to store replacement image if possible
+
+ OUString sURLRequest( sURL );
+ if ( !( mrExport.getExportFlags() & SvXMLExportFlags::OASIS ) )
+ sURLRequest += "?oasis=false";
+ mrExport.AddEmbeddedObjectAsBase64( sURLRequest );
+ }
+ }
+ }
+ if( !bIsEmptyPresObj )
+ {
+ OUString sURL = XML_EMBEDDEDOBJECTGRAPHIC_URL_BASE + sPersistName;
+ if( !bExportEmbedded )
+ {
+ sURL = GetExport().AddEmbeddedObject( sURL );
+ mrExport.AddAttribute(XML_NAMESPACE_XLINK, XML_HREF, sURL );
+ mrExport.AddAttribute( XML_NAMESPACE_XLINK, XML_TYPE, XML_SIMPLE );
+ mrExport.AddAttribute( XML_NAMESPACE_XLINK, XML_SHOW, XML_EMBED );
+ mrExport.AddAttribute( XML_NAMESPACE_XLINK, XML_ACTUATE, XML_ONLOAD );
+ }
+
+ SvXMLElementExport aElem( GetExport(), XML_NAMESPACE_DRAW,
+ XML_IMAGE, false, true );
+
+ if( bExportEmbedded )
+ GetExport().AddEmbeddedObjectAsBase64( sURL );
+ }
+
+ ImpExportEvents( xShape );
+ ImpExportGluePoints( xShape );
+ ImpExportDescription( xShape ); // #i68101#
+
+}
+
+void XMLShapeExport::ImpExportPageShape(
+ const uno::Reference< drawing::XShape >& xShape,
+ XmlShapeType eShapeType, XMLShapeExportFlags nFeatures /* = SEF_DEFAULT */, awt::Point* pRefPoint /* = NULL */)
+{
+ const uno::Reference< beans::XPropertySet > xPropSet(xShape, uno::UNO_QUERY);
+ if(!xPropSet.is())
+ return;
+
+ // #86163# Transformation
+ ImpExportNewTrans(xPropSet, nFeatures, pRefPoint);
+
+ // export page number used for this page
+ uno::Reference< beans::XPropertySetInfo > xPropSetInfo( xPropSet->getPropertySetInfo() );
+ static constexpr OUString aPageNumberStr(u"PageNumber"_ustr);
+ if( xPropSetInfo.is() && xPropSetInfo->hasPropertyByName(aPageNumberStr))
+ {
+ sal_Int32 nPageNumber = 0;
+ xPropSet->getPropertyValue(aPageNumberStr) >>= nPageNumber;
+ if( nPageNumber )
+ mrExport.AddAttribute(XML_NAMESPACE_DRAW, XML_PAGE_NUMBER, OUString::number(nPageNumber));
+ }
+
+ // a presentation page shape, normally used on notes pages only. If
+ // it is used not as presentation shape, it may have been created with
+ // copy-paste exchange between draw and impress (this IS possible...)
+ if(eShapeType == XmlShapeType::PresPageShape)
+ {
+ mrExport.AddAttribute(XML_NAMESPACE_PRESENTATION, XML_CLASS,
+ XML_PAGE);
+ }
+
+ // write Page shape
+ bool bCreateNewline( (nFeatures & XMLShapeExportFlags::NO_WS) == XMLShapeExportFlags::NONE ); // #86116#/#92210#
+ SvXMLElementExport aOBJ(mrExport, XML_NAMESPACE_DRAW, XML_PAGE_THUMBNAIL, bCreateNewline, true);
+}
+
+void XMLShapeExport::ImpExportCaptionShape(
+ const uno::Reference< drawing::XShape >& xShape,
+ XMLShapeExportFlags nFeatures /* = SEF_DEFAULT */, awt::Point* pRefPoint /* = NULL */)
+{
+ const uno::Reference< beans::XPropertySet > xPropSet(xShape, uno::UNO_QUERY);
+ if(!xPropSet.is())
+ return;
+
+ // Transformation
+ ImpExportNewTrans(xPropSet, nFeatures, pRefPoint);
+
+ // evtl. corner radius?
+ sal_Int32 nCornerRadius(0);
+ xPropSet->getPropertyValue("CornerRadius") >>= nCornerRadius;
+ if(nCornerRadius)
+ {
+ OUStringBuffer sStringBuffer;
+ mrExport.GetMM100UnitConverter().convertMeasureToXML(sStringBuffer,
+ nCornerRadius);
+ mrExport.AddAttribute(XML_NAMESPACE_DRAW, XML_CORNER_RADIUS, sStringBuffer.makeStringAndClear());
+ }
+
+ awt::Point aCaptionPoint;
+ xPropSet->getPropertyValue("CaptionPoint") >>= aCaptionPoint;
+
+ mrExport.GetMM100UnitConverter().convertMeasureToXML(msBuffer,
+ aCaptionPoint.X);
+ mrExport.AddAttribute( XML_NAMESPACE_DRAW, XML_CAPTION_POINT_X, msBuffer.makeStringAndClear() );
+ mrExport.GetMM100UnitConverter().convertMeasureToXML(msBuffer,
+ aCaptionPoint.Y);
+ mrExport.AddAttribute( XML_NAMESPACE_DRAW, XML_CAPTION_POINT_Y, msBuffer.makeStringAndClear() );
+
+ // write Caption shape. Add export later.
+ bool bCreateNewline( (nFeatures & XMLShapeExportFlags::NO_WS) == XMLShapeExportFlags::NONE ); // #86116#/#92210#
+ bool bAnnotation( (nFeatures & XMLShapeExportFlags::ANNOTATION) == XMLShapeExportFlags::ANNOTATION );
+
+ SvXMLElementExport aObj( mrExport,
+ (bAnnotation ? XML_NAMESPACE_OFFICE
+ : XML_NAMESPACE_DRAW),
+ (bAnnotation ? XML_ANNOTATION : XML_CAPTION),
+ bCreateNewline, true );
+
+ ImpExportDescription( xShape ); // #i68101#
+ ImpExportEvents( xShape );
+ ImpExportGluePoints( xShape );
+ if( bAnnotation )
+ mrExport.exportAnnotationMeta( xShape );
+ ImpExportText( xShape );
+
+}
+
+void XMLShapeExport::ImpExportFrameShape(
+ const uno::Reference< drawing::XShape >& xShape,
+ XMLShapeExportFlags nFeatures, css::awt::Point* pRefPoint)
+{
+ const uno::Reference< beans::XPropertySet > xPropSet(xShape, uno::UNO_QUERY);
+ if(!xPropSet.is())
+ return;
+
+ // Transformation
+ ImpExportNewTrans(xPropSet, nFeatures, pRefPoint);
+
+ bool bCreateNewline( (nFeatures & XMLShapeExportFlags::NO_WS) == XMLShapeExportFlags::NONE ); // #86116#/#92210#
+ SvXMLElementExport aElem( mrExport, XML_NAMESPACE_DRAW,
+ XML_FRAME, bCreateNewline, true );
+
+ // export frame url
+ OUString aStr;
+ xPropSet->getPropertyValue("FrameURL") >>= aStr;
+ mrExport.AddAttribute ( XML_NAMESPACE_XLINK, XML_HREF, GetExport().GetRelativeReference(aStr) );
+ mrExport.AddAttribute ( XML_NAMESPACE_XLINK, XML_TYPE, XML_SIMPLE );
+ mrExport.AddAttribute ( XML_NAMESPACE_XLINK, XML_SHOW, XML_EMBED );
+ mrExport.AddAttribute ( XML_NAMESPACE_XLINK, XML_ACTUATE, XML_ONLOAD );
+
+ // export name
+ xPropSet->getPropertyValue("FrameName") >>= aStr;
+ if( !aStr.isEmpty() )
+ mrExport.AddAttribute( XML_NAMESPACE_DRAW, XML_FRAME_NAME, aStr );
+
+ // write floating frame
+ {
+ SvXMLElementExport aOBJ(mrExport, XML_NAMESPACE_DRAW, XML_FLOATING_FRAME, true, true);
+ }
+
+ ImpExportDescription(xShape);
+}
+
+void XMLShapeExport::ImpExportAppletShape(
+ const uno::Reference< drawing::XShape >& xShape,
+ XMLShapeExportFlags nFeatures, css::awt::Point* pRefPoint)
+{
+ const uno::Reference< beans::XPropertySet > xPropSet(xShape, uno::UNO_QUERY);
+ if(!xPropSet.is())
+ return;
+
+ // Transformation
+ ImpExportNewTrans(xPropSet, nFeatures, pRefPoint);
+
+ bool bCreateNewline( (nFeatures & XMLShapeExportFlags::NO_WS) == XMLShapeExportFlags::NONE ); // #86116#/#92210#
+ SvXMLElementExport aElement( mrExport, XML_NAMESPACE_DRAW,
+ XML_FRAME, bCreateNewline, true );
+
+ // export frame url
+ OUString aStr;
+ xPropSet->getPropertyValue("AppletCodeBase") >>= aStr;
+ mrExport.AddAttribute ( XML_NAMESPACE_XLINK, XML_HREF, GetExport().GetRelativeReference(aStr) );
+ mrExport.AddAttribute ( XML_NAMESPACE_XLINK, XML_TYPE, XML_SIMPLE );
+ mrExport.AddAttribute ( XML_NAMESPACE_XLINK, XML_SHOW, XML_EMBED );
+ mrExport.AddAttribute ( XML_NAMESPACE_XLINK, XML_ACTUATE, XML_ONLOAD );
+
+ // export draw:applet-name
+ xPropSet->getPropertyValue("AppletName") >>= aStr;
+ if( !aStr.isEmpty() )
+ mrExport.AddAttribute( XML_NAMESPACE_DRAW, XML_APPLET_NAME, aStr );
+
+ // export draw:code
+ xPropSet->getPropertyValue("AppletCode") >>= aStr;
+ mrExport.AddAttribute( XML_NAMESPACE_DRAW, XML_CODE, aStr );
+
+ // export draw:may-script
+ bool bIsScript = false;
+ xPropSet->getPropertyValue("AppletIsScript") >>= bIsScript;
+ mrExport.AddAttribute( XML_NAMESPACE_DRAW, XML_MAY_SCRIPT, bIsScript ? XML_TRUE : XML_FALSE );
+
+ {
+ // write applet
+ SvXMLElementExport aOBJ(mrExport, XML_NAMESPACE_DRAW, XML_APPLET, true, true);
+
+ // export parameters
+ uno::Sequence< beans::PropertyValue > aCommands;
+ xPropSet->getPropertyValue("AppletCommands") >>= aCommands;
+ for( const auto& rCommand : std::as_const(aCommands) )
+ {
+ rCommand.Value >>= aStr;
+ mrExport.AddAttribute( XML_NAMESPACE_DRAW, XML_NAME, rCommand.Name );
+ mrExport.AddAttribute( XML_NAMESPACE_DRAW, XML_VALUE, aStr );
+ SvXMLElementExport aElem( mrExport, XML_NAMESPACE_DRAW, XML_PARAM, false, true );
+ }
+ }
+
+ ImpExportDescription(xShape);
+}
+
+void XMLShapeExport::ImpExportPluginShape(
+ const uno::Reference< drawing::XShape >& xShape,
+ XMLShapeExportFlags nFeatures, css::awt::Point* pRefPoint)
+{
+ const uno::Reference< beans::XPropertySet > xPropSet(xShape, uno::UNO_QUERY);
+ if(!xPropSet.is())
+ return;
+
+ // Transformation
+ ImpExportNewTrans(xPropSet, nFeatures, pRefPoint);
+
+ bool bCreateNewline( (nFeatures & XMLShapeExportFlags::NO_WS) == XMLShapeExportFlags::NONE ); // #86116#/#92210#
+ SvXMLElementExport aElement( mrExport, XML_NAMESPACE_DRAW,
+ XML_FRAME, bCreateNewline, true );
+
+ // export plugin url
+ OUString aStr;
+ xPropSet->getPropertyValue("PluginURL") >>= aStr;
+ mrExport.AddAttribute ( XML_NAMESPACE_XLINK, XML_HREF, GetExport().GetRelativeReference(aStr) );
+ mrExport.AddAttribute ( XML_NAMESPACE_XLINK, XML_TYPE, XML_SIMPLE );
+ mrExport.AddAttribute ( XML_NAMESPACE_XLINK, XML_SHOW, XML_EMBED );
+ mrExport.AddAttribute ( XML_NAMESPACE_XLINK, XML_ACTUATE, XML_ONLOAD );
+
+ // export mime-type
+ xPropSet->getPropertyValue("PluginMimeType") >>= aStr;
+ if(!aStr.isEmpty())
+ mrExport.AddAttribute( XML_NAMESPACE_DRAW, XML_MIME_TYPE, aStr );
+
+ {
+ // write plugin
+ SvXMLElementExport aOBJ(mrExport, XML_NAMESPACE_DRAW, XML_PLUGIN, true, true);
+
+ // export parameters
+ uno::Sequence< beans::PropertyValue > aCommands;
+ xPropSet->getPropertyValue("PluginCommands") >>= aCommands;
+ for( const auto& rCommand : std::as_const(aCommands) )
+ {
+ rCommand.Value >>= aStr;
+ mrExport.AddAttribute( XML_NAMESPACE_DRAW, XML_NAME, rCommand.Name );
+ mrExport.AddAttribute( XML_NAMESPACE_DRAW, XML_VALUE, aStr );
+ SvXMLElementExport aElem( mrExport, XML_NAMESPACE_DRAW, XML_PARAM, false, true );
+ }
+ }
+
+ ImpExportDescription(xShape);
+}
+
+static void lcl_CopyStream(
+ uno::Reference<io::XInputStream> const& xInStream,
+ uno::Reference<embed::XStorage> const& xTarget,
+ OUString const& rPath, const OUString& rMimeType)
+{
+ ::comphelper::LifecycleProxy proxy;
+ uno::Reference<io::XStream> const xStream(
+ ::comphelper::OStorageHelper::GetStreamAtPackageURL(xTarget, rPath,
+ embed::ElementModes::WRITE | embed::ElementModes::TRUNCATE, proxy));
+ uno::Reference<io::XOutputStream> const xOutStream(
+ (xStream.is()) ? xStream->getOutputStream() : nullptr);
+ if (!xOutStream.is())
+ {
+ SAL_WARN("xmloff", "no output stream");
+ throw uno::Exception("no output stream",nullptr);
+ }
+ uno::Reference< beans::XPropertySet > const xStreamProps(xStream,
+ uno::UNO_QUERY);
+ if (xStreamProps.is()) { // this is NOT supported in FileSystemStorage
+ xStreamProps->setPropertyValue("MediaType",
+ uno::Any(rMimeType));
+ xStreamProps->setPropertyValue( // turn off compression
+ "Compressed",
+ uno::Any(false));
+ }
+ ::comphelper::OStorageHelper::CopyInputToOutput(xInStream, xOutStream);
+ xOutStream->closeOutput();
+ proxy.commitStorages();
+}
+
+static OUString
+lcl_StoreMediaAndGetURL(SvXMLExport & rExport,
+ uno::Reference<beans::XPropertySet> const& xPropSet,
+ OUString const& rURL, const OUString& rMimeType)
+{
+ OUString urlPath;
+ if (rURL.startsWithIgnoreAsciiCase("vnd.sun.star.Package:", &urlPath))
+ {
+ try // video is embedded
+ {
+ uno::Reference<embed::XStorage> const xTarget(
+ rExport.GetTargetStorage(), uno::UNO_SET_THROW);
+ uno::Reference<io::XInputStream> xInStream;
+ xPropSet->getPropertyValue("PrivateStream")
+ >>= xInStream;
+
+ if (!xInStream.is())
+ {
+ SAL_WARN("xmloff", "no input stream");
+ return OUString();
+ }
+
+ lcl_CopyStream(xInStream, xTarget, rURL, rMimeType);
+
+ return urlPath;
+ }
+ catch (uno::Exception const&)
+ {
+ TOOLS_INFO_EXCEPTION("xmloff", "exception while storing embedded media");
+ }
+ return OUString();
+ }
+ else
+ {
+ return rExport.GetRelativeReference(rURL); // linked
+ }
+}
+
+namespace
+{
+void ExportGraphicPreview(const uno::Reference<graphic::XGraphic>& xGraphic, SvXMLExport& rExport, const std::u16string_view& rPrefix, const std::u16string_view& rExtension, const OUString& rMimeType)
+{
+ const bool bExportEmbedded(rExport.getExportFlags() & SvXMLExportFlags::EMBEDDED);
+
+ if( xGraphic.is() ) try
+ {
+ uno::Reference< uno::XComponentContext > xContext = rExport.getComponentContext();
+
+ uno::Reference< embed::XStorage > xPictureStorage;
+ uno::Reference< embed::XStorage > xStorage;
+ uno::Reference< io::XStream > xPictureStream;
+
+ OUString sPictureName;
+ if( bExportEmbedded )
+ {
+ xPictureStream.set( xContext->getServiceManager()->createInstanceWithContext( "com.sun.star.comp.MemoryStream", xContext), uno::UNO_QUERY_THROW );
+ }
+ else
+ {
+ xStorage.set( rExport.GetTargetStorage(), uno::UNO_SET_THROW );
+
+ xPictureStorage.set( xStorage->openStorageElement( "Pictures" , ::embed::ElementModes::READWRITE ), uno::UNO_SET_THROW );
+
+ sal_Int32 nIndex = 0;
+ do
+ {
+ sPictureName = rPrefix + OUString::number( ++nIndex ) + rExtension;
+ }
+ while( xPictureStorage->hasByName( sPictureName ) );
+
+ xPictureStream.set( xPictureStorage->openStreamElement( sPictureName, ::embed::ElementModes::READWRITE ), uno::UNO_SET_THROW );
+ }
+
+ uno::Reference< graphic::XGraphicProvider > xProvider( graphic::GraphicProvider::create(xContext) );
+ uno::Sequence< beans::PropertyValue > aArgs{
+ comphelper::makePropertyValue("MimeType", rMimeType ),
+ comphelper::makePropertyValue("OutputStream", xPictureStream->getOutputStream())
+ };
+ xProvider->storeGraphic( xGraphic, aArgs );
+
+ if( xPictureStorage.is() )
+ {
+ uno::Reference< embed::XTransactedObject > xTrans( xPictureStorage, uno::UNO_QUERY );
+ if( xTrans.is() )
+ xTrans->commit();
+ }
+
+ if( !bExportEmbedded )
+ {
+ OUString sURL = "Pictures/" + sPictureName;
+ rExport.AddAttribute( XML_NAMESPACE_XLINK, XML_HREF, sURL );
+ rExport.AddAttribute( XML_NAMESPACE_XLINK, XML_TYPE, XML_SIMPLE );
+ rExport.AddAttribute( XML_NAMESPACE_XLINK, XML_SHOW, XML_EMBED );
+ rExport.AddAttribute( XML_NAMESPACE_XLINK, XML_ACTUATE, XML_ONLOAD );
+ }
+
+ SvXMLElementExport aElem( rExport, XML_NAMESPACE_DRAW, XML_IMAGE, false, true );
+
+ if( bExportEmbedded )
+ {
+ uno::Reference< io::XSeekableInputStream > xSeekable( xPictureStream, uno::UNO_QUERY_THROW );
+ xSeekable->seek(0);
+
+ XMLBase64Export aBase64Exp( rExport );
+ aBase64Exp.exportOfficeBinaryDataElement( uno::Reference < io::XInputStream >( xPictureStream, uno::UNO_QUERY_THROW ) );
+ }
+ }
+ catch( uno::Exception const & )
+ {
+ DBG_UNHANDLED_EXCEPTION("xmloff.draw");
+ }
+}
+}
+
+void XMLShapeExport::ImpExportMediaShape(
+ const uno::Reference< drawing::XShape >& xShape,
+ XmlShapeType eShapeType, XMLShapeExportFlags nFeatures, css::awt::Point* pRefPoint)
+{
+ const uno::Reference< beans::XPropertySet > xPropSet(xShape, uno::UNO_QUERY);
+ if(!xPropSet.is())
+ return;
+
+ // Transformation
+ ImpExportNewTrans(xPropSet, nFeatures, pRefPoint);
+
+ if(eShapeType == XmlShapeType::PresMediaShape)
+ {
+ (void)ImpExportPresentationAttributes( xPropSet, GetXMLToken(XML_OBJECT) );
+ }
+ bool bCreateNewline( (nFeatures & XMLShapeExportFlags::NO_WS) == XMLShapeExportFlags::NONE ); // #86116#/#92210#
+ SvXMLElementExport aElem( mrExport, XML_NAMESPACE_DRAW,
+ XML_FRAME, bCreateNewline, true );
+
+ // export media url
+ OUString aMediaURL;
+ xPropSet->getPropertyValue("MediaURL") >>= aMediaURL;
+ OUString sMimeType;
+ xPropSet->getPropertyValue("MediaMimeType") >>= sMimeType;
+
+ OUString const persistentURL =
+ lcl_StoreMediaAndGetURL(GetExport(), xPropSet, aMediaURL, sMimeType);
+
+ mrExport.AddAttribute ( XML_NAMESPACE_XLINK, XML_HREF, persistentURL );
+ mrExport.AddAttribute ( XML_NAMESPACE_XLINK, XML_TYPE, XML_SIMPLE );
+ mrExport.AddAttribute ( XML_NAMESPACE_XLINK, XML_SHOW, XML_EMBED );
+ mrExport.AddAttribute ( XML_NAMESPACE_XLINK, XML_ACTUATE, XML_ONLOAD );
+
+ // export mime-type
+ mrExport.AddAttribute( XML_NAMESPACE_DRAW, XML_MIME_TYPE, sMimeType );
+
+ // write plugin
+ auto pPluginOBJ = std::make_unique<SvXMLElementExport>(mrExport, XML_NAMESPACE_DRAW, XML_PLUGIN, !( nFeatures & XMLShapeExportFlags::NO_WS ), true);
+
+ // export parameters
+ static constexpr OUString aFalseStr( u"false"_ustr );
+ static constexpr OUString aTrueStr( u"true"_ustr );
+
+ bool bLoop = false;
+ static constexpr OUString aLoopStr( u"Loop"_ustr );
+ xPropSet->getPropertyValue( aLoopStr ) >>= bLoop;
+ mrExport.AddAttribute( XML_NAMESPACE_DRAW, XML_NAME, aLoopStr );
+ mrExport.AddAttribute( XML_NAMESPACE_DRAW, XML_VALUE, bLoop ? aTrueStr : aFalseStr );
+ delete new SvXMLElementExport( mrExport, XML_NAMESPACE_DRAW, XML_PARAM, false, true );
+
+ bool bMute = false;
+ static constexpr OUString aMuteStr( u"Mute"_ustr );
+ xPropSet->getPropertyValue( aMuteStr ) >>= bMute;
+ mrExport.AddAttribute( XML_NAMESPACE_DRAW, XML_NAME, aMuteStr );
+ mrExport.AddAttribute( XML_NAMESPACE_DRAW, XML_VALUE, bMute ? aTrueStr : aFalseStr );
+ delete new SvXMLElementExport( mrExport, XML_NAMESPACE_DRAW, XML_PARAM, false, true );
+
+ sal_Int16 nVolumeDB = 0;
+ xPropSet->getPropertyValue("VolumeDB") >>= nVolumeDB;
+ mrExport.AddAttribute( XML_NAMESPACE_DRAW, XML_NAME, "VolumeDB" );
+ mrExport.AddAttribute( XML_NAMESPACE_DRAW, XML_VALUE, OUString::number( nVolumeDB ) );
+ delete new SvXMLElementExport( mrExport, XML_NAMESPACE_DRAW, XML_PARAM, false, true );
+
+ media::ZoomLevel eZoom;
+ OUString aZoomValue;
+ xPropSet->getPropertyValue("Zoom") >>= eZoom;
+ switch( eZoom )
+ {
+ case media::ZoomLevel_ZOOM_1_TO_4 : aZoomValue = "25%"; break;
+ case media::ZoomLevel_ZOOM_1_TO_2 : aZoomValue = "50%"; break;
+ case media::ZoomLevel_ORIGINAL : aZoomValue = "100%"; break;
+ case media::ZoomLevel_ZOOM_2_TO_1 : aZoomValue = "200%"; break;
+ case media::ZoomLevel_ZOOM_4_TO_1 : aZoomValue = "400%"; break;
+ case media::ZoomLevel_FIT_TO_WINDOW: aZoomValue = "fit"; break;
+ case media::ZoomLevel_FIT_TO_WINDOW_FIXED_ASPECT: aZoomValue = "fixedfit"; break;
+ case media::ZoomLevel_FULLSCREEN : aZoomValue = "fullscreen"; break;
+
+ default:
+ break;
+ }
+
+ if( !aZoomValue.isEmpty() )
+ {
+ mrExport.AddAttribute( XML_NAMESPACE_DRAW, XML_NAME, "Zoom" );
+ mrExport.AddAttribute( XML_NAMESPACE_DRAW, XML_VALUE, aZoomValue );
+ delete new SvXMLElementExport( mrExport, XML_NAMESPACE_DRAW, XML_PARAM, false, true );
+ }
+
+ pPluginOBJ.reset();
+
+ uno::Reference<graphic::XGraphic> xGraphic;
+ xPropSet->getPropertyValue("Graphic") >>= xGraphic;
+ Graphic aGraphic(xGraphic);
+ if (!aGraphic.IsNone())
+ {
+ // The media has a preview, export it.
+ ExportGraphicPreview(xGraphic, mrExport, u"MediaPreview", u".png", "image/png");
+ }
+
+ ImpExportDescription(xShape);
+}
+
+void XMLShapeExport::ImpExport3DSceneShape( const uno::Reference< drawing::XShape >& xShape, XMLShapeExportFlags nFeatures, awt::Point* pRefPoint)
+{
+ uno::Reference< drawing::XShapes > xShapes(xShape, uno::UNO_QUERY);
+ if(!(xShapes.is() && xShapes->getCount()))
+ return;
+
+ uno::Reference< beans::XPropertySet > xPropSet( xShape, uno::UNO_QUERY );
+ SAL_WARN_IF( !xPropSet.is(), "xmloff", "XMLShapeExport::ImpExport3DSceneShape can't export a scene without a propertyset" );
+ if( !xPropSet.is() )
+ return;
+
+ // Transformation
+ ImpExportNewTrans(xPropSet, nFeatures, pRefPoint);
+
+ // 3d attributes
+ export3DSceneAttributes( xPropSet );
+
+ // write 3DScene shape
+ bool bCreateNewline( (nFeatures & XMLShapeExportFlags::NO_WS) == XMLShapeExportFlags::NONE ); // #86116#/#92210#
+ SvXMLElementExport aOBJ( mrExport, XML_NAMESPACE_DR3D, XML_SCENE, bCreateNewline, true);
+
+ ImpExportDescription( xShape ); // #i68101#
+ ImpExportEvents( xShape );
+
+ // write 3DSceneLights
+ export3DLamps( xPropSet );
+
+ // #89764# if export of position is suppressed for group shape,
+ // positions of contained objects should be written relative to
+ // the upper left edge of the group.
+ awt::Point aUpperLeft;
+
+ if(!(nFeatures & XMLShapeExportFlags::POSITION))
+ {
+ nFeatures |= XMLShapeExportFlags::POSITION;
+ aUpperLeft = xShape->getPosition();
+ pRefPoint = &aUpperLeft;
+ }
+
+ // write members
+ exportShapes( xShapes, nFeatures, pRefPoint );
+}
+
+void XMLShapeExport::ImpExport3DShape(
+ const uno::Reference< drawing::XShape >& xShape,
+ XmlShapeType eShapeType)
+{
+ const uno::Reference< beans::XPropertySet > xPropSet(xShape, uno::UNO_QUERY);
+ if(!xPropSet.is())
+ return;
+
+ OUString aStr;
+ OUStringBuffer sStringBuffer;
+
+ // transformation (UNO_NAME_3D_TRANSFORM_MATRIX == "D3DTransformMatrix")
+ uno::Any aAny = xPropSet->getPropertyValue("D3DTransformMatrix");
+ drawing::HomogenMatrix aHomMat;
+ aAny >>= aHomMat;
+ SdXMLImExTransform3D aTransform;
+ aTransform.AddHomogenMatrix(aHomMat);
+ if(aTransform.NeedsAction())
+ mrExport.AddAttribute(XML_NAMESPACE_DR3D, XML_TRANSFORM, aTransform.GetExportString(mrExport.GetMM100UnitConverter()));
+
+ switch(eShapeType)
+ {
+ case XmlShapeType::Draw3DCubeObject:
+ {
+ // minEdge
+ aAny = xPropSet->getPropertyValue("D3DPosition");
+ drawing::Position3D aPosition3D;
+ aAny >>= aPosition3D;
+ ::basegfx::B3DVector aPos3D(aPosition3D.PositionX, aPosition3D.PositionY, aPosition3D.PositionZ);
+
+ // maxEdge
+ aAny = xPropSet->getPropertyValue("D3DSize");
+ drawing::Direction3D aDirection3D;
+ aAny >>= aDirection3D;
+ ::basegfx::B3DVector aDir3D(aDirection3D.DirectionX, aDirection3D.DirectionY, aDirection3D.DirectionZ);
+
+ // transform maxEdge from distance to pos
+ aDir3D = aPos3D + aDir3D;
+
+ // write minEdge
+ if(aPos3D != ::basegfx::B3DVector(-2500.0, -2500.0, -2500.0)) // write only when not default
+ {
+ SvXMLUnitConverter::convertB3DVector(sStringBuffer, aPos3D);
+ aStr = sStringBuffer.makeStringAndClear();
+ mrExport.AddAttribute(XML_NAMESPACE_DR3D, XML_MIN_EDGE, aStr);
+ }
+
+ // write maxEdge
+ if(aDir3D != ::basegfx::B3DVector(2500.0, 2500.0, 2500.0)) // write only when not default
+ {
+ SvXMLUnitConverter::convertB3DVector(sStringBuffer, aDir3D);
+ aStr = sStringBuffer.makeStringAndClear();
+ mrExport.AddAttribute(XML_NAMESPACE_DR3D, XML_MAX_EDGE, aStr);
+ }
+
+ // write 3DCube shape
+ // #i123542# Do this *after* the attributes are added, else these will be lost since opening
+ // the scope will clear the global attribute list at the exporter
+ SvXMLElementExport aOBJ(mrExport, XML_NAMESPACE_DR3D, XML_CUBE, true, true);
+
+ break;
+ }
+ case XmlShapeType::Draw3DSphereObject:
+ {
+ // Center
+ aAny = xPropSet->getPropertyValue("D3DPosition");
+ drawing::Position3D aPosition3D;
+ aAny >>= aPosition3D;
+ ::basegfx::B3DVector aPos3D(aPosition3D.PositionX, aPosition3D.PositionY, aPosition3D.PositionZ);
+
+ // Size
+ aAny = xPropSet->getPropertyValue("D3DSize");
+ drawing::Direction3D aDirection3D;
+ aAny >>= aDirection3D;
+ ::basegfx::B3DVector aDir3D(aDirection3D.DirectionX, aDirection3D.DirectionY, aDirection3D.DirectionZ);
+
+ // write Center
+ if(aPos3D != ::basegfx::B3DVector(0.0, 0.0, 0.0)) // write only when not default
+ {
+ SvXMLUnitConverter::convertB3DVector(sStringBuffer, aPos3D);
+ aStr = sStringBuffer.makeStringAndClear();
+ mrExport.AddAttribute(XML_NAMESPACE_DR3D, XML_CENTER, aStr);
+ }
+
+ // write Size
+ if(aDir3D != ::basegfx::B3DVector(5000.0, 5000.0, 5000.0)) // write only when not default
+ {
+ SvXMLUnitConverter::convertB3DVector(sStringBuffer, aDir3D);
+ aStr = sStringBuffer.makeStringAndClear();
+ mrExport.AddAttribute(XML_NAMESPACE_DR3D, XML_SIZE, aStr);
+ }
+
+ // write 3DSphere shape
+ // #i123542# Do this *after* the attributes are added, else these will be lost since opening
+ // the scope will clear the global attribute list at the exporter
+ SvXMLElementExport aOBJ(mrExport, XML_NAMESPACE_DR3D, XML_SPHERE, true, true);
+
+ break;
+ }
+ case XmlShapeType::Draw3DLatheObject:
+ case XmlShapeType::Draw3DExtrudeObject:
+ {
+ // write special 3DLathe/3DExtrude attributes, get 3D tools::PolyPolygon as drawing::PolyPolygonShape3D
+ aAny = xPropSet->getPropertyValue("D3DPolyPolygon3D");
+ drawing::PolyPolygonShape3D aUnoPolyPolygon3D;
+ aAny >>= aUnoPolyPolygon3D;
+
+ // convert to 3D PolyPolygon
+ const basegfx::B3DPolyPolygon aPolyPolygon3D(
+ basegfx::utils::UnoPolyPolygonShape3DToB3DPolyPolygon(
+ aUnoPolyPolygon3D));
+
+ // convert to 2D tools::PolyPolygon using identity 3D transformation (just grep X and Y)
+ const basegfx::B3DHomMatrix aB3DHomMatrixFor2DConversion;
+ const basegfx::B2DPolyPolygon aPolyPolygon(
+ basegfx::utils::createB2DPolyPolygonFromB3DPolyPolygon(
+ aPolyPolygon3D,
+ aB3DHomMatrixFor2DConversion));
+
+ // get 2D range of it
+ const basegfx::B2DRange aPolyPolygonRange(aPolyPolygon.getB2DRange());
+
+ // export ViewBox
+ SdXMLImExViewBox aViewBox(
+ aPolyPolygonRange.getMinX(),
+ aPolyPolygonRange.getMinY(),
+ aPolyPolygonRange.getWidth(),
+ aPolyPolygonRange.getHeight());
+
+ mrExport.AddAttribute(XML_NAMESPACE_SVG, XML_VIEWBOX, aViewBox.GetExportString());
+
+ // prepare svg:d string
+ const OUString aPolygonString(
+ basegfx::utils::exportToSvgD(
+ aPolyPolygon,
+ true, // bUseRelativeCoordinates
+ false, // bDetectQuadraticBeziers TTTT: not used in old, but maybe activated now
+ true)); // bHandleRelativeNextPointCompatible
+
+ // write point array
+ mrExport.AddAttribute(XML_NAMESPACE_SVG, XML_D, aPolygonString);
+
+ if(eShapeType == XmlShapeType::Draw3DLatheObject)
+ {
+ // write 3DLathe shape
+ SvXMLElementExport aOBJ(mrExport, XML_NAMESPACE_DR3D, XML_ROTATE, true, true);
+ }
+ else
+ {
+ // write 3DExtrude shape
+ SvXMLElementExport aOBJ(mrExport, XML_NAMESPACE_DR3D, XML_EXTRUDE, true, true);
+ }
+ break;
+ }
+ default:
+ break;
+ }
+}
+
+/** helper for chart that adds all attributes of a 3d scene element to the export */
+void XMLShapeExport::export3DSceneAttributes( const css::uno::Reference< css::beans::XPropertySet >& xPropSet )
+{
+ OUString aStr;
+ OUStringBuffer sStringBuffer;
+
+ // world transformation (UNO_NAME_3D_TRANSFORM_MATRIX == "D3DTransformMatrix")
+ uno::Any aAny = xPropSet->getPropertyValue("D3DTransformMatrix");
+ drawing::HomogenMatrix aHomMat;
+ aAny >>= aHomMat;
+ SdXMLImExTransform3D aTransform;
+ aTransform.AddHomogenMatrix(aHomMat);
+ if(aTransform.NeedsAction())
+ mrExport.AddAttribute(XML_NAMESPACE_DR3D, XML_TRANSFORM, aTransform.GetExportString(mrExport.GetMM100UnitConverter()));
+
+ // VRP, VPN, VUP
+ aAny = xPropSet->getPropertyValue("D3DCameraGeometry");
+ drawing::CameraGeometry aCamGeo;
+ aAny >>= aCamGeo;
+
+ ::basegfx::B3DVector aVRP(aCamGeo.vrp.PositionX, aCamGeo.vrp.PositionY, aCamGeo.vrp.PositionZ);
+ if(aVRP != ::basegfx::B3DVector(0.0, 0.0, 1.0)) // write only when not default
+ {
+ SvXMLUnitConverter::convertB3DVector(sStringBuffer, aVRP);
+ aStr = sStringBuffer.makeStringAndClear();
+ mrExport.AddAttribute(XML_NAMESPACE_DR3D, XML_VRP, aStr);
+ }
+
+ ::basegfx::B3DVector aVPN(aCamGeo.vpn.DirectionX, aCamGeo.vpn.DirectionY, aCamGeo.vpn.DirectionZ);
+ if(aVPN != ::basegfx::B3DVector(0.0, 0.0, 1.0)) // write only when not default
+ {
+ SvXMLUnitConverter::convertB3DVector(sStringBuffer, aVPN);
+ aStr = sStringBuffer.makeStringAndClear();
+ mrExport.AddAttribute(XML_NAMESPACE_DR3D, XML_VPN, aStr);
+ }
+
+ ::basegfx::B3DVector aVUP(aCamGeo.vup.DirectionX, aCamGeo.vup.DirectionY, aCamGeo.vup.DirectionZ);
+ if(aVUP != ::basegfx::B3DVector(0.0, 1.0, 0.0)) // write only when not default
+ {
+ SvXMLUnitConverter::convertB3DVector(sStringBuffer, aVUP);
+ aStr = sStringBuffer.makeStringAndClear();
+ mrExport.AddAttribute(XML_NAMESPACE_DR3D, XML_VUP, aStr);
+ }
+
+ // projection "D3DScenePerspective" drawing::ProjectionMode
+ aAny = xPropSet->getPropertyValue("D3DScenePerspective");
+ drawing::ProjectionMode aPrjMode;
+ aAny >>= aPrjMode;
+ if(aPrjMode == drawing::ProjectionMode_PARALLEL)
+ aStr = GetXMLToken(XML_PARALLEL);
+ else
+ aStr = GetXMLToken(XML_PERSPECTIVE);
+ mrExport.AddAttribute(XML_NAMESPACE_DR3D, XML_PROJECTION, aStr);
+
+ // distance
+ aAny = xPropSet->getPropertyValue("D3DSceneDistance");
+ sal_Int32 nDistance = 0;
+ aAny >>= nDistance;
+ mrExport.GetMM100UnitConverter().convertMeasureToXML(sStringBuffer,
+ nDistance);
+ aStr = sStringBuffer.makeStringAndClear();
+ mrExport.AddAttribute(XML_NAMESPACE_DR3D, XML_DISTANCE, aStr);
+
+ // focalLength
+ aAny = xPropSet->getPropertyValue("D3DSceneFocalLength");
+ sal_Int32 nFocalLength = 0;
+ aAny >>= nFocalLength;
+ mrExport.GetMM100UnitConverter().convertMeasureToXML(sStringBuffer,
+ nFocalLength);
+ aStr = sStringBuffer.makeStringAndClear();
+ mrExport.AddAttribute(XML_NAMESPACE_DR3D, XML_FOCAL_LENGTH, aStr);
+
+ // shadowSlant
+ aAny = xPropSet->getPropertyValue("D3DSceneShadowSlant");
+ sal_Int16 nShadowSlant = 0;
+ aAny >>= nShadowSlant;
+ mrExport.AddAttribute(XML_NAMESPACE_DR3D, XML_SHADOW_SLANT, OUString::number(static_cast<sal_Int32>(nShadowSlant)));
+
+ // shadeMode
+ aAny = xPropSet->getPropertyValue("D3DSceneShadeMode");
+ drawing::ShadeMode aShadeMode;
+ if(aAny >>= aShadeMode)
+ {
+ if(aShadeMode == drawing::ShadeMode_FLAT)
+ aStr = GetXMLToken(XML_FLAT);
+ else if(aShadeMode == drawing::ShadeMode_PHONG)
+ aStr = GetXMLToken(XML_PHONG);
+ else if(aShadeMode == drawing::ShadeMode_SMOOTH)
+ aStr = GetXMLToken(XML_GOURAUD);
+ else
+ aStr = GetXMLToken(XML_DRAFT);
+ }
+ else
+ {
+ // ShadeMode enum not there, write default
+ aStr = GetXMLToken(XML_GOURAUD);
+ }
+ mrExport.AddAttribute(XML_NAMESPACE_DR3D, XML_SHADE_MODE, aStr);
+
+ // ambientColor
+ aAny = xPropSet->getPropertyValue("D3DSceneAmbientColor");
+ sal_Int32 nAmbientColor = 0;
+ aAny >>= nAmbientColor;
+ ::sax::Converter::convertColor(sStringBuffer, nAmbientColor);
+ aStr = sStringBuffer.makeStringAndClear();
+ mrExport.AddAttribute(XML_NAMESPACE_DR3D, XML_AMBIENT_COLOR, aStr);
+
+ // lightingMode
+ aAny = xPropSet->getPropertyValue("D3DSceneTwoSidedLighting");
+ bool bTwoSidedLighting = false;
+ aAny >>= bTwoSidedLighting;
+ ::sax::Converter::convertBool(sStringBuffer, bTwoSidedLighting);
+ aStr = sStringBuffer.makeStringAndClear();
+ mrExport.AddAttribute(XML_NAMESPACE_DR3D, XML_LIGHTING_MODE, aStr);
+}
+
+/** helper for chart that exports all lamps from the propertyset */
+void XMLShapeExport::export3DLamps( const css::uno::Reference< css::beans::XPropertySet >& xPropSet )
+{
+ // write lamps 1..8 as content
+ OUString aStr;
+ OUStringBuffer sStringBuffer;
+
+ static constexpr OUStringLiteral aColorPropName(u"D3DSceneLightColor");
+ static constexpr OUStringLiteral aDirectionPropName(u"D3DSceneLightDirection");
+ static constexpr OUStringLiteral aLightOnPropName(u"D3DSceneLightOn");
+
+ ::basegfx::B3DVector aLightDirection;
+ drawing::Direction3D aLightDir;
+ bool bLightOnOff = false;
+ for(sal_Int32 nLamp = 1; nLamp <= 8; nLamp++)
+ {
+ OUString aIndexStr = OUString::number( nLamp );
+
+ // lightcolor
+ OUString aPropName = aColorPropName + aIndexStr;
+ sal_Int32 nLightColor = 0;
+ xPropSet->getPropertyValue( aPropName ) >>= nLightColor;
+ ::sax::Converter::convertColor(sStringBuffer, nLightColor);
+ aStr = sStringBuffer.makeStringAndClear();
+ mrExport.AddAttribute(XML_NAMESPACE_DR3D, XML_DIFFUSE_COLOR, aStr);
+
+ // lightdirection
+ aPropName = aDirectionPropName + aIndexStr;
+ xPropSet->getPropertyValue(aPropName) >>= aLightDir;
+ aLightDirection = ::basegfx::B3DVector(aLightDir.DirectionX, aLightDir.DirectionY, aLightDir.DirectionZ);
+ SvXMLUnitConverter::convertB3DVector(sStringBuffer, aLightDirection);
+ aStr = sStringBuffer.makeStringAndClear();
+ mrExport.AddAttribute(XML_NAMESPACE_DR3D, XML_DIRECTION, aStr);
+
+ // lighton
+ aPropName = aLightOnPropName + aIndexStr;
+ xPropSet->getPropertyValue(aPropName) >>= bLightOnOff;
+ ::sax::Converter::convertBool(sStringBuffer, bLightOnOff);
+ aStr = sStringBuffer.makeStringAndClear();
+ mrExport.AddAttribute(XML_NAMESPACE_DR3D, XML_ENABLED, aStr);
+
+ // specular
+ mrExport.AddAttribute(XML_NAMESPACE_DR3D, XML_SPECULAR,
+ nLamp == 1 ? XML_TRUE : XML_FALSE);
+
+ // write light entry
+ SvXMLElementExport aOBJ(mrExport, XML_NAMESPACE_DR3D, XML_LIGHT, true, true);
+ }
+}
+
+
+// using namespace css::io;
+// using namespace ::xmloff::EnhancedCustomShapeToken;
+
+
+static void ExportParameter( OUStringBuffer& rStrBuffer, const css::drawing::EnhancedCustomShapeParameter& rParameter )
+{
+ if ( !rStrBuffer.isEmpty() )
+ rStrBuffer.append( ' ' );
+ if ( rParameter.Value.getValueTypeClass() == uno::TypeClass_DOUBLE )
+ {
+ double fNumber = 0.0;
+ rParameter.Value >>= fNumber;
+ ::rtl::math::doubleToUStringBuffer( rStrBuffer, fNumber, rtl_math_StringFormat_Automatic, rtl_math_DecimalPlaces_Max, '.', true );
+ }
+ else
+ {
+ sal_Int32 nValue = 0;
+ rParameter.Value >>= nValue;
+
+ switch( rParameter.Type )
+ {
+ case css::drawing::EnhancedCustomShapeParameterType::EQUATION :
+ {
+ rStrBuffer.append( "?f" + OUString::number( nValue ) );
+ }
+ break;
+
+ case css::drawing::EnhancedCustomShapeParameterType::ADJUSTMENT :
+ {
+ rStrBuffer.append( '$' );
+ rStrBuffer.append( nValue );
+ }
+ break;
+
+ case css::drawing::EnhancedCustomShapeParameterType::BOTTOM :
+ rStrBuffer.append( GetXMLToken( XML_BOTTOM ) ); break;
+ case css::drawing::EnhancedCustomShapeParameterType::RIGHT :
+ rStrBuffer.append( GetXMLToken( XML_RIGHT ) ); break;
+ case css::drawing::EnhancedCustomShapeParameterType::TOP :
+ rStrBuffer.append( GetXMLToken( XML_TOP ) ); break;
+ case css::drawing::EnhancedCustomShapeParameterType::LEFT :
+ rStrBuffer.append( GetXMLToken( XML_LEFT ) ); break;
+ case css::drawing::EnhancedCustomShapeParameterType::XSTRETCH :
+ rStrBuffer.append( GetXMLToken( XML_XSTRETCH ) ); break;
+ case css::drawing::EnhancedCustomShapeParameterType::YSTRETCH :
+ rStrBuffer.append( GetXMLToken( XML_YSTRETCH ) ); break;
+ case css::drawing::EnhancedCustomShapeParameterType::HASSTROKE :
+ rStrBuffer.append( GetXMLToken( XML_HASSTROKE ) ); break;
+ case css::drawing::EnhancedCustomShapeParameterType::HASFILL :
+ rStrBuffer.append( GetXMLToken( XML_HASFILL ) ); break;
+ case css::drawing::EnhancedCustomShapeParameterType::WIDTH :
+ rStrBuffer.append( GetXMLToken( XML_WIDTH ) ); break;
+ case css::drawing::EnhancedCustomShapeParameterType::HEIGHT :
+ rStrBuffer.append( GetXMLToken( XML_HEIGHT ) ); break;
+ case css::drawing::EnhancedCustomShapeParameterType::LOGWIDTH :
+ rStrBuffer.append( GetXMLToken( XML_LOGWIDTH ) ); break;
+ case css::drawing::EnhancedCustomShapeParameterType::LOGHEIGHT :
+ rStrBuffer.append( GetXMLToken( XML_LOGHEIGHT ) ); break;
+ default :
+ rStrBuffer.append( nValue );
+ }
+ }
+}
+
+static void ImpExportEquations( SvXMLExport& rExport, const uno::Sequence< OUString >& rEquations )
+{
+ sal_Int32 i;
+ for ( i = 0; i < rEquations.getLength(); i++ )
+ {
+ OUString aStr= "f" + OUString::number( i );
+ rExport.AddAttribute( XML_NAMESPACE_DRAW, XML_NAME, aStr );
+
+ aStr = rEquations[ i ];
+ sal_Int32 nIndex = 0;
+ do
+ {
+ nIndex = aStr.indexOf( '?', nIndex );
+ if ( nIndex != -1 )
+ {
+ aStr = OUString::Concat(aStr.subView(0, nIndex + 1)) + "f"
+ + aStr.subView(nIndex + 1, aStr.getLength() - nIndex - 1);
+ nIndex++;
+ }
+ } while( nIndex != -1 );
+ rExport.AddAttribute( XML_NAMESPACE_DRAW, XML_FORMULA, aStr );
+ SvXMLElementExport aOBJ( rExport, XML_NAMESPACE_DRAW, XML_EQUATION, true, true );
+ }
+}
+
+static void ImpExportHandles( SvXMLExport& rExport, const uno::Sequence< beans::PropertyValues >& rHandles )
+{
+ if ( !rHandles.hasElements() )
+ return;
+
+ OUString aStr;
+ OUStringBuffer aStrBuffer;
+
+ for ( const uno::Sequence< beans::PropertyValue >& rPropSeq : rHandles )
+ {
+ bool bPosition = false;
+ for ( const beans::PropertyValue& rPropVal : rPropSeq )
+ {
+ switch( EASGet( rPropVal.Name ) )
+ {
+ case EAS_Position :
+ {
+ css::drawing::EnhancedCustomShapeParameterPair aPosition;
+ if ( rPropVal.Value >>= aPosition )
+ {
+ ExportParameter( aStrBuffer, aPosition.First );
+ ExportParameter( aStrBuffer, aPosition.Second );
+ aStr = aStrBuffer.makeStringAndClear();
+ rExport.AddAttribute( XML_NAMESPACE_DRAW, XML_HANDLE_POSITION, aStr );
+ bPosition = true;
+ }
+ }
+ break;
+ case EAS_MirroredX :
+ {
+ bool bMirroredX;
+ if ( rPropVal.Value >>= bMirroredX )
+ rExport.AddAttribute( XML_NAMESPACE_DRAW, XML_HANDLE_MIRROR_HORIZONTAL,
+ bMirroredX ? GetXMLToken( XML_TRUE ) : GetXMLToken( XML_FALSE ) );
+ }
+ break;
+ case EAS_MirroredY :
+ {
+ bool bMirroredY;
+ if ( rPropVal.Value >>= bMirroredY )
+ rExport.AddAttribute( XML_NAMESPACE_DRAW, XML_HANDLE_MIRROR_VERTICAL,
+ bMirroredY ? GetXMLToken( XML_TRUE ) : GetXMLToken( XML_FALSE ) );
+ }
+ break;
+ case EAS_Switched :
+ {
+ bool bSwitched;
+ if ( rPropVal.Value >>= bSwitched )
+ rExport.AddAttribute( XML_NAMESPACE_DRAW, XML_HANDLE_SWITCHED,
+ bSwitched ? GetXMLToken( XML_TRUE ) : GetXMLToken( XML_FALSE ) );
+ }
+ break;
+ case EAS_Polar :
+ {
+ css::drawing::EnhancedCustomShapeParameterPair aPolar;
+ if ( rPropVal.Value >>= aPolar )
+ {
+ ExportParameter( aStrBuffer, aPolar.First );
+ ExportParameter( aStrBuffer, aPolar.Second );
+ aStr = aStrBuffer.makeStringAndClear();
+ rExport.AddAttribute( XML_NAMESPACE_DRAW, XML_HANDLE_POLAR, aStr );
+ }
+ }
+ break;
+ case EAS_RadiusRangeMinimum :
+ {
+ css::drawing::EnhancedCustomShapeParameter aRadiusRangeMinimum;
+ if ( rPropVal.Value >>= aRadiusRangeMinimum )
+ {
+ ExportParameter( aStrBuffer, aRadiusRangeMinimum );
+ aStr = aStrBuffer.makeStringAndClear();
+ rExport.AddAttribute( XML_NAMESPACE_DRAW, XML_HANDLE_RADIUS_RANGE_MINIMUM, aStr );
+ }
+ }
+ break;
+ case EAS_RadiusRangeMaximum :
+ {
+ css::drawing::EnhancedCustomShapeParameter aRadiusRangeMaximum;
+ if ( rPropVal.Value >>= aRadiusRangeMaximum )
+ {
+ ExportParameter( aStrBuffer, aRadiusRangeMaximum );
+ aStr = aStrBuffer.makeStringAndClear();
+ rExport.AddAttribute( XML_NAMESPACE_DRAW, XML_HANDLE_RADIUS_RANGE_MAXIMUM, aStr );
+ }
+ }
+ break;
+ case EAS_RangeXMinimum :
+ {
+ css::drawing::EnhancedCustomShapeParameter aXRangeMinimum;
+ if ( rPropVal.Value >>= aXRangeMinimum )
+ {
+ ExportParameter( aStrBuffer, aXRangeMinimum );
+ aStr = aStrBuffer.makeStringAndClear();
+ rExport.AddAttribute( XML_NAMESPACE_DRAW, XML_HANDLE_RANGE_X_MINIMUM, aStr );
+ }
+ }
+ break;
+ case EAS_RangeXMaximum :
+ {
+ css::drawing::EnhancedCustomShapeParameter aXRangeMaximum;
+ if ( rPropVal.Value >>= aXRangeMaximum )
+ {
+ ExportParameter( aStrBuffer, aXRangeMaximum );
+ aStr = aStrBuffer.makeStringAndClear();
+ rExport.AddAttribute( XML_NAMESPACE_DRAW, XML_HANDLE_RANGE_X_MAXIMUM, aStr );
+ }
+ }
+ break;
+ case EAS_RangeYMinimum :
+ {
+ css::drawing::EnhancedCustomShapeParameter aYRangeMinimum;
+ if ( rPropVal.Value >>= aYRangeMinimum )
+ {
+ ExportParameter( aStrBuffer, aYRangeMinimum );
+ aStr = aStrBuffer.makeStringAndClear();
+ rExport.AddAttribute( XML_NAMESPACE_DRAW, XML_HANDLE_RANGE_Y_MINIMUM, aStr );
+ }
+ }
+ break;
+ case EAS_RangeYMaximum :
+ {
+ css::drawing::EnhancedCustomShapeParameter aYRangeMaximum;
+ if ( rPropVal.Value >>= aYRangeMaximum )
+ {
+ ExportParameter( aStrBuffer, aYRangeMaximum );
+ aStr = aStrBuffer.makeStringAndClear();
+ rExport.AddAttribute( XML_NAMESPACE_DRAW, XML_HANDLE_RANGE_Y_MAXIMUM, aStr );
+ }
+ }
+ break;
+ default:
+ break;
+ }
+ }
+ if ( bPosition )
+ SvXMLElementExport aOBJ( rExport, XML_NAMESPACE_DRAW, XML_HANDLE, true, true );
+ else
+ rExport.ClearAttrList();
+ }
+}
+
+static void ImpExportEnhancedPath( SvXMLExport& rExport,
+ const uno::Sequence< css::drawing::EnhancedCustomShapeParameterPair >& rCoordinates,
+ const uno::Sequence< css::drawing::EnhancedCustomShapeSegment >& rSegments,
+ bool bExtended = false )
+{
+
+ OUString aStr;
+ OUStringBuffer aStrBuffer;
+ bool bNeedExtended = false;
+
+ sal_Int32 i, j, k, l;
+
+ sal_Int32 nCoords = rCoordinates.getLength();
+ sal_Int32 nSegments = rSegments.getLength();
+ bool bSimpleSegments = nSegments == 0;
+ if ( bSimpleSegments )
+ nSegments = 4;
+ for ( j = i = 0; j < nSegments; j++ )
+ {
+ css::drawing::EnhancedCustomShapeSegment aSegment;
+ if ( bSimpleSegments )
+ {
+ // if there are not enough segments we will default them
+ switch( j )
+ {
+ case 0 :
+ {
+ aSegment.Count = 1;
+ aSegment.Command = css::drawing::EnhancedCustomShapeSegmentCommand::MOVETO;
+ }
+ break;
+ case 1 :
+ {
+ aSegment.Count = static_cast<sal_Int16>(std::min( nCoords - 1, sal_Int32(32767) ));
+ aSegment.Command = css::drawing::EnhancedCustomShapeSegmentCommand::LINETO;
+ }
+ break;
+ case 2 :
+ {
+ aSegment.Count = 1;
+ aSegment.Command = css::drawing::EnhancedCustomShapeSegmentCommand::CLOSESUBPATH;
+ }
+ break;
+ case 3 :
+ {
+ aSegment.Count = 1;
+ aSegment.Command = css::drawing::EnhancedCustomShapeSegmentCommand::ENDSUBPATH;
+ }
+ break;
+ }
+ }
+ else
+ aSegment = rSegments[ j ];
+
+ if ( !aStrBuffer.isEmpty() )
+ aStrBuffer.append( ' ' );
+
+ sal_Int32 nParameter = 0;
+ switch( aSegment.Command )
+ {
+ case css::drawing::EnhancedCustomShapeSegmentCommand::CLOSESUBPATH :
+ aStrBuffer.append( 'Z' ); break;
+ case css::drawing::EnhancedCustomShapeSegmentCommand::ENDSUBPATH :
+ aStrBuffer.append( 'N' ); break;
+ case css::drawing::EnhancedCustomShapeSegmentCommand::NOFILL :
+ aStrBuffer.append( 'F' ); break;
+ case css::drawing::EnhancedCustomShapeSegmentCommand::NOSTROKE :
+ aStrBuffer.append( 'S' ); break;
+
+ case css::drawing::EnhancedCustomShapeSegmentCommand::MOVETO :
+ aStrBuffer.append( 'M' ); nParameter = 1; break;
+ case css::drawing::EnhancedCustomShapeSegmentCommand::LINETO :
+ aStrBuffer.append( 'L' ); nParameter = 1; break;
+ case css::drawing::EnhancedCustomShapeSegmentCommand::CURVETO :
+ aStrBuffer.append( 'C' ); nParameter = 3; break;
+ case css::drawing::EnhancedCustomShapeSegmentCommand::ANGLEELLIPSETO :
+ aStrBuffer.append( 'T' ); nParameter = 3; break;
+ case css::drawing::EnhancedCustomShapeSegmentCommand::ANGLEELLIPSE :
+ aStrBuffer.append( 'U' ); nParameter = 3; break;
+ case css::drawing::EnhancedCustomShapeSegmentCommand::ARCTO :
+ aStrBuffer.append( 'A' ); nParameter = 4; break;
+ case css::drawing::EnhancedCustomShapeSegmentCommand::ARC :
+ aStrBuffer.append( 'B' ); nParameter = 4; break;
+ case css::drawing::EnhancedCustomShapeSegmentCommand::CLOCKWISEARCTO :
+ aStrBuffer.append( 'W' ); nParameter = 4; break;
+ case css::drawing::EnhancedCustomShapeSegmentCommand::CLOCKWISEARC :
+ aStrBuffer.append( 'V' ); nParameter = 4; break;
+ case css::drawing::EnhancedCustomShapeSegmentCommand::ELLIPTICALQUADRANTX :
+ aStrBuffer.append( 'X' ); nParameter = 1; break;
+ case css::drawing::EnhancedCustomShapeSegmentCommand::ELLIPTICALQUADRANTY :
+ aStrBuffer.append( 'Y' ); nParameter = 1; break;
+ case css::drawing::EnhancedCustomShapeSegmentCommand::QUADRATICCURVETO :
+ aStrBuffer.append( 'Q' ); nParameter = 2; break;
+ case css::drawing::EnhancedCustomShapeSegmentCommand::ARCANGLETO :
+ if ( bExtended ) {
+ aStrBuffer.append( 'G' );
+ nParameter = 2;
+ } else {
+ aStrBuffer.setLength( aStrBuffer.getLength() - 1);
+ bNeedExtended = true;
+ i += 2;
+ }
+ break;
+ case css::drawing::EnhancedCustomShapeSegmentCommand::DARKEN :
+ if ( bExtended )
+ aStrBuffer.append( 'H' );
+ else
+ bNeedExtended = true;
+ break;
+ case css::drawing::EnhancedCustomShapeSegmentCommand::DARKENLESS :
+ if ( bExtended )
+ aStrBuffer.append( 'I' );
+ else
+ bNeedExtended = true;
+ break;
+ case css::drawing::EnhancedCustomShapeSegmentCommand::LIGHTEN :
+ if ( bExtended )
+ aStrBuffer.append( 'J' );
+ else
+ bNeedExtended = true;
+ break;
+ case css::drawing::EnhancedCustomShapeSegmentCommand::LIGHTENLESS :
+ if ( bExtended )
+ aStrBuffer.append( 'K' );
+ else
+ bNeedExtended = true;
+ break;
+ default : // ups, seems to be something wrong
+ {
+ aSegment.Count = 1;
+ aSegment.Command = css::drawing::EnhancedCustomShapeSegmentCommand::LINETO;
+ }
+ break;
+ }
+ if ( nParameter )
+ {
+ for ( k = 0; k < aSegment.Count; k++ )
+ {
+ if ( ( i + nParameter ) <= nCoords )
+ {
+ for ( l = 0; l < nParameter; l++ )
+ {
+ ExportParameter( aStrBuffer, rCoordinates[ i ].First );
+ ExportParameter( aStrBuffer, rCoordinates[ i++ ].Second );
+ }
+ }
+ else
+ {
+ j = nSegments; // error -> exiting
+ break;
+ }
+ }
+ }
+ }
+ aStr = aStrBuffer.makeStringAndClear();
+ rExport.AddAttribute( bExtended ? XML_NAMESPACE_DRAW_EXT : XML_NAMESPACE_DRAW, XML_ENHANCED_PATH, aStr );
+ if (!bExtended && bNeedExtended && (rExport.getSaneDefaultVersion() & SvtSaveOptions::ODFSVER_EXTENDED))
+ ImpExportEnhancedPath( rExport, rCoordinates, rSegments, true );
+}
+
+static void ImpExportEnhancedGeometry( SvXMLExport& rExport, const uno::Reference< beans::XPropertySet >& xPropSet )
+{
+ bool bEquations = false;
+ uno::Sequence< OUString > aEquations;
+
+ bool bHandles = false;
+ uno::Sequence< beans::PropertyValues > aHandles;
+
+ uno::Sequence< css::drawing::EnhancedCustomShapeSegment > aSegments;
+ uno::Sequence< css::drawing::EnhancedCustomShapeParameterPair > aCoordinates;
+
+ uno::Sequence< css::drawing::EnhancedCustomShapeAdjustmentValue > aAdjustmentValues;
+
+ OUString aStr;
+ OUStringBuffer aStrBuffer;
+ double fTextRotateAngle(0.0);
+ double fTextPreRotateAngle(0.0); // will be consolidated with fTextRotateAngle at the end
+ SvXMLUnitConverter& rUnitConverter = rExport.GetMM100UnitConverter();
+
+ uno::Reference< beans::XPropertySetInfo > xPropSetInfo( xPropSet->getPropertySetInfo() );
+
+ // geometry
+ static constexpr OUString sCustomShapeGeometry( u"CustomShapeGeometry"_ustr );
+ if ( xPropSetInfo.is() && xPropSetInfo->hasPropertyByName( sCustomShapeGeometry ) )
+ {
+ uno::Any aGeoPropSet( xPropSet->getPropertyValue( sCustomShapeGeometry ) );
+ uno::Sequence< beans::PropertyValue > aGeoPropSeq;
+
+ if ( aGeoPropSet >>= aGeoPropSeq )
+ {
+ bool bCoordinates = false;
+ OUString aCustomShapeType( "non-primitive" );
+
+ for ( const beans::PropertyValue& rGeoProp : std::as_const(aGeoPropSeq) )
+ {
+ switch( EASGet( rGeoProp.Name ) )
+ {
+ case EAS_Type :
+ {
+ rGeoProp.Value >>= aCustomShapeType;
+ }
+ break;
+ case EAS_MirroredX :
+ {
+ bool bMirroredX;
+ if ( rGeoProp.Value >>= bMirroredX )
+ rExport.AddAttribute( XML_NAMESPACE_DRAW, XML_MIRROR_HORIZONTAL,
+ bMirroredX ? GetXMLToken( XML_TRUE ) : GetXMLToken( XML_FALSE ) );
+ }
+ break;
+ case EAS_MirroredY :
+ {
+ bool bMirroredY;
+ if ( rGeoProp.Value >>= bMirroredY )
+ rExport.AddAttribute( XML_NAMESPACE_DRAW, XML_MIRROR_VERTICAL,
+ bMirroredY ? GetXMLToken( XML_TRUE ) : GetXMLToken( XML_FALSE ) );
+ }
+ break;
+ case EAS_ViewBox :
+ {
+ awt::Rectangle aRect;
+ if ( rGeoProp.Value >>= aRect )
+ {
+ SdXMLImExViewBox aViewBox( aRect.X, aRect.Y, aRect.Width, aRect.Height );
+ rExport.AddAttribute( XML_NAMESPACE_SVG, XML_VIEWBOX, aViewBox.GetExportString() );
+ }
+ }
+ break;
+ case EAS_TextPreRotateAngle :
+ {
+ rGeoProp.Value >>= fTextPreRotateAngle;
+ }
+ break;
+ case EAS_TextRotateAngle :
+ {
+ rGeoProp.Value >>= fTextRotateAngle;
+ }
+ break;
+ case EAS_Extrusion :
+ {
+ uno::Sequence< beans::PropertyValue > aExtrusionPropSeq;
+ if ( rGeoProp.Value >>= aExtrusionPropSeq )
+ {
+ bool bSkewValuesProvided = false;
+ for ( const beans::PropertyValue& rProp : std::as_const(aExtrusionPropSeq) )
+ {
+ switch( EASGet( rProp.Name ) )
+ {
+ case EAS_Extrusion :
+ {
+ bool bExtrusionOn;
+ if ( rProp.Value >>= bExtrusionOn )
+ rExport.AddAttribute( XML_NAMESPACE_DRAW, XML_EXTRUSION,
+ bExtrusionOn ? GetXMLToken( XML_TRUE ) : GetXMLToken( XML_FALSE ) );
+ }
+ break;
+ case EAS_Brightness :
+ {
+ double fExtrusionBrightness = 0;
+ if ( rProp.Value >>= fExtrusionBrightness )
+ {
+ ::sax::Converter::convertDouble(
+ aStrBuffer,
+ fExtrusionBrightness,
+ false,
+ util::MeasureUnit::PERCENT,
+ util::MeasureUnit::PERCENT);
+ aStrBuffer.append( '%' );
+ aStr = aStrBuffer.makeStringAndClear();
+ rExport.AddAttribute( XML_NAMESPACE_DRAW, XML_EXTRUSION_BRIGHTNESS, aStr );
+ }
+ }
+ break;
+ case EAS_Depth :
+ {
+ css::drawing::EnhancedCustomShapeParameterPair aDepthParaPair;
+ if ( rProp.Value >>= aDepthParaPair )
+ {
+ double fDepth = 0;
+ if ( aDepthParaPair.First.Value >>= fDepth )
+ {
+ rExport.GetMM100UnitConverter().convertDouble( aStrBuffer, fDepth );
+ ExportParameter( aStrBuffer, aDepthParaPair.Second );
+ aStr = aStrBuffer.makeStringAndClear();
+ rExport.AddAttribute( XML_NAMESPACE_DRAW, XML_EXTRUSION_DEPTH, aStr );
+ }
+ }
+ }
+ break;
+ case EAS_Diffusion :
+ {
+ double fExtrusionDiffusion = 0;
+ if ( rProp.Value >>= fExtrusionDiffusion )
+ {
+ ::sax::Converter::convertDouble(
+ aStrBuffer,
+ fExtrusionDiffusion,
+ false,
+ util::MeasureUnit::PERCENT,
+ util::MeasureUnit::PERCENT);
+ aStrBuffer.append( '%' );
+ aStr = aStrBuffer.makeStringAndClear();
+ rExport.AddAttribute( XML_NAMESPACE_DRAW, XML_EXTRUSION_DIFFUSION, aStr );
+ }
+ }
+ break;
+ case EAS_NumberOfLineSegments :
+ {
+ sal_Int32 nExtrusionNumberOfLineSegments = 0;
+ if ( rProp.Value >>= nExtrusionNumberOfLineSegments )
+ rExport.AddAttribute( XML_NAMESPACE_DRAW, XML_EXTRUSION_NUMBER_OF_LINE_SEGMENTS, OUString::number( nExtrusionNumberOfLineSegments ) );
+ }
+ break;
+ case EAS_LightFace :
+ {
+ bool bExtrusionLightFace;
+ if ( rProp.Value >>= bExtrusionLightFace )
+ rExport.AddAttribute( XML_NAMESPACE_DRAW, XML_EXTRUSION_LIGHT_FACE,
+ bExtrusionLightFace ? GetXMLToken( XML_TRUE ) : GetXMLToken( XML_FALSE ) );
+ }
+ break;
+ case EAS_FirstLightHarsh :
+ {
+ bool bExtrusionFirstLightHarsh;
+ if ( rProp.Value >>= bExtrusionFirstLightHarsh )
+ rExport.AddAttribute( XML_NAMESPACE_DRAW, XML_EXTRUSION_FIRST_LIGHT_HARSH,
+ bExtrusionFirstLightHarsh ? GetXMLToken( XML_TRUE ) : GetXMLToken( XML_FALSE ) );
+ }
+ break;
+ case EAS_SecondLightHarsh :
+ {
+ bool bExtrusionSecondLightHarsh;
+ if ( rProp.Value >>= bExtrusionSecondLightHarsh )
+ rExport.AddAttribute( XML_NAMESPACE_DRAW, XML_EXTRUSION_SECOND_LIGHT_HARSH,
+ bExtrusionSecondLightHarsh ? GetXMLToken( XML_TRUE ) : GetXMLToken( XML_FALSE ) );
+ }
+ break;
+ case EAS_FirstLightLevel :
+ {
+ double fExtrusionFirstLightLevel = 0;
+ if ( rProp.Value >>= fExtrusionFirstLightLevel )
+ {
+ ::sax::Converter::convertDouble(
+ aStrBuffer,
+ fExtrusionFirstLightLevel,
+ false,
+ util::MeasureUnit::PERCENT,
+ util::MeasureUnit::PERCENT);
+ aStrBuffer.append( '%' );
+ aStr = aStrBuffer.makeStringAndClear();
+ rExport.AddAttribute( XML_NAMESPACE_DRAW, XML_EXTRUSION_FIRST_LIGHT_LEVEL, aStr );
+ }
+ }
+ break;
+ case EAS_SecondLightLevel :
+ {
+ double fExtrusionSecondLightLevel = 0;
+ if ( rProp.Value >>= fExtrusionSecondLightLevel )
+ {
+ ::sax::Converter::convertDouble(
+ aStrBuffer,
+ fExtrusionSecondLightLevel,
+ false,
+ util::MeasureUnit::PERCENT,
+ util::MeasureUnit::PERCENT);
+ aStrBuffer.append( '%' );
+ aStr = aStrBuffer.makeStringAndClear();
+ rExport.AddAttribute( XML_NAMESPACE_DRAW, XML_EXTRUSION_SECOND_LIGHT_LEVEL, aStr );
+ }
+ }
+ break;
+ case EAS_FirstLightDirection :
+ {
+ drawing::Direction3D aExtrusionFirstLightDirection;
+ if ( rProp.Value >>= aExtrusionFirstLightDirection )
+ {
+ ::basegfx::B3DVector aVec3D( aExtrusionFirstLightDirection.DirectionX, aExtrusionFirstLightDirection.DirectionY,
+ aExtrusionFirstLightDirection.DirectionZ );
+ SvXMLUnitConverter::convertB3DVector( aStrBuffer, aVec3D );
+ aStr = aStrBuffer.makeStringAndClear();
+ rExport.AddAttribute( XML_NAMESPACE_DRAW, XML_EXTRUSION_FIRST_LIGHT_DIRECTION, aStr );
+ }
+ }
+ break;
+ case EAS_SecondLightDirection :
+ {
+ drawing::Direction3D aExtrusionSecondLightDirection;
+ if ( rProp.Value >>= aExtrusionSecondLightDirection )
+ {
+ ::basegfx::B3DVector aVec3D( aExtrusionSecondLightDirection.DirectionX, aExtrusionSecondLightDirection.DirectionY,
+ aExtrusionSecondLightDirection.DirectionZ );
+ SvXMLUnitConverter::convertB3DVector( aStrBuffer, aVec3D );
+ aStr = aStrBuffer.makeStringAndClear();
+ rExport.AddAttribute( XML_NAMESPACE_DRAW, XML_EXTRUSION_SECOND_LIGHT_DIRECTION, aStr );
+ }
+ }
+ break;
+ case EAS_Metal :
+ {
+ bool bExtrusionMetal;
+ if ( rProp.Value >>= bExtrusionMetal )
+ rExport.AddAttribute( XML_NAMESPACE_DRAW, XML_EXTRUSION_METAL,
+ bExtrusionMetal ? GetXMLToken( XML_TRUE ) : GetXMLToken( XML_FALSE ) );
+ }
+ break;
+ case EAS_MetalType :
+ {
+ // export only if ODF extensions are enabled
+ sal_Int16 eMetalType;
+ if (rProp.Value >>= eMetalType)
+ {
+ SvtSaveOptions::ODFSaneDefaultVersion eVersion = rExport.getSaneDefaultVersion();
+ if (eVersion > SvtSaveOptions::ODFSVER_013
+ && (eVersion & SvtSaveOptions::ODFSVER_EXTENDED))
+ {
+ if (eMetalType == drawing::EnhancedCustomShapeMetalType::MetalMSCompatible)
+ aStr = "loext:MetalMSCompatible";
+ else
+ aStr = "draw:MetalODF";
+ rExport.AddAttribute(XML_NAMESPACE_LO_EXT, XML_EXTRUSION_METAL_TYPE, aStr);
+ }
+ }
+ }
+ break;
+ case EAS_ShadeMode :
+ {
+ // shadeMode
+ drawing::ShadeMode eShadeMode;
+ if( rProp.Value >>= eShadeMode )
+ {
+ if( eShadeMode == drawing::ShadeMode_FLAT )
+ aStr = GetXMLToken( XML_FLAT );
+ else if( eShadeMode == drawing::ShadeMode_PHONG )
+ aStr = GetXMLToken( XML_PHONG );
+ else if( eShadeMode == drawing::ShadeMode_SMOOTH )
+ aStr = GetXMLToken( XML_GOURAUD );
+ else
+ aStr = GetXMLToken( XML_DRAFT );
+ }
+ else
+ {
+ // ShadeMode enum not there, write default
+ aStr = GetXMLToken( XML_FLAT);
+ }
+ rExport.AddAttribute( XML_NAMESPACE_DR3D, XML_SHADE_MODE, aStr );
+ }
+ break;
+ case EAS_RotateAngle :
+ {
+ css::drawing::EnhancedCustomShapeParameterPair aRotateAngleParaPair;
+ if ( rProp.Value >>= aRotateAngleParaPair )
+ {
+ ExportParameter( aStrBuffer, aRotateAngleParaPair.First );
+ ExportParameter( aStrBuffer, aRotateAngleParaPair.Second );
+ aStr = aStrBuffer.makeStringAndClear();
+ rExport.AddAttribute( XML_NAMESPACE_DRAW, XML_EXTRUSION_ROTATION_ANGLE, aStr );
+ }
+ }
+ break;
+ case EAS_RotationCenter :
+ {
+ drawing::Direction3D aExtrusionRotationCenter;
+ if ( rProp.Value >>= aExtrusionRotationCenter )
+ {
+ ::basegfx::B3DVector aVec3D( aExtrusionRotationCenter.DirectionX, aExtrusionRotationCenter.DirectionY,
+ aExtrusionRotationCenter.DirectionZ );
+ SvXMLUnitConverter::convertB3DVector( aStrBuffer, aVec3D );
+ aStr = aStrBuffer.makeStringAndClear();
+ rExport.AddAttribute( XML_NAMESPACE_DRAW, XML_EXTRUSION_ROTATION_CENTER, aStr );
+ }
+ }
+ break;
+ case EAS_Shininess :
+ {
+ double fExtrusionShininess = 0;
+ if ( rProp.Value >>= fExtrusionShininess )
+ {
+ ::sax::Converter::convertDouble(
+ aStrBuffer,
+ fExtrusionShininess,
+ false,
+ util::MeasureUnit::PERCENT,
+ util::MeasureUnit::PERCENT);
+ aStrBuffer.append( '%' );
+ aStr = aStrBuffer.makeStringAndClear();
+ rExport.AddAttribute( XML_NAMESPACE_DRAW, XML_EXTRUSION_SHININESS, aStr );
+ }
+ }
+ break;
+ case EAS_Skew :
+ {
+ css::drawing::EnhancedCustomShapeParameterPair aSkewParaPair;
+ if ( rProp.Value >>= aSkewParaPair )
+ {
+ bSkewValuesProvided = true;
+ ExportParameter( aStrBuffer, aSkewParaPair.First );
+ ExportParameter( aStrBuffer, aSkewParaPair.Second );
+ aStr = aStrBuffer.makeStringAndClear();
+ rExport.AddAttribute( XML_NAMESPACE_DRAW, XML_EXTRUSION_SKEW, aStr );
+ }
+ }
+ break;
+ case EAS_Specularity :
+ {
+ double fExtrusionSpecularity = 0;
+ if ( rProp.Value >>= fExtrusionSpecularity )
+ {
+ SvtSaveOptions::ODFSaneDefaultVersion eVersion = rExport.getSaneDefaultVersion();
+ if (fExtrusionSpecularity > 100.0 && eVersion >= SvtSaveOptions::ODFSVER_012
+ && (eVersion & SvtSaveOptions::ODFSVER_EXTENDED))
+ {
+ // tdf#147580 write values > 100% in loext
+ ::sax::Converter::convertDouble(
+ aStrBuffer,
+ fExtrusionSpecularity,
+ false,
+ util::MeasureUnit::PERCENT,
+ util::MeasureUnit::PERCENT);
+ aStrBuffer.append( '%' );
+ aStr = aStrBuffer.makeStringAndClear();
+ rExport.AddAttribute( XML_NAMESPACE_LO_EXT, XML_EXTRUSION_SPECULARITY_LOEXT, aStr );
+ }
+ // tdf#147580 ODF 1 allows arbitrary percent, later versions not
+ if (eVersion >= SvtSaveOptions::ODFSVER_012)
+ {
+ fExtrusionSpecularity = std::clamp<double>(fExtrusionSpecularity, 0.0, 100.0);
+ }
+ ::sax::Converter::convertDouble(
+ aStrBuffer,
+ fExtrusionSpecularity,
+ false,
+ util::MeasureUnit::PERCENT,
+ util::MeasureUnit::PERCENT);
+ aStrBuffer.append( '%' );
+ aStr = aStrBuffer.makeStringAndClear();
+ rExport.AddAttribute( XML_NAMESPACE_DRAW, XML_EXTRUSION_SPECULARITY, aStr );
+ }
+ }
+ break;
+ case EAS_ProjectionMode :
+ {
+ drawing::ProjectionMode eProjectionMode;
+ if ( rProp.Value >>= eProjectionMode )
+ rExport.AddAttribute( XML_NAMESPACE_DR3D, XML_PROJECTION,
+ eProjectionMode == drawing::ProjectionMode_PARALLEL ? GetXMLToken( XML_PARALLEL ) : GetXMLToken( XML_PERSPECTIVE ) );
+ }
+ break;
+ case EAS_ViewPoint :
+ {
+ drawing::Position3D aExtrusionViewPoint;
+ if ( rProp.Value >>= aExtrusionViewPoint )
+ {
+ rUnitConverter.convertPosition3D( aStrBuffer, aExtrusionViewPoint );
+ aStr = aStrBuffer.makeStringAndClear();
+ rExport.AddAttribute( XML_NAMESPACE_DRAW, XML_EXTRUSION_VIEWPOINT, aStr );
+ }
+ }
+ break;
+ case EAS_Origin :
+ {
+ css::drawing::EnhancedCustomShapeParameterPair aOriginParaPair;
+ if ( rProp.Value >>= aOriginParaPair )
+ {
+ ExportParameter( aStrBuffer, aOriginParaPair.First );
+ ExportParameter( aStrBuffer, aOriginParaPair.Second );
+ aStr = aStrBuffer.makeStringAndClear();
+ rExport.AddAttribute( XML_NAMESPACE_DRAW, XML_EXTRUSION_ORIGIN, aStr );
+ }
+ }
+ break;
+ case EAS_Color :
+ {
+ bool bExtrusionColor;
+ if ( rProp.Value >>= bExtrusionColor )
+ {
+ rExport.AddAttribute( XML_NAMESPACE_DRAW, XML_EXTRUSION_COLOR,
+ bExtrusionColor ? GetXMLToken( XML_TRUE ) : GetXMLToken( XML_FALSE ) );
+ }
+ }
+ break;
+ default:
+ break;
+ }
+ }
+ // tdf#141301: no specific skew values provided
+ if (!bSkewValuesProvided)
+ {
+ // so we need to export default values explicitly
+ rExport.AddAttribute( XML_NAMESPACE_DRAW, XML_EXTRUSION_SKEW, "50 -135");
+ }
+ }
+ }
+ break;
+ case EAS_TextPath :
+ {
+ uno::Sequence< beans::PropertyValue > aTextPathPropSeq;
+ if ( rGeoProp.Value >>= aTextPathPropSeq )
+ {
+ for ( const beans::PropertyValue& rProp : std::as_const(aTextPathPropSeq) )
+ {
+ switch( EASGet( rProp.Name ) )
+ {
+ case EAS_TextPath :
+ {
+ bool bTextPathOn;
+ if ( rProp.Value >>= bTextPathOn )
+ rExport.AddAttribute( XML_NAMESPACE_DRAW, XML_TEXT_PATH,
+ bTextPathOn ? GetXMLToken( XML_TRUE ) : GetXMLToken( XML_FALSE ) );
+ }
+ break;
+ case EAS_TextPathMode :
+ {
+ css::drawing::EnhancedCustomShapeTextPathMode eTextPathMode;
+ if ( rProp.Value >>= eTextPathMode )
+ {
+ switch ( eTextPathMode )
+ {
+ case css::drawing::EnhancedCustomShapeTextPathMode_NORMAL: aStr = GetXMLToken( XML_NORMAL ); break;
+ case css::drawing::EnhancedCustomShapeTextPathMode_PATH : aStr = GetXMLToken( XML_PATH ); break;
+ case css::drawing::EnhancedCustomShapeTextPathMode_SHAPE : aStr = GetXMLToken( XML_SHAPE ); break;
+ default:
+ break;
+ }
+ if ( !aStr.isEmpty() )
+ rExport.AddAttribute( XML_NAMESPACE_DRAW, XML_TEXT_PATH_MODE, aStr );
+ }
+ }
+ break;
+ case EAS_ScaleX :
+ {
+ bool bScaleX;
+ if ( rProp.Value >>= bScaleX )
+ {
+ aStr = bScaleX ? GetXMLToken( XML_SHAPE ) : GetXMLToken( XML_PATH );
+ rExport.AddAttribute( XML_NAMESPACE_DRAW, XML_TEXT_PATH_SCALE, aStr );
+ }
+ }
+ break;
+ case EAS_SameLetterHeights :
+ {
+ bool bSameLetterHeights;
+ if ( rProp.Value >>= bSameLetterHeights )
+ rExport.AddAttribute( XML_NAMESPACE_DRAW, XML_TEXT_PATH_SAME_LETTER_HEIGHTS,
+ bSameLetterHeights ? GetXMLToken( XML_TRUE ) : GetXMLToken( XML_FALSE ) );
+ }
+ break;
+ default:
+ break;
+ }
+ }
+ }
+ }
+ break;
+ case EAS_Path :
+ {
+ uno::Sequence< beans::PropertyValue > aPathPropSeq;
+ if ( rGeoProp.Value >>= aPathPropSeq )
+ {
+ for ( const beans::PropertyValue& rProp : std::as_const(aPathPropSeq) )
+ {
+ switch( EASGet( rProp.Name ) )
+ {
+ case EAS_SubViewSize:
+ {
+ // export draw:sub-view-size (do not export in ODF 1.3 or older)
+ if ((rExport.getSaneDefaultVersion() & SvtSaveOptions::ODFSVER_EXTENDED) == 0)
+ {
+ continue;
+ }
+ uno::Sequence< awt::Size > aSubViewSizes;
+ rProp.Value >>= aSubViewSizes;
+
+ for ( int nIdx = 0; nIdx < aSubViewSizes.getLength(); nIdx++ )
+ {
+ if ( nIdx )
+ aStrBuffer.append(' ');
+ aStrBuffer.append( aSubViewSizes[nIdx].Width );
+ aStrBuffer.append(' ');
+ aStrBuffer.append( aSubViewSizes[nIdx].Height );
+ }
+ aStr = aStrBuffer.makeStringAndClear();
+ rExport.AddAttribute( XML_NAMESPACE_DRAW_EXT, XML_SUB_VIEW_SIZE, aStr );
+ }
+ break;
+ case EAS_ExtrusionAllowed :
+ {
+ bool bExtrusionAllowed;
+ if ( rProp.Value >>= bExtrusionAllowed )
+ rExport.AddAttribute( XML_NAMESPACE_DRAW, XML_EXTRUSION_ALLOWED,
+ bExtrusionAllowed ? GetXMLToken( XML_TRUE ) : GetXMLToken( XML_FALSE ) );
+ }
+ break;
+ case EAS_ConcentricGradientFillAllowed :
+ {
+ bool bConcentricGradientFillAllowed;
+ if ( rProp.Value >>= bConcentricGradientFillAllowed )
+ rExport.AddAttribute( XML_NAMESPACE_DRAW, XML_CONCENTRIC_GRADIENT_FILL_ALLOWED,
+ bConcentricGradientFillAllowed ? GetXMLToken( XML_TRUE ) : GetXMLToken( XML_FALSE ) );
+ }
+ break;
+ case EAS_TextPathAllowed :
+ {
+ bool bTextPathAllowed;
+ if ( rProp.Value >>= bTextPathAllowed )
+ rExport.AddAttribute( XML_NAMESPACE_DRAW, XML_TEXT_PATH_ALLOWED,
+ bTextPathAllowed ? GetXMLToken( XML_TRUE ) : GetXMLToken( XML_FALSE ) );
+ }
+ break;
+ case EAS_GluePoints :
+ {
+ css::uno::Sequence< css::drawing::EnhancedCustomShapeParameterPair> aGluePoints;
+ if ( rProp.Value >>= aGluePoints )
+ {
+ if ( aGluePoints.hasElements() )
+ {
+ for( const auto& rGluePoint : std::as_const(aGluePoints) )
+ {
+ ExportParameter( aStrBuffer, rGluePoint.First );
+ ExportParameter( aStrBuffer, rGluePoint.Second );
+ }
+ aStr = aStrBuffer.makeStringAndClear();
+ }
+ rExport.AddAttribute( XML_NAMESPACE_DRAW, XML_GLUE_POINTS, aStr );
+ }
+ }
+ break;
+ case EAS_GluePointType :
+ {
+ sal_Int16 nGluePointType = sal_Int16();
+ if ( rProp.Value >>= nGluePointType )
+ {
+ switch ( nGluePointType )
+ {
+ case css::drawing::EnhancedCustomShapeGluePointType::NONE : aStr = GetXMLToken( XML_NONE ); break;
+ case css::drawing::EnhancedCustomShapeGluePointType::SEGMENTS : aStr = GetXMLToken( XML_SEGMENTS ); break;
+ case css::drawing::EnhancedCustomShapeGluePointType::RECT : aStr = GetXMLToken( XML_RECTANGLE ); break;
+ }
+ if ( !aStr.isEmpty() )
+ rExport.AddAttribute( XML_NAMESPACE_DRAW, XML_GLUE_POINT_TYPE, aStr );
+ }
+ }
+ break;
+ case EAS_Coordinates :
+ {
+ bCoordinates = ( rProp.Value >>= aCoordinates );
+ }
+ break;
+ case EAS_Segments :
+ {
+ rProp.Value >>= aSegments;
+ }
+ break;
+ case EAS_StretchX :
+ {
+ sal_Int32 nStretchPoint = 0;
+ if ( rProp.Value >>= nStretchPoint )
+ rExport.AddAttribute( XML_NAMESPACE_DRAW, XML_PATH_STRETCHPOINT_X, OUString::number( nStretchPoint ) );
+ }
+ break;
+ case EAS_StretchY :
+ {
+ sal_Int32 nStretchPoint = 0;
+ if ( rProp.Value >>= nStretchPoint )
+ rExport.AddAttribute( XML_NAMESPACE_DRAW, XML_PATH_STRETCHPOINT_Y, OUString::number( nStretchPoint ) );
+ }
+ break;
+ case EAS_TextFrames :
+ {
+ css::uno::Sequence< css::drawing::EnhancedCustomShapeTextFrame > aPathTextFrames;
+ if ( rProp.Value >>= aPathTextFrames )
+ {
+ if ( aPathTextFrames.hasElements() )
+ {
+ for ( const auto& rPathTextFrame : std::as_const(aPathTextFrames) )
+ {
+ ExportParameter( aStrBuffer, rPathTextFrame.TopLeft.First );
+ ExportParameter( aStrBuffer, rPathTextFrame.TopLeft.Second );
+ ExportParameter( aStrBuffer, rPathTextFrame.BottomRight.First );
+ ExportParameter( aStrBuffer, rPathTextFrame.BottomRight.Second );
+ }
+ aStr = aStrBuffer.makeStringAndClear();
+ }
+ rExport.AddAttribute( XML_NAMESPACE_DRAW, XML_TEXT_AREAS, aStr );
+ }
+ }
+ break;
+ default:
+ break;
+ }
+ }
+ }
+ }
+ break;
+ case EAS_Equations :
+ {
+ bEquations = ( rGeoProp.Value >>= aEquations );
+ }
+ break;
+ case EAS_Handles :
+ {
+ bHandles = ( rGeoProp.Value >>= aHandles );
+ }
+ break;
+ case EAS_AdjustmentValues :
+ {
+ rGeoProp.Value >>= aAdjustmentValues;
+ }
+ break;
+ default:
+ break;
+ }
+ } // for
+
+ // ToDo: Where is TextPreRotateAngle still used? We cannot save it in ODF.
+ fTextRotateAngle += fTextPreRotateAngle;
+ // Workaround for writing-mode bt-lr and tb-rl90 in ODF strict,
+ // otherwise loext:writing-mode is used in style export.
+ if (!(rExport.getSaneDefaultVersion() & SvtSaveOptions::ODFSVER_EXTENDED))
+ {
+ if (xPropSetInfo->hasPropertyByName(u"WritingMode"_ustr))
+ {
+ sal_Int16 nDirection = -1;
+ xPropSet->getPropertyValue(u"WritingMode"_ustr) >>= nDirection;
+ if (nDirection == text::WritingMode2::TB_RL90)
+ fTextRotateAngle -= 90;
+ else if (nDirection == text::WritingMode2::BT_LR)
+ fTextRotateAngle -= 270;
+ }
+ }
+ if (fTextRotateAngle != 0)
+ {
+ ::sax::Converter::convertDouble( aStrBuffer, fTextRotateAngle );
+ aStr = aStrBuffer.makeStringAndClear();
+ rExport.AddAttribute( XML_NAMESPACE_DRAW, XML_TEXT_ROTATE_ANGLE, aStr );
+ }
+
+ rExport.AddAttribute( XML_NAMESPACE_DRAW, XML_TYPE, aCustomShapeType );
+
+ // adjustments
+ sal_Int32 nAdjustmentValues = aAdjustmentValues.getLength();
+ if ( nAdjustmentValues )
+ {
+ sal_Int32 i, nValue = 0;
+ for ( i = 0; i < nAdjustmentValues; i++ )
+ {
+ if ( i )
+ aStrBuffer.append( ' ' );
+
+ const css::drawing::EnhancedCustomShapeAdjustmentValue& rAdj = aAdjustmentValues[ i ];
+ if ( rAdj.State == beans::PropertyState_DIRECT_VALUE )
+ {
+ if ( rAdj.Value.getValueTypeClass() == uno::TypeClass_DOUBLE )
+ {
+ double fValue = 0.0;
+ rAdj.Value >>= fValue;
+ ::sax::Converter::convertDouble(aStrBuffer, fValue);
+ }
+ else
+ {
+ rAdj.Value >>= nValue;
+ aStrBuffer.append(nValue);
+ }
+ }
+ else
+ {
+ // this should not be, but better than setting nothing
+ aStrBuffer.append("0");
+ }
+ }
+ aStr = aStrBuffer.makeStringAndClear();
+ rExport.AddAttribute( XML_NAMESPACE_DRAW, XML_MODIFIERS, aStr );
+ }
+ if ( bCoordinates )
+ ImpExportEnhancedPath( rExport, aCoordinates, aSegments );
+ }
+ }
+ SvXMLElementExport aOBJ( rExport, XML_NAMESPACE_DRAW, XML_ENHANCED_GEOMETRY, true, true );
+ if ( bEquations )
+ ImpExportEquations( rExport, aEquations );
+ if ( bHandles )
+ ImpExportHandles( rExport, aHandles );
+}
+
+void XMLShapeExport::ImpExportCustomShape(
+ const uno::Reference< drawing::XShape >& xShape,
+ XMLShapeExportFlags nFeatures, css::awt::Point* pRefPoint )
+{
+ const uno::Reference< beans::XPropertySet > xPropSet(xShape, uno::UNO_QUERY);
+ if ( !xPropSet.is() )
+ return;
+
+ uno::Reference< beans::XPropertySetInfo > xPropSetInfo( xPropSet->getPropertySetInfo() );
+
+ // Transformation
+ ImpExportNewTrans( xPropSet, nFeatures, pRefPoint );
+
+ if ( xPropSetInfo.is() )
+ {
+ OUString aStr;
+ if ( xPropSetInfo->hasPropertyByName( "CustomShapeEngine" ) )
+ {
+ uno::Any aEngine( xPropSet->getPropertyValue( "CustomShapeEngine" ) );
+ if ( ( aEngine >>= aStr ) && !aStr.isEmpty() )
+ mrExport.AddAttribute( XML_NAMESPACE_DRAW, XML_ENGINE, aStr );
+ }
+ if ( xPropSetInfo->hasPropertyByName( "CustomShapeData" ) )
+ {
+ uno::Any aData( xPropSet->getPropertyValue( "CustomShapeData" ) );
+ if ( ( aData >>= aStr ) && !aStr.isEmpty() )
+ mrExport.AddAttribute( XML_NAMESPACE_DRAW, XML_DATA, aStr );
+ }
+ }
+ bool bCreateNewline( (nFeatures & XMLShapeExportFlags::NO_WS) == XMLShapeExportFlags::NONE ); // #86116#/#92210#
+ SvXMLElementExport aOBJ( mrExport, XML_NAMESPACE_DRAW, XML_CUSTOM_SHAPE, bCreateNewline, true );
+ ImpExportDescription( xShape ); // #i68101#
+ ImpExportEvents( xShape );
+ ImpExportGluePoints( xShape );
+ ImpExportText( xShape );
+ ImpExportEnhancedGeometry( mrExport, xPropSet );
+
+}
+
+void XMLShapeExport::ImpExportTableShape( const uno::Reference< drawing::XShape >& xShape, XmlShapeType eShapeType, XMLShapeExportFlags nFeatures, css::awt::Point* pRefPoint )
+{
+ uno::Reference< beans::XPropertySet > xPropSet(xShape, uno::UNO_QUERY);
+ uno::Reference< container::XNamed > xNamed(xShape, uno::UNO_QUERY);
+
+ SAL_WARN_IF( !xPropSet.is() || !xNamed.is(), "xmloff", "xmloff::XMLShapeExport::ImpExportTableShape(), table shape is not implementing needed interfaces");
+ if(!(xPropSet.is() && xNamed.is()))
+ return;
+
+ try
+ {
+ // Transformation
+ ImpExportNewTrans(xPropSet, nFeatures, pRefPoint);
+
+ bool bIsEmptyPresObj = false;
+
+ // presentation settings
+ if(eShapeType == XmlShapeType::PresTableShape)
+ bIsEmptyPresObj = ImpExportPresentationAttributes( xPropSet, GetXMLToken(XML_TABLE) );
+
+ const bool bCreateNewline( (nFeatures & XMLShapeExportFlags::NO_WS) == XMLShapeExportFlags::NONE );
+
+ SvXMLElementExport aElement( mrExport, XML_NAMESPACE_DRAW, XML_FRAME, bCreateNewline, true );
+
+ // do not export in ODF 1.1 or older
+ if (mrExport.getSaneDefaultVersion() >= SvtSaveOptions::ODFSVER_012)
+ {
+ if( !bIsEmptyPresObj )
+ {
+ uno::Reference< container::XNamed > xTemplate( xPropSet->getPropertyValue("TableTemplate"), uno::UNO_QUERY );
+ if( xTemplate.is() )
+ {
+ const OUString sTemplate( xTemplate->getName() );
+ if( !sTemplate.isEmpty() )
+ {
+ mrExport.AddAttribute(XML_NAMESPACE_TABLE, XML_TEMPLATE_NAME, sTemplate );
+
+ for( const XMLPropertyMapEntry* pEntry = &aXMLTableShapeAttributes[0]; !pEntry->IsEnd(); pEntry++ )
+ {
+ try
+ {
+ bool bBool = false;
+ xPropSet->getPropertyValue( pEntry->getApiName() ) >>= bBool;
+ if( bBool )
+ mrExport.AddAttribute(pEntry->mnNameSpace, pEntry->meXMLName, XML_TRUE );
+ }
+ catch( uno::Exception& )
+ {
+ DBG_UNHANDLED_EXCEPTION("xmloff.draw");
+ }
+ }
+ }
+ }
+
+ uno::Reference< table::XColumnRowRange > xRange( xPropSet->getPropertyValue( gsModel ), uno::UNO_QUERY_THROW );
+ GetShapeTableExport()->exportTable( xRange );
+ }
+ }
+
+ if( !bIsEmptyPresObj )
+ {
+ uno::Reference< graphic::XGraphic > xGraphic( xPropSet->getPropertyValue("ReplacementGraphic"), uno::UNO_QUERY );
+ ExportGraphicPreview(xGraphic, mrExport, u"TablePreview", u".svm", "image/x-vclgraphic");
+ }
+
+ ImpExportEvents( xShape );
+ ImpExportGluePoints( xShape );
+ ImpExportDescription( xShape ); // #i68101#
+ }
+ catch( uno::Exception const & )
+ {
+ DBG_UNHANDLED_EXCEPTION("xmloff.draw");
+ }
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/xmloff/source/draw/shapeimport.cxx b/xmloff/source/draw/shapeimport.cxx
new file mode 100644
index 0000000000..5186c8be2b
--- /dev/null
+++ b/xmloff/source/draw/shapeimport.cxx
@@ -0,0 +1,951 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#include <tools/debug.hxx>
+#include <comphelper/diagnose_ex.hxx>
+#include <sal/log.hxx>
+#include <comphelper/attributelist.hxx>
+
+#include <com/sun/star/beans/XPropertySet.hpp>
+#include <com/sun/star/text/PositionLayoutDir.hpp>
+#include <com/sun/star/drawing/XShapes3.hpp>
+
+#include <utility>
+#include <xmloff/unointerfacetouniqueidentifiermapper.hxx>
+
+#include <xmloff/shapeimport.hxx>
+#include <xmloff/xmlstyle.hxx>
+#include <xmloff/xmltkmap.hxx>
+#include <xmloff/xmlnamespace.hxx>
+#include <xmloff/xmltoken.hxx>
+#include <xmloff/table/XMLTableImport.hxx>
+#include "eventimp.hxx"
+#include "ximpshap.hxx"
+#include "sdpropls.hxx"
+#include <xmloff/xmlprmap.hxx>
+#include "ximp3dscene.hxx"
+#include "ximp3dobject.hxx"
+#include "ximpgrp.hxx"
+#include "ximplink.hxx"
+
+#include <unordered_map>
+#include <string_view>
+#include <vector>
+
+namespace {
+
+class ShapeGroupContext;
+
+}
+
+using namespace ::com::sun::star;
+using namespace ::xmloff::token;
+
+namespace {
+
+struct ConnectionHint
+{
+ css::uno::Reference< css::drawing::XShape > mxConnector;
+ OUString aDestShapeId;
+ sal_Int32 nDestGlueId;
+ bool bStart;
+};
+
+}
+
+/** this map store all gluepoint id mappings for shapes that had user defined gluepoints. This
+ is needed because on insertion the gluepoints will get a new and unique id */
+typedef std::map<sal_Int32,sal_Int32> GluePointIdMap;
+typedef std::unordered_map< css::uno::Reference < css::drawing::XShape >, GluePointIdMap > ShapeGluePointsMap;
+
+/** this struct is created for each startPage() call and stores information that is needed during
+ import of shapes for one page. Since pages could be nested ( notes pages inside impress ) there
+ is a pointer so one can build up a stack of this structs */
+struct XMLShapeImportPageContextImpl
+{
+ ShapeGluePointsMap maShapeGluePointsMap;
+
+ uno::Reference < drawing::XShapes > mxShapes;
+
+ std::shared_ptr<XMLShapeImportPageContextImpl> mpNext;
+};
+
+/** this class is to enable adding members to the XMLShapeImportHelper without getting incompatible */
+struct XMLShapeImportHelperImpl
+{
+ // context for sorting shapes
+ std::shared_ptr<ShapeGroupContext> mpGroupContext;
+
+ std::vector<ConnectionHint> maConnections;
+
+ // #88546# possibility to switch progress bar handling on/off
+ bool mbHandleProgressBar;
+
+ // stores the capability of the current model to create presentation shapes
+ bool mbIsPresentationShapesSupported;
+};
+
+constexpr OUStringLiteral gsStartShape(u"StartShape");
+constexpr OUStringLiteral gsEndShape(u"EndShape");
+constexpr OUStringLiteral gsStartGluePointIndex(u"StartGluePointIndex");
+constexpr OUStringLiteral gsEndGluePointIndex(u"EndGluePointIndex");
+
+XMLShapeImportHelper::XMLShapeImportHelper(
+ SvXMLImport& rImporter,
+ const uno::Reference< frame::XModel>& rModel,
+ SvXMLImportPropertyMapper *pExtMapper )
+: mpImpl( new XMLShapeImportHelperImpl ),
+ mrImporter( rImporter )
+{
+ mpImpl->mpGroupContext = nullptr;
+
+ // #88546# init to sal_False
+ mpImpl->mbHandleProgressBar = false;
+
+ mpSdPropHdlFactory = new XMLSdPropHdlFactory( rModel, rImporter );
+
+ // construct PropertySetMapper
+ rtl::Reference < XMLPropertySetMapper > xMapper = new XMLShapePropertySetMapper(mpSdPropHdlFactory, false);
+ mpPropertySetMapper = new SvXMLImportPropertyMapper( xMapper, rImporter );
+
+ if( pExtMapper )
+ {
+ rtl::Reference < SvXMLImportPropertyMapper > xExtMapper( pExtMapper );
+ mpPropertySetMapper->ChainImportMapper( xExtMapper );
+ }
+
+ // chain text attributes
+ mpPropertySetMapper->ChainImportMapper(XMLTextImportHelper::CreateParaExtPropMapper(rImporter));
+ mpPropertySetMapper->ChainImportMapper(XMLTextImportHelper::CreateParaDefaultExtPropMapper(rImporter));
+
+ // construct PresPagePropsMapper
+ xMapper = new XMLPropertySetMapper(aXMLSDPresPageProps, mpSdPropHdlFactory, false);
+ mpPresPagePropsMapper = new SvXMLImportPropertyMapper( xMapper, rImporter );
+
+ uno::Reference< lang::XServiceInfo > xInfo( rImporter.GetModel(), uno::UNO_QUERY );
+ mpImpl->mbIsPresentationShapesSupported = xInfo.is() && xInfo->supportsService( "com.sun.star.presentation.PresentationDocument" );
+}
+
+XMLShapeImportHelper::~XMLShapeImportHelper()
+{
+ SAL_WARN_IF( !mpImpl->maConnections.empty(), "xmloff", "XMLShapeImportHelper::restoreConnections() was not called!" );
+
+ // cleanup factory, decrease refcount. Should lead to destruction.
+ mpSdPropHdlFactory.clear();
+
+ // cleanup mapper, decrease refcount. Should lead to destruction.
+ mpPropertySetMapper.clear();
+
+ // cleanup presPage mapper, decrease refcount. Should lead to destruction.
+ mpPresPagePropsMapper.clear();
+
+ // Styles or AutoStyles context?
+ if(mxStylesContext.is())
+ mxStylesContext->dispose();
+
+ if(mxAutoStylesContext.is())
+ mxAutoStylesContext->dispose();
+}
+
+
+SvXMLShapeContext* XMLShapeImportHelper::Create3DSceneChildContext(
+ SvXMLImport& rImport,
+ sal_Int32 nElement,
+ const uno::Reference< xml::sax::XFastAttributeList>& xAttrList,
+ uno::Reference< drawing::XShapes > const & rShapes)
+{
+ SdXMLShapeContext *pContext = nullptr;
+
+ if(rShapes.is())
+ {
+ switch(nElement)
+ {
+ case XML_ELEMENT(DR3D, XML_SCENE):
+ {
+ // dr3d:3dscene inside dr3d:3dscene context
+ pContext = new SdXML3DSceneShapeContext( rImport, xAttrList, rShapes, false);
+ break;
+ }
+ case XML_ELEMENT(DR3D, XML_CUBE):
+ {
+ // dr3d:3dcube inside dr3d:3dscene context
+ pContext = new SdXML3DCubeObjectShapeContext( rImport, xAttrList, rShapes);
+ break;
+ }
+ case XML_ELEMENT(DR3D, XML_SPHERE):
+ {
+ // dr3d:3dsphere inside dr3d:3dscene context
+ pContext = new SdXML3DSphereObjectShapeContext( rImport, xAttrList, rShapes);
+ break;
+ }
+ case XML_ELEMENT(DR3D, XML_ROTATE):
+ {
+ // dr3d:3dlathe inside dr3d:3dscene context
+ pContext = new SdXML3DLatheObjectShapeContext( rImport, xAttrList, rShapes);
+ break;
+ }
+ case XML_ELEMENT(DR3D, XML_EXTRUDE):
+ {
+ // dr3d:3dextrude inside dr3d:3dscene context
+ pContext = new SdXML3DExtrudeObjectShapeContext( rImport, xAttrList, rShapes);
+ break;
+ }
+ default:
+ XMLOFF_WARN_UNKNOWN_ELEMENT("xmloff", nElement);
+ }
+ }
+
+ if (!pContext)
+ return nullptr;
+
+ // now parse the attribute list and call the child context for each unknown attribute
+ for(auto& aIter : sax_fastparser::castToFastAttributeList(xAttrList))
+ {
+ if (!pContext->processAttribute( aIter ))
+ XMLOFF_WARN_UNKNOWN("xmloff", aIter);
+
+ }
+
+ return pContext;
+}
+
+void XMLShapeImportHelper::SetStylesContext(SvXMLStylesContext* pNew)
+{
+ mxStylesContext.set(pNew);
+}
+
+void XMLShapeImportHelper::SetAutoStylesContext(SvXMLStylesContext* pNew)
+{
+ mxAutoStylesContext.set(pNew);
+}
+
+SvXMLShapeContext* XMLShapeImportHelper::CreateGroupChildContext(
+ SvXMLImport& rImport,
+ sal_Int32 nElement,
+ const uno::Reference< xml::sax::XFastAttributeList>& xAttrList,
+ uno::Reference< drawing::XShapes > const & rShapes,
+ bool bTemporaryShape)
+{
+ SdXMLShapeContext *pContext = nullptr;
+ switch (nElement)
+ {
+ case XML_ELEMENT(DRAW, XML_G):
+ // draw:g inside group context (RECURSIVE)
+ pContext = new SdXMLGroupShapeContext( rImport, xAttrList, rShapes, bTemporaryShape);
+ break;
+ case XML_ELEMENT(DR3D, XML_SCENE):
+ {
+ // dr3d:3dscene inside group context
+ pContext = new SdXML3DSceneShapeContext( rImport, xAttrList, rShapes, bTemporaryShape);
+ break;
+ }
+ case XML_ELEMENT(DRAW, XML_RECT):
+ {
+ // draw:rect inside group context
+ pContext = new SdXMLRectShapeContext( rImport, xAttrList, rShapes, bTemporaryShape );
+ break;
+ }
+ case XML_ELEMENT(DRAW, XML_LINE):
+ {
+ // draw:line inside group context
+ pContext = new SdXMLLineShapeContext( rImport, xAttrList, rShapes, bTemporaryShape );
+ break;
+ }
+ case XML_ELEMENT(DRAW, XML_CIRCLE):
+ case XML_ELEMENT(DRAW, XML_ELLIPSE):
+ {
+ // draw:circle or draw:ellipse inside group context
+ pContext = new SdXMLEllipseShapeContext( rImport, xAttrList, rShapes, bTemporaryShape );
+ break;
+ }
+ case XML_ELEMENT(DRAW, XML_POLYGON):
+ case XML_ELEMENT(DRAW, XML_POLYLINE):
+ {
+ // draw:polygon or draw:polyline inside group context
+ pContext = new SdXMLPolygonShapeContext( rImport, xAttrList, rShapes,
+ nElement == XML_ELEMENT(DRAW, XML_POLYGON), bTemporaryShape );
+ break;
+ }
+ case XML_ELEMENT(DRAW, XML_PATH):
+ {
+ // draw:path inside group context
+ pContext = new SdXMLPathShapeContext( rImport, xAttrList, rShapes, bTemporaryShape);
+ break;
+ }
+ case XML_ELEMENT(DRAW, XML_FRAME):
+ {
+ // text:text-box inside group context
+ pContext = new SdXMLFrameShapeContext( rImport, xAttrList, rShapes, bTemporaryShape );
+ break;
+ }
+ case XML_ELEMENT(DRAW, XML_CONTROL):
+ {
+ // draw:control inside group context
+ pContext = new SdXMLControlShapeContext( rImport, xAttrList, rShapes, bTemporaryShape );
+ break;
+ }
+ case XML_ELEMENT(DRAW, XML_CONNECTOR):
+ {
+ // draw:connector inside group context
+ pContext = new SdXMLConnectorShapeContext( rImport, xAttrList, rShapes, bTemporaryShape );
+ break;
+ }
+ case XML_ELEMENT(DRAW, XML_MEASURE):
+ {
+ // draw:measure inside group context
+ pContext = new SdXMLMeasureShapeContext( rImport, xAttrList, rShapes, bTemporaryShape );
+ break;
+ }
+ case XML_ELEMENT(DRAW, XML_PAGE_THUMBNAIL):
+ {
+ // draw:page inside group context
+ pContext = new SdXMLPageShapeContext( rImport, xAttrList, rShapes, bTemporaryShape );
+ break;
+ }
+ case XML_ELEMENT(DRAW, XML_CAPTION):
+ case XML_ELEMENT(OFFICE, XML_ANNOTATION):
+ {
+ // draw:caption inside group context
+ pContext = new SdXMLCaptionShapeContext( rImport, xAttrList, rShapes, bTemporaryShape );
+ break;
+ }
+ case XML_ELEMENT(CHART, XML_CHART):
+ {
+ // chart:chart inside group context
+ pContext = new SdXMLChartShapeContext( rImport, xAttrList, rShapes, bTemporaryShape );
+ break;
+ }
+ case XML_ELEMENT(DRAW, XML_CUSTOM_SHAPE):
+ {
+ // draw:customshape
+ pContext = new SdXMLCustomShapeContext( rImport, xAttrList, rShapes );
+ break;
+ }
+ case XML_ELEMENT(DRAW, XML_A):
+ return new SdXMLShapeLinkContext( rImport, xAttrList, rShapes );
+ // add other shapes here...
+ default:
+ XMLOFF_INFO_UNKNOWN_ELEMENT("xmloff", nElement);
+ return new SvXMLShapeContext( rImport, bTemporaryShape );
+ }
+
+ // now parse the attribute list and call the child context for each unknown attribute
+ for (auto &aIter : sax_fastparser::castToFastAttributeList( xAttrList ))
+ {
+ if (!pContext->processAttribute( aIter ))
+ XMLOFF_INFO_UNKNOWN("xmloff", aIter);
+ }
+ return pContext;
+}
+
+// This method is called from SdXMLFrameShapeContext to create children of draw:frame
+SvXMLShapeContext* XMLShapeImportHelper::CreateFrameChildContext(
+ SvXMLImport& rImport,
+ sal_Int32 nElement,
+ const uno::Reference< xml::sax::XFastAttributeList>& rAttrList,
+ uno::Reference< drawing::XShapes > const & rShapes,
+ const uno::Reference< xml::sax::XFastAttributeList>& rFrameAttrList)
+{
+ SdXMLShapeContext *pContext = nullptr;
+
+ rtl::Reference<sax_fastparser::FastAttributeList> xCombinedAttrList = new sax_fastparser::FastAttributeList(rAttrList);
+ if( rFrameAttrList.is() )
+ xCombinedAttrList->add(rFrameAttrList);
+
+ switch(nElement)
+ {
+ case XML_ELEMENT(DRAW, XML_TEXT_BOX):
+ {
+ // text:text-box inside group context
+ pContext = new SdXMLTextBoxShapeContext( rImport, xCombinedAttrList, rShapes );
+ break;
+ }
+ case XML_ELEMENT(DRAW, XML_IMAGE):
+ {
+ // office:image inside group context
+ pContext = new SdXMLGraphicObjectShapeContext( rImport, xCombinedAttrList, rShapes );
+ break;
+ }
+ case XML_ELEMENT(DRAW, XML_OBJECT):
+ case XML_ELEMENT(DRAW, XML_OBJECT_OLE):
+ {
+ // draw:object or draw:object_ole
+ pContext = new SdXMLObjectShapeContext( rImport, xCombinedAttrList, rShapes );
+ break;
+ }
+ case XML_ELEMENT(TABLE, XML_TABLE):
+ {
+ // draw:object or draw:object_ole
+ if( rImport.IsTableShapeSupported() )
+ pContext = new SdXMLTableShapeContext( rImport, xCombinedAttrList, rShapes );
+ break;
+
+ }
+ case XML_ELEMENT(DRAW, XML_PLUGIN):
+ {
+ // draw:plugin
+ pContext = new SdXMLPluginShapeContext( rImport, xCombinedAttrList, rShapes );
+ break;
+ }
+ case XML_ELEMENT(DRAW, XML_FLOATING_FRAME):
+ {
+ // draw:floating-frame
+ pContext = new SdXMLFloatingFrameShapeContext( rImport, xCombinedAttrList, rShapes );
+ break;
+ }
+ case XML_ELEMENT(DRAW, XML_APPLET):
+ {
+ // draw:applet
+ pContext = new SdXMLAppletShapeContext( rImport, xCombinedAttrList, rShapes );
+ break;
+ }
+ // add other shapes here...
+ default:
+ SAL_INFO("xmloff", "unknown element " << SvXMLImport::getPrefixAndNameFromToken(nElement));
+ break;
+ }
+
+ if( pContext )
+ {
+ // now parse the attribute list and call the child context for each unknown attribute
+ for(auto& aIter : *xCombinedAttrList)
+ {
+ if (!pContext->processAttribute( aIter ))
+ SAL_INFO("xmloff", "unknown attribute " << SvXMLImport::getPrefixAndNameFromToken(aIter.getToken()) << " value=" << aIter.toString());
+ }
+ }
+
+ return pContext;
+}
+
+css::uno::Reference< css::xml::sax::XFastContextHandler > XMLShapeImportHelper::CreateFrameChildContext(
+ SvXMLImportContext *pThisContext,
+ sal_Int32 nElement,
+ const uno::Reference< xml::sax::XFastAttributeList>& xAttrList )
+{
+ css::uno::Reference< css::xml::sax::XFastContextHandler > xContext;
+ SdXMLFrameShapeContext *pFrameContext = dynamic_cast<SdXMLFrameShapeContext*>( pThisContext );
+ if (pFrameContext)
+ xContext = pFrameContext->createFastChildContext( nElement, xAttrList );
+
+ if (!xContext)
+ XMLOFF_WARN_UNKNOWN_ELEMENT("xmloff", nElement);
+ return xContext;
+}
+
+/** this function is called whenever the implementation classes like to add this new
+ shape to the given XShapes.
+*/
+void XMLShapeImportHelper::addShape( uno::Reference< drawing::XShape >& rShape,
+ const uno::Reference< xml::sax::XFastAttributeList >&,
+ uno::Reference< drawing::XShapes >& rShapes)
+{
+ if( rShape.is() && rShapes.is() )
+ {
+ // add new shape to parent
+ rShapes->add( rShape );
+
+ uno::Reference<beans::XPropertySet> xPropertySet(rShape, uno::UNO_QUERY);
+ if (xPropertySet.is())
+ {
+ static constexpr OUStringLiteral sHandlePathObjScale = u"HandlePathObjScale";
+ xPropertySet->setPropertyValue(sHandlePathObjScale, uno::Any(true));
+ }
+ }
+}
+
+/** this function is called whenever the implementation classes have finished importing
+ a shape to the given XShapes. The shape is already inserted into its XShapes and
+ all properties and styles are set.
+*/
+void XMLShapeImportHelper::finishShape(
+ css::uno::Reference< css::drawing::XShape >& rShape,
+ const css::uno::Reference< css::xml::sax::XFastAttributeList >&,
+ css::uno::Reference< css::drawing::XShapes >&)
+{
+ /* Set property <PositionLayoutDir>
+ to <PositionInHoriL2R>, if it exists and the import states that
+ the shape positioning attributes are in horizontal left-to-right
+ layout. This is the case for the OpenOffice.org file format.
+ This setting is done for Writer documents, because the property
+ only exists at service css::text::Shape - the Writer
+ UNO service for shapes.
+ The value indicates that the positioning attributes are given
+ in horizontal left-to-right layout. The property is evaluated
+ during the first positioning of the shape in order to convert
+ the shape position given in the OpenOffice.org file format to
+ the one for the OASIS Open Office file format. (#i28749#, #i36248#)
+ */
+ uno::Reference< beans::XPropertySet > xPropSet(rShape, uno::UNO_QUERY);
+ if ( xPropSet.is() )
+ {
+ if ( mrImporter.IsShapePositionInHoriL2R() &&
+ xPropSet->getPropertySetInfo()->hasPropertyByName(
+ "PositionLayoutDir") )
+ {
+ uno::Any aPosLayoutDir;
+ aPosLayoutDir <<= text::PositionLayoutDir::PositionInHoriL2R;
+ xPropSet->setPropertyValue( "PositionLayoutDir", aPosLayoutDir );
+ }
+ }
+}
+
+namespace {
+
+// helper functions for z-order sorting
+struct ZOrderHint
+{
+ sal_Int32 nIs;
+ sal_Int32 nShould;
+ /// The hint is for this shape. We don't use uno::Reference here to speed up
+ /// some operations, and because this shape is always held by mxShapes
+ drawing::XShape* pShape;
+
+ bool operator<(const ZOrderHint& rComp) const { return nShould < rComp.nShould; }
+};
+
+// a) handle z-order of group contents after it has been imported
+// b) apply group events over group contents after it has been imported
+class ShapeGroupContext
+{
+public:
+ uno::Reference< drawing::XShapes > mxShapes;
+ std::vector<SdXMLEventContextData> maEventData;
+ std::vector<ZOrderHint> maZOrderList;
+ std::vector<ZOrderHint> maUnsortedList;
+
+ sal_Int32 mnCurrentZ;
+ std::shared_ptr<ShapeGroupContext> mpParentContext;
+
+ ShapeGroupContext( uno::Reference< drawing::XShapes > xShapes, std::shared_ptr<ShapeGroupContext> pParentContext );
+
+ void popGroupAndPostProcess();
+private:
+ void moveShape( sal_Int32 nSourcePos, sal_Int32 nDestPos );
+};
+
+}
+
+ShapeGroupContext::ShapeGroupContext( uno::Reference< drawing::XShapes > xShapes, std::shared_ptr<ShapeGroupContext> pParentContext )
+: mxShapes(std::move( xShapes )), mnCurrentZ( 0 ), mpParentContext( std::move(pParentContext) )
+{
+}
+
+void ShapeGroupContext::moveShape( sal_Int32 nSourcePos, sal_Int32 nDestPos )
+{
+ uno::Any aAny( mxShapes->getByIndex( nSourcePos ) );
+ uno::Reference< beans::XPropertySet > xPropSet;
+ aAny >>= xPropSet;
+
+ if( !(xPropSet.is() && xPropSet->getPropertySetInfo()->hasPropertyByName( "ZOrder" )) )
+ return;
+
+ xPropSet->setPropertyValue( "ZOrder", uno::Any(nDestPos) );
+
+ for( ZOrderHint& rHint : maZOrderList )
+ {
+ if( rHint.nIs < nSourcePos )
+ {
+ DBG_ASSERT(rHint.nIs >= nDestPos, "Shape sorting failed" );
+ rHint.nIs++;
+ }
+ }
+
+ for( ZOrderHint& rHint : maUnsortedList )
+ {
+ if( rHint.nIs < nSourcePos )
+ {
+ SAL_WARN_IF( rHint.nIs < nDestPos, "xmloff", "shape sorting failed" );
+ rHint.nIs++;
+ }
+ }
+}
+
+// sort shapes
+void ShapeGroupContext::popGroupAndPostProcess()
+{
+ if (!maEventData.empty())
+ {
+ // tdf#127791 wait until a group is popped to set its event data
+ for (auto& event : maEventData)
+ event.ApplyProperties();
+ maEventData.clear();
+ }
+
+ // only do something if we have shapes to sort
+ if( maZOrderList.empty() )
+ return;
+
+ // check if there are more shapes than inserted with ::shapeWithZIndexAdded()
+ // This can happen if there where already shapes on the page before import
+ // Since the writer may delete some of this shapes during import, we need
+ // to do this here and not in our c'tor anymore
+
+ // check if we have more shapes than we know of
+ sal_Int32 nCount = mxShapes->getCount();
+
+ nCount -= maZOrderList.size();
+ nCount -= maUnsortedList.size();
+
+ if( nCount > 0 )
+ {
+ // first update offsets of added shapes
+ for (ZOrderHint& rHint : maZOrderList)
+ rHint.nIs += nCount;
+ for (ZOrderHint& rHint : maUnsortedList)
+ rHint.nIs += nCount;
+
+ // second add the already existing shapes in the unsorted list
+ ZOrderHint aNewHint;
+ aNewHint.pShape = nullptr;
+ do
+ {
+ nCount--;
+
+ aNewHint.nIs = nCount;
+ aNewHint.nShould = -1;
+
+ maUnsortedList.insert(maUnsortedList.begin(), aNewHint);
+ }
+ while( nCount );
+ }
+
+ bool bSorted = std::is_sorted(maZOrderList.begin(), maZOrderList.end(),
+ [](const ZOrderHint& rLeft, const ZOrderHint& rRight)
+ { return rLeft.nShould < rRight.nShould; } );
+
+ if (bSorted)
+ return; // nothin' to do
+
+ // sort z-ordered shapes by nShould field
+ std::sort(maZOrderList.begin(), maZOrderList.end());
+
+ uno::Reference<drawing::XShapes3> xShapes3(mxShapes, uno::UNO_QUERY);
+ if( xShapes3.is())
+ {
+ uno::Sequence<sal_Int32> aNewOrder(maZOrderList.size() + maUnsortedList.size());
+ auto pNewOrder = aNewOrder.getArray();
+ sal_Int32 nIndex = 0;
+
+ for (const ZOrderHint& rHint : maZOrderList)
+ {
+ // fill in the gaps from unordered list
+ for (std::vector<ZOrderHint>::iterator aIt = maUnsortedList.begin(); aIt != maUnsortedList.end() && nIndex < rHint.nShould; )
+ {
+ pNewOrder[nIndex++] = (*aIt).nIs;
+ aIt = maUnsortedList.erase(aIt);
+ }
+
+ pNewOrder[nIndex] = rHint.nIs;
+ nIndex++;
+ }
+
+ try
+ {
+ xShapes3->sort(aNewOrder);
+ maZOrderList.clear();
+ return;
+ }
+ catch (const css::lang::IllegalArgumentException& /*e*/)
+ {}
+ }
+
+ // this is the current index, all shapes before that
+ // index are finished
+ sal_Int32 nIndex = 0;
+ for (const ZOrderHint& rHint : maZOrderList)
+ {
+ for (std::vector<ZOrderHint>::iterator aIt = maUnsortedList.begin(); aIt != maUnsortedList.end() && nIndex < rHint.nShould; )
+ {
+ moveShape( (*aIt).nIs, nIndex++ );
+ aIt = maUnsortedList.erase(aIt);
+
+ }
+
+ if(rHint.nIs != nIndex )
+ moveShape( rHint.nIs, nIndex );
+
+ nIndex++;
+ }
+ maZOrderList.clear();
+}
+
+void XMLShapeImportHelper::pushGroupForPostProcessing( uno::Reference< drawing::XShapes >& rShapes )
+{
+ mpImpl->mpGroupContext = std::make_shared<ShapeGroupContext>( rShapes, mpImpl->mpGroupContext );
+}
+
+void XMLShapeImportHelper::addShapeEvents(SdXMLEventContextData& rData)
+{
+ if (mpImpl->mpGroupContext && mpImpl->mpGroupContext->mxShapes == rData.mxShape)
+ {
+ // tdf#127791 wait until a group is popped to set its event data so
+ // that the events are applied to all its children, which are not available
+ // at the start of the group tag
+ mpImpl->mpGroupContext->maEventData.push_back(rData);
+ }
+ else
+ rData.ApplyProperties();
+}
+
+void XMLShapeImportHelper::popGroupAndPostProcess()
+{
+ SAL_WARN_IF( !mpImpl->mpGroupContext, "xmloff", "No context to sort!" );
+ if( !mpImpl->mpGroupContext )
+ return;
+
+ try
+ {
+ mpImpl->mpGroupContext->popGroupAndPostProcess();
+ }
+ catch( const uno::Exception& )
+ {
+ DBG_UNHANDLED_EXCEPTION("xmloff", "exception while sorting shapes, sorting failed");
+ }
+
+ // put parent on top and drop current context, we are done
+ mpImpl->mpGroupContext = mpImpl->mpGroupContext->mpParentContext;
+}
+
+void XMLShapeImportHelper::shapeWithZIndexAdded( css::uno::Reference< css::drawing::XShape > const & xShape, sal_Int32 nZIndex )
+{
+ if( !mpImpl->mpGroupContext)
+ return;
+
+ ZOrderHint aNewHint;
+ aNewHint.nIs = mpImpl->mpGroupContext->mnCurrentZ++;
+ aNewHint.nShould = nZIndex;
+ aNewHint.pShape = xShape.get();
+
+ if( nZIndex == -1 )
+ {
+ // don't care, so add to unsorted list
+ mpImpl->mpGroupContext->maUnsortedList.push_back(aNewHint);
+ }
+ else
+ {
+ // insert into sort list
+ mpImpl->mpGroupContext->maZOrderList.push_back(aNewHint);
+ }
+}
+
+void XMLShapeImportHelper::shapeRemoved(const uno::Reference<drawing::XShape>& xShape)
+{
+ auto it = std::find_if(mpImpl->mpGroupContext->maZOrderList.begin(), mpImpl->mpGroupContext->maZOrderList.end(), [&xShape](const ZOrderHint& rHint)
+ {
+ return rHint.pShape == xShape.get();
+ });
+ if (it == mpImpl->mpGroupContext->maZOrderList.end())
+ // Part of the unsorted list, nothing to do.
+ return;
+
+ sal_Int32 nZIndex = it->nIs;
+
+ for (it = mpImpl->mpGroupContext->maZOrderList.begin(); it != mpImpl->mpGroupContext->maZOrderList.end();)
+ {
+ if (it->nIs == nZIndex)
+ {
+ // This is xShape: remove it and adjust the max of indexes
+ // accordingly.
+ it = mpImpl->mpGroupContext->maZOrderList.erase(it);
+ mpImpl->mpGroupContext->mnCurrentZ--;
+ continue;
+ }
+ else if (it->nIs > nZIndex)
+ // On top of xShape: adjust actual index to reflect removal.
+ it->nIs--;
+
+ // On top of or below xShape.
+ ++it;
+ }
+}
+
+void XMLShapeImportHelper::addShapeConnection( css::uno::Reference< css::drawing::XShape > const & rConnectorShape,
+ bool bStart,
+ const OUString& rDestShapeId,
+ sal_Int32 nDestGlueId )
+{
+ ConnectionHint aHint;
+ aHint.mxConnector = rConnectorShape;
+ aHint.bStart = bStart;
+ aHint.aDestShapeId = rDestShapeId;
+ aHint.nDestGlueId = nDestGlueId;
+
+ mpImpl->maConnections.push_back( aHint );
+}
+
+void XMLShapeImportHelper::restoreConnections()
+{
+ const std::vector<ConnectionHint>::size_type nCount = mpImpl->maConnections.size();
+ for( std::vector<ConnectionHint>::size_type i = 0; i < nCount; i++ )
+ {
+ ConnectionHint& rHint = mpImpl->maConnections[i];
+ uno::Reference< beans::XPropertySet > xConnector( rHint.mxConnector, uno::UNO_QUERY );
+ if( xConnector.is() )
+ {
+ // #86637# remember line deltas
+ uno::Any aLine1Delta;
+ uno::Any aLine2Delta;
+ uno::Any aLine3Delta;
+ OUString aStr1("EdgeLine1Delta");
+ OUString aStr2("EdgeLine2Delta");
+ OUString aStr3("EdgeLine3Delta");
+ aLine1Delta = xConnector->getPropertyValue(aStr1);
+ aLine2Delta = xConnector->getPropertyValue(aStr2);
+ aLine3Delta = xConnector->getPropertyValue(aStr3);
+
+ // #86637# simply setting these values WILL force the connector to do
+ // a new layout promptly. So the line delta values have to be rescued
+ // and restored around connector changes.
+ uno::Reference< drawing::XShape > xShape(
+ mrImporter.getInterfaceToIdentifierMapper().getReference( rHint.aDestShapeId ), uno::UNO_QUERY );
+ if( xShape.is() )
+ {
+ if (rHint.bStart)
+ xConnector->setPropertyValue( gsStartShape, uno::Any(xShape) );
+ else
+ xConnector->setPropertyValue( gsEndShape, uno::Any(xShape) );
+
+ sal_Int32 nGlueId = rHint.nDestGlueId < 4 ? rHint.nDestGlueId : getGluePointId( xShape, rHint.nDestGlueId );
+ if(rHint.bStart)
+ xConnector->setPropertyValue( gsStartGluePointIndex, uno::Any(nGlueId) );
+ else
+ xConnector->setPropertyValue( gsEndGluePointIndex, uno::Any(nGlueId) );
+ }
+
+ // #86637# restore line deltas
+ xConnector->setPropertyValue(aStr1, aLine1Delta );
+ xConnector->setPropertyValue(aStr2, aLine2Delta );
+ xConnector->setPropertyValue(aStr3, aLine3Delta );
+ }
+ }
+ mpImpl->maConnections.clear();
+}
+
+SvXMLImportPropertyMapper* XMLShapeImportHelper::CreateShapePropMapper( const uno::Reference< frame::XModel>& rModel, SvXMLImport& rImport )
+{
+ rtl::Reference< XMLPropertyHandlerFactory > xFactory = new XMLSdPropHdlFactory( rModel, rImport );
+ rtl::Reference < XMLPropertySetMapper > xMapper = new XMLShapePropertySetMapper( xFactory, false );
+ SvXMLImportPropertyMapper* pResult = new SvXMLImportPropertyMapper( xMapper, rImport );
+
+ // chain text attributes
+ pResult->ChainImportMapper( XMLTextImportHelper::CreateParaExtPropMapper( rImport ) );
+ return pResult;
+}
+
+/** adds a mapping for a gluepoint identifier from an xml file to the identifier created after inserting
+ the new gluepoint into the core. The saved mappings can be retrieved by getGluePointId() */
+void XMLShapeImportHelper::addGluePointMapping( css::uno::Reference< css::drawing::XShape > const & xShape,
+ sal_Int32 nSourceId, sal_Int32 nDestinnationId )
+{
+ if( mpPageContext )
+ mpPageContext->maShapeGluePointsMap[xShape][nSourceId] = nDestinnationId;
+}
+
+/** moves all current DestinationId's by n */
+void XMLShapeImportHelper::moveGluePointMapping( const css::uno::Reference< css::drawing::XShape >& xShape, const sal_Int32 n )
+{
+ if( mpPageContext )
+ {
+ ShapeGluePointsMap::iterator aShapeIter( mpPageContext->maShapeGluePointsMap.find( xShape ) );
+ if( aShapeIter != mpPageContext->maShapeGluePointsMap.end() )
+ {
+ for ( auto& rShapeId : (*aShapeIter).second )
+ {
+ if ( rShapeId.second != -1 )
+ rShapeId.second += n;
+ }
+ }
+ }
+}
+
+/** retrieves a mapping for a gluepoint identifier from the current xml file to the identifier created after
+ inserting the new gluepoint into the core. The mapping must be initialized first with addGluePointMapping() */
+sal_Int32 XMLShapeImportHelper::getGluePointId( const css::uno::Reference< css::drawing::XShape >& xShape, sal_Int32 nSourceId )
+{
+ if( mpPageContext )
+ {
+ ShapeGluePointsMap::iterator aShapeIter( mpPageContext->maShapeGluePointsMap.find( xShape ) );
+ if( aShapeIter != mpPageContext->maShapeGluePointsMap.end() )
+ {
+ GluePointIdMap::iterator aIdIter = (*aShapeIter).second.find(nSourceId);
+ if( aIdIter != (*aShapeIter).second.end() )
+ return (*aIdIter).second;
+ }
+ }
+
+ return -1;
+}
+
+/** this method must be calling before the first shape is imported for the given page */
+void XMLShapeImportHelper::startPage( css::uno::Reference< css::drawing::XShapes > const & rShapes )
+{
+ const std::shared_ptr<XMLShapeImportPageContextImpl> pOldContext = mpPageContext;
+ mpPageContext = std::make_shared<XMLShapeImportPageContextImpl>();
+ mpPageContext->mpNext = pOldContext;
+ mpPageContext->mxShapes = rShapes;
+}
+
+/** this method must be calling after the last shape is imported for the given page */
+void XMLShapeImportHelper::endPage( css::uno::Reference< css::drawing::XShapes > const & rShapes )
+{
+ SAL_WARN_IF( !mpPageContext || (mpPageContext->mxShapes != rShapes), "xmloff", "wrong call to endPage(), no startPage called or wrong page" );
+ if( nullptr == mpPageContext )
+ return;
+
+ restoreConnections();
+
+ mpPageContext = mpPageContext->mpNext;
+}
+
+/** defines if the import should increment the progress bar or not */
+void XMLShapeImportHelper::enableHandleProgressBar()
+{
+ mpImpl->mbHandleProgressBar = true;
+}
+
+bool XMLShapeImportHelper::IsHandleProgressBarEnabled() const
+{
+ return mpImpl->mbHandleProgressBar;
+}
+
+/** queries the capability of the current model to create presentation shapes */
+bool XMLShapeImportHelper::IsPresentationShapesSupported() const
+{
+ return mpImpl->mbIsPresentationShapesSupported;
+}
+
+const rtl::Reference< XMLTableImport >& XMLShapeImportHelper::GetShapeTableImport()
+{
+ if( !mxShapeTableImport.is() )
+ {
+ rtl::Reference< XMLPropertyHandlerFactory > xFactory( new XMLSdPropHdlFactory( mrImporter.GetModel(), mrImporter ) );
+ rtl::Reference< XMLPropertySetMapper > xPropertySetMapper( new XMLShapePropertySetMapper( xFactory, false ) );
+ mxShapeTableImport = new XMLTableImport( mrImporter, xPropertySetMapper, xFactory );
+ }
+
+ return mxShapeTableImport;
+}
+
+void SvXMLShapeContext::setHyperlink( const OUString& rHyperlink )
+{
+ msHyperlink = rHyperlink;
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/xmloff/source/draw/xexptran.cxx b/xmloff/source/draw/xexptran.cxx
new file mode 100644
index 0000000000..c3ea5a4b0f
--- /dev/null
+++ b/xmloff/source/draw/xexptran.cxx
@@ -0,0 +1,1056 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#include <sal/config.h>
+
+#include <string_view>
+
+#include <utility>
+#include <xexptran.hxx>
+#include <rtl/ustrbuf.hxx>
+#include <osl/diagnose.h>
+#include <sax/tools/converter.hxx>
+#include <xmloff/xmluconv.hxx>
+#include <basegfx/matrix/b2dhommatrix.hxx>
+#include <basegfx/tuple/b2dtuple.hxx>
+#include <basegfx/tuple/b3dtuple.hxx>
+#include <basegfx/matrix/b3dhommatrix.hxx>
+#include <basegfx/numeric/ftools.hxx>
+#include <basegfx/matrix/b3dhommatrixtools.hxx>
+
+using namespace ::com::sun::star;
+
+// parsing help functions for simple chars
+static void Imp_SkipSpaces(std::u16string_view rStr, sal_Int32& rPos, const sal_Int32 nLen)
+{
+ while(rPos < nLen
+ && ' ' == rStr[rPos])
+ rPos++;
+}
+
+static void Imp_SkipSpacesAndOpeningBraces(std::u16string_view rStr, sal_Int32& rPos, const sal_Int32 nLen)
+{
+ while(rPos < nLen
+ && (' ' == rStr[rPos] || '(' == rStr[rPos]))
+ rPos++;
+}
+
+static void Imp_SkipSpacesAndCommas(std::u16string_view rStr, sal_Int32& rPos, const sal_Int32 nLen)
+{
+ while(rPos < nLen
+ && (' ' == rStr[rPos] || ',' == rStr[rPos]))
+ rPos++;
+}
+
+static void Imp_SkipSpacesAndClosingBraces(std::u16string_view rStr, sal_Int32& rPos, const sal_Int32 nLen)
+{
+ while(rPos < nLen
+ && (' ' == rStr[rPos] || ')' == rStr[rPos]))
+ rPos++;
+}
+
+// parsing help functions for integer numbers
+
+static bool Imp_IsOnUnitChar(std::u16string_view rStr, const sal_Int32 nPos)
+{
+ sal_Unicode aChar(rStr[nPos]);
+
+ return ('a' <= aChar && 'z' >= aChar)
+ || ('A' <= aChar && 'Z' >= aChar)
+ || '%' == aChar;
+}
+
+static double Imp_GetDoubleChar(std::u16string_view rStr, sal_Int32& rPos, const sal_Int32 nLen,
+ const SvXMLUnitConverter& rConv, double fRetval, bool bLookForUnits = false)
+{
+ sal_Unicode aChar(rStr[rPos]);
+ OUStringBuffer sNumberString(32);
+
+ if('+' == aChar || '-' == aChar)
+ {
+ sNumberString.append(rStr[rPos]);
+ ++rPos;
+ aChar = rPos >= nLen ? 0 : rStr[rPos];
+ }
+
+ while(('0' <= aChar && '9' >= aChar)
+ || '.' == aChar)
+ {
+ sNumberString.append(rStr[rPos]);
+ ++rPos;
+ aChar = rPos >= nLen ? 0 : rStr[rPos];
+ }
+
+ if('e' == aChar || 'E' == aChar)
+ {
+ sNumberString.append(rStr[rPos]);
+ ++rPos;
+ aChar = rPos >= nLen ? 0 : rStr[rPos];
+
+ if('+' == aChar || '-' == aChar)
+ {
+ sNumberString.append(rStr[rPos]);
+ ++rPos;
+ aChar = rPos >= nLen ? 0 : rStr[rPos];
+ }
+
+ while('0' <= aChar && '9' >= aChar)
+ {
+ sNumberString.append(rStr[rPos]);
+ ++rPos;
+ aChar = rPos >= nLen ? 0 : rStr[rPos];
+ }
+ }
+
+ if(bLookForUnits)
+ {
+ Imp_SkipSpaces(rStr, rPos, nLen);
+ while(rPos < nLen && Imp_IsOnUnitChar(rStr, rPos))
+ sNumberString.append(rStr[rPos++]);
+ }
+
+ if(!sNumberString.isEmpty())
+ {
+ if(bLookForUnits)
+ rConv.convertDouble(fRetval, sNumberString);
+ else
+ {
+ ::sax::Converter::convertDouble(fRetval, sNumberString);
+ }
+ }
+
+ return fRetval;
+}
+
+static void Imp_PutDoubleChar(OUString& rStr, double fValue)
+{
+ OUStringBuffer sStringBuffer;
+ ::sax::Converter::convertDouble(sStringBuffer, fValue);
+ rStr += sStringBuffer;
+}
+
+static void Imp_PutDoubleChar(OUStringBuffer& rStr, const SvXMLUnitConverter& rConv, double fValue,
+ bool bConvertUnits = false)
+{
+ OUStringBuffer sStringBuffer;
+
+ if(bConvertUnits)
+ rConv.convertDouble(sStringBuffer, fValue);
+ else
+ {
+ ::sax::Converter::convertDouble(sStringBuffer, fValue);
+ }
+
+ rStr.append(sStringBuffer);
+}
+
+// base class of all 2D transform objects
+
+struct ImpSdXMLExpTransObj2DBase
+{
+ sal_uInt16 mnType;
+ explicit ImpSdXMLExpTransObj2DBase(sal_uInt16 nType)
+ : mnType(nType) {}
+};
+
+// possible object types for 2D
+
+#define IMP_SDXMLEXP_TRANSOBJ2D_ROTATE 0x0000
+#define IMP_SDXMLEXP_TRANSOBJ2D_SCALE 0x0001
+#define IMP_SDXMLEXP_TRANSOBJ2D_TRANSLATE 0x0002
+#define IMP_SDXMLEXP_TRANSOBJ2D_SKEWX 0x0003
+#define IMP_SDXMLEXP_TRANSOBJ2D_SKEWY 0x0004
+#define IMP_SDXMLEXP_TRANSOBJ2D_MATRIX 0x0005
+
+// classes of objects, different sizes
+
+namespace {
+
+struct ImpSdXMLExpTransObj2DRotate : public ImpSdXMLExpTransObj2DBase
+{
+ double mfRotate;
+ explicit ImpSdXMLExpTransObj2DRotate(double fVal)
+ : ImpSdXMLExpTransObj2DBase(IMP_SDXMLEXP_TRANSOBJ2D_ROTATE), mfRotate(fVal) {}
+};
+struct ImpSdXMLExpTransObj2DScale : public ImpSdXMLExpTransObj2DBase
+{
+ ::basegfx::B2DTuple maScale;
+ explicit ImpSdXMLExpTransObj2DScale(const ::basegfx::B2DTuple& rNew)
+ : ImpSdXMLExpTransObj2DBase(IMP_SDXMLEXP_TRANSOBJ2D_SCALE), maScale(rNew) {}
+};
+struct ImpSdXMLExpTransObj2DTranslate : public ImpSdXMLExpTransObj2DBase
+{
+ ::basegfx::B2DTuple maTranslate;
+ explicit ImpSdXMLExpTransObj2DTranslate(const ::basegfx::B2DTuple& rNew)
+ : ImpSdXMLExpTransObj2DBase(IMP_SDXMLEXP_TRANSOBJ2D_TRANSLATE), maTranslate(rNew) {}
+};
+struct ImpSdXMLExpTransObj2DSkewX : public ImpSdXMLExpTransObj2DBase
+{
+ double mfSkewX;
+ explicit ImpSdXMLExpTransObj2DSkewX(double fVal)
+ : ImpSdXMLExpTransObj2DBase(IMP_SDXMLEXP_TRANSOBJ2D_SKEWX), mfSkewX(fVal) {}
+};
+struct ImpSdXMLExpTransObj2DSkewY : public ImpSdXMLExpTransObj2DBase
+{
+ double mfSkewY;
+ explicit ImpSdXMLExpTransObj2DSkewY(double fVal)
+ : ImpSdXMLExpTransObj2DBase(IMP_SDXMLEXP_TRANSOBJ2D_SKEWY), mfSkewY(fVal) {}
+};
+struct ImpSdXMLExpTransObj2DMatrix : public ImpSdXMLExpTransObj2DBase
+{
+ ::basegfx::B2DHomMatrix maMatrix;
+ explicit ImpSdXMLExpTransObj2DMatrix(::basegfx::B2DHomMatrix aNew)
+ : ImpSdXMLExpTransObj2DBase(IMP_SDXMLEXP_TRANSOBJ2D_MATRIX), maMatrix(std::move(aNew)) {}
+};
+
+}
+
+// add members
+
+void SdXMLImExTransform2D::AddRotate(double fNew)
+{
+ if(fNew != 0.0)
+ maList.push_back(std::make_shared<ImpSdXMLExpTransObj2DRotate>(fNew));
+}
+
+void SdXMLImExTransform2D::AddTranslate(const ::basegfx::B2DTuple& rNew)
+{
+ if(!rNew.equalZero())
+ maList.push_back(std::make_shared<ImpSdXMLExpTransObj2DTranslate>(rNew));
+}
+
+void SdXMLImExTransform2D::AddSkewX(double fNew)
+{
+ if(fNew != 0.0)
+ maList.push_back(std::make_shared<ImpSdXMLExpTransObj2DSkewX>(fNew));
+}
+
+// gen string for export
+const OUString& SdXMLImExTransform2D::GetExportString(const SvXMLUnitConverter& rConv)
+{
+ OUStringBuffer aNewString;
+ OUString aClosingBrace(")");
+ OUString aEmptySpace(" ");
+
+ const sal_uInt32 nCount = maList.size();
+ for(sal_uInt32 a(0); a < nCount; a++)
+ {
+ ImpSdXMLExpTransObj2DBase* pObj = maList[a].get();
+ switch(pObj->mnType)
+ {
+ case IMP_SDXMLEXP_TRANSOBJ2D_ROTATE :
+ {
+ aNewString.append("rotate (");
+ Imp_PutDoubleChar(aNewString, rConv, static_cast<ImpSdXMLExpTransObj2DRotate*>(pObj)->mfRotate);
+ aNewString.append(aClosingBrace);
+ break;
+ }
+ case IMP_SDXMLEXP_TRANSOBJ2D_SCALE :
+ {
+ aNewString.append("scale (");
+ Imp_PutDoubleChar(aNewString, rConv, static_cast<ImpSdXMLExpTransObj2DScale*>(pObj)->maScale.getX());
+ aNewString.append(aEmptySpace);
+ Imp_PutDoubleChar(aNewString, rConv, static_cast<ImpSdXMLExpTransObj2DScale*>(pObj)->maScale.getY());
+ aNewString.append(aClosingBrace);
+ break;
+ }
+ case IMP_SDXMLEXP_TRANSOBJ2D_TRANSLATE :
+ {
+ aNewString.append("translate (");
+ Imp_PutDoubleChar(aNewString, rConv, static_cast<ImpSdXMLExpTransObj2DTranslate*>(pObj)->maTranslate.getX(), true);
+ aNewString.append(aEmptySpace);
+ Imp_PutDoubleChar(aNewString, rConv, static_cast<ImpSdXMLExpTransObj2DTranslate*>(pObj)->maTranslate.getY(), true);
+ aNewString.append(aClosingBrace);
+ break;
+ }
+ case IMP_SDXMLEXP_TRANSOBJ2D_SKEWX :
+ {
+ aNewString.append("skewX (");
+ Imp_PutDoubleChar(aNewString, rConv, static_cast<ImpSdXMLExpTransObj2DSkewX*>(pObj)->mfSkewX);
+ aNewString.append(aClosingBrace);
+ break;
+ }
+ case IMP_SDXMLEXP_TRANSOBJ2D_SKEWY :
+ {
+ aNewString.append("skewY (");
+ Imp_PutDoubleChar(aNewString, rConv, static_cast<ImpSdXMLExpTransObj2DSkewY*>(pObj)->mfSkewY);
+ aNewString.append(aClosingBrace);
+ break;
+ }
+ case IMP_SDXMLEXP_TRANSOBJ2D_MATRIX :
+ {
+ aNewString.append("matrix (");
+
+ // a
+ Imp_PutDoubleChar(aNewString, rConv, static_cast<ImpSdXMLExpTransObj2DMatrix*>(pObj)->maMatrix.get(0, 0));
+ aNewString.append(aEmptySpace);
+
+ // b
+ Imp_PutDoubleChar(aNewString, rConv, static_cast<ImpSdXMLExpTransObj2DMatrix*>(pObj)->maMatrix.get(1, 0));
+ aNewString.append(aEmptySpace);
+
+ // c
+ Imp_PutDoubleChar(aNewString, rConv, static_cast<ImpSdXMLExpTransObj2DMatrix*>(pObj)->maMatrix.get(0, 1));
+ aNewString.append(aEmptySpace);
+
+ // d
+ Imp_PutDoubleChar(aNewString, rConv, static_cast<ImpSdXMLExpTransObj2DMatrix*>(pObj)->maMatrix.get(1, 1));
+ aNewString.append(aEmptySpace);
+
+ // e
+ Imp_PutDoubleChar(aNewString, rConv, static_cast<ImpSdXMLExpTransObj2DMatrix*>(pObj)->maMatrix.get(0, 2), true);
+ aNewString.append(aEmptySpace);
+
+ // f
+ Imp_PutDoubleChar(aNewString, rConv, static_cast<ImpSdXMLExpTransObj2DMatrix*>(pObj)->maMatrix.get(1, 2), true);
+
+ aNewString.append(aClosingBrace);
+ break;
+ }
+ default :
+ {
+ OSL_FAIL("SdXMLImExTransform2D: impossible entry!");
+ break;
+ }
+ }
+
+ // if not the last entry, add one space to next tag
+ if(a + 1 != maList.size())
+ {
+ aNewString.append(aEmptySpace);
+ }
+ }
+
+ // fill string form OUString
+ msString = aNewString.makeStringAndClear();
+
+ return msString;
+}
+
+// sets new string, parses it and generates entries
+void SdXMLImExTransform2D::SetString(const OUString& rNew, const SvXMLUnitConverter& rConv)
+{
+ msString = rNew;
+ maList.clear();
+
+ if(msString.isEmpty())
+ return;
+
+ const OUString aStr = msString;
+ const sal_Int32 nLen(aStr.getLength());
+
+ static constexpr OUStringLiteral aString_rotate( u"rotate" );
+ static constexpr OUStringLiteral aString_scale( u"scale" );
+ static constexpr OUStringLiteral aString_translate( u"translate" );
+ static constexpr OUStringLiteral aString_skewX( u"skewX" );
+ static constexpr OUStringLiteral aString_skewY( u"skewY" );
+ static constexpr OUStringLiteral aString_matrix( u"matrix" );
+
+ sal_Int32 nPos(0);
+
+ while(nPos < nLen)
+ {
+ // skip spaces
+ Imp_SkipSpaces(aStr, nPos, nLen);
+
+ // look for tag
+ if(nPos < nLen)
+ {
+ if(nPos == aStr.indexOf(aString_rotate, nPos))
+ {
+ double fValue(0.0);
+ nPos += 6;
+ Imp_SkipSpacesAndOpeningBraces(aStr, nPos, nLen);
+ fValue = Imp_GetDoubleChar(aStr, nPos, nLen, rConv, fValue);
+ if(fValue != 0.0)
+ maList.push_back(std::make_shared<ImpSdXMLExpTransObj2DRotate>(fValue));
+
+ Imp_SkipSpacesAndClosingBraces(aStr, nPos, nLen);
+ }
+ else if(nPos == aStr.indexOf(aString_scale, nPos))
+ {
+ ::basegfx::B2DTuple aValue(1.0, 1.0);
+ nPos += 5;
+ Imp_SkipSpacesAndOpeningBraces(aStr, nPos, nLen);
+ aValue.setX(Imp_GetDoubleChar(aStr, nPos, nLen, rConv, aValue.getX()));
+ Imp_SkipSpacesAndCommas(aStr, nPos, nLen);
+ aValue.setY(Imp_GetDoubleChar(aStr, nPos, nLen, rConv, aValue.getY()));
+
+ if(aValue.getX() != 1.0 || aValue.getY() != 1.0)
+ maList.push_back(std::make_shared<ImpSdXMLExpTransObj2DScale>(aValue));
+
+ Imp_SkipSpacesAndClosingBraces(aStr, nPos, nLen);
+ }
+ else if(nPos == aStr.indexOf(aString_translate, nPos))
+ {
+ ::basegfx::B2DTuple aValue;
+ nPos += 9;
+ Imp_SkipSpacesAndOpeningBraces(aStr, nPos, nLen);
+ aValue.setX(Imp_GetDoubleChar(aStr, nPos, nLen, rConv, aValue.getX(), true));
+ Imp_SkipSpacesAndCommas(aStr, nPos, nLen);
+ aValue.setY(Imp_GetDoubleChar(aStr, nPos, nLen, rConv, aValue.getY(), true));
+
+ if(!aValue.equalZero())
+ maList.push_back(std::make_shared<ImpSdXMLExpTransObj2DTranslate>(aValue));
+
+ Imp_SkipSpacesAndClosingBraces(aStr, nPos, nLen);
+ }
+ else if(nPos == aStr.indexOf(aString_skewX, nPos))
+ {
+ double fValue(0.0);
+ nPos += 5;
+ Imp_SkipSpacesAndOpeningBraces(aStr, nPos, nLen);
+ fValue = Imp_GetDoubleChar(aStr, nPos, nLen, rConv, fValue);
+ if(fValue != 0.0)
+ maList.push_back(std::make_shared<ImpSdXMLExpTransObj2DSkewX>(fValue));
+
+ Imp_SkipSpacesAndClosingBraces(aStr, nPos, nLen);
+ }
+ else if(nPos == aStr.indexOf(aString_skewY, nPos))
+ {
+ double fValue(0.0);
+ nPos += 5;
+ Imp_SkipSpacesAndOpeningBraces(aStr, nPos, nLen);
+ fValue = Imp_GetDoubleChar(aStr, nPos, nLen, rConv, fValue);
+ if(fValue != 0.0)
+ maList.push_back(std::make_shared<ImpSdXMLExpTransObj2DSkewY>(fValue));
+
+ Imp_SkipSpacesAndClosingBraces(aStr, nPos, nLen);
+ }
+ else if(nPos == aStr.indexOf(aString_matrix, nPos))
+ {
+ ::basegfx::B2DHomMatrix aValue;
+
+ nPos += 6;
+ Imp_SkipSpacesAndOpeningBraces(aStr, nPos, nLen);
+
+ // a
+ aValue.set(0, 0, Imp_GetDoubleChar(aStr, nPos, nLen, rConv, aValue.get(0, 0)));
+ Imp_SkipSpacesAndCommas(aStr, nPos, nLen);
+
+ // b
+ aValue.set(1, 0, Imp_GetDoubleChar(aStr, nPos, nLen, rConv, aValue.get(1, 0)));
+ Imp_SkipSpacesAndCommas(aStr, nPos, nLen);
+
+ // c
+ aValue.set(0, 1, Imp_GetDoubleChar(aStr, nPos, nLen, rConv, aValue.get(0, 1)));
+ Imp_SkipSpacesAndCommas(aStr, nPos, nLen);
+
+ // d
+ aValue.set(1, 1, Imp_GetDoubleChar(aStr, nPos, nLen, rConv, aValue.get(1, 1)));
+ Imp_SkipSpacesAndCommas(aStr, nPos, nLen);
+
+ // e
+ aValue.set(0, 2, Imp_GetDoubleChar(aStr, nPos, nLen, rConv, aValue.get(0, 2), true));
+ Imp_SkipSpacesAndCommas(aStr, nPos, nLen);
+
+ // f
+ aValue.set(1, 2, Imp_GetDoubleChar(aStr, nPos, nLen, rConv, aValue.get(1, 2), true));
+ Imp_SkipSpacesAndCommas(aStr, nPos, nLen);
+
+ if(!aValue.isIdentity())
+ maList.push_back(std::make_shared<ImpSdXMLExpTransObj2DMatrix>(aValue));
+
+ Imp_SkipSpacesAndClosingBraces(aStr, nPos, nLen);
+ }
+ else
+ {
+ nPos++;
+ }
+ }
+ }
+}
+
+void SdXMLImExTransform2D::GetFullTransform(::basegfx::B2DHomMatrix& rFullTrans)
+{
+ rFullTrans.identity();
+
+ const sal_uInt32 nCount = maList.size();
+ for(sal_uInt32 a(0); a < nCount; a++)
+ {
+ ImpSdXMLExpTransObj2DBase* pObj = maList[a].get();
+ switch(pObj->mnType)
+ {
+ case IMP_SDXMLEXP_TRANSOBJ2D_ROTATE :
+ {
+ // #i78696#
+ // mfRotate is mathematically wrong oriented since we export/import the angle
+ // values mirrored. This error is fixed in the API, but not yet in the FileFormat.
+ // For the FileFormat there is a follow-up task (#i78698#) to fix this in the next
+ // ODF FileFormat version. For now - to emulate the old behaviour - it is necessary
+ // to mirror the value here
+ rFullTrans.rotate(static_cast<ImpSdXMLExpTransObj2DRotate*>(pObj)->mfRotate * -1.0);
+ break;
+ }
+ case IMP_SDXMLEXP_TRANSOBJ2D_SCALE :
+ {
+ const ::basegfx::B2DTuple& rScale = static_cast<ImpSdXMLExpTransObj2DScale*>(pObj)->maScale;
+ rFullTrans.scale(rScale.getX(), rScale.getY());
+ break;
+ }
+ case IMP_SDXMLEXP_TRANSOBJ2D_TRANSLATE :
+ {
+ const ::basegfx::B2DTuple& rTranslate = static_cast<ImpSdXMLExpTransObj2DTranslate*>(pObj)->maTranslate;
+ rFullTrans.translate(rTranslate.getX(), rTranslate.getY());
+ break;
+ }
+ case IMP_SDXMLEXP_TRANSOBJ2D_SKEWX :
+ {
+ // For to get a mathematical correct matrix from already existing documents,
+ // mirror the value here. ODF spec is unclear about direction.
+ rFullTrans.shearX(-tan(static_cast<ImpSdXMLExpTransObj2DSkewX*>(pObj)->mfSkewX));
+ break;
+ }
+ case IMP_SDXMLEXP_TRANSOBJ2D_SKEWY :
+ {
+ // LibreOffice does not write skewY, OOo neither. Such files are foreign documents
+ // or manually set transformations. OOo had used the value as -tan(value) before
+ // errors were introduced, Scribus 1.5.4 uses it as -tan(value) too, MS Office does
+ // not shear at all. ODF spec is unclear about direction.
+ rFullTrans.shearY(-tan(static_cast<ImpSdXMLExpTransObj2DSkewY*>(pObj)->mfSkewY));
+ break;
+ }
+ case IMP_SDXMLEXP_TRANSOBJ2D_MATRIX :
+ {
+ rFullTrans *= static_cast<ImpSdXMLExpTransObj2DMatrix*>(pObj)->maMatrix;
+ break;
+ }
+ default :
+ {
+ OSL_FAIL("SdXMLImExTransform2D: impossible entry!");
+ break;
+ }
+ }
+ }
+}
+
+// base class of all 3D transform objects
+
+struct ImpSdXMLExpTransObj3DBase
+{
+ sal_uInt16 mnType;
+ explicit ImpSdXMLExpTransObj3DBase(sal_uInt16 nType)
+ : mnType(nType) {}
+};
+
+// possible object types for 3D
+
+#define IMP_SDXMLEXP_TRANSOBJ3D_ROTATE_X 0x0000
+#define IMP_SDXMLEXP_TRANSOBJ3D_ROTATE_Y 0x0001
+#define IMP_SDXMLEXP_TRANSOBJ3D_ROTATE_Z 0x0002
+#define IMP_SDXMLEXP_TRANSOBJ3D_SCALE 0x0003
+#define IMP_SDXMLEXP_TRANSOBJ3D_TRANSLATE 0x0004
+#define IMP_SDXMLEXP_TRANSOBJ3D_MATRIX 0x0005
+
+// classes of objects, different sizes
+
+namespace {
+
+struct ImpSdXMLExpTransObj3DRotateX : public ImpSdXMLExpTransObj3DBase
+{
+ double mfRotateX;
+ explicit ImpSdXMLExpTransObj3DRotateX(double fVal)
+ : ImpSdXMLExpTransObj3DBase(IMP_SDXMLEXP_TRANSOBJ3D_ROTATE_X), mfRotateX(fVal) {}
+};
+struct ImpSdXMLExpTransObj3DRotateY : public ImpSdXMLExpTransObj3DBase
+{
+ double mfRotateY;
+ explicit ImpSdXMLExpTransObj3DRotateY(double fVal)
+ : ImpSdXMLExpTransObj3DBase(IMP_SDXMLEXP_TRANSOBJ3D_ROTATE_Y), mfRotateY(fVal) {}
+};
+struct ImpSdXMLExpTransObj3DRotateZ : public ImpSdXMLExpTransObj3DBase
+{
+ double mfRotateZ;
+ explicit ImpSdXMLExpTransObj3DRotateZ(double fVal)
+ : ImpSdXMLExpTransObj3DBase(IMP_SDXMLEXP_TRANSOBJ3D_ROTATE_Z), mfRotateZ(fVal) {}
+};
+struct ImpSdXMLExpTransObj3DScale : public ImpSdXMLExpTransObj3DBase
+{
+ ::basegfx::B3DTuple maScale;
+ explicit ImpSdXMLExpTransObj3DScale(const ::basegfx::B3DTuple& rNew)
+ : ImpSdXMLExpTransObj3DBase(IMP_SDXMLEXP_TRANSOBJ3D_SCALE), maScale(rNew) {}
+};
+struct ImpSdXMLExpTransObj3DTranslate : public ImpSdXMLExpTransObj3DBase
+{
+ ::basegfx::B3DTuple maTranslate;
+ explicit ImpSdXMLExpTransObj3DTranslate(const ::basegfx::B3DTuple& rNew)
+ : ImpSdXMLExpTransObj3DBase(IMP_SDXMLEXP_TRANSOBJ3D_TRANSLATE), maTranslate(rNew) {}
+};
+struct ImpSdXMLExpTransObj3DMatrix : public ImpSdXMLExpTransObj3DBase
+{
+ ::basegfx::B3DHomMatrix maMatrix;
+ explicit ImpSdXMLExpTransObj3DMatrix(::basegfx::B3DHomMatrix aNew)
+ : ImpSdXMLExpTransObj3DBase(IMP_SDXMLEXP_TRANSOBJ3D_MATRIX), maMatrix(std::move(aNew)) {}
+};
+
+}
+
+// add members
+
+void SdXMLImExTransform3D::AddMatrix(const ::basegfx::B3DHomMatrix& rNew)
+{
+ if(!rNew.isIdentity())
+ maList.push_back(std::make_shared<ImpSdXMLExpTransObj3DMatrix>(rNew));
+}
+
+void SdXMLImExTransform3D::AddHomogenMatrix(const drawing::HomogenMatrix& xHomMat)
+{
+ AddMatrix(basegfx::utils::UnoHomogenMatrixToB3DHomMatrix(xHomMat));
+}
+
+// gen string for export
+const OUString& SdXMLImExTransform3D::GetExportString(const SvXMLUnitConverter& rConv)
+{
+ OUStringBuffer aNewString;
+ OUString aClosingBrace(")");
+ OUString aEmptySpace(" ");
+
+ const sal_uInt32 nCount = maList.size();
+ for(sal_uInt32 a(0); a < nCount; a++)
+ {
+ ImpSdXMLExpTransObj3DBase* pObj = maList[a].get();
+ switch(pObj->mnType)
+ {
+ case IMP_SDXMLEXP_TRANSOBJ3D_ROTATE_X :
+ {
+ aNewString.append("rotatex (");
+ Imp_PutDoubleChar(aNewString, rConv, basegfx::rad2deg( static_cast<ImpSdXMLExpTransObj3DRotateX*>(pObj)->mfRotateX) );
+ aNewString.append(aClosingBrace);
+ break;
+ }
+ case IMP_SDXMLEXP_TRANSOBJ3D_ROTATE_Y :
+ {
+ aNewString.append("rotatey (");
+ Imp_PutDoubleChar(aNewString, rConv, basegfx::rad2deg( static_cast<ImpSdXMLExpTransObj3DRotateY*>(pObj)->mfRotateY) );
+ aNewString.append(aClosingBrace);
+ break;
+ }
+ case IMP_SDXMLEXP_TRANSOBJ3D_ROTATE_Z :
+ {
+ aNewString.append("rotatez (");
+ Imp_PutDoubleChar(aNewString, rConv, basegfx::rad2deg( static_cast<ImpSdXMLExpTransObj3DRotateZ*>(pObj)->mfRotateZ) );
+ aNewString.append(aClosingBrace);
+ break;
+ }
+ case IMP_SDXMLEXP_TRANSOBJ3D_SCALE :
+ {
+ aNewString.append("scale (");
+ Imp_PutDoubleChar(aNewString, rConv, static_cast<ImpSdXMLExpTransObj3DScale*>(pObj)->maScale.getX());
+ aNewString.append(aEmptySpace);
+ Imp_PutDoubleChar(aNewString, rConv, static_cast<ImpSdXMLExpTransObj3DScale*>(pObj)->maScale.getY());
+ aNewString.append(aEmptySpace);
+ Imp_PutDoubleChar(aNewString, rConv, static_cast<ImpSdXMLExpTransObj3DScale*>(pObj)->maScale.getZ());
+ aNewString.append(aClosingBrace);
+ break;
+ }
+ case IMP_SDXMLEXP_TRANSOBJ3D_TRANSLATE :
+ {
+ aNewString.append("translate (");
+ Imp_PutDoubleChar(aNewString, rConv, static_cast<ImpSdXMLExpTransObj3DTranslate*>(pObj)->maTranslate.getX(), true);
+ aNewString.append(aEmptySpace);
+ Imp_PutDoubleChar(aNewString, rConv, static_cast<ImpSdXMLExpTransObj3DTranslate*>(pObj)->maTranslate.getY(), true);
+ aNewString.append(aEmptySpace);
+ Imp_PutDoubleChar(aNewString, rConv, static_cast<ImpSdXMLExpTransObj3DTranslate*>(pObj)->maTranslate.getZ(), true);
+ aNewString.append(aClosingBrace);
+ break;
+ }
+ case IMP_SDXMLEXP_TRANSOBJ3D_MATRIX :
+ {
+ aNewString.append("matrix (");
+
+ // a
+ Imp_PutDoubleChar(aNewString, rConv, static_cast<ImpSdXMLExpTransObj3DMatrix*>(pObj)->maMatrix.get(0, 0));
+ aNewString.append(aEmptySpace);
+
+ // b
+ Imp_PutDoubleChar(aNewString, rConv, static_cast<ImpSdXMLExpTransObj3DMatrix*>(pObj)->maMatrix.get(1, 0));
+ aNewString.append(aEmptySpace);
+
+ // c
+ Imp_PutDoubleChar(aNewString, rConv, static_cast<ImpSdXMLExpTransObj3DMatrix*>(pObj)->maMatrix.get(2, 0));
+ aNewString.append(aEmptySpace);
+
+ // d
+ Imp_PutDoubleChar(aNewString, rConv, static_cast<ImpSdXMLExpTransObj3DMatrix*>(pObj)->maMatrix.get(0, 1));
+ aNewString.append(aEmptySpace);
+
+ // e
+ Imp_PutDoubleChar(aNewString, rConv, static_cast<ImpSdXMLExpTransObj3DMatrix*>(pObj)->maMatrix.get(1, 1));
+ aNewString.append(aEmptySpace);
+
+ // f
+ Imp_PutDoubleChar(aNewString, rConv, static_cast<ImpSdXMLExpTransObj3DMatrix*>(pObj)->maMatrix.get(2, 1));
+ aNewString.append(aEmptySpace);
+
+ // g
+ Imp_PutDoubleChar(aNewString, rConv, static_cast<ImpSdXMLExpTransObj3DMatrix*>(pObj)->maMatrix.get(0, 2));
+ aNewString.append(aEmptySpace);
+
+ // h
+ Imp_PutDoubleChar(aNewString, rConv, static_cast<ImpSdXMLExpTransObj3DMatrix*>(pObj)->maMatrix.get(1, 2));
+ aNewString.append(aEmptySpace);
+
+ // i
+ Imp_PutDoubleChar(aNewString, rConv, static_cast<ImpSdXMLExpTransObj3DMatrix*>(pObj)->maMatrix.get(2, 2));
+ aNewString.append(aEmptySpace);
+
+ // j
+ Imp_PutDoubleChar(aNewString, rConv, static_cast<ImpSdXMLExpTransObj3DMatrix*>(pObj)->maMatrix.get(0, 3), true);
+ aNewString.append(aEmptySpace);
+
+ // k
+ Imp_PutDoubleChar(aNewString, rConv, static_cast<ImpSdXMLExpTransObj3DMatrix*>(pObj)->maMatrix.get(1, 3), true);
+ aNewString.append(aEmptySpace);
+
+ // l
+ Imp_PutDoubleChar(aNewString, rConv, static_cast<ImpSdXMLExpTransObj3DMatrix*>(pObj)->maMatrix.get(2, 3), true);
+
+ aNewString.append(aClosingBrace);
+ break;
+ }
+ default :
+ {
+ OSL_FAIL("SdXMLImExTransform3D: impossible entry!");
+ break;
+ }
+ }
+
+ // if not the last entry, add one space to next tag
+ if(a + 1 != maList.size())
+ {
+ aNewString.append(aEmptySpace);
+ }
+ }
+
+ // fill string form OUString
+ msString = aNewString.makeStringAndClear();
+
+ return msString;
+}
+
+// for Import: constructor with string, parses it and generates entries
+SdXMLImExTransform3D::SdXMLImExTransform3D(const OUString& rNew, const SvXMLUnitConverter& rConv)
+{
+ SetString(rNew, rConv);
+}
+
+// sets new string, parses it and generates entries
+void SdXMLImExTransform3D::SetString(const OUString& rNew, const SvXMLUnitConverter& rConv)
+{
+ msString = rNew;
+ maList.clear();
+
+ if(msString.isEmpty())
+ return;
+
+ const OUString aStr = msString;
+ const sal_Int32 nLen(aStr.getLength());
+
+ static constexpr OUStringLiteral aString_rotatex( u"rotatex" );
+ static constexpr OUStringLiteral aString_rotatey( u"rotatey" );
+ static constexpr OUStringLiteral aString_rotatez( u"rotatez" );
+ static constexpr OUStringLiteral aString_scale( u"scale" );
+ static constexpr OUStringLiteral aString_translate( u"translate" );
+ static constexpr OUStringLiteral aString_matrix( u"matrix" );
+
+ sal_Int32 nPos(0);
+
+ while(nPos < nLen)
+ {
+ // skip spaces
+ Imp_SkipSpaces(aStr, nPos, nLen);
+
+ // look for tag
+ if(nPos < nLen)
+ {
+ if(nPos == aStr.indexOf(aString_rotatex, nPos))
+ {
+ double fValue(0.0);
+
+ nPos += 7;
+ Imp_SkipSpacesAndOpeningBraces(aStr, nPos, nLen);
+ fValue = Imp_GetDoubleChar(aStr, nPos, nLen, rConv, fValue);
+ if(fValue != 0.0)
+ maList.push_back(std::make_shared<ImpSdXMLExpTransObj3DRotateX>(basegfx::deg2rad(fValue)));
+
+ Imp_SkipSpacesAndClosingBraces(aStr, nPos, nLen);
+ }
+ else if(nPos == aStr.indexOf(aString_rotatey, nPos))
+ {
+ double fValue(0.0);
+
+ nPos += 7;
+ Imp_SkipSpacesAndOpeningBraces(aStr, nPos, nLen);
+ fValue = Imp_GetDoubleChar(aStr, nPos, nLen, rConv, fValue);
+ if(fValue != 0.0)
+ maList.push_back(std::make_shared<ImpSdXMLExpTransObj3DRotateY>(basegfx::deg2rad(fValue)));
+
+ Imp_SkipSpacesAndClosingBraces(aStr, nPos, nLen);
+ }
+ else if(nPos == aStr.indexOf(aString_rotatez, nPos))
+ {
+ double fValue(0.0);
+
+ nPos += 7;
+ Imp_SkipSpacesAndOpeningBraces(aStr, nPos, nLen);
+ fValue = Imp_GetDoubleChar(aStr, nPos, nLen, rConv, fValue);
+ if(fValue != 0.0)
+ maList.push_back(std::make_shared<ImpSdXMLExpTransObj3DRotateZ>(basegfx::deg2rad(fValue)));
+
+ Imp_SkipSpacesAndClosingBraces(aStr, nPos, nLen);
+ }
+ else if(nPos == aStr.indexOf(aString_scale, nPos))
+ {
+ ::basegfx::B3DTuple aValue(1.0, 1.0, 1.0);
+
+ nPos += 5;
+ Imp_SkipSpacesAndOpeningBraces(aStr, nPos, nLen);
+ aValue.setX(Imp_GetDoubleChar(aStr, nPos, nLen, rConv, aValue.getX()));
+ Imp_SkipSpacesAndCommas(aStr, nPos, nLen);
+ aValue.setY(Imp_GetDoubleChar(aStr, nPos, nLen, rConv, aValue.getY()));
+ Imp_SkipSpacesAndCommas(aStr, nPos, nLen);
+ aValue.setZ(Imp_GetDoubleChar(aStr, nPos, nLen, rConv, aValue.getZ()));
+
+ if(1.0 != aValue.getX() || 1.0 != aValue.getY() || 1.0 != aValue.getZ())
+ maList.push_back(std::make_shared<ImpSdXMLExpTransObj3DScale>(aValue));
+
+ Imp_SkipSpacesAndClosingBraces(aStr, nPos, nLen);
+ }
+ else if(nPos == aStr.indexOf(aString_translate, nPos))
+ {
+ ::basegfx::B3DTuple aValue;
+
+ nPos += 9;
+ Imp_SkipSpacesAndOpeningBraces(aStr, nPos, nLen);
+ aValue.setX(Imp_GetDoubleChar(aStr, nPos, nLen, rConv, aValue.getX(), true));
+ Imp_SkipSpacesAndCommas(aStr, nPos, nLen);
+ aValue.setY(Imp_GetDoubleChar(aStr, nPos, nLen, rConv, aValue.getY(), true));
+ Imp_SkipSpacesAndCommas(aStr, nPos, nLen);
+ aValue.setZ(Imp_GetDoubleChar(aStr, nPos, nLen, rConv, aValue.getZ(), true));
+
+ if(!aValue.equalZero())
+ maList.push_back(std::make_shared<ImpSdXMLExpTransObj3DTranslate>(aValue));
+
+ Imp_SkipSpacesAndClosingBraces(aStr, nPos, nLen);
+ }
+ else if(nPos == aStr.indexOf(aString_matrix, nPos))
+ {
+ ::basegfx::B3DHomMatrix aValue;
+
+ nPos += 6;
+ Imp_SkipSpacesAndOpeningBraces(aStr, nPos, nLen);
+
+ // a
+ aValue.set(0, 0, Imp_GetDoubleChar(aStr, nPos, nLen, rConv, aValue.get(0, 0)));
+ Imp_SkipSpacesAndCommas(aStr, nPos, nLen);
+
+ // b
+ aValue.set(1, 0, Imp_GetDoubleChar(aStr, nPos, nLen, rConv, aValue.get(1, 0)));
+ Imp_SkipSpacesAndCommas(aStr, nPos, nLen);
+
+ // c
+ aValue.set(2, 0, Imp_GetDoubleChar(aStr, nPos, nLen, rConv, aValue.get(2, 0)));
+ Imp_SkipSpacesAndCommas(aStr, nPos, nLen);
+
+ // d
+ aValue.set(0, 1, Imp_GetDoubleChar(aStr, nPos, nLen, rConv, aValue.get(0, 1)));
+ Imp_SkipSpacesAndCommas(aStr, nPos, nLen);
+
+ // e
+ aValue.set(1, 1, Imp_GetDoubleChar(aStr, nPos, nLen, rConv, aValue.get(1, 1)));
+ Imp_SkipSpacesAndCommas(aStr, nPos, nLen);
+
+ // f
+ aValue.set(2, 1, Imp_GetDoubleChar(aStr, nPos, nLen, rConv, aValue.get(2, 1)));
+ Imp_SkipSpacesAndCommas(aStr, nPos, nLen);
+
+ // g
+ aValue.set(0, 2, Imp_GetDoubleChar(aStr, nPos, nLen, rConv, aValue.get(0, 2)));
+ Imp_SkipSpacesAndCommas(aStr, nPos, nLen);
+
+ // h
+ aValue.set(1, 2, Imp_GetDoubleChar(aStr, nPos, nLen, rConv, aValue.get(1, 2)));
+ Imp_SkipSpacesAndCommas(aStr, nPos, nLen);
+
+ // i
+ aValue.set(2, 2, Imp_GetDoubleChar(aStr, nPos, nLen, rConv, aValue.get(2, 2)));
+ Imp_SkipSpacesAndCommas(aStr, nPos, nLen);
+
+ // j
+ aValue.set(0, 3, Imp_GetDoubleChar(aStr, nPos, nLen, rConv, aValue.get(0, 3), true));
+ Imp_SkipSpacesAndCommas(aStr, nPos, nLen);
+
+ // k
+ aValue.set(1, 3, Imp_GetDoubleChar(aStr, nPos, nLen, rConv, aValue.get(1, 3), true));
+ Imp_SkipSpacesAndCommas(aStr, nPos, nLen);
+
+ // l
+ aValue.set(2, 3, Imp_GetDoubleChar(aStr, nPos, nLen, rConv, aValue.get(2, 3), true));
+ Imp_SkipSpacesAndCommas(aStr, nPos, nLen);
+
+ if(!aValue.isIdentity())
+ maList.push_back(std::make_shared<ImpSdXMLExpTransObj3DMatrix>(aValue));
+
+ Imp_SkipSpacesAndClosingBraces(aStr, nPos, nLen);
+ }
+ else
+ {
+ nPos++;
+ }
+ }
+ }
+}
+
+bool SdXMLImExTransform3D::GetFullHomogenTransform(css::drawing::HomogenMatrix& xHomMat)
+{
+ ::basegfx::B3DHomMatrix aFullTransform;
+ GetFullTransform(aFullTransform);
+
+ if(!aFullTransform.isIdentity())
+ {
+ basegfx::utils::B3DHomMatrixToUnoHomogenMatrix(aFullTransform, xHomMat);
+ return true;
+ }
+
+ return false;
+}
+
+void SdXMLImExTransform3D::GetFullTransform(::basegfx::B3DHomMatrix& rFullTrans)
+{
+ rFullTrans.identity();
+
+ const sal_uInt32 nCount = maList.size();
+ for(sal_uInt32 a(0); a < nCount; a++)
+ {
+ ImpSdXMLExpTransObj3DBase* pObj = maList[a].get();
+ switch(pObj->mnType)
+ {
+ case IMP_SDXMLEXP_TRANSOBJ3D_ROTATE_X :
+ {
+ rFullTrans.rotate(static_cast<ImpSdXMLExpTransObj3DRotateX*>(pObj)->mfRotateX, 0.0, 0.0);
+ break;
+ }
+ case IMP_SDXMLEXP_TRANSOBJ3D_ROTATE_Y :
+ {
+ rFullTrans.rotate(0.0, static_cast<ImpSdXMLExpTransObj3DRotateY*>(pObj)->mfRotateY, 0.0);
+ break;
+ }
+ case IMP_SDXMLEXP_TRANSOBJ3D_ROTATE_Z :
+ {
+ rFullTrans.rotate(0.0, 0.0, static_cast<ImpSdXMLExpTransObj3DRotateZ*>(pObj)->mfRotateZ);
+ break;
+ }
+ case IMP_SDXMLEXP_TRANSOBJ3D_SCALE :
+ {
+ const ::basegfx::B3DTuple& rScale = static_cast<ImpSdXMLExpTransObj3DScale*>(pObj)->maScale;
+ rFullTrans.scale(rScale.getX(), rScale.getY(), rScale.getZ());
+ break;
+ }
+ case IMP_SDXMLEXP_TRANSOBJ3D_TRANSLATE :
+ {
+ const ::basegfx::B3DTuple& rTranslate = static_cast<ImpSdXMLExpTransObj3DTranslate*>(pObj)->maTranslate;
+ rFullTrans.translate(rTranslate.getX(), rTranslate.getY(), rTranslate.getZ());
+ break;
+ }
+ case IMP_SDXMLEXP_TRANSOBJ3D_MATRIX :
+ {
+ rFullTrans *= static_cast<ImpSdXMLExpTransObj3DMatrix*>(pObj)->maMatrix;
+ break;
+ }
+ default :
+ {
+ OSL_FAIL("SdXMLImExTransform3D: impossible entry!");
+ break;
+ }
+ }
+ }
+}
+
+SdXMLImExViewBox::SdXMLImExViewBox(double fX, double fY, double fW, double fH)
+: mfX( fX ),
+ mfY( fY ),
+ mfW( fW ),
+ mfH( fH )
+{
+}
+
+// #100617# Asked vincent hardy: svg:viewBox values may be double precision.
+SdXMLImExViewBox::SdXMLImExViewBox(OUString aNew, const SvXMLUnitConverter& rConv)
+: msString(std::move(aNew)),
+ mfX( 0.0 ),
+ mfY( 0.0 ),
+ mfW( 1000.0 ),
+ mfH( 1000.0 )
+{
+ if(msString.isEmpty())
+ return;
+
+ const OUString aStr = msString;
+ const sal_Int32 nLen(aStr.getLength());
+ sal_Int32 nPos(0);
+
+ // skip starting spaces
+ Imp_SkipSpaces(aStr, nPos, nLen);
+
+ // get mX, #100617# be prepared for doubles
+ mfX = Imp_GetDoubleChar(aStr, nPos, nLen, rConv, mfX);
+
+ // skip spaces and commas
+ Imp_SkipSpacesAndCommas(aStr, nPos, nLen);
+
+ // get mY, #100617# be prepared for doubles
+ mfY = Imp_GetDoubleChar(aStr, nPos, nLen, rConv, mfY);
+
+ // skip spaces and commas
+ Imp_SkipSpacesAndCommas(aStr, nPos, nLen);
+
+ // get mW, #100617# be prepared for doubles
+ mfW = Imp_GetDoubleChar(aStr, nPos, nLen, rConv, mfW);
+
+ // skip spaces and commas
+ Imp_SkipSpacesAndCommas(aStr, nPos, nLen);
+
+ // get mH, #100617# be prepared for doubles
+ mfH = Imp_GetDoubleChar(aStr, nPos, nLen, rConv, mfH);
+
+}
+
+const OUString& SdXMLImExViewBox::GetExportString()
+{
+ OUString aNewString;
+ OUString aEmptySpace(" ");
+
+ Imp_PutDoubleChar(aNewString, mfX);
+ aNewString += aEmptySpace;
+
+ Imp_PutDoubleChar(aNewString, mfY);
+ aNewString += aEmptySpace;
+
+ Imp_PutDoubleChar(aNewString, mfW);
+ aNewString += aEmptySpace;
+
+ Imp_PutDoubleChar(aNewString, mfH);
+
+ // set new string
+ msString = aNewString;
+
+ return msString;
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/xmloff/source/draw/ximp3dobject.cxx b/xmloff/source/draw/ximp3dobject.cxx
new file mode 100644
index 0000000000..c17defc242
--- /dev/null
+++ b/xmloff/source/draw/ximp3dobject.cxx
@@ -0,0 +1,369 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#include "ximp3dobject.hxx"
+#include <xmloff/xmluconv.hxx>
+#include <xmloff/xmlnamespace.hxx>
+#include <com/sun/star/beans/XPropertySet.hpp>
+#include <xexptran.hxx>
+#include <com/sun/star/drawing/PolyPolygonShape3D.hpp>
+#include <com/sun/star/drawing/Direction3D.hpp>
+#include <com/sun/star/drawing/Position3D.hpp>
+#include <sal/log.hxx>
+#include <osl/diagnose.h>
+#include <basegfx/polygon/b2dpolypolygon.hxx>
+#include <basegfx/polygon/b2dpolypolygontools.hxx>
+#include <basegfx/polygon/b3dpolypolygontools.hxx>
+
+using namespace ::com::sun::star;
+using namespace ::xmloff::token;
+
+
+SdXML3DObjectContext::SdXML3DObjectContext(
+ SvXMLImport& rImport,
+ const css::uno::Reference< css::xml::sax::XFastAttributeList>& xAttrList,
+ uno::Reference< drawing::XShapes > const & rShapes)
+: SdXMLShapeContext( rImport, xAttrList, rShapes, false/*bTemporaryShape*/ ),
+ mbSetTransform( false )
+{
+ for(auto& aIter : sax_fastparser::castToFastAttributeList(xAttrList))
+ {
+ const OUString sValue = aIter.toString();
+ switch(aIter.getToken())
+ {
+ case XML_ELEMENT(DRAW, XML_STYLE_NAME):
+ {
+ maDrawStyleName = sValue;
+ break;
+ }
+ case XML_ELEMENT(DR3D, XML_TRANSFORM):
+ {
+ SdXMLImExTransform3D aTransform(sValue, GetImport().GetMM100UnitConverter());
+ if(aTransform.NeedsAction())
+ mbSetTransform = aTransform.GetFullHomogenTransform(mxHomMat);
+ break;
+ }
+ default:
+ XMLOFF_WARN_UNKNOWN("xmloff", aIter);
+ }
+ }
+}
+
+SdXML3DObjectContext::~SdXML3DObjectContext()
+{
+}
+
+void SdXML3DObjectContext::startFastElement(
+ sal_Int32 nElement,
+ const css::uno::Reference< css::xml::sax::XFastAttributeList >& xAttrList )
+{
+ uno::Reference< beans::XPropertySet > xPropSet(mxShape, uno::UNO_QUERY);
+ if(xPropSet.is())
+ {
+ // set parameters
+ if(mbSetTransform)
+ {
+ xPropSet->setPropertyValue("D3DTransformMatrix", uno::Any(mxHomMat));
+ }
+
+ // call parent
+ SdXMLShapeContext::startFastElement(nElement, xAttrList);
+ }
+}
+
+SdXML3DCubeObjectShapeContext::SdXML3DCubeObjectShapeContext(
+ SvXMLImport& rImport,
+ const css::uno::Reference< css::xml::sax::XFastAttributeList>& xAttrList,
+ uno::Reference< drawing::XShapes > const & rShapes)
+: SdXML3DObjectContext( rImport, xAttrList, rShapes ),
+ maMinEdge(-2500.0, -2500.0, -2500.0),
+ maMaxEdge(2500.0, 2500.0, 2500.0)
+{
+ for(auto& aIter : sax_fastparser::castToFastAttributeList(xAttrList))
+ {
+ switch(aIter.getToken())
+ {
+ case XML_ELEMENT(DR3D, XML_MIN_EDGE):
+ {
+ ::basegfx::B3DVector aNewVec;
+ SvXMLUnitConverter::convertB3DVector(aNewVec, aIter.toView());
+
+ if(aNewVec != maMinEdge)
+ maMinEdge = aNewVec;
+ break;
+ }
+ case XML_ELEMENT(DR3D, XML_MAX_EDGE):
+ {
+ ::basegfx::B3DVector aNewVec;
+ SvXMLUnitConverter::convertB3DVector(aNewVec, aIter.toView());
+
+ if(aNewVec != maMaxEdge)
+ maMaxEdge = aNewVec;
+ break;
+ }
+ default:
+ XMLOFF_WARN_UNKNOWN("xmloff", aIter);
+ }
+ }
+}
+
+SdXML3DCubeObjectShapeContext::~SdXML3DCubeObjectShapeContext()
+{
+}
+
+void SdXML3DCubeObjectShapeContext::startFastElement(
+ sal_Int32 nElement,
+ const css::uno::Reference< css::xml::sax::XFastAttributeList >& xAttrList )
+{
+ // create shape
+ AddShape( "com.sun.star.drawing.Shape3DCubeObject" );
+ if(!mxShape.is())
+ return;
+
+ // add, set style and properties from base shape
+ SetStyle();
+ SdXML3DObjectContext::startFastElement(nElement, xAttrList);
+
+ // set local parameters on shape
+ uno::Reference< beans::XPropertySet > xPropSet(mxShape, uno::UNO_QUERY);
+ if(!xPropSet.is())
+ return;
+
+ // set parameters
+ drawing::Position3D aPosition3D;
+ drawing::Direction3D aDirection3D;
+
+ // convert from min, max to size to be set
+ maMaxEdge = maMaxEdge - maMinEdge;
+
+ aPosition3D.PositionX = maMinEdge.getX();
+ aPosition3D.PositionY = maMinEdge.getY();
+ aPosition3D.PositionZ = maMinEdge.getZ();
+
+ aDirection3D.DirectionX = maMaxEdge.getX();
+ aDirection3D.DirectionY = maMaxEdge.getY();
+ aDirection3D.DirectionZ = maMaxEdge.getZ();
+
+ xPropSet->setPropertyValue("D3DPosition", uno::Any(aPosition3D));
+ xPropSet->setPropertyValue("D3DSize", uno::Any(aDirection3D));
+}
+
+SdXML3DSphereObjectShapeContext::SdXML3DSphereObjectShapeContext(
+ SvXMLImport& rImport,
+ const css::uno::Reference< css::xml::sax::XFastAttributeList>& xAttrList,
+ uno::Reference< drawing::XShapes > const & rShapes)
+: SdXML3DObjectContext( rImport, xAttrList, rShapes ),
+ maCenter(0.0, 0.0, 0.0),
+ maSphereSize(5000.0, 5000.0, 5000.0)
+{
+ for(auto& aIter : sax_fastparser::castToFastAttributeList(xAttrList))
+ {
+ switch(aIter.getToken())
+ {
+ case XML_ELEMENT(DR3D, XML_CENTER):
+ {
+ ::basegfx::B3DVector aNewVec;
+ SvXMLUnitConverter::convertB3DVector(aNewVec, aIter.toView());
+
+ if(aNewVec != maCenter)
+ maCenter = aNewVec;
+ break;
+ }
+ case XML_ELEMENT(DR3D, XML_SIZE):
+ {
+ ::basegfx::B3DVector aNewVec;
+ SvXMLUnitConverter::convertB3DVector(aNewVec, aIter.toView());
+
+ if(aNewVec != maSphereSize)
+ maSphereSize = aNewVec;
+ break;
+ }
+ default:
+ XMLOFF_WARN_UNKNOWN("xmloff", aIter);
+ }
+ }
+}
+
+SdXML3DSphereObjectShapeContext::~SdXML3DSphereObjectShapeContext()
+{
+}
+
+void SdXML3DSphereObjectShapeContext::startFastElement(
+ sal_Int32 nElement,
+ const css::uno::Reference< css::xml::sax::XFastAttributeList >& xAttrList )
+{
+ // create shape
+ AddShape( "com.sun.star.drawing.Shape3DSphereObject" );
+ if(!mxShape.is())
+ return;
+
+ // add, set style and properties from base shape
+ SetStyle();
+ SdXML3DObjectContext::startFastElement(nElement, xAttrList);
+
+ // set local parameters on shape
+ uno::Reference< beans::XPropertySet > xPropSet(mxShape, uno::UNO_QUERY);
+ if(!xPropSet.is())
+ return;
+
+ // set parameters
+ drawing::Position3D aPosition3D;
+ drawing::Direction3D aDirection3D;
+
+ aPosition3D.PositionX = maCenter.getX();
+ aPosition3D.PositionY = maCenter.getY();
+ aPosition3D.PositionZ = maCenter.getZ();
+
+ aDirection3D.DirectionX = maSphereSize.getX();
+ aDirection3D.DirectionY = maSphereSize.getY();
+ aDirection3D.DirectionZ = maSphereSize.getZ();
+
+ xPropSet->setPropertyValue("D3DPosition", uno::Any(aPosition3D));
+ xPropSet->setPropertyValue("D3DSize", uno::Any(aDirection3D));
+}
+
+SdXML3DPolygonBasedShapeContext::SdXML3DPolygonBasedShapeContext(
+ SvXMLImport& rImport,
+ const css::uno::Reference< css::xml::sax::XFastAttributeList>& xAttrList,
+ uno::Reference< drawing::XShapes > const & rShapes)
+: SdXML3DObjectContext( rImport, xAttrList, rShapes )
+{
+ for(auto& aIter : sax_fastparser::castToFastAttributeList(xAttrList))
+ {
+ OUString sValue = aIter.toString();
+
+ switch(aIter.getToken())
+ {
+ case XML_ELEMENT(SVG, XML_VIEWBOX):
+ case XML_ELEMENT(SVG_COMPAT, XML_VIEWBOX):
+ {
+ maViewBox = sValue;
+ break;
+ }
+ case XML_ELEMENT(SVG, XML_D):
+ case XML_ELEMENT(SVG_COMPAT, XML_D):
+ {
+ maPoints = sValue;
+ break;
+ }
+ default:
+ XMLOFF_WARN_UNKNOWN("xmloff", aIter);
+ }
+ }
+}
+
+SdXML3DPolygonBasedShapeContext::~SdXML3DPolygonBasedShapeContext()
+{
+}
+
+void SdXML3DPolygonBasedShapeContext::startFastElement(
+ sal_Int32 nElement,
+ const css::uno::Reference< css::xml::sax::XFastAttributeList >& xAttrList )
+{
+ uno::Reference< beans::XPropertySet > xPropSet(mxShape, uno::UNO_QUERY);
+
+ if(!xPropSet.is())
+ return;
+
+ // set parameters
+ if(!maPoints.isEmpty() && !maViewBox.isEmpty())
+ {
+ // import 2d tools::PolyPolygon from svg:d
+ basegfx::B2DPolyPolygon aPolyPolygon;
+
+ if(basegfx::utils::importFromSvgD(aPolyPolygon, maPoints, GetImport().needFixPositionAfterZ(), nullptr))
+ {
+ // convert to 3D PolyPolygon
+ const basegfx::B3DPolyPolygon aB3DPolyPolygon(
+ basegfx::utils::createB3DPolyPolygonFromB2DPolyPolygon(
+ aPolyPolygon));
+
+ // convert to UNO API class PolyPolygonShape3D
+ drawing::PolyPolygonShape3D aPolyPolygon3D;
+ basegfx::utils::B3DPolyPolygonToUnoPolyPolygonShape3D(
+ aB3DPolyPolygon,
+ aPolyPolygon3D);
+
+ // set polygon data
+ xPropSet->setPropertyValue("D3DPolyPolygon3D", uno::Any(aPolyPolygon3D));
+ }
+ else
+ {
+ OSL_ENSURE(false, "Error on importing svg:d for 3D tools::PolyPolygon (!)");
+ }
+ }
+
+ // call parent
+ SdXML3DObjectContext::startFastElement(nElement, xAttrList);
+}
+
+
+SdXML3DLatheObjectShapeContext::SdXML3DLatheObjectShapeContext(
+ SvXMLImport& rImport,
+ const css::uno::Reference< css::xml::sax::XFastAttributeList>& xAttrList,
+ uno::Reference< drawing::XShapes > const & rShapes)
+: SdXML3DPolygonBasedShapeContext( rImport, xAttrList, rShapes )
+{
+}
+
+SdXML3DLatheObjectShapeContext::~SdXML3DLatheObjectShapeContext()
+{
+}
+
+void SdXML3DLatheObjectShapeContext::startFastElement(
+ sal_Int32 nElement,
+ const css::uno::Reference< css::xml::sax::XFastAttributeList >& xAttrList )
+{
+ // create shape
+ AddShape( "com.sun.star.drawing.Shape3DLatheObject" );
+ if(mxShape.is())
+ {
+ // add, set style and properties from base shape
+ SetStyle();
+ SdXML3DPolygonBasedShapeContext::startFastElement(nElement, xAttrList);
+ }
+}
+
+SdXML3DExtrudeObjectShapeContext::SdXML3DExtrudeObjectShapeContext(
+ SvXMLImport& rImport,
+ const css::uno::Reference< css::xml::sax::XFastAttributeList>& xAttrList,
+ uno::Reference< drawing::XShapes > const & rShapes)
+: SdXML3DPolygonBasedShapeContext( rImport, xAttrList, rShapes )
+{
+}
+
+SdXML3DExtrudeObjectShapeContext::~SdXML3DExtrudeObjectShapeContext()
+{
+}
+
+void SdXML3DExtrudeObjectShapeContext::startFastElement(
+ sal_Int32 nElement,
+ const css::uno::Reference< css::xml::sax::XFastAttributeList >& xAttrList )
+{
+ AddShape( "com.sun.star.drawing.Shape3DExtrudeObject" );
+ if(mxShape.is())
+ {
+ // add, set style and properties from base shape
+ SetStyle();
+ SdXML3DPolygonBasedShapeContext::startFastElement(nElement, xAttrList);
+ }
+}
+
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/xmloff/source/draw/ximp3dobject.hxx b/xmloff/source/draw/ximp3dobject.hxx
new file mode 100644
index 0000000000..2862d094db
--- /dev/null
+++ b/xmloff/source/draw/ximp3dobject.hxx
@@ -0,0 +1,136 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#pragma once
+
+#include <com/sun/star/drawing/XShapes.hpp>
+#include <com/sun/star/drawing/HomogenMatrix.hpp>
+#include "ximpshap.hxx"
+
+// common shape context
+
+class SdXML3DObjectContext : public SdXMLShapeContext
+{
+ // the shape group this object should be created inside
+
+ css::drawing::HomogenMatrix mxHomMat;
+ bool mbSetTransform;
+
+public:
+
+ SdXML3DObjectContext( SvXMLImport& rImport,
+ const css::uno::Reference< css::xml::sax::XFastAttributeList>& xAttrList,
+ css::uno::Reference< css::drawing::XShapes > const & rShapes);
+ virtual ~SdXML3DObjectContext() override;
+
+ virtual void SAL_CALL startFastElement(
+ sal_Int32 nElement,
+ const css::uno::Reference< css::xml::sax::XFastAttributeList >& xAttrList ) override;
+};
+
+// dr3d:3dcube context
+
+class SdXML3DCubeObjectShapeContext : public SdXML3DObjectContext
+{
+ ::basegfx::B3DVector maMinEdge;
+ ::basegfx::B3DVector maMaxEdge;
+
+public:
+
+ SdXML3DCubeObjectShapeContext( SvXMLImport& rImport,
+ const css::uno::Reference< css::xml::sax::XFastAttributeList>& xAttrList,
+ css::uno::Reference< css::drawing::XShapes > const & rShapes);
+ virtual ~SdXML3DCubeObjectShapeContext() override;
+
+ virtual void SAL_CALL startFastElement(
+ sal_Int32 nElement,
+ const css::uno::Reference< css::xml::sax::XFastAttributeList >& xAttrList ) override;
+};
+
+// dr3d:3dsphere context
+
+class SdXML3DSphereObjectShapeContext : public SdXML3DObjectContext
+{
+ ::basegfx::B3DVector maCenter;
+ ::basegfx::B3DVector maSphereSize;
+
+public:
+
+ SdXML3DSphereObjectShapeContext( SvXMLImport& rImport,
+ const css::uno::Reference< css::xml::sax::XFastAttributeList>& xAttrList,
+ css::uno::Reference< css::drawing::XShapes > const & rShapes);
+ virtual ~SdXML3DSphereObjectShapeContext() override;
+
+ virtual void SAL_CALL startFastElement(
+ sal_Int32 nElement,
+ const css::uno::Reference< css::xml::sax::XFastAttributeList >& xAttrList ) override;
+};
+
+// polygonbased context
+
+class SdXML3DPolygonBasedShapeContext : public SdXML3DObjectContext
+{
+ OUString maPoints;
+ OUString maViewBox;
+
+public:
+
+ SdXML3DPolygonBasedShapeContext( SvXMLImport& rImport,
+ const css::uno::Reference< css::xml::sax::XFastAttributeList>& xAttrList,
+ css::uno::Reference< css::drawing::XShapes > const & rShapes);
+ virtual ~SdXML3DPolygonBasedShapeContext() override;
+
+ virtual void SAL_CALL startFastElement(
+ sal_Int32 nElement,
+ const css::uno::Reference< css::xml::sax::XFastAttributeList >& xAttrList ) override;
+};
+
+// dr3d:3dlathe context
+
+class SdXML3DLatheObjectShapeContext : public SdXML3DPolygonBasedShapeContext
+{
+public:
+
+ SdXML3DLatheObjectShapeContext( SvXMLImport& rImport,
+ const css::uno::Reference< css::xml::sax::XFastAttributeList>& xAttrList,
+ css::uno::Reference< css::drawing::XShapes > const & rShapes);
+ virtual ~SdXML3DLatheObjectShapeContext() override;
+
+ virtual void SAL_CALL startFastElement(
+ sal_Int32 nElement,
+ const css::uno::Reference< css::xml::sax::XFastAttributeList >& xAttrList ) override;
+};
+
+// dr3d:3dextrude context
+
+class SdXML3DExtrudeObjectShapeContext : public SdXML3DPolygonBasedShapeContext
+{
+public:
+
+ SdXML3DExtrudeObjectShapeContext( SvXMLImport& rImport,
+ const css::uno::Reference< css::xml::sax::XFastAttributeList>& xAttrList,
+ css::uno::Reference< css::drawing::XShapes > const & rShapes);
+ virtual ~SdXML3DExtrudeObjectShapeContext() override;
+
+ virtual void SAL_CALL startFastElement(
+ sal_Int32 nElement,
+ const css::uno::Reference< css::xml::sax::XFastAttributeList >& xAttrList ) override;
+};
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/xmloff/source/draw/ximp3dscene.cxx b/xmloff/source/draw/ximp3dscene.cxx
new file mode 100644
index 0000000000..31da3652e3
--- /dev/null
+++ b/xmloff/source/draw/ximp3dscene.cxx
@@ -0,0 +1,441 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#include <sax/tools/converter.hxx>
+#include <rtl/math.hxx>
+#include <sal/log.hxx>
+
+#include "ximp3dscene.hxx"
+#include <xmloff/xmluconv.hxx>
+#include <xexptran.hxx>
+#include <xmloff/xmltoken.hxx>
+#include <xmloff/xmlnamespace.hxx>
+#include <com/sun/star/beans/XPropertySet.hpp>
+#include <com/sun/star/drawing/Direction3D.hpp>
+#include <com/sun/star/drawing/CameraGeometry.hpp>
+#include "eventimp.hxx"
+#include "descriptionimp.hxx"
+
+using namespace ::com::sun::star;
+using namespace ::xmloff::token;
+
+// dr3d:3dlight context
+
+SdXML3DLightContext::SdXML3DLightContext(
+ SvXMLImport& rImport,
+ const css::uno::Reference< css::xml::sax::XFastAttributeList >& xAttrList)
+: SvXMLImportContext( rImport ),
+ maDiffuseColor(0x00000000),
+ maDirection(0.0, 0.0, 1.0),
+ mbEnabled(false),
+ mbSpecular(false)
+{
+ // read attributes for the 3DScene
+ for( auto& aIter : sax_fastparser::castToFastAttributeList(xAttrList) )
+ {
+ switch(aIter.getToken())
+ {
+ case XML_ELEMENT(DR3D, XML_DIFFUSE_COLOR):
+ {
+ ::sax::Converter::convertColor(maDiffuseColor, aIter.toView());
+ break;
+ }
+ case XML_ELEMENT(DR3D, XML_DIRECTION):
+ {
+ ::basegfx::B3DVector aVal;
+ SvXMLUnitConverter::convertB3DVector(aVal, aIter.toView());
+ if (!std::isnan(aVal.getX()) && !std::isnan(aVal.getY()) && !std::isnan(aVal.getZ()))
+ {
+ maDirection = aVal;
+ }
+ else
+ {
+ SAL_WARN("xmloff", "NaNs found in light direction: " << aIter.toString());
+ }
+ break;
+ }
+ case XML_ELEMENT(DR3D, XML_ENABLED):
+ {
+ (void)::sax::Converter::convertBool(mbEnabled, aIter.toView());
+ break;
+ }
+ case XML_ELEMENT(DR3D, XML_SPECULAR):
+ {
+ (void)::sax::Converter::convertBool(mbSpecular, aIter.toView());
+ break;
+ }
+ default:
+ XMLOFF_WARN_UNKNOWN("xmloff", aIter);
+ }
+ }
+}
+
+SdXML3DLightContext::~SdXML3DLightContext()
+{
+}
+
+
+SdXML3DSceneShapeContext::SdXML3DSceneShapeContext(
+ SvXMLImport& rImport,
+ const css::uno::Reference< css::xml::sax::XFastAttributeList>& xAttrList,
+ uno::Reference< drawing::XShapes > const & rShapes,
+ bool bTemporaryShapes)
+: SdXMLShapeContext( rImport, xAttrList, rShapes, bTemporaryShapes ), SdXML3DSceneAttributesHelper( rImport )
+{
+}
+
+SdXML3DSceneShapeContext::~SdXML3DSceneShapeContext()
+{
+}
+
+void SdXML3DSceneShapeContext::startFastElement(
+ sal_Int32 nElement,
+ const css::uno::Reference< css::xml::sax::XFastAttributeList >& xAttrList )
+{
+ // create new 3DScene shape and add it to rShapes, use it
+ // as base for the new 3DScene import
+ AddShape( "com.sun.star.drawing.Shape3DSceneObject" );
+ if( mxShape.is() )
+ {
+ SetStyle();
+
+ mxChildren.set( mxShape, uno::UNO_QUERY );
+ if( mxChildren.is() )
+ GetImport().GetShapeImport()->pushGroupForPostProcessing( mxChildren );
+
+ SetLayer();
+
+ // set pos, size, shear and rotate
+ SetTransformation();
+ }
+
+ // read attributes for the 3DScene
+ for( auto& aIter : sax_fastparser::castToFastAttributeList(xAttrList) )
+ processSceneAttribute( aIter );
+
+ // #91047# call parent function is missing here, added it
+ if(mxShape.is())
+ {
+ // call parent
+ SdXMLShapeContext::startFastElement(nElement, xAttrList);
+ }
+}
+
+void SdXML3DSceneShapeContext::endFastElement(sal_Int32 nElement)
+{
+ if(!mxShape.is())
+ return;
+
+ uno::Reference< beans::XPropertySet > xPropSet(mxShape, uno::UNO_QUERY);
+ if(xPropSet.is())
+ {
+ setSceneAttributes( xPropSet );
+ }
+
+ if( mxChildren.is() )
+ GetImport().GetShapeImport()->popGroupAndPostProcess();
+
+ // call parent
+ SdXMLShapeContext::endFastElement(nElement);
+}
+
+css::uno::Reference< css::xml::sax::XFastContextHandler > SdXML3DSceneShapeContext::createFastChildContext(
+ sal_Int32 nElement,
+ const css::uno::Reference< css::xml::sax::XFastAttributeList >& xAttrList )
+{
+ SvXMLImportContextRef xContext;
+ switch (nElement)
+ {
+ // #i68101#
+ case XML_ELEMENT(SVG, XML_TITLE):
+ case XML_ELEMENT(SVG_COMPAT, XML_TITLE):
+ case XML_ELEMENT(SVG, XML_DESC):
+ case XML_ELEMENT(SVG_COMPAT, XML_DESC):
+ xContext = new SdXMLDescriptionContext( GetImport(), nElement, mxShape );
+ break;
+ case XML_ELEMENT(OFFICE, XML_EVENT_LISTENERS):
+ xContext = new SdXMLEventsContext( GetImport(), mxShape );
+ break;
+ // look for local light context first
+ case XML_ELEMENT(DR3D, XML_LIGHT):
+ // dr3d:light inside dr3d:scene context
+ xContext = create3DLightContext( xAttrList );
+ break;
+ default:
+ // call GroupChildContext function at common ShapeImport
+ return XMLShapeImportHelper::Create3DSceneChildContext(
+ GetImport(), nElement, xAttrList, mxChildren);
+ }
+ return xContext;
+}
+
+SdXML3DSceneAttributesHelper::SdXML3DSceneAttributesHelper( SvXMLImport& rImporter )
+: mrImport( rImporter ),
+ mbSetTransform( false ),
+ mxPrjMode(drawing::ProjectionMode_PERSPECTIVE),
+ mnDistance(1000),
+ mnFocalLength(1000),
+ mnShadowSlant(0),
+ mxShadeMode(drawing::ShadeMode_SMOOTH),
+ maAmbientColor(0x00666666),
+ mbLightingMode(false),
+ maVRP(0.0, 0.0, 1.0),
+ maVPN(0.0, 0.0, 1.0),
+ maVUP(0.0, 1.0, 0.0),
+ mbVRPUsed(false)
+{
+}
+
+/** creates a 3d light context and adds it to the internal list for later processing */
+SvXMLImportContext * SdXML3DSceneAttributesHelper::create3DLightContext( const css::uno::Reference< css::xml::sax::XFastAttributeList >& xAttrList)
+{
+ const rtl::Reference<SdXML3DLightContext> xContext{new SdXML3DLightContext(mrImport, xAttrList)};
+
+ // remember SdXML3DLightContext for later evaluation
+ maList.push_back(xContext);
+
+ return xContext.get();
+}
+
+/** this should be called for each scene attribute */
+void SdXML3DSceneAttributesHelper::processSceneAttribute( const sax_fastparser::FastAttributeList::FastAttributeIter & aIter )
+{
+ auto nAttributeToken = aIter.getToken();
+ if( !IsTokenInNamespace(nAttributeToken, XML_NAMESPACE_DR3D) )
+ return;
+
+ switch(nAttributeToken & TOKEN_MASK)
+ {
+ case XML_TRANSFORM:
+ {
+ SdXMLImExTransform3D aTransform(aIter.toString(), mrImport.GetMM100UnitConverter());
+ if(aTransform.NeedsAction())
+ mbSetTransform = aTransform.GetFullHomogenTransform(mxHomMat);
+ return;
+ }
+ case XML_VRP:
+ {
+ ::basegfx::B3DVector aNewVec;
+ SvXMLUnitConverter::convertB3DVector(aNewVec, aIter.toView());
+
+ if(aNewVec != maVRP)
+ {
+ maVRP = aNewVec;
+ mbVRPUsed = true;
+ }
+ return;
+ }
+ case XML_VPN:
+ {
+ ::basegfx::B3DVector aNewVec;
+ SvXMLUnitConverter::convertB3DVector(aNewVec, aIter.toView());
+
+ if(aNewVec != maVPN)
+ {
+ maVPN = aNewVec;
+ }
+ return;
+ }
+ case XML_VUP:
+ {
+ ::basegfx::B3DVector aNewVec;
+ SvXMLUnitConverter::convertB3DVector(aNewVec, aIter.toView());
+
+ if(aNewVec != maVUP)
+ {
+ maVUP = aNewVec;
+ }
+ return;
+ }
+ case XML_PROJECTION:
+ {
+ if( IsXMLToken( aIter, XML_PARALLEL ) )
+ mxPrjMode = drawing::ProjectionMode_PARALLEL;
+ else
+ mxPrjMode = drawing::ProjectionMode_PERSPECTIVE;
+ return;
+ }
+ case XML_DISTANCE:
+ {
+ mrImport.GetMM100UnitConverter().convertMeasureToCore(mnDistance,
+ aIter.toView());
+ return;
+ }
+ case XML_FOCAL_LENGTH:
+ {
+ mrImport.GetMM100UnitConverter().convertMeasureToCore(mnFocalLength,
+ aIter.toView());
+ return;
+ }
+ case XML_SHADOW_SLANT:
+ {
+ ::sax::Converter::convertNumber(mnShadowSlant, aIter.toView());
+ return;
+ }
+ case XML_SHADE_MODE:
+ {
+ if( IsXMLToken( aIter, XML_FLAT ) )
+ mxShadeMode = drawing::ShadeMode_FLAT;
+ else if( IsXMLToken( aIter, XML_PHONG ) )
+ mxShadeMode = drawing::ShadeMode_PHONG;
+ else if( IsXMLToken( aIter, XML_GOURAUD ) )
+ mxShadeMode = drawing::ShadeMode_SMOOTH;
+ else
+ mxShadeMode = drawing::ShadeMode_DRAFT;
+ return;
+ }
+ case XML_AMBIENT_COLOR:
+ {
+ ::sax::Converter::convertColor(maAmbientColor, aIter.toView());
+ return;
+ }
+ case XML_LIGHTING_MODE:
+ {
+ (void)::sax::Converter::convertBool(mbLightingMode, aIter.toView());
+ return;
+ }
+ default:
+ XMLOFF_WARN_UNKNOWN("xmloff", aIter);
+ }
+}
+
+/** this sets the scene attributes at this propertyset */
+void SdXML3DSceneAttributesHelper::setSceneAttributes( const css::uno::Reference< css::beans::XPropertySet >& xPropSet )
+{
+ uno::Any aAny;
+
+ // world transformation
+ if(mbSetTransform)
+ {
+ xPropSet->setPropertyValue("D3DTransformMatrix", uno::Any(mxHomMat));
+ }
+
+ // distance
+ xPropSet->setPropertyValue("D3DSceneDistance", uno::Any(mnDistance));
+ // focalLength
+ xPropSet->setPropertyValue("D3DSceneFocalLength", uno::Any(mnFocalLength));
+ // shadowSlant
+ xPropSet->setPropertyValue("D3DSceneShadowSlant", uno::Any(static_cast<sal_Int16>(mnShadowSlant)));
+ // shadeMode
+ xPropSet->setPropertyValue("D3DSceneShadeMode", uno::Any(mxShadeMode));
+ // ambientColor
+ xPropSet->setPropertyValue("D3DSceneAmbientColor", uno::Any(maAmbientColor));
+ // lightingMode
+ xPropSet->setPropertyValue("D3DSceneTwoSidedLighting", uno::Any(mbLightingMode));
+
+ if( !maList.empty() )
+ {
+ uno::Any aAny2;
+ uno::Any aAny3;
+
+ // set lights
+ for( size_t a = 0; a < maList.size(); a++)
+ {
+ SdXML3DLightContext* pCtx = maList[ a ].get();
+
+ // set anys
+ aAny <<= pCtx->GetDiffuseColor();
+ drawing::Direction3D aLightDir;
+ aLightDir.DirectionX = pCtx->GetDirection().getX();
+ aLightDir.DirectionY = pCtx->GetDirection().getY();
+ aLightDir.DirectionZ = pCtx->GetDirection().getZ();
+ aAny2 <<= aLightDir;
+ aAny3 <<= pCtx->GetEnabled();
+
+ switch(a)
+ {
+ case 0:
+ {
+ xPropSet->setPropertyValue("D3DSceneLightColor1", aAny);
+ xPropSet->setPropertyValue("D3DSceneLightDirection1", aAny2);
+ xPropSet->setPropertyValue("D3DSceneLightOn1", aAny3);
+ break;
+ }
+ case 1:
+ {
+ xPropSet->setPropertyValue("D3DSceneLightColor2", aAny);
+ xPropSet->setPropertyValue("D3DSceneLightDirection2", aAny2);
+ xPropSet->setPropertyValue("D3DSceneLightOn2", aAny3);
+ break;
+ }
+ case 2:
+ {
+ xPropSet->setPropertyValue("D3DSceneLightColor3", aAny);
+ xPropSet->setPropertyValue("D3DSceneLightDirection3", aAny2);
+ xPropSet->setPropertyValue("D3DSceneLightOn3", aAny3);
+ break;
+ }
+ case 3:
+ {
+ xPropSet->setPropertyValue("D3DSceneLightColor4", aAny);
+ xPropSet->setPropertyValue("D3DSceneLightDirection4", aAny2);
+ xPropSet->setPropertyValue("D3DSceneLightOn4", aAny3);
+ break;
+ }
+ case 4:
+ {
+ xPropSet->setPropertyValue("D3DSceneLightColor5", aAny);
+ xPropSet->setPropertyValue("D3DSceneLightDirection5", aAny2);
+ xPropSet->setPropertyValue("D3DSceneLightOn5", aAny3);
+ break;
+ }
+ case 5:
+ {
+ xPropSet->setPropertyValue("D3DSceneLightColor6", aAny);
+ xPropSet->setPropertyValue("D3DSceneLightDirection6", aAny2);
+ xPropSet->setPropertyValue("D3DSceneLightOn6", aAny3);
+ break;
+ }
+ case 6:
+ {
+ xPropSet->setPropertyValue("D3DSceneLightColor7", aAny);
+ xPropSet->setPropertyValue("D3DSceneLightDirection7", aAny2);
+ xPropSet->setPropertyValue("D3DSceneLightOn7", aAny3);
+ break;
+ }
+ case 7:
+ {
+ xPropSet->setPropertyValue("D3DSceneLightColor8", aAny);
+ xPropSet->setPropertyValue("D3DSceneLightDirection8", aAny2);
+ xPropSet->setPropertyValue("D3DSceneLightOn8", aAny3);
+ break;
+ }
+ }
+ }
+ }
+
+ // CameraGeometry and camera settings
+ drawing::CameraGeometry aCamGeo;
+ aCamGeo.vrp.PositionX = maVRP.getX();
+ aCamGeo.vrp.PositionY = maVRP.getY();
+ aCamGeo.vrp.PositionZ = maVRP.getZ();
+ aCamGeo.vpn.DirectionX = maVPN.getX();
+ aCamGeo.vpn.DirectionY = maVPN.getY();
+ aCamGeo.vpn.DirectionZ = maVPN.getZ();
+ aCamGeo.vup.DirectionX = maVUP.getX();
+ aCamGeo.vup.DirectionY = maVUP.getY();
+ aCamGeo.vup.DirectionZ = maVUP.getZ();
+ xPropSet->setPropertyValue("D3DCameraGeometry", uno::Any(aCamGeo));
+
+ // #91047# set drawing::ProjectionMode AFTER camera geometry is set
+ // projection "D3DScenePerspective" drawing::ProjectionMode
+ xPropSet->setPropertyValue("D3DScenePerspective", uno::Any(mxPrjMode));
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/xmloff/source/draw/ximp3dscene.hxx b/xmloff/source/draw/ximp3dscene.hxx
new file mode 100644
index 0000000000..b0155591e3
--- /dev/null
+++ b/xmloff/source/draw/ximp3dscene.hxx
@@ -0,0 +1,52 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#pragma once
+
+#include <xmloff/xmlictxt.hxx>
+#include <com/sun/star/drawing/XShapes.hpp>
+#include "ximpshap.hxx"
+
+// dr3d:3dscene context
+
+class SdXML3DSceneShapeContext : public SdXMLShapeContext, public SdXML3DSceneAttributesHelper
+{
+ // the shape group this group is working on
+ // this is the scene at the same time
+ css::uno::Reference< css::drawing::XShapes > mxChildren;
+
+public:
+
+ SdXML3DSceneShapeContext(
+ SvXMLImport& rImport,
+ const css::uno::Reference< css::xml::sax::XFastAttributeList>& xAttrList,
+ css::uno::Reference< css::drawing::XShapes > const & rShapes,
+ bool bTemporaryShape);
+ virtual ~SdXML3DSceneShapeContext() override;
+
+ virtual css::uno::Reference< css::xml::sax::XFastContextHandler > SAL_CALL createFastChildContext(
+ sal_Int32 nElement,
+ const css::uno::Reference< css::xml::sax::XFastAttributeList >& AttrList ) override;
+ virtual void SAL_CALL startFastElement(
+ sal_Int32 nElement,
+ const css::uno::Reference< css::xml::sax::XFastAttributeList >& xAttrList ) override;
+ virtual void SAL_CALL endFastElement(sal_Int32 nElement) override;
+};
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/xmloff/source/draw/ximpbody.cxx b/xmloff/source/draw/ximpbody.cxx
new file mode 100644
index 0000000000..764c011eec
--- /dev/null
+++ b/xmloff/source/draw/ximpbody.cxx
@@ -0,0 +1,365 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#include "ximpbody.hxx"
+#include <xmloff/xmlnamespace.hxx>
+#include "ximpnote.hxx"
+#include <com/sun/star/drawing/XDrawPage.hpp>
+#include <com/sun/star/drawing/XDrawPages.hpp>
+#include <com/sun/star/container/XNamed.hpp>
+#include <com/sun/star/presentation/XPresentationPage.hpp>
+#include "ximpstyl.hxx"
+#include <com/sun/star/drawing/XMasterPageTarget.hpp>
+#include <com/sun/star/beans/XPropertySet.hpp>
+#include <com/sun/star/animations/XAnimationNodeSupplier.hpp>
+
+#include <xmloff/unointerfacetouniqueidentifiermapper.hxx>
+#include <xmloff/families.hxx>
+#include "ximpshow.hxx"
+#include "layerimp.hxx"
+#include <animationimport.hxx>
+#include <sal/log.hxx>
+
+using namespace ::com::sun::star;
+using namespace ::xmloff::token;
+
+SdXMLDrawPageContext::SdXMLDrawPageContext( SdXMLImport& rImport,
+ const css::uno::Reference< css::xml::sax::XFastAttributeList>& xAttrList,
+ uno::Reference< drawing::XShapes > const & rShapes)
+: SdXMLGenericPageContext( rImport, xAttrList, rShapes )
+, mbHadSMILNodes( false )
+{
+ bool bHaveXmlId( false );
+ OUString sXmlId, sStyleName, sContextName, sMasterPageName, sHREF;
+
+ for (auto &aIter : sax_fastparser::castToFastAttributeList( xAttrList ))
+ {
+ OUString sValue = aIter.toString();
+ switch(aIter.getToken())
+ {
+ case XML_ELEMENT(DRAW, XML_NAME):
+ {
+ sContextName = sValue;
+ break;
+ }
+ case XML_ELEMENT(DRAW, XML_STYLE_NAME):
+ {
+ sStyleName = sValue;
+ break;
+ }
+ case XML_ELEMENT(DRAW, XML_MASTER_PAGE_NAME):
+ {
+ sMasterPageName = sValue;
+ break;
+ }
+ case XML_ELEMENT(PRESENTATION, XML_PRESENTATION_PAGE_LAYOUT_NAME):
+ case XML_ELEMENT(PRESENTATION_SO52, XML_PRESENTATION_PAGE_LAYOUT_NAME):
+ case XML_ELEMENT(PRESENTATION_OOO, XML_PRESENTATION_PAGE_LAYOUT_NAME):
+ {
+ maPageLayoutName = sValue;
+ break;
+ }
+ case XML_ELEMENT(PRESENTATION, XML_USE_HEADER_NAME):
+ case XML_ELEMENT(PRESENTATION_SO52, XML_USE_HEADER_NAME):
+ case XML_ELEMENT(PRESENTATION_OOO, XML_USE_HEADER_NAME):
+ {
+ maUseHeaderDeclName = sValue;
+ break;
+ }
+ case XML_ELEMENT(PRESENTATION, XML_USE_FOOTER_NAME):
+ case XML_ELEMENT(PRESENTATION_SO52, XML_USE_FOOTER_NAME):
+ case XML_ELEMENT(PRESENTATION_OOO, XML_USE_FOOTER_NAME):
+ {
+ maUseFooterDeclName = sValue;
+ break;
+ }
+ case XML_ELEMENT(PRESENTATION, XML_USE_DATE_TIME_NAME):
+ case XML_ELEMENT(PRESENTATION_SO52, XML_USE_DATE_TIME_NAME):
+ case XML_ELEMENT(PRESENTATION_OOO, XML_USE_DATE_TIME_NAME):
+ {
+ maUseDateTimeDeclName = sValue;
+ break;
+ }
+ case XML_ELEMENT(DRAW, XML_ID):
+ {
+ if (!bHaveXmlId) { sXmlId = sValue; }
+ }
+ break;
+ case XML_ELEMENT(XML, XML_ID):
+ {
+ sXmlId = sValue;
+ bHaveXmlId = true;
+ }
+ break;
+ case XML_ELEMENT(XLINK, XML_HREF):
+ {
+ sHREF = sValue;
+ break;
+ }
+ }
+ }
+
+ if (!sXmlId.isEmpty())
+ {
+ uno::Reference< uno::XInterface > const xRef( rShapes );
+ GetImport().getInterfaceToIdentifierMapper().registerReference(
+ sXmlId, xRef );
+ }
+ GetImport().GetShapeImport()->startPage( rShapes );
+
+ uno::Reference< drawing::XDrawPage > xShapeDrawPage(rShapes, uno::UNO_QUERY);
+
+ // set PageName?
+ if(!sContextName.isEmpty())
+ {
+ if(xShapeDrawPage.is())
+ {
+ uno::Reference < container::XNamed > xNamed(xShapeDrawPage, uno::UNO_QUERY);
+ if(xNamed.is())
+ xNamed->setName(sContextName);
+ }
+ }
+
+ // set MasterPage?
+ if(!sMasterPageName.isEmpty())
+ {
+ // #85906# Code for setting masterpage needs complete rework
+ // since GetSdImport().GetMasterStylesContext() gives always ZERO
+ // because of content/style file split. Now the mechanism is to
+ // compare the wanted masterpage-name with the existing masterpages
+ // which were loaded and created in the styles section loading.
+ uno::Reference< drawing::XDrawPages > xMasterPages(GetSdImport().GetLocalMasterPages(), uno::UNO_QUERY);
+ uno::Reference < drawing::XMasterPageTarget > xDrawPage(rShapes, uno::UNO_QUERY);
+ uno::Reference< drawing::XDrawPage > xMasterPage;
+
+ if(xDrawPage.is() && xMasterPages.is())
+ {
+ bool bDone(false);
+ OUString sDisplayName( rImport.GetStyleDisplayName(
+ XmlStyleFamily::MASTER_PAGE, sMasterPageName ) );
+
+ for(sal_Int32 a = 0; !bDone && a < xMasterPages->getCount(); a++)
+ {
+ uno::Any aAny(xMasterPages->getByIndex(a));
+ aAny >>= xMasterPage;
+
+ if(xMasterPage.is())
+ {
+ uno::Reference< beans::XPropertySet > xPropSet(xMasterPage, uno::UNO_QUERY_THROW);
+ if (xPropSet.is())
+ {
+ OUString aPropName("SlideLayout");
+ uno::Reference< beans::XPropertySetInfo > xInfo(xPropSet->getPropertySetInfo());
+ if (xInfo.is() && xInfo->hasPropertyByName(aPropName))
+ {
+ sal_Int32 nType = -1;
+ uno::Reference< container::XNameAccess > xPageLayouts(GetSdImport().getPageLayouts());
+ if (xPageLayouts.is())
+ {
+ if (xPageLayouts->hasByName(maPageLayoutName))
+ xPageLayouts->getByName(maPageLayoutName) >>= nType;
+ }
+ if (-1 != nType)
+ xPropSet->setPropertyValue(aPropName, uno::Any(static_cast<sal_Int16>(nType)));
+ }
+ }
+
+ uno::Reference < container::XNamed > xMasterNamed(xMasterPage, uno::UNO_QUERY);
+ if(xMasterNamed.is())
+ {
+ OUString sLoopMasterPageName = xMasterNamed->getName();
+
+ if(!sLoopMasterPageName.isEmpty() && sLoopMasterPageName == sDisplayName)
+ {
+ xDrawPage->setMasterPage(xMasterPage);
+ bDone = true;
+ }
+ }
+ }
+ }
+
+ SAL_WARN_IF( !bDone, "xmloff", "xmloff::SdXMLDrawPageContext::SdXMLDrawPageContext(), could not find a master slide!" );
+ }
+ }
+
+ SetStyle( sStyleName );
+
+ if( !sHREF.isEmpty() )
+ {
+ uno::Reference< beans::XPropertySet > xProps( xShapeDrawPage, uno::UNO_QUERY );
+ if( xProps.is() )
+ {
+ sal_Int32 nIndex = sHREF.lastIndexOf( '#' );
+ if( nIndex != -1 )
+ {
+ OUString aFileName( sHREF.copy( 0, nIndex ) );
+ std::u16string_view aBookmarkName( sHREF.subView( nIndex+1 ) );
+
+ sHREF = GetImport().GetAbsoluteReference( aFileName ) + "#"
+ + aBookmarkName;
+ }
+
+ xProps->setPropertyValue("BookmarkURL", uno::Any( sHREF ) );
+ }
+ }
+
+ SetLayout();
+
+ DeleteAllShapes();
+}
+
+SdXMLDrawPageContext::~SdXMLDrawPageContext()
+{
+}
+
+css::uno::Reference< css::xml::sax::XFastContextHandler > SdXMLDrawPageContext::createFastChildContext(sal_Int32 nElement,
+ const css::uno::Reference<css::xml::sax::XFastAttributeList>& xAttrList)
+{
+ // some special objects inside draw:page context
+ switch(nElement)
+ {
+ case XML_ELEMENT(PRESENTATION, XML_NOTES):
+ case XML_ELEMENT(PRESENTATION_SO52, XML_NOTES):
+ case XML_ELEMENT(PRESENTATION_OOO, XML_NOTES):
+ {
+ if( GetSdImport().IsImpress() )
+ {
+ // get notes page
+ uno::Reference< presentation::XPresentationPage > xPresPage(GetLocalShapesContext(), uno::UNO_QUERY);
+ if(xPresPage.is())
+ {
+ uno::Reference< drawing::XDrawPage > xNotesDrawPage = xPresPage->getNotesPage();
+ if(xNotesDrawPage.is())
+ {
+ // presentation:notes inside draw:page context
+ return new SdXMLNotesContext( GetSdImport(), xAttrList, xNotesDrawPage);
+ }
+ }
+ }
+ break;
+ }
+ case XML_ELEMENT(ANIMATION, XML_PAR):
+ case XML_ELEMENT(ANIMATION_OOO, XML_PAR):
+ case XML_ELEMENT(ANIMATION, XML_SEQ):
+ case XML_ELEMENT(ANIMATION_OOO, XML_SEQ):
+ {
+ if( GetSdImport().IsImpress() )
+ {
+ uno::Reference< animations::XAnimationNodeSupplier > xNodeSupplier(GetLocalShapesContext(), uno::UNO_QUERY);
+ if(xNodeSupplier.is())
+ {
+ mbHadSMILNodes = true;
+ return new xmloff::AnimationNodeContext( xNodeSupplier->getAnimationNode(), GetSdImport(), nElement, xAttrList );
+ }
+ }
+ break;
+ }
+ case XML_ELEMENT(DRAW, XML_LAYER_SET):
+ {
+ return new SdXMLLayerSetContext( GetSdImport() );
+ }
+ }
+
+ // call parent when no own context was created
+ return SdXMLGenericPageContext::createFastChildContext(nElement, xAttrList);
+}
+
+void SdXMLDrawPageContext::endFastElement(sal_Int32 nElement)
+{
+ SdXMLGenericPageContext::endFastElement(nElement);
+ GetImport().GetShapeImport()->endPage(GetLocalShapesContext());
+
+ if( mbHadSMILNodes )
+ {
+ uno::Reference< animations::XAnimationNodeSupplier > xNodeSupplier(GetLocalShapesContext(), uno::UNO_QUERY);
+ uno::Reference< beans::XPropertySet > xPageProps( GetLocalShapesContext(), uno::UNO_QUERY );
+ if(xNodeSupplier.is())
+ xmloff::AnimationNodeContext::postProcessRootNode( xNodeSupplier->getAnimationNode(), xPageProps );
+ }
+}
+
+SdXMLBodyContext::SdXMLBodyContext( SdXMLImport& rImport )
+: SvXMLImportContext( rImport )
+{
+}
+
+SdXMLBodyContext::~SdXMLBodyContext()
+{
+}
+
+css::uno::Reference< css::xml::sax::XFastContextHandler > SdXMLBodyContext::createFastChildContext(
+ sal_Int32 nElement,
+ const css::uno::Reference< css::xml::sax::XFastAttributeList >& xAttrList )
+{
+ switch (nElement)
+ {
+ case XML_ELEMENT(PRESENTATION, XML_SETTINGS):
+ case XML_ELEMENT(PRESENTATION_SO52, XML_SETTINGS):
+ case XML_ELEMENT(PRESENTATION_OOO, XML_SETTINGS):
+ {
+ return new SdXMLShowsContext( GetSdImport(), xAttrList );
+ }
+ case XML_ELEMENT(DRAW, XML_PAGE):
+ {
+ // only read the first page in preview mode
+ if( (GetSdImport().GetNewPageCount() == 0) || !GetSdImport().IsPreview() )
+ {
+ // import this page
+ uno::Reference< drawing::XDrawPage > xNewDrawPage;
+ uno::Reference< drawing::XDrawPages > xDrawPages(GetSdImport().GetLocalDrawPages(), uno::UNO_QUERY);
+
+ if( !xDrawPages.is() )
+ break;
+
+ if(GetSdImport().GetNewPageCount() + 1 > xDrawPages->getCount())
+ {
+ // new page, create and insert
+ xNewDrawPage = xDrawPages->insertNewByIndex(xDrawPages->getCount());
+ }
+ else
+ {
+ // existing page, use it
+ uno::Any aAny(xDrawPages->getByIndex(GetSdImport().GetNewPageCount()));
+ aAny >>= xNewDrawPage;
+ }
+
+ // increment global import page counter
+ GetSdImport().IncrementNewPageCount();
+
+ if(xNewDrawPage.is())
+ {
+ // draw:page inside office:body context
+ return new SdXMLDrawPageContext(GetSdImport(), xAttrList, xNewDrawPage);
+ }
+ }
+ break;
+ }
+ case XML_ELEMENT(PRESENTATION, XML_HEADER_DECL):
+ case XML_ELEMENT(PRESENTATION, XML_FOOTER_DECL):
+ case XML_ELEMENT(PRESENTATION, XML_DATE_TIME_DECL):
+ {
+ return new SdXMLHeaderFooterDeclContext( GetImport(), xAttrList );
+ }
+ default:
+ XMLOFF_WARN_UNKNOWN_ELEMENT("xmloff", nElement);
+ }
+ return nullptr;
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/xmloff/source/draw/ximpbody.hxx b/xmloff/source/draw/ximpbody.hxx
new file mode 100644
index 0000000000..95d411385c
--- /dev/null
+++ b/xmloff/source/draw/ximpbody.hxx
@@ -0,0 +1,59 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#pragma once
+
+#include <xmloff/xmlictxt.hxx>
+#include "sdxmlimp_impl.hxx"
+#include "ximppage.hxx"
+
+// draw:page context
+
+class SdXMLDrawPageContext : public SdXMLGenericPageContext
+{
+ bool mbHadSMILNodes;
+
+public:
+ SdXMLDrawPageContext( SdXMLImport& rImport,
+ const css::uno::Reference< css::xml::sax::XFastAttributeList>& xAttrList,
+ css::uno::Reference< css::drawing::XShapes > const & rShapes);
+ virtual ~SdXMLDrawPageContext() override;
+
+ virtual css::uno::Reference< XFastContextHandler > SAL_CALL createFastChildContext(sal_Int32 Element,
+ const css::uno::Reference<css::xml::sax::XFastAttributeList>& Attribs) override;
+ virtual void SAL_CALL endFastElement(sal_Int32 nElement) override;
+
+};
+
+// office:body context
+
+class SdXMLBodyContext : public SvXMLImportContext
+{
+ const SdXMLImport& GetSdImport() const { return static_cast<const SdXMLImport&>(GetImport()); }
+ SdXMLImport& GetSdImport() { return static_cast<SdXMLImport&>(GetImport()); }
+
+public:
+ SdXMLBodyContext( SdXMLImport& rImport );
+ virtual ~SdXMLBodyContext() override;
+
+ virtual css::uno::Reference< css::xml::sax::XFastContextHandler > SAL_CALL createFastChildContext(
+ sal_Int32 nElement, const css::uno::Reference< css::xml::sax::XFastAttributeList >& AttrList ) override;
+};
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/xmloff/source/draw/ximpcustomshape.cxx b/xmloff/source/draw/ximpcustomshape.cxx
new file mode 100644
index 0000000000..56b9fd4cc4
--- /dev/null
+++ b/xmloff/source/draw/ximpcustomshape.cxx
@@ -0,0 +1,1421 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#include "ximpcustomshape.hxx"
+#include <o3tl/any.hxx>
+#include <rtl/math.hxx>
+#include <rtl/ustrbuf.hxx>
+#include <rtl/ustring.hxx>
+#include <com/sun/star/uno/Reference.h>
+#include <com/sun/star/awt/Rectangle.hpp>
+#include <com/sun/star/xml/sax/XAttributeList.hpp>
+#include <xmloff/xmltoken.hxx>
+#include <EnhancedCustomShapeToken.hxx>
+#include <xmloff/xmlimp.hxx>
+#include <xmloff/namespacemap.hxx>
+#include <xmloff/xmluconv.hxx>
+#include <xmloff/xmlement.hxx>
+#include <xexptran.hxx>
+#include <com/sun/star/drawing/Direction3D.hpp>
+#include <com/sun/star/drawing/EnhancedCustomShapeParameterPair.hpp>
+#include <com/sun/star/drawing/EnhancedCustomShapeParameterType.hpp>
+#include <com/sun/star/drawing/EnhancedCustomShapeTextFrame.hpp>
+#include <com/sun/star/drawing/EnhancedCustomShapeAdjustmentValue.hpp>
+#include <com/sun/star/drawing/EnhancedCustomShapeSegment.hpp>
+#include <com/sun/star/drawing/EnhancedCustomShapeSegmentCommand.hpp>
+#include <com/sun/star/drawing/EnhancedCustomShapeTextPathMode.hpp>
+#include <com/sun/star/drawing/EnhancedCustomShapeMetalType.hpp>
+#include <com/sun/star/drawing/ProjectionMode.hpp>
+#include <com/sun/star/drawing/Position3D.hpp>
+#include <sax/tools/converter.hxx>
+#include <comphelper/sequence.hxx>
+#include <o3tl/string_view.hxx>
+#include <memory>
+#include <string_view>
+#include <unordered_map>
+
+using namespace ::com::sun::star;
+using namespace ::xmloff::token;
+using namespace ::xmloff::EnhancedCustomShapeToken;
+
+
+XMLEnhancedCustomShapeContext::XMLEnhancedCustomShapeContext( SvXMLImport& rImport,
+ css::uno::Reference< css::drawing::XShape >& rxShape,
+ std::vector< css::beans::PropertyValue >& rCustomShapeGeometry ) :
+ SvXMLImportContext( rImport ),
+ mrUnitConverter( rImport.GetMM100UnitConverter() ),
+ mrxShape( rxShape ),
+ mrCustomShapeGeometry( rCustomShapeGeometry )
+{
+}
+
+const SvXMLEnumMapEntry<sal_uInt16> aXML_GluePointEnumMap[] =
+{
+ { XML_NONE, 0 },
+ { XML_SEGMENTS, 1 },
+ { XML_NONE, 2 },
+ { XML_RECTANGLE, 3 },
+ { XML_TOKEN_INVALID, 0 }
+};
+static void GetBool( std::vector< css::beans::PropertyValue >& rDest,
+ std::string_view rValue, const EnhancedCustomShapeTokenEnum eDestProp )
+{
+ bool bAttrBool;
+ if (::sax::Converter::convertBool( bAttrBool, rValue ))
+ {
+ beans::PropertyValue aProp;
+ aProp.Name = EASGet( eDestProp );
+ aProp.Value <<= bAttrBool;
+ rDest.push_back( aProp );
+ }
+}
+
+static void GetInt32( std::vector< css::beans::PropertyValue >& rDest,
+ std::string_view rValue, const EnhancedCustomShapeTokenEnum eDestProp )
+{
+ sal_Int32 nAttrNumber;
+ if (::sax::Converter::convertNumber( nAttrNumber, rValue ))
+ {
+ beans::PropertyValue aProp;
+ aProp.Name = EASGet( eDestProp );
+ aProp.Value <<= nAttrNumber;
+ rDest.push_back( aProp );
+ }
+}
+
+static void GetDouble( std::vector< css::beans::PropertyValue >& rDest,
+ std::string_view rValue, const EnhancedCustomShapeTokenEnum eDestProp )
+{
+ double fAttrDouble;
+ if (::sax::Converter::convertDouble( fAttrDouble, rValue ))
+ {
+ beans::PropertyValue aProp;
+ aProp.Name = EASGet( eDestProp );
+ aProp.Value <<= fAttrDouble;
+ rDest.push_back( aProp );
+ }
+}
+
+static void GetString( std::vector< css::beans::PropertyValue >& rDest,
+ const OUString& rValue, const EnhancedCustomShapeTokenEnum eDestProp )
+{
+ beans::PropertyValue aProp;
+ aProp.Name = EASGet( eDestProp );
+ aProp.Value <<= rValue;
+ rDest.push_back( aProp );
+}
+
+template<typename EnumT>
+static void GetEnum( std::vector< css::beans::PropertyValue >& rDest,
+ std::string_view rValue, const EnhancedCustomShapeTokenEnum eDestProp,
+ const SvXMLEnumMapEntry<EnumT>& rMap )
+{
+ EnumT eKind;
+ if( SvXMLUnitConverter::convertEnum( eKind, rValue, &rMap ) )
+ {
+ beans::PropertyValue aProp;
+ aProp.Name = EASGet( eDestProp );
+ aProp.Value <<= static_cast<sal_Int16>(eKind);
+ rDest.push_back( aProp );
+ }
+}
+
+static void GetDoublePercentage( std::vector< css::beans::PropertyValue >& rDest,
+ std::string_view rValue, const EnhancedCustomShapeTokenEnum eDestProp )
+{
+ sal_Int16 const eSrcUnit = ::sax::Converter::GetUnitFromString(
+ rValue, util::MeasureUnit::MM_100TH);
+ if (util::MeasureUnit::PERCENT != eSrcUnit)
+ return;
+
+ rtl_math_ConversionStatus eStatus;
+ double fAttrDouble = rtl_math_stringToDouble(rValue.data(),
+ rValue.data() + rValue.size(),
+ '.', ',', &eStatus, nullptr);
+ if ( eStatus == rtl_math_ConversionStatus_Ok )
+ {
+ beans::PropertyValue aProp;
+ aProp.Name = EASGet( eDestProp );
+ aProp.Value <<= fAttrDouble;
+ rDest.push_back( aProp );
+ }
+}
+
+static void GetB3DVector( std::vector< css::beans::PropertyValue >& rDest,
+ std::string_view rValue, const EnhancedCustomShapeTokenEnum eDestProp )
+{
+ ::basegfx::B3DVector aB3DVector;
+ if ( SvXMLUnitConverter::convertB3DVector( aB3DVector, rValue ) )
+ {
+ drawing::Direction3D aDirection3D( aB3DVector.getX(), aB3DVector.getY(), aB3DVector.getZ() );
+ beans::PropertyValue aProp;
+ aProp.Name = EASGet( eDestProp );
+ aProp.Value <<= aDirection3D;
+ rDest.push_back( aProp );
+ }
+}
+
+static bool GetEquationName( std::u16string_view rEquation, const sal_Int32 nStart, OUString& rEquationName )
+{
+ sal_Int32 nIndex = nStart;
+ while( nIndex < static_cast<sal_Int32>(rEquation.size()) )
+ {
+ sal_Unicode nChar = rEquation[ nIndex ];
+ if (
+ ( ( nChar >= 'a' ) && ( nChar <= 'z' ) )
+ || ( ( nChar >= 'A' ) && ( nChar <= 'Z' ) )
+ || ( ( nChar >= '0' ) && ( nChar <= '9' ) )
+ )
+ {
+ nIndex++;
+ }
+ else
+ break;
+ }
+ bool bValid = ( nIndex - nStart ) != 0;
+ if ( bValid )
+ rEquationName = rEquation.substr( nStart, nIndex - nStart );
+ return bValid;
+}
+
+static bool GetNextParameter( css::drawing::EnhancedCustomShapeParameter& rParameter, sal_Int32& nIndex, std::u16string_view rParaString )
+{
+ if ( nIndex >= static_cast<sal_Int32>(rParaString.size()) )
+ return false;
+
+ bool bValid = true;
+ bool bNumberRequired = true;
+ bool bMustBePositiveWholeNumbered = false;
+
+ rParameter.Type = css::drawing::EnhancedCustomShapeParameterType::NORMAL;
+ if ( rParaString[ nIndex ] == '$' )
+ {
+ rParameter.Type = css::drawing::EnhancedCustomShapeParameterType::ADJUSTMENT;
+ bMustBePositiveWholeNumbered = true;
+ nIndex++;
+ }
+ else if ( rParaString[ nIndex ] == '?' )
+ {
+ nIndex++;
+ bNumberRequired = false;
+ OUString aEquationName;
+ bValid = GetEquationName( rParaString, nIndex, aEquationName );
+ if ( bValid )
+ {
+ rParameter.Type = css::drawing::EnhancedCustomShapeParameterType::EQUATION;
+ rParameter.Value <<= aEquationName;
+ nIndex += aEquationName.getLength();
+ }
+ }
+ else if ( rParaString[ nIndex ] > '9' )
+ {
+ bNumberRequired = false;
+ if ( o3tl::matchIgnoreAsciiCase( rParaString, u"left", nIndex ) )
+ {
+ rParameter.Type = css::drawing::EnhancedCustomShapeParameterType::LEFT;
+ nIndex += 4;
+ }
+ else if ( o3tl::matchIgnoreAsciiCase( rParaString, u"top", nIndex ) )
+ {
+ rParameter.Type = css::drawing::EnhancedCustomShapeParameterType::TOP;
+ nIndex += 3;
+ }
+ else if ( o3tl::matchIgnoreAsciiCase( rParaString, u"right", nIndex ) )
+ {
+ rParameter.Type = css::drawing::EnhancedCustomShapeParameterType::RIGHT;
+ nIndex += 5;
+ }
+ else if ( o3tl::matchIgnoreAsciiCase( rParaString, u"bottom", nIndex ) )
+ {
+ rParameter.Type = css::drawing::EnhancedCustomShapeParameterType::BOTTOM;
+ nIndex += 6;
+ }
+ else if ( o3tl::matchIgnoreAsciiCase( rParaString, u"xstretch", nIndex ) )
+ {
+ rParameter.Type = css::drawing::EnhancedCustomShapeParameterType::XSTRETCH;
+ nIndex += 8;
+ }
+ else if ( o3tl::matchIgnoreAsciiCase( rParaString, u"ystretch", nIndex ) )
+ {
+ rParameter.Type = css::drawing::EnhancedCustomShapeParameterType::YSTRETCH;
+ nIndex += 8;
+ }
+ else if ( o3tl::matchIgnoreAsciiCase( rParaString, u"hasstroke", nIndex ) )
+ {
+ rParameter.Type = css::drawing::EnhancedCustomShapeParameterType::HASSTROKE;
+ nIndex += 9;
+ }
+ else if ( o3tl::matchIgnoreAsciiCase( rParaString, u"hasfill", nIndex ) )
+ {
+ rParameter.Type = css::drawing::EnhancedCustomShapeParameterType::HASFILL;
+ nIndex += 7;
+ }
+ else if ( o3tl::matchIgnoreAsciiCase( rParaString, u"width", nIndex ) )
+ {
+ rParameter.Type = css::drawing::EnhancedCustomShapeParameterType::WIDTH;
+ nIndex += 5;
+ }
+ else if ( o3tl::matchIgnoreAsciiCase( rParaString, u"height", nIndex ) )
+ {
+ rParameter.Type = css::drawing::EnhancedCustomShapeParameterType::HEIGHT;
+ nIndex += 6;
+ }
+ else if ( o3tl::matchIgnoreAsciiCase( rParaString, u"logwidth", nIndex ) )
+ {
+ rParameter.Type = css::drawing::EnhancedCustomShapeParameterType::LOGWIDTH;
+ nIndex += 8;
+ }
+ else if ( o3tl::matchIgnoreAsciiCase( rParaString, u"logheight", nIndex ) )
+ {
+ rParameter.Type = css::drawing::EnhancedCustomShapeParameterType::LOGHEIGHT;
+ nIndex += 9;
+ }
+ else
+ bValid = false;
+ }
+ if ( bValid )
+ {
+ if ( bNumberRequired )
+ {
+ sal_Int32 nStartIndex = nIndex;
+ sal_Int32 nEIndex = 0; // index of "E" in double
+
+ bool bE = false; // set if a double is including a "E" statement
+ bool bENum = false; // there is at least one number after "E"
+ bool bDot = false; // set if there is a dot included
+ bool bEnd = false; // set for each value that can not be part of a double/integer
+
+ while( ( nIndex < static_cast<sal_Int32>(rParaString.size()) ) && bValid )
+ {
+ switch( rParaString[ nIndex ] )
+ {
+ case '.' :
+ {
+ if ( bMustBePositiveWholeNumbered )
+ bValid = false;
+ else
+ {
+ if ( bDot )
+ bValid = false;
+ else
+ bDot = true;
+ }
+ }
+ break;
+ case '-' :
+ {
+ if ( bMustBePositiveWholeNumbered )
+ bValid = false;
+ else
+ {
+ if ( nStartIndex == nIndex )
+ bValid = true;
+ else if ( bE )
+ {
+ if ( nEIndex + 1 == nIndex )
+ bValid = true;
+ else if ( bENum )
+ bEnd = true;
+ else
+ bValid = false;
+ }
+ }
+ }
+ break;
+
+ case 'e' :
+ case 'E' :
+ {
+ if ( bMustBePositiveWholeNumbered )
+ bEnd = true;
+ else
+ {
+ if ( !bE )
+ {
+ bE = true;
+ nEIndex = nIndex;
+ }
+ else
+ bEnd = true;
+ }
+ }
+ break;
+ case '0' :
+ case '1' :
+ case '2' :
+ case '3' :
+ case '4' :
+ case '5' :
+ case '6' :
+ case '7' :
+ case '8' :
+ case '9' :
+ {
+ if ( bE && ! bENum )
+ bENum = true;
+ }
+ break;
+ default:
+ bEnd = true;
+ }
+ if ( !bEnd )
+ nIndex++;
+ else
+ break;
+ }
+ if ( nIndex == nStartIndex )
+ bValid = false;
+ if ( bValid )
+ {
+ std::u16string_view aNumber( rParaString.substr( nStartIndex, nIndex - nStartIndex ) );
+ if ( bE || bDot )
+ {
+ double fAttrDouble;
+ if (::sax::Converter::convertDouble(fAttrDouble, aNumber))
+ rParameter.Value <<= fAttrDouble;
+ else
+ bValid = false;
+ }
+ else
+ {
+ sal_Int32 nValue;
+ if (::sax::Converter::convertNumber(nValue, aNumber))
+ rParameter.Value <<= nValue;
+ else
+ bValid = false;
+ }
+ }
+ }
+ }
+ if ( bValid )
+ {
+ // skipping white spaces and commas (#i121507#)
+ const sal_Unicode aSpace(' ');
+ const sal_Unicode aCommata(',');
+
+ while(nIndex < static_cast<sal_Int32>(rParaString.size()))
+ {
+ const sal_Unicode aCandidate(rParaString[nIndex]);
+
+ if(aSpace == aCandidate || aCommata == aCandidate)
+ {
+ nIndex++;
+ }
+ else
+ {
+ break;
+ }
+ }
+ }
+ return bValid;
+}
+
+static void GetPosition3D( std::vector< css::beans::PropertyValue >& rDest, // e.g. draw:extrusion-viewpoint
+ std::string_view rValue, const EnhancedCustomShapeTokenEnum eDestProp,
+ const SvXMLUnitConverter& rUnitConverter )
+{
+ drawing::Position3D aPosition3D;
+ if ( rUnitConverter.convertPosition3D( aPosition3D, rValue ) )
+ {
+ beans::PropertyValue aProp;
+ aProp.Name = EASGet( eDestProp );
+ aProp.Value <<= aPosition3D;
+ rDest.push_back( aProp );
+ }
+}
+
+static void GetDoubleSequence( std::vector< css::beans::PropertyValue >& rDest, // e.g. draw:glue-point-leaving-directions
+ std::string_view rValue, const EnhancedCustomShapeTokenEnum eDestProp )
+{
+ std::vector< double > vDirection;
+ sal_Int32 nIndex = 0;
+ do
+ {
+ double fAttrDouble;
+ std::string_view aToken( o3tl::getToken(rValue, 0, ',', nIndex ) );
+ if (!::sax::Converter::convertDouble( fAttrDouble, aToken ))
+ break;
+ else
+ vDirection.push_back( fAttrDouble );
+ }
+ while ( nIndex >= 0 );
+
+ if ( !vDirection.empty() )
+ {
+ beans::PropertyValue aProp;
+ aProp.Name = EASGet( eDestProp );
+ aProp.Value <<= comphelper::containerToSequence(vDirection);
+ rDest.push_back( aProp );
+ }
+}
+
+static void GetSizeSequence( std::vector< css::beans::PropertyValue >& rDest,
+ std::string_view rValue, const EnhancedCustomShapeTokenEnum eDestProp )
+{
+ std::vector< sal_Int32 > vNum;
+ sal_Int32 nIndex = 0;
+ do
+ {
+ sal_Int32 n;
+ std::string_view aToken( o3tl::getToken(rValue, 0, ' ', nIndex ) );
+ if (!::sax::Converter::convertNumber( n, aToken ))
+ break;
+ else
+ vNum.push_back( n );
+ }
+ while ( nIndex >= 0 );
+
+ if ( vNum.empty() )
+ return;
+
+ uno::Sequence< awt::Size > aSizeSeq((vNum.size() + 1) / 2);
+ std::vector< sal_Int32 >::const_iterator aIter = vNum.begin();
+ std::vector< sal_Int32 >::const_iterator aEnd = vNum.end();
+ awt::Size* pValues = aSizeSeq.getArray();
+
+ while ( aIter != aEnd ) {
+ pValues->Width = *aIter++;
+ if ( aIter != aEnd )
+ pValues->Height = *aIter++;
+ pValues ++;
+ }
+
+ beans::PropertyValue aProp;
+ aProp.Name = EASGet( eDestProp );
+ aProp.Value <<= aSizeSeq;
+ rDest.push_back( aProp );
+}
+
+static void GetEnhancedParameter( std::vector< css::beans::PropertyValue >& rDest, // e.g. draw:handle-position
+ std::u16string_view rValue, const EnhancedCustomShapeTokenEnum eDestProp )
+{
+ sal_Int32 nIndex = 0;
+ css::drawing::EnhancedCustomShapeParameter aParameter;
+ if ( GetNextParameter( aParameter, nIndex, rValue ) )
+ {
+ beans::PropertyValue aProp;
+ aProp.Name = EASGet( eDestProp );
+ aProp.Value <<= aParameter;
+ rDest.push_back( aProp );
+ }
+}
+
+static void GetEnhancedParameterPair( std::vector< css::beans::PropertyValue >& rDest, // e.g. draw:handle-position
+ std::u16string_view rValue, const EnhancedCustomShapeTokenEnum eDestProp )
+{
+ sal_Int32 nIndex = 0;
+ css::drawing::EnhancedCustomShapeParameterPair aParameterPair;
+ if ( GetNextParameter( aParameterPair.First, nIndex, rValue )
+ && GetNextParameter( aParameterPair.Second, nIndex, rValue ) )
+ {
+ beans::PropertyValue aProp;
+ aProp.Name = EASGet( eDestProp );
+ aProp.Value <<= aParameterPair;
+ rDest.push_back( aProp );
+ }
+}
+
+static sal_Int32 GetEnhancedParameterPairSequence( std::vector< css::beans::PropertyValue >& rDest, // e.g. draw:glue-points
+ std::u16string_view rValue, const EnhancedCustomShapeTokenEnum eDestProp )
+{
+ std::vector< css::drawing::EnhancedCustomShapeParameterPair > vParameter;
+ css::drawing::EnhancedCustomShapeParameterPair aParameter;
+
+ sal_Int32 nIndex = 0;
+ while ( GetNextParameter( aParameter.First, nIndex, rValue )
+ && GetNextParameter( aParameter.Second, nIndex, rValue ) )
+ {
+ vParameter.push_back( aParameter );
+ }
+ if ( !vParameter.empty() )
+ {
+ beans::PropertyValue aProp;
+ aProp.Name = EASGet( eDestProp );
+ aProp.Value <<= comphelper::containerToSequence(vParameter);
+ rDest.push_back( aProp );
+ }
+ return vParameter.size();
+}
+
+static void GetEnhancedRectangleSequence( std::vector< css::beans::PropertyValue >& rDest, // e.g. draw:text-areas
+ std::u16string_view rValue, const EnhancedCustomShapeTokenEnum eDestProp )
+{
+ std::vector< css::drawing::EnhancedCustomShapeTextFrame > vTextFrame;
+ css::drawing::EnhancedCustomShapeTextFrame aParameter;
+
+ sal_Int32 nIndex = 0;
+
+ while ( GetNextParameter( aParameter.TopLeft.First, nIndex, rValue )
+ && GetNextParameter( aParameter.TopLeft.Second, nIndex, rValue )
+ && GetNextParameter( aParameter.BottomRight.First, nIndex, rValue )
+ && GetNextParameter( aParameter.BottomRight.Second, nIndex, rValue ) )
+ {
+ vTextFrame.push_back( aParameter );
+ }
+ if ( !vTextFrame.empty() )
+ {
+ beans::PropertyValue aProp;
+ aProp.Name = EASGet( eDestProp );
+ aProp.Value <<= comphelper::containerToSequence(vTextFrame);
+ rDest.push_back( aProp );
+ }
+}
+
+static void
+GetEnhancedPath(std::vector<css::beans::PropertyValue>& rDest, // e.g. draw:enhanced-path
+ std::u16string_view rValue, std::u16string_view rType)
+{
+ std::vector< css::drawing::EnhancedCustomShapeParameterPair > vCoordinates;
+ std::vector< css::drawing::EnhancedCustomShapeSegment > vSegments;
+
+ sal_Int32 nIndex = 0;
+ sal_Int32 nParameterCount = 0;
+
+ sal_Int32 nParametersNeeded = 1;
+ sal_Int16 nLatestSegmentCommand = css::drawing::EnhancedCustomShapeSegmentCommand::MOVETO;
+
+ bool bValid = true;
+
+ while( bValid && ( nIndex < static_cast<sal_Int32>(rValue.size()) ) )
+ {
+ switch( rValue[ nIndex ] )
+ {
+ case 'M' :
+ {
+ nLatestSegmentCommand = css::drawing::EnhancedCustomShapeSegmentCommand::MOVETO;
+ nParametersNeeded = 1;
+ nIndex++;
+ }
+ break;
+ case 'L' :
+ {
+ nLatestSegmentCommand = css::drawing::EnhancedCustomShapeSegmentCommand::LINETO;
+ nParametersNeeded = 1;
+ nIndex++;
+ }
+ break;
+ case 'C' :
+ {
+ nLatestSegmentCommand = css::drawing::EnhancedCustomShapeSegmentCommand::CURVETO;
+ nParametersNeeded = 3;
+ nIndex++;
+ }
+ break;
+ case 'Z' :
+ {
+ nLatestSegmentCommand = css::drawing::EnhancedCustomShapeSegmentCommand::CLOSESUBPATH;
+ nParametersNeeded = 0;
+ nIndex++;
+ }
+ break;
+ case 'N' :
+ {
+ nLatestSegmentCommand = css::drawing::EnhancedCustomShapeSegmentCommand::ENDSUBPATH;
+ nParametersNeeded = 0;
+ nIndex++;
+ }
+ break;
+ case 'F' :
+ {
+ nLatestSegmentCommand = css::drawing::EnhancedCustomShapeSegmentCommand::NOFILL;
+ nParametersNeeded = 0;
+ nIndex++;
+ }
+ break;
+ case 'S' :
+ {
+ nLatestSegmentCommand = css::drawing::EnhancedCustomShapeSegmentCommand::NOSTROKE;
+ nParametersNeeded = 0;
+ nIndex++;
+ }
+ break;
+ case 'T' :
+ {
+ nLatestSegmentCommand = css::drawing::EnhancedCustomShapeSegmentCommand::ANGLEELLIPSETO;
+ nParametersNeeded = 3;
+ nIndex++;
+ }
+ break;
+ case 'U' :
+ {
+ nLatestSegmentCommand = css::drawing::EnhancedCustomShapeSegmentCommand::ANGLEELLIPSE;
+ nParametersNeeded = 3;
+ nIndex++;
+ }
+ break;
+ case 'A' :
+ {
+ nLatestSegmentCommand = css::drawing::EnhancedCustomShapeSegmentCommand::ARCTO;
+ nParametersNeeded = 4;
+ nIndex++;
+ }
+ break;
+ case 'B' :
+ {
+ nLatestSegmentCommand = css::drawing::EnhancedCustomShapeSegmentCommand::ARC;
+ nParametersNeeded = 4;
+ nIndex++;
+ }
+ break;
+ case 'G' :
+ {
+ nLatestSegmentCommand = css::drawing::EnhancedCustomShapeSegmentCommand::ARCANGLETO;
+ nParametersNeeded = 2;
+ nIndex++;
+ }
+ break;
+ case 'H' :
+ {
+ nLatestSegmentCommand = css::drawing::EnhancedCustomShapeSegmentCommand::DARKEN;
+ nParametersNeeded = 0;
+ nIndex++;
+ }
+ break;
+ case 'I' :
+ {
+ nLatestSegmentCommand = css::drawing::EnhancedCustomShapeSegmentCommand::DARKENLESS;
+ nParametersNeeded = 0;
+ nIndex++;
+ }
+ break;
+ case 'J' :
+ {
+ nLatestSegmentCommand = css::drawing::EnhancedCustomShapeSegmentCommand::LIGHTEN;
+ nParametersNeeded = 0;
+ nIndex++;
+ }
+ break;
+ case 'K' :
+ {
+ nLatestSegmentCommand = css::drawing::EnhancedCustomShapeSegmentCommand::LIGHTENLESS;
+ nParametersNeeded = 0;
+ nIndex++;
+ }
+ break;
+ case 'W' :
+ {
+ nLatestSegmentCommand = css::drawing::EnhancedCustomShapeSegmentCommand::CLOCKWISEARCTO;
+ nParametersNeeded = 4;
+ nIndex++;
+ }
+ break;
+ case 'V' :
+ {
+ nLatestSegmentCommand = css::drawing::EnhancedCustomShapeSegmentCommand::CLOCKWISEARC;
+ nParametersNeeded = 4;
+ nIndex++;
+ }
+ break;
+ case 'X' :
+ {
+ nLatestSegmentCommand = css::drawing::EnhancedCustomShapeSegmentCommand::ELLIPTICALQUADRANTX;
+ nParametersNeeded = 1;
+ nIndex++;
+ }
+ break;
+ case 'Y' :
+ {
+ nLatestSegmentCommand = css::drawing::EnhancedCustomShapeSegmentCommand::ELLIPTICALQUADRANTY;
+ nParametersNeeded = 1;
+ nIndex++;
+ }
+ break;
+ case 'Q' :
+ {
+ nLatestSegmentCommand = css::drawing::EnhancedCustomShapeSegmentCommand::QUADRATICCURVETO;
+ nParametersNeeded = 2;
+ nIndex++;
+ }
+ break;
+ case ' ' :
+ {
+ nIndex++;
+ }
+ break;
+
+ case '$' :
+ case '?' :
+ case '0' :
+ case '1' :
+ case '2' :
+ case '3' :
+ case '4' :
+ case '5' :
+ case '6' :
+ case '7' :
+ case '8' :
+ case '9' :
+ case '.' :
+ case '-' :
+ {
+ css::drawing::EnhancedCustomShapeParameterPair aPair;
+ if ( GetNextParameter( aPair.First, nIndex, rValue ) &&
+ GetNextParameter( aPair.Second, nIndex, rValue ) )
+ {
+ vCoordinates.push_back( aPair );
+ nParameterCount++;
+ }
+ else
+ bValid = false;
+ }
+ break;
+ default:
+ nIndex++;
+ break;
+ }
+ if ( !nParameterCount && !nParametersNeeded )
+ {
+ css::drawing::EnhancedCustomShapeSegment aSegment;
+ aSegment.Command = nLatestSegmentCommand;
+ aSegment.Count = 0;
+ vSegments.push_back( aSegment );
+ nParametersNeeded = 0x7fffffff;
+ }
+ else if ( nParameterCount >= nParametersNeeded )
+ {
+ // Special rule for moveto in ODF 1.2 section 19.145
+ // "If a moveto is followed by multiple pairs of coordinates, they are treated as lineto."
+ if ( nLatestSegmentCommand == css::drawing::EnhancedCustomShapeSegmentCommand::MOVETO )
+ {
+ css::drawing::EnhancedCustomShapeSegment aSegment;
+ aSegment.Command = css::drawing::EnhancedCustomShapeSegmentCommand::MOVETO;
+ aSegment.Count = 1;
+ vSegments.push_back( aSegment );
+ nIndex--;
+ nLatestSegmentCommand = css::drawing::EnhancedCustomShapeSegmentCommand::LINETO;
+ nParametersNeeded = 1;
+ }
+ else
+ {
+ // General rule in ODF 1.2. section 19.145
+ // "If a command is repeated multiple times, all repeated command characters
+ // except the first one may be omitted." Thus check if the last command is identical,
+ // if so, we just need to increment the count
+ if ( !vSegments.empty() && ( vSegments[ vSegments.size() - 1 ].Command == nLatestSegmentCommand ) )
+ vSegments[ vSegments.size() -1 ].Count++;
+ else
+ {
+ css::drawing::EnhancedCustomShapeSegment aSegment;
+ aSegment.Command = nLatestSegmentCommand;
+ aSegment.Count = 1;
+ vSegments.push_back( aSegment );
+ }
+ }
+ nParameterCount = 0;
+ }
+ }
+
+ // Corrections for wrong paths in curvedArrow shapes written by older LO versions
+ if (!vSegments.empty()
+ && (rType == u"mso-spt102" || rType == u"mso-spt103" || rType == u"mso-spt104"
+ || rType == u"mso-spt105")
+ && vSegments[0].Count == 2)
+ {
+ vSegments[0].Count = 1;
+ css::drawing::EnhancedCustomShapeSegment aSegment;
+ aSegment.Count = 1;
+ aSegment.Command
+ = vSegments[0].Command == css::drawing::EnhancedCustomShapeSegmentCommand::CLOCKWISEARC
+ ? css::drawing::EnhancedCustomShapeSegmentCommand::CLOCKWISEARCTO
+ : css::drawing::EnhancedCustomShapeSegmentCommand::ARCTO;
+ vSegments.insert(vSegments.begin() + 1, aSegment);
+ }
+
+ // adding the Coordinates property
+ beans::PropertyValue aProp;
+ aProp.Name = EASGet( EAS_Coordinates );
+ aProp.Value <<= comphelper::containerToSequence(vCoordinates);
+ rDest.push_back( aProp );
+
+ // adding the Segments property
+ aProp.Name = EASGet( EAS_Segments );
+ aProp.Value <<= comphelper::containerToSequence(vSegments);
+ rDest.push_back( aProp );
+}
+
+static void GetAdjustmentValues( std::vector< css::beans::PropertyValue >& rDest, // draw:adjustments
+ std::u16string_view rValue )
+{
+ std::vector< css::drawing::EnhancedCustomShapeAdjustmentValue > vAdjustmentValue;
+ css::drawing::EnhancedCustomShapeParameter aParameter;
+ sal_Int32 nIndex = 0;
+ while ( GetNextParameter( aParameter, nIndex, rValue ) )
+ {
+ css::drawing::EnhancedCustomShapeAdjustmentValue aAdj;
+ if ( aParameter.Type == css::drawing::EnhancedCustomShapeParameterType::NORMAL )
+ {
+ aAdj.Value = aParameter.Value;
+ aAdj.State = beans::PropertyState_DIRECT_VALUE;
+ }
+ else
+ aAdj.State = beans::PropertyState_DEFAULT_VALUE; // this should not be, but better than setting nothing
+
+ vAdjustmentValue.push_back( aAdj );
+ }
+
+ sal_Int32 nAdjustmentValues = vAdjustmentValue.size();
+ if ( nAdjustmentValues )
+ {
+ beans::PropertyValue aProp;
+ aProp.Name = EASGet( EAS_AdjustmentValues );
+ aProp.Value <<= comphelper::containerToSequence(vAdjustmentValue);
+ rDest.push_back( aProp );
+ }
+}
+
+void XMLEnhancedCustomShapeContext::startFastElement(
+ sal_Int32 /*nElement*/,
+ const css::uno::Reference< css::xml::sax::XFastAttributeList >& xAttrList )
+{
+ sal_Int32 nAttrNumber;
+ std::optional<std::string_view> oSpecularityValue; // for postpone extrusion-specularity
+ std::optional<OUString> oPathValue; // for postpone GetEnhancedPath;
+ OUString sType("non-primitive"); // default in ODF
+ for( auto& aIter : sax_fastparser::castToFastAttributeList(xAttrList) )
+ {
+ switch( EASGet( aIter.getToken() ) )
+ {
+ case EAS_type :
+ {
+ sType = aIter.toString();
+ GetString( mrCustomShapeGeometry, sType, EAS_Type );
+ }
+ break;
+ case EAS_mirror_horizontal :
+ GetBool( mrCustomShapeGeometry, aIter.toView(), EAS_MirroredX );
+ break;
+ case EAS_mirror_vertical :
+ GetBool( mrCustomShapeGeometry, aIter.toView(), EAS_MirroredY );
+ break;
+ case EAS_viewBox :
+ {
+ SdXMLImExViewBox aViewBox( aIter.toString(), GetImport().GetMM100UnitConverter() );
+ awt::Rectangle aRect( aViewBox.GetX(), aViewBox.GetY(), aViewBox.GetWidth(), aViewBox.GetHeight() );
+ beans::PropertyValue aProp;
+ aProp.Name = EASGet( EAS_ViewBox );
+ aProp.Value <<= aRect;
+ mrCustomShapeGeometry.push_back( aProp );
+ }
+ break;
+ case EAS_sub_view_size:
+ GetSizeSequence( maPath, aIter.toView(), EAS_SubViewSize );
+ break;
+ case EAS_text_rotate_angle :
+ GetDouble( mrCustomShapeGeometry, aIter.toView(), EAS_TextRotateAngle );
+ break;
+ case EAS_extrusion_allowed :
+ GetBool( maPath, aIter.toView(), EAS_ExtrusionAllowed );
+ break;
+ case EAS_text_path_allowed :
+ GetBool( maPath, aIter.toView(), EAS_TextPathAllowed );
+ break;
+ case EAS_concentric_gradient_fill_allowed :
+ GetBool( maPath, aIter.toView(), EAS_ConcentricGradientFillAllowed );
+ break;
+ case EAS_extrusion :
+ GetBool( maExtrusion, aIter.toView(), EAS_Extrusion );
+ break;
+ case EAS_extrusion_brightness :
+ GetDoublePercentage( maExtrusion, aIter.toView(), EAS_Brightness );
+ break;
+ case EAS_extrusion_depth :
+ {
+ OUString rValue = aIter.toString();
+ sal_Int32 nIndex = 0;
+ css::drawing::EnhancedCustomShapeParameterPair aParameterPair;
+ css::drawing::EnhancedCustomShapeParameter& rDepth = aParameterPair.First;
+ if ( GetNextParameter( rDepth, nIndex, rValue ) )
+ {
+ css::drawing::EnhancedCustomShapeParameter& rFraction = aParameterPair.Second;
+ // try to catch the unit for the depth
+ sal_Int16 const eSrcUnit(
+ ::sax::Converter::GetUnitFromString(
+ rValue, util::MeasureUnit::MM_100TH));
+
+ OUStringBuffer aUnitStr;
+ double fFactor = ::sax::Converter::GetConversionFactor(
+ aUnitStr, util::MeasureUnit::MM_100TH, eSrcUnit);
+ if ( ( fFactor != 1.0 ) && ( fFactor != 0.0 ) )
+ {
+ double fDepth(0.0);
+ if ( rDepth.Value >>= fDepth )
+ {
+ fDepth /= fFactor;
+ rDepth.Value <<= fDepth;
+ }
+ }
+ if ( rValue.matchIgnoreAsciiCase( aUnitStr, nIndex ) )
+ nIndex += aUnitStr.getLength();
+
+ // skipping white spaces
+ while( ( nIndex < rValue.getLength() ) && rValue[ nIndex ] == ' ' )
+ nIndex++;
+
+ if ( GetNextParameter( rFraction, nIndex, rValue ) )
+ {
+ beans::PropertyValue aProp;
+ aProp.Name = EASGet( EAS_Depth );
+ aProp.Value <<= aParameterPair;
+ maExtrusion.push_back( aProp );
+ }
+ }
+ }
+ break;
+ case EAS_extrusion_diffusion :
+ GetDoublePercentage( maExtrusion, aIter.toView(), EAS_Diffusion );
+ break;
+ case EAS_extrusion_number_of_line_segments :
+ GetInt32( maExtrusion, aIter.toView(), EAS_NumberOfLineSegments );
+ break;
+ case EAS_extrusion_light_face :
+ GetBool( maExtrusion, aIter.toView(), EAS_LightFace );
+ break;
+ case EAS_extrusion_first_light_harsh :
+ GetBool( maExtrusion, aIter.toView(), EAS_FirstLightHarsh );
+ break;
+ case EAS_extrusion_second_light_harsh :
+ GetBool( maExtrusion, aIter.toView(), EAS_SecondLightHarsh );
+ break;
+ case EAS_extrusion_first_light_level :
+ GetDoublePercentage( maExtrusion, aIter.toView(), EAS_FirstLightLevel );
+ break;
+ case EAS_extrusion_second_light_level :
+ GetDoublePercentage( maExtrusion, aIter.toView(), EAS_SecondLightLevel );
+ break;
+ case EAS_extrusion_first_light_direction :
+ GetB3DVector( maExtrusion, aIter.toView(), EAS_FirstLightDirection );
+ break;
+ case EAS_extrusion_second_light_direction :
+ GetB3DVector( maExtrusion, aIter.toView(), EAS_SecondLightDirection );
+ break;
+ case EAS_extrusion_metal :
+ GetBool( maExtrusion, aIter.toView(), EAS_Metal );
+ break;
+ case EAS_extrusion_metal_type :
+ {
+ OUString rValue = aIter.toString();
+ sal_Int16 eMetalType(drawing::EnhancedCustomShapeMetalType::MetalODF);
+ if (rValue == "loext:MetalMSCompatible")
+ eMetalType = drawing::EnhancedCustomShapeMetalType::MetalMSCompatible;
+ beans::PropertyValue aProp;
+ aProp.Name = EASGet(EAS_MetalType);
+ aProp.Value <<= eMetalType;
+ maExtrusion.push_back(aProp);
+ }
+ break;
+ case EAS_shade_mode :
+ {
+ drawing::ShadeMode eShadeMode( drawing::ShadeMode_FLAT );
+ if( IsXMLToken( aIter, XML_PHONG ) )
+ eShadeMode = drawing::ShadeMode_PHONG;
+ else if ( IsXMLToken( aIter, XML_GOURAUD ) )
+ eShadeMode = drawing::ShadeMode_SMOOTH;
+ else if ( IsXMLToken( aIter, XML_DRAFT ) )
+ eShadeMode = drawing::ShadeMode_DRAFT;
+
+ beans::PropertyValue aProp;
+ aProp.Name = EASGet( EAS_ShadeMode );
+ aProp.Value <<= eShadeMode;
+ maExtrusion.push_back( aProp );
+ }
+ break;
+ case EAS_extrusion_rotation_angle :
+ GetEnhancedParameterPair( maExtrusion, aIter.toString(), EAS_RotateAngle );
+ break;
+ case EAS_extrusion_rotation_center :
+ GetB3DVector( maExtrusion, aIter.toView(), EAS_RotationCenter );
+ break;
+ case EAS_extrusion_shininess :
+ GetDoublePercentage( maExtrusion, aIter.toView(), EAS_Shininess );
+ break;
+ case EAS_extrusion_skew :
+ GetEnhancedParameterPair( maExtrusion, aIter.toString(), EAS_Skew );
+ break;
+ case EAS_extrusion_specularity :
+ if (!oSpecularityValue)
+ oSpecularityValue = aIter.toView();
+ break;
+ case EAS_extrusion_specularity_loext :
+ oSpecularityValue = aIter.toView();
+ break;
+ case EAS_projection :
+ {
+ drawing::ProjectionMode eProjectionMode( drawing::ProjectionMode_PERSPECTIVE );
+ if( IsXMLToken( aIter, XML_PARALLEL ) )
+ eProjectionMode = drawing::ProjectionMode_PARALLEL;
+
+ beans::PropertyValue aProp;
+ aProp.Name = EASGet( EAS_ProjectionMode );
+ aProp.Value <<= eProjectionMode;
+ maExtrusion.push_back( aProp );
+ }
+ break;
+ case EAS_extrusion_viewpoint :
+ GetPosition3D( maExtrusion, aIter.toView(), EAS_ViewPoint, mrUnitConverter );
+ break;
+ case EAS_extrusion_origin :
+ GetEnhancedParameterPair( maExtrusion, aIter.toString(), EAS_Origin );
+ break;
+ case EAS_extrusion_color :
+ GetBool( maExtrusion, aIter.toView(), EAS_Color );
+ break;
+ case EAS_enhanced_path :
+ oPathValue = aIter.toString();
+ break;
+ case EAS_path_stretchpoint_x :
+ {
+ if (::sax::Converter::convertNumber(nAttrNumber, aIter.toView()))
+ {
+ beans::PropertyValue aProp;
+ aProp.Name = EASGet( EAS_StretchX );
+ aProp.Value <<= nAttrNumber;
+ maPath.push_back( aProp );
+ }
+ }
+ break;
+ case EAS_path_stretchpoint_y :
+ {
+ if (::sax::Converter::convertNumber(nAttrNumber, aIter.toView()))
+ {
+ beans::PropertyValue aProp;
+ aProp.Name = EASGet( EAS_StretchY );
+ aProp.Value <<= nAttrNumber;
+ maPath.push_back( aProp );
+ }
+ }
+ break;
+ case EAS_text_areas :
+ GetEnhancedRectangleSequence( maPath, aIter.toString(), EAS_TextFrames );
+ break;
+ case EAS_glue_points :
+ {
+ sal_Int32 i, nPairs = GetEnhancedParameterPairSequence( maPath, aIter.toString(), EAS_GluePoints );
+ GetImport().GetShapeImport()->moveGluePointMapping( mrxShape, nPairs );
+ for ( i = 0; i < nPairs; i++ )
+ GetImport().GetShapeImport()->addGluePointMapping( mrxShape, i + 4, i + 4 );
+ }
+ break;
+ case EAS_glue_point_type :
+ GetEnum( maPath, aIter.toView(), EAS_GluePointType, *aXML_GluePointEnumMap );
+ break;
+ case EAS_glue_point_leaving_directions :
+ GetDoubleSequence( maPath, aIter.toView(), EAS_GluePointLeavingDirections );
+ break;
+ case EAS_text_path :
+ GetBool( maTextPath, aIter.toView(), EAS_TextPath );
+ break;
+ case EAS_text_path_mode :
+ {
+ css::drawing::EnhancedCustomShapeTextPathMode eTextPathMode( css::drawing::EnhancedCustomShapeTextPathMode_NORMAL );
+ if( IsXMLToken( aIter, XML_PATH ) )
+ eTextPathMode = css::drawing::EnhancedCustomShapeTextPathMode_PATH;
+ else if ( IsXMLToken( aIter, XML_SHAPE ) )
+ eTextPathMode = css::drawing::EnhancedCustomShapeTextPathMode_SHAPE;
+
+ beans::PropertyValue aProp;
+ aProp.Name = EASGet( EAS_TextPathMode );
+ aProp.Value <<= eTextPathMode;
+ maTextPath.push_back( aProp );
+ }
+ break;
+ case EAS_text_path_scale :
+ {
+ bool bScaleX = IsXMLToken( aIter, XML_SHAPE );
+ beans::PropertyValue aProp;
+ aProp.Name = EASGet( EAS_ScaleX );
+ aProp.Value <<= bScaleX;
+ maTextPath.push_back( aProp );
+ }
+ break;
+ case EAS_text_path_same_letter_heights :
+ GetBool( maTextPath, aIter.toView(), EAS_SameLetterHeights );
+ break;
+ case EAS_modifiers :
+ GetAdjustmentValues( mrCustomShapeGeometry, aIter.toString() );
+ break;
+ default:
+ break;
+ }
+ }
+ if (oSpecularityValue)
+ GetDoublePercentage( maExtrusion, *oSpecularityValue, EAS_Specularity );
+ if (oPathValue)
+ GetEnhancedPath(maPath, *oPathValue, sType);
+}
+
+static void SdXMLCustomShapePropertyMerge( std::vector< css::beans::PropertyValue >& rPropVec,
+ const std::vector< beans::PropertyValues >& rElement,
+ const OUString& rElementName )
+{
+ if ( !rElement.empty() )
+ {
+ beans::PropertyValue aProp;
+ aProp.Name = rElementName;
+ aProp.Value <<= comphelper::containerToSequence(rElement);
+ rPropVec.push_back( aProp );
+ }
+}
+
+static void SdXMLCustomShapePropertyMerge( std::vector< css::beans::PropertyValue >& rPropVec,
+ const std::vector< OUString >& rElement,
+ const OUString& rElementName )
+{
+ if ( !rElement.empty() )
+ {
+ beans::PropertyValue aProp;
+ aProp.Name = rElementName;
+ aProp.Value <<= comphelper::containerToSequence(rElement);
+ rPropVec.push_back( aProp );
+ }
+}
+
+static void SdXMLCustomShapePropertyMerge( std::vector< css::beans::PropertyValue >& rPropVec,
+ const std::vector< css::beans::PropertyValue >& rElement,
+ const OUString& rElementName )
+{
+ if ( !rElement.empty() )
+ {
+ beans::PropertyValue aProp;
+ aProp.Name = rElementName;
+ aProp.Value <<= comphelper::containerToSequence(rElement);
+ rPropVec.push_back( aProp );
+ }
+}
+
+typedef std::unordered_map< OUString, sal_Int32 > EquationHashMap;
+
+/* if rPara.Type is from type EnhancedCustomShapeParameterType::EQUATION, the name of the equation
+ will be converted from OUString to index */
+static void CheckAndResolveEquationParameter( css::drawing::EnhancedCustomShapeParameter& rPara, EquationHashMap* pH )
+{
+ if ( rPara.Type == css::drawing::EnhancedCustomShapeParameterType::EQUATION )
+ {
+ OUString aEquationName;
+ if ( rPara.Value >>= aEquationName )
+ {
+ sal_Int32 nIndex = 0;
+ EquationHashMap::iterator aHashIter( pH->find( aEquationName ) );
+ if ( aHashIter != pH->end() )
+ nIndex = (*aHashIter).second;
+ rPara.Value <<= nIndex;
+ }
+ }
+}
+
+void XMLEnhancedCustomShapeContext::endFastElement(sal_Int32 )
+{
+ // resolve properties that are indexing an Equation
+ if ( !maEquations.empty() )
+ {
+ // creating hash map containing the name and index of each equation
+ EquationHashMap aH;
+ std::vector< OUString >::iterator aEquationNameIter = maEquationNames.begin();
+ std::vector< OUString >::iterator aEquationNameEnd = maEquationNames.end();
+ while( aEquationNameIter != aEquationNameEnd )
+ {
+ aH[ *aEquationNameIter ] = static_cast<sal_Int32>( aEquationNameIter - maEquationNames.begin() );
+ ++aEquationNameIter;
+ }
+
+ // resolve equation
+ for( auto& rEquation : maEquations )
+ {
+ sal_Int32 nIndexOf = 0;
+ do
+ {
+ nIndexOf = rEquation.indexOf( '?', nIndexOf );
+ if ( nIndexOf != -1 )
+ {
+ OUString aEquationName;
+ if ( GetEquationName( rEquation, nIndexOf + 1, aEquationName ) )
+ {
+ // copying first characters inclusive '?'
+ sal_Int32 nIndex = 0;
+ EquationHashMap::iterator aHashIter( aH.find( aEquationName ) );
+ if ( aHashIter != aH.end() )
+ nIndex = (*aHashIter).second;
+ OUString aNew = rEquation.subView( 0, nIndexOf + 1 ) +
+ OUString::number( nIndex ) +
+ rEquation.subView( nIndexOf + aEquationName.getLength() + 1 );
+ rEquation = aNew;
+ }
+ nIndexOf++;
+ }
+ }
+ while( nIndexOf != -1 );
+ }
+
+ // Path
+ for ( const beans::PropertyValue& rPathItem : maPath )
+ {
+ switch( EASGet( rPathItem.Name ) )
+ {
+ case EAS_Coordinates :
+ case EAS_GluePoints :
+ {
+ uno::Sequence< css::drawing::EnhancedCustomShapeParameterPair > const & rSeq =
+ *o3tl::doAccess<uno::Sequence< css::drawing::EnhancedCustomShapeParameterPair > >(
+ rPathItem.Value);
+ for ( const auto& rElem : rSeq )
+ {
+ CheckAndResolveEquationParameter( const_cast<css::drawing::EnhancedCustomShapeParameter &>(rElem.First), &aH );
+ CheckAndResolveEquationParameter( const_cast<css::drawing::EnhancedCustomShapeParameter &>(rElem.Second), &aH );
+ }
+ }
+ break;
+ case EAS_TextFrames :
+ {
+ uno::Sequence< css::drawing::EnhancedCustomShapeTextFrame > const & rSeq =
+ *o3tl::doAccess<uno::Sequence< css::drawing::EnhancedCustomShapeTextFrame > >(
+ rPathItem.Value);
+ for ( const auto& rElem : rSeq )
+ {
+ CheckAndResolveEquationParameter( const_cast<css::drawing::EnhancedCustomShapeParameter &>(rElem.TopLeft.First), &aH );
+ CheckAndResolveEquationParameter( const_cast<css::drawing::EnhancedCustomShapeParameter &>(rElem.TopLeft.Second), &aH );
+ CheckAndResolveEquationParameter( const_cast<css::drawing::EnhancedCustomShapeParameter &>(rElem.BottomRight.First), &aH );
+ CheckAndResolveEquationParameter( const_cast<css::drawing::EnhancedCustomShapeParameter &>(rElem.BottomRight.Second), &aH );
+ }
+ }
+ break;
+ default:
+ break;
+ }
+ }
+ for ( css::beans::PropertyValues const & aHandle : maHandles )
+ {
+ for ( beans::PropertyValue const & propValue : aHandle )
+ {
+ switch( EASGet( propValue.Name ) )
+ {
+ case EAS_RangeYMinimum :
+ case EAS_RangeYMaximum :
+ case EAS_RangeXMinimum :
+ case EAS_RangeXMaximum :
+ case EAS_RadiusRangeMinimum :
+ case EAS_RadiusRangeMaximum :
+ {
+ CheckAndResolveEquationParameter( const_cast<css::drawing::EnhancedCustomShapeParameter &>(*o3tl::doAccess<css::drawing::EnhancedCustomShapeParameter>(
+ propValue.Value)), &aH );
+ }
+ break;
+
+ case EAS_Position :
+ case EAS_Polar :
+ {
+ CheckAndResolveEquationParameter( const_cast<css::drawing::EnhancedCustomShapeParameter &>((*o3tl::doAccess<css::drawing::EnhancedCustomShapeParameterPair>(
+ propValue.Value)).First), &aH );
+ CheckAndResolveEquationParameter( const_cast<css::drawing::EnhancedCustomShapeParameter &>((*o3tl::doAccess<css::drawing::EnhancedCustomShapeParameterPair>(
+ propValue.Value)).Second), &aH );
+ }
+ break;
+ default:
+ break;
+ }
+ }
+ }
+ }
+
+ SdXMLCustomShapePropertyMerge( mrCustomShapeGeometry, maExtrusion, EASGet( EAS_Extrusion ) );
+ SdXMLCustomShapePropertyMerge( mrCustomShapeGeometry, maPath, EASGet( EAS_Path ) );
+ SdXMLCustomShapePropertyMerge( mrCustomShapeGeometry, maTextPath, EASGet( EAS_TextPath ) );
+ SdXMLCustomShapePropertyMerge( mrCustomShapeGeometry, maEquations, EASGet( EAS_Equations ) );
+ if ( !maHandles.empty() )
+ SdXMLCustomShapePropertyMerge( mrCustomShapeGeometry, maHandles, EASGet( EAS_Handles ) );
+}
+
+css::uno::Reference< css::xml::sax::XFastContextHandler > XMLEnhancedCustomShapeContext::createFastChildContext(
+ sal_Int32 nElement,
+ const css::uno::Reference< css::xml::sax::XFastAttributeList >& xAttrList )
+{
+ EnhancedCustomShapeTokenEnum aTokenEnum = EASGet( nElement );
+ if ( aTokenEnum == EAS_equation )
+ {
+ OUString aFormula;
+ OUString aFormulaName;
+ for( auto& aIter : sax_fastparser::castToFastAttributeList(xAttrList) )
+ {
+ OUString sValue = aIter.toString();
+ switch( EASGet( aIter.getToken() ) )
+ {
+ case EAS_formula :
+ aFormula = sValue;
+ break;
+ case EAS_name :
+ aFormulaName = sValue;
+ break;
+ default:
+ break;
+ }
+ }
+ if ( !aFormulaName.isEmpty() || !aFormula.isEmpty() )
+ {
+ maEquations.push_back( aFormula );
+ maEquationNames.push_back( aFormulaName );
+ }
+ }
+ else if ( aTokenEnum == EAS_handle )
+ {
+ std::vector< css::beans::PropertyValue > aHandle;
+ for( auto& aIter : sax_fastparser::castToFastAttributeList(xAttrList) )
+ {
+ switch( EASGet( aIter.getToken() ) )
+ {
+ case EAS_handle_mirror_vertical :
+ GetBool( aHandle, aIter.toView(), EAS_MirroredY );
+ break;
+ case EAS_handle_mirror_horizontal :
+ GetBool( aHandle, aIter.toView(), EAS_MirroredX );
+ break;
+ case EAS_handle_switched :
+ GetBool( aHandle, aIter.toView(), EAS_Switched );
+ break;
+ case EAS_handle_position :
+ GetEnhancedParameterPair( aHandle, aIter.toString(), EAS_Position );
+ break;
+ case EAS_handle_range_x_minimum :
+ GetEnhancedParameter( aHandle, aIter.toString(), EAS_RangeXMinimum );
+ break;
+ case EAS_handle_range_x_maximum :
+ GetEnhancedParameter( aHandle, aIter.toString(), EAS_RangeXMaximum );
+ break;
+ case EAS_handle_range_y_minimum :
+ GetEnhancedParameter( aHandle, aIter.toString(), EAS_RangeYMinimum );
+ break;
+ case EAS_handle_range_y_maximum :
+ GetEnhancedParameter( aHandle, aIter.toString(), EAS_RangeYMaximum );
+ break;
+ case EAS_handle_polar :
+ GetEnhancedParameterPair( aHandle, aIter.toString(), EAS_Polar );
+ break;
+ case EAS_handle_radius_range_minimum :
+ GetEnhancedParameter( aHandle, aIter.toString(), EAS_RadiusRangeMinimum );
+ break;
+ case EAS_handle_radius_range_maximum :
+ GetEnhancedParameter( aHandle, aIter.toString(), EAS_RadiusRangeMaximum );
+ break;
+ default:
+ break;
+ }
+ }
+ maHandles.push_back( comphelper::containerToSequence(aHandle) );
+ }
+ return nullptr;
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/xmloff/source/draw/ximpcustomshape.hxx b/xmloff/source/draw/ximpcustomshape.hxx
new file mode 100644
index 0000000000..f7e14765a1
--- /dev/null
+++ b/xmloff/source/draw/ximpcustomshape.hxx
@@ -0,0 +1,66 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#pragma once
+
+#include <xmloff/xmlictxt.hxx>
+#include <xmloff/xmluconv.hxx>
+#include <rtl/ustring.hxx>
+#include <vector>
+#include <com/sun/star/uno/Reference.h>
+#include <com/sun/star/beans/PropertyValue.hpp>
+#include <com/sun/star/beans/PropertyValues.hpp>
+#include <com/sun/star/drawing/XShape.hpp>
+
+namespace com::sun::star {
+ namespace container { class XIndexContainer; }
+ namespace beans { class XPropertySet; }
+ namespace xml::sax { class XAttributeList; }
+}
+
+class XMLEnhancedCustomShapeContext : public SvXMLImportContext
+{
+ SvXMLUnitConverter& mrUnitConverter;
+ css::uno::Reference< css::drawing::XShape >& mrxShape;
+ std::vector< css::beans::PropertyValue >& mrCustomShapeGeometry;
+
+ std::vector< css::beans::PropertyValue > maExtrusion;
+ std::vector< css::beans::PropertyValue > maPath;
+ std::vector< css::beans::PropertyValue > maTextPath;
+ std::vector< css::beans::PropertyValues > maHandles;
+ std::vector< OUString > maEquations;
+ std::vector< OUString > maEquationNames;
+
+public:
+
+
+ XMLEnhancedCustomShapeContext( SvXMLImport& rImport, css::uno::Reference< css::drawing::XShape > &,
+ std::vector< css::beans::PropertyValue >& rCustomShapeGeometry );
+
+ virtual void SAL_CALL startFastElement(
+ sal_Int32 nElement,
+ const css::uno::Reference< css::xml::sax::XFastAttributeList >& xAttrList ) override;
+ virtual void SAL_CALL endFastElement(sal_Int32 nElement) override;
+
+ virtual css::uno::Reference< css::xml::sax::XFastContextHandler > SAL_CALL createFastChildContext(
+ sal_Int32 nElement,
+ const css::uno::Reference< css::xml::sax::XFastAttributeList >& AttrList ) override;
+};
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/xmloff/source/draw/ximpgrp.cxx b/xmloff/source/draw/ximpgrp.cxx
new file mode 100644
index 0000000000..c9cf7e218a
--- /dev/null
+++ b/xmloff/source/draw/ximpgrp.cxx
@@ -0,0 +1,100 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#include<xmloff/xmlnamespace.hxx>
+#include "ximpgrp.hxx"
+#include <xmloff/xmltoken.hxx>
+#include "ximpshap.hxx"
+#include "eventimp.hxx"
+#include "descriptionimp.hxx"
+
+using namespace ::com::sun::star;
+using namespace ::xmloff::token;
+
+
+SdXMLGroupShapeContext::SdXMLGroupShapeContext(
+ SvXMLImport& rImport,
+ const uno::Reference< xml::sax::XFastAttributeList>& xAttrList,
+ uno::Reference< drawing::XShapes > const & rShapes,
+ bool bTemporaryShape)
+: SdXMLShapeContext( rImport, xAttrList, rShapes, bTemporaryShape )
+{
+}
+
+SdXMLGroupShapeContext::~SdXMLGroupShapeContext()
+{
+}
+
+css::uno::Reference< css::xml::sax::XFastContextHandler > SdXMLGroupShapeContext::createFastChildContext(
+ sal_Int32 nElement,
+ const css::uno::Reference< css::xml::sax::XFastAttributeList >& xAttrList )
+{
+ // #i68101#
+ if( nElement == XML_ELEMENT(SVG, XML_TITLE) ||
+ nElement == XML_ELEMENT(SVG, XML_DESC ) ||
+ nElement == XML_ELEMENT(SVG_COMPAT, XML_TITLE) ||
+ nElement == XML_ELEMENT(SVG_COMPAT, XML_DESC ) )
+ {
+ return new SdXMLDescriptionContext( GetImport(), nElement, mxShape );
+ }
+ else if( nElement == XML_ELEMENT(OFFICE, XML_EVENT_LISTENERS) )
+ {
+ return new SdXMLEventsContext( GetImport(), mxShape );
+ }
+ else if( nElement == XML_ELEMENT(DRAW, XML_GLUE_POINT) )
+ {
+ addGluePoint( xAttrList );
+ }
+ else
+ {
+ // call GroupChildContext function at common ShapeImport
+ return XMLShapeImportHelper::CreateGroupChildContext(
+ GetImport(), nElement, xAttrList, mxChildren);
+ }
+ return nullptr;
+}
+
+void SdXMLGroupShapeContext::startFastElement (sal_Int32 /*nElement*/,
+ const css::uno::Reference< css::xml::sax::XFastAttributeList >& /*xAttrList*/)
+{
+ // create new group shape and add it to rShapes, use it
+ // as base for the new group import
+ AddShape( "com.sun.star.drawing.GroupShape" );
+
+ if(mxShape.is())
+ {
+ SetStyle( false );
+
+ mxChildren.set( mxShape, uno::UNO_QUERY );
+ if( mxChildren.is() )
+ GetImport().GetShapeImport()->pushGroupForPostProcessing( mxChildren );
+ }
+
+ GetImport().GetShapeImport()->finishShape( mxShape, mxAttrList, mxShapes );
+}
+
+void SdXMLGroupShapeContext::endFastElement(sal_Int32 nElement)
+{
+ if( mxChildren.is() )
+ GetImport().GetShapeImport()->popGroupAndPostProcess();
+
+ SdXMLShapeContext::endFastElement(nElement);
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/xmloff/source/draw/ximpgrp.hxx b/xmloff/source/draw/ximpgrp.hxx
new file mode 100644
index 0000000000..8dda1b9ba1
--- /dev/null
+++ b/xmloff/source/draw/ximpgrp.hxx
@@ -0,0 +1,49 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#pragma once
+
+#include <xmloff/xmlictxt.hxx>
+#include <com/sun/star/drawing/XShapes.hpp>
+#include "ximpshap.hxx"
+
+// draw:g context (RECURSIVE)
+
+class SdXMLGroupShapeContext : public SdXMLShapeContext
+{
+ // the shape group this group is working on
+ css::uno::Reference< css::drawing::XShapes > mxChildren;
+
+public:
+
+ SdXMLGroupShapeContext( SvXMLImport& rImport,
+ const css::uno::Reference< css::xml::sax::XFastAttributeList>& xAttrList,
+ css::uno::Reference< css::drawing::XShapes > const & rShapes,
+ bool bTemporaryShape);
+ virtual ~SdXMLGroupShapeContext() override;
+
+ virtual void SAL_CALL startFastElement(
+ sal_Int32 nElement,
+ const css::uno::Reference< css::xml::sax::XFastAttributeList >& xAttrList ) override;
+ virtual void SAL_CALL endFastElement(sal_Int32 nElement) override;
+ virtual css::uno::Reference< css::xml::sax::XFastContextHandler > SAL_CALL createFastChildContext(
+ sal_Int32 nElement, const css::uno::Reference< css::xml::sax::XFastAttributeList >& AttrList ) override;
+};
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/xmloff/source/draw/ximplink.cxx b/xmloff/source/draw/ximplink.cxx
new file mode 100644
index 0000000000..24672f9a74
--- /dev/null
+++ b/xmloff/source/draw/ximplink.cxx
@@ -0,0 +1,67 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#include <sal/log.hxx>
+#include <utility>
+#include <xmloff/xmlimp.hxx>
+#include <xmloff/xmlnamespace.hxx>
+#include "ximplink.hxx"
+#include <xmloff/xmltoken.hxx>
+
+using namespace ::com::sun::star;
+using namespace ::xmloff::token;
+
+
+SdXMLShapeLinkContext::SdXMLShapeLinkContext( SvXMLImport& rImport, const uno::Reference< xml::sax::XFastAttributeList>& xAttrList, uno::Reference< drawing::XShapes > xShapes)
+: SvXMLShapeContext( rImport, false )
+, mxParent(std::move( xShapes ))
+{
+ for (auto &aIter : sax_fastparser::castToFastAttributeList( xAttrList ))
+ {
+ if( aIter.getToken() == XML_ELEMENT(XLINK, XML_HREF) )
+ {
+ assert(msHyperlink.pData);
+ msHyperlink = aIter.toString();
+ }
+ else
+ XMLOFF_WARN_UNKNOWN("xmloff", aIter);
+ }
+}
+
+SdXMLShapeLinkContext::~SdXMLShapeLinkContext()
+{
+}
+
+css::uno::Reference< css::xml::sax::XFastContextHandler > SdXMLShapeLinkContext::createFastChildContext(
+ sal_Int32 nElement,
+ const css::uno::Reference< css::xml::sax::XFastAttributeList >& xAttrList )
+{
+ SvXMLShapeContext* pContext = XMLShapeImportHelper::CreateGroupChildContext( GetImport(), nElement, xAttrList, mxParent);
+
+ if( pContext )
+ {
+ pContext->setHyperlink( msHyperlink );
+ return pContext;
+ }
+
+ return nullptr;
+
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/xmloff/source/draw/ximplink.hxx b/xmloff/source/draw/ximplink.hxx
new file mode 100644
index 0000000000..017c638402
--- /dev/null
+++ b/xmloff/source/draw/ximplink.hxx
@@ -0,0 +1,47 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#pragma once
+
+#include <xmloff/xmlictxt.hxx>
+#include <xmloff/shapeimport.hxx>
+#include <com/sun/star/drawing/XShapes.hpp>
+
+// draw:a context
+
+// this should have been a SvXMLImportContext but CreateGroupChildContext() returns
+// an unneeded derivation. Should be changed sometime during refactoring.
+
+class SdXMLShapeLinkContext : public SvXMLShapeContext
+{
+ // the parent shape group this link is placed in
+ css::uno::Reference< css::drawing::XShapes > mxParent;
+
+public:
+
+ SdXMLShapeLinkContext( SvXMLImport& rImport,
+ const css::uno::Reference< css::xml::sax::XFastAttributeList>& xAttrList,
+ css::uno::Reference< css::drawing::XShapes > xShapes);
+ virtual ~SdXMLShapeLinkContext() override;
+
+ virtual css::uno::Reference< css::xml::sax::XFastContextHandler > SAL_CALL createFastChildContext(
+ sal_Int32 nElement, const css::uno::Reference< css::xml::sax::XFastAttributeList >& AttrList ) override;
+};
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/xmloff/source/draw/ximpnote.cxx b/xmloff/source/draw/ximpnote.cxx
new file mode 100644
index 0000000000..d855e85bf4
--- /dev/null
+++ b/xmloff/source/draw/ximpnote.cxx
@@ -0,0 +1,92 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#include "ximpnote.hxx"
+#include <xmloff/xmlnamespace.hxx>
+
+using namespace ::com::sun::star;
+using namespace ::xmloff::token;
+
+SdXMLNotesContext::SdXMLNotesContext(
+ SdXMLImport& rImport, const css::uno::Reference<css::xml::sax::XFastAttributeList>& xAttrList,
+ uno::Reference<drawing::XShapes> const& rShapes)
+ : SdXMLGenericPageContext(rImport, xAttrList, rShapes)
+{
+ OUString sStyleName, sPageMasterName;
+
+ for (auto& aIter : sax_fastparser::castToFastAttributeList(xAttrList))
+ {
+ OUString sValue = aIter.toString();
+ switch (aIter.getToken())
+ {
+ case XML_ELEMENT(STYLE, XML_PAGE_LAYOUT_NAME):
+ {
+ sPageMasterName = sValue;
+ break;
+ }
+ case XML_ELEMENT(DRAW, XML_STYLE_NAME):
+ {
+ sStyleName = sValue;
+ break;
+ }
+ case XML_ELEMENT(PRESENTATION, XML_USE_HEADER_NAME):
+ case XML_ELEMENT(PRESENTATION_SO52, XML_USE_HEADER_NAME):
+ case XML_ELEMENT(PRESENTATION_OOO, XML_USE_HEADER_NAME):
+ {
+ maUseHeaderDeclName = sValue;
+ break;
+ }
+ case XML_ELEMENT(PRESENTATION, XML_USE_FOOTER_NAME):
+ case XML_ELEMENT(PRESENTATION_SO52, XML_USE_FOOTER_NAME):
+ case XML_ELEMENT(PRESENTATION_OOO, XML_USE_FOOTER_NAME):
+ {
+ maUseFooterDeclName = sValue;
+ break;
+ }
+ case XML_ELEMENT(PRESENTATION, XML_USE_DATE_TIME_NAME):
+ case XML_ELEMENT(PRESENTATION_SO52, XML_USE_DATE_TIME_NAME):
+ case XML_ELEMENT(PRESENTATION_OOO, XML_USE_DATE_TIME_NAME):
+ {
+ maUseDateTimeDeclName = sValue;
+ break;
+ }
+ }
+ }
+
+ SetStyle(sStyleName);
+
+ // now delete all up-to-now contained shapes from this notes page
+ uno::Reference<drawing::XShape> xShape;
+ while (rShapes->getCount())
+ {
+ rShapes->getByIndex(0) >>= xShape;
+ if (xShape.is())
+ rShapes->remove(xShape);
+ }
+
+ // set page-master?
+ if (!sPageMasterName.isEmpty())
+ {
+ SetPageMaster(sPageMasterName);
+ }
+}
+
+SdXMLNotesContext::~SdXMLNotesContext() {}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/xmloff/source/draw/ximpnote.hxx b/xmloff/source/draw/ximpnote.hxx
new file mode 100644
index 0000000000..d7fe276b84
--- /dev/null
+++ b/xmloff/source/draw/ximpnote.hxx
@@ -0,0 +1,36 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#pragma once
+
+#include "sdxmlimp_impl.hxx"
+#include "ximppage.hxx"
+
+// presentation:notes context
+
+class SdXMLNotesContext : public SdXMLGenericPageContext
+{
+public:
+ SdXMLNotesContext( SdXMLImport& rImport,
+ const css::uno::Reference< css::xml::sax::XFastAttributeList>& xAttrList,
+ css::uno::Reference< css::drawing::XShapes > const & rShapes);
+ virtual ~SdXMLNotesContext() override;
+};
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/xmloff/source/draw/ximppage.cxx b/xmloff/source/draw/ximppage.cxx
new file mode 100644
index 0000000000..37619c72ce
--- /dev/null
+++ b/xmloff/source/draw/ximppage.cxx
@@ -0,0 +1,600 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#include <sal/config.h>
+
+#include <com/sun/star/frame/XModel.hpp>
+#include <com/sun/star/geometry/RealPoint2D.hpp>
+#include <com/sun/star/text/XTextCursor.hpp>
+#include <com/sun/star/util/DateTime.hpp>
+#include <com/sun/star/lang/IndexOutOfBoundsException.hpp>
+#include <com/sun/star/lang/XMultiServiceFactory.hpp>
+#include <cppuhelper/implbase.hxx>
+#include <sax/tools/converter.hxx>
+#include <XMLNumberStylesImport.hxx>
+#include <xmloff/xmlstyle.hxx>
+#include <xmloff/xmltoken.hxx>
+#include <xmloff/xmlnamespace.hxx>
+#include "ximppage.hxx"
+#include <animimp.hxx>
+#include <XMLStringBufferImportContext.hxx>
+#include <xmloff/xmlictxt.hxx>
+#include "ximpstyl.hxx"
+#include <xmloff/prstylei.hxx>
+#include <PropertySetMerger.hxx>
+#include <sal/log.hxx>
+#include <comphelper/diagnose_ex.hxx>
+
+#include <xmloff/unointerfacetouniqueidentifiermapper.hxx>
+#include <xmloff/xmluconv.hxx>
+
+using namespace ::com::sun::star;
+using namespace ::xmloff::token;
+using namespace ::com::sun::star::uno;
+using namespace ::com::sun::star::lang;
+using namespace ::com::sun::star::text;
+using namespace ::com::sun::star::util;
+using namespace ::com::sun::star::beans;
+using namespace ::com::sun::star::drawing;
+using namespace ::com::sun::star::container;
+using namespace ::com::sun::star::office;
+using namespace ::com::sun::star::xml::sax;
+using namespace ::com::sun::star::geometry;
+
+namespace {
+
+class DrawAnnotationContext : public SvXMLImportContext
+{
+
+public:
+ DrawAnnotationContext( SvXMLImport& rImport, const Reference< xml::sax::XFastAttributeList>& xAttrList, const Reference< XAnnotationAccess >& xAnnotationAccess );
+
+ virtual css::uno::Reference< css::xml::sax::XFastContextHandler > SAL_CALL createFastChildContext(
+ sal_Int32 nElement, const css::uno::Reference< css::xml::sax::XFastAttributeList >& AttrList ) override;
+ virtual void SAL_CALL endFastElement(sal_Int32 nElement) override;
+
+private:
+ Reference< XAnnotation > mxAnnotation;
+ Reference< XTextCursor > mxCursor;
+
+ OUStringBuffer maAuthorBuffer;
+ OUStringBuffer maInitialsBuffer;
+ OUStringBuffer maDateBuffer;
+};
+
+}
+
+DrawAnnotationContext::DrawAnnotationContext( SvXMLImport& rImport, const Reference< xml::sax::XFastAttributeList>& xAttrList, const Reference< XAnnotationAccess >& xAnnotationAccess )
+: SvXMLImportContext( rImport )
+, mxAnnotation( xAnnotationAccess->createAndInsertAnnotation() )
+{
+ if( !mxAnnotation.is() )
+ return;
+
+ RealPoint2D aPosition;
+ RealSize2D aSize;
+
+ for (auto &aIter : sax_fastparser::castToFastAttributeList( xAttrList ))
+ {
+ switch( aIter.getToken() )
+ {
+ case XML_ELEMENT(SVG, XML_X):
+ case XML_ELEMENT(SVG_COMPAT, XML_X):
+ {
+ sal_Int32 x;
+ GetImport().GetMM100UnitConverter().convertMeasureToCore(
+ x, aIter.toView());
+ aPosition.X = static_cast<double>(x) / 100.0;
+ break;
+ }
+ case XML_ELEMENT(SVG, XML_Y):
+ case XML_ELEMENT(SVG_COMPAT, XML_Y):
+ {
+ sal_Int32 y;
+ GetImport().GetMM100UnitConverter().convertMeasureToCore(
+ y, aIter.toView());
+ aPosition.Y = static_cast<double>(y) / 100.0;
+ break;
+ }
+ case XML_ELEMENT(SVG, XML_WIDTH):
+ case XML_ELEMENT(SVG_COMPAT, XML_WIDTH):
+ {
+ sal_Int32 w;
+ GetImport().GetMM100UnitConverter().convertMeasureToCore(
+ w, aIter.toView());
+ aSize.Width = static_cast<double>(w) / 100.0;
+ break;
+ }
+ case XML_ELEMENT(SVG, XML_HEIGHT):
+ case XML_ELEMENT(SVG_COMPAT, XML_HEIGHT):
+ {
+ sal_Int32 h;
+ GetImport().GetMM100UnitConverter().convertMeasureToCore(
+ h, aIter.toView());
+ aSize.Height = static_cast<double>(h) / 100.0;
+ }
+ break;
+ default:
+ XMLOFF_WARN_UNKNOWN("xmloff", aIter);
+ }
+ }
+
+ mxAnnotation->setPosition( aPosition );
+ mxAnnotation->setSize( aSize );
+}
+
+css::uno::Reference< css::xml::sax::XFastContextHandler > DrawAnnotationContext::createFastChildContext(
+ sal_Int32 nElement,
+ const css::uno::Reference< css::xml::sax::XFastAttributeList >& xAttrList )
+{
+ if( mxAnnotation.is() )
+ {
+ if (nElement == XML_ELEMENT(DC, XML_CREATOR) )
+ return new XMLStringBufferImportContext(GetImport(), maAuthorBuffer);
+ else if( nElement == XML_ELEMENT(DC, XML_DATE) )
+ return new XMLStringBufferImportContext(GetImport(), maDateBuffer);
+ else if ( nElement == XML_ELEMENT(TEXT, XML_SENDER_INITIALS)
+ || nElement == XML_ELEMENT(LO_EXT, XML_SENDER_INITIALS)
+ || nElement == XML_ELEMENT(META, XML_CREATOR_INITIALS))
+ {
+ return new XMLStringBufferImportContext(GetImport(), maInitialsBuffer);
+ }
+ else
+ {
+ // create text cursor on demand
+ if( !mxCursor.is() )
+ {
+ uno::Reference< text::XText > xText( mxAnnotation->getTextRange() );
+ if( xText.is() )
+ {
+ rtl::Reference < XMLTextImportHelper > xTxtImport = GetImport().GetTextImport();
+ mxCursor = xText->createTextCursor();
+ if( mxCursor.is() )
+ xTxtImport->SetCursor( mxCursor );
+ }
+ }
+
+ // if we have a text cursor, lets try to import some text
+ if( mxCursor.is() )
+ {
+ auto p = GetImport().GetTextImport()->CreateTextChildContext( GetImport(), nElement, xAttrList );
+ if (p)
+ return p;
+ }
+ }
+ }
+ XMLOFF_WARN_UNKNOWN_ELEMENT("xmloff", nElement);
+ return nullptr;
+}
+
+void DrawAnnotationContext::endFastElement(sal_Int32)
+{
+ if(mxCursor.is())
+ {
+ // delete addition newline
+ mxCursor->gotoEnd( false );
+ mxCursor->goLeft( 1, true );
+ mxCursor->setString( "" );
+
+ // reset cursor
+ GetImport().GetTextImport()->ResetCursor();
+ }
+
+ if( mxAnnotation.is() )
+ {
+ mxAnnotation->setAuthor( maAuthorBuffer.makeStringAndClear() );
+ mxAnnotation->setInitials( maInitialsBuffer.makeStringAndClear() );
+
+ util::DateTime aDateTime;
+ if (::sax::Converter::parseDateTime(aDateTime, maDateBuffer))
+ {
+ mxAnnotation->setDateTime(aDateTime);
+ }
+ maDateBuffer.setLength(0);
+ }
+}
+
+
+SdXMLGenericPageContext::SdXMLGenericPageContext(
+ SvXMLImport& rImport,
+ const Reference< xml::sax::XFastAttributeList>& xAttrList,
+ Reference< drawing::XShapes > const & rShapes)
+: SvXMLImportContext( rImport )
+, mxShapes( rShapes )
+, mxAnnotationAccess( rShapes, UNO_QUERY )
+{
+ for (auto &aIter : sax_fastparser::castToFastAttributeList( xAttrList ))
+ {
+ if( aIter.getToken() == XML_ELEMENT(DRAW, XML_NAV_ORDER) )
+ {
+ msNavOrder = aIter.toString();
+ break;
+ }
+ }
+}
+
+SdXMLGenericPageContext::~SdXMLGenericPageContext()
+{
+}
+
+void SdXMLGenericPageContext::startFastElement( sal_Int32 /*nElement*/, const Reference< css::xml::sax::XFastAttributeList >& )
+{
+ GetImport().GetShapeImport()->pushGroupForPostProcessing( mxShapes );
+
+ if( GetImport().IsFormsSupported() )
+ GetImport().GetFormImport()->startPage( Reference< drawing::XDrawPage >::query( mxShapes ) );
+}
+
+css::uno::Reference< css::xml::sax::XFastContextHandler > SdXMLGenericPageContext::createFastChildContext(
+ sal_Int32 nElement,
+ const Reference< xml::sax::XFastAttributeList>& xAttrList )
+{
+ if( nElement == XML_ELEMENT(PRESENTATION, XML_ANIMATIONS) )
+ {
+ return new XMLAnimationsContext( GetImport() );
+ }
+ else if( nElement == XML_ELEMENT(OFFICE, XML_FORMS) )
+ {
+ if( GetImport().IsFormsSupported() )
+ return xmloff::OFormLayerXMLImport::createOfficeFormsContext( GetImport() );
+ }
+ else if( nElement == XML_ELEMENT(OFFICE, XML_ANNOTATION) || nElement == XML_ELEMENT(OFFICE_EXT, XML_ANNOTATION) )
+ {
+ if( mxAnnotationAccess.is() )
+ return new DrawAnnotationContext( GetImport(), xAttrList, mxAnnotationAccess );
+ }
+ else
+ {
+ // call GroupChildContext function at common ShapeImport
+ auto p = XMLShapeImportHelper::CreateGroupChildContext(GetImport(), nElement, xAttrList, mxShapes);
+ if (p)
+ return p;
+ }
+ XMLOFF_WARN_UNKNOWN_ELEMENT("xmloff", nElement);
+ return nullptr;
+}
+
+void SdXMLGenericPageContext::endFastElement(sal_Int32 )
+{
+ GetImport().GetShapeImport()->popGroupAndPostProcess();
+
+ if( GetImport().IsFormsSupported() )
+ GetImport().GetFormImport()->endPage();
+
+ if( !maUseHeaderDeclName.isEmpty() || !maUseFooterDeclName.isEmpty() || !maUseDateTimeDeclName.isEmpty() )
+ {
+ try
+ {
+ Reference <beans::XPropertySet> xSet(mxShapes, uno::UNO_QUERY_THROW );
+ Reference< beans::XPropertySetInfo > xInfo( xSet->getPropertySetInfo() );
+
+ if( !maUseHeaderDeclName.isEmpty() )
+ {
+ static constexpr OUString aStrHeaderTextProp( u"HeaderText"_ustr );
+ if( xInfo->hasPropertyByName( aStrHeaderTextProp ) )
+ xSet->setPropertyValue( aStrHeaderTextProp,
+ Any( GetSdImport().GetHeaderDecl( maUseHeaderDeclName ) ) );
+ }
+
+ if( !maUseFooterDeclName.isEmpty() )
+ {
+ static constexpr OUString aStrFooterTextProp( u"FooterText"_ustr );
+ if( xInfo->hasPropertyByName( aStrFooterTextProp ) )
+ xSet->setPropertyValue( aStrFooterTextProp,
+ Any( GetSdImport().GetFooterDecl( maUseFooterDeclName ) ) );
+ }
+
+ if( !maUseDateTimeDeclName.isEmpty() )
+ {
+ static constexpr OUString aStrDateTimeTextProp( u"DateTimeText"_ustr );
+ if( xInfo->hasPropertyByName( aStrDateTimeTextProp ) )
+ {
+ bool bFixed;
+ OUString aDateTimeFormat;
+ const OUString aText( GetSdImport().GetDateTimeDecl( maUseDateTimeDeclName, bFixed, aDateTimeFormat ) );
+
+ xSet->setPropertyValue("IsDateTimeFixed",
+ Any( bFixed ) );
+
+ if( bFixed )
+ {
+ xSet->setPropertyValue( aStrDateTimeTextProp, Any( aText ) );
+ }
+ else if( !aDateTimeFormat.isEmpty() )
+ {
+ const SdXMLStylesContext* pStyles = dynamic_cast< const SdXMLStylesContext* >( GetSdImport().GetShapeImport()->GetStylesContext() );
+ if( !pStyles )
+ pStyles = dynamic_cast< const SdXMLStylesContext* >( GetSdImport().GetShapeImport()->GetAutoStylesContext() );
+
+ if( pStyles )
+ {
+ const SdXMLNumberFormatImportContext* pSdNumStyle =
+ dynamic_cast< const SdXMLNumberFormatImportContext* >( pStyles->FindStyleChildContext( XmlStyleFamily::DATA_STYLE, aDateTimeFormat, true ) );
+
+ if( pSdNumStyle )
+ {
+ xSet->setPropertyValue("DateTimeFormat",
+ Any( pSdNumStyle->GetDrawKey() ) );
+ }
+ }
+ }
+ }
+ }
+ }
+ catch(const uno::Exception&)
+ {
+ TOOLS_WARN_EXCEPTION("xmloff.draw", "");
+ }
+ }
+
+ SetNavigationOrder();
+}
+
+void SdXMLGenericPageContext::SetStyle( OUString const & rStyleName )
+{
+ // set PageProperties?
+ if(rStyleName.isEmpty())
+ return;
+
+ try
+ {
+ const SvXMLImportContext* pContext = GetSdImport().GetShapeImport()->GetAutoStylesContext();
+
+ if (const SdXMLStylesContext* pStyles = dynamic_cast<const SdXMLStylesContext *>(pContext))
+ {
+ const SvXMLStyleContext* pStyle = pStyles->FindStyleChildContext(
+ XmlStyleFamily::SD_DRAWINGPAGE_ID, rStyleName);
+
+ if (const XMLPropStyleContext* pPropStyle = dynamic_cast<const XMLPropStyleContext*>(pStyle))
+ {
+ Reference <beans::XPropertySet> xPropSet1(mxShapes, uno::UNO_QUERY);
+ if(xPropSet1.is())
+ {
+ Reference< beans::XPropertySet > xPropSet( xPropSet1 );
+ Reference< beans::XPropertySet > xBackgroundSet;
+
+ static constexpr OUString aBackground(u"Background"_ustr);
+ if( xPropSet1->getPropertySetInfo()->hasPropertyByName( aBackground ) )
+ {
+ Reference< beans::XPropertySetInfo > xInfo( xPropSet1->getPropertySetInfo() );
+ if( xInfo.is() && xInfo->hasPropertyByName( aBackground ) )
+ {
+ Reference< lang::XMultiServiceFactory > xServiceFact(GetSdImport().GetModel(), uno::UNO_QUERY);
+ if(xServiceFact.is())
+ {
+ xBackgroundSet.set(xServiceFact->createInstance("com.sun.star.drawing.Background"), UNO_QUERY);
+ }
+ }
+
+ if( xBackgroundSet.is() )
+ xPropSet = PropertySetMerger_CreateInstance( xPropSet1, xBackgroundSet );
+ }
+
+ if(xPropSet.is())
+ {
+ const_cast<XMLPropStyleContext*>(pPropStyle)->FillPropertySet(xPropSet);
+
+ if( xBackgroundSet.is() )
+ xPropSet1->setPropertyValue( aBackground, uno::Any( xBackgroundSet ) );
+ }
+ }
+ }
+ }
+ }
+ catch (const uno::Exception&)
+ {
+ TOOLS_WARN_EXCEPTION("xmloff.draw", "");
+ }
+}
+
+void SdXMLGenericPageContext::SetLayout()
+{
+ // set PresentationPageLayout?
+ if(!GetSdImport().IsImpress() || maPageLayoutName.isEmpty())
+ return;
+
+ sal_Int32 nType = -1;
+
+ const SvXMLImportContext* pContext = GetSdImport().GetShapeImport()->GetStylesContext();
+
+ if (const SdXMLStylesContext* pStyles = dynamic_cast<const SdXMLStylesContext *>(pContext))
+ {
+ const SvXMLStyleContext* pStyle = pStyles->FindStyleChildContext( XmlStyleFamily::SD_PRESENTATIONPAGELAYOUT_ID, maPageLayoutName);
+
+ if (const SdXMLPresentationPageLayoutContext* pLayout = dynamic_cast<const SdXMLPresentationPageLayoutContext*>(pStyle))
+ {
+ nType = pLayout->GetTypeId();
+ }
+ }
+
+ if( -1 == nType )
+ {
+ Reference< container::XNameAccess > xPageLayouts( GetSdImport().getPageLayouts() );
+ if( xPageLayouts.is() )
+ {
+ if( xPageLayouts->hasByName( maPageLayoutName ) )
+ xPageLayouts->getByName( maPageLayoutName ) >>= nType;
+ }
+
+ }
+
+ if( -1 != nType )
+ {
+ Reference <beans::XPropertySet> xPropSet(mxShapes, uno::UNO_QUERY);
+ if(xPropSet.is())
+ {
+ OUString aPropName("Layout");
+ Reference< beans::XPropertySetInfo > xInfo( xPropSet->getPropertySetInfo() );
+ if( xInfo.is() && xInfo->hasPropertyByName( aPropName ) )
+ xPropSet->setPropertyValue(aPropName, uno::Any( static_cast<sal_Int16>(nType) ) );
+ }
+ }
+}
+
+void SdXMLGenericPageContext::DeleteAllShapes()
+{
+ // now delete all up-to-now contained shapes; they have been created
+ // when setting the presentation page layout.
+ while(mxShapes->getCount())
+ {
+ Reference< drawing::XShape > xShape;
+ uno::Any aAny(mxShapes->getByIndex(0));
+
+ aAny >>= xShape;
+
+ if(xShape.is())
+ {
+ mxShapes->remove(xShape);
+ }
+ }
+}
+
+void SdXMLGenericPageContext::SetPageMaster( OUString const & rsPageMasterName )
+{
+ if (!GetSdImport().GetShapeImport()->GetStylesContext())
+ return;
+
+ // look for PageMaster with this name
+
+ // #80012# GetStylesContext() replaced with GetAutoStylesContext()
+ const SvXMLStylesContext* pAutoStyles = GetSdImport().GetShapeImport()->GetAutoStylesContext();
+
+ const SvXMLStyleContext* pStyle = pAutoStyles ? pAutoStyles->FindStyleChildContext(XmlStyleFamily::SD_PAGEMASTERCONTEXT_ID, rsPageMasterName) : nullptr;
+
+ const SdXMLPageMasterContext* pPageMaster = dynamic_cast<const SdXMLPageMasterContext*>(pStyle);
+ if (!pPageMaster)
+ return;
+
+ const SdXMLPageMasterStyleContext* pPageMasterContext = pPageMaster->GetPageMasterStyle();
+
+ if (!pPageMasterContext)
+ return;
+
+ Reference< drawing::XDrawPage > xMasterPage(GetLocalShapesContext(), uno::UNO_QUERY);
+ if (!xMasterPage.is())
+ return;
+
+ // set sizes for this masterpage
+ Reference <beans::XPropertySet> xPropSet(xMasterPage, uno::UNO_QUERY);
+ if (xPropSet.is())
+ {
+ xPropSet->setPropertyValue("BorderBottom", Any(pPageMasterContext->GetBorderBottom()));
+ xPropSet->setPropertyValue("BorderLeft", Any(pPageMasterContext->GetBorderLeft()));
+ xPropSet->setPropertyValue("BorderRight", Any(pPageMasterContext->GetBorderRight()));
+ xPropSet->setPropertyValue("BorderTop", Any(pPageMasterContext->GetBorderTop()));
+ xPropSet->setPropertyValue("Width", Any(pPageMasterContext->GetWidth()));
+ xPropSet->setPropertyValue("Height", Any(pPageMasterContext->GetHeight()));
+ xPropSet->setPropertyValue("Orientation", Any(pPageMasterContext->GetOrientation()));
+ }
+}
+
+namespace {
+
+class XoNavigationOrderAccess : public ::cppu::WeakImplHelper< XIndexAccess >
+{
+public:
+ explicit XoNavigationOrderAccess( std::vector< Reference< XShape > >& rShapes );
+
+ // XIndexAccess
+ virtual sal_Int32 SAL_CALL getCount( ) override;
+ virtual Any SAL_CALL getByIndex( sal_Int32 Index ) override;
+
+ // XElementAccess
+ virtual Type SAL_CALL getElementType( ) override;
+ virtual sal_Bool SAL_CALL hasElements( ) override;
+
+private:
+ std::vector< Reference< XShape > > maShapes;
+};
+
+}
+
+XoNavigationOrderAccess::XoNavigationOrderAccess( std::vector< Reference< XShape > >& rShapes )
+{
+ maShapes.swap( rShapes );
+}
+
+// XIndexAccess
+sal_Int32 SAL_CALL XoNavigationOrderAccess::getCount( )
+{
+ return static_cast< sal_Int32 >( maShapes.size() );
+}
+
+Any SAL_CALL XoNavigationOrderAccess::getByIndex( sal_Int32 Index )
+{
+ if( (Index < 0) || (Index > getCount()) )
+ throw IndexOutOfBoundsException();
+
+ return Any( maShapes[Index] );
+}
+
+// XElementAccess
+Type SAL_CALL XoNavigationOrderAccess::getElementType( )
+{
+ return cppu::UnoType<XShape>::get();
+}
+
+sal_Bool SAL_CALL XoNavigationOrderAccess::hasElements( )
+{
+ return !maShapes.empty();
+}
+
+void SdXMLGenericPageContext::SetNavigationOrder()
+{
+ if( msNavOrder.isEmpty() )
+ return;
+
+ try
+ {
+ sal_uInt32 nIndex;
+ const sal_uInt32 nCount = static_cast< sal_uInt32 >( mxShapes->getCount() );
+ std::vector< Reference< XShape > > aShapes( nCount );
+
+ ::comphelper::UnoInterfaceToUniqueIdentifierMapper& rIdMapper = GetSdImport().getInterfaceToIdentifierMapper();
+ SvXMLTokenEnumerator aEnumerator( msNavOrder );
+ std::u16string_view sId;
+ for( nIndex = 0; nIndex < nCount; ++nIndex )
+ {
+ if( !aEnumerator.getNextToken(sId) )
+ break;
+
+ aShapes[nIndex].set( rIdMapper.getReference( OUString(sId) ), UNO_QUERY );
+ }
+
+ for( nIndex = 0; nIndex < nCount; ++nIndex )
+ {
+ if( !aShapes[nIndex].is() )
+ {
+ OSL_FAIL("xmloff::SdXMLGenericPageContext::SetNavigationOrder(), draw:nav-order attribute incomplete!");
+ // todo: warning?
+ return;
+ }
+ }
+
+ Reference< XPropertySet > xSet( mxShapes, UNO_QUERY_THROW );
+ xSet->setPropertyValue("NavigationOrder", Any( Reference< XIndexAccess >( new XoNavigationOrderAccess( aShapes ) ) ) );
+ }
+ catch(const uno::Exception&)
+ {
+ TOOLS_WARN_EXCEPTION("xmloff.draw",
+ "unexpected exception caught while importing shape navigation order!");
+ }
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/xmloff/source/draw/ximppage.hxx b/xmloff/source/draw/ximppage.hxx
new file mode 100644
index 0000000000..5303458dd1
--- /dev/null
+++ b/xmloff/source/draw/ximppage.hxx
@@ -0,0 +1,77 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#pragma once
+
+#include <xmloff/xmlictxt.hxx>
+#include "sdxmlimp_impl.hxx"
+#include <com/sun/star/drawing/XShapes.hpp>
+#include <com/sun/star/office/XAnnotationAccess.hpp>
+
+// draw:g context (RECURSIVE)
+
+class SdXMLGenericPageContext : public SvXMLImportContext
+{
+ // the shape group this group is working on
+ css::uno::Reference< css::drawing::XShapes > mxShapes;
+ css::uno::Reference< css::office::XAnnotationAccess > mxAnnotationAccess;
+
+protected:
+ OUString maPageLayoutName;
+ OUString maUseHeaderDeclName;
+ OUString maUseFooterDeclName;
+ OUString maUseDateTimeDeclName;
+ OUString msNavOrder;
+
+ /** sets the page style on this page */
+ void SetStyle( OUString const & rStyleName );
+
+ /** sets the presentation layout at this page. It is used for drawing pages and for the handout master */
+ void SetLayout();
+
+ /** deletes all shapes on this drawing page */
+ void DeleteAllShapes();
+
+ const SdXMLImport& GetSdImport() const { return static_cast<const SdXMLImport&>(GetImport()); }
+ SdXMLImport& GetSdImport() { return static_cast<SdXMLImport&>(GetImport()); }
+
+ /** sets the properties from a page master style with the given name on this contexts page */
+ void SetPageMaster( OUString const & rsPageMasterName );
+
+ void SetNavigationOrder();
+
+public:
+
+ SdXMLGenericPageContext( SvXMLImport& rImport,
+ const css::uno::Reference< css::xml::sax::XFastAttributeList>& xAttrList,
+ css::uno::Reference< css::drawing::XShapes > const & rShapes);
+ virtual ~SdXMLGenericPageContext() override;
+
+ virtual void SAL_CALL startFastElement( sal_Int32 nElement, const css::uno::Reference< css::xml::sax::XFastAttributeList >& xAttrList ) override;
+ virtual css::uno::Reference< css::xml::sax::XFastContextHandler > SAL_CALL createFastChildContext(
+ sal_Int32 nElement, const css::uno::Reference< css::xml::sax::XFastAttributeList >& AttrList ) override;
+ virtual void SAL_CALL endFastElement(sal_Int32 nElement) override;
+
+ const css::uno::Reference< css::drawing::XShapes >& GetLocalShapesContext() const
+ { return mxShapes; }
+ css::uno::Reference< css::drawing::XShapes >& GetLocalShapesContext()
+ { return mxShapes; }
+};
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/xmloff/source/draw/ximpshap.cxx b/xmloff/source/draw/ximpshap.cxx
new file mode 100644
index 0000000000..aaee9668fa
--- /dev/null
+++ b/xmloff/source/draw/ximpshap.cxx
@@ -0,0 +1,4021 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#include <config_wasm_strip.h>
+
+#include <cassert>
+
+#include <sal/log.hxx>
+#include <com/sun/star/document/XEventsSupplier.hpp>
+#include <com/sun/star/container/XNameReplace.hpp>
+#include <com/sun/star/presentation/ClickAction.hpp>
+#include <com/sun/star/drawing/FillStyle.hpp>
+#include <com/sun/star/drawing/LineStyle.hpp>
+#include <utility>
+#include <xmloff/unointerfacetouniqueidentifiermapper.hxx>
+#include <com/sun/star/drawing/XGluePointsSupplier.hpp>
+#include <com/sun/star/drawing/GluePoint2.hpp>
+#include <com/sun/star/drawing/Alignment.hpp>
+#include <com/sun/star/drawing/EscapeDirection.hpp>
+#include <com/sun/star/media/ZoomLevel.hpp>
+#include <com/sun/star/awt/Rectangle.hpp>
+#include <com/sun/star/style/XStyleFamiliesSupplier.hpp>
+#include <com/sun/star/container/XNameAccess.hpp>
+#include "ximpshap.hxx"
+#include <xmloff/XMLBase64ImportContext.hxx>
+#include <xmloff/XMLShapeStyleContext.hxx>
+#include <xmloff/xmluconv.hxx>
+#include <com/sun/star/container/XNamed.hpp>
+#include <com/sun/star/beans/XPropertySet.hpp>
+#include <com/sun/star/awt/XControlModel.hpp>
+#include <com/sun/star/drawing/XControlShape.hpp>
+#include <com/sun/star/drawing/PointSequenceSequence.hpp>
+#include <com/sun/star/drawing/PointSequence.hpp>
+#include <com/sun/star/lang/XServiceInfo.hpp>
+#include <com/sun/star/lang/XMultiServiceFactory.hpp>
+#include <com/sun/star/util/XCloneable.hpp>
+#include <com/sun/star/beans/XMultiPropertyStates.hpp>
+#include <xexptran.hxx>
+#include <com/sun/star/drawing/PolyPolygonBezierCoords.hpp>
+#include <com/sun/star/beans/XPropertySetInfo.hpp>
+#include <com/sun/star/drawing/HomogenMatrix3.hpp>
+#include <com/sun/star/graphic/XGraphic.hpp>
+#include <com/sun/star/style/XStyle.hpp>
+
+#include <sax/tools/converter.hxx>
+#include <comphelper/sequence.hxx>
+#include <comphelper/diagnose_ex.hxx>
+#include <comphelper/mediamimetype.hxx>
+
+#include <xmloff/families.hxx>
+#include<xmloff/xmlnamespace.hxx>
+#include <xmloff/xmltoken.hxx>
+#include <EnhancedCustomShapeToken.hxx>
+#include <XMLReplacementImageContext.hxx>
+#include <XMLImageMapContext.hxx>
+#include "sdpropls.hxx"
+#include "eventimp.hxx"
+#include "descriptionimp.hxx"
+#include "SignatureLineContext.hxx"
+#include "QRCodeContext.hxx"
+#include "ximpcustomshape.hxx"
+#include <XMLEmbeddedObjectImportContext.hxx>
+#include <xmloff/xmlerror.hxx>
+#include <xmloff/table/XMLTableImport.hxx>
+#include <xmloff/ProgressBarHelper.hxx>
+#include <basegfx/matrix/b2dhommatrix.hxx>
+#include <com/sun/star/drawing/XEnhancedCustomShapeDefaulter.hpp>
+#include <com/sun/star/container/XChild.hpp>
+#include <com/sun/star/text/XTextDocument.hpp>
+#include <basegfx/matrix/b2dhommatrixtools.hxx>
+#include <basegfx/point/b2dpoint.hxx>
+#include <basegfx/polygon/b2dpolygon.hxx>
+#include <basegfx/polygon/b2dpolygontools.hxx>
+#include <basegfx/polygon/b2dpolypolygon.hxx>
+#include <basegfx/polygon/b2dpolypolygontools.hxx>
+#include <basegfx/vector/b2dvector.hxx>
+#include <tools/urlobj.hxx>
+#include <o3tl/any.hxx>
+#include <o3tl/safeint.hxx>
+
+using namespace ::com::sun::star;
+using namespace ::com::sun::star::uno;
+using namespace ::com::sun::star::drawing;
+using namespace ::com::sun::star::style;
+using namespace ::com::sun::star::container;
+using namespace ::com::sun::star::document;
+using namespace ::xmloff::token;
+using namespace ::xmloff::EnhancedCustomShapeToken;
+
+SvXMLEnumMapEntry<drawing::Alignment> const aXML_GlueAlignment_EnumMap[] =
+{
+ { XML_TOP_LEFT, drawing::Alignment_TOP_LEFT },
+ { XML_TOP, drawing::Alignment_TOP },
+ { XML_TOP_RIGHT, drawing::Alignment_TOP_RIGHT },
+ { XML_LEFT, drawing::Alignment_LEFT },
+ { XML_CENTER, drawing::Alignment_CENTER },
+ { XML_RIGHT, drawing::Alignment_RIGHT },
+ { XML_BOTTOM_LEFT, drawing::Alignment_BOTTOM_LEFT },
+ { XML_BOTTOM, drawing::Alignment_BOTTOM },
+ { XML_BOTTOM_RIGHT, drawing::Alignment_BOTTOM_RIGHT },
+ { XML_TOKEN_INVALID, drawing::Alignment(0) }
+};
+
+SvXMLEnumMapEntry<drawing::EscapeDirection> const aXML_GlueEscapeDirection_EnumMap[] =
+{
+ { XML_AUTO, drawing::EscapeDirection_SMART },
+ { XML_LEFT, drawing::EscapeDirection_LEFT },
+ { XML_RIGHT, drawing::EscapeDirection_RIGHT },
+ { XML_UP, drawing::EscapeDirection_UP },
+ { XML_DOWN, drawing::EscapeDirection_DOWN },
+ { XML_HORIZONTAL, drawing::EscapeDirection_HORIZONTAL },
+ { XML_VERTICAL, drawing::EscapeDirection_VERTICAL },
+ { XML_TOKEN_INVALID, drawing::EscapeDirection(0) }
+};
+
+static bool ImpIsEmptyURL( std::u16string_view rURL )
+{
+ if( rURL.empty() )
+ return true;
+
+ // #i13140# Also compare against 'toplevel' URLs. which also
+ // result in empty filename strings.
+ if( rURL == u"#./" )
+ return true;
+
+ return false;
+}
+
+
+SdXMLShapeContext::SdXMLShapeContext(
+ SvXMLImport& rImport,
+ css::uno::Reference< css::xml::sax::XFastAttributeList> xAttrList,
+ uno::Reference< drawing::XShapes > xShapes,
+ bool bTemporaryShape)
+ : SvXMLShapeContext( rImport, bTemporaryShape )
+ , mxShapes(std::move( xShapes ))
+ , mxAttrList(std::move(xAttrList))
+ , mbListContextPushed( false )
+ , mnStyleFamily(XmlStyleFamily::SD_GRAPHICS_ID)
+ , mbIsPlaceholder(false)
+ , mbClearDefaultAttributes( true )
+ , mbIsUserTransformed(false)
+ , mnZOrder(-1)
+ , maSize(1, 1)
+ , mnRelWidth(0)
+ , mnRelHeight(0)
+ , maPosition(0, 0)
+ , mbVisible(true)
+ , mbPrintable(true)
+ , mbHaveXmlId(false)
+ , mbTextBox(false)
+{
+}
+
+SdXMLShapeContext::~SdXMLShapeContext()
+{
+}
+
+css::uno::Reference< css::xml::sax::XFastContextHandler > SdXMLShapeContext::createFastChildContext(
+ sal_Int32 nElement,
+ const css::uno::Reference< css::xml::sax::XFastAttributeList >& xAttrList )
+{
+ SvXMLImportContextRef xContext;
+ // #i68101#
+ if( nElement == XML_ELEMENT(SVG, XML_TITLE) || nElement == XML_ELEMENT(SVG, XML_DESC)
+ || nElement == XML_ELEMENT(SVG_COMPAT, XML_TITLE) || nElement == XML_ELEMENT(SVG_COMPAT, XML_DESC) )
+ {
+ xContext = new SdXMLDescriptionContext( GetImport(), nElement, mxShape );
+ }
+ else if( nElement == XML_ELEMENT(LO_EXT, XML_SIGNATURELINE) )
+ {
+ xContext = new SignatureLineContext( GetImport(), nElement, xAttrList, mxShape );
+ }
+ else if( nElement == XML_ELEMENT(LO_EXT, XML_QRCODE) )
+ {
+ xContext = new QRCodeContext( GetImport(), nElement, xAttrList, mxShape );
+ }
+ else if( nElement == XML_ELEMENT(OFFICE, XML_EVENT_LISTENERS) )
+ {
+ xContext = new SdXMLEventsContext( GetImport(), mxShape );
+ }
+ else if( nElement == XML_ELEMENT(DRAW, XML_GLUE_POINT) )
+ {
+ addGluePoint( xAttrList );
+ }
+ else if( nElement == XML_ELEMENT(DRAW, XML_THUMBNAIL) )
+ {
+ // search attributes for xlink:href
+ maThumbnailURL = xAttrList->getOptionalValue(XML_ELEMENT(XLINK, XML_HREF));
+ }
+ else
+ {
+ // create text cursor on demand
+ if( !mxCursor.is() )
+ {
+ uno::Reference< text::XText > xText( mxShape, uno::UNO_QUERY );
+ if( xText.is() )
+ {
+ rtl::Reference < XMLTextImportHelper > xTxtImport =
+ GetImport().GetTextImport();
+ mxOldCursor = xTxtImport->GetCursor();
+ mxCursor = xText->createTextCursor();
+ if( mxCursor.is() )
+ {
+ xTxtImport->SetCursor( mxCursor );
+ }
+
+ // remember old list item and block (#91964#) and reset them
+ // for the text frame
+ xTxtImport->PushListContext();
+ mbListContextPushed = true;
+ }
+ }
+
+ // if we have a text cursor, lets try to import some text
+ if( mxCursor.is() )
+ {
+ xContext = GetImport().GetTextImport()->CreateTextChildContext(
+ GetImport(), nElement, xAttrList,
+ ( mbTextBox ? XMLTextType::TextBox : XMLTextType::Shape ) );
+ }
+ }
+
+ if (!xContext)
+ XMLOFF_WARN_UNKNOWN_ELEMENT("xmloff", nElement);
+
+ return xContext;
+}
+
+void SdXMLShapeContext::addGluePoint( const uno::Reference< xml::sax::XFastAttributeList>& xAttrList )
+{
+ // get the gluepoints container for this shape if it's not already there
+ if( !mxGluePoints.is() )
+ {
+ uno::Reference< drawing::XGluePointsSupplier > xSupplier( mxShape, uno::UNO_QUERY );
+ if( !xSupplier.is() )
+ return;
+
+ mxGluePoints.set( xSupplier->getGluePoints(), UNO_QUERY );
+
+ if( !mxGluePoints.is() )
+ return;
+ }
+
+ drawing::GluePoint2 aGluePoint;
+ aGluePoint.IsUserDefined = true;
+ aGluePoint.Position.X = 0;
+ aGluePoint.Position.Y = 0;
+ aGluePoint.Escape = drawing::EscapeDirection_SMART;
+ aGluePoint.PositionAlignment = drawing::Alignment_CENTER;
+ aGluePoint.IsRelative = true;
+
+ sal_Int32 nId = -1;
+
+ // read attributes for the 3DScene
+ for( auto& aIter : sax_fastparser::castToFastAttributeList(xAttrList) )
+ {
+ switch(aIter.getToken())
+ {
+ case XML_ELEMENT(SVG, XML_X):
+ case XML_ELEMENT(SVG_COMPAT, XML_X):
+ GetImport().GetMM100UnitConverter().convertMeasureToCore(
+ aGluePoint.Position.X, aIter.toView());
+ break;
+ case XML_ELEMENT(SVG, XML_Y):
+ case XML_ELEMENT(SVG_COMPAT, XML_Y):
+ GetImport().GetMM100UnitConverter().convertMeasureToCore(
+ aGluePoint.Position.Y, aIter.toView());
+ break;
+ case XML_ELEMENT(DRAW, XML_ID):
+ nId = aIter.toInt32();
+ break;
+ case XML_ELEMENT(DRAW, XML_ALIGN):
+ {
+ drawing::Alignment eKind;
+ if( SvXMLUnitConverter::convertEnum( eKind, aIter.toView(), aXML_GlueAlignment_EnumMap ) )
+ {
+ aGluePoint.PositionAlignment = eKind;
+ aGluePoint.IsRelative = false;
+ }
+ break;
+ }
+ case XML_ELEMENT(DRAW, XML_ESCAPE_DIRECTION):
+ {
+ SvXMLUnitConverter::convertEnum( aGluePoint.Escape, aIter.toView(), aXML_GlueEscapeDirection_EnumMap );
+ break;
+ }
+ default:
+ XMLOFF_WARN_UNKNOWN("xmloff", aIter);
+ }
+ }
+
+ if( nId != -1 )
+ {
+ try
+ {
+ sal_Int32 nInternalId = mxGluePoints->insert( uno::Any( aGluePoint ) );
+ GetImport().GetShapeImport()->addGluePointMapping( mxShape, nId, nInternalId );
+ }
+ catch(const uno::Exception&)
+ {
+ DBG_UNHANDLED_EXCEPTION( "xmloff", "during setting of gluepoints");
+ }
+ }
+}
+
+void SdXMLShapeContext::startFastElement (sal_Int32 /*nElement*/,
+ const css::uno::Reference< css::xml::sax::XFastAttributeList >& /*xAttrList*/)
+{
+ GetImport().GetShapeImport()->finishShape( mxShape, mxAttrList, mxShapes );
+}
+
+void SdXMLShapeContext::endFastElement(sal_Int32 )
+{
+ if(mxCursor.is())
+ {
+ // tdf#72776 force UpdateData in the EditSource so we will not override text in SdrOutliner
+ if( mxLockable.is() )
+ {
+ mxLockable->removeActionLock();
+ mxLockable->addActionLock();
+ }
+
+ // delete addition newline
+ mxCursor->gotoEnd( false );
+ mxCursor->goLeft( 1, true );
+ mxCursor->setString( "" );
+
+ // reset cursor
+ GetImport().GetTextImport()->ResetCursor();
+ }
+
+ if(mxOldCursor.is())
+ GetImport().GetTextImport()->SetCursor( mxOldCursor );
+
+ // reinstall old list item (if necessary) #91964#
+ if (mbListContextPushed) {
+ GetImport().GetTextImport()->PopListContext();
+ }
+
+ if( !msHyperlink.isEmpty() ) try
+ {
+ uno::Reference< beans::XPropertySet > xProp( mxShape, uno::UNO_QUERY );
+
+ if ( xProp.is() && xProp->getPropertySetInfo()->hasPropertyByName( "Hyperlink" ) )
+ xProp->setPropertyValue( "Hyperlink", uno::Any( msHyperlink ) );
+ Reference< XEventsSupplier > xEventsSupplier( mxShape, UNO_QUERY );
+
+ if( xEventsSupplier.is() )
+ {
+ Reference< XNameReplace > xEvents( xEventsSupplier->getEvents(), UNO_SET_THROW );
+
+ uno::Sequence< beans::PropertyValue > aProperties{
+ { /* Name */ "EventType",
+ /* Handle */ -1,
+ /* Value */ uno::Any(OUString( "Presentation" )),
+ /* State */ beans::PropertyState_DIRECT_VALUE },
+
+ { /* Name */ "ClickAction",
+ /* Handle */ -1,
+ /* Value */ uno::Any(css::presentation::ClickAction_DOCUMENT),
+ /* State */ beans::PropertyState_DIRECT_VALUE },
+
+ { /* Name */ "Bookmark",
+ /* Handle */ -1,
+ /* Value */ uno::Any(msHyperlink),
+ /* State */ beans::PropertyState_DIRECT_VALUE }
+ };
+
+ xEvents->replaceByName( "OnClick", Any( aProperties ) );
+ }
+ else
+ {
+ // in draw use the Bookmark property
+ Reference< beans::XPropertySet > xSet( mxShape, UNO_QUERY_THROW );
+ xSet->setPropertyValue( "Bookmark", Any( msHyperlink ) );
+ xSet->setPropertyValue("OnClick", Any( css::presentation::ClickAction_DOCUMENT ) );
+ }
+ }
+ catch(const Exception&)
+ {
+ DBG_UNHANDLED_EXCEPTION("xmloff", "while setting hyperlink");
+ }
+
+ if( mxLockable.is() )
+ mxLockable->removeActionLock();
+}
+
+void SdXMLShapeContext::AddShape(uno::Reference< drawing::XShape >& xShape)
+{
+ if(xShape.is())
+ {
+ // set shape local
+ mxShape = xShape;
+
+ if(!maShapeName.isEmpty())
+ {
+ uno::Reference< container::XNamed > xNamed( mxShape, uno::UNO_QUERY );
+ if( xNamed.is() )
+ xNamed->setName( maShapeName );
+ }
+
+ rtl::Reference< XMLShapeImportHelper > xImp( GetImport().GetShapeImport() );
+ xImp->addShape( xShape, mxAttrList, mxShapes );
+
+ if( mbClearDefaultAttributes )
+ {
+ uno::Reference<beans::XMultiPropertyStates> xMultiPropertyStates(xShape, uno::UNO_QUERY );
+ if (xMultiPropertyStates.is())
+ xMultiPropertyStates->setAllPropertiesToDefault();
+ }
+
+ if( !mbVisible || !mbPrintable ) try
+ {
+ uno::Reference< beans::XPropertySet > xSet( xShape, uno::UNO_QUERY_THROW );
+ if( !mbVisible )
+ xSet->setPropertyValue("Visible", uno::Any( false ) );
+
+ if( !mbPrintable )
+ xSet->setPropertyValue("Printable", uno::Any( false ) );
+ }
+ catch(const Exception&)
+ {
+ DBG_UNHANDLED_EXCEPTION( "xmloff", "while setting visible or printable" );
+ }
+
+ if(!mbTemporaryShape && (!GetImport().HasTextImport()
+ || !GetImport().GetTextImport()->IsInsideDeleteContext()))
+ {
+ xImp->shapeWithZIndexAdded( xShape, mnZOrder );
+ }
+
+ if (mnRelWidth || mnRelHeight)
+ {
+ uno::Reference<beans::XPropertySet> xPropertySet(xShape, uno::UNO_QUERY);
+ uno::Reference<beans::XPropertySetInfo> xPropertySetInfo = xPropertySet->getPropertySetInfo();
+ if (mnRelWidth && xPropertySetInfo->hasPropertyByName("RelativeWidth"))
+ xPropertySet->setPropertyValue("RelativeWidth", uno::Any(mnRelWidth));
+ if (mnRelHeight && xPropertySetInfo->hasPropertyByName("RelativeHeight"))
+ xPropertySet->setPropertyValue("RelativeHeight", uno::Any(mnRelHeight));
+ }
+
+ if( !maShapeId.isEmpty() )
+ {
+ uno::Reference< uno::XInterface > xRef( static_cast<uno::XInterface *>(xShape.get()) );
+ GetImport().getInterfaceToIdentifierMapper().registerReference( maShapeId, xRef );
+ }
+
+ // #91065# count only if counting for shape import is enabled
+ if(GetImport().GetShapeImport()->IsHandleProgressBarEnabled())
+ {
+ // #80365# increment progress bar at load once for each draw object
+ GetImport().GetProgressBarHelper()->Increment();
+ }
+ }
+
+ mxLockable.set( xShape, UNO_QUERY );
+
+ if( mxLockable.is() )
+ mxLockable->addActionLock();
+
+}
+
+void SdXMLShapeContext::AddShape(OUString const & serviceName)
+{
+ uno::Reference< lang::XMultiServiceFactory > xServiceFact(GetImport().GetModel(), uno::UNO_QUERY);
+ if(!xServiceFact.is())
+ return;
+
+ try
+ {
+ /* Since fix for issue i33294 the Writer model doesn't support
+ com.sun.star.drawing.OLE2Shape anymore.
+ To handle Draw OLE objects it's decided to import these
+ objects as com.sun.star.drawing.OLE2Shape and convert these
+ objects after the import into com.sun.star.drawing.GraphicObjectShape.
+ */
+ uno::Reference< drawing::XShape > xShape;
+ if ( serviceName == "com.sun.star.drawing.OLE2Shape" &&
+ uno::Reference< text::XTextDocument >(GetImport().GetModel(), uno::UNO_QUERY).is() )
+ {
+ xShape.set(xServiceFact->createInstance("com.sun.star.drawing.temporaryForXMLImportOLE2Shape"), uno::UNO_QUERY);
+ }
+ else if (serviceName == "com.sun.star.drawing.GraphicObjectShape"
+ || serviceName == "com.sun.star.drawing.AppletShape"
+ || serviceName == "com.sun.star.drawing.FrameShape"
+ || serviceName == "com.sun.star.drawing.MediaShape"
+ || serviceName == "com.sun.star.drawing.OLE2Shape"
+ || serviceName == "com.sun.star.drawing.PluginShape"
+ || serviceName == "com.sun.star.presentation.MediaShape")
+ {
+ // On adding another entry to this list of service names to pass an argument via the WithArguments variant
+ // you may need to adjust the more obscure OReportDefinition::createInstanceWithArguments as well as the
+ // more obvious SvxUnoDrawMSFactory::createInstanceWithArguments
+ xShape.set( xServiceFact->createInstanceWithArguments(serviceName, { css::uno::Any(GetImport().GetDocumentBase()) }),
+ css::uno::UNO_QUERY);
+ }
+ else
+ {
+ xShape.set(xServiceFact->createInstance(serviceName), uno::UNO_QUERY);
+ }
+ if( xShape.is() )
+ AddShape( xShape );
+ }
+ catch(const uno::Exception& e)
+ {
+ TOOLS_WARN_EXCEPTION("xmloff", "AddShape " << serviceName);
+ uno::Sequence<OUString> aSeq { serviceName };
+ GetImport().SetError( XMLERROR_FLAG_ERROR | XMLERROR_API,
+ aSeq, e.Message, nullptr );
+ }
+}
+
+void SdXMLShapeContext::SetTransformation()
+{
+ if(!mxShape.is())
+ return;
+
+ uno::Reference< beans::XPropertySet > xPropSet(mxShape, uno::UNO_QUERY);
+ if(!xPropSet.is())
+ return;
+
+ maUsedTransformation.identity();
+
+ if(maSize.Width != 1 || maSize.Height != 1)
+ {
+ // take care there are no zeros used by error
+ if(0 == maSize.Width)
+ maSize.Width = 1;
+ if(0 == maSize.Height)
+ maSize.Height = 1;
+
+ // set global size. This should always be used.
+ maUsedTransformation.scale(maSize.Width, maSize.Height);
+ }
+
+ if(maPosition.X != 0 || maPosition.Y != 0)
+ {
+ // if global position is used, add it to transformation
+ maUsedTransformation.translate(maPosition.X, maPosition.Y);
+ }
+
+ if(mnTransform.NeedsAction())
+ {
+ // transformation is used, apply to object.
+ // NOTICE: The transformation is applied AFTER evtl. used
+ // global positioning and scaling is used, so any shear or
+ // rotate used herein is applied around the (0,0) position
+ // of the PAGE object !!!
+ ::basegfx::B2DHomMatrix aMat;
+ mnTransform.GetFullTransform(aMat);
+
+ // now add to transformation
+ maUsedTransformation *= aMat;
+ }
+
+ // now set transformation for this object
+
+ // maUsedTransformtion contains the mathematical correct matrix, which if
+ // applied to a unit square would generate the transformed shape. But the property
+ // "Transformation" contains a matrix, which can be used in TRSetBaseGeometry
+ // and would be created by TRGetBaseGeometry. And those use a mathematically wrong
+ // sign for the shearing angle. So we need to adapt the matrix here.
+ basegfx::B2DTuple aScale;
+ basegfx::B2DTuple aTranslate;
+ double fRotate;
+ double fShearX;
+ maUsedTransformation.decompose(aScale, aTranslate, fRotate, fShearX);
+ basegfx::B2DHomMatrix aB2DHomMatrix;
+ aB2DHomMatrix = basegfx::utils::createScaleShearXRotateTranslateB2DHomMatrix(
+ aScale,
+ basegfx::fTools::equalZero(fShearX) ? 0.0 : -fShearX,
+ basegfx::fTools::equalZero(fRotate) ? 0.0 : fRotate,
+ aTranslate);
+ drawing::HomogenMatrix3 aUnoMatrix;
+
+ aUnoMatrix.Line1.Column1 = aB2DHomMatrix.get(0, 0);
+ aUnoMatrix.Line1.Column2 = aB2DHomMatrix.get(0, 1);
+ aUnoMatrix.Line1.Column3 = aB2DHomMatrix.get(0, 2);
+
+ aUnoMatrix.Line2.Column1 = aB2DHomMatrix.get(1, 0);
+ aUnoMatrix.Line2.Column2 = aB2DHomMatrix.get(1, 1);
+ aUnoMatrix.Line2.Column3 = aB2DHomMatrix.get(1, 2);
+
+ aUnoMatrix.Line3.Column1 = 0;
+ aUnoMatrix.Line3.Column2 = 0;
+ aUnoMatrix.Line3.Column3 = 1;
+
+ xPropSet->setPropertyValue("Transformation", Any(aUnoMatrix));
+}
+
+void SdXMLShapeContext::SetStyle( bool bSupportsStyle /* = true */)
+{
+ try
+ {
+ uno::Reference< beans::XPropertySet > xPropSet(mxShape, uno::UNO_QUERY);
+ if( !xPropSet.is() )
+ return;
+
+ do
+ {
+ // set style on shape
+ if(maDrawStyleName.isEmpty())
+ break;
+
+ const SvXMLStyleContext* pStyle = nullptr;
+ bool bAutoStyle(false);
+
+ if(GetImport().GetShapeImport()->GetAutoStylesContext())
+ pStyle = GetImport().GetShapeImport()->GetAutoStylesContext()->FindStyleChildContext(mnStyleFamily, maDrawStyleName);
+
+ if(pStyle)
+ bAutoStyle = true;
+
+ if(!pStyle && GetImport().GetShapeImport()->GetStylesContext())
+ pStyle = GetImport().GetShapeImport()->GetStylesContext()->FindStyleChildContext(mnStyleFamily, maDrawStyleName);
+
+ OUString aStyleName = maDrawStyleName;
+ uno::Reference< style::XStyle > xStyle;
+
+ XMLPropStyleContext* pDocStyle
+ = dynamic_cast<XMLShapeStyleContext*>(const_cast<SvXMLStyleContext*>(pStyle));
+ if (pDocStyle)
+ {
+ if( pDocStyle->GetStyle().is() )
+ {
+ xStyle = pDocStyle->GetStyle();
+ }
+ else
+ {
+ aStyleName = pDocStyle->GetParentName();
+ }
+ }
+
+ if( !xStyle.is() && !aStyleName.isEmpty() )
+ {
+ try
+ {
+
+ uno::Reference< style::XStyleFamiliesSupplier > xFamiliesSupplier( GetImport().GetModel(), uno::UNO_QUERY );
+
+ if( xFamiliesSupplier.is() )
+ {
+ uno::Reference< container::XNameAccess > xFamilies( xFamiliesSupplier->getStyleFamilies() );
+ if( xFamilies.is() )
+ {
+
+ uno::Reference< container::XNameAccess > xFamily;
+
+ if( XmlStyleFamily::SD_PRESENTATION_ID == mnStyleFamily )
+ {
+ aStyleName = GetImport().GetStyleDisplayName(
+ XmlStyleFamily::SD_PRESENTATION_ID,
+ aStyleName );
+ sal_Int32 nPos = aStyleName.lastIndexOf( '-' );
+ if( -1 != nPos )
+ {
+ OUString aFamily( aStyleName.copy( 0, nPos ) );
+
+ xFamilies->getByName( aFamily ) >>= xFamily;
+ aStyleName = aStyleName.copy( nPos + 1 );
+ }
+ }
+ else
+ {
+ // get graphics family
+ if (xFamilies->hasByName("graphics"))
+ xFamilies->getByName("graphics") >>= xFamily;
+ else
+ xFamilies->getByName("GraphicStyles") >>= xFamily;
+
+ aStyleName = GetImport().GetStyleDisplayName(
+ XmlStyleFamily::SD_GRAPHICS_ID,
+ aStyleName );
+ }
+
+ if( xFamily.is() )
+ xFamily->getByName( aStyleName ) >>= xStyle;
+ }
+ }
+ }
+ catch(const uno::Exception&)
+ {
+ DBG_UNHANDLED_EXCEPTION( "xmloff", "finding style for shape" );
+ }
+ }
+
+ if( bSupportsStyle && xStyle.is() )
+ {
+ try
+ {
+ // set style on object
+ xPropSet->setPropertyValue("Style", Any(xStyle));
+ }
+ catch(const uno::Exception&)
+ {
+ DBG_UNHANDLED_EXCEPTION( "xmloff", "setting style for shape" );
+ }
+ }
+
+ // Writer shapes: if this one has a TextBox, set it here. We need to do it before
+ // pDocStyle->FillPropertySet, because setting some properties depend on the format
+ // having RES_CNTNT attribute (e.g., UNO_NAME_TEXT_(LEFT|RIGHT|UPPER|LOWER)DIST; see
+ // SwTextBoxHelper::syncProperty, which indirectly calls SwTextBoxHelper::isTextBox)
+ uno::Reference<beans::XPropertySetInfo> xPropertySetInfo
+ = xPropSet->getPropertySetInfo();
+ static constexpr OUString sTextBox = u"TextBox"_ustr;
+ if (xPropertySetInfo->hasPropertyByName(sTextBox))
+ xPropSet->setPropertyValue(sTextBox, uno::Any(mbTextBox));
+
+ // if this is an auto style, set its properties
+ if(bAutoStyle && pDocStyle)
+ {
+ // set PropertySet on object
+ pDocStyle->FillPropertySet(xPropSet);
+ }
+
+ } while(false);
+
+ // try to set text auto style
+ do
+ {
+ // set style on shape
+ if( maTextStyleName.isEmpty() )
+ break;
+
+ if( nullptr == GetImport().GetShapeImport()->GetAutoStylesContext())
+ break;
+
+ const SvXMLStyleContext* pTempStyle = GetImport().GetShapeImport()->GetAutoStylesContext()->FindStyleChildContext(XmlStyleFamily::TEXT_PARAGRAPH, maTextStyleName);
+ XMLPropStyleContext* pStyle = const_cast<XMLPropStyleContext*>(dynamic_cast<const XMLPropStyleContext*>( pTempStyle ) ); // use temp var, PTR_CAST is a bad macro, FindStyleChildContext will be called twice
+ if( pStyle == nullptr )
+ break;
+
+ // set PropertySet on object
+ pStyle->FillPropertySet(xPropSet);
+
+ } while(false);
+ }
+ catch(const uno::Exception&)
+ {
+ }
+}
+
+void SdXMLShapeContext::SetLayer()
+{
+ if( maLayerName.isEmpty() )
+ return;
+
+ try
+ {
+ uno::Reference< beans::XPropertySet > xPropSet(mxShape, uno::UNO_QUERY);
+ if(xPropSet.is() )
+ {
+ xPropSet->setPropertyValue("LayerName", Any(maLayerName));
+ return;
+ }
+ }
+ catch(const uno::Exception&)
+ {
+ }
+}
+
+void SdXMLShapeContext::SetThumbnail()
+{
+ if( maThumbnailURL.isEmpty() )
+ return;
+
+ try
+ {
+ uno::Reference< beans::XPropertySet > xPropSet(mxShape, uno::UNO_QUERY);
+ if( !xPropSet.is() )
+ return;
+
+ uno::Reference< beans::XPropertySetInfo > xPropSetInfo( xPropSet->getPropertySetInfo() );
+ if( xPropSetInfo.is() && xPropSetInfo->hasPropertyByName( "ThumbnailGraphic" ) )
+ {
+ // load the thumbnail graphic and export it to a wmf stream so we can set
+ // it at the api
+
+ uno::Reference<graphic::XGraphic> xGraphic = GetImport().loadGraphicByURL(maThumbnailURL);
+ xPropSet->setPropertyValue("ThumbnailGraphic", uno::Any(xGraphic));
+ }
+ }
+ catch(const uno::Exception&)
+ {
+ }
+}
+
+// this is called from the parent group for each unparsed attribute in the attribute list
+bool SdXMLShapeContext::processAttribute( const sax_fastparser::FastAttributeList::FastAttributeIter & aIter )
+{
+ sal_Int32 nTmp;
+ switch (aIter.getToken())
+ {
+ case XML_ELEMENT(DRAW, XML_ZINDEX):
+ case XML_ELEMENT(DRAW_EXT, XML_ZINDEX):
+ mnZOrder = aIter.toInt32();
+ break;
+ case XML_ELEMENT(DRAW, XML_ID):
+ case XML_ELEMENT(DRAW_EXT, XML_ID):
+ if (!mbHaveXmlId) { maShapeId = aIter.toString(); }
+ break;
+ case XML_ELEMENT(DRAW, XML_NAME):
+ case XML_ELEMENT(DRAW_EXT, XML_NAME):
+ maShapeName = aIter.toString();
+ break;
+ case XML_ELEMENT(DRAW, XML_STYLE_NAME):
+ case XML_ELEMENT(DRAW_EXT, XML_STYLE_NAME):
+ maDrawStyleName = aIter.toString();
+ break;
+ case XML_ELEMENT(DRAW, XML_TEXT_STYLE_NAME):
+ case XML_ELEMENT(DRAW_EXT, XML_TEXT_STYLE_NAME):
+ maTextStyleName = aIter.toString();
+ break;
+ case XML_ELEMENT(DRAW, XML_LAYER):
+ case XML_ELEMENT(DRAW_EXT, XML_LAYER):
+ maLayerName = aIter.toString();
+ break;
+ case XML_ELEMENT(DRAW, XML_TRANSFORM):
+ case XML_ELEMENT(DRAW_EXT, XML_TRANSFORM):
+ mnTransform.SetString(aIter.toString(), GetImport().GetMM100UnitConverter());
+ break;
+ case XML_ELEMENT(DRAW, XML_DISPLAY):
+ case XML_ELEMENT(DRAW_EXT, XML_DISPLAY):
+ mbVisible = IsXMLToken( aIter, XML_ALWAYS ) || IsXMLToken( aIter, XML_SCREEN );
+ mbPrintable = IsXMLToken( aIter, XML_ALWAYS ) || IsXMLToken( aIter, XML_PRINTER );
+ break;
+ case XML_ELEMENT(PRESENTATION, XML_USER_TRANSFORMED):
+ mbIsUserTransformed = IsXMLToken( aIter, XML_TRUE );
+ break;
+ case XML_ELEMENT(PRESENTATION, XML_PLACEHOLDER):
+ mbIsPlaceholder = IsXMLToken( aIter, XML_TRUE );
+ if( mbIsPlaceholder )
+ mbClearDefaultAttributes = false;
+ break;
+ case XML_ELEMENT(PRESENTATION, XML_CLASS):
+ maPresentationClass = aIter.toString();
+ break;
+ case XML_ELEMENT(PRESENTATION, XML_STYLE_NAME):
+ maDrawStyleName = aIter.toString();
+ mnStyleFamily = XmlStyleFamily::SD_PRESENTATION_ID;
+ break;
+ case XML_ELEMENT(SVG, XML_X):
+ case XML_ELEMENT(SVG_COMPAT, XML_X):
+ GetImport().GetMM100UnitConverter().convertMeasureToCore(
+ maPosition.X, aIter.toView());
+ break;
+ case XML_ELEMENT(SVG, XML_Y):
+ case XML_ELEMENT(SVG_COMPAT, XML_Y):
+ GetImport().GetMM100UnitConverter().convertMeasureToCore(
+ maPosition.Y, aIter.toView());
+ break;
+ case XML_ELEMENT(SVG, XML_WIDTH):
+ case XML_ELEMENT(SVG_COMPAT, XML_WIDTH):
+ GetImport().GetMM100UnitConverter().convertMeasureToCore(
+ maSize.Width, aIter.toView());
+ if (maSize.Width > 0)
+ maSize.Width = o3tl::saturating_add<sal_Int32>(maSize.Width, 1);
+ else if (maSize.Width < 0)
+ maSize.Width = o3tl::saturating_add<sal_Int32>(maSize.Width, -1);
+ break;
+ case XML_ELEMENT(SVG, XML_HEIGHT):
+ case XML_ELEMENT(SVG_COMPAT, XML_HEIGHT):
+ GetImport().GetMM100UnitConverter().convertMeasureToCore(
+ maSize.Height, aIter.toView());
+ if (maSize.Height > 0)
+ maSize.Height = o3tl::saturating_add<sal_Int32>(maSize.Height, 1);
+ else if (maSize.Height < 0)
+ maSize.Height = o3tl::saturating_add<sal_Int32>(maSize.Height, -1);
+ break;
+ case XML_ELEMENT(SVG, XML_TRANSFORM):
+ case XML_ELEMENT(SVG_COMPAT, XML_TRANSFORM):
+ // because of #85127# take svg:transform into account and handle like
+ // draw:transform for compatibility
+ mnTransform.SetString(aIter.toString(), GetImport().GetMM100UnitConverter());
+ break;
+ case XML_ELEMENT(STYLE, XML_REL_WIDTH):
+ if (sax::Converter::convertPercent(nTmp, aIter.toView()))
+ mnRelWidth = static_cast<sal_Int16>(nTmp);
+ break;
+ case XML_ELEMENT(STYLE, XML_REL_HEIGHT):
+ if (sax::Converter::convertPercent(nTmp, aIter.toView()))
+ mnRelHeight = static_cast<sal_Int16>(nTmp);
+ break;
+ case XML_ELEMENT(NONE, XML_ID):
+ case XML_ELEMENT(XML, XML_ID):
+ maShapeId = aIter.toString();
+ mbHaveXmlId = true;
+ break;
+ default:
+ return false;
+ }
+ return true;
+}
+
+bool SdXMLShapeContext::isPresentationShape() const
+{
+ if( !maPresentationClass.isEmpty() && const_cast<SdXMLShapeContext*>(this)->GetImport().GetShapeImport()->IsPresentationShapesSupported() )
+ {
+ if(XmlStyleFamily::SD_PRESENTATION_ID == mnStyleFamily)
+ {
+ return true;
+ }
+
+ if( IsXMLToken( maPresentationClass, XML_HEADER ) || IsXMLToken( maPresentationClass, XML_FOOTER ) ||
+ IsXMLToken( maPresentationClass, XML_PAGE_NUMBER ) || IsXMLToken( maPresentationClass, XML_DATE_TIME ) )
+ {
+ return true;
+ }
+ }
+
+ return false;
+}
+
+SdXMLRectShapeContext::SdXMLRectShapeContext(
+ SvXMLImport& rImport,
+ const css::uno::Reference< css::xml::sax::XFastAttributeList>& xAttrList,
+ uno::Reference< drawing::XShapes > const & rShapes,
+ bool bTemporaryShape)
+: SdXMLShapeContext( rImport, xAttrList, rShapes, bTemporaryShape ),
+ mnRadius( 0 )
+{
+}
+
+SdXMLRectShapeContext::~SdXMLRectShapeContext()
+{
+}
+
+// this is called from the parent group for each unparsed attribute in the attribute list
+bool SdXMLRectShapeContext::processAttribute( const sax_fastparser::FastAttributeList::FastAttributeIter & aIter )
+{
+ switch (aIter.getToken())
+ {
+ case XML_ELEMENT(DRAW, XML_CORNER_RADIUS):
+ GetImport().GetMM100UnitConverter().convertMeasureToCore(
+ mnRadius, aIter.toView());
+ break;
+ default:
+ return SdXMLShapeContext::processAttribute( aIter );
+ }
+ return true;
+}
+
+void SdXMLRectShapeContext::startFastElement (sal_Int32 nElement,
+ const css::uno::Reference< css::xml::sax::XFastAttributeList >& xAttrList)
+{
+ // create rectangle shape
+ AddShape("com.sun.star.drawing.RectangleShape");
+ if(!mxShape.is())
+ return;
+
+ // Add, set Style and properties from base shape
+ SetStyle();
+ SetLayer();
+
+ // set pos, size, shear and rotate
+ SetTransformation();
+
+ if(mnRadius)
+ {
+ uno::Reference< beans::XPropertySet > xPropSet(mxShape, uno::UNO_QUERY);
+ if(xPropSet.is())
+ {
+ try
+ {
+ xPropSet->setPropertyValue("CornerRadius", uno::Any( mnRadius ) );
+ }
+ catch(const uno::Exception&)
+ {
+ DBG_UNHANDLED_EXCEPTION( "xmloff", "setting corner radius");
+ }
+ }
+ }
+ SdXMLShapeContext::startFastElement(nElement, xAttrList);
+}
+
+
+SdXMLLineShapeContext::SdXMLLineShapeContext(
+ SvXMLImport& rImport,
+ const css::uno::Reference< css::xml::sax::XFastAttributeList>& xAttrList,
+ uno::Reference< drawing::XShapes > const & rShapes,
+ bool bTemporaryShape)
+: SdXMLShapeContext( rImport, xAttrList, rShapes, bTemporaryShape ),
+ mnX1( 0 ),
+ mnY1( 0 ),
+ mnX2( 1 ),
+ mnY2( 1 )
+{
+}
+
+SdXMLLineShapeContext::~SdXMLLineShapeContext()
+{
+}
+
+// this is called from the parent group for each unparsed attribute in the attribute list
+bool SdXMLLineShapeContext::processAttribute( const sax_fastparser::FastAttributeList::FastAttributeIter & aIter )
+{
+ switch (aIter.getToken())
+ {
+ case XML_ELEMENT(SVG, XML_X1):
+ case XML_ELEMENT(SVG_COMPAT, XML_X1):
+ GetImport().GetMM100UnitConverter().convertMeasureToCore(
+ mnX1, aIter.toView());
+ break;
+ case XML_ELEMENT(SVG, XML_Y1):
+ case XML_ELEMENT(SVG_COMPAT, XML_Y1):
+ GetImport().GetMM100UnitConverter().convertMeasureToCore(
+ mnY1, aIter.toView());
+ break;
+ case XML_ELEMENT(SVG, XML_X2):
+ case XML_ELEMENT(SVG_COMPAT, XML_X2):
+ GetImport().GetMM100UnitConverter().convertMeasureToCore(
+ mnX2, aIter.toView());
+ break;
+ case XML_ELEMENT(SVG, XML_Y2):
+ case XML_ELEMENT(SVG_COMPAT, XML_Y2):
+ GetImport().GetMM100UnitConverter().convertMeasureToCore(
+ mnY2, aIter.toView());
+ break;
+ default:
+ return SdXMLShapeContext::processAttribute( aIter );
+ }
+ return true;
+}
+
+void SdXMLLineShapeContext::startFastElement (sal_Int32 nElement,
+ const css::uno::Reference< css::xml::sax::XFastAttributeList >& xAttrList)
+{
+ // #85920# use SetTransformation() to handle import of simple lines.
+ // This is necessary to take into account all anchor positions and
+ // other things. All shape imports use the same import schemata now.
+ // create necessary shape (Line Shape)
+ AddShape("com.sun.star.drawing.PolyLineShape");
+
+ if(!mxShape.is())
+ return;
+
+ // Add, set Style and properties from base shape
+ SetStyle();
+ SetLayer();
+
+ // get sizes and offsets
+ awt::Point aTopLeft(mnX1, mnY1);
+ awt::Point aBottomRight(mnX2, mnY2);
+
+ if(mnX1 > mnX2)
+ {
+ aTopLeft.X = mnX2;
+ aBottomRight.X = mnX1;
+ }
+
+ if(mnY1 > mnY2)
+ {
+ aTopLeft.Y = mnY2;
+ aBottomRight.Y = mnY1;
+ }
+
+ // set local parameters on shape
+ uno::Reference< beans::XPropertySet > xPropSet(mxShape, uno::UNO_QUERY);
+ if(xPropSet.is())
+ {
+ drawing::PointSequenceSequence aPolyPoly(1);
+ drawing::PointSequence* pOuterSequence = aPolyPoly.getArray();
+ pOuterSequence->realloc(2);
+ awt::Point* pInnerSequence = pOuterSequence->getArray();
+
+ *pInnerSequence = awt::Point(o3tl::saturating_sub(mnX1, aTopLeft.X), o3tl::saturating_sub(mnY1, aTopLeft.Y));
+ pInnerSequence++;
+ *pInnerSequence = awt::Point(o3tl::saturating_sub(mnX2, aTopLeft.X), o3tl::saturating_sub(mnY2, aTopLeft.Y));
+
+ xPropSet->setPropertyValue("Geometry", Any(aPolyPoly));
+ }
+
+ // Size is included in point coordinates
+ maSize.Width = 1;
+ maSize.Height = 1;
+ maPosition.X = aTopLeft.X;
+ maPosition.Y = aTopLeft.Y;
+
+ // set pos, size, shear and rotate and get copy of matrix
+ SetTransformation();
+
+ SdXMLShapeContext::startFastElement(nElement, xAttrList);
+}
+
+
+SdXMLEllipseShapeContext::SdXMLEllipseShapeContext(
+ SvXMLImport& rImport,
+ const css::uno::Reference< css::xml::sax::XFastAttributeList>& xAttrList,
+ uno::Reference< drawing::XShapes > const & rShapes,
+ bool bTemporaryShape)
+: SdXMLShapeContext( rImport, xAttrList, rShapes, bTemporaryShape ),
+ mnCX( 0 ),
+ mnCY( 0 ),
+ mnRX( 1 ),
+ mnRY( 1 ),
+ meKind( drawing::CircleKind_FULL ),
+ mnStartAngle( 0 ),
+ mnEndAngle( 0 )
+{
+}
+
+SdXMLEllipseShapeContext::~SdXMLEllipseShapeContext()
+{
+}
+
+// this is called from the parent group for each unparsed attribute in the attribute list
+bool SdXMLEllipseShapeContext::processAttribute( const sax_fastparser::FastAttributeList::FastAttributeIter & aIter )
+{
+ switch (aIter.getToken())
+ {
+ case XML_ELEMENT(SVG, XML_RX):
+ case XML_ELEMENT(SVG_COMPAT, XML_RX):
+ GetImport().GetMM100UnitConverter().convertMeasureToCore(
+ mnRX, aIter.toView());
+ break;
+ case XML_ELEMENT(SVG, XML_RY):
+ case XML_ELEMENT(SVG_COMPAT, XML_RY):
+ GetImport().GetMM100UnitConverter().convertMeasureToCore(
+ mnRY, aIter.toView());
+ break;
+ case XML_ELEMENT(SVG, XML_CX):
+ case XML_ELEMENT(SVG_COMPAT, XML_CX):
+ GetImport().GetMM100UnitConverter().convertMeasureToCore(
+ mnCX, aIter.toView());
+ break;
+ case XML_ELEMENT(SVG, XML_CY):
+ case XML_ELEMENT(SVG_COMPAT, XML_CY):
+ GetImport().GetMM100UnitConverter().convertMeasureToCore(
+ mnCY, aIter.toView());
+ break;
+ case XML_ELEMENT(SVG, XML_R):
+ case XML_ELEMENT(SVG_COMPAT, XML_R):
+ // single radius, it's a circle and both radii are the same
+ GetImport().GetMM100UnitConverter().convertMeasureToCore(
+ mnRX, aIter.toView());
+ mnRY = mnRX;
+ break;
+ case XML_ELEMENT(DRAW, XML_KIND):
+ SvXMLUnitConverter::convertEnum( meKind, aIter.toView(), aXML_CircleKind_EnumMap );
+ break;
+ case XML_ELEMENT(DRAW, XML_START_ANGLE):
+ {
+ double dStartAngle;
+ if (::sax::Converter::convertDouble( dStartAngle, aIter.toView() ))
+ mnStartAngle = static_cast<sal_Int32>(dStartAngle * 100.0);
+ break;
+ }
+ case XML_ELEMENT(DRAW, XML_END_ANGLE):
+ {
+ double dEndAngle;
+ if (::sax::Converter::convertDouble( dEndAngle, aIter.toView() ))
+ mnEndAngle = static_cast<sal_Int32>(dEndAngle * 100.0);
+ break;
+ }
+ default:
+ return SdXMLShapeContext::processAttribute( aIter );
+ }
+ return true;
+}
+
+void SdXMLEllipseShapeContext::startFastElement (sal_Int32 nElement,
+ const css::uno::Reference< css::xml::sax::XFastAttributeList >& xAttrList)
+{
+ // create rectangle shape
+ AddShape("com.sun.star.drawing.EllipseShape");
+ if(!mxShape.is())
+ return;
+
+ // Add, set Style and properties from base shape
+ SetStyle();
+ SetLayer();
+
+ if(mnCX != 0 || mnCY != 0 || mnRX != 1 || mnRY != 1)
+ {
+ // #i121972# center/radius is used, put to pos and size
+ maSize.Width = 2 * mnRX;
+ maSize.Height = 2 * mnRY;
+ maPosition.X = mnCX - mnRX;
+ maPosition.Y = mnCY - mnRY;
+ }
+ // set pos, size, shear and rotate
+ SetTransformation();
+
+ if( meKind != drawing::CircleKind_FULL )
+ {
+ uno::Reference< beans::XPropertySet > xPropSet( mxShape, uno::UNO_QUERY );
+ if( xPropSet.is() )
+ {
+ // calculate the correct start and end angle
+ sal_Int32 mnOldStartAngle = mnStartAngle;
+ sal_Int32 mnOldEndAngle = mnEndAngle;
+ basegfx::B2DTuple aScale;
+ basegfx::B2DTuple aTranslate;
+ double fRotate;
+ double fShearX;
+ maUsedTransformation.decompose(aScale, aTranslate, fRotate, fShearX);
+ if (aScale.getX() < 0 || aScale.getY() < 0)
+ {
+ // The angle for a horizontal flip is the same as the angle for a
+ // vertical flip because a vertical flip is treated as a horizontal
+ // flip plus a rotation.
+
+ // To perform the flip, the start and end angle are switched and we
+ // use the fact performing a horizontal flip on a shape will change
+ // the angle that a radius makes with the origin to 180 degrees
+ // minus that angle (we use 54000 hundredths of a degree to get the
+ // modulus operation to give a value between 0 and 36000).
+
+ mnStartAngle = (54000 - mnOldEndAngle) % 36000;
+ mnEndAngle = (54000 - mnOldStartAngle) % 36000;
+ }
+
+ xPropSet->setPropertyValue("CircleKind", Any( meKind) );
+ xPropSet->setPropertyValue("CircleStartAngle", Any(mnStartAngle) );
+ xPropSet->setPropertyValue("CircleEndAngle", Any(mnEndAngle) );
+ }
+ }
+
+ SdXMLShapeContext::startFastElement(nElement, xAttrList);
+}
+
+
+SdXMLPolygonShapeContext::SdXMLPolygonShapeContext(
+ SvXMLImport& rImport,
+ const css::uno::Reference< css::xml::sax::XFastAttributeList>& xAttrList,
+ uno::Reference< drawing::XShapes > const & rShapes, bool bClosed, bool bTemporaryShape)
+: SdXMLShapeContext( rImport, xAttrList, rShapes, bTemporaryShape ),
+ mbClosed( bClosed )
+{
+}
+
+// this is called from the parent group for each unparsed attribute in the attribute list
+bool SdXMLPolygonShapeContext::processAttribute( const sax_fastparser::FastAttributeList::FastAttributeIter & aIter )
+{
+ switch (aIter.getToken())
+ {
+ case XML_ELEMENT(SVG, XML_VIEWBOX):
+ case XML_ELEMENT(SVG_COMPAT, XML_VIEWBOX):
+ maViewBox = aIter.toString();
+ break;
+ case XML_ELEMENT(DRAW, XML_POINTS):
+ maPoints = aIter.toString();
+ break;
+ default:
+ return SdXMLShapeContext::processAttribute( aIter);
+ }
+ return true;
+}
+
+SdXMLPolygonShapeContext::~SdXMLPolygonShapeContext()
+{
+}
+
+void SdXMLPolygonShapeContext::startFastElement (sal_Int32 nElement,
+ const css::uno::Reference< css::xml::sax::XFastAttributeList >& xAttrList)
+{
+ // Add, set Style and properties from base shape
+ if(mbClosed)
+ AddShape("com.sun.star.drawing.PolyPolygonShape");
+ else
+ AddShape("com.sun.star.drawing.PolyLineShape");
+
+ if( !mxShape.is() )
+ return;
+
+ SetStyle();
+ SetLayer();
+
+ // set local parameters on shape
+ uno::Reference< beans::XPropertySet > xPropSet(mxShape, uno::UNO_QUERY);
+ if(xPropSet.is())
+ {
+ // set polygon
+ if(!maPoints.isEmpty() && !maViewBox.isEmpty())
+ {
+ const SdXMLImExViewBox aViewBox(maViewBox, GetImport().GetMM100UnitConverter());
+ basegfx::B2DVector aSize(aViewBox.GetWidth(), aViewBox.GetHeight());
+
+ // Is this correct? It overrides ViewBox stuff; OTOH it makes no
+ // sense to have the geometry content size different from object size
+ if(maSize.Width != 0 && maSize.Height != 0)
+ {
+ aSize = basegfx::B2DVector(maSize.Width, maSize.Height);
+ }
+
+ basegfx::B2DPolygon aPolygon;
+
+ if(basegfx::utils::importFromSvgPoints(aPolygon, maPoints))
+ {
+ if(aPolygon.count())
+ {
+ const basegfx::B2DRange aSourceRange(
+ aViewBox.GetX(), aViewBox.GetY(),
+ aViewBox.GetX() + aViewBox.GetWidth(), aViewBox.GetY() + aViewBox.GetHeight());
+ const basegfx::B2DRange aTargetRange(
+ aViewBox.GetX(), aViewBox.GetY(),
+ aViewBox.GetX() + aSize.getX(), aViewBox.GetY() + aSize.getY());
+
+ if(!aSourceRange.equal(aTargetRange))
+ {
+ aPolygon.transform(
+ basegfx::utils::createSourceRangeTargetRangeTransform(
+ aSourceRange,
+ aTargetRange));
+ }
+
+ css::drawing::PointSequenceSequence aPointSequenceSequence;
+ basegfx::utils::B2DPolyPolygonToUnoPointSequenceSequence(basegfx::B2DPolyPolygon(aPolygon), aPointSequenceSequence);
+ xPropSet->setPropertyValue("Geometry", Any(aPointSequenceSequence));
+ // Size is now contained in the point coordinates, adapt maSize for
+ // to use the correct transformation matrix in SetTransformation()
+ maSize.Width = 1;
+ maSize.Height = 1;
+ }
+ }
+ }
+ }
+
+ // set pos, size, shear and rotate and get copy of matrix
+ SetTransformation();
+
+ SdXMLShapeContext::startFastElement(nElement, xAttrList);
+}
+
+
+SdXMLPathShapeContext::SdXMLPathShapeContext(
+ SvXMLImport& rImport,
+ const css::uno::Reference< css::xml::sax::XFastAttributeList>& xAttrList,
+ uno::Reference< drawing::XShapes > const & rShapes,
+ bool bTemporaryShape)
+: SdXMLShapeContext( rImport, xAttrList, rShapes, bTemporaryShape )
+{
+}
+
+SdXMLPathShapeContext::~SdXMLPathShapeContext()
+{
+}
+
+// this is called from the parent group for each unparsed attribute in the attribute list
+bool SdXMLPathShapeContext::processAttribute( const sax_fastparser::FastAttributeList::FastAttributeIter & aIter )
+{
+ switch (aIter.getToken())
+ {
+ case XML_ELEMENT(SVG, XML_VIEWBOX):
+ case XML_ELEMENT(SVG_COMPAT, XML_VIEWBOX):
+ maViewBox = aIter.toString();
+ break;
+ case XML_ELEMENT(SVG, XML_D):
+ case XML_ELEMENT(SVG_COMPAT, XML_D):
+ maD = aIter.toString();
+ break;
+ default:
+ return SdXMLShapeContext::processAttribute( aIter );
+ }
+ return true;
+}
+
+void SdXMLPathShapeContext::startFastElement (sal_Int32 nElement,
+ const css::uno::Reference< css::xml::sax::XFastAttributeList >& xAttrList)
+{
+ // create polygon shape
+ if(maD.isEmpty())
+ return;
+
+ const SdXMLImExViewBox aViewBox(maViewBox, GetImport().GetMM100UnitConverter());
+ basegfx::B2DVector aSize(aViewBox.GetWidth(), aViewBox.GetHeight());
+
+ // Is this correct? It overrides ViewBox stuff; OTOH it makes no
+ // sense to have the geometry content size different from object size
+ if(maSize.Width != 0 && maSize.Height != 0)
+ {
+ aSize = basegfx::B2DVector(maSize.Width, maSize.Height);
+ }
+
+ basegfx::B2DPolyPolygon aPolyPolygon;
+
+ if(!basegfx::utils::importFromSvgD(aPolyPolygon, maD, GetImport().needFixPositionAfterZ(), nullptr))
+ return;
+
+ if(!aPolyPolygon.count())
+ return;
+
+ const basegfx::B2DRange aSourceRange(
+ aViewBox.GetX(), aViewBox.GetY(),
+ aViewBox.GetX() + aViewBox.GetWidth(), aViewBox.GetY() + aViewBox.GetHeight());
+ const basegfx::B2DRange aTargetRange(
+ aViewBox.GetX(), aViewBox.GetY(),
+ aViewBox.GetX() + aSize.getX(), aViewBox.GetY() + aSize.getY());
+
+ if(!aSourceRange.equal(aTargetRange))
+ {
+ aPolyPolygon.transform(
+ basegfx::utils::createSourceRangeTargetRangeTransform(
+ aSourceRange,
+ aTargetRange));
+ }
+
+ // create shape
+ OUString service;
+
+ if(aPolyPolygon.areControlPointsUsed())
+ {
+ if(aPolyPolygon.isClosed())
+ {
+ service = "com.sun.star.drawing.ClosedBezierShape";
+ }
+ else
+ {
+ service = "com.sun.star.drawing.OpenBezierShape";
+ }
+ }
+ else
+ {
+ if(aPolyPolygon.isClosed())
+ {
+ service = "com.sun.star.drawing.PolyPolygonShape";
+ }
+ else
+ {
+ service = "com.sun.star.drawing.PolyLineShape";
+ }
+ }
+
+ // Add, set Style and properties from base shape
+ AddShape(service);
+
+ // #89344# test for mxShape.is() and not for mxShapes.is() to support
+ // shape import helper classes WITHOUT XShapes (member mxShapes). This
+ // is used by the writer.
+ if( !mxShape.is() )
+ return;
+
+ SetStyle();
+ SetLayer();
+
+ // set local parameters on shape
+ uno::Reference< beans::XPropertySet > xPropSet(mxShape, uno::UNO_QUERY);
+
+ if(xPropSet.is())
+ {
+ uno::Any aAny;
+
+ // set polygon data
+ if(aPolyPolygon.areControlPointsUsed())
+ {
+ drawing::PolyPolygonBezierCoords aSourcePolyPolygon;
+
+ basegfx::utils::B2DPolyPolygonToUnoPolyPolygonBezierCoords(
+ aPolyPolygon,
+ aSourcePolyPolygon);
+ aAny <<= aSourcePolyPolygon;
+ }
+ else
+ {
+ drawing::PointSequenceSequence aSourcePolyPolygon;
+
+ basegfx::utils::B2DPolyPolygonToUnoPointSequenceSequence(
+ aPolyPolygon,
+ aSourcePolyPolygon);
+ aAny <<= aSourcePolyPolygon;
+ }
+
+ xPropSet->setPropertyValue("Geometry", aAny);
+ // Size is now contained in the point coordinates, adapt maSize for
+ // to use the correct transformation matrix in SetTransformation()
+ maSize.Width = 1;
+ maSize.Height = 1;
+ }
+
+ // set pos, size, shear and rotate
+ SetTransformation();
+
+ SdXMLShapeContext::startFastElement(nElement, xAttrList);
+}
+
+
+SdXMLTextBoxShapeContext::SdXMLTextBoxShapeContext(
+ SvXMLImport& rImport,
+ const css::uno::Reference< css::xml::sax::XFastAttributeList>& xAttrList,
+ uno::Reference< drawing::XShapes > const & rShapes)
+: SdXMLShapeContext( rImport, xAttrList, rShapes, false/*bTemporaryShape*/ ),
+ mnRadius(0),
+ maChainNextName("")
+{
+}
+
+SdXMLTextBoxShapeContext::~SdXMLTextBoxShapeContext()
+{
+}
+
+// this is called from the parent group for each unparsed attribute in the attribute list
+bool SdXMLTextBoxShapeContext::processAttribute( const sax_fastparser::FastAttributeList::FastAttributeIter & aIter )
+{
+ switch (aIter.getToken())
+ {
+ case XML_ELEMENT(DRAW, XML_CORNER_RADIUS):
+ GetImport().GetMM100UnitConverter().convertMeasureToCore(
+ mnRadius, aIter.toView());
+ break;
+ case XML_ELEMENT(DRAW, XML_CHAIN_NEXT_NAME):
+ maChainNextName = aIter.toString();
+ break;
+ default:
+ return SdXMLShapeContext::processAttribute( aIter );
+ }
+ return true;
+}
+
+void SdXMLTextBoxShapeContext::startFastElement (sal_Int32 nElement,
+ const css::uno::Reference< css::xml::sax::XFastAttributeList >& xAttrList)
+{
+ // create textbox shape
+ bool bIsPresShape = false;
+ bool bClearText = false;
+
+ OUString service;
+
+ if( isPresentationShape() )
+ {
+ // check if the current document supports presentation shapes
+ if( GetImport().GetShapeImport()->IsPresentationShapesSupported() )
+ {
+ if( IsXMLToken( maPresentationClass, XML_SUBTITLE ))
+ {
+ // XmlShapeType::PresSubtitleShape
+ service = "com.sun.star.presentation.SubtitleShape";
+ }
+ else if( IsXMLToken( maPresentationClass, XML_PRESENTATION_OUTLINE ) )
+ {
+ // XmlShapeType::PresOutlinerShape
+ service = "com.sun.star.presentation.OutlinerShape";
+ }
+ else if( IsXMLToken( maPresentationClass, XML_NOTES ) )
+ {
+ // XmlShapeType::PresNotesShape
+ service = "com.sun.star.presentation.NotesShape";
+ }
+ else if( IsXMLToken( maPresentationClass, XML_HEADER ) )
+ {
+ // XmlShapeType::PresHeaderShape
+ service = "com.sun.star.presentation.HeaderShape";
+ bClearText = true;
+ }
+ else if( IsXMLToken( maPresentationClass, XML_FOOTER ) )
+ {
+ // XmlShapeType::PresFooterShape
+ service = "com.sun.star.presentation.FooterShape";
+ bClearText = true;
+ }
+ else if( IsXMLToken( maPresentationClass, XML_PAGE_NUMBER ) )
+ {
+ // XmlShapeType::PresSlideNumberShape
+ service = "com.sun.star.presentation.SlideNumberShape";
+ bClearText = true;
+ }
+ else if( IsXMLToken( maPresentationClass, XML_DATE_TIME ) )
+ {
+ // XmlShapeType::PresDateTimeShape
+ service = "com.sun.star.presentation.DateTimeShape";
+ bClearText = true;
+ }
+ else // IsXMLToken( maPresentationClass, XML_TITLE ) )
+ {
+ // XmlShapeType::PresTitleTextShape
+ service = "com.sun.star.presentation.TitleTextShape";
+ }
+ bIsPresShape = true;
+ }
+ }
+
+ if( service.isEmpty() )
+ {
+ // normal text shape
+ service = "com.sun.star.drawing.TextShape";
+ }
+
+ // Add, set Style and properties from base shape
+ AddShape(service);
+
+ if( !mxShape.is() )
+ return;
+
+ SetStyle();
+ SetLayer();
+
+ if(bIsPresShape)
+ {
+ uno::Reference< beans::XPropertySet > xProps(mxShape, uno::UNO_QUERY);
+ if(xProps.is())
+ {
+ uno::Reference< beans::XPropertySetInfo > xPropsInfo( xProps->getPropertySetInfo() );
+ if( xPropsInfo.is() )
+ {
+ if( !mbIsPlaceholder && xPropsInfo->hasPropertyByName("IsEmptyPresentationObject"))
+ xProps->setPropertyValue("IsEmptyPresentationObject", css::uno::Any(false) );
+
+ if( mbIsUserTransformed && xPropsInfo->hasPropertyByName("IsPlaceholderDependent"))
+ xProps->setPropertyValue("IsPlaceholderDependent", css::uno::Any(false) );
+ }
+ }
+ }
+
+ if( bClearText )
+ {
+ uno::Reference< text::XText > xText( mxShape, uno::UNO_QUERY );
+ xText->setString( "" );
+ }
+
+ // set parameters on shape
+//A AW->CL: Eventually You need to strip scale and translate from the transformation
+//A to reach the same goal again.
+//A if(!bIsPresShape || mbIsUserTransformed)
+//A {
+//A // set pos and size on shape, this should remove binding
+//A // to presentation object on masterpage
+//A SetSizeAndPosition();
+//A }
+
+ // set pos, size, shear and rotate
+ SetTransformation();
+
+ if(mnRadius)
+ {
+ uno::Reference< beans::XPropertySet > xPropSet(mxShape, uno::UNO_QUERY);
+ if(xPropSet.is())
+ {
+ try
+ {
+ xPropSet->setPropertyValue("CornerRadius", uno::Any( mnRadius ) );
+ }
+ catch(const uno::Exception&)
+ {
+ DBG_UNHANDLED_EXCEPTION( "xmloff", "setting corner radius");
+ }
+ }
+ }
+
+ if(!maChainNextName.isEmpty())
+ {
+ uno::Reference< beans::XPropertySet > xPropSet(mxShape, uno::UNO_QUERY);
+ if(xPropSet.is())
+ {
+ try
+ {
+ xPropSet->setPropertyValue("TextChainNextName",
+ uno::Any( maChainNextName ) );
+ }
+ catch(const uno::Exception&)
+ {
+ DBG_UNHANDLED_EXCEPTION( "xmloff", "setting name of next chain link");
+ }
+ }
+ }
+
+ SdXMLShapeContext::startFastElement(nElement, xAttrList);
+}
+
+
+SdXMLControlShapeContext::SdXMLControlShapeContext(
+ SvXMLImport& rImport,
+ const css::uno::Reference< css::xml::sax::XFastAttributeList>& xAttrList,
+ uno::Reference< drawing::XShapes > const & rShapes,
+ bool bTemporaryShape)
+: SdXMLShapeContext( rImport, xAttrList, rShapes, bTemporaryShape )
+{
+}
+
+SdXMLControlShapeContext::~SdXMLControlShapeContext()
+{
+}
+
+// this is called from the parent group for each unparsed attribute in the attribute list
+bool SdXMLControlShapeContext::processAttribute( const sax_fastparser::FastAttributeList::FastAttributeIter & aIter )
+{
+ switch (aIter.getToken())
+ {
+ case XML_ELEMENT(DRAW, XML_CONTROL):
+ maFormId = aIter.toString();
+ break;
+ default:
+ return SdXMLShapeContext::processAttribute( aIter );
+ }
+ return true;
+}
+
+void SdXMLControlShapeContext::startFastElement (sal_Int32 nElement,
+ const css::uno::Reference< css::xml::sax::XFastAttributeList >& xAttrList)
+{
+ // create Control shape
+ // add, set style and properties from base shape
+ AddShape("com.sun.star.drawing.ControlShape");
+ if( !mxShape.is() )
+ return;
+
+ SAL_WARN_IF( !!maFormId.isEmpty(), "xmloff", "draw:control without a form:id attribute!" );
+ if( !maFormId.isEmpty() )
+ {
+ if( GetImport().IsFormsSupported() )
+ {
+ uno::Reference< awt::XControlModel > xControlModel( GetImport().GetFormImport()->lookupControl( maFormId ), uno::UNO_QUERY );
+ if( xControlModel.is() )
+ {
+ uno::Reference< drawing::XControlShape > xControl( mxShape, uno::UNO_QUERY );
+ if( xControl.is() )
+ xControl->setControl( xControlModel );
+
+ }
+ }
+ }
+
+ SetStyle();
+ SetLayer();
+
+ // set pos, size, shear and rotate
+ SetTransformation();
+
+ SdXMLShapeContext::startFastElement(nElement, xAttrList);
+}
+
+
+SdXMLConnectorShapeContext::SdXMLConnectorShapeContext(
+ SvXMLImport& rImport,
+ const css::uno::Reference< css::xml::sax::XFastAttributeList>& xAttrList,
+ uno::Reference< drawing::XShapes > const & rShapes,
+ bool bTemporaryShape)
+: SdXMLShapeContext( rImport, xAttrList, rShapes, bTemporaryShape ),
+ maStart(0,0),
+ maEnd(1,1),
+ mnType( drawing::ConnectorType_STANDARD ),
+ mnStartGlueId(-1),
+ mnEndGlueId(-1),
+ mnDelta1(0),
+ mnDelta2(0),
+ mnDelta3(0),
+ mbLikelyOOXMLCurve(true)
+{
+}
+
+SdXMLConnectorShapeContext::~SdXMLConnectorShapeContext()
+{
+}
+
+bool SvXMLImport::needFixPositionAfterZ() const
+{
+ bool bWrongPositionAfterZ( false );
+ sal_Int32 nUPD( 0 );
+ sal_Int32 nBuildId( 0 );
+ if ( getBuildIds( nUPD, nBuildId ) && // test OOo and old versions of LibO and AOO
+ ( ( ( nUPD == 641 ) || ( nUPD == 645 ) || ( nUPD == 680 ) || ( nUPD == 300 ) ||
+ ( nUPD == 310 ) || ( nUPD == 320 ) || ( nUPD == 330 ) || ( nUPD == 340 ) ||
+ ( nUPD == 350 && nBuildId < 202 ) )
+ || (getGeneratorVersion() == SvXMLImport::AOO_40x))) // test if AOO 4.0.x
+ // apparently bug was fixed in AOO by i#123433 f15874d8f976f3874bdbcb53429eeefa65c28841
+ {
+ bWrongPositionAfterZ = true;
+ }
+ return bWrongPositionAfterZ;
+}
+
+namespace
+{
+bool lcl_IsLikelyOOXMLCurve(const basegfx::B2DPolygon& rPolygon)
+{
+ sal_uInt32 nCount = rPolygon.count();
+ if (!rPolygon.areControlPointsUsed() or nCount < 2)
+ return false; // no curve at all
+
+ basegfx::B2DVector aStartVec(rPolygon.getNextControlPoint(0) - rPolygon.getB2DPoint(0));
+ basegfx::B2DVector aEndVec(rPolygon.getPrevControlPoint(nCount-1) - rPolygon.getB2DPoint(nCount - 1));
+ // LibreOffice uses one point less than OOXML for the same underlying bentConnector or
+ // STANDARD connector, respectively. A deeper inspection is only needed in case of 2 resulting
+ // points. Those connector paths look like a quarter ellipse.
+ switch (nCount)
+ {
+ case 2:
+ {
+ // In case start and end direction are parallel, it cannot be OOXML because that case
+ // introduces a handle on the path and the curve has three points then.
+ if (basegfx::areParallel(aStartVec, aEndVec))
+ return false;
+ // OOXML sets the control point at 1/2, LibreOffice at 2/3 of width or height.
+ // A tolerance is used because +-1 deviations due to integer arithmetic in many places.
+ basegfx::B2DRange aRect(rPolygon.getB2DPoint(0), rPolygon.getB2DPoint(1));
+ if ((basegfx::fTools::equalZero(aStartVec.getX())
+ && basegfx::fTools::equal(aStartVec.getLength() * 2.0, aRect.getHeight(), 2.0))
+ || (basegfx::fTools::equalZero(aStartVec.getY())
+ && basegfx::fTools::equal(aStartVec.getLength() * 2.0, aRect.getWidth(), 2.0)))
+ return true;
+ }
+ break;
+ case 3:
+ case 5:
+ return basegfx::areParallel(aStartVec, aEndVec);
+ break;
+ case 4: // start and end direction are orthogonal
+ return basegfx::fTools::equalZero(aStartVec.scalar( aEndVec));
+ break;
+ default:
+ return false;
+ }
+ return false;
+}
+} // end namespace
+
+// this is called from the parent group for each unparsed attribute in the attribute list
+bool SdXMLConnectorShapeContext::processAttribute( const sax_fastparser::FastAttributeList::FastAttributeIter & aIter )
+{
+ switch( aIter.getToken() )
+ {
+ case XML_ELEMENT(DRAW, XML_START_SHAPE):
+ maStartShapeId = aIter.toString();
+ break;
+ case XML_ELEMENT(DRAW, XML_START_GLUE_POINT):
+ mnStartGlueId = aIter.toInt32();
+ break;
+ case XML_ELEMENT(DRAW, XML_END_SHAPE):
+ maEndShapeId = aIter.toString();
+ break;
+ case XML_ELEMENT(DRAW, XML_END_GLUE_POINT):
+ mnEndGlueId = aIter.toInt32();
+ break;
+ case XML_ELEMENT(DRAW, XML_LINE_SKEW):
+ {
+ OUString sValue = aIter.toString();
+ SvXMLTokenEnumerator aTokenEnum( sValue );
+ std::u16string_view aToken;
+ if( aTokenEnum.getNextToken( aToken ) )
+ {
+ GetImport().GetMM100UnitConverter().convertMeasureToCore(
+ mnDelta1, aToken);
+ if( aTokenEnum.getNextToken( aToken ) )
+ {
+ GetImport().GetMM100UnitConverter().convertMeasureToCore(
+ mnDelta2, aToken);
+ if( aTokenEnum.getNextToken( aToken ) )
+ {
+ GetImport().GetMM100UnitConverter().convertMeasureToCore(
+ mnDelta3, aToken);
+ }
+ }
+ }
+ break;
+ }
+ case XML_ELEMENT(DRAW, XML_TYPE):
+ {
+ (void)SvXMLUnitConverter::convertEnum( mnType, aIter.toView(), aXML_ConnectionKind_EnumMap );
+ break;
+ }
+ // #121965# draw:transform may be used in ODF1.2, e.g. exports from MS seem to use these
+ case XML_ELEMENT(DRAW, XML_TRANSFORM):
+ mnTransform.SetString(aIter.toString(), GetImport().GetMM100UnitConverter());
+ break;
+
+ case XML_ELEMENT(SVG, XML_X1):
+ case XML_ELEMENT(SVG_COMPAT, XML_X1):
+ GetImport().GetMM100UnitConverter().convertMeasureToCore(
+ maStart.X, aIter.toView());
+ break;
+ case XML_ELEMENT(SVG, XML_Y1):
+ case XML_ELEMENT(SVG_COMPAT, XML_Y1):
+ GetImport().GetMM100UnitConverter().convertMeasureToCore(
+ maStart.Y, aIter.toView());
+ break;
+ case XML_ELEMENT(SVG, XML_X2):
+ case XML_ELEMENT(SVG_COMPAT, XML_X2):
+ GetImport().GetMM100UnitConverter().convertMeasureToCore(
+ maEnd.X, aIter.toView());
+ break;
+ case XML_ELEMENT(SVG, XML_Y2):
+ case XML_ELEMENT(SVG_COMPAT, XML_Y2):
+ GetImport().GetMM100UnitConverter().convertMeasureToCore(
+ maEnd.Y, aIter.toView());
+ break;
+ case XML_ELEMENT(SVG, XML_D):
+ case XML_ELEMENT(SVG_COMPAT, XML_D):
+ {
+ basegfx::B2DPolyPolygon aPolyPolygon;
+
+ if(basegfx::utils::importFromSvgD(aPolyPolygon, aIter.toString(), GetImport().needFixPositionAfterZ(), nullptr))
+ {
+ if(aPolyPolygon.count())
+ {
+ drawing::PolyPolygonBezierCoords aSourcePolyPolygon;
+
+ basegfx::utils::B2DPolyPolygonToUnoPolyPolygonBezierCoords(
+ aPolyPolygon,
+ aSourcePolyPolygon);
+ maPath <<= aSourcePolyPolygon;
+
+ mbLikelyOOXMLCurve = lcl_IsLikelyOOXMLCurve(aPolyPolygon.getB2DPolygon(0));
+ }
+ }
+ break;
+ }
+ default:
+ return SdXMLShapeContext::processAttribute( aIter );
+ }
+ return true;
+}
+
+void SdXMLConnectorShapeContext::startFastElement (sal_Int32 nElement,
+ const css::uno::Reference< css::xml::sax::XFastAttributeList >& xAttrList)
+{
+ // For security reasons, do not add empty connectors. There may have been an error in EA2
+ // that created empty, far set off connectors (e.g. 63 meters below top of document). This
+ // is not guaranteed, but it's definitely safe to not add empty connectors.
+ bool bDoAdd(true);
+
+ if( maStartShapeId.isEmpty()
+ && maEndShapeId.isEmpty()
+ && maStart.X == maEnd.X
+ && maStart.Y == maEnd.Y
+ && 0 == mnDelta1
+ && 0 == mnDelta2
+ && 0 == mnDelta3
+ )
+ {
+ bDoAdd = false;
+ }
+
+ if(!bDoAdd)
+ return;
+
+ // create Connector shape
+ // add, set style and properties from base shape
+ AddShape("com.sun.star.drawing.ConnectorShape");
+ if(!mxShape.is())
+ return;
+
+ // #121965# if draw:transform is used, apply directly to the start
+ // and end positions before using these
+ if(mnTransform.NeedsAction())
+ {
+ // transformation is used, apply to object.
+ ::basegfx::B2DHomMatrix aMat;
+ mnTransform.GetFullTransform(aMat);
+
+ if(!aMat.isIdentity())
+ {
+ basegfx::B2DPoint aStart(maStart.X, maStart.Y);
+ basegfx::B2DPoint aEnd(maEnd.X, maEnd.Y);
+
+ aStart = aMat * aStart;
+ aEnd = aMat * aEnd;
+
+ maStart.X = basegfx::fround(aStart.getX());
+ maStart.Y = basegfx::fround(aStart.getY());
+ maEnd.X = basegfx::fround(aEnd.getX());
+ maEnd.Y = basegfx::fround(aEnd.getY());
+ }
+ }
+
+ uno::Reference< beans::XPropertySet > xProps( mxShape, uno::UNO_QUERY );
+ if (xProps.is())
+ xProps->setPropertyValue("EdgeOOXMLCurve", Any(mbLikelyOOXMLCurve));
+
+ // add connection ids
+ if( !maStartShapeId.isEmpty() )
+ GetImport().GetShapeImport()->addShapeConnection( mxShape, true, maStartShapeId, mnStartGlueId );
+ if( !maEndShapeId.isEmpty() )
+ GetImport().GetShapeImport()->addShapeConnection( mxShape, false, maEndShapeId, mnEndGlueId );
+
+ if( xProps.is() )
+ {
+ xProps->setPropertyValue("StartPosition", Any(maStart));
+ xProps->setPropertyValue("EndPosition", Any(maEnd) );
+ xProps->setPropertyValue("EdgeKind", Any(mnType) );
+ xProps->setPropertyValue("EdgeLine1Delta", Any(mnDelta1) );
+ xProps->setPropertyValue("EdgeLine2Delta", Any(mnDelta2) );
+ xProps->setPropertyValue("EdgeLine3Delta", Any(mnDelta3) );
+ }
+ SetStyle();
+ SetLayer();
+
+ if ( maPath.hasValue() )
+ {
+ // #i115492#
+ // Ignore svg:d attribute for text documents created by OpenOffice.org
+ // versions before OOo 3.3, because these OOo versions are storing
+ // svg:d values not using the correct unit.
+ bool bApplySVGD( true );
+ if ( uno::Reference< text::XTextDocument >(GetImport().GetModel(), uno::UNO_QUERY).is() )
+ {
+ sal_Int32 nUPD( 0 );
+ sal_Int32 nBuild( 0 );
+ const bool bBuildIdFound = GetImport().getBuildIds( nUPD, nBuild );
+ if ( GetImport().IsTextDocInOOoFileFormat() ||
+ ( bBuildIdFound &&
+ ( ( nUPD == 641 ) || ( nUPD == 645 ) || // prior OOo 2.0
+ ( nUPD == 680 ) || // OOo 2.x
+ ( nUPD == 300 ) || // OOo 3.0 - OOo 3.0.1
+ ( nUPD == 310 ) || // OOo 3.1 - OOo 3.1.1
+ ( nUPD == 320 ) ) ) ) // OOo 3.2 - OOo 3.2.1
+ {
+ bApplySVGD = false;
+ }
+ }
+
+ if ( bApplySVGD )
+ {
+ // tdf#83360 use path data only when redundant data of start and end point coordinates of
+ // path start/end and connector start/end is equal. This is to avoid using erroneous
+ // or inconsistent path data at import of foreign formats. Office itself always
+ // writes out a consistent data set. Not using it when there is inconsistency
+ // is okay since the path data is redundant, buffered data just to avoid recalculation
+ // of the connector's layout at load time, no real information would be lost.
+ // A 'connected' end has prio to direct coordinate data in Start/EndPosition
+ // to the path data (which should have the start/end redundant in the path)
+ const drawing::PolyPolygonBezierCoords* pSource = static_cast< const drawing::PolyPolygonBezierCoords* >(maPath.getValue());
+ const sal_uInt32 nSequenceCount(pSource->Coordinates.getLength());
+ bool bStartEqual(false);
+ bool bEndEqual(false);
+
+ if(nSequenceCount)
+ {
+ const drawing::PointSequence& rStartSeq = pSource->Coordinates[0];
+ const sal_uInt32 nStartCount = rStartSeq.getLength();
+
+ if(nStartCount)
+ {
+ const awt::Point& rStartPoint = rStartSeq.getConstArray()[0];
+
+ if(rStartPoint.X == maStart.X && rStartPoint.Y == maStart.Y)
+ {
+ bStartEqual = true;
+ }
+ }
+
+ const drawing::PointSequence& rEndSeq = pSource->Coordinates[nSequenceCount - 1];
+ const sal_uInt32 nEndCount = rEndSeq.getLength();
+
+ if(nEndCount)
+ {
+ const awt::Point& rEndPoint = rEndSeq.getConstArray()[nEndCount - 1];
+
+ if(rEndPoint.X == maEnd.X && rEndPoint.Y == maEnd.Y)
+ {
+ bEndEqual = true;
+ }
+ }
+ }
+
+ if(!bStartEqual || !bEndEqual)
+ {
+ bApplySVGD = false;
+ }
+ }
+
+ if ( bApplySVGD )
+ {
+ assert(maPath.getValueType() == cppu::UnoType<drawing::PolyPolygonBezierCoords>::get());
+ xProps->setPropertyValue("PolyPolygonBezier", maPath);
+ }
+ }
+
+ SdXMLShapeContext::startFastElement(nElement, xAttrList);
+}
+
+
+SdXMLMeasureShapeContext::SdXMLMeasureShapeContext(
+ SvXMLImport& rImport,
+ const css::uno::Reference< css::xml::sax::XFastAttributeList>& xAttrList,
+ uno::Reference< drawing::XShapes > const & rShapes,
+ bool bTemporaryShape)
+: SdXMLShapeContext( rImport, xAttrList, rShapes, bTemporaryShape ),
+ maStart(0,0),
+ maEnd(1,1)
+{
+}
+
+SdXMLMeasureShapeContext::~SdXMLMeasureShapeContext()
+{
+}
+
+// this is called from the parent group for each unparsed attribute in the attribute list
+bool SdXMLMeasureShapeContext::processAttribute( const sax_fastparser::FastAttributeList::FastAttributeIter & aIter )
+{
+ switch( aIter.getToken() )
+ {
+ case XML_ELEMENT(SVG, XML_X1):
+ case XML_ELEMENT(SVG_COMPAT, XML_X1):
+ {
+ GetImport().GetMM100UnitConverter().convertMeasureToCore(
+ maStart.X, aIter.toView());
+ break;
+ }
+ case XML_ELEMENT(SVG, XML_Y1):
+ case XML_ELEMENT(SVG_COMPAT, XML_Y1):
+ {
+ GetImport().GetMM100UnitConverter().convertMeasureToCore(
+ maStart.Y, aIter.toView());
+ break;
+ }
+ case XML_ELEMENT(SVG, XML_X2):
+ case XML_ELEMENT(SVG_COMPAT, XML_X2):
+ {
+ GetImport().GetMM100UnitConverter().convertMeasureToCore(
+ maEnd.X, aIter.toView());
+ break;
+ }
+ case XML_ELEMENT(SVG, XML_Y2):
+ case XML_ELEMENT(SVG_COMPAT, XML_Y2):
+ {
+ GetImport().GetMM100UnitConverter().convertMeasureToCore(
+ maEnd.Y, aIter.toView());
+ break;
+ }
+ default:
+ return SdXMLShapeContext::processAttribute( aIter );
+ }
+ return true;
+}
+
+void SdXMLMeasureShapeContext::startFastElement (sal_Int32 nElement,
+ const css::uno::Reference< css::xml::sax::XFastAttributeList >& xAttrList)
+{
+ // create Measure shape
+ // add, set style and properties from base shape
+ AddShape("com.sun.star.drawing.MeasureShape");
+ if(!mxShape.is())
+ return;
+
+ SetStyle();
+ SetLayer();
+
+ uno::Reference< beans::XPropertySet > xProps( mxShape, uno::UNO_QUERY );
+ if( xProps.is() )
+ {
+ xProps->setPropertyValue("StartPosition", Any(maStart));
+ xProps->setPropertyValue("EndPosition", Any(maEnd) );
+ }
+
+ // delete pre created fields
+ uno::Reference< text::XText > xText( mxShape, uno::UNO_QUERY );
+ if( xText.is() )
+ {
+ xText->setString( " " );
+ }
+
+ SdXMLShapeContext::startFastElement(nElement, xAttrList);
+}
+
+void SdXMLMeasureShapeContext::endFastElement(sal_Int32 nElement)
+{
+ do
+ {
+ // delete pre created fields
+ uno::Reference< text::XText > xText( mxShape, uno::UNO_QUERY );
+ if( !xText.is() )
+ break;
+
+ uno::Reference< text::XTextCursor > xCursor( xText->createTextCursor() );
+ if( !xCursor.is() )
+ break;
+
+ xCursor->collapseToStart();
+ xCursor->goRight( 1, true );
+ xCursor->setString( "" );
+ }
+ while(false);
+
+ SdXMLShapeContext::endFastElement(nElement);
+}
+
+
+SdXMLPageShapeContext::SdXMLPageShapeContext(
+ SvXMLImport& rImport,
+ const css::uno::Reference< css::xml::sax::XFastAttributeList>& xAttrList,
+ uno::Reference< drawing::XShapes > const & rShapes,
+ bool bTemporaryShape)
+: SdXMLShapeContext( rImport, xAttrList, rShapes, bTemporaryShape ), mnPageNumber(0)
+{
+ mbClearDefaultAttributes = false;
+}
+
+SdXMLPageShapeContext::~SdXMLPageShapeContext()
+{
+}
+
+// this is called from the parent group for each unparsed attribute in the attribute list
+bool SdXMLPageShapeContext::processAttribute( const sax_fastparser::FastAttributeList::FastAttributeIter & aIter )
+{
+ if( aIter.getToken() == XML_ELEMENT(DRAW, XML_PAGE_NUMBER) )
+ mnPageNumber = aIter.toInt32();
+ else
+ return SdXMLShapeContext::processAttribute( aIter );
+ return true;
+}
+
+void SdXMLPageShapeContext::startFastElement (sal_Int32 nElement,
+ const css::uno::Reference< css::xml::sax::XFastAttributeList >& xAttrList)
+{
+ // create Page shape
+ // add, set style and properties from base shape
+
+ // #86163# take into account which type of PageShape needs to
+ // be constructed. It's a presentation shape if presentation:XML_CLASS == XML_PAGE.
+ bool bIsPresentation = !maPresentationClass.isEmpty() &&
+ GetImport().GetShapeImport()->IsPresentationShapesSupported();
+
+ uno::Reference< lang::XServiceInfo > xInfo( mxShapes, uno::UNO_QUERY );
+ const bool bIsOnHandoutPage = xInfo.is() && xInfo->supportsService("com.sun.star.presentation.HandoutMasterPage");
+
+ if( bIsOnHandoutPage )
+ {
+ AddShape("com.sun.star.presentation.HandoutShape");
+ }
+ else
+ {
+ if(bIsPresentation && !IsXMLToken( maPresentationClass, XML_PAGE ) )
+ {
+ bIsPresentation = false;
+ }
+
+ if(bIsPresentation)
+ {
+ AddShape("com.sun.star.presentation.PageShape");
+ }
+ else
+ {
+ AddShape("com.sun.star.drawing.PageShape");
+ }
+ }
+
+ if(!mxShape.is())
+ return;
+
+ SetStyle();
+ SetLayer();
+
+ // set pos, size, shear and rotate
+ SetTransformation();
+
+ uno::Reference< beans::XPropertySet > xPropSet(mxShape, uno::UNO_QUERY);
+ if(xPropSet.is())
+ {
+ uno::Reference< beans::XPropertySetInfo > xPropSetInfo( xPropSet->getPropertySetInfo() );
+ static constexpr OUString aPageNumberStr(u"PageNumber"_ustr);
+ if( xPropSetInfo.is() && xPropSetInfo->hasPropertyByName(aPageNumberStr))
+ xPropSet->setPropertyValue(aPageNumberStr, uno::Any( mnPageNumber ));
+ }
+
+ SdXMLShapeContext::startFastElement(nElement, xAttrList);
+}
+
+
+SdXMLCaptionShapeContext::SdXMLCaptionShapeContext(
+ SvXMLImport& rImport,
+ const css::uno::Reference< css::xml::sax::XFastAttributeList>& xAttrList,
+ uno::Reference< drawing::XShapes > const & rShapes,
+ bool bTemporaryShape)
+: SdXMLShapeContext( rImport, xAttrList, rShapes, bTemporaryShape ),
+ // #86616# for correct edge rounding import mnRadius needs to be initialized
+ mnRadius( 0 )
+{
+}
+
+SdXMLCaptionShapeContext::~SdXMLCaptionShapeContext()
+{
+}
+
+void SdXMLCaptionShapeContext::startFastElement (sal_Int32 nElement,
+ const css::uno::Reference< css::xml::sax::XFastAttributeList >& xAttrList)
+{
+ // create Caption shape
+ // add, set style and properties from base shape
+ AddShape("com.sun.star.drawing.CaptionShape");
+ if( !mxShape.is() )
+ return;
+
+ SetStyle();
+ SetLayer();
+
+ uno::Reference< beans::XPropertySet > xProps( mxShape, uno::UNO_QUERY );
+
+ // SJ: If AutoGrowWidthItem is set, SetTransformation will lead to the wrong SnapRect
+ // because NbcAdjustTextFrameWidthAndHeight() is called (text is set later and center alignment
+ // is the default setting, so the top left reference point that is used by the caption point is
+ // no longer correct) There are two ways to solve this problem, temporarily disabling the
+ // autogrowwidth as we are doing here or to apply the CaptionPoint after setting text
+ bool bIsAutoGrowWidth = false;
+ if ( xProps.is() )
+ {
+ uno::Any aAny( xProps->getPropertyValue("TextAutoGrowWidth") );
+ aAny >>= bIsAutoGrowWidth;
+
+ if ( bIsAutoGrowWidth )
+ xProps->setPropertyValue("TextAutoGrowWidth", uno::Any( false ) );
+ }
+
+ // set pos, size, shear and rotate
+ SetTransformation();
+ if( xProps.is() )
+ xProps->setPropertyValue("CaptionPoint", uno::Any( maCaptionPoint ) );
+
+ if ( bIsAutoGrowWidth )
+ xProps->setPropertyValue("TextAutoGrowWidth", uno::Any( true ) );
+
+ if(mnRadius)
+ {
+ uno::Reference< beans::XPropertySet > xPropSet(mxShape, uno::UNO_QUERY);
+ if(xPropSet.is())
+ {
+ try
+ {
+ xPropSet->setPropertyValue("CornerRadius", uno::Any( mnRadius ) );
+ }
+ catch(const uno::Exception&)
+ {
+ DBG_UNHANDLED_EXCEPTION( "xmloff", "setting corner radius");
+ }
+ }
+ }
+
+ SdXMLShapeContext::startFastElement(nElement, xAttrList);
+}
+
+// this is called from the parent group for each unparsed attribute in the attribute list
+bool SdXMLCaptionShapeContext::processAttribute( const sax_fastparser::FastAttributeList::FastAttributeIter & aIter )
+{
+ switch (aIter.getToken())
+ {
+ case XML_ELEMENT(DRAW, XML_CAPTION_POINT_X):
+ GetImport().GetMM100UnitConverter().convertMeasureToCore(
+ maCaptionPoint.X, aIter.toView());
+ break;
+ case XML_ELEMENT(DRAW, XML_CAPTION_POINT_Y):
+ GetImport().GetMM100UnitConverter().convertMeasureToCore(
+ maCaptionPoint.Y, aIter.toView());
+ break;
+ case XML_ELEMENT(DRAW, XML_CORNER_RADIUS):
+ GetImport().GetMM100UnitConverter().convertMeasureToCore(
+ mnRadius, aIter.toView());
+ break;
+ default:
+ return SdXMLShapeContext::processAttribute( aIter );
+ }
+ return true;
+}
+
+
+SdXMLGraphicObjectShapeContext::SdXMLGraphicObjectShapeContext(
+ SvXMLImport& rImport,
+ const css::uno::Reference< css::xml::sax::XFastAttributeList>& xAttrList,
+ uno::Reference< drawing::XShapes > const & rShapes)
+: SdXMLShapeContext( rImport, xAttrList, rShapes, false/*bTemporaryShape*/ )
+{
+}
+
+// this is called from the parent group for each unparsed attribute in the attribute list
+bool SdXMLGraphicObjectShapeContext::processAttribute( const sax_fastparser::FastAttributeList::FastAttributeIter & aIter )
+{
+ switch (aIter.getToken())
+ {
+ case XML_ELEMENT(XLINK, XML_HREF):
+ maURL = aIter.toString();
+ break;
+ case XML_ELEMENT(DRAW, XML_MIME_TYPE):
+ case XML_ELEMENT(LO_EXT, XML_MIME_TYPE):
+ msMimeType = aIter.toString();
+ break;
+ default:
+ return SdXMLShapeContext::processAttribute(aIter);
+ }
+ return true;
+}
+
+void SdXMLGraphicObjectShapeContext::startFastElement (sal_Int32 nElement,
+ const css::uno::Reference< css::xml::sax::XFastAttributeList >& xAttrList)
+{
+ // create graphic object shape
+ OUString service;
+
+ if( IsXMLToken( maPresentationClass, XML_GRAPHIC ) && GetImport().GetShapeImport()->IsPresentationShapesSupported() )
+ {
+ service = "com.sun.star.presentation.GraphicObjectShape";
+ }
+ else
+ {
+ service = "com.sun.star.drawing.GraphicObjectShape";
+ }
+
+ AddShape(service);
+
+ if(!mxShape.is())
+ return;
+
+ SetStyle();
+ SetLayer();
+
+ uno::Reference< beans::XPropertySet > xPropset(mxShape, uno::UNO_QUERY);
+ if(xPropset.is())
+ {
+ // since OOo 1.x had no line or fill style for graphics, but may create
+ // documents with them, we have to override them here
+ sal_Int32 nUPD, nBuildId;
+ if( GetImport().getBuildIds( nUPD, nBuildId ) && (nUPD == 645) ) try
+ {
+ xPropset->setPropertyValue("FillStyle", Any( FillStyle_NONE ) );
+ xPropset->setPropertyValue("LineStyle", Any( LineStyle_NONE ) );
+ }
+ catch(const Exception&)
+ {
+ }
+
+ uno::Reference< beans::XPropertySetInfo > xPropsInfo( xPropset->getPropertySetInfo() );
+ if( xPropsInfo.is() && xPropsInfo->hasPropertyByName("IsEmptyPresentationObject"))
+ xPropset->setPropertyValue("IsEmptyPresentationObject", css::uno::Any( mbIsPlaceholder ) );
+
+ if( !mbIsPlaceholder )
+ {
+ if( !maURL.isEmpty() )
+ {
+ uno::Reference<graphic::XGraphic> xGraphic = GetImport().loadGraphicByURL(maURL);
+ if (xGraphic.is())
+ {
+ xPropset->setPropertyValue("Graphic", uno::Any(xGraphic));
+ }
+ }
+ }
+ }
+
+ if(mbIsUserTransformed)
+ {
+ uno::Reference< beans::XPropertySet > xProps(mxShape, uno::UNO_QUERY);
+ if(xProps.is())
+ {
+ uno::Reference< beans::XPropertySetInfo > xPropsInfo( xProps->getPropertySetInfo() );
+ if( xPropsInfo.is() )
+ {
+ if( xPropsInfo->hasPropertyByName("IsPlaceholderDependent"))
+ xProps->setPropertyValue("IsPlaceholderDependent", css::uno::Any(false) );
+ }
+ }
+ }
+
+ // set pos, size, shear and rotate
+ SetTransformation();
+
+ SdXMLShapeContext::startFastElement(nElement, xAttrList);
+}
+
+void SdXMLGraphicObjectShapeContext::endFastElement(sal_Int32 nElement)
+{
+ if (mxBase64Stream.is())
+ {
+ uno::Reference<graphic::XGraphic> xGraphic(GetImport().loadGraphicFromBase64(mxBase64Stream));
+ if (xGraphic.is())
+ {
+ uno::Reference<beans::XPropertySet> xProperties(mxShape, uno::UNO_QUERY);
+ if (xProperties.is())
+ {
+ xProperties->setPropertyValue("Graphic", uno::Any(xGraphic));
+ }
+ }
+ }
+
+ SdXMLShapeContext::endFastElement(nElement);
+}
+
+css::uno::Reference< css::xml::sax::XFastContextHandler > SdXMLGraphicObjectShapeContext::createFastChildContext(
+ sal_Int32 nElement,
+ const css::uno::Reference< css::xml::sax::XFastAttributeList >& xAttrList )
+{
+ css::uno::Reference< css::xml::sax::XFastContextHandler > xContext;
+
+ if( nElement == XML_ELEMENT(OFFICE, XML_BINARY_DATA) )
+ {
+ if( maURL.isEmpty() && !mxBase64Stream.is() )
+ {
+ mxBase64Stream = GetImport().GetStreamForGraphicObjectURLFromBase64();
+ if( mxBase64Stream.is() )
+ xContext = new XMLBase64ImportContext( GetImport(),
+ mxBase64Stream );
+ }
+ }
+
+ // delegate to parent class if no context could be created
+ if (!xContext)
+ xContext = SdXMLShapeContext::createFastChildContext(nElement,
+ xAttrList);
+
+ if (!xContext)
+ XMLOFF_WARN_UNKNOWN_ELEMENT("xmloff", nElement);
+
+ return xContext;
+}
+
+SdXMLGraphicObjectShapeContext::~SdXMLGraphicObjectShapeContext()
+{
+
+}
+
+
+SdXMLChartShapeContext::SdXMLChartShapeContext(
+ SvXMLImport& rImport,
+ const css::uno::Reference< css::xml::sax::XFastAttributeList>& xAttrList,
+ uno::Reference< drawing::XShapes > const & rShapes,
+ bool bTemporaryShape)
+: SdXMLShapeContext( rImport, xAttrList, rShapes, bTemporaryShape )
+{
+}
+
+void SdXMLChartShapeContext::startFastElement (sal_Int32 nElement,
+ const css::uno::Reference< css::xml::sax::XFastAttributeList >& xAttrList)
+{
+ const bool bIsPresentation = isPresentationShape();
+
+ AddShape(
+ bIsPresentation
+ ? OUString("com.sun.star.presentation.ChartShape")
+ : OUString("com.sun.star.drawing.OLE2Shape"));
+
+ if(!mxShape.is())
+ return;
+
+ SetStyle();
+ SetLayer();
+
+ if( !mbIsPlaceholder )
+ {
+ uno::Reference< beans::XPropertySet > xProps(mxShape, uno::UNO_QUERY);
+ if(xProps.is())
+ {
+ uno::Reference< beans::XPropertySetInfo > xPropsInfo( xProps->getPropertySetInfo() );
+ if( xPropsInfo.is() && xPropsInfo->hasPropertyByName("IsEmptyPresentationObject"))
+ xProps->setPropertyValue("IsEmptyPresentationObject", css::uno::Any(false) );
+
+ uno::Any aAny;
+
+ xProps->setPropertyValue("CLSID", Any(OUString("12DCAE26-281F-416F-a234-c3086127382e")) );
+
+ aAny = xProps->getPropertyValue("Model");
+ uno::Reference< frame::XModel > xChartModel;
+ if( aAny >>= xChartModel )
+ {
+#if !ENABLE_WASM_STRIP_CHART
+ // WASM_CHART change
+ // TODO: Maybe use SdXMLGraphicObjectShapeContext completely instead
+ // or try to create as mbIsPlaceholder object adding a Chart visualization
+ // that should be available somehow
+ mxChartContext.set( GetImport().GetChartImport()->CreateChartContext( GetImport(), xChartModel ) );
+#endif
+ }
+ }
+ }
+
+ if(mbIsUserTransformed)
+ {
+ uno::Reference< beans::XPropertySet > xProps(mxShape, uno::UNO_QUERY);
+ if(xProps.is())
+ {
+ uno::Reference< beans::XPropertySetInfo > xPropsInfo( xProps->getPropertySetInfo() );
+ if( xPropsInfo.is() )
+ {
+ if( xPropsInfo->hasPropertyByName("IsPlaceholderDependent"))
+ xProps->setPropertyValue("IsPlaceholderDependent", css::uno::Any(false) );
+ }
+ }
+ }
+
+ // set pos, size, shear and rotate
+ SetTransformation();
+
+ SdXMLShapeContext::startFastElement(nElement, xAttrList);
+
+ if( mxChartContext.is() )
+ mxChartContext->startFastElement( nElement, xAttrList );
+}
+
+void SdXMLChartShapeContext::endFastElement(sal_Int32 nElement)
+{
+ if( mxChartContext.is() )
+ mxChartContext->endFastElement(nElement);
+
+ SdXMLShapeContext::endFastElement(nElement);
+}
+
+void SdXMLChartShapeContext::characters( const OUString& rChars )
+{
+ if( mxChartContext.is() )
+ mxChartContext->characters( rChars );
+}
+
+css::uno::Reference< css::xml::sax::XFastContextHandler > SdXMLChartShapeContext::createFastChildContext(
+ sal_Int32 nElement,
+ const css::uno::Reference< css::xml::sax::XFastAttributeList >& xAttrList )
+{
+ if( mxChartContext.is() )
+ return mxChartContext->createFastChildContext( nElement, xAttrList );
+
+ return nullptr;
+}
+
+
+SdXMLObjectShapeContext::SdXMLObjectShapeContext( SvXMLImport& rImport,
+ const css::uno::Reference< css::xml::sax::XFastAttributeList>& xAttrList,
+ css::uno::Reference< css::drawing::XShapes > const & rShapes)
+: SdXMLShapeContext( rImport, xAttrList, rShapes, false/*bTemporaryShape*/ )
+{
+}
+
+SdXMLObjectShapeContext::~SdXMLObjectShapeContext()
+{
+}
+
+void SdXMLObjectShapeContext::startFastElement (sal_Int32 /*nElement*/,
+ const css::uno::Reference< css::xml::sax::XFastAttributeList >& /*xAttrList*/)
+{
+ // #96717# in theorie, if we don't have a URL we shouldn't even
+ // export this OLE shape. But practically it's too risky right now
+ // to change this so we better dispose this on load
+ //if( !mbIsPlaceholder && ImpIsEmptyURL(maHref) )
+ // return;
+
+ // #100592# this BugFix prevents that a shape is created. CL
+ // is thinking about an alternative.
+ // #i13140# Check for more than empty string in maHref, there are
+ // other possibilities that maHref results in empty container
+ // storage names
+ if( !(GetImport().getImportFlags() & SvXMLImportFlags::EMBEDDED) && !mbIsPlaceholder && ImpIsEmptyURL(maHref) )
+ return;
+
+ OUString service("com.sun.star.drawing.OLE2Shape");
+
+ bool bIsPresShape = !maPresentationClass.isEmpty() && GetImport().GetShapeImport()->IsPresentationShapesSupported();
+
+ if( bIsPresShape )
+ {
+ if( IsXMLToken( maPresentationClass, XML_CHART ) )
+ {
+ service = "com.sun.star.presentation.ChartShape";
+ }
+ else if( IsXMLToken( maPresentationClass, XML_TABLE ) )
+ {
+ service = "com.sun.star.presentation.CalcShape";
+ }
+ else if( IsXMLToken( maPresentationClass, XML_OBJECT ) )
+ {
+ service = "com.sun.star.presentation.OLE2Shape";
+ }
+ }
+
+ AddShape(service);
+
+ if( !mxShape.is() )
+ return;
+
+ SetLayer();
+
+ if(bIsPresShape)
+ {
+ uno::Reference< beans::XPropertySet > xProps(mxShape, uno::UNO_QUERY);
+ if(xProps.is())
+ {
+ uno::Reference< beans::XPropertySetInfo > xPropsInfo( xProps->getPropertySetInfo() );
+ if( xPropsInfo.is() )
+ {
+ if( !mbIsPlaceholder && xPropsInfo->hasPropertyByName("IsEmptyPresentationObject"))
+ xProps->setPropertyValue("IsEmptyPresentationObject", css::uno::Any(false) );
+
+ if( mbIsUserTransformed && xPropsInfo->hasPropertyByName("IsPlaceholderDependent"))
+ xProps->setPropertyValue("IsPlaceholderDependent", css::uno::Any(false) );
+ }
+ }
+ }
+
+ if( !mbIsPlaceholder && !maHref.isEmpty() )
+ {
+ uno::Reference< beans::XPropertySet > xProps( mxShape, uno::UNO_QUERY );
+
+ if( xProps.is() )
+ {
+ OUString aPersistName = GetImport().ResolveEmbeddedObjectURL( maHref, maCLSID );
+
+ if ( GetImport().IsPackageURL( maHref ) )
+ {
+ static constexpr OUString sURL( u"vnd.sun.star.EmbeddedObject:"_ustr );
+
+ if ( aPersistName.startsWith( sURL ) )
+ aPersistName = aPersistName.copy( sURL.getLength() );
+
+ xProps->setPropertyValue("PersistName",
+ uno::Any( aPersistName ) );
+ }
+ else
+ {
+ // this is OOo link object
+ xProps->setPropertyValue("LinkURL",
+ uno::Any( aPersistName ) );
+ }
+ }
+ }
+
+ // set pos, size, shear and rotate
+ SetTransformation();
+
+ SetStyle();
+
+ GetImport().GetShapeImport()->finishShape( mxShape, mxAttrList, mxShapes );
+}
+
+void SdXMLObjectShapeContext::endFastElement(sal_Int32 nElement)
+{
+ if (GetImport().isGeneratorVersionOlderThan(
+ SvXMLImport::OOo_34x, SvXMLImport::LO_41x)) // < LO 4.0
+ {
+ // #i118485#
+ // If it's an old file from us written before OOo3.4, we need to correct
+ // FillStyle and LineStyle for OLE2 objects. The error was that the old paint
+ // implementations just ignored added fill/linestyles completely, thus
+ // those objects need to be corrected to not show blue and hairline which
+ // always was the default, but would be shown now
+ uno::Reference< beans::XPropertySet > xProps(mxShape, uno::UNO_QUERY);
+
+ if( xProps.is() )
+ {
+ xProps->setPropertyValue("FillStyle", uno::Any(drawing::FillStyle_NONE));
+ xProps->setPropertyValue("LineStyle", uno::Any(drawing::LineStyle_NONE));
+ }
+ }
+
+ if( mxBase64Stream.is() )
+ {
+ OUString aPersistName( GetImport().ResolveEmbeddedObjectURLFromBase64() );
+ static constexpr OUStringLiteral sURL( u"vnd.sun.star.EmbeddedObject:" );
+
+ aPersistName = aPersistName.copy( sURL.getLength() );
+
+ uno::Reference< beans::XPropertySet > xProps(mxShape, uno::UNO_QUERY);
+ if( xProps.is() )
+ xProps->setPropertyValue("PersistName", uno::Any( aPersistName ) );
+ }
+
+ SdXMLShapeContext::endFastElement(nElement);
+}
+
+// this is called from the parent group for each unparsed attribute in the attribute list
+bool SdXMLObjectShapeContext::processAttribute( const sax_fastparser::FastAttributeList::FastAttributeIter & aIter )
+{
+ switch( aIter.getToken() )
+ {
+ case XML_ELEMENT(DRAW, XML_CLASS_ID):
+ maCLSID = aIter.toString();
+ break;
+ case XML_ELEMENT(XLINK, XML_HREF):
+ maHref = aIter.toString();
+ break;
+ default:
+ return SdXMLShapeContext::processAttribute( aIter );
+ }
+ return true;
+}
+
+css::uno::Reference< css::xml::sax::XFastContextHandler > SdXMLObjectShapeContext::createFastChildContext(
+ sal_Int32 nElement,
+ const css::uno::Reference< css::xml::sax::XFastAttributeList >& xAttrList )
+{
+ if(nElement == XML_ELEMENT(OFFICE, XML_BINARY_DATA))
+ {
+ mxBase64Stream = GetImport().GetStreamForEmbeddedObjectURLFromBase64();
+ if( mxBase64Stream.is() )
+ return new XMLBase64ImportContext( GetImport(), mxBase64Stream );
+ }
+ else if( nElement == XML_ELEMENT(OFFICE, XML_DOCUMENT) ||
+ nElement == XML_ELEMENT(MATH, XML_MATH) )
+ {
+ rtl::Reference<XMLEmbeddedObjectImportContext> xEContext(
+ new XMLEmbeddedObjectImportContext(GetImport(), nElement, xAttrList));
+ maCLSID = xEContext->GetFilterCLSID();
+ if( !maCLSID.isEmpty() )
+ {
+ uno::Reference< beans::XPropertySet > xPropSet(mxShape, uno::UNO_QUERY);
+ if( xPropSet.is() )
+ {
+ xPropSet->setPropertyValue("CLSID", uno::Any( maCLSID ) );
+
+ uno::Reference< lang::XComponent > xComp;
+ xPropSet->getPropertyValue("Model") >>= xComp;
+ SAL_WARN_IF( !xComp.is(), "xmloff", "no xModel for own OLE format" );
+ xEContext->SetComponent(xComp);
+ }
+ }
+ return xEContext;
+ }
+
+ // delegate to parent class if no context could be created
+ return SdXMLShapeContext::createFastChildContext(nElement, xAttrList);
+}
+
+SdXMLAppletShapeContext::SdXMLAppletShapeContext( SvXMLImport& rImport,
+ const css::uno::Reference< css::xml::sax::XFastAttributeList>& xAttrList,
+ css::uno::Reference< css::drawing::XShapes > const & rShapes)
+: SdXMLShapeContext( rImport, xAttrList, rShapes, false/*bTemporaryShape*/ ),
+ mbIsScript( false )
+{
+}
+
+SdXMLAppletShapeContext::~SdXMLAppletShapeContext()
+{
+}
+
+void SdXMLAppletShapeContext::startFastElement (sal_Int32 /*nElement*/,
+ const css::uno::Reference< css::xml::sax::XFastAttributeList >& /*xAttrList*/)
+{
+ AddShape("com.sun.star.drawing.AppletShape");
+
+ if( mxShape.is() )
+ {
+ SetLayer();
+
+ // set pos, size, shear and rotate
+ SetTransformation();
+ GetImport().GetShapeImport()->finishShape( mxShape, mxAttrList, mxShapes );
+ }
+}
+
+// this is called from the parent group for each unparsed attribute in the attribute list
+bool SdXMLAppletShapeContext::processAttribute( const sax_fastparser::FastAttributeList::FastAttributeIter & aIter )
+{
+ switch( aIter.getToken() )
+ {
+ case XML_ELEMENT(DRAW, XML_APPLET_NAME):
+ maAppletName = aIter.toString();
+ break;
+ case XML_ELEMENT(DRAW, XML_CODE):
+ maAppletCode = aIter.toString();
+ break;
+ case XML_ELEMENT(DRAW, XML_MAY_SCRIPT):
+ mbIsScript = IsXMLToken( aIter, XML_TRUE );
+ break;
+ case XML_ELEMENT(XLINK, XML_HREF):
+ maHref = GetImport().GetAbsoluteReference(aIter.toString());
+ break;
+ default:
+ return SdXMLShapeContext::processAttribute( aIter );
+ }
+ return true;
+}
+
+void SdXMLAppletShapeContext::endFastElement(sal_Int32 nElement)
+{
+ uno::Reference< beans::XPropertySet > xProps( mxShape, uno::UNO_QUERY );
+ if( xProps.is() )
+ {
+ if ( maSize.Width && maSize.Height )
+ {
+ // the visual area for applet must be set on loading
+ awt::Rectangle aRect( 0, 0, maSize.Width, maSize.Height );
+ xProps->setPropertyValue("VisibleArea", Any(aRect) );
+ }
+
+ if( maParams.hasElements() )
+ {
+ xProps->setPropertyValue("AppletCommands", Any(maParams) );
+ }
+
+ if( !maHref.isEmpty() )
+ {
+ xProps->setPropertyValue("AppletCodeBase", Any(maHref) );
+ }
+
+ if( !maAppletName.isEmpty() )
+ {
+ xProps->setPropertyValue("AppletName", Any(maAppletName) );
+ }
+
+ if( mbIsScript )
+ {
+ xProps->setPropertyValue("AppletIsScript", Any(mbIsScript) );
+
+ }
+
+ if( !maAppletCode.isEmpty() )
+ {
+ xProps->setPropertyValue("AppletCode", Any(maAppletCode) );
+ }
+
+ xProps->setPropertyValue("AppletDocBase", Any(GetImport().GetDocumentBase()) );
+
+ SetThumbnail();
+ }
+
+ SdXMLShapeContext::endFastElement(nElement);
+}
+
+css::uno::Reference< css::xml::sax::XFastContextHandler > SdXMLAppletShapeContext::createFastChildContext(
+ sal_Int32 nElement,
+ const css::uno::Reference< css::xml::sax::XFastAttributeList >& xAttrList )
+{
+ if( nElement == XML_ELEMENT(DRAW, XML_PARAM) )
+ {
+ OUString aParamName, aParamValue;
+ // now parse the attribute list and look for draw:name and draw:value
+ for( auto& aIter : sax_fastparser::castToFastAttributeList(xAttrList) )
+ {
+ if( aIter.getToken() == XML_ELEMENT(DRAW, XML_NAME) )
+ aParamName = aIter.toString();
+ if( aIter.getToken() == XML_ELEMENT(DRAW, XML_VALUE) )
+ aParamValue = aIter.toString();
+ }
+
+ if( !aParamName.isEmpty() )
+ {
+ sal_Int32 nIndex = maParams.getLength();
+ maParams.realloc( nIndex + 1 );
+ auto pParams = maParams.getArray();
+ pParams[nIndex].Name = aParamName;
+ pParams[nIndex].Handle = -1;
+ pParams[nIndex].Value <<= aParamValue;
+ pParams[nIndex].State = beans::PropertyState_DIRECT_VALUE;
+ }
+
+ return new SvXMLImportContext( GetImport() );
+ }
+
+ return SdXMLShapeContext::createFastChildContext( nElement, xAttrList );
+}
+
+
+SdXMLPluginShapeContext::SdXMLPluginShapeContext( SvXMLImport& rImport,
+ const css::uno::Reference< css::xml::sax::XFastAttributeList>& xAttrList,
+ css::uno::Reference< css::drawing::XShapes > const & rShapes) :
+SdXMLShapeContext( rImport, xAttrList, rShapes, false/*bTemporaryShape*/ ),
+mbMedia( false )
+{
+}
+
+SdXMLPluginShapeContext::~SdXMLPluginShapeContext()
+{
+}
+
+void SdXMLPluginShapeContext::startFastElement (sal_Int32 /*nElement*/,
+ const css::uno::Reference< css::xml::sax::XFastAttributeList >& xAttrList)
+{
+
+ // watch for MimeType attribute to see if we have a media object
+ for( auto& aIter : sax_fastparser::castToFastAttributeList(xAttrList) )
+ {
+ if( aIter.getToken() == XML_ELEMENT(DRAW, XML_MIME_TYPE) )
+ {
+ if (::comphelper::IsMediaMimeType(aIter.toView()))
+ mbMedia = true;
+ // leave this loop
+ break;
+ }
+ }
+
+ OUString service;
+
+ bool bIsPresShape = false;
+
+ if( mbMedia )
+ {
+ service = "com.sun.star.drawing.MediaShape";
+
+ bIsPresShape = !maPresentationClass.isEmpty() && GetImport().GetShapeImport()->IsPresentationShapesSupported();
+ if( bIsPresShape )
+ {
+ if( IsXMLToken( maPresentationClass, XML_OBJECT ) )
+ {
+ service = "com.sun.star.presentation.MediaShape";
+ }
+ }
+ }
+ else
+ service = "com.sun.star.drawing.PluginShape";
+
+ AddShape(service);
+
+ if( !mxShape.is() )
+ return;
+
+ if (mbMedia)
+ {
+ // The media may have a crop, apply it.
+ SetStyle(/*bSupportsStyle=*/false);
+ }
+
+ SetLayer();
+
+ if(bIsPresShape)
+ {
+ uno::Reference< beans::XPropertySet > xProps( mxShape, uno::UNO_QUERY );
+ if(xProps.is())
+ {
+ uno::Reference< beans::XPropertySetInfo > xPropsInfo( xProps->getPropertySetInfo() );
+ if( xPropsInfo.is() )
+ {
+ if( !mbIsPlaceholder && xPropsInfo->hasPropertyByName("IsEmptyPresentationObject"))
+ xProps->setPropertyValue("IsEmptyPresentationObject", css::uno::Any(false) );
+
+ if( mbIsUserTransformed && xPropsInfo->hasPropertyByName("IsPlaceholderDependent"))
+ xProps->setPropertyValue("IsPlaceholderDependent", css::uno::Any(false) );
+ }
+ }
+ }
+
+ // set pos, size, shear and rotate
+ SetTransformation();
+ GetImport().GetShapeImport()->finishShape( mxShape, mxAttrList, mxShapes );
+}
+
+static OUString
+lcl_GetMediaReference(SvXMLImport const& rImport, OUString const& rURL)
+{
+ if (rImport.IsPackageURL(rURL))
+ {
+ return "vnd.sun.star.Package:" + rURL;
+ }
+ else
+ {
+ return rImport.GetAbsoluteReference(rURL);
+ }
+}
+
+// this is called from the parent group for each unparsed attribute in the attribute list
+bool SdXMLPluginShapeContext::processAttribute( const sax_fastparser::FastAttributeList::FastAttributeIter & aIter )
+{
+ switch( aIter.getToken() )
+ {
+ case XML_ELEMENT(DRAW, XML_MIME_TYPE):
+ maMimeType = aIter.toString();
+ break;
+ case XML_ELEMENT(XLINK, XML_HREF):
+ maHref = lcl_GetMediaReference(GetImport(), aIter.toString());
+ break;
+ default:
+ return SdXMLShapeContext::processAttribute( aIter );
+ }
+ return true;
+}
+
+void SdXMLPluginShapeContext::endFastElement(sal_Int32 nElement)
+{
+ uno::Reference< beans::XPropertySet > xProps( mxShape, uno::UNO_QUERY );
+
+ if( xProps.is() )
+ {
+ if ( maSize.Width && maSize.Height )
+ {
+ static constexpr OUString sVisibleArea( u"VisibleArea"_ustr );
+ uno::Reference< beans::XPropertySetInfo > aXPropSetInfo( xProps->getPropertySetInfo() );
+ if ( !aXPropSetInfo.is() || aXPropSetInfo->hasPropertyByName( sVisibleArea ) )
+ {
+ // the visual area for a plugin must be set on loading
+ awt::Rectangle aRect( 0, 0, maSize.Width, maSize.Height );
+ xProps->setPropertyValue( sVisibleArea, Any(aRect) );
+ }
+ }
+
+ if( !mbMedia )
+ {
+ // in case we have a plugin object
+ if( maParams.hasElements() )
+ {
+ xProps->setPropertyValue("PluginCommands", Any(maParams) );
+ }
+
+ if( !maMimeType.isEmpty() )
+ {
+ xProps->setPropertyValue("PluginMimeType", Any(maMimeType) );
+ }
+
+ if( !maHref.isEmpty() )
+ {
+ xProps->setPropertyValue("PluginURL", Any(maHref) );
+ }
+ }
+ else
+ {
+ // in case we have a media object
+ xProps->setPropertyValue( "MediaURL", uno::Any(maHref));
+
+ xProps->setPropertyValue("MediaMimeType", uno::Any(maMimeType) );
+
+ for( const auto& rParam : std::as_const(maParams) )
+ {
+ const OUString& rName = rParam.Name;
+
+ if( rName == "Loop" )
+ {
+ OUString aValueStr;
+ rParam.Value >>= aValueStr;
+ xProps->setPropertyValue("Loop",
+ uno::Any( aValueStr == "true" ) );
+ }
+ else if( rName == "Mute" )
+ {
+ OUString aValueStr;
+ rParam.Value >>= aValueStr;
+ xProps->setPropertyValue("Mute",
+ uno::Any( aValueStr == "true" ) );
+ }
+ else if( rName == "VolumeDB" )
+ {
+ OUString aValueStr;
+ rParam.Value >>= aValueStr;
+ xProps->setPropertyValue("VolumeDB",
+ uno::Any( static_cast< sal_Int16 >( aValueStr.toInt32() ) ) );
+ }
+ else if( rName == "Zoom" )
+ {
+ OUString aZoomStr;
+ media::ZoomLevel eZoomLevel;
+
+ rParam.Value >>= aZoomStr;
+
+ if( aZoomStr == "25%" )
+ eZoomLevel = media::ZoomLevel_ZOOM_1_TO_4;
+ else if( aZoomStr == "50%" )
+ eZoomLevel = media::ZoomLevel_ZOOM_1_TO_2;
+ else if( aZoomStr == "100%" )
+ eZoomLevel = media::ZoomLevel_ORIGINAL;
+ else if( aZoomStr == "200%" )
+ eZoomLevel = media::ZoomLevel_ZOOM_2_TO_1;
+ else if( aZoomStr == "400%" )
+ eZoomLevel = media::ZoomLevel_ZOOM_4_TO_1;
+ else if( aZoomStr == "fit" )
+ eZoomLevel = media::ZoomLevel_FIT_TO_WINDOW;
+ else if( aZoomStr == "fixedfit" )
+ eZoomLevel = media::ZoomLevel_FIT_TO_WINDOW_FIXED_ASPECT;
+ else if( aZoomStr == "fullscreen" )
+ eZoomLevel = media::ZoomLevel_FULLSCREEN;
+ else
+ eZoomLevel = media::ZoomLevel_NOT_AVAILABLE;
+
+ xProps->setPropertyValue("Zoom", uno::Any( eZoomLevel ) );
+ }
+ }
+ }
+
+ SetThumbnail();
+ }
+
+ SdXMLShapeContext::endFastElement(nElement);
+}
+
+css::uno::Reference< css::xml::sax::XFastContextHandler > SdXMLPluginShapeContext::createFastChildContext(
+ sal_Int32 nElement,
+ const css::uno::Reference< css::xml::sax::XFastAttributeList >& xAttrList )
+{
+ if( nElement == XML_ELEMENT(DRAW, XML_PARAM) )
+ {
+ OUString aParamName, aParamValue;
+ // now parse the attribute list and look for draw:name and draw:value
+ for( auto& aIter : sax_fastparser::castToFastAttributeList(xAttrList) )
+ {
+ if( aIter.getToken() == XML_ELEMENT(DRAW, XML_NAME) )
+ aParamName = aIter.toString();
+ else if( aIter.getToken() == XML_ELEMENT(DRAW, XML_VALUE) )
+ aParamValue = aIter.toString();
+ }
+
+ if( !aParamName.isEmpty() )
+ {
+ sal_Int32 nIndex = maParams.getLength();
+ maParams.realloc( nIndex + 1 );
+ auto pParams = maParams.getArray();
+ pParams[nIndex].Name = aParamName;
+ pParams[nIndex].Handle = -1;
+ pParams[nIndex].Value <<= aParamValue;
+ pParams[nIndex].State = beans::PropertyState_DIRECT_VALUE;
+ }
+
+ return new SvXMLImportContext( GetImport() );
+ }
+
+ return SdXMLShapeContext::createFastChildContext( nElement, xAttrList );
+}
+
+
+SdXMLFloatingFrameShapeContext::SdXMLFloatingFrameShapeContext( SvXMLImport& rImport,
+ const css::uno::Reference< css::xml::sax::XFastAttributeList>& xAttrList,
+ css::uno::Reference< css::drawing::XShapes > const & rShapes)
+: SdXMLShapeContext( rImport, xAttrList, rShapes, false/*bTemporaryShape*/ )
+{
+}
+
+SdXMLFloatingFrameShapeContext::~SdXMLFloatingFrameShapeContext()
+{
+}
+
+uno::Reference<drawing::XShape> SdXMLFloatingFrameShapeContext::CreateFloatingFrameShape() const
+{
+ uno::Reference<lang::XMultiServiceFactory> xServiceFact(GetImport().GetModel(), uno::UNO_QUERY);
+ if (!xServiceFact.is())
+ return nullptr;
+ uno::Reference<drawing::XShape> xShape(
+ xServiceFact->createInstance("com.sun.star.drawing.FrameShape"), uno::UNO_QUERY);
+ return xShape;
+}
+
+void SdXMLFloatingFrameShapeContext::startFastElement (sal_Int32 /*nElement*/,
+ const css::uno::Reference< css::xml::sax::XFastAttributeList >& /*xAttrList*/)
+{
+ uno::Reference<drawing::XShape> xShape(SdXMLFloatingFrameShapeContext::CreateFloatingFrameShape());
+
+ uno::Reference< beans::XPropertySet > xProps(xShape, uno::UNO_QUERY);
+ // set FrameURL before AddShape, we have to do it again later because it
+ // gets cleared when the SdrOle2Obj is attached to the XShape. But we want
+ // FrameURL to exist when AddShape triggers SetPersistName which itself
+ // triggers SdrOle2Obj::CheckFileLink_Impl and at that point we want to
+ // know what URL will end up being used. So bodge this by setting FrameURL
+ // to the temp pre-SdrOle2Obj attached properties and we can smuggle it
+ // eventually into SdrOle2Obj::SetPersistName at the right point after
+ // PersistName is set but before SdrOle2Obj::CheckFileLink_Impl is called
+ // in order to inform the link manager that this is an IFrame that links to
+ // a URL
+ if (xProps && !maHref.isEmpty())
+ xProps->setPropertyValue("FrameURL", Any(maHref));
+
+ AddShape(xShape);
+
+ if( !mxShape.is() )
+ return;
+
+ SetLayer();
+
+ // set pos, size, shear and rotate
+ SetTransformation();
+
+ if( xProps.is() )
+ {
+ if( !maFrameName.isEmpty() )
+ {
+ xProps->setPropertyValue("FrameName", Any(maFrameName) );
+ }
+
+ if( !maHref.isEmpty() )
+ {
+ if (INetURLObject(maHref).IsExoticProtocol())
+ GetImport().NotifyMacroEventRead();
+
+ xProps->setPropertyValue("FrameURL", Any(maHref) );
+ }
+ }
+
+ SetStyle();
+
+ GetImport().GetShapeImport()->finishShape( mxShape, mxAttrList, mxShapes );
+}
+
+// this is called from the parent group for each unparsed attribute in the attribute list
+bool SdXMLFloatingFrameShapeContext::processAttribute( const sax_fastparser::FastAttributeList::FastAttributeIter & aIter )
+{
+ switch( aIter.getToken() )
+ {
+ case XML_ELEMENT(DRAW, XML_FRAME_NAME):
+ maFrameName = aIter.toString();
+ break;
+ case XML_ELEMENT(XLINK, XML_HREF):
+ maHref = GetImport().GetAbsoluteReference(aIter.toString());
+ break;
+ default:
+ return SdXMLShapeContext::processAttribute( aIter );
+ }
+ return true;
+}
+
+void SdXMLFloatingFrameShapeContext::endFastElement(sal_Int32 nElement)
+{
+ uno::Reference< beans::XPropertySet > xProps( mxShape, uno::UNO_QUERY );
+
+ if( xProps.is() )
+ {
+ if ( maSize.Width && maSize.Height )
+ {
+ // the visual area for a floating frame must be set on loading
+ awt::Rectangle aRect( 0, 0, maSize.Width, maSize.Height );
+ xProps->setPropertyValue("VisibleArea", Any(aRect) );
+ }
+ }
+
+ SetThumbnail();
+ SdXMLShapeContext::endFastElement(nElement);
+}
+
+
+SdXMLFrameShapeContext::SdXMLFrameShapeContext( SvXMLImport& rImport,
+ const css::uno::Reference< css::xml::sax::XFastAttributeList>& xAttrList,
+ css::uno::Reference< css::drawing::XShapes > const & rShapes,
+ bool bTemporaryShape)
+: SdXMLShapeContext( rImport, xAttrList, rShapes, bTemporaryShape ),
+ mbSupportsReplacement( false )
+{
+ uno::Reference < util::XCloneable > xClone( xAttrList, uno::UNO_QUERY );
+ if( xClone.is() )
+ mxAttrList.set( xClone->createClone(), uno::UNO_QUERY );
+ else
+ mxAttrList = new sax_fastparser::FastAttributeList(xAttrList);
+}
+
+SdXMLFrameShapeContext::~SdXMLFrameShapeContext()
+{
+}
+
+void SdXMLFrameShapeContext::removeGraphicFromImportContext(const SvXMLImportContext& rContext)
+{
+ const SdXMLGraphicObjectShapeContext* pSdXMLGraphicObjectShapeContext = dynamic_cast< const SdXMLGraphicObjectShapeContext* >(&rContext);
+
+ if(!pSdXMLGraphicObjectShapeContext)
+ return;
+
+ try
+ {
+ uno::Reference< container::XChild > xChild(pSdXMLGraphicObjectShapeContext->getShape(), uno::UNO_QUERY_THROW);
+
+ uno::Reference< drawing::XShapes > xParent(xChild->getParent(), uno::UNO_QUERY_THROW);
+
+ // remove from parent
+ xParent->remove(pSdXMLGraphicObjectShapeContext->getShape());
+
+ // dispose
+ uno::Reference< lang::XComponent > xComp(pSdXMLGraphicObjectShapeContext->getShape(), UNO_QUERY);
+
+ if(xComp.is())
+ {
+ xComp->dispose();
+ }
+ }
+ catch( uno::Exception& )
+ {
+ DBG_UNHANDLED_EXCEPTION( "xmloff", "Error in cleanup of multiple graphic object import." );
+ }
+}
+
+namespace
+{
+uno::Reference<beans::XPropertySet> getGraphicPropertySetFromImportContext(const SvXMLImportContext& rContext)
+{
+ uno::Reference<beans::XPropertySet> aPropertySet;
+ const SdXMLGraphicObjectShapeContext* pSdXMLGraphicObjectShapeContext = dynamic_cast<const SdXMLGraphicObjectShapeContext*>(&rContext);
+
+ if (pSdXMLGraphicObjectShapeContext)
+ aPropertySet.set(pSdXMLGraphicObjectShapeContext->getShape(), uno::UNO_QUERY);
+
+ return aPropertySet;
+}
+
+} // end anonymous namespace
+
+uno::Reference<graphic::XGraphic> SdXMLFrameShapeContext::getGraphicFromImportContext(const SvXMLImportContext& rContext) const
+{
+ uno::Reference<graphic::XGraphic> xGraphic;
+ try
+ {
+ const uno::Reference<beans::XPropertySet> xPropertySet = getGraphicPropertySetFromImportContext(rContext);
+
+ if (xPropertySet.is())
+ {
+ xPropertySet->getPropertyValue("Graphic") >>= xGraphic;
+ }
+ }
+ catch( uno::Exception& )
+ {
+ DBG_UNHANDLED_EXCEPTION("xmloff", "Error in cleanup of multiple graphic object import.");
+ }
+
+ return xGraphic;
+}
+
+OUString SdXMLFrameShapeContext::getMimeTypeFromImportContext(const SvXMLImportContext& rContext) const
+{
+ OUString aMimeType;
+ const SdXMLGraphicObjectShapeContext* pSdXMLGraphicObjectShapeContext = dynamic_cast<const SdXMLGraphicObjectShapeContext*>(&rContext);
+
+ if (pSdXMLGraphicObjectShapeContext)
+ aMimeType = pSdXMLGraphicObjectShapeContext->getMimeType();
+ return aMimeType;
+}
+
+OUString SdXMLFrameShapeContext::getGraphicPackageURLFromImportContext(const SvXMLImportContext& rContext) const
+{
+ OUString aRetval;
+ const SdXMLGraphicObjectShapeContext* pSdXMLGraphicObjectShapeContext = dynamic_cast< const SdXMLGraphicObjectShapeContext* >(&rContext);
+
+ if(pSdXMLGraphicObjectShapeContext)
+ {
+ try
+ {
+ const uno::Reference< beans::XPropertySet > xPropSet(pSdXMLGraphicObjectShapeContext->getShape(), uno::UNO_QUERY_THROW);
+
+ xPropSet->getPropertyValue("GraphicStreamURL") >>= aRetval;
+ }
+ catch( uno::Exception& )
+ {
+ DBG_UNHANDLED_EXCEPTION( "xmloff", "Error in cleanup of multiple graphic object import." );
+ }
+ }
+
+ return aRetval;
+}
+
+css::uno::Reference< css::xml::sax::XFastContextHandler > SdXMLFrameShapeContext::createFastChildContext(
+ sal_Int32 nElement,
+ const uno::Reference< xml::sax::XFastAttributeList>& xAttrList )
+{
+ SvXMLImportContextRef xContext;
+ if( !mxImplContext.is() )
+ {
+ SvXMLShapeContext* pShapeContext = XMLShapeImportHelper::CreateFrameChildContext(
+ GetImport(), nElement, xAttrList, mxShapes, mxAttrList );
+
+ xContext = pShapeContext;
+
+ // propagate the hyperlink to child context
+ if ( !msHyperlink.isEmpty() )
+ pShapeContext->setHyperlink( msHyperlink );
+
+ auto nToken = nElement & TOKEN_MASK;
+ bool bMedia = false;
+ // Ignore gltf model if necessary and so the fallback image will be imported
+ if( nToken == XML_PLUGIN )
+ {
+ SdXMLPluginShapeContext* pPluginContext = dynamic_cast<SdXMLPluginShapeContext*>(pShapeContext);
+ if( pPluginContext && pPluginContext->getMimeType() == "model/vnd.gltf+json" )
+ {
+ mxImplContext = nullptr;
+ return new SvXMLImportContext(GetImport());
+ }
+ else if (pPluginContext && ::comphelper::IsMediaMimeType(pPluginContext->getMimeType()))
+ {
+ // The media may have a preview, import it.
+ bMedia = true;
+ }
+ }
+
+ mxImplContext = xContext;
+ mbSupportsReplacement = (nToken == XML_OBJECT ) || (nToken == XML_OBJECT_OLE) || bMedia;
+ setSupportsMultipleContents(nToken == XML_IMAGE);
+
+ if(getSupportsMultipleContents() && dynamic_cast< SdXMLGraphicObjectShapeContext* >(xContext.get()))
+ {
+ if ( !maShapeId.isEmpty() )
+ GetImport().getInterfaceToIdentifierMapper().reserveIdentifier( maShapeId );
+
+ addContent(*mxImplContext);
+ }
+ }
+ else if(getSupportsMultipleContents() && nElement == XML_ELEMENT(DRAW, XML_IMAGE))
+ {
+ // read another image
+ xContext = XMLShapeImportHelper::CreateFrameChildContext(
+ GetImport(), nElement, xAttrList, mxShapes, mxAttrList);
+ mxImplContext = xContext;
+
+ if(dynamic_cast< SdXMLGraphicObjectShapeContext* >(xContext.get()))
+ {
+ addContent(*mxImplContext);
+ }
+ }
+ else if( mbSupportsReplacement && !mxReplImplContext.is() &&
+ nElement == XML_ELEMENT(DRAW, XML_IMAGE) )
+ {
+ // read replacement image
+ SvXMLImportContext *pImplContext = mxImplContext.get();
+ SdXMLShapeContext *pSContext =
+ dynamic_cast<SdXMLShapeContext*>( pImplContext );
+ if( pSContext )
+ {
+ uno::Reference < beans::XPropertySet > xPropSet(
+ pSContext->getShape(), uno::UNO_QUERY );
+ if( xPropSet.is() )
+ {
+ xContext = new XMLReplacementImageContext( GetImport(),
+ nElement, xAttrList, xPropSet );
+ mxReplImplContext = xContext;
+ }
+ }
+ }
+ else if( nElement == XML_ELEMENT(SVG, XML_TITLE) || // #i68101#
+ nElement == XML_ELEMENT(SVG_COMPAT, XML_TITLE) ||
+ nElement == XML_ELEMENT(SVG, XML_DESC) ||
+ nElement == XML_ELEMENT(SVG_COMPAT, XML_DESC) ||
+ nElement == XML_ELEMENT(OFFICE, XML_EVENT_LISTENERS) ||
+ nElement == XML_ELEMENT(DRAW, XML_GLUE_POINT) ||
+ nElement == XML_ELEMENT(DRAW, XML_THUMBNAIL) )
+ {
+ if (getSupportsMultipleContents())
+ { // tdf#103567 ensure props are set on surviving shape
+ // note: no more draw:image can be added once we get here
+ mxImplContext = solveMultipleImages();
+ }
+ SvXMLImportContext *pImplContext = mxImplContext.get();
+ xContext = static_cast<SvXMLImportContext*>(dynamic_cast<SdXMLShapeContext&>(*pImplContext).createFastChildContext( nElement,
+ xAttrList ).get());
+ }
+ else if ( nElement == XML_ELEMENT(DRAW, XML_IMAGE_MAP) )
+ {
+ if (getSupportsMultipleContents())
+ { // tdf#103567 ensure props are set on surviving shape
+ // note: no more draw:image can be added once we get here
+ mxImplContext = solveMultipleImages();
+ }
+ SdXMLShapeContext *pSContext = dynamic_cast< SdXMLShapeContext* >( mxImplContext.get() );
+ if( pSContext )
+ {
+ uno::Reference < beans::XPropertySet > xPropSet( pSContext->getShape(), uno::UNO_QUERY );
+ if (xPropSet.is())
+ {
+ xContext = new XMLImageMapContext(GetImport(), xPropSet);
+ }
+ }
+ }
+ else if ( nElement == XML_ELEMENT(LO_EXT, XML_SIGNATURELINE) )
+ {
+ SdXMLShapeContext* pSContext = dynamic_cast<SdXMLShapeContext*>(mxImplContext.get());
+ if (pSContext)
+ {
+ uno::Reference<beans::XPropertySet> xPropSet(pSContext->getShape(), uno::UNO_QUERY);
+ if (xPropSet.is())
+ {
+ xContext = new SignatureLineContext(GetImport(), nElement, xAttrList,
+ pSContext->getShape());
+ }
+ }
+ }
+ else if ( nElement == XML_ELEMENT(LO_EXT, XML_QRCODE))
+ {
+ SdXMLShapeContext* pSContext = dynamic_cast<SdXMLShapeContext*>(mxImplContext.get());
+ if (pSContext)
+ {
+ uno::Reference<beans::XPropertySet> xPropSet(pSContext->getShape(), uno::UNO_QUERY);
+ if (xPropSet.is())
+ {
+ xContext = new QRCodeContext(GetImport(), nElement, xAttrList,
+ pSContext->getShape());
+ }
+ }
+ }
+
+ return xContext;
+}
+
+void SdXMLFrameShapeContext::startFastElement (sal_Int32 /*nElement*/,
+ const css::uno::Reference< css::xml::sax::XFastAttributeList >& /*xAttrList*/)
+{
+ // ignore
+}
+
+void SdXMLFrameShapeContext::endFastElement(sal_Int32 nElement)
+{
+ // solve if multiple image child contexts were imported
+ SvXMLImportContextRef const pSelectedContext(solveMultipleImages());
+ const SdXMLGraphicObjectShapeContext* pShapeContext(
+ dynamic_cast<const SdXMLGraphicObjectShapeContext*>(pSelectedContext.get()));
+ if ( pShapeContext )
+ {
+ assert( mxImplContext.is() );
+ const uno::Reference< uno::XInterface > xShape( pShapeContext->getShape() );
+ GetImport().getInterfaceToIdentifierMapper().registerReservedReference( maShapeId, xShape );
+ }
+
+ if( !mxImplContext.is() )
+ {
+ // now check if this is an empty presentation object
+ for( auto& aIter : sax_fastparser::castToFastAttributeList(mxAttrList) )
+ {
+ switch (aIter.getToken())
+ {
+ case XML_ELEMENT(PRESENTATION, XML_PLACEHOLDER):
+ mbIsPlaceholder = IsXMLToken( aIter, XML_TRUE );
+ break;
+ case XML_ELEMENT(PRESENTATION, XML_CLASS):
+ maPresentationClass = aIter.toString();
+ break;
+ default:;
+ }
+ }
+
+ if( (!maPresentationClass.isEmpty()) && mbIsPlaceholder )
+ {
+ uno::Reference< xml::sax::XFastAttributeList> xEmpty;
+
+ enum XMLTokenEnum eToken = XML_TEXT_BOX;
+
+ if( IsXMLToken( maPresentationClass, XML_GRAPHIC ) )
+ {
+ eToken = XML_IMAGE;
+
+ }
+ else if( IsXMLToken( maPresentationClass, XML_PAGE ) )
+ {
+ eToken = XML_PAGE_THUMBNAIL;
+ }
+ else if( IsXMLToken( maPresentationClass, XML_CHART ) ||
+ IsXMLToken( maPresentationClass, XML_TABLE ) ||
+ IsXMLToken( maPresentationClass, XML_OBJECT ) )
+ {
+ eToken = XML_OBJECT;
+ }
+
+ auto x = XML_ELEMENT(DRAW, eToken);
+ mxImplContext = XMLShapeImportHelper::CreateFrameChildContext(
+ GetImport(), x, mxAttrList, mxShapes, xEmpty );
+
+ if( mxImplContext.is() )
+ {
+ mxImplContext->startFastElement( x, mxAttrList );
+ mxImplContext->endFastElement(x);
+ }
+ }
+ }
+
+ mxImplContext = nullptr;
+ SdXMLShapeContext::endFastElement(nElement);
+}
+
+bool SdXMLFrameShapeContext::processAttribute( const sax_fastparser::FastAttributeList::FastAttributeIter & aIter )
+{
+ bool bId( false );
+
+ switch ( aIter.getToken() )
+ {
+ case XML_ELEMENT(DRAW, XML_ID):
+ case XML_ELEMENT(DRAW_EXT, XML_ID):
+ case XML_ELEMENT(NONE, XML_ID):
+ case XML_ELEMENT(XML, XML_ID) :
+ bId = true;
+ break;
+ default:;
+ }
+
+ if ( bId )
+ return SdXMLShapeContext::processAttribute( aIter );
+ return true; // deliberately ignoring other attributes
+}
+
+
+SdXMLCustomShapeContext::SdXMLCustomShapeContext(
+ SvXMLImport& rImport,
+ const css::uno::Reference< css::xml::sax::XFastAttributeList>& xAttrList,
+ uno::Reference< drawing::XShapes > const & rShapes)
+: SdXMLShapeContext( rImport, xAttrList, rShapes, false/*bTemporaryShape*/ )
+{
+ // See the XMLTextFrameContext ctor, a frame has Writer content (and not
+ // editeng) if its autostyle has a parent style. Do the same for shapes as well.
+ for( auto& aIter : sax_fastparser::castToFastAttributeList(xAttrList) )
+ {
+ if (aIter.getToken() == XML_ELEMENT(DRAW, XML_STYLE_NAME))
+ {
+ OUString aStyleName = aIter.toString();
+ if(!aStyleName.isEmpty())
+ {
+ rtl::Reference<XMLTextImportHelper> xTxtImport = GetImport().GetTextImport();
+ XMLPropStyleContext* pStyle = xTxtImport->FindAutoFrameStyle(aStyleName);
+ // Note that this an API name, so intentionally not localized.
+ // Also allow other Frame styles with the same prefix, we just want to reject
+ // Graphics after all.
+ if (pStyle && pStyle->GetParentName().startsWith("Frame"))
+ {
+ mbTextBox = true;
+ break;
+ }
+ }
+ }
+ }
+}
+
+SdXMLCustomShapeContext::~SdXMLCustomShapeContext()
+{
+}
+
+// this is called from the parent group for each unparsed attribute in the attribute list
+bool SdXMLCustomShapeContext::processAttribute( const sax_fastparser::FastAttributeList::FastAttributeIter & aIter )
+{
+ if( aIter.getToken() == XML_ELEMENT(DRAW, XML_ENGINE) )
+ {
+ maCustomShapeEngine = aIter.toString();
+ }
+ else if (aIter.getToken() == XML_ELEMENT(DRAW, XML_DATA) )
+ {
+ maCustomShapeData = aIter.toString();
+ }
+ else
+ return SdXMLShapeContext::processAttribute( aIter );
+ return true;
+}
+
+void SdXMLCustomShapeContext::startFastElement (sal_Int32 nElement,
+ const css::uno::Reference< css::xml::sax::XFastAttributeList >& xAttrList)
+{
+ // create rectangle shape
+ AddShape("com.sun.star.drawing.CustomShape");
+ if ( !mxShape.is() )
+ return;
+
+ // Add, set Style and properties from base shape
+ SetStyle();
+ SetLayer();
+
+ // set pos, size, shear and rotate
+ SetTransformation();
+
+ try
+ {
+ uno::Reference< beans::XPropertySet > xPropSet( mxShape, uno::UNO_QUERY );
+ if( xPropSet.is() )
+ {
+ if ( !maCustomShapeEngine.isEmpty() )
+ {
+ xPropSet->setPropertyValue( EASGet( EAS_CustomShapeEngine ), Any(maCustomShapeEngine) );
+ }
+ if ( !maCustomShapeData.isEmpty() )
+ {
+ xPropSet->setPropertyValue( EASGet( EAS_CustomShapeData ), Any(maCustomShapeData) );
+ }
+ }
+ }
+ catch(const uno::Exception&)
+ {
+ DBG_UNHANDLED_EXCEPTION( "xmloff", "setting enhanced customshape geometry" );
+ }
+ SdXMLShapeContext::startFastElement(nElement, xAttrList);
+}
+
+void SdXMLCustomShapeContext::endFastElement(sal_Int32 nElement)
+{
+ // Customshapes remember mirror state in its enhanced geometry.
+ // SetTransformation() in StartElement() may have applied mirroring, but that is not yet
+ // contained. Merge that information here before writing the property.
+ if(!maUsedTransformation.isIdentity())
+ {
+ basegfx::B2DVector aScale, aTranslate;
+ double fRotate, fShearX;
+
+ maUsedTransformation.decompose(aScale, aTranslate, fRotate, fShearX);
+
+ if (aScale.getX() < 0.0)
+ {
+ static constexpr OUString sName(u"MirroredX"_ustr);
+ //fdo#84043 Merge, if property exists, otherwise append it
+ auto aI = std::find_if(maCustomShapeGeometry.begin(), maCustomShapeGeometry.end(),
+ [](beans::PropertyValue& rValue) { return rValue.Name == sName; });
+ if (aI != maCustomShapeGeometry.end())
+ {
+ beans::PropertyValue& rItem = *aI;
+ bool bMirroredX = *o3tl::doAccess<bool>(rItem.Value);
+ rItem.Value <<= !bMirroredX;
+ rItem.Handle = -1;
+ rItem.State = beans::PropertyState_DIRECT_VALUE;
+ }
+ else
+ {
+ beans::PropertyValue* pItem;
+ maCustomShapeGeometry.emplace_back();
+ pItem = &maCustomShapeGeometry.back();
+ pItem->Name = sName;
+ pItem->Handle = -1;
+ pItem->Value <<= true;
+ pItem->State = beans::PropertyState_DIRECT_VALUE;
+ }
+ }
+
+ if (aScale.getY() < 0.0)
+ {
+ static constexpr OUString sName(u"MirroredY"_ustr);
+ //fdo#84043 Merge, if property exists, otherwise append it
+ auto aI = std::find_if(maCustomShapeGeometry.begin(), maCustomShapeGeometry.end(),
+ [](beans::PropertyValue& rValue) { return rValue.Name == sName; });
+ if (aI != maCustomShapeGeometry.end())
+ {
+ beans::PropertyValue& rItem = *aI;
+ bool bMirroredY = *o3tl::doAccess<bool>(rItem.Value);
+ rItem.Value <<= !bMirroredY;
+ rItem.Handle = -1;
+ rItem.State = beans::PropertyState_DIRECT_VALUE;
+ }
+ else
+ {
+ beans::PropertyValue* pItem;
+ maCustomShapeGeometry.emplace_back();
+ pItem = &maCustomShapeGeometry.back();
+ pItem->Name = sName;
+ pItem->Handle = -1;
+ pItem->Value <<= true;
+ pItem->State = beans::PropertyState_DIRECT_VALUE;
+ }
+ }
+ }
+
+ if ( !maCustomShapeGeometry.empty() )
+ {
+ // converting the vector to a sequence
+ uno::Sequence< beans::PropertyValue > aSeq( comphelper::containerToSequence(maCustomShapeGeometry) );
+
+ try
+ {
+ uno::Reference< beans::XPropertySet > xPropSet( mxShape, uno::UNO_QUERY );
+ if( xPropSet.is() )
+ {
+ xPropSet->setPropertyValue( "CustomShapeGeometry", Any(aSeq) );
+ }
+ }
+ catch(const uno::Exception&)
+ {
+ DBG_UNHANDLED_EXCEPTION( "xmloff", "setting enhanced customshape geometry" );
+ }
+
+ sal_Int32 nUPD;
+ sal_Int32 nBuild;
+ if (GetImport().getBuildIds(nUPD, nBuild))
+ {
+ if( ((nUPD >= 640 && nUPD <= 645) || (nUPD == 680)) && (nBuild <= 9221) )
+ {
+ Reference< drawing::XEnhancedCustomShapeDefaulter > xDefaulter( mxShape, UNO_QUERY );
+ if( xDefaulter.is() )
+ {
+ xDefaulter->createCustomShapeDefaults( "" );
+ }
+ }
+ }
+ }
+
+ SdXMLShapeContext::endFastElement(nElement);
+
+ // tdf#98163 call a custom slot to be able to reset the UNO API
+ // implementations held on the SdrObjects of type
+ // SdrObjCustomShape - those tend to linger until the entire file
+ // is loaded. For large files with a lot of these, 32bit systems
+ // may crash due to being out of resources after ca. 4200
+ // Outliners and VirtualDevices used there as RefDevice
+ try
+ {
+ uno::Reference< beans::XPropertySet > xPropSet(mxShape, uno::UNO_QUERY);
+
+ if(xPropSet.is())
+ {
+ xPropSet->setPropertyValue(
+ "FlushCustomShapeUnoApiObjects", css::uno::Any(true));
+ }
+ }
+ catch(const uno::Exception&)
+ {
+ DBG_UNHANDLED_EXCEPTION("xmloff", "flushing after load");
+ }
+}
+
+css::uno::Reference< css::xml::sax::XFastContextHandler > SdXMLCustomShapeContext::createFastChildContext(
+ sal_Int32 nElement,
+ const uno::Reference< xml::sax::XFastAttributeList>& xAttrList )
+{
+ css::uno::Reference< css::xml::sax::XFastContextHandler > xContext;
+ if ( nElement == XML_ELEMENT(DRAW, XML_ENHANCED_GEOMETRY) )
+ {
+ uno::Reference< beans::XPropertySet > xPropSet( mxShape,uno::UNO_QUERY );
+ if ( xPropSet.is() )
+ xContext = new XMLEnhancedCustomShapeContext( GetImport(), mxShape, maCustomShapeGeometry );
+ }
+ // delegate to parent class if no context could be created
+ if (!xContext)
+ xContext = SdXMLShapeContext::createFastChildContext( nElement,
+ xAttrList);
+ return xContext;
+}
+
+SdXMLTableShapeContext::SdXMLTableShapeContext( SvXMLImport& rImport, const css::uno::Reference< css::xml::sax::XFastAttributeList>& xAttrList, css::uno::Reference< css::drawing::XShapes > const & rShapes )
+: SdXMLShapeContext( rImport, xAttrList, rShapes, false )
+{
+}
+
+SdXMLTableShapeContext::~SdXMLTableShapeContext()
+{
+}
+
+void SdXMLTableShapeContext::startFastElement (sal_Int32 nElement,
+ const css::uno::Reference< css::xml::sax::XFastAttributeList >& xAttrList)
+{
+ OUString service("com.sun.star.drawing.TableShape");
+
+ bool bIsPresShape = !maPresentationClass.isEmpty() && GetImport().GetShapeImport()->IsPresentationShapesSupported();
+ if( bIsPresShape )
+ {
+ if( IsXMLToken( maPresentationClass, XML_TABLE ) )
+ {
+ service = "com.sun.star.presentation.TableShape";
+ }
+ }
+
+ AddShape(service);
+
+ if( !mxShape.is() )
+ return;
+
+ SetLayer();
+
+ uno::Reference< beans::XPropertySet > xProps(mxShape, uno::UNO_QUERY);
+
+ if(bIsPresShape && xProps.is())
+ {
+ uno::Reference< beans::XPropertySetInfo > xPropsInfo( xProps->getPropertySetInfo() );
+ if( xPropsInfo.is() )
+ {
+ if( !mbIsPlaceholder && xPropsInfo->hasPropertyByName("IsEmptyPresentationObject"))
+ xProps->setPropertyValue("IsEmptyPresentationObject", css::uno::Any(false) );
+
+ if( mbIsUserTransformed && xPropsInfo->hasPropertyByName("IsPlaceholderDependent"))
+ xProps->setPropertyValue("IsPlaceholderDependent", css::uno::Any(false) );
+ }
+ }
+
+ SetStyle();
+
+ if( xProps.is() )
+ {
+ if( !msTemplateStyleName.isEmpty() ) try
+ {
+ Reference< XStyleFamiliesSupplier > xFamiliesSupp( GetImport().GetModel(), UNO_QUERY_THROW );
+ Reference< XNameAccess > xFamilies( xFamiliesSupp->getStyleFamilies() );
+ Reference< XNameAccess > xTableFamily( xFamilies->getByName( "table" ), UNO_QUERY_THROW );
+ Reference< XStyle > xTableStyle( xTableFamily->getByName( msTemplateStyleName ), UNO_QUERY_THROW );
+ xProps->setPropertyValue("TableTemplate", Any( xTableStyle ) );
+ }
+ catch(const Exception&)
+ {
+ DBG_UNHANDLED_EXCEPTION("xmloff.draw");
+ }
+
+ const XMLPropertyMapEntry* pEntry = &aXMLTableShapeAttributes[0];
+ for( int i = 0; !pEntry->IsEnd() && (i < 6); i++, pEntry++ )
+ {
+ try
+ {
+ xProps->setPropertyValue( pEntry->getApiName(), Any( maTemplateStylesUsed[i] ) );
+ }
+ catch(const Exception&)
+ {
+ DBG_UNHANDLED_EXCEPTION("xmloff.draw");
+ }
+ }
+ }
+
+ GetImport().GetShapeImport()->finishShape( mxShape, mxAttrList, mxShapes );
+
+ const rtl::Reference< XMLTableImport >& xTableImport( GetImport().GetShapeImport()->GetShapeTableImport() );
+ if( xTableImport.is() && xProps.is() )
+ {
+ uno::Reference< table::XColumnRowRange > xColumnRowRange(
+ xProps->getPropertyValue("Model"), uno::UNO_QUERY );
+
+ if( xColumnRowRange.is() )
+ mxTableImportContext = xTableImport->CreateTableContext( xColumnRowRange );
+
+ if( mxTableImportContext.is() )
+ mxTableImportContext->startFastElement( nElement, xAttrList );
+ }
+}
+
+void SdXMLTableShapeContext::endFastElement(sal_Int32 nElement)
+{
+ if( mxTableImportContext.is() )
+ mxTableImportContext->endFastElement(nElement);
+
+ SdXMLShapeContext::endFastElement(nElement);
+
+ if( mxShape.is() )
+ {
+ // set pos, size, shear and rotate
+ SetTransformation();
+ }
+}
+
+// this is called from the parent group for each unparsed attribute in the attribute list
+bool SdXMLTableShapeContext::processAttribute( const sax_fastparser::FastAttributeList::FastAttributeIter & aIter )
+{
+ auto nElement = aIter.getToken();
+ if( IsTokenInNamespace(nElement, XML_NAMESPACE_TABLE) )
+ {
+ if( (nElement & TOKEN_MASK) == XML_TEMPLATE_NAME )
+ {
+ msTemplateStyleName = aIter.toString();
+ }
+ else
+ {
+ int i = 0;
+ const XMLPropertyMapEntry* pEntry = &aXMLTableShapeAttributes[0];
+ while( !pEntry->IsEnd() && (i < 6) )
+ {
+ if( (nElement & TOKEN_MASK) == pEntry->meXMLName )
+ {
+ if( IsXMLToken( aIter, XML_TRUE ) )
+ maTemplateStylesUsed[i] = true;
+ break;
+ }
+ pEntry++;
+ i++;
+ }
+ }
+ }
+ return SdXMLShapeContext::processAttribute( aIter );
+}
+
+css::uno::Reference< css::xml::sax::XFastContextHandler > SdXMLTableShapeContext::createFastChildContext(
+ sal_Int32 nElement,
+ const css::uno::Reference< css::xml::sax::XFastAttributeList >& xAttrList )
+{
+ if( mxTableImportContext.is() && IsTokenInNamespace(nElement, XML_NAMESPACE_TABLE) )
+ return mxTableImportContext->createFastChildContext(nElement, xAttrList);
+ return SdXMLShapeContext::createFastChildContext(nElement, xAttrList);
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/xmloff/source/draw/ximpshap.hxx b/xmloff/source/draw/ximpshap.hxx
new file mode 100644
index 0000000000..9a61f4b594
--- /dev/null
+++ b/xmloff/source/draw/ximpshap.hxx
@@ -0,0 +1,648 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#pragma once
+
+#include <com/sun/star/io/XOutputStream.hpp>
+#include <com/sun/star/document/XActionLockable.hpp>
+#include <com/sun/star/drawing/Alignment.hpp>
+#include <com/sun/star/drawing/CircleKind.hpp>
+#include <com/sun/star/drawing/ConnectorType.hpp>
+#include <com/sun/star/drawing/EscapeDirection.hpp>
+#include <com/sun/star/container/XIdentifierContainer.hpp>
+#include <xmloff/xmlictxt.hxx>
+#include <com/sun/star/drawing/XShapes.hpp>
+#include <com/sun/star/text/XTextCursor.hpp>
+#include <com/sun/star/awt/Point.hpp>
+#include <xexptran.hxx>
+#include <vector>
+#include <xmloff/shapeimport.hxx>
+#include <xmlmultiimagehelper.hxx>
+#include <basegfx/matrix/b2dhommatrix.hxx>
+
+template<typename EnumT> struct SvXMLEnumMapEntry;
+
+// common shape context
+
+class SdXMLShapeContext : public SvXMLShapeContext
+{
+protected:
+ // the shape group this object should be created inside
+ css::uno::Reference< css::drawing::XShapes > mxShapes;
+ css::uno::Reference< css::text::XTextCursor > mxCursor;
+ css::uno::Reference< css::text::XTextCursor > mxOldCursor;
+ css::uno::Reference< css::xml::sax::XFastAttributeList> mxAttrList;
+ css::uno::Reference< css::container::XIdentifierContainer > mxGluePoints;
+ css::uno::Reference< css::document::XActionLockable > mxLockable;
+
+ OUString maDrawStyleName;
+ OUString maTextStyleName;
+ OUString maPresentationClass;
+ OUString maShapeName;
+ OUString maThumbnailURL;
+
+ /// whether to restore list context (#91964#)
+ bool mbListContextPushed;
+
+ XmlStyleFamily mnStyleFamily;
+ bool mbIsPlaceholder;
+ bool mbClearDefaultAttributes;
+ bool mbIsUserTransformed;
+ sal_Int32 mnZOrder;
+ OUString maShapeId;
+ OUString maLayerName;
+
+ SdXMLImExTransform2D mnTransform;
+ css::awt::Size maSize;
+ sal_Int16 mnRelWidth;
+ sal_Int16 mnRelHeight;
+ css::awt::Point maPosition;
+ basegfx::B2DHomMatrix maUsedTransformation;
+
+ bool mbVisible;
+ bool mbPrintable;
+ bool mbHaveXmlId;
+ bool mbTextBox; ///< If the text of this shape is handled by a Writer TextFrame.
+
+ /** if bSupportsStyle is false, auto styles will be set but not a style */
+ void SetStyle( bool bSupportsStyle = true );
+ void SetLayer();
+ void SetThumbnail();
+
+ void AddShape(css::uno::Reference< css::drawing::XShape >& xShape);
+ void AddShape(OUString const & serviceName);
+ void SetTransformation();
+
+ using SvXMLImportContext::GetImport;
+
+ void addGluePoint( const css::uno::Reference< css::xml::sax::XFastAttributeList>& xAttrList );
+
+ bool isPresentationShape() const;
+
+public:
+
+ SdXMLShapeContext( SvXMLImport& rImport,
+ css::uno::Reference< css::xml::sax::XFastAttributeList> xAttrList,
+ css::uno::Reference< css::drawing::XShapes > xShapes,
+ bool bTemporaryShape);
+ virtual ~SdXMLShapeContext() override;
+
+ virtual void SAL_CALL startFastElement(
+ sal_Int32 nElement,
+ const css::uno::Reference< css::xml::sax::XFastAttributeList >& xAttrList ) override;
+ virtual void SAL_CALL endFastElement(sal_Int32 nElement) override;
+ virtual css::uno::Reference< css::xml::sax::XFastContextHandler > SAL_CALL createFastChildContext(
+ sal_Int32 nElement, const css::uno::Reference< css::xml::sax::XFastAttributeList >& AttrList ) override;
+
+ // this is called from the parent group for each unparsed attribute in the attribute list
+ virtual bool processAttribute( const sax_fastparser::FastAttributeList::FastAttributeIter & );
+
+};
+
+// draw:rect context
+
+class SdXMLRectShapeContext : public SdXMLShapeContext
+{
+ sal_Int32 mnRadius;
+
+public:
+
+ SdXMLRectShapeContext( SvXMLImport& rImport,
+ const css::uno::Reference< css::xml::sax::XFastAttributeList>& xAttrList,
+ css::uno::Reference< css::drawing::XShapes > const & rShapes,
+ bool bTemporaryShape);
+ virtual ~SdXMLRectShapeContext() override;
+ virtual void SAL_CALL startFastElement(
+ sal_Int32 nElement,
+ const css::uno::Reference< css::xml::sax::XFastAttributeList >& xAttrList ) override;
+
+ // this is called from the parent group for each unparsed attribute in the attribute list
+ virtual bool processAttribute( const sax_fastparser::FastAttributeList::FastAttributeIter & ) override;
+};
+
+// draw:line context
+
+class SdXMLLineShapeContext : public SdXMLShapeContext
+{
+ sal_Int32 mnX1;
+ sal_Int32 mnY1;
+ sal_Int32 mnX2;
+ sal_Int32 mnY2;
+
+public:
+
+ SdXMLLineShapeContext( SvXMLImport& rImport,
+ const css::uno::Reference< css::xml::sax::XFastAttributeList>& xAttrList,
+ css::uno::Reference< css::drawing::XShapes > const & rShapes,
+ bool bTemporaryShape);
+ virtual ~SdXMLLineShapeContext() override;
+ virtual void SAL_CALL startFastElement(
+ sal_Int32 nElement,
+ const css::uno::Reference< css::xml::sax::XFastAttributeList >& xAttrList ) override;
+
+ // this is called from the parent group for each unparsed attribute in the attribute list
+ virtual bool processAttribute( const sax_fastparser::FastAttributeList::FastAttributeIter & ) override;
+};
+
+// draw:ellipse and draw:circle context
+
+class SdXMLEllipseShapeContext : public SdXMLShapeContext
+{
+ sal_Int32 mnCX;
+ sal_Int32 mnCY;
+ sal_Int32 mnRX;
+ sal_Int32 mnRY;
+
+ css::drawing::CircleKind meKind;
+ sal_Int32 mnStartAngle;
+ sal_Int32 mnEndAngle;
+public:
+
+ SdXMLEllipseShapeContext( SvXMLImport& rImport,
+ const css::uno::Reference< css::xml::sax::XFastAttributeList>& xAttrList,
+ css::uno::Reference< css::drawing::XShapes > const & rShapes,
+ bool bTemporaryShape);
+ virtual ~SdXMLEllipseShapeContext() override;
+ virtual void SAL_CALL startFastElement(
+ sal_Int32 nElement,
+ const css::uno::Reference< css::xml::sax::XFastAttributeList >& xAttrList ) override;
+
+ // this is called from the parent group for each unparsed attribute in the attribute list
+ virtual bool processAttribute( const sax_fastparser::FastAttributeList::FastAttributeIter & ) override;
+};
+
+// draw:polyline and draw:polygon context
+
+class SdXMLPolygonShapeContext : public SdXMLShapeContext
+{
+ OUString maPoints;
+ OUString maViewBox;
+ bool mbClosed;
+
+public:
+
+ SdXMLPolygonShapeContext( SvXMLImport& rImport,
+ const css::uno::Reference< css::xml::sax::XFastAttributeList>& xAttrList,
+ css::uno::Reference< css::drawing::XShapes > const & rShapes, bool bClosed, bool bTemporaryShape);
+ virtual ~SdXMLPolygonShapeContext() override;
+ virtual void SAL_CALL startFastElement(
+ sal_Int32 nElement,
+ const css::uno::Reference< css::xml::sax::XFastAttributeList >& xAttrList ) override;
+
+ // this is called from the parent group for each unparsed attribute in the attribute list
+ virtual bool processAttribute( const sax_fastparser::FastAttributeList::FastAttributeIter & ) override;
+};
+
+// draw:path context
+
+class SdXMLPathShapeContext : public SdXMLShapeContext
+{
+ OUString maD;
+ OUString maViewBox;
+
+public:
+
+ SdXMLPathShapeContext( SvXMLImport& rImport,
+ const css::uno::Reference< css::xml::sax::XFastAttributeList>& xAttrList,
+ css::uno::Reference< css::drawing::XShapes > const & rShapes,
+ bool bTemporaryShape);
+ virtual ~SdXMLPathShapeContext() override;
+ virtual void SAL_CALL startFastElement(
+ sal_Int32 nElement,
+ const css::uno::Reference< css::xml::sax::XFastAttributeList >& xAttrList ) override;
+
+ // this is called from the parent group for each unparsed attribute in the attribute list
+ virtual bool processAttribute( const sax_fastparser::FastAttributeList::FastAttributeIter & ) override;
+};
+
+// draw:text-box context
+
+class SdXMLTextBoxShapeContext : public SdXMLShapeContext
+{
+ sal_Int32 mnRadius;
+ OUString maChainNextName;
+
+public:
+
+ SdXMLTextBoxShapeContext( SvXMLImport& rImport,
+ const css::uno::Reference< css::xml::sax::XFastAttributeList>& xAttrList,
+ css::uno::Reference< css::drawing::XShapes > const & rShapes);
+ virtual ~SdXMLTextBoxShapeContext() override;
+ virtual void SAL_CALL startFastElement(
+ sal_Int32 nElement,
+ const css::uno::Reference< css::xml::sax::XFastAttributeList >& xAttrList ) override;
+
+ // this is called from the parent group for each unparsed attribute in the attribute list
+ virtual bool processAttribute( const sax_fastparser::FastAttributeList::FastAttributeIter & ) override;
+};
+
+// draw:control context
+
+class SdXMLControlShapeContext : public SdXMLShapeContext
+{
+private:
+ OUString maFormId;
+
+public:
+
+ SdXMLControlShapeContext( SvXMLImport& rImport,
+ const css::uno::Reference< css::xml::sax::XFastAttributeList>& xAttrList,
+ css::uno::Reference< css::drawing::XShapes > const & rShapes,
+ bool bTemporaryShape);
+ virtual ~SdXMLControlShapeContext() override;
+ virtual void SAL_CALL startFastElement(
+ sal_Int32 nElement,
+ const css::uno::Reference< css::xml::sax::XFastAttributeList >& xAttrList ) override;
+
+ // this is called from the parent group for each unparsed attribute in the attribute list
+ virtual bool processAttribute( const sax_fastparser::FastAttributeList::FastAttributeIter & ) override;
+};
+
+// draw:connector context
+
+class SdXMLConnectorShapeContext : public SdXMLShapeContext
+{
+private:
+ css::awt::Point maStart;
+ css::awt::Point maEnd;
+
+ css::drawing::ConnectorType
+ mnType;
+
+ OUString maStartShapeId;
+ sal_Int32 mnStartGlueId;
+ OUString maEndShapeId;
+ sal_Int32 mnEndGlueId;
+
+ sal_Int32 mnDelta1;
+ sal_Int32 mnDelta2;
+ sal_Int32 mnDelta3;
+
+ css::uno::Any maPath;
+
+ // Guess from the svg:d attribute whether the shape was rendered using OOXML definition. The
+ // default value is true to cover files exported to ODF by MS Office, which does not write a
+ // svg:d attribute. LibreOffice has always written a svg:d attribute.
+ bool mbLikelyOOXMLCurve;
+
+public:
+
+ SdXMLConnectorShapeContext( SvXMLImport& rImport,
+ const css::uno::Reference< css::xml::sax::XFastAttributeList>& xAttrList,
+ css::uno::Reference< css::drawing::XShapes > const & rShapes,
+ bool bTemporaryShape);
+ virtual ~SdXMLConnectorShapeContext() override;
+ virtual void SAL_CALL startFastElement(
+ sal_Int32 nElement,
+ const css::uno::Reference< css::xml::sax::XFastAttributeList >& xAttrList ) override;
+
+ // this is called from the parent group for each unparsed attribute in the attribute list
+ virtual bool processAttribute( const sax_fastparser::FastAttributeList::FastAttributeIter & ) override;
+};
+
+// draw:measure context
+
+class SdXMLMeasureShapeContext : public SdXMLShapeContext
+{
+private:
+ css::awt::Point maStart;
+ css::awt::Point maEnd;
+
+public:
+
+ SdXMLMeasureShapeContext( SvXMLImport& rImport,
+ const css::uno::Reference< css::xml::sax::XFastAttributeList>& xAttrList,
+ css::uno::Reference< css::drawing::XShapes > const & rShapes,
+ bool bTemporaryShape);
+ virtual ~SdXMLMeasureShapeContext() override;
+ virtual void SAL_CALL startFastElement(
+ sal_Int32 nElement,
+ const css::uno::Reference< css::xml::sax::XFastAttributeList >& xAttrList ) override;
+ virtual void SAL_CALL endFastElement(sal_Int32 nElement) override;
+
+ // this is called from the parent group for each unparsed attribute in the attribute list
+ virtual bool processAttribute( const sax_fastparser::FastAttributeList::FastAttributeIter & ) override;
+};
+
+// draw:page context
+
+class SdXMLPageShapeContext : public SdXMLShapeContext
+{
+private:
+ sal_Int32 mnPageNumber;
+public:
+
+ SdXMLPageShapeContext( SvXMLImport& rImport,
+ const css::uno::Reference< css::xml::sax::XFastAttributeList>& xAttrList,
+ css::uno::Reference< css::drawing::XShapes > const & rShapes,
+ bool bTemporaryShape);
+ virtual ~SdXMLPageShapeContext() override;
+ virtual void SAL_CALL startFastElement(
+ sal_Int32 nElement,
+ const css::uno::Reference< css::xml::sax::XFastAttributeList >& xAttrList ) override;
+
+ // this is called from the parent group for each unparsed attribute in the attribute list
+ virtual bool processAttribute( const sax_fastparser::FastAttributeList::FastAttributeIter & ) override;
+};
+
+// draw:caption context
+
+class SdXMLCaptionShapeContext : public SdXMLShapeContext
+{
+private:
+ css::awt::Point maCaptionPoint;
+ sal_Int32 mnRadius;
+
+public:
+
+ SdXMLCaptionShapeContext( SvXMLImport& rImport,
+ const css::uno::Reference< css::xml::sax::XFastAttributeList>& xAttrList,
+ css::uno::Reference< css::drawing::XShapes > const & rShapes,
+ bool bTemporaryShape);
+ virtual ~SdXMLCaptionShapeContext() override;
+ virtual void SAL_CALL startFastElement(
+ sal_Int32 nElement,
+ const css::uno::Reference< css::xml::sax::XFastAttributeList >& xAttrList ) override;
+
+ // this is called from the parent group for each unparsed attribute in the attribute list
+ virtual bool processAttribute( const sax_fastparser::FastAttributeList::FastAttributeIter & ) override;
+};
+
+// office:image context
+
+class SdXMLGraphicObjectShapeContext : public SdXMLShapeContext
+{
+private:
+ OUString maURL;
+ OUString msMimeType;
+ css::uno::Reference < css::io::XOutputStream > mxBase64Stream;
+
+public:
+ OUString const& getMimeType() const { return msMimeType; }
+
+ SdXMLGraphicObjectShapeContext( SvXMLImport& rImport,
+ const css::uno::Reference< css::xml::sax::XFastAttributeList>& xAttrList,
+ css::uno::Reference< css::drawing::XShapes > const & rShapes);
+ virtual ~SdXMLGraphicObjectShapeContext() override;
+
+ virtual void SAL_CALL startFastElement(
+ sal_Int32 nElement,
+ const css::uno::Reference< css::xml::sax::XFastAttributeList >& xAttrList ) override;
+ virtual void SAL_CALL endFastElement(sal_Int32 nElement) override;
+ virtual css::uno::Reference< css::xml::sax::XFastContextHandler > SAL_CALL createFastChildContext(
+ sal_Int32 nElement,
+ const css::uno::Reference< css::xml::sax::XFastAttributeList >& xAttrList ) override;
+
+ // this is called from the parent group for each unparsed attribute in the attribute list
+ virtual bool processAttribute( const sax_fastparser::FastAttributeList::FastAttributeIter & ) override;
+};
+
+// chart:chart context
+
+class SdXMLChartShapeContext : public SdXMLShapeContext
+{
+ SvXMLImportContextRef mxChartContext;
+
+public:
+
+ SdXMLChartShapeContext( SvXMLImport& rImport,
+ const css::uno::Reference< css::xml::sax::XFastAttributeList>& xAttrList,
+ css::uno::Reference< css::drawing::XShapes > const & rShapes,
+ bool bTemporaryShape);
+
+ virtual void SAL_CALL startFastElement(
+ sal_Int32 nElement,
+ const css::uno::Reference< css::xml::sax::XFastAttributeList >& xAttrList ) override;
+ virtual void SAL_CALL endFastElement(sal_Int32 nElement) override;
+ virtual void SAL_CALL characters( const OUString& rChars ) override;
+ virtual css::uno::Reference< css::xml::sax::XFastContextHandler > SAL_CALL createFastChildContext(
+ sal_Int32 nElement, const css::uno::Reference< css::xml::sax::XFastAttributeList >& AttrList ) override;
+};
+
+// draw:object and draw:object_ole context
+
+class SdXMLObjectShapeContext : public SdXMLShapeContext
+{
+private:
+ OUString maCLSID;
+ OUString maHref;
+
+ css::uno::Reference < css::io::XOutputStream > mxBase64Stream;
+
+public:
+
+ SdXMLObjectShapeContext( SvXMLImport& rImport,
+ const css::uno::Reference< css::xml::sax::XFastAttributeList>& xAttrList,
+ css::uno::Reference< css::drawing::XShapes > const & rShapes);
+ virtual ~SdXMLObjectShapeContext() override;
+
+ virtual void SAL_CALL startFastElement(
+ sal_Int32 nElement,
+ const css::uno::Reference< css::xml::sax::XFastAttributeList >& xAttrList ) override;
+ virtual void SAL_CALL endFastElement(sal_Int32 nElement) override;
+
+ virtual css::uno::Reference< css::xml::sax::XFastContextHandler > SAL_CALL createFastChildContext(
+ sal_Int32 nElement, const css::uno::Reference< css::xml::sax::XFastAttributeList >& AttrList ) override;
+
+ // this is called from the parent group for each unparsed attribute in the attribute list
+ virtual bool processAttribute( const sax_fastparser::FastAttributeList::FastAttributeIter & ) override;
+};
+
+// draw:applet
+
+class SdXMLAppletShapeContext : public SdXMLShapeContext
+{
+private:
+ OUString maAppletName;
+ OUString maAppletCode;
+ OUString maHref;
+ bool mbIsScript;
+
+ css::uno::Sequence< css::beans::PropertyValue > maParams;
+
+public:
+
+ SdXMLAppletShapeContext( SvXMLImport& rImport,
+ const css::uno::Reference< css::xml::sax::XFastAttributeList>& xAttrList,
+ css::uno::Reference< css::drawing::XShapes > const & rShapes);
+ virtual ~SdXMLAppletShapeContext() override;
+
+ virtual void SAL_CALL startFastElement(
+ sal_Int32 nElement,
+ const css::uno::Reference< css::xml::sax::XFastAttributeList >& xAttrList ) override;
+ virtual void SAL_CALL endFastElement(sal_Int32 nElement) override;
+ virtual css::uno::Reference< css::xml::sax::XFastContextHandler > SAL_CALL createFastChildContext(
+ sal_Int32 nElement,
+ const css::uno::Reference< css::xml::sax::XFastAttributeList >& xAttrList ) override;
+
+ // this is called from the parent group for each unparsed attribute in the attribute list
+ virtual bool processAttribute( const sax_fastparser::FastAttributeList::FastAttributeIter & ) override;
+};
+
+// draw:plugin
+
+class SdXMLPluginShapeContext : public SdXMLShapeContext
+{
+private:
+ OUString maMimeType;
+ OUString maHref;
+ bool mbMedia;
+
+ css::uno::Sequence< css::beans::PropertyValue > maParams;
+
+public:
+
+ SdXMLPluginShapeContext( SvXMLImport& rImport,
+ const css::uno::Reference< css::xml::sax::XFastAttributeList>& xAttrList,
+ css::uno::Reference< css::drawing::XShapes > const & rShapes);
+ virtual ~SdXMLPluginShapeContext() override;
+
+ virtual void SAL_CALL startFastElement(
+ sal_Int32 nElement,
+ const css::uno::Reference< css::xml::sax::XFastAttributeList >& xAttrList ) override;
+ virtual void SAL_CALL endFastElement(sal_Int32 nElement) override;
+ virtual css::uno::Reference< css::xml::sax::XFastContextHandler > SAL_CALL createFastChildContext(
+ sal_Int32 nElement,
+ const css::uno::Reference< css::xml::sax::XFastAttributeList >& xAttrList ) override;
+
+ // this is called from the parent group for each unparsed attribute in the attribute list
+ virtual bool processAttribute( const sax_fastparser::FastAttributeList::FastAttributeIter & ) override;
+
+ const OUString& getMimeType() const { return maMimeType; }
+};
+
+// draw:floating-frame
+
+class SdXMLFloatingFrameShapeContext : public SdXMLShapeContext
+{
+private:
+ OUString maFrameName;
+ OUString maHref;
+
+ css::uno::Reference<css::drawing::XShape> CreateFloatingFrameShape() const;
+
+public:
+
+ SdXMLFloatingFrameShapeContext( SvXMLImport& rImport,
+ const css::uno::Reference< css::xml::sax::XFastAttributeList>& xAttrList,
+ css::uno::Reference< css::drawing::XShapes > const & rShapes);
+ virtual ~SdXMLFloatingFrameShapeContext() override;
+
+ virtual void SAL_CALL startFastElement(
+ sal_Int32 nElement,
+ const css::uno::Reference< css::xml::sax::XFastAttributeList >& xAttrList ) override;
+ virtual void SAL_CALL endFastElement(sal_Int32 nElement) override;
+
+ // this is called from the parent group for each unparsed attribute in the attribute list
+ virtual bool processAttribute( const sax_fastparser::FastAttributeList::FastAttributeIter & ) override;
+};
+
+// draw:-frame
+
+class SdXMLFrameShapeContext : public SdXMLShapeContext, public MultiImageImportHelper
+{
+private:
+ bool mbSupportsReplacement;
+ SvXMLImportContextRef mxImplContext;
+ SvXMLImportContextRef mxReplImplContext;
+
+protected:
+ /// helper to get the created xShape instance, needs to be overridden
+ void removeGraphicFromImportContext(const SvXMLImportContext& rContext) override;
+ OUString getGraphicPackageURLFromImportContext(const SvXMLImportContext& rContext) const override;
+ OUString getMimeTypeFromImportContext(const SvXMLImportContext& rContext) const override;
+ css::uno::Reference<css::graphic::XGraphic> getGraphicFromImportContext(const SvXMLImportContext& rContext) const override;
+
+public:
+
+ SdXMLFrameShapeContext( SvXMLImport& rImport,
+ const css::uno::Reference< css::xml::sax::XFastAttributeList>& xAttrList,
+ css::uno::Reference< css::drawing::XShapes > const & rShapes,
+ bool bTemporaryShape);
+ virtual ~SdXMLFrameShapeContext() override;
+
+ virtual css::uno::Reference< css::xml::sax::XFastContextHandler > SAL_CALL createFastChildContext(
+ sal_Int32 nElement, const css::uno::Reference< css::xml::sax::XFastAttributeList >& AttrList ) override;
+
+ virtual void SAL_CALL startFastElement(
+ sal_Int32 nElement,
+ const css::uno::Reference< css::xml::sax::XFastAttributeList >& xAttrList ) override;
+ virtual void SAL_CALL endFastElement(sal_Int32 nElement) override;
+
+ virtual bool processAttribute( const sax_fastparser::FastAttributeList::FastAttributeIter & ) override;
+};
+
+class SdXMLCustomShapeContext : public SdXMLShapeContext
+{
+ OUString maCustomShapeEngine;
+ OUString maCustomShapeData;
+
+ std::vector< css::beans::PropertyValue > maCustomShapeGeometry;
+
+public:
+
+
+ SdXMLCustomShapeContext( SvXMLImport& rImport,
+ const css::uno::Reference< css::xml::sax::XFastAttributeList>& xAttrList,
+ css::uno::Reference< css::drawing::XShapes > const & rShapes);
+ virtual ~SdXMLCustomShapeContext() override;
+
+ virtual void SAL_CALL startFastElement(
+ sal_Int32 nElement,
+ const css::uno::Reference< css::xml::sax::XFastAttributeList >& xAttrList ) override;
+ virtual void SAL_CALL endFastElement(sal_Int32 nElement) override;
+ virtual css::uno::Reference< css::xml::sax::XFastContextHandler > SAL_CALL createFastChildContext(
+ sal_Int32 nElement, const css::uno::Reference< css::xml::sax::XFastAttributeList >& AttrList ) override;
+
+ // this is called from the parent group for each unparsed attribute in the attribute list
+ virtual bool processAttribute( const sax_fastparser::FastAttributeList::FastAttributeIter & ) override;
+};
+
+// draw:table
+
+class SdXMLTableShapeContext : public SdXMLShapeContext
+{
+public:
+
+ SdXMLTableShapeContext( SvXMLImport& rImport,
+ const css::uno::Reference< css::xml::sax::XFastAttributeList>& xAttrList,
+ css::uno::Reference< css::drawing::XShapes > const & rShapes );
+ virtual ~SdXMLTableShapeContext() override;
+
+ virtual void SAL_CALL startFastElement(
+ sal_Int32 nElement,
+ const css::uno::Reference< css::xml::sax::XFastAttributeList >& xAttrList ) override;
+ virtual void SAL_CALL endFastElement(sal_Int32 nElement) override;
+
+ virtual css::uno::Reference< css::xml::sax::XFastContextHandler > SAL_CALL createFastChildContext(
+ sal_Int32 nElement, const css::uno::Reference< css::xml::sax::XFastAttributeList >& AttrList ) override;
+
+ // this is called from the parent group for each unparsed attribute in the attribute list
+ virtual bool processAttribute( const sax_fastparser::FastAttributeList::FastAttributeIter & ) override;
+
+private:
+ SvXMLImportContextRef mxTableImportContext;
+ OUString msTemplateStyleName;
+ bool maTemplateStylesUsed[6] = {};
+};
+
+extern SvXMLEnumMapEntry<css::drawing::Alignment> const aXML_GlueAlignment_EnumMap[];
+extern SvXMLEnumMapEntry<css::drawing::EscapeDirection> const aXML_GlueEscapeDirection_EnumMap[];
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/xmloff/source/draw/ximpshow.cxx b/xmloff/source/draw/ximpshow.cxx
new file mode 100644
index 0000000000..117511f77c
--- /dev/null
+++ b/xmloff/source/draw/ximpshow.cxx
@@ -0,0 +1,243 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#include <com/sun/star/frame/XModel.hpp>
+#include <com/sun/star/util/Duration.hpp>
+#include <com/sun/star/xml/sax/XAttributeList.hpp>
+#include <com/sun/star/presentation/XCustomPresentationSupplier.hpp>
+#include <com/sun/star/presentation/XPresentationSupplier.hpp>
+#include <com/sun/star/container/XIndexContainer.hpp>
+#include <com/sun/star/drawing/XDrawPagesSupplier.hpp>
+#include <sax/tools/converter.hxx>
+#include <xmloff/xmltoken.hxx>
+#include <xmloff/xmlnamespace.hxx>
+#include <xmloff/namespacemap.hxx>
+#include <xmloff/xmluconv.hxx>
+#include "ximpshow.hxx"
+
+using namespace ::cppu;
+using namespace ::com::sun::star;
+using namespace ::com::sun::star::xml;
+using namespace ::com::sun::star::xml::sax;
+using namespace ::com::sun::star::uno;
+using namespace ::com::sun::star::drawing;
+using namespace ::com::sun::star::beans;
+using namespace ::com::sun::star::lang;
+using namespace ::com::sun::star::util;
+using namespace ::com::sun::star::container;
+using namespace ::com::sun::star::presentation;
+using namespace ::xmloff::token;
+
+SdXMLShowsContext::SdXMLShowsContext( SdXMLImport& rImport, const Reference< XFastAttributeList >& xAttrList )
+: SvXMLImportContext(rImport)
+{
+
+ Reference< XCustomPresentationSupplier > xShowsSupplier( rImport.GetModel(), UNO_QUERY );
+ if( xShowsSupplier.is() )
+ {
+ mxShows = xShowsSupplier->getCustomPresentations();
+ mxShowFactory.set( mxShows, UNO_QUERY );
+ }
+
+ Reference< XDrawPagesSupplier > xDrawPagesSupplier( rImport.GetModel(), UNO_QUERY );
+ if( xDrawPagesSupplier.is() )
+ mxPages.set( xDrawPagesSupplier->getDrawPages(), UNO_QUERY );
+
+ Reference< XPresentationSupplier > xPresentationSupplier( rImport.GetModel(), UNO_QUERY );
+ if( xPresentationSupplier.is() )
+ mxPresProps.set( xPresentationSupplier->getPresentation(), UNO_QUERY );
+
+ if( !mxPresProps.is() )
+ return;
+
+ bool bAll = true;
+ uno::Any aAny;
+ // Per ODF this is default, but we did it wrong before LO 6.0 (tdf#108824)
+ bool bIsMouseVisible = true;
+ if (rImport.getGeneratorVersion() < SvXMLImport::LO_6x)
+ bIsMouseVisible = false;
+
+ // read attributes
+ for (auto &aIter : sax_fastparser::castToFastAttributeList( xAttrList ))
+ {
+ switch( aIter.getToken() )
+ {
+ case XML_ELEMENT(PRESENTATION, XML_START_PAGE):
+ {
+ mxPresProps->setPropertyValue("FirstPage", Any(aIter.toString()) );
+ bAll = false;
+ break;
+ }
+ case XML_ELEMENT(PRESENTATION, XML_SHOW):
+ {
+ maCustomShowName = aIter.toString();
+ bAll = false;
+ break;
+ }
+ case XML_ELEMENT(PRESENTATION, XML_PAUSE):
+ {
+ Duration aDuration;
+ if (!::sax::Converter::convertDuration(aDuration, aIter.toView()))
+ continue;
+
+ const sal_Int32 nMS = (aDuration.Hours * 60 +
+ aDuration.Minutes) * 60 + aDuration.Seconds;
+ mxPresProps->setPropertyValue("Pause", Any(nMS) );
+ break;
+ }
+ case XML_ELEMENT(PRESENTATION, XML_ANIMATIONS):
+ {
+ aAny <<= IsXMLToken( aIter, XML_ENABLED );
+ mxPresProps->setPropertyValue("AllowAnimations", aAny );
+ break;
+ }
+ case XML_ELEMENT(PRESENTATION, XML_STAY_ON_TOP):
+ {
+ aAny <<= IsXMLToken( aIter, XML_TRUE );
+ mxPresProps->setPropertyValue("IsAlwaysOnTop", aAny );
+ break;
+ }
+ case XML_ELEMENT(PRESENTATION, XML_FORCE_MANUAL):
+ {
+ aAny <<= IsXMLToken( aIter, XML_TRUE );
+ mxPresProps->setPropertyValue("IsAutomatic", aAny );
+ break;
+ }
+ case XML_ELEMENT(PRESENTATION, XML_ENDLESS):
+ {
+ aAny <<= IsXMLToken( aIter, XML_TRUE );
+ mxPresProps->setPropertyValue("IsEndless", aAny );
+ break;
+ }
+ case XML_ELEMENT(PRESENTATION, XML_FULL_SCREEN):
+ {
+ aAny <<= IsXMLToken( aIter, XML_TRUE );
+ mxPresProps->setPropertyValue("IsFullScreen", aAny );
+ break;
+ }
+ case XML_ELEMENT(PRESENTATION, XML_MOUSE_VISIBLE):
+ {
+ bIsMouseVisible = IsXMLToken( aIter, XML_TRUE );
+ break;
+ }
+ case XML_ELEMENT(PRESENTATION, XML_START_WITH_NAVIGATOR):
+ {
+ aAny <<= IsXMLToken( aIter, XML_TRUE );
+ mxPresProps->setPropertyValue("StartWithNavigator", aAny );
+ break;
+ }
+ case XML_ELEMENT(PRESENTATION, XML_MOUSE_AS_PEN):
+ {
+ aAny <<= IsXMLToken( aIter, XML_TRUE );
+ mxPresProps->setPropertyValue("UsePen", aAny );
+ break;
+ }
+ case XML_ELEMENT(PRESENTATION, XML_TRANSITION_ON_CLICK):
+ {
+ aAny <<= IsXMLToken( aIter, XML_ENABLED );
+ mxPresProps->setPropertyValue("IsTransitionOnClick", aAny );
+ break;
+ }
+ case XML_ELEMENT(PRESENTATION, XML_SHOW_LOGO):
+ {
+ aAny <<= IsXMLToken( aIter, XML_TRUE );
+ mxPresProps->setPropertyValue("IsShowLogo", aAny );
+ break;
+ }
+ }
+ }
+ mxPresProps->setPropertyValue("IsShowAll", Any(bAll) );
+ mxPresProps->setPropertyValue("IsMouseVisible", Any(bIsMouseVisible) );
+}
+
+SdXMLShowsContext::~SdXMLShowsContext()
+{
+ if( !maCustomShowName.isEmpty() )
+ {
+ uno::Any aAny;
+ aAny <<= maCustomShowName;
+ mxPresProps->setPropertyValue("CustomShow", aAny );
+ }
+}
+
+css::uno::Reference< css::xml::sax::XFastContextHandler > SdXMLShowsContext::createFastChildContext(
+ sal_Int32 nElement,
+ const css::uno::Reference< css::xml::sax::XFastAttributeList >& xAttrList )
+{
+ if( nElement == XML_ELEMENT(PRESENTATION, XML_SHOW) )
+ {
+ OUString aName;
+ OUString aPages;
+
+ // read attributes
+ for (auto &aIter : sax_fastparser::castToFastAttributeList( xAttrList ))
+ {
+ OUString sValue = aIter.toString();
+
+ switch( aIter.getToken() )
+ {
+ case XML_ELEMENT(PRESENTATION, XML_NAME):
+ aName = sValue;
+ break;
+ case XML_ELEMENT(PRESENTATION, XML_PAGES):
+ aPages = sValue;
+ break;
+ }
+ }
+
+ if( !aName.isEmpty() && !aPages.isEmpty() )
+ {
+ Reference< XIndexContainer > xShow( mxShowFactory->createInstance(), UNO_QUERY );
+ if( xShow.is() )
+ {
+ SvXMLTokenEnumerator aPageNames( aPages, ',' );
+ std::u16string_view sPageNameView;
+
+ while( aPageNames.getNextToken( sPageNameView ) )
+ {
+ OUString sPageName(sPageNameView);
+ if( !mxPages->hasByName( sPageName ) )
+ continue;
+
+ Reference< XDrawPage > xPage;
+ mxPages->getByName( sPageName ) >>= xPage;
+ if( xPage.is() )
+ {
+ xShow->insertByIndex( xShow->getCount(), Any(xPage) );
+ }
+ }
+
+ Any aAny;
+ aAny <<= xShow;
+ if( mxShows->hasByName( aName ) )
+ {
+ mxShows->replaceByName( aName, aAny );
+ }
+ else
+ {
+ mxShows->insertByName( aName, aAny );
+ }
+ }
+ }
+ }
+
+ return nullptr;
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/xmloff/source/draw/ximpshow.hxx b/xmloff/source/draw/ximpshow.hxx
new file mode 100644
index 0000000000..33948c3a64
--- /dev/null
+++ b/xmloff/source/draw/ximpshow.hxx
@@ -0,0 +1,49 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#pragma once
+
+#include <xmloff/xmlictxt.hxx>
+#include "sdxmlimp_impl.hxx"
+#include <memory>
+#include <com/sun/star/beans/XPropertySet.hpp>
+#include <com/sun/star/lang/XSingleServiceFactory.hpp>
+#include <com/sun/star/container/XNameContainer.hpp>
+
+// presentations:animations
+
+class SdXMLShowsContext : public SvXMLImportContext
+{
+public:
+
+ SdXMLShowsContext( SdXMLImport& rImport,
+ const css::uno::Reference< css::xml::sax::XFastAttributeList>& xAttrList);
+ virtual ~SdXMLShowsContext() override;
+
+ virtual css::uno::Reference< css::xml::sax::XFastContextHandler > SAL_CALL createFastChildContext(
+ sal_Int32 nElement, const css::uno::Reference< css::xml::sax::XFastAttributeList >& AttrList ) override;
+private:
+ css::uno::Reference< css::lang::XSingleServiceFactory > mxShowFactory;
+ css::uno::Reference< css::container::XNameContainer > mxShows;
+ css::uno::Reference< css::beans::XPropertySet > mxPresProps;
+ css::uno::Reference< css::container::XNameAccess > mxPages;
+ OUString maCustomShowName;
+};
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/xmloff/source/draw/ximpstyl.cxx b/xmloff/source/draw/ximpstyl.cxx
new file mode 100644
index 0000000000..8e68544764
--- /dev/null
+++ b/xmloff/source/draw/ximpstyl.cxx
@@ -0,0 +1,1466 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#include "ximpstyl.hxx"
+#include <utility>
+#include <xmloff/maptype.hxx>
+#include <xmloff/XMLDrawingPageStyleContext.hxx>
+#include <xmloff/XMLShapeStyleContext.hxx>
+#include <xmloff/xmlnamespace.hxx>
+#include <xmloff/xmlprmap.hxx>
+#include <xmloff/xmltoken.hxx>
+#include <xmloff/xmluconv.hxx>
+#include "ximpnote.hxx"
+#include <xmlsdtypes.hxx>
+#include <tools/debug.hxx>
+#include <sal/log.hxx>
+#include <comphelper/diagnose_ex.hxx>
+#include <com/sun/star/frame/XModel.hpp>
+#include <com/sun/star/style/XStyle.hpp>
+#include <com/sun/star/lang/XSingleServiceFactory.hpp>
+#include <com/sun/star/presentation/XPresentationPage.hpp>
+#include <com/sun/star/drawing/FillStyle.hpp>
+#include <com/sun/star/drawing/XDrawPages.hpp>
+#include <com/sun/star/container/XNamed.hpp>
+#include <com/sun/star/beans/XPropertySet.hpp>
+#include <com/sun/star/beans/XPropertyState.hpp>
+#include <com/sun/star/presentation/XHandoutMasterSupplier.hpp>
+#include <com/sun/star/util/Color.hpp>
+#include <comphelper/namecontainer.hxx>
+#include <xmloff/autolayout.hxx>
+#include <xmloff/xmlprcon.hxx>
+#include <xmloff/families.hxx>
+#include <com/sun/star/container/XNameContainer.hpp>
+#include <svl/numformat.hxx>
+#include <svl/zforlist.hxx>
+#include "layerimp.hxx"
+#include <xmloff/XMLGraphicsDefaultStyle.hxx>
+#include <XMLNumberStylesImport.hxx>
+#include <XMLThemeContext.hxx>
+#include <unotools/configmgr.hxx>
+#include <xmloff/xmlerror.hxx>
+#include <xmloff/table/XMLTableImport.hxx>
+#include <comphelper/sequenceashashmap.hxx>
+#include <sax/tools/converter.hxx>
+#include <comphelper/sequence.hxx>
+
+using namespace ::com::sun::star;
+using namespace ::com::sun::star::uno;
+using namespace ::com::sun::star::xml::sax;
+using namespace ::xmloff::token;
+
+namespace {
+
+class SdXMLDrawingPagePropertySetContext : public SvXMLPropertySetContext
+{
+public:
+
+ SdXMLDrawingPagePropertySetContext( SvXMLImport& rImport, sal_Int32 nElement,
+ const css::uno::Reference< css::xml::sax::XFastAttributeList >& xAttrList,
+ ::std::vector< XMLPropertyState > &rProps,
+ const rtl::Reference < SvXMLImportPropertyMapper > &rMap );
+
+ using SvXMLPropertySetContext::createFastChildContext;
+ virtual css::uno::Reference< css::xml::sax::XFastContextHandler > createFastChildContext(
+ sal_Int32 nElement,
+ const css::uno::Reference< css::xml::sax::XFastAttributeList >& xAttrList,
+ ::std::vector< XMLPropertyState > &rProperties,
+ const XMLPropertyState& rProp ) override;
+};
+} // end anonymous namespace
+
+SdXMLDrawingPagePropertySetContext::SdXMLDrawingPagePropertySetContext(
+ SvXMLImport& rImport, sal_Int32 nElement,
+ const uno::Reference< xml::sax::XFastAttributeList > & xAttrList,
+ ::std::vector< XMLPropertyState > &rProps,
+ const rtl::Reference < SvXMLImportPropertyMapper > &rMap ) :
+ SvXMLPropertySetContext( rImport, nElement, xAttrList,
+ XML_TYPE_PROP_DRAWING_PAGE, rProps, rMap )
+{
+}
+
+css::uno::Reference< css::xml::sax::XFastContextHandler > SdXMLDrawingPagePropertySetContext::createFastChildContext(
+ sal_Int32 nElement,
+ const css::uno::Reference< css::xml::sax::XFastAttributeList >& xAttrList,
+ ::std::vector< XMLPropertyState > &rProperties,
+ const XMLPropertyState& rProp )
+{
+ switch( mxMapper->getPropertySetMapper()->GetEntryContextId( rProp.mnIndex ) )
+ {
+ case CTF_PAGE_SOUND_URL:
+ {
+ for (auto &aIter : sax_fastparser::castToFastAttributeList(xAttrList))
+ {
+ if( aIter.getToken() == XML_ELEMENT(XLINK, XML_HREF) )
+ {
+ uno::Any aAny( GetImport().GetAbsoluteReference( aIter.toString() ) );
+ XMLPropertyState aPropState( rProp.mnIndex, aAny );
+ rProperties.push_back( aPropState );
+ }
+ else
+ XMLOFF_WARN_UNKNOWN("xmloff", aIter);
+ }
+ break;
+ }
+ }
+
+ return SvXMLPropertySetContext::createFastChildContext( nElement,
+ xAttrList,
+ rProperties, rProp );
+}
+
+namespace {
+
+
+class SdXMLDrawingPageStyleContext : public XMLDrawingPageStyleContext
+{
+public:
+
+ SdXMLDrawingPageStyleContext(
+ SvXMLImport& rImport,
+ SvXMLStylesContext& rStyles);
+
+ virtual css::uno::Reference< css::xml::sax::XFastContextHandler > SAL_CALL createFastChildContext(
+ sal_Int32 nElement, const css::uno::Reference< css::xml::sax::XFastAttributeList >& AttrList ) override;
+
+ virtual void Finish( bool bOverwrite ) override;
+};
+
+const sal_uInt16 MAX_SPECIAL_DRAW_STYLES = 7;
+ContextID_Index_Pair const g_ContextIDs[MAX_SPECIAL_DRAW_STYLES+1] =
+{
+ { CTF_DASHNAME, -1, drawing::FillStyle::FillStyle_MAKE_FIXED_SIZE },
+ { CTF_LINESTARTNAME, -1, drawing::FillStyle::FillStyle_MAKE_FIXED_SIZE },
+ { CTF_LINEENDNAME, -1, drawing::FillStyle::FillStyle_MAKE_FIXED_SIZE },
+ { CTF_FILLGRADIENTNAME, -1, drawing::FillStyle::FillStyle_GRADIENT},
+ { CTF_FILLTRANSNAME, -1, drawing::FillStyle::FillStyle_MAKE_FIXED_SIZE },
+ { CTF_FILLHATCHNAME, -1, drawing::FillStyle::FillStyle_HATCH },
+ { CTF_FILLBITMAPNAME, -1, drawing::FillStyle::FillStyle_BITMAP },
+ { -1, -1, drawing::FillStyle::FillStyle_MAKE_FIXED_SIZE }
+};
+XmlStyleFamily const g_Families[MAX_SPECIAL_DRAW_STYLES] =
+{
+ XmlStyleFamily::SD_STROKE_DASH_ID,
+ XmlStyleFamily::SD_MARKER_ID,
+ XmlStyleFamily::SD_MARKER_ID,
+ XmlStyleFamily::SD_GRADIENT_ID,
+ XmlStyleFamily::SD_GRADIENT_ID,
+ XmlStyleFamily::SD_HATCH_ID,
+ XmlStyleFamily::SD_FILL_IMAGE_ID
+};
+
+}
+
+XMLDrawingPageStyleContext::XMLDrawingPageStyleContext(
+ SvXMLImport& rImport,
+ SvXMLStylesContext& rStyles,
+ ContextID_Index_Pair const pContextIDs[],
+ XmlStyleFamily const pFamilies[])
+ : XMLPropStyleContext(rImport, rStyles, XmlStyleFamily::SD_DRAWINGPAGE_ID)
+ , m_pFamilies(pFamilies)
+{
+ size_t size(1); // for the -1 entry
+ for (ContextID_Index_Pair const* pTemp(pContextIDs); pTemp->nContextID != -1; ++size, ++pTemp);
+ m_pContextIDs.reset(new ContextID_Index_Pair[size]);
+ std::memcpy(m_pContextIDs.get(), pContextIDs, size * sizeof(ContextID_Index_Pair));
+}
+
+SdXMLDrawingPageStyleContext::SdXMLDrawingPageStyleContext(
+ SvXMLImport& rImport,
+ SvXMLStylesContext& rStyles)
+ : XMLDrawingPageStyleContext(rImport, rStyles, g_ContextIDs, g_Families)
+{
+}
+
+css::uno::Reference< css::xml::sax::XFastContextHandler > SdXMLDrawingPageStyleContext::createFastChildContext(
+ sal_Int32 nElement,
+ const css::uno::Reference< css::xml::sax::XFastAttributeList >& xAttrList )
+{
+ if( nElement == XML_ELEMENT(STYLE, XML_DRAWING_PAGE_PROPERTIES) )
+ {
+ rtl::Reference < SvXMLImportPropertyMapper > xImpPrMap =
+ GetStyles()->GetImportPropertyMapper( GetFamily() );
+ if( xImpPrMap.is() )
+ return new SdXMLDrawingPagePropertySetContext( GetImport(), nElement,
+ xAttrList,
+ GetProperties(),
+ xImpPrMap );
+ }
+
+ return XMLPropStyleContext::createFastChildContext( nElement, xAttrList );
+}
+
+void SdXMLDrawingPageStyleContext::Finish( bool bOverwrite )
+{
+ XMLPropStyleContext::Finish( bOverwrite );
+
+ ::std::vector< XMLPropertyState > &rProperties = GetProperties();
+
+ const rtl::Reference< XMLPropertySetMapper >& rImpPrMap = GetStyles()->GetImportPropertyMapper( GetFamily() )->getPropertySetMapper();
+
+ for(auto& property : rProperties)
+ {
+ if( property.mnIndex == -1 )
+ continue;
+
+ sal_Int16 nContextID = rImpPrMap->GetEntryContextId(property.mnIndex);
+ switch( nContextID )
+ {
+ case CTF_DATE_TIME_FORMAT:
+ {
+ OUString sStyleName;
+ property.maValue >>= sStyleName;
+
+ sal_Int32 nStyle = 0;
+
+ const SdXMLNumberFormatImportContext* pSdNumStyle =
+ dynamic_cast< const SdXMLNumberFormatImportContext*> (
+ GetStyles()->FindStyleChildContext( XmlStyleFamily::DATA_STYLE, sStyleName, true ) );
+
+ if( pSdNumStyle )
+ nStyle = pSdNumStyle->GetDrawKey();
+
+ property.maValue <<= nStyle;
+ }
+ break;
+ }
+ }
+
+}
+
+
+// #i35918#
+void XMLDrawingPageStyleContext::FillPropertySet(
+ const Reference< beans::XPropertySet > & rPropSet )
+{
+ rtl::Reference < SvXMLImportPropertyMapper > xImpPrMap =
+ GetStyles()->GetImportPropertyMapper( GetFamily() );
+ SAL_WARN_IF( !xImpPrMap.is(), "xmloff", "There is the import prop mapper" );
+ if( xImpPrMap.is() )
+ xImpPrMap->FillPropertySet(GetProperties(), rPropSet, m_pContextIDs.get());
+
+ Reference< beans::XPropertySetInfo > xInfo;
+ for (size_t i=0; m_pContextIDs[i].nContextID != -1; ++i)
+ {
+ sal_Int32 nIndex = m_pContextIDs[i].nIndex;
+ if( nIndex != -1 )
+ {
+ struct XMLPropertyState& rState = GetProperties()[nIndex];
+ OUString sStyleName;
+ rState.maValue >>= sStyleName;
+
+ if (::xmloff::IsIgnoreFillStyleNamedItem(rPropSet, m_pContextIDs[i].nExpectedFillStyle))
+ {
+ SAL_INFO("xmloff.style", "XMLDrawingPageStyleContext: dropping fill named item: " << sStyleName);
+ break; // ignore it, it's not used
+ }
+
+ sStyleName = GetImport().GetStyleDisplayName( m_pFamilies[i],
+ sStyleName );
+ // get property set mapper
+ rtl::Reference<XMLPropertySetMapper> rPropMapper =
+ xImpPrMap->getPropertySetMapper();
+
+ // set property
+ const OUString& rPropertyName =
+ rPropMapper->GetEntryAPIName(rState.mnIndex);
+ if( !xInfo.is() )
+ xInfo = rPropSet->getPropertySetInfo();
+ if ( xInfo->hasPropertyByName( rPropertyName ) )
+ {
+ rPropSet->setPropertyValue( rPropertyName, Any( sStyleName ) );
+ }
+ }
+ }
+}
+
+
+SdXMLPageMasterStyleContext::SdXMLPageMasterStyleContext(
+ SdXMLImport& rImport,
+ sal_Int32 /*nElement*/,
+ const uno::Reference< xml::sax::XFastAttributeList>& xAttrList)
+: SvXMLStyleContext(rImport, XmlStyleFamily::SD_PAGEMASTERSTYLECONTEXT_ID),
+ mnBorderBottom( 0 ),
+ mnBorderLeft( 0 ),
+ mnBorderRight( 0 ),
+ mnBorderTop( 0 ),
+ mnWidth( 0 ),
+ mnHeight( 0 ),
+ meOrientation(GetSdImport().IsDraw() ? view::PaperOrientation_PORTRAIT : view::PaperOrientation_LANDSCAPE)
+{
+ // set family to something special at SvXMLStyleContext
+ // for differences in search-methods
+
+ for (auto &aIter : sax_fastparser::castToFastAttributeList( xAttrList ))
+ {
+ switch(aIter.getToken())
+ {
+ case XML_ELEMENT(FO, XML_MARGIN_TOP):
+ case XML_ELEMENT(FO_COMPAT, XML_MARGIN_TOP):
+ {
+ GetSdImport().GetMM100UnitConverter().convertMeasureToCore(
+ mnBorderTop, aIter.toView());
+ break;
+ }
+ case XML_ELEMENT(FO, XML_MARGIN_BOTTOM):
+ case XML_ELEMENT(FO_COMPAT, XML_MARGIN_BOTTOM):
+ {
+ GetSdImport().GetMM100UnitConverter().convertMeasureToCore(
+ mnBorderBottom, aIter.toView());
+ break;
+ }
+ case XML_ELEMENT(FO, XML_MARGIN_LEFT):
+ case XML_ELEMENT(FO_COMPAT, XML_MARGIN_LEFT):
+ {
+ GetSdImport().GetMM100UnitConverter().convertMeasureToCore(
+ mnBorderLeft, aIter.toView());
+ break;
+ }
+ case XML_ELEMENT(FO, XML_MARGIN_RIGHT):
+ case XML_ELEMENT(FO_COMPAT, XML_MARGIN_RIGHT):
+ {
+ GetSdImport().GetMM100UnitConverter().convertMeasureToCore(
+ mnBorderRight, aIter.toView());
+ break;
+ }
+ case XML_ELEMENT(FO, XML_PAGE_WIDTH):
+ case XML_ELEMENT(FO_COMPAT, XML_PAGE_WIDTH):
+ {
+ GetSdImport().GetMM100UnitConverter().convertMeasureToCore(
+ mnWidth, aIter.toView());
+ break;
+ }
+ case XML_ELEMENT(FO, XML_PAGE_HEIGHT):
+ case XML_ELEMENT(FO_COMPAT, XML_PAGE_HEIGHT):
+ {
+ GetSdImport().GetMM100UnitConverter().convertMeasureToCore(
+ mnHeight, aIter.toView());
+ break;
+ }
+ case XML_ELEMENT(STYLE, XML_PRINT_ORIENTATION):
+ {
+ if( IsXMLToken( aIter, XML_PORTRAIT ) )
+ meOrientation = view::PaperOrientation_PORTRAIT;
+ else
+ meOrientation = view::PaperOrientation_LANDSCAPE;
+ break;
+ }
+ default:
+ XMLOFF_WARN_UNKNOWN("xmloff", aIter);
+ }
+ }
+}
+
+SdXMLPageMasterStyleContext::~SdXMLPageMasterStyleContext()
+{
+}
+
+
+SdXMLPageMasterContext::SdXMLPageMasterContext(
+ SdXMLImport& rImport,
+ sal_Int32 /*nElement*/,
+ const uno::Reference< xml::sax::XFastAttributeList>& /*xAttrList*/)
+: SvXMLStyleContext(rImport, XmlStyleFamily::SD_PAGEMASTERCONTEXT_ID)
+{
+ // set family to something special at SvXMLStyleContext
+ // for differences in search-methods
+
+}
+
+css::uno::Reference< css::xml::sax::XFastContextHandler > SdXMLPageMasterContext::createFastChildContext(
+ sal_Int32 nElement,
+ const css::uno::Reference< css::xml::sax::XFastAttributeList >& xAttrList )
+{
+ if(nElement == XML_ELEMENT(STYLE, XML_PAGE_LAYOUT_PROPERTIES))
+ {
+ DBG_ASSERT(!mxPageMasterStyle.is(), "PageMasterStyle is set, there seem to be two of them (!)");
+ mxPageMasterStyle.set(new SdXMLPageMasterStyleContext(GetSdImport(), nElement, xAttrList));
+ return mxPageMasterStyle;
+ }
+ else
+ XMLOFF_WARN_UNKNOWN_ELEMENT("xmloff", nElement);
+
+ return nullptr;
+}
+
+SdXMLPresentationPageLayoutContext::SdXMLPresentationPageLayoutContext(
+ SdXMLImport& rImport,
+ sal_Int32 /*nElement*/,
+ const uno::Reference< xml::sax::XFastAttributeList >& /*xAttrList*/)
+: SvXMLStyleContext(rImport, XmlStyleFamily::SD_PRESENTATIONPAGELAYOUT_ID),
+ mnTypeId( AUTOLAYOUT_NONE )
+{
+ // set family to something special at SvXMLStyleContext
+ // for differences in search-methods
+}
+
+css::uno::Reference< css::xml::sax::XFastContextHandler > SdXMLPresentationPageLayoutContext::createFastChildContext(
+ sal_Int32 nElement,
+ const css::uno::Reference< css::xml::sax::XFastAttributeList >& xAttrList )
+{
+ SvXMLImportContextRef xContext;
+
+ if(nElement == XML_ELEMENT(PRESENTATION, XML_PLACEHOLDER))
+ {
+ const rtl::Reference< SdXMLPresentationPlaceholderContext > xLclContext{
+ new SdXMLPresentationPlaceholderContext(GetSdImport(), nElement, xAttrList)};
+ // presentation:placeholder inside style:presentation-page-layout context
+ xContext = xLclContext.get();
+
+ // remember SdXMLPresentationPlaceholderContext for later evaluation
+ maList.push_back(xLclContext);
+ }
+ else
+ XMLOFF_WARN_UNKNOWN_ELEMENT("xmloff", nElement);
+
+ return xContext;
+}
+
+void SdXMLPresentationPageLayoutContext::endFastElement(sal_Int32 )
+{
+ // build presentation page layout type here
+ // calc mnTpeId due to content of maList
+ // at the moment only use number of types used there
+ if( maList.empty() )
+ return;
+
+ SdXMLPresentationPlaceholderContext* pObj0 = maList[ 0 ].get();
+ if( pObj0->GetName() == "handout" )
+ {
+ switch( maList.size() )
+ {
+ case 1:
+ mnTypeId = AUTOLAYOUT_HANDOUT1;
+ break;
+ case 2:
+ mnTypeId = AUTOLAYOUT_HANDOUT2;
+ break;
+ case 3:
+ mnTypeId = AUTOLAYOUT_HANDOUT3;
+ break;
+ case 4:
+ mnTypeId = AUTOLAYOUT_HANDOUT4;
+ break;
+ case 9:
+ mnTypeId = AUTOLAYOUT_HANDOUT9;
+ break;
+ default:
+ mnTypeId = AUTOLAYOUT_HANDOUT6;
+ }
+ }
+ else
+ {
+ switch( maList.size() )
+ {
+ case 1:
+ {
+ if( pObj0->GetName() == "title" )
+ {
+ mnTypeId = AUTOLAYOUT_TITLE_ONLY;
+ }
+ else
+ {
+ mnTypeId = AUTOLAYOUT_ONLY_TEXT;
+ }
+ break;
+ }
+ case 2:
+ {
+ SdXMLPresentationPlaceholderContext* pObj1 = maList[ 1 ].get();
+
+ if( pObj1->GetName() == "subtitle" )
+ {
+ mnTypeId = AUTOLAYOUT_TITLE;
+ }
+ else if( pObj1->GetName() == "outline" )
+ {
+ mnTypeId = AUTOLAYOUT_TITLE_CONTENT;
+ }
+ else if( pObj1->GetName() == "chart" )
+ {
+ mnTypeId = AUTOLAYOUT_CHART;
+ }
+ else if( pObj1->GetName() == "table" )
+ {
+ mnTypeId = AUTOLAYOUT_TAB;
+ }
+ else if( pObj1->GetName() == "object" )
+ {
+ mnTypeId = AUTOLAYOUT_OBJ;
+ }
+ else if( pObj1->GetName() == "vertical_outline" )
+ {
+ if( pObj0->GetName() == "vertical_title" )
+ {
+ mnTypeId = AUTOLAYOUT_VTITLE_VCONTENT;
+ }
+ else
+ {
+ mnTypeId = AUTOLAYOUT_TITLE_VCONTENT;
+ }
+ }
+ else
+ {
+ mnTypeId = AUTOLAYOUT_NOTES;
+ }
+ break;
+ }
+ case 3:
+ {
+ SdXMLPresentationPlaceholderContext* pObj1 = maList[ 1 ].get();
+ SdXMLPresentationPlaceholderContext* pObj2 = maList[ 2 ].get();
+
+ if( pObj1->GetName() == "outline" )
+ {
+ if( pObj2->GetName() == "outline" )
+ {
+ mnTypeId = AUTOLAYOUT_TITLE_2CONTENT;
+ }
+ else if( pObj2->GetName() == "chart" )
+ {
+ mnTypeId = AUTOLAYOUT_TEXTCHART;
+ }
+ else if( pObj2->GetName() == "graphic" )
+ {
+ mnTypeId = AUTOLAYOUT_TEXTCLIP;
+ }
+ else
+ {
+ if(pObj1->GetX() < pObj2->GetX())
+ {
+ mnTypeId = AUTOLAYOUT_TEXTOBJ; // outline left, object right
+ }
+ else
+ {
+ mnTypeId = AUTOLAYOUT_TEXTOVEROBJ; // outline top, object right
+ }
+ }
+ }
+ else if( pObj1->GetName() == "chart" )
+ {
+ mnTypeId = AUTOLAYOUT_CHARTTEXT;
+ }
+ else if( pObj1->GetName() == "graphic" )
+ {
+ if( pObj2->GetName() == "vertical_outline" )
+ {
+ mnTypeId = AUTOLAYOUT_TITLE_2VTEXT;
+ }
+ else
+ {
+ mnTypeId = AUTOLAYOUT_CLIPTEXT;
+ }
+ }
+ else if( pObj1->GetName() == "vertical_outline" )
+ {
+ mnTypeId = AUTOLAYOUT_VTITLE_VCONTENT_OVER_VCONTENT;
+ }
+ else
+ {
+ if(pObj1->GetX() < pObj2->GetX())
+ {
+ mnTypeId = AUTOLAYOUT_OBJTEXT; // left, right
+ }
+ else
+ {
+ mnTypeId = AUTOLAYOUT_TITLE_CONTENT_OVER_CONTENT; // top, bottom
+ }
+ }
+ break;
+ }
+ case 4:
+ {
+ SdXMLPresentationPlaceholderContext* pObj1 = maList[ 1 ].get();
+ SdXMLPresentationPlaceholderContext* pObj2 = maList[ 2 ].get();
+
+ if( pObj1->GetName() == "object" )
+ {
+ if(pObj1->GetX() < pObj2->GetX())
+ {
+ mnTypeId = AUTOLAYOUT_TITLE_2CONTENT_OVER_CONTENT;
+ }
+ else
+ {
+ mnTypeId = AUTOLAYOUT_TITLE_2CONTENT_CONTENT;
+ }
+ }
+ else
+ {
+ mnTypeId = AUTOLAYOUT_TITLE_CONTENT_2CONTENT;
+ }
+ break;
+ }
+ case 5:
+ {
+ SdXMLPresentationPlaceholderContext* pObj1 = maList[ 1 ].get();
+
+ if( pObj1->GetName() == "object" )
+ {
+ mnTypeId = AUTOLAYOUT_TITLE_4CONTENT;
+ }
+ else
+ {
+ mnTypeId = AUTOLAYOUT_4CLIPART;
+ }
+ break;
+
+ }
+ case 7:
+ {
+ mnTypeId = AUTOLAYOUT_TITLE_6CONTENT; // tdf#141978: Apply 6content layout
+ break;
+ }
+ default:
+ {
+ mnTypeId = AUTOLAYOUT_NONE;
+ break;
+ }
+ }
+ }
+
+ // release remembered contexts, they are no longer needed
+ maList.clear();
+}
+
+SdXMLPresentationPlaceholderContext::SdXMLPresentationPlaceholderContext(
+ SdXMLImport& rImport,
+ sal_Int32 /*nElement*/,
+ const uno::Reference< xml::sax::XFastAttributeList>& xAttrList)
+: SvXMLImportContext( rImport ),
+ mnX(0)
+{
+ for (auto &aIter : sax_fastparser::castToFastAttributeList( xAttrList ))
+ {
+ switch(aIter.getToken())
+ {
+ case XML_ELEMENT(PRESENTATION, XML_OBJECT):
+ {
+ msName = aIter.toString();
+ break;
+ }
+ case XML_ELEMENT(SVG, XML_X):
+ case XML_ELEMENT(SVG_COMPAT, XML_X):
+ {
+ GetSdImport().GetMM100UnitConverter().convertMeasureToCore(
+ mnX, aIter.toView());
+ break;
+ }
+ case XML_ELEMENT(SVG, XML_Y):
+ case XML_ELEMENT(SVG_COMPAT, XML_Y):
+ {
+ break;
+ }
+ case XML_ELEMENT(SVG, XML_WIDTH):
+ case XML_ELEMENT(SVG_COMPAT, XML_WIDTH):
+ {
+ break;
+ }
+ case XML_ELEMENT(SVG, XML_HEIGHT):
+ case XML_ELEMENT(SVG_COMPAT, XML_HEIGHT):
+ {
+ break;
+ }
+ default:
+ XMLOFF_WARN_UNKNOWN("xmloff", aIter);
+ }
+ }
+}
+
+SdXMLPresentationPlaceholderContext::~SdXMLPresentationPlaceholderContext()
+{
+}
+
+
+SdXMLMasterPageContext::SdXMLMasterPageContext(
+ SdXMLImport& rImport,
+ sal_Int32 nElement,
+ const uno::Reference< xml::sax::XFastAttributeList>& xAttrList,
+ uno::Reference< drawing::XShapes > const & rShapes)
+: SdXMLGenericPageContext( rImport, xAttrList, rShapes )
+{
+ const bool bHandoutMaster = (nElement & TOKEN_MASK) == XML_HANDOUT_MASTER;
+ OUString sStyleName, sPageMasterName;
+
+ for (auto &aIter : sax_fastparser::castToFastAttributeList( xAttrList ))
+ {
+ const OUString sValue = aIter.toString();
+ switch(aIter.getToken())
+ {
+ case XML_ELEMENT(STYLE, XML_NAME):
+ {
+ msName = sValue;
+ break;
+ }
+ case XML_ELEMENT(STYLE, XML_DISPLAY_NAME):
+ {
+ msDisplayName = sValue;
+ break;
+ }
+ case XML_ELEMENT(STYLE, XML_PAGE_LAYOUT_NAME):
+ {
+ sPageMasterName = sValue;
+ break;
+ }
+ case XML_ELEMENT(DRAW, XML_STYLE_NAME):
+ {
+ sStyleName = sValue;
+ break;
+ }
+ case XML_ELEMENT(PRESENTATION, XML_PRESENTATION_PAGE_LAYOUT_NAME):
+ {
+ maPageLayoutName = sValue;
+ break;
+ }
+ case XML_ELEMENT(PRESENTATION, XML_USE_HEADER_NAME):
+ {
+ maUseHeaderDeclName = sValue;
+ break;
+ }
+ case XML_ELEMENT(PRESENTATION, XML_USE_FOOTER_NAME):
+ {
+ maUseFooterDeclName = sValue;
+ break;
+ }
+ case XML_ELEMENT(PRESENTATION, XML_USE_DATE_TIME_NAME):
+ {
+ maUseDateTimeDeclName = sValue;
+ break;
+ }
+ default:
+ XMLOFF_WARN_UNKNOWN("xmloff", aIter);
+ }
+ }
+
+ if( msDisplayName.isEmpty() )
+ msDisplayName = msName;
+ else if( msDisplayName != msName )
+ GetImport().AddStyleDisplayName( XmlStyleFamily::MASTER_PAGE, msName, msDisplayName );
+
+ GetImport().GetShapeImport()->startPage( GetLocalShapesContext() );
+
+ // set page name?
+ if(!bHandoutMaster && !msDisplayName.isEmpty() && GetLocalShapesContext().is())
+ {
+ uno::Reference < container::XNamed > xNamed(GetLocalShapesContext(), uno::UNO_QUERY);
+ if(xNamed.is())
+ xNamed->setName(msDisplayName);
+ }
+
+ // set page-master?
+ if(!sPageMasterName.isEmpty())
+ {
+ SetPageMaster( sPageMasterName );
+ }
+
+ SetStyle( sStyleName );
+
+ SetLayout();
+
+ DeleteAllShapes();
+}
+
+SdXMLMasterPageContext::~SdXMLMasterPageContext()
+{
+}
+
+void SdXMLMasterPageContext::endFastElement(sal_Int32 nElement)
+{
+ // set styles on master-page
+ if(!msName.isEmpty() && GetSdImport().GetShapeImport()->GetStylesContext())
+ {
+ SvXMLImportContext* pContext = GetSdImport().GetShapeImport()->GetStylesContext();
+ if (SdXMLStylesContext* pSdContext = dynamic_cast<SdXMLStylesContext*>(pContext))
+ pSdContext->SetMasterPageStyles(*this);
+ }
+
+ SdXMLGenericPageContext::endFastElement(nElement);
+ GetImport().GetShapeImport()->endPage(GetLocalShapesContext());
+}
+
+css::uno::Reference< css::xml::sax::XFastContextHandler > SdXMLMasterPageContext::createFastChildContext(
+ sal_Int32 nElement,
+ const css::uno::Reference< css::xml::sax::XFastAttributeList >& xAttrList )
+{
+ switch (nElement)
+ {
+ // some special objects inside style:masterpage context
+ case XML_ELEMENT(STYLE, XML_STYLE):
+ {
+ if(GetSdImport().GetShapeImport()->GetStylesContext())
+ {
+ // style:style inside master-page context -> presentation style
+ XMLShapeStyleContext* pNew = new XMLShapeStyleContext(
+ GetSdImport(),
+ *GetSdImport().GetShapeImport()->GetStylesContext(),
+ XmlStyleFamily::SD_PRESENTATION_ID);
+
+ // add this style to the outer StylesContext class for later processing
+ GetSdImport().GetShapeImport()->GetStylesContext()->AddStyle(*pNew);
+ return pNew;
+ }
+ break;
+ }
+ case XML_ELEMENT(PRESENTATION, XML_NOTES):
+ {
+ if( GetSdImport().IsImpress() )
+ {
+ // get notes page
+ uno::Reference< presentation::XPresentationPage > xPresPage(GetLocalShapesContext(), uno::UNO_QUERY);
+ if(xPresPage.is())
+ {
+ uno::Reference< drawing::XDrawPage > xNotesDrawPage = xPresPage->getNotesPage();
+ if(xNotesDrawPage.is())
+ {
+ // presentation:notes inside master-page context
+ return new SdXMLNotesContext( GetSdImport(), xAttrList, xNotesDrawPage);
+ }
+ }
+ }
+ break;
+ }
+ case XML_ELEMENT(LO_EXT, XML_THEME):
+ {
+ uno::Reference<drawing::XDrawPage> xMasterPage(GetLocalShapesContext(), uno::UNO_QUERY);
+ return new XMLThemeContext(GetSdImport(), xAttrList, xMasterPage);
+ break;
+ }
+ }
+ return SdXMLGenericPageContext::createFastChildContext(nElement, xAttrList);
+}
+
+SdXMLStylesContext::SdXMLStylesContext(
+ SdXMLImport& rImport,
+ bool bIsAutoStyle)
+: SvXMLStylesContext(rImport),
+ mbIsAutoStyle(bIsAutoStyle)
+{
+ Reference< uno::XComponentContext > xContext = rImport.GetComponentContext();
+ mpNumFormatter = std::make_unique<SvNumberFormatter>( xContext, LANGUAGE_SYSTEM );
+ mpNumFmtHelper = std::make_unique<SvXMLNumFmtHelper>( mpNumFormatter.get(), xContext );
+}
+
+SvXMLStyleContext* SdXMLStylesContext::CreateStyleChildContext(
+ sal_Int32 nElement,
+ const uno::Reference< xml::sax::XFastAttributeList >& xAttrList)
+{
+ switch (nElement)
+ {
+ case XML_ELEMENT(TABLE, XML_TABLE_TEMPLATE):
+ {
+ auto pContext = GetImport().GetShapeImport()->GetShapeTableImport()->CreateTableTemplateContext(nElement, xAttrList );
+ if (pContext)
+ return pContext;
+ break;
+ }
+ case XML_ELEMENT(STYLE, XML_PAGE_LAYOUT):
+ // style:page-master inside office:styles context
+ return new SdXMLPageMasterContext(GetSdImport(), nElement, xAttrList);
+ case XML_ELEMENT(STYLE, XML_PRESENTATION_PAGE_LAYOUT):
+ // style:presentation-page-layout inside office:styles context
+ return new SdXMLPresentationPageLayoutContext(GetSdImport(), nElement, xAttrList);
+ case XML_ELEMENT(NUMBER, XML_DATE_STYLE):
+ // number:date-style or number:time-style
+ return new SdXMLNumberFormatImportContext( GetSdImport(), nElement, mpNumFmtHelper->getData(), SvXMLStylesTokens::DATE_STYLE, xAttrList, *this );
+ case XML_ELEMENT(NUMBER, XML_TIME_STYLE):
+ // number:date-style or number:time-style
+ return new SdXMLNumberFormatImportContext( GetSdImport(), nElement, mpNumFmtHelper->getData(), SvXMLStylesTokens::TIME_STYLE, xAttrList, *this );
+ case XML_ELEMENT(NUMBER, XML_NUMBER_STYLE):
+ return new SvXMLNumFormatContext( GetSdImport(), nElement,
+ mpNumFmtHelper->getData(), SvXMLStylesTokens::NUMBER_STYLE, xAttrList, *this );
+ case XML_ELEMENT(NUMBER, XML_CURRENCY_STYLE):
+ return new SvXMLNumFormatContext( GetSdImport(), nElement,
+ mpNumFmtHelper->getData(), SvXMLStylesTokens::CURRENCY_STYLE, xAttrList, *this );
+ case XML_ELEMENT(NUMBER, XML_PERCENTAGE_STYLE):
+ return new SvXMLNumFormatContext( GetSdImport(), nElement,
+ mpNumFmtHelper->getData(), SvXMLStylesTokens::PERCENTAGE_STYLE, xAttrList, *this );
+ case XML_ELEMENT(NUMBER, XML_BOOLEAN_STYLE):
+ return new SvXMLNumFormatContext( GetSdImport(), nElement,
+ mpNumFmtHelper->getData(), SvXMLStylesTokens::BOOLEAN_STYLE, xAttrList, *this );
+ case XML_ELEMENT(NUMBER, XML_TEXT_STYLE):
+ return new SvXMLNumFormatContext( GetSdImport(), nElement,
+ mpNumFmtHelper->getData(), SvXMLStylesTokens::TEXT_STYLE, xAttrList, *this );
+ case XML_ELEMENT(PRESENTATION, XML_HEADER_DECL):
+ case XML_ELEMENT(PRESENTATION, XML_FOOTER_DECL):
+ case XML_ELEMENT(PRESENTATION, XML_DATE_TIME_DECL):
+ return new SdXMLHeaderFooterDeclContext( GetImport(), xAttrList );
+ case XML_ELEMENT(STYLE, XML_STYLE):
+ break; // ignore
+ default:
+ XMLOFF_INFO_UNKNOWN_ELEMENT("xmloff", nElement);
+ }
+
+ // call base class
+ return SvXMLStylesContext::CreateStyleChildContext(nElement, xAttrList);
+}
+
+SvXMLStyleContext* SdXMLStylesContext::CreateStyleStyleChildContext(
+ XmlStyleFamily nFamily,
+ sal_Int32 nElement,
+ const uno::Reference< css::xml::sax::XFastAttributeList >& xAttrList)
+{
+ switch( nFamily )
+ {
+ case XmlStyleFamily::SD_DRAWINGPAGE_ID:
+ return new SdXMLDrawingPageStyleContext(GetSdImport(), *this );
+ case XmlStyleFamily::TABLE_CELL:
+ case XmlStyleFamily::TABLE_COLUMN:
+ case XmlStyleFamily::TABLE_ROW:
+ return new XMLShapeStyleContext( GetSdImport(), *this, nFamily );
+ default: break;
+ }
+
+ // call base class
+ return SvXMLStylesContext::CreateStyleStyleChildContext(nFamily, nElement, xAttrList);
+}
+
+SvXMLStyleContext* SdXMLStylesContext::CreateDefaultStyleStyleChildContext(
+ XmlStyleFamily nFamily,
+ sal_Int32 nElement,
+ const Reference< XFastAttributeList > & xAttrList )
+{
+ switch( nFamily )
+ {
+ case XmlStyleFamily::SD_GRAPHICS_ID:
+ return new XMLGraphicsDefaultStyle(GetSdImport(), *this );
+ default: break;
+ }
+
+ // call base class
+ return SvXMLStylesContext::CreateDefaultStyleStyleChildContext(nFamily, nElement, xAttrList);
+}
+
+rtl::Reference< SvXMLImportPropertyMapper > SdXMLStylesContext::GetImportPropertyMapper(
+ XmlStyleFamily nFamily) const
+{
+ rtl::Reference < SvXMLImportPropertyMapper > xMapper;
+
+ switch( nFamily )
+ {
+ case XmlStyleFamily::SD_DRAWINGPAGE_ID:
+ {
+ if(!xPresImpPropMapper.is())
+ {
+ rtl::Reference< XMLShapeImportHelper > aImpHelper = const_cast<SvXMLImport&>(GetImport()).GetShapeImport();
+ const_cast<SdXMLStylesContext*>(this)->xPresImpPropMapper =
+ aImpHelper->GetPresPagePropsMapper();
+ }
+ xMapper = xPresImpPropMapper;
+ break;
+ }
+
+ case XmlStyleFamily::TABLE_COLUMN:
+ case XmlStyleFamily::TABLE_ROW:
+ case XmlStyleFamily::TABLE_CELL:
+ {
+ const rtl::Reference< XMLTableImport >& xTableImport( const_cast< SvXMLImport& >( GetImport() ).GetShapeImport()->GetShapeTableImport() );
+
+ switch( nFamily )
+ {
+ case XmlStyleFamily::TABLE_COLUMN: xMapper = xTableImport->GetColumnImportPropertySetMapper().get(); break;
+ case XmlStyleFamily::TABLE_ROW: xMapper = xTableImport->GetRowImportPropertySetMapper().get(); break;
+ case XmlStyleFamily::TABLE_CELL: xMapper = xTableImport->GetCellImportPropertySetMapper().get(); break;
+ default: break;
+ }
+ break;
+ }
+ default: break;
+ }
+
+ // call base class
+ if( !xMapper.is() )
+ xMapper = SvXMLStylesContext::GetImportPropertyMapper(nFamily);
+ return xMapper;
+}
+
+// Process all style and object info
+
+void SdXMLStylesContext::endFastElement(sal_Int32 )
+{
+ if(mbIsAutoStyle)
+ {
+ // AutoStyles for text import
+ GetImport().GetTextImport()->SetAutoStyles( this );
+
+ // AutoStyles for chart
+ GetImport().GetChartImport()->SetAutoStylesContext( this );
+
+ // AutoStyles for forms
+ GetImport().GetFormImport()->setAutoStyleContext( this );
+
+ // associate AutoStyles with styles in preparation to setting Styles on shapes
+ for(sal_uInt32 a(0); a < GetStyleCount(); a++)
+ {
+ const SvXMLStyleContext* pStyle = GetStyle(a);
+ if (const XMLShapeStyleContext* pDocStyle = dynamic_cast<const XMLShapeStyleContext*>(pStyle))
+ {
+ SvXMLStylesContext* pStylesContext = GetSdImport().GetShapeImport()->GetStylesContext();
+ if (pStylesContext)
+ {
+ pStyle = pStylesContext->FindStyleChildContext(pStyle->GetFamily(), pStyle->GetParentName());
+
+ if (const XMLShapeStyleContext* pParentStyle = dynamic_cast<const XMLShapeStyleContext*>(pStyle))
+ {
+ if(pParentStyle->GetStyle().is())
+ {
+ const_cast<XMLShapeStyleContext*>(pDocStyle)->SetStyle(pParentStyle->GetStyle());
+ }
+ }
+ }
+ }
+ }
+
+ FinishStyles( false );
+ }
+ else
+ {
+ // Process styles list
+ ImpSetGraphicStyles();
+ ImpSetCellStyles();
+ GetImport().GetShapeImport()->GetShapeTableImport()->finishStyles();
+
+ // put style infos in the info set for other components ( content import f.e. )
+ uno::Reference< beans::XPropertySet > xInfoSet( GetImport().getImportInfo() );
+ if( xInfoSet.is() )
+ {
+ uno::Reference< beans::XPropertySetInfo > xInfoSetInfo( xInfoSet->getPropertySetInfo() );
+
+ if( xInfoSetInfo->hasPropertyByName("PageLayouts") )
+ xInfoSet->setPropertyValue("PageLayouts", uno::Any( getPageLayouts() ) );
+ }
+
+ }
+}
+
+// set master-page styles (all with family="presentation" and a special
+// prefix) on given master-page.
+
+void SdXMLStylesContext::SetMasterPageStyles(SdXMLMasterPageContext const & rMaster) const
+{
+ const uno::Reference<container::XNameAccess>& rStyleFamilies =
+ GetSdImport().GetLocalDocStyleFamilies();
+
+ if (!rStyleFamilies.is())
+ return;
+
+ if (!rStyleFamilies->hasByName(rMaster.GetDisplayName()))
+ return;
+
+ try
+ {
+ uno::Reference< container::XNameAccess > xMasterPageStyles( rStyleFamilies->getByName(rMaster.GetDisplayName()), UNO_QUERY_THROW );
+ OUString sPrefix(rMaster.GetDisplayName() + "-");
+ ImpSetGraphicStyles(xMasterPageStyles, XmlStyleFamily::SD_PRESENTATION_ID, sPrefix);
+ }
+ catch (const uno::Exception&)
+ {
+ TOOLS_WARN_EXCEPTION("xmloff.draw", "");
+ }
+}
+
+// Process styles list:
+// set graphic styles (all with family="graphics"). Remember xStyle at list element.
+
+void SdXMLStylesContext::ImpSetGraphicStyles() const
+{
+ if(GetSdImport().GetLocalDocStyleFamilies().is()) try
+ {
+ uno::Reference< container::XNameAccess > xGraphicPageStyles( GetSdImport().GetLocalDocStyleFamilies()->getByName("graphics"), uno::UNO_QUERY_THROW );
+
+ ImpSetGraphicStyles(xGraphicPageStyles, XmlStyleFamily::SD_GRAPHICS_ID, u"");
+ }
+ catch( uno::Exception& )
+ {
+ TOOLS_WARN_EXCEPTION("xmloff.draw", "");
+ }
+}
+
+void SdXMLStylesContext::ImpSetCellStyles() const
+{
+ if(GetSdImport().GetLocalDocStyleFamilies().is()) try
+ {
+ uno::Reference< container::XNameAccess > xGraphicPageStyles( GetSdImport().GetLocalDocStyleFamilies()->getByName("cell"), uno::UNO_QUERY_THROW );
+
+ ImpSetGraphicStyles(xGraphicPageStyles, XmlStyleFamily::TABLE_CELL, u"");
+ }
+ catch( uno::Exception& )
+ {
+ TOOLS_WARN_EXCEPTION("xmloff.draw", "");
+ }
+}
+
+//Resolves: fdo#34987 if the style's auto height before and after is the same
+//then don't reset it back to the underlying default of true for the small
+//period before it's going to be reset to false again. Doing this avoids the
+//master page shapes from resizing themselves due to autoheight becoming
+//enabled before having autoheight turned off again and getting stuck on that
+//autosized height
+static bool canSkipReset(std::u16string_view rName, const XMLPropStyleContext* pPropStyle,
+ const uno::Reference< beans::XPropertySet > &rPropSet, const rtl::Reference < XMLPropertySetMapper >& rPrMap)
+{
+ bool bCanSkipReset = false;
+ if (pPropStyle && rName == u"TextAutoGrowHeight")
+ {
+ bool bOldStyleTextAutoGrowHeight(false);
+ rPropSet->getPropertyValue("TextAutoGrowHeight") >>= bOldStyleTextAutoGrowHeight;
+
+ sal_Int32 nIndexStyle = rPrMap->GetEntryIndex(XML_NAMESPACE_DRAW, u"auto-grow-height", 0);
+ if (nIndexStyle != -1)
+ {
+ const ::std::vector< XMLPropertyState > &rProperties = pPropStyle->GetProperties();
+ auto property = std::find_if(rProperties.cbegin(), rProperties.cend(),
+ [nIndexStyle](const XMLPropertyState& rProp) { return rProp.mnIndex == nIndexStyle; });
+ if (property != rProperties.cend())
+ {
+ bool bNewStyleTextAutoGrowHeight(false);
+ property->maValue >>= bNewStyleTextAutoGrowHeight;
+ bCanSkipReset = (bNewStyleTextAutoGrowHeight == bOldStyleTextAutoGrowHeight);
+ }
+ }
+ }
+ return bCanSkipReset;
+}
+
+// help function used by ImpSetGraphicStyles() and ImpSetMasterPageStyles()
+
+void SdXMLStylesContext::ImpSetGraphicStyles( uno::Reference< container::XNameAccess > const & xPageStyles, XmlStyleFamily nFamily, std::u16string_view rPrefix) const
+{
+ sal_Int32 nPrefLen(rPrefix.size());
+
+ sal_uInt32 a;
+
+ // set defaults
+ for( a = 0; a < GetStyleCount(); a++)
+ {
+ const SvXMLStyleContext* pStyle = GetStyle(a);
+
+ if(nFamily == pStyle->GetFamily() && pStyle->IsDefaultStyle())
+ {
+ const_cast<SvXMLStyleContext*>(pStyle)->SetDefaults();
+ }
+ }
+
+ // create all styles and set properties
+ for( a = 0; a < GetStyleCount(); a++)
+ {
+ try
+ {
+ const SvXMLStyleContext* pStyle = GetStyle(a);
+ if(nFamily == pStyle->GetFamily() && !pStyle->IsDefaultStyle())
+ {
+ OUString aStyleName(pStyle->GetDisplayName());
+
+ if( nPrefLen )
+ {
+ sal_Int32 nStylePrefLen = aStyleName.lastIndexOf( '-' ) + 1;
+ if( (nPrefLen != nStylePrefLen) || !aStyleName.startsWith(rPrefix) )
+ continue;
+
+ aStyleName = aStyleName.copy( nPrefLen );
+ }
+
+ XMLPropStyleContext* pPropStyle = dynamic_cast< XMLPropStyleContext* >(const_cast< SvXMLStyleContext* >( pStyle ) );
+
+ uno::Reference< style::XStyle > xStyle;
+ if(xPageStyles->hasByName(aStyleName))
+ {
+ xPageStyles->getByName(aStyleName) >>= xStyle;
+
+ // set properties of existing styles to default
+ uno::Reference< beans::XPropertySet > xPropSet( xStyle, uno::UNO_QUERY );
+ uno::Reference< beans::XPropertySetInfo > xPropSetInfo;
+ if( xPropSet.is() )
+ xPropSetInfo = xPropSet->getPropertySetInfo();
+
+ uno::Reference< beans::XPropertyState > xPropState( xStyle, uno::UNO_QUERY );
+
+ if( xPropState.is() )
+ {
+ rtl::Reference < XMLPropertySetMapper > xPrMap;
+ rtl::Reference < SvXMLImportPropertyMapper > xImpPrMap = GetImportPropertyMapper( nFamily );
+ SAL_WARN_IF( !xImpPrMap.is(), "xmloff", "There is the import prop mapper" );
+ if( xImpPrMap.is() )
+ xPrMap = xImpPrMap->getPropertySetMapper();
+ if( xPrMap.is() )
+ {
+ const sal_Int32 nCount = xPrMap->GetEntryCount();
+ for( sal_Int32 i = 0; i < nCount; i++ )
+ {
+ const OUString& rName = xPrMap->GetEntryAPIName( i );
+ if( xPropSetInfo->hasPropertyByName( rName ) && beans::PropertyState_DIRECT_VALUE == xPropState->getPropertyState( rName ) )
+ {
+ bool bCanSkipReset = canSkipReset(rName, pPropStyle, xPropSet, xPrMap);
+ if (bCanSkipReset)
+ continue;
+ xPropState->setPropertyToDefault( rName );
+ }
+ }
+ }
+ }
+ }
+ else
+ {
+ // graphics style does not exist, create and add it
+ uno::Reference< lang::XSingleServiceFactory > xServiceFact(xPageStyles, uno::UNO_QUERY);
+ if(xServiceFact.is())
+ {
+ uno::Reference< style::XStyle > xNewStyle( xServiceFact->createInstance(), uno::UNO_QUERY);
+
+ if(xNewStyle.is())
+ {
+ // remember style
+ xStyle = xNewStyle;
+
+ // add new style to graphics style pool
+ uno::Reference< container::XNameContainer > xInsertContainer(xPageStyles, uno::UNO_QUERY);
+ if(xInsertContainer.is())
+ xInsertContainer->insertByName(aStyleName, uno::Any( xStyle ) );
+ }
+ }
+ }
+
+ if(xStyle.is())
+ {
+ // set properties at style
+ uno::Reference< beans::XPropertySet > xPropSet(xStyle, uno::UNO_QUERY);
+ if(xPropSet.is() && pPropStyle)
+ {
+ pPropStyle->FillPropertySet(xPropSet);
+ pPropStyle->SetStyle(xStyle);
+ }
+ }
+ }
+ }
+ catch(const Exception& e)
+ {
+ const_cast<SdXMLImport*>(&GetSdImport())->SetError( XMLERROR_FLAG_WARNING | XMLERROR_API, {}, e.Message, nullptr );
+ }
+ }
+
+ // now set parents for all styles (when necessary)
+ for(a = 0; a < GetStyleCount(); a++)
+ {
+ const SvXMLStyleContext* pStyle = GetStyle(a);
+
+ if(pStyle && !pStyle->GetDisplayName().isEmpty() && (nFamily == pStyle->GetFamily())) try
+ {
+ OUString aStyleName(pStyle->GetDisplayName());
+ if( nPrefLen )
+ {
+ sal_Int32 nStylePrefLen = aStyleName.lastIndexOf( '-' ) + 1;
+ if( (nPrefLen != nStylePrefLen) || !aStyleName.startsWith( rPrefix ) )
+ continue;
+
+ aStyleName = aStyleName.copy( nPrefLen );
+ }
+
+ uno::Reference< style::XStyle > xStyle( xPageStyles->getByName(aStyleName), UNO_QUERY );
+ if(xStyle.is())
+ {
+ // set parent style name
+ OUString sParentStyleDisplayName( GetImport().GetStyleDisplayName( pStyle->GetFamily(), pStyle->GetParentName() ) );
+ if( nPrefLen )
+ {
+ sal_Int32 nStylePrefLen = sParentStyleDisplayName.lastIndexOf( '-' ) + 1;
+ if( (nPrefLen != nStylePrefLen) || !sParentStyleDisplayName.startsWith( rPrefix ) )
+ continue;
+
+ sParentStyleDisplayName = sParentStyleDisplayName.copy( nPrefLen );
+ }
+ xStyle->setParentStyle( sParentStyleDisplayName );
+ }
+ }
+ catch( const Exception& e )
+ {
+ const_cast<SdXMLImport*>(&GetSdImport())->SetError( XMLERROR_FLAG_WARNING | XMLERROR_API, {}, e.Message, nullptr );
+ }
+ }
+}
+
+// helper function to create the uno component that hold the mappings from
+// xml auto layout name to internal autolayout id
+
+uno::Reference< container::XNameAccess > SdXMLStylesContext::getPageLayouts() const
+{
+ uno::Reference< container::XNameContainer > xLayouts( comphelper::NameContainer_createInstance( ::cppu::UnoType<sal_Int32>::get()) );
+
+ for(sal_uInt32 a(0); a < GetStyleCount(); a++)
+ {
+ const SvXMLStyleContext* pStyle = GetStyle(a);
+ if (const SdXMLPresentationPageLayoutContext* pContext = dynamic_cast<const SdXMLPresentationPageLayoutContext*>(pStyle))
+ {
+ xLayouts->insertByName(pStyle->GetName(), uno::Any(static_cast<sal_Int32>(pContext->GetTypeId())));
+ }
+ }
+
+ return xLayouts;
+}
+
+
+SdXMLMasterStylesContext::SdXMLMasterStylesContext(
+ SdXMLImport& rImport)
+: SvXMLImportContext( rImport )
+{
+}
+
+css::uno::Reference< css::xml::sax::XFastContextHandler > SdXMLMasterStylesContext::createFastChildContext(
+ sal_Int32 nElement,
+ const css::uno::Reference< css::xml::sax::XFastAttributeList >& xAttrList )
+{
+ if( nElement == XML_ELEMENT(DRAW, XML_LAYER_SET) )
+ {
+ return new SdXMLLayerSetContext( GetImport() );
+ }
+ else if( nElement == XML_ELEMENT(STYLE, XML_MASTER_PAGE) )
+ {
+ // style:masterpage inside office:styles context
+ uno::Reference< drawing::XDrawPage > xNewMasterPage;
+ uno::Reference< drawing::XDrawPages > xMasterPages(GetSdImport().GetLocalMasterPages(), uno::UNO_QUERY);
+
+ if( xMasterPages.is() )
+ {
+ sal_Int32 nNewMasterPageCount = GetSdImport().GetNewMasterPageCount();
+ sal_Int32 nMasterPageCount = xMasterPages->getCount();
+ if (nNewMasterPageCount + 1 > nMasterPageCount)
+ {
+ // arbitrary limit to master pages when fuzzing to avoid deadend timeouts
+ if (nMasterPageCount >= 64 && utl::ConfigManager::IsFuzzing())
+ return nullptr;
+
+ // new page, create and insert
+ xNewMasterPage = xMasterPages->insertNewByIndex(nMasterPageCount);
+ }
+ else
+ {
+ // existing page, use it
+ xMasterPages->getByIndex(nNewMasterPageCount) >>= xNewMasterPage;
+ }
+
+ // increment global import page counter
+ GetSdImport().IncrementNewMasterPageCount();
+
+ if(xNewMasterPage.is())
+ {
+ if(GetSdImport().GetShapeImport()->GetStylesContext())
+ {
+ const rtl::Reference<SdXMLMasterPageContext> xLclContext{
+ new SdXMLMasterPageContext(GetSdImport(),
+ nElement, xAttrList, xNewMasterPage)};
+ maMasterPageList.push_back(xLclContext);
+ return xLclContext;
+ }
+ }
+ }
+ }
+ else if( nElement == XML_ELEMENT(STYLE, XML_HANDOUT_MASTER) )
+ {
+ uno::Reference< presentation::XHandoutMasterSupplier > xHandoutSupp( GetSdImport().GetModel(), uno::UNO_QUERY );
+ if( xHandoutSupp.is() )
+ {
+ uno::Reference< drawing::XShapes > xHandoutPage = xHandoutSupp->getHandoutMasterPage();
+ if(xHandoutPage.is() && GetSdImport().GetShapeImport()->GetStylesContext())
+ {
+ return new SdXMLMasterPageContext(GetSdImport(),
+ nElement, xAttrList, xHandoutPage);
+ }
+ }
+ }
+ else
+ XMLOFF_WARN_UNKNOWN_ELEMENT("xmloff", nElement);
+ return nullptr;
+}
+
+SdXMLHeaderFooterDeclContext::SdXMLHeaderFooterDeclContext(SvXMLImport& rImport,
+ const css::uno::Reference< css::xml::sax::XFastAttributeList >& xAttrList)
+ : SvXMLStyleContext( rImport )
+ , mbFixed(false)
+{
+ for (auto &aIter : sax_fastparser::castToFastAttributeList( xAttrList ))
+ {
+ if( aIter.getToken() == XML_ELEMENT(PRESENTATION, XML_NAME) )
+ {
+ maStrName = aIter.toString();
+ }
+ else if( aIter.getToken() == XML_ELEMENT(PRESENTATION, XML_SOURCE) )
+ {
+ mbFixed = IsXMLToken( aIter, XML_FIXED );
+ }
+ else if( aIter.getToken() == XML_ELEMENT(STYLE, XML_DATA_STYLE_NAME) )
+ {
+ maStrDateTimeFormat = aIter.toString();
+ }
+ else
+ {
+ XMLOFF_WARN_UNKNOWN("xmloff", aIter);
+ }
+ }
+}
+
+bool SdXMLHeaderFooterDeclContext::IsTransient() const
+{
+ return true;
+}
+
+void SdXMLHeaderFooterDeclContext::endFastElement(sal_Int32 nToken)
+{
+ SdXMLImport& rImport = dynamic_cast<SdXMLImport&>(GetImport());
+ auto nElement = nToken & TOKEN_MASK;
+ if( nElement == XML_HEADER_DECL )
+ {
+ rImport.AddHeaderDecl( maStrName, maStrText );
+ }
+ else if( nElement == XML_FOOTER_DECL )
+ {
+ rImport.AddFooterDecl( maStrName, maStrText );
+ }
+ else if( nElement == XML_DATE_TIME_DECL )
+ {
+ rImport.AddDateTimeDecl( maStrName, maStrText, mbFixed, maStrDateTimeFormat );
+ }
+ else
+ {
+ XMLOFF_WARN_UNKNOWN_ELEMENT("xmloff", nToken);
+ }
+}
+
+void SdXMLHeaderFooterDeclContext::characters( const OUString& rChars )
+{
+ maStrText += rChars;
+}
+
+namespace xmloff {
+
+bool IsIgnoreFillStyleNamedItem(
+ css::uno::Reference<css::beans::XPropertySet> const& xProps,
+ drawing::FillStyle const nExpectedFillStyle)
+{
+ assert(xProps.is());
+ if (nExpectedFillStyle == drawing::FillStyle::FillStyle_MAKE_FIXED_SIZE)
+ {
+ return false;
+ }
+
+ // note: the caller must have called FillPropertySet() previously
+ drawing::FillStyle fillStyle{drawing::FillStyle_NONE};
+ xProps->getPropertyValue("FillStyle") >>= fillStyle;
+ return fillStyle != nExpectedFillStyle;
+}
+
+} // namespace xmloff
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/xmloff/source/draw/ximpstyl.hxx b/xmloff/source/draw/ximpstyl.hxx
new file mode 100644
index 0000000000..b26e46eacd
--- /dev/null
+++ b/xmloff/source/draw/ximpstyl.hxx
@@ -0,0 +1,247 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#pragma once
+
+#include <svl/zforlist.hxx>
+#include <xmloff/xmlictxt.hxx>
+#include <xmloff/xmlimppr.hxx>
+#include <xmloff/xmlnumfi.hxx>
+#include "sdxmlimp_impl.hxx"
+#include "ximppage.hxx"
+#include <xmloff/xmlstyle.hxx>
+#include <com/sun/star/view/PaperOrientation.hpp>
+#include <memory>
+#include <vector>
+
+class SvNumberFormatter;
+class SvXMLNumFmtHelper;
+
+// special style:style context inside style:page-master context
+
+class SdXMLPageMasterStyleContext: public SvXMLStyleContext
+{
+ sal_Int32 mnBorderBottom;
+ sal_Int32 mnBorderLeft;
+ sal_Int32 mnBorderRight;
+ sal_Int32 mnBorderTop;
+ sal_Int32 mnWidth;
+ sal_Int32 mnHeight;
+ css::view::PaperOrientation meOrientation;
+
+ const SdXMLImport& GetSdImport() const { return static_cast<const SdXMLImport&>(GetImport()); }
+ SdXMLImport& GetSdImport() { return static_cast<SdXMLImport&>(GetImport()); }
+
+public:
+
+ SdXMLPageMasterStyleContext(
+ SdXMLImport& rImport,
+ sal_Int32 nElement,
+ const css::uno::Reference< css::xml::sax::XFastAttributeList >& xAttrList);
+ virtual ~SdXMLPageMasterStyleContext() override;
+
+ sal_Int32 GetBorderBottom() const { return mnBorderBottom; }
+ sal_Int32 GetBorderLeft() const { return mnBorderLeft; }
+ sal_Int32 GetBorderRight() const { return mnBorderRight; }
+ sal_Int32 GetBorderTop() const { return mnBorderTop; }
+ sal_Int32 GetWidth() const { return mnWidth; }
+ sal_Int32 GetHeight() const { return mnHeight; }
+ css::view::PaperOrientation GetOrientation() const { return meOrientation; }
+};
+
+// style:page-master context
+
+class SdXMLPageMasterContext: public SvXMLStyleContext
+{
+ rtl::Reference<SdXMLPageMasterStyleContext> mxPageMasterStyle;
+
+ const SdXMLImport& GetSdImport() const { return static_cast<const SdXMLImport&>(GetImport()); }
+ SdXMLImport& GetSdImport() { return static_cast<SdXMLImport&>(GetImport()); }
+
+public:
+
+ SdXMLPageMasterContext(
+ SdXMLImport& rImport,
+ sal_Int32 nElement,
+ const css::uno::Reference< css::xml::sax::XFastAttributeList >& xAttrList);
+
+ virtual css::uno::Reference< css::xml::sax::XFastContextHandler > SAL_CALL createFastChildContext(
+ sal_Int32 nElement, const css::uno::Reference< css::xml::sax::XFastAttributeList >& AttrList ) override;
+
+ const SdXMLPageMasterStyleContext* GetPageMasterStyle() const { return mxPageMasterStyle.get(); }
+};
+
+// style:masterpage context
+
+class SdXMLMasterPageContext: public SdXMLGenericPageContext
+{
+ OUString msName;
+ OUString msDisplayName;
+
+public:
+
+ SdXMLMasterPageContext(
+ SdXMLImport& rImport,
+ sal_Int32 nElement,
+ const css::uno::Reference< css::xml::sax::XFastAttributeList >& xAttrList,
+ css::uno::Reference< css::drawing::XShapes > const & rShapes);
+ virtual ~SdXMLMasterPageContext() override;
+
+ virtual css::uno::Reference< css::xml::sax::XFastContextHandler > SAL_CALL createFastChildContext(
+ sal_Int32 nElement,
+ const css::uno::Reference< css::xml::sax::XFastAttributeList >& AttrList ) override;
+
+ virtual void SAL_CALL endFastElement(sal_Int32 nElement) override;
+
+ const OUString& GetDisplayName() const { return msDisplayName; }
+
+};
+
+// presentation:placeholder context
+
+class SdXMLPresentationPlaceholderContext: public SvXMLImportContext
+{
+ OUString msName;
+ sal_Int32 mnX;
+
+ const SdXMLImport& GetSdImport() const { return static_cast<const SdXMLImport&>(GetImport()); }
+ SdXMLImport& GetSdImport() { return static_cast<SdXMLImport&>(GetImport()); }
+
+public:
+ SdXMLPresentationPlaceholderContext(
+ SdXMLImport& rImport,
+ sal_Int32 nElement,
+ const css::uno::Reference< css::xml::sax::XFastAttributeList >& xAttrList);
+ virtual ~SdXMLPresentationPlaceholderContext() override;
+
+ const OUString& GetName() const { return msName; }
+ sal_Int32 GetX() const { return mnX; }
+};
+
+// style:presentation-page-layout context
+
+class SdXMLPresentationPageLayoutContext: public SvXMLStyleContext
+{
+ std::vector< rtl::Reference< SdXMLPresentationPlaceholderContext > >
+ maList;
+ sal_uInt16 mnTypeId;
+
+ const SdXMLImport& GetSdImport() const { return static_cast<const SdXMLImport&>(GetImport()); }
+ SdXMLImport& GetSdImport() { return static_cast<SdXMLImport&>(GetImport()); }
+
+public:
+
+ SdXMLPresentationPageLayoutContext(
+ SdXMLImport& rImport,
+ sal_Int32 nElement,
+ const css::uno::Reference< css::xml::sax::XFastAttributeList >& xAttrList);
+
+ virtual css::uno::Reference< css::xml::sax::XFastContextHandler > SAL_CALL createFastChildContext(
+ sal_Int32 nElement, const css::uno::Reference< css::xml::sax::XFastAttributeList >& AttrList ) override;
+
+ virtual void SAL_CALL endFastElement(sal_Int32 nElement) override;
+
+ sal_uInt16 GetTypeId() const { return mnTypeId; }
+};
+
+// office:styles context
+
+class SdXMLStylesContext : public SvXMLStylesContext
+{
+ rtl::Reference< SvXMLImportPropertyMapper > xPresImpPropMapper;
+ bool mbIsAutoStyle;
+ std::unique_ptr<SvXMLNumFmtHelper> mpNumFmtHelper;
+ std::unique_ptr<SvNumberFormatter> mpNumFormatter;
+
+ const SdXMLImport& GetSdImport() const { return static_cast<const SdXMLImport&>(GetImport()); }
+ SdXMLImport& GetSdImport() { return static_cast<SdXMLImport&>(GetImport()); }
+
+ void ImpSetGraphicStyles() const;
+ void ImpSetCellStyles() const;
+ void ImpSetGraphicStyles( css::uno::Reference< css::container::XNameAccess > const & xPageStyles,
+ XmlStyleFamily nFamily, std::u16string_view rPrefix) const;
+
+protected:
+ using SvXMLStylesContext::CreateStyleChildContext;
+ virtual SvXMLStyleContext* CreateStyleChildContext(
+ sal_Int32 nElement,
+ const css::uno::Reference< css::xml::sax::XFastAttributeList >& xAttrList) override;
+
+ using SvXMLStylesContext::CreateStyleStyleChildContext;
+ virtual SvXMLStyleContext *CreateStyleStyleChildContext(
+ XmlStyleFamily nFamily,
+ sal_Int32 nElement,
+ const css::uno::Reference< css::xml::sax::XFastAttributeList >& xAttrList) override;
+
+ using SvXMLStylesContext::CreateDefaultStyleStyleChildContext;
+ virtual SvXMLStyleContext *CreateDefaultStyleStyleChildContext(
+ XmlStyleFamily nFamily,
+ sal_Int32 nElement,
+ const css::uno::Reference< css::xml::sax::XFastAttributeList >& xAttrList) override;
+public:
+
+ SdXMLStylesContext(
+ SdXMLImport& rImport,
+ bool bIsAutoStyle);
+
+ virtual void SAL_CALL endFastElement(sal_Int32 nElement) override;
+ virtual rtl::Reference< SvXMLImportPropertyMapper > GetImportPropertyMapper(XmlStyleFamily nFamily) const override;
+
+ void SetMasterPageStyles(SdXMLMasterPageContext const & rMaster) const;
+
+ css::uno::Reference< css::container::XNameAccess > getPageLayouts() const;
+};
+
+// office:master-styles context
+
+class SdXMLMasterStylesContext : public SvXMLImportContext
+{
+ std::vector< rtl::Reference< SdXMLMasterPageContext > > maMasterPageList;
+
+ const SdXMLImport& GetSdImport() const { return static_cast<const SdXMLImport&>(GetImport()); }
+ SdXMLImport& GetSdImport() { return static_cast<SdXMLImport&>(GetImport()); }
+
+public:
+
+ SdXMLMasterStylesContext(SdXMLImport& rImport);
+
+ virtual css::uno::Reference< css::xml::sax::XFastContextHandler > SAL_CALL createFastChildContext(
+ sal_Int32 nElement, const css::uno::Reference< css::xml::sax::XFastAttributeList >& AttrList ) override;
+};
+
+// <pres:header-decl>, <pres:footer-decl> and <pres:date-time-decl>
+
+class SdXMLHeaderFooterDeclContext : public SvXMLStyleContext
+{
+public:
+ SdXMLHeaderFooterDeclContext( SvXMLImport& rImport,
+ const css::uno::Reference< css::xml::sax::XFastAttributeList >& xAttrList );
+
+ virtual bool IsTransient() const override;
+ virtual void SAL_CALL endFastElement(sal_Int32 ) override;
+ virtual void SAL_CALL characters( const OUString& rChars ) override;
+
+private:
+ OUString maStrName;
+ OUString maStrText;
+ OUString maStrDateTimeFormat;
+ bool mbFixed;
+};
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */