external/boost/include/boost/property_tree/info_parser.hpp |   32 +
 include/oox/drawingml/diagram/diagramhelper_oox.hxx        |   14 
 include/svx/diagram/DiagramHelper_svx.hxx                  |   21 
 include/svx/diagram/datamodel_svx.hxx                      |  118 +++--
 include/svx/svdogrp.hxx                                    |    3 
 oox/source/drawingml/diagram/datamodel_oox.cxx             |    9 
 oox/source/drawingml/diagram/datamodel_oox.hxx             |    1 
 oox/source/drawingml/diagram/diagram.cxx                   |  146 ++++++
 oox/source/drawingml/diagram/diagram.hxx                   |    7 
 oox/source/drawingml/diagram/diagramhelper_oox.cxx         |   51 ++
 svx/source/diagram/DiagramHelper_svx.cxx                   |   16 
 svx/source/diagram/datamodel_svx.cxx                       |  290 +++++++++++--
 svx/source/svdraw/svdogrp.cxx                              |   84 +++
 svx/source/xml/xmlexport.cxx                               |   10 
 14 files changed, 723 insertions(+), 79 deletions(-)

New commits:
commit 09605513f455972a3ad64d3bf4b5fe12af87e483
Author:     Armin Le Grand (collabora) <[email protected]>
AuthorDate: Tue Feb 24 15:09:24 2026 +0100
Commit:     Armin Le Grand <[email protected]>
CommitDate: Thu Feb 26 16:42:59 2026 +0100

    SmartArt: Progress in standard FileFormat RoundTrip
    
    Added functionality to ex/import using boost::property_tree
    and it's read/write_info functionality, based on conversion
    to/from OUString. This keeps it most user-readable in XML
    format. I currently use <svg:desc> to add it, secured by a
    token and preserving evtl. existing Description at the
    GroupObject hosting the Diagram, but may move somewhere
    else. This has the advantage that <svg:desc> is supported
    since version 1.0 and the SmartArt/Diagram ModelData *is*
    the object's Description. Not sure yet, we will see.
    
    There were some hard parts, e.g. I needed to find a way to
    incarnate a class defined in oox inside svx and that class
    is derived from baseclass in svx in oox, but got that done.
    
    Still secured by ACTIVATE_ADVANCED_DIAGRAM_FEATURES since
    this will still need some corrections, but basic round-trip
    is functional.
    
    This will allow to copy/paste between two office instances
    and is also the base for thinking about providing gallery
    functionality for Diagrams.
    
    Had some problems with boost/property_tree stuff var
    shadowing, also lock of model was missing in
    SvxDrawingLayerExport, will change that in next version
    to ssth more sophisticated.
    
    Change-Id: I526d3b2477b5de40df990345c9c06d0a2f9cbfeb
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/200219
    Tested-by: Jenkins
    Reviewed-by: Armin Le Grand <[email protected]>

diff --git a/external/boost/include/boost/property_tree/info_parser.hpp 
b/external/boost/include/boost/property_tree/info_parser.hpp
new file mode 100644
index 000000000000..fe4c44aa4a88
--- /dev/null
+++ b/external/boost/include/boost/property_tree/info_parser.hpp
@@ -0,0 +1,32 @@
+/* generated by bin/gen-boost-headers, do not edit! */
+#pragma once
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wpragmas"  /* first! for GCC */
+#pragma GCC diagnostic ignored "-Wunknown-warning-option" // second! for Clang 
5
+#pragma GCC diagnostic ignored "-Wdelete-non-virtual-dtor"
+#pragma GCC diagnostic ignored "-Wdeprecated-builtins"
+#pragma GCC diagnostic ignored "-Wdeprecated-declarations"
+#pragma GCC diagnostic ignored "-Wdeprecated-copy"
+#pragma GCC diagnostic ignored "-Wdeprecated-copy-dtor"
+#pragma GCC diagnostic ignored "-Wextra"
+#pragma GCC diagnostic ignored "-Wignored-qualifiers"
+#pragma GCC diagnostic ignored "-Wimplicit-fallthrough"
+#pragma GCC diagnostic ignored "-Winvalid-constexpr"
+#pragma GCC diagnostic ignored "-Wmaybe-uninitialized"
+#pragma GCC diagnostic ignored "-Wmicrosoft-unqualified-friend"
+#pragma GCC diagnostic ignored "-Wnonnull"
+#pragma GCC diagnostic ignored "-Wparentheses"
+#pragma GCC diagnostic ignored "-Wplacement-new"
+#pragma GCC diagnostic ignored "-Wreturn-type"
+#pragma GCC diagnostic ignored "-Wshadow"
+#pragma GCC diagnostic ignored "-Wstrict-aliasing"
+#pragma GCC diagnostic ignored "-Wtautological-constant-out-of-range-compare"
+#pragma GCC diagnostic ignored "-Wtype-limits"
+#pragma GCC diagnostic ignored "-Wundef"
+#pragma GCC diagnostic ignored "-Wunused-but-set-variable"
+#pragma GCC diagnostic ignored "-Wunused-local-typedefs"
+#pragma GCC diagnostic ignored "-Wunused-macros"
+#pragma GCC diagnostic ignored "-Wunused-parameter"
+#pragma GCC diagnostic ignored "-Wunused-variable"
+#include_next <boost/property_tree/info_parser.hpp>
+#pragma GCC diagnostic pop
diff --git a/include/oox/drawingml/diagram/diagramhelper_oox.hxx 
b/include/oox/drawingml/diagram/diagramhelper_oox.hxx
index 30367e0b2930..d6e31592d20d 100644
--- a/include/oox/drawingml/diagram/diagramhelper_oox.hxx
+++ b/include/oox/drawingml/diagram/diagramhelper_oox.hxx
@@ -71,6 +71,7 @@ public:
         std::shared_ptr<::oox::drawingml::Theme> xTheme,
         css::awt::Size aImportSize);
     explicit DiagramHelper_oox(DiagramHelper_oox const& rSource);
+    explicit DiagramHelper_oox(const boost::property_tree::ptree& 
rDiagramModel);
     virtual ~DiagramHelper_oox();
 
     // re-create XShapes
@@ -110,6 +111,19 @@ public:
 
     // needed to create DiagramHelper_oox in svx' SdrObjGroup copy constructor
     virtual DiagramHelper_oox* clone() const override;
+
+    // write data to boost::property_tree
+    virtual void addDiagramModelData(boost::property_tree::ptree& rTarget) 
const override;
+};
+
+class DiagramHelperFactory_oox : public svx::diagram::DiagramHelperFactory_svx
+{
+public:
+    DiagramHelperFactory_oox();
+    virtual ~DiagramHelperFactory_oox();
+
+    // overloaded here to allow instantiation of a DiagramHelper_oox
+    virtual std::shared_ptr<svx::diagram::DiagramHelper_svx> 
createDiagramHelper_svx(boost::property_tree::ptree& rTarget) const override;
 };
 
 }
diff --git a/include/svx/diagram/DiagramHelper_svx.hxx 
b/include/svx/diagram/DiagramHelper_svx.hxx
index 60bd7c37754b..580e1597ffe5 100644
--- a/include/svx/diagram/DiagramHelper_svx.hxx
+++ b/include/svx/diagram/DiagramHelper_svx.hxx
@@ -134,6 +134,27 @@ public:
 
     // needed to create DiagramHelper_oox in svx' SdrObjGroup copy constructor
     virtual DiagramHelper_svx* clone() const = 0;
+
+    // write data to boost::property_tree
+    virtual void addDiagramModelData(boost::property_tree::ptree& rTarget) 
const = 0;
+};
+
+class SVXCORE_DLLPUBLIC DiagramHelperFactory_svx
+{
+protected:
+    // do prohibit direct instantiation, only DiagramHelper_oox is intended
+    DiagramHelperFactory_svx();
+
+    // keep global var of this module hidden
+    static DiagramHelperFactory_svx* pSingleGlobalDiagramHelperFactory_svx;
+
+public:
+    // try to access global static single instance of DiagramHelperFactory
+    static DiagramHelperFactory_svx& getDiagramHelperFactory_svx();
+
+    // virtual call to instantiate a new DiagramHelper, overloaded in oox to
+    // allow instantiation of a DiagramHelper_oox
+    virtual std::shared_ptr<svx::diagram::DiagramHelper_svx> 
createDiagramHelper_svx(boost::property_tree::ptree& rTarget) const = 0;
 };
 
 }} // end of namespace
diff --git a/include/svx/diagram/datamodel_svx.hxx 
b/include/svx/diagram/datamodel_svx.hxx
index d2990e000f61..3ae95d7ac54a 100644
--- a/include/svx/diagram/datamodel_svx.hxx
+++ b/include/svx/diagram/datamodel_svx.hxx
@@ -35,6 +35,7 @@
 #include <com/sun/star/drawing/XShape.hpp>
 #include <oox/token/tokens.hxx>
 #include <sax/fshelper.hxx>
+#include <boost/property_tree/ptree.hpp>
 
 namespace svx::diagram {
 
@@ -59,18 +60,21 @@ enum TypeConstant {
 struct SVXCORE_DLLPUBLIC Connection
 {
     Connection();
-
-    TypeConstant mnXMLType; // default is XML_parOf
-    OUString msModelId;
-    OUString msSourceId;
-    OUString msDestId;
-    OUString msParTransId;
-    OUString msPresId;
-    OUString msSibTransId;
-    sal_Int32 mnSourceOrder;
-    sal_Int32 mnDestOrder;
+    explicit Connection(const boost::property_tree::ptree& rConnectionData);
+
+    /* DEFAULT      Variable        varName    XML_Tag */
+    /* XML_parOf */ TypeConstant    mnXMLType; // XML_type
+    /* (empty)   */ OUString        msModelId; // XML_modelId
+    /* (empty)   */ OUString        msSourceId; // XML_srcId
+    /* (empty)   */ OUString        msDestId; // XML_destId
+    /* (empty)   */ OUString        msPresId; // XML_presId
+    /* (empty)   */ OUString        msSibTransId; // XML_sibTransId
+    /* (empty)   */ OUString        msParTransId; // XML_parTransId
+    /* 0         */ sal_Int32       mnSourceOrder; // XML_srcOrd
+    /* 0         */ sal_Int32       mnDestOrder; // XML_destOrd
 
     void writeDiagramData(sax_fastparser::FSHelperPtr& rTarget);
+    void addDiagramModelData(boost::property_tree::ptree& rTarget) const;
 };
 
 typedef std::vector< Connection > Connections;
@@ -80,57 +84,64 @@ typedef std::vector< Connection > Connections;
 struct SVXCORE_DLLPUBLIC Point
 {
     Point();
+    explicit Point(const boost::property_tree::ptree& rPointData);
 
     // PT: dgm:pt
     // PRS: dgm:prSet
     // PLV: dgm:presLayoutVars
 
-    /* PT  */ OUString msCnxId;
-    /* PT  */ OUString msModelId;
-    /* PRS */ OUString msColorTransformCategoryId;
-    /* PRS */ OUString msColorTransformTypeId;
-    /* PRS */ OUString msLayoutCategoryId;
-    /* PRS */ OUString msLayoutTypeId;
-    /* PRS */ OUString msPlaceholderText;
-    /* PRS */ OUString msPresentationAssociationId;
-    /* PRS */ OUString msPresentationLayoutName;
-    /* PRS */ OUString msPresentationLayoutStyleLabel;
-    /* PRS */ OUString msQuickStyleCategoryId;
-    /* PRS */ OUString msQuickStyleTypeId;
-    /* PLV */ OUString msResizeHandles;
-
-    /* PT  */ TypeConstant mnXMLType; // default is XML_node
-    /* PLV */ sal_Int32 mnMaxChildren;
-    /* PLV */ sal_Int32 mnPreferredChildren;
-    /* PLV */ sal_Int32 mnDirection;
-    /* PLV */ std::optional<sal_Int32> moHierarchyBranch;
-
-    /* PRS */ sal_Int32 mnCustomAngle;
-    /* PRS */ sal_Int32 mnPercentageNeighbourWidth;
-    /* PRS */ sal_Int32 mnPercentageNeighbourHeight;
-    /* PRS */ sal_Int32 mnPercentageOwnWidth;
-    /* PRS */ sal_Int32 mnPercentageOwnHeight;
-    /* PRS */ sal_Int32 mnIncludeAngleScale;
-    /* PRS */ sal_Int32 mnRadiusScale;
-    /* PRS */ sal_Int32 mnWidthScale;
-    /* PRS */ sal_Int32 mnHeightScale;
-    /* PRS */ sal_Int32 mnWidthOverride;
-    /* PRS */ sal_Int32 mnHeightOverride;
-    /* PRS */ sal_Int32 mnLayoutStyleCount;
-    /* PRS */ sal_Int32 mnLayoutStyleIndex;
-
-    /* PLV */ bool mbOrgChartEnabled : 1;
-    /* PLV */ bool mbBulletEnabled : 1;
-    /* PRS */ bool mbCoherent3DOffset : 1;
-    /* PRS */ bool mbCustomHorizontalFlip : 1;
-    /* PRS */ bool mbCustomVerticalFlip : 1;
-    /* PRS */ bool mbCustomText : 1;
-    /* PRS */ bool mbIsPlaceholder : 1;
+    /* TYP DEFAULT     Variable     varName  XML_Tag */
+    /* PT  (empty)  */ OUString     msCnxId; // XML_cxnId
+    /* PT  (empty)  */ OUString     msModelId; // XML_modelId
+    /* PRS (empty)  */ OUString     msColorTransformCategoryId; // XML_csCatId
+    /* PRS (empty)  */ OUString     msColorTransformTypeId; // XML_csTypeId
+    /* PRS (empty)  */ OUString     msLayoutCategoryId; // XML_loCatId
+    /* PRS (empty)  */ OUString     msLayoutTypeId; // XML_loTypeId
+    /* PRS (empty)  */ OUString     msPlaceholderText; // XML_phldrT
+    /* PRS (empty)  */ OUString     msPresentationAssociationId; // 
XML_presAssocID
+    /* PRS (empty)  */ OUString     msPresentationLayoutName; // XML_presName
+    /* PRS (empty)  */ OUString     msPresentationLayoutStyleLabel; // 
XML_presStyleLbl
+    /* PRS (empty)  */ OUString     msQuickStyleCategoryId; // XML_qsCatId
+    /* PRS (empty)  */ OUString     msQuickStyleTypeId; // XML_qsTypeId
+    /* PLV (empty)  */ OUString     msResizeHandles; // XML_resizeHandles
+
+    /* PT  XML_node */ TypeConstant mnXMLType; // default is XML_node // 
XML_type
+    /* PLV -1       */ sal_Int32    mnMaxChildren; // XML_chMax
+    /* PLV -1       */ sal_Int32    mnPreferredChildren; // XML_chPref
+    /* PLV XML_norm */ sal_Int32    mnDirection; // XML_dir
+    /* PLV (opt)    */ std::optional<sal_Int32> moHierarchyBranch; // 
XML_hierBranch
+
+    /* PRS -1       */ sal_Int32    mnCustomAngle; // XML_custAng
+    /* PRS -1       */ sal_Int32    mnPercentageNeighbourWidth; // 
XML_custLinFactNeighborX
+    /* PRS -1       */ sal_Int32    mnPercentageNeighbourHeight; // 
XML_custLinFactNeighborY
+    /* PRS -1       */ sal_Int32    mnPercentageOwnWidth; // XML_custLinFactX
+    /* PRS -1       */ sal_Int32    mnPercentageOwnHeight; // XML_custLinFactY
+    /* PRS -1       */ sal_Int32    mnIncludeAngleScale; // XML_custRadScaleInc
+    /* PRS -1       */ sal_Int32    mnRadiusScale; // XML_custRadScaleRad
+    /* PRS -1       */ sal_Int32    mnWidthScale; // XML_custScaleX
+    /* PRS -1       */ sal_Int32    mnHeightScale; // XML_custScaleY
+    /* PRS -1       */ sal_Int32    mnWidthOverride; // XML_custSzX
+    /* PRS -1       */ sal_Int32    mnHeightOverride; // XML_custSzY
+    /* PRS -1       */ sal_Int32    mnLayoutStyleCount; // XML_presStyleCnt
+    /* PRS -1       */ sal_Int32    mnLayoutStyleIndex; // XML_presStyleIdx
+
+    /* PLV (false)  */ bool         mbOrgChartEnabled : 1; // XML_orgChart
+    /* PLV (false)  */ bool         mbBulletEnabled : 1; // XML_bulletEnabled
+    /* PRS (false)  */ bool         mbCoherent3DOffset : 1; // 
XML_coherent3DOff
+    /* PRS (false)  */ bool         mbCustomHorizontalFlip : 1; // 
XML_custFlipHor
+    /* PRS (false)  */ bool         mbCustomVerticalFlip : 1; // 
XML_custFlipVert
+    /* PRS (false)  */ bool         mbCustomText : 1; // XML_custT
+    /* PRS (false)  */ bool         mbIsPlaceholder : 1; // XML_phldr
 
     void writeDiagramData_data(sax_fastparser::FSHelperPtr& rTarget);
+    void addDiagramModelData(boost::property_tree::ptree& rTarget) const;
 };
 
+TypeConstant SVXCORE_DLLPUBLIC getTypeConstantForName(std::u16string_view 
aName);
+std::u16string_view SVXCORE_DLLPUBLIC getNameForTypeConstant(TypeConstant 
aTypeConstant);
 void SVXCORE_DLLPUBLIC addTypeConstantToFastAttributeList(TypeConstant 
aTypeConstant, rtl::Reference<sax_fastparser::FastAttributeList>& 
rAttributeList, bool bPoint);
+void SVXCORE_DLLPUBLIC addTypeConstantToDiagramModelData(TypeConstant 
aTypeConstant, boost::property_tree::ptree& rTarget, bool bPoint);
+
 typedef std::vector< Point >        Points;
 
 /** Snippet of Diagram ModelData for Diagram-defining data undo/redo
@@ -171,6 +182,7 @@ protected:
     // shall not be incarnated - target to use is 
oox::drawingml::DiagramData_oox
     DiagramData_svx();
     explicit DiagramData_svx(DiagramData_svx const& rSource);
+    explicit DiagramData_svx(const boost::property_tree::ptree& rDiagramModel);
 
 public:
     // access associated SdrObjGroup/XShape/RootShape
@@ -189,6 +201,7 @@ public:
 
     // read accesses
     Connections& getConnections() { return maConnections; }
+    const Connections& getConnections() const { return maConnections; }
     Points& getPoints() { return maPoints; }
     const Points& getPoints() const { return maPoints; }
     StringMap& getPresOfNameMap() { return maPresOfNameMap; }
@@ -217,6 +230,9 @@ public:
     css::uno::Reference<css::drawing::XShape> 
getXShapeByModelID(std::u16string_view rModelID) const;
     const Point* getPointByModelID(std::u16string_view rModelID) const;
 
+    // write data to boost::property_tree
+    void addDiagramModelData(boost::property_tree::ptree& rTarget) const;
+
 protected:
     // helpers
     void getDiagramChildrenString(OUStringBuffer& rBuf, const Point* pPoint, 
sal_Int32 nLevel) const;
diff --git a/include/svx/svdogrp.hxx b/include/svx/svdogrp.hxx
index 5e8c9f58f0ab..6f1478eeff12 100644
--- a/include/svx/svdogrp.hxx
+++ b/include/svx/svdogrp.hxx
@@ -114,6 +114,9 @@ public:
     virtual rtl::Reference<SdrObject> DoConvertToPolyObj(bool bBezier,
                                                          bool bAddText) const 
override;
 
+    virtual void SetDescription(const OUString& rStr) override;
+    virtual OUString GetDescription() const override;
+
     virtual void dumpAsXml(xmlTextWriterPtr pWriter) const override;
     virtual void AddToHdlList(SdrHdlList& rHdlList) const override;
 };
diff --git a/oox/source/drawingml/diagram/datamodel_oox.cxx 
b/oox/source/drawingml/diagram/datamodel_oox.cxx
index 9c9f4b085e12..fe1e45c0a95f 100644
--- a/oox/source/drawingml/diagram/datamodel_oox.cxx
+++ b/oox/source/drawingml/diagram/datamodel_oox.cxx
@@ -35,6 +35,7 @@
 #include <oox/export/drawingml.hxx>
 #include <sax/fastattribs.hxx>
 #include <oox/export/shapes.hxx>
+#include <boost/property_tree/ptree.hpp>
 
 #include <unordered_set>
 
@@ -295,11 +296,17 @@ DiagramData_oox::DiagramData_oox()
 
 DiagramData_oox::DiagramData_oox(DiagramData_oox const& rSource)
 : svx::diagram::DiagramData_svx(rSource)
-, mpBackgroundShapeFillProperties()
+, mpBackgroundShapeFillProperties(rSource.mpBackgroundShapeFillProperties)
 , maPointShapeMap()
 {
 }
 
+DiagramData_oox::DiagramData_oox(const boost::property_tree::ptree& 
rDiagramModel)
+: svx::diagram::DiagramData_svx(rDiagramModel)
+, mpBackgroundShapeFillProperties( std::make_shared<FillProperties>() )
+{
+}
+
 DiagramData_oox::~DiagramData_oox()
 {
 }
diff --git a/oox/source/drawingml/diagram/datamodel_oox.hxx 
b/oox/source/drawingml/diagram/datamodel_oox.hxx
index 9cede1263d90..0ad26fc605dc 100644
--- a/oox/source/drawingml/diagram/datamodel_oox.hxx
+++ b/oox/source/drawingml/diagram/datamodel_oox.hxx
@@ -43,6 +43,7 @@ public:
 
     DiagramData_oox();
     explicit DiagramData_oox(DiagramData_oox const& rSource);
+    explicit DiagramData_oox(const boost::property_tree::ptree& rDiagramModel);
     virtual ~DiagramData_oox();
 
     // creates temporary processing data from model data
diff --git a/oox/source/drawingml/diagram/diagram.cxx 
b/oox/source/drawingml/diagram/diagram.cxx
index c6d33ee4df8b..3656e8705c44 100644
--- a/oox/source/drawingml/diagram/diagram.cxx
+++ b/oox/source/drawingml/diagram/diagram.cxx
@@ -46,6 +46,12 @@
 #include <com/sun/star/io/TempFile.hpp>
 #include <oox/export/drawingml.hxx>
 
+#include <com/sun/star/xml/sax/XSAXSerializable.hpp>
+#include <com/sun/star/xml/sax/Writer.hpp>
+#include <oox/core/fastparser.hxx>
+#include <unotools/streamwrap.hxx>
+#include <tools/stream.hxx>
+
 #ifdef DBG_UTIL
 #include <osl/file.hxx>
 #include <o3tl/environment.hxx>
@@ -172,6 +178,89 @@ SmartArtDiagram::SmartArtDiagram()
 {
 }
 
+SmartArtDiagram::SmartArtDiagram(const boost::property_tree::ptree& 
rDiagramModel)
+: maDiagramFontHeights()
+, mpData(std::make_shared<DiagramData_oox>(rDiagramModel))
+, mpLayout(std::make_shared<DiagramLayout>(*this))
+, maStyles()
+, maColors()
+, maDiagramPRDomMap()
+{
+#ifdef DBG_UTIL
+    mpData->dump();
+#endif
+    const OUString 
aOOXLayoutDOM(OUString::fromUtf8(rDiagramModel.get("OOXLayout", "")));
+    const OUString 
aOOXStyleDOM(OUString::fromUtf8(rDiagramModel.get("OOXStyle", "")));
+    const OUString 
aOOXColorDOM(OUString::fromUtf8(rDiagramModel.get("OOXColor", "")));
+
+    if (!aOOXLayoutDOM.isEmpty() || !aOOXStyleDOM.isEmpty() || 
!aOOXColorDOM.isEmpty())
+    {
+        // we need a PowerPointImport for the FragmentHandlers, so create a 
single
+        // temporary one. Use this for all possible DomTrees
+        rtl::Reference<oox::ppt::PowerPointImport> xPPTImport(new 
oox::ppt::PowerPointImport(comphelper::getProcessComponentContext()));
+
+        if (!aOOXLayoutDOM.isEmpty())
+        {
+            // construct MemoryStream and OStreamWrapper with SVG in OUString
+            const OString sUtf8(OUStringToOString(aOOXLayoutDOM, 
RTL_TEXTENCODING_UTF8));
+            SvMemoryStream aStream(const_cast<char*>(sUtf8.getStr()), 
sUtf8.getLength(), StreamMode::READ);
+            rtl::Reference<utl::OStreamWrapper> pStreamWrapper = new 
utl::OStreamWrapper(aStream);
+
+            // create the dom parser & create DomTree
+            uno::Reference<xml::dom::XDocumentBuilder> 
xDomBuilder(xml::dom::DocumentBuilder::create(comphelper::getProcessComponentContext()));
+            uno::Reference<xml::dom::XDocument> 
aDomTree(xDomBuilder->parse(pStreamWrapper->getInputStream()));
+
+            // set DomTree locally
+            setOOXDomValue(svx::diagram::DomMapFlag::OOXLayout, 
uno::Any(aDomTree));
+
+            // import DomTree to mpLayout
+            uno::Reference<xml::sax::XFastSAXSerializable> 
xSerializer(aDomTree, uno::UNO_QUERY_THROW);
+            rtl::Reference< core::FragmentHandler > xRefLayout(new 
DiagramLayoutFragmentHandler(*xPPTImport, "internal", mpLayout));
+            xPPTImport->importFragment(xRefLayout, xSerializer);
+        }
+
+        if (!aOOXStyleDOM.isEmpty())
+        {
+            // construct MemoryStream and OStreamWrapper with SVG in OUString
+            const OString sUtf8(OUStringToOString(aOOXStyleDOM, 
RTL_TEXTENCODING_UTF8));
+            SvMemoryStream aStream(const_cast<char*>(sUtf8.getStr()), 
sUtf8.getLength(), StreamMode::READ);
+            rtl::Reference<utl::OStreamWrapper> pStreamWrapper = new 
utl::OStreamWrapper(aStream);
+
+            // create the dom parser & create DomTree
+            uno::Reference<xml::dom::XDocumentBuilder> 
xDomBuilder(xml::dom::DocumentBuilder::create(comphelper::getProcessComponentContext()));
+            uno::Reference<xml::dom::XDocument> 
aDomTree(xDomBuilder->parse(pStreamWrapper->getInputStream()));
+
+            // set DomTree locally
+            setOOXDomValue(svx::diagram::DomMapFlag::OOXStyle, 
uno::Any(aDomTree));
+
+            // import DomTree to maStyles
+            uno::Reference<xml::sax::XFastSAXSerializable> 
xSerializer(aDomTree, uno::UNO_QUERY_THROW);
+            rtl::Reference< core::FragmentHandler > xRefLayout(new 
DiagramQStylesFragmentHandler(*xPPTImport, "internal", maStyles));
+            xPPTImport->importFragment(xRefLayout, xSerializer);
+        }
+
+        if (!aOOXColorDOM.isEmpty())
+        {
+            // construct MemoryStream and OStreamWrapper with SVG in OUString
+            const OString sUtf8(OUStringToOString(aOOXColorDOM, 
RTL_TEXTENCODING_UTF8));
+            SvMemoryStream aStream(const_cast<char*>(sUtf8.getStr()), 
sUtf8.getLength(), StreamMode::READ);
+            rtl::Reference<utl::OStreamWrapper> pStreamWrapper = new 
utl::OStreamWrapper(aStream);
+
+            // create the dom parser & create DomTree
+            uno::Reference<xml::dom::XDocumentBuilder> 
xDomBuilder(xml::dom::DocumentBuilder::create(comphelper::getProcessComponentContext()));
+            uno::Reference<xml::dom::XDocument> 
aDomTree(xDomBuilder->parse(pStreamWrapper->getInputStream()));
+
+            // set DomTree locally
+            setOOXDomValue(svx::diagram::DomMapFlag::OOXColor, 
uno::Any(aDomTree));
+
+            // import DomTree to maColors
+            uno::Reference<xml::sax::XFastSAXSerializable> 
xSerializer(aDomTree, uno::UNO_QUERY_THROW);
+            rtl::Reference< core::FragmentHandler > xRefLayout(new 
ColorFragmentHandler(*xPPTImport, "internal", maColors));
+            xPPTImport->importFragment(xRefLayout, xSerializer);
+        }
+    }
+}
+
 SmartArtDiagram::SmartArtDiagram(SmartArtDiagram const& rSource)
 : maDiagramFontHeights()
 , mpData(rSource.mpData ? new DiagramData_oox(*rSource.mpData) : nullptr)
@@ -307,6 +396,63 @@ void SmartArtDiagram::writeDiagramOOXDrawing(DrawingML& 
rOriginalDrawingML, uno:
 #endif
 }
 
+void SmartArtDiagram::addDomTreeToModelData(svx::diagram::DomMapFlag aId, 
std::u16string_view aName, boost::property_tree::ptree& rTarget) const
+{
+    uno::Reference<xml::dom::XDocument> aDomTree;
+    getOOXDomValue(aId) >>= aDomTree;
+
+    if (aDomTree)
+    {
+        // serialize DomTree to a MemoryStream
+        SvMemoryStream aStream( 1024, 1024 );
+        rtl::Reference<utl::OStreamWrapper> pStreamWrapper = new 
utl::OStreamWrapper( aStream );
+        uno::Reference<xml::sax::XSAXSerializable> serializer;
+        uno::Reference<xml::sax::XWriter> writer = 
xml::sax::Writer::create(comphelper::getProcessComponentContext());
+        serializer.set(aDomTree, uno::UNO_QUERY);
+        writer->setOutputStream(pStreamWrapper->getOutputStream());
+        
serializer->serialize(uno::Reference<xml::sax::XDocumentHandler>(writer, 
uno::UNO_QUERY_THROW), uno::Sequence<beans::StringPair>());
+
+        // put into string
+        const OUString aContent(static_cast<const char*>(aStream.GetData()), 
aStream.TellEnd(), RTL_TEXTENCODING_UTF8);
+
+        // add to ModelData
+        const OString sUtf8(OUStringToOString(aName, RTL_TEXTENCODING_UTF8));
+        rTarget.put(sUtf8.getStr(), aContent);
+    }
+}
+
+void SmartArtDiagram::addDiagramModelData(boost::property_tree::ptree& 
rTarget) const
+{
+    // add Point and Connection data
+    getData()->addDiagramModelData(rTarget);
+
+    // What DomMaps are needed?
+    //
+    // With the above OOXData is covered. OOXDataImageRels/OOXDataHlinkRels 
also,
+    // these may/will be re-created when OOX export and a new OOXDataDomTree
+    // needs to be created.
+    // Similar with OOXDrawing: This contains parts of ModelData, e.g. Text and
+    // Attributes represented by the XShapes/Sdrobjects, so for internal 
formats
+    // this is not needed to be saved. This also true for OOXDrawingImageRels
+    // and OOXDrawingHlinkRels.
+    // We *do* import OOXLayoutDomTree/ModelInfo and this is used in the 
layouting
+    // mechanism (reLayout), but it is not changed. We could add an export of 
that
+    // for internal formats, but since it's not changed it just needs to be
+    // preserved, either for internal use or export to OOX formats.
+    // OOXStyle and OOXColor are imported only on oox import side, partially 
held
+    // for initial import at Diagram classes. Also never changed, but maybe 
needed
+    // for export to OOX formats. Not sure about that since Style and Color is
+    // part of XShape/SdrObject Model Hierarchy, so exports to OOX should be 
possible
+    // without these, but maybe MSO wants that data...
+    //
+    // OOXLayout = 3,
+    // OOXStyle = 4,
+    // OOXColor = 5,
+    addDomTreeToModelData(svx::diagram::DomMapFlag::OOXLayout, u"OOXLayout", 
rTarget);
+    addDomTreeToModelData(svx::diagram::DomMapFlag::OOXStyle, u"OOXStyle", 
rTarget);
+    addDomTreeToModelData(svx::diagram::DomMapFlag::OOXColor, u"OOXColor", 
rTarget);
+}
+
 using ShapePairs
     = std::map<std::shared_ptr<drawingml::Shape>, 
uno::Reference<drawing::XShape>>;
 
diff --git a/oox/source/drawingml/diagram/diagram.hxx 
b/oox/source/drawingml/diagram/diagram.hxx
index c63e806866c8..e4988aa70cc3 100644
--- a/oox/source/drawingml/diagram/diagram.hxx
+++ b/oox/source/drawingml/diagram/diagram.hxx
@@ -130,6 +130,7 @@ class SmartArtDiagram
 public:
     explicit SmartArtDiagram();
     explicit SmartArtDiagram(SmartArtDiagram const& rSource);
+    explicit SmartArtDiagram(const boost::property_tree::ptree& rDiagramModel);
     void setData( const OoxDiagramDataPtr& pData )
         { mpData = pData; }
     const OoxDiagramDataPtr& getData() const
@@ -159,7 +160,13 @@ public:
     void writeDiagramOOXData(DrawingML& rOriginalDrawingML, 
css::uno::Reference<css::io::XOutputStream>& xOutputStream, std::u16string_view 
rDrawingRelId) const;
     void writeDiagramOOXDrawing(DrawingML& rOriginalDrawingML, 
css::uno::Reference<css::io::XOutputStream>& xOutputStream) const;
 
+    // write data to boost::property_tree
+    void addDiagramModelData(boost::property_tree::ptree& rTarget) const;
+
 private:
+    // helper for addDiagramModelData
+    void addDomTreeToModelData(svx::diagram::DomMapFlag aId, 
std::u16string_view aName, boost::property_tree::ptree& rTarget) const;
+
     // This contains groups of shapes: automatic font size is the same in each 
group.
     oox::core::NamedShapePairs maDiagramFontHeights;
 
diff --git a/oox/source/drawingml/diagram/diagramhelper_oox.cxx 
b/oox/source/drawingml/diagram/diagramhelper_oox.cxx
index 8c1aa2036d0e..5beba10cc781 100644
--- a/oox/source/drawingml/diagram/diagramhelper_oox.cxx
+++ b/oox/source/drawingml/diagram/diagramhelper_oox.cxx
@@ -63,6 +63,16 @@ DiagramHelper_oox::DiagramHelper_oox(DiagramHelper_oox 
const& rSource)
 {
 }
 
+DiagramHelper_oox::DiagramHelper_oox(const boost::property_tree::ptree& 
rDiagramModel)
+    : DiagramHelper_svx()
+    , mpDiagramPtr(new SmartArtDiagram(rDiagramModel))
+    , mpDiagramThemePtr()
+    , maDiagramImportSize()
+    , msNewNodeId()
+    , msNewNodeText()
+{
+}
+
 DiagramHelper_oox::~DiagramHelper_oox() {}
 
 void DiagramHelper_oox::moveDiagramModelDataFromOldToNewXShape(
@@ -303,7 +313,7 @@ OUString DiagramHelper_oox::getDiagramString() const
         return mpDiagramPtr->getData()->getDiagramString();
     }
 
-    return OUString();
+    return EMPTY_OUSTRING;
 }
 
 std::vector<std::pair<OUString, OUString>>
@@ -516,6 +526,45 @@ DiagramHelper_oox* DiagramHelper_oox::clone() const
 
     return new DiagramHelper_oox(*this);
 }
+
+void DiagramHelper_oox::addDiagramModelData(boost::property_tree::ptree& 
rTarget) const
+{
+    if (!mpDiagramPtr)
+        return;
+
+    mpDiagramPtr->addDiagramModelData(rTarget);
+}
+
+DiagramHelperFactory_oox::DiagramHelperFactory_oox()
+    : DiagramHelperFactory_svx()
+{
+    // make clear that this is supposed to happen only once
+    assert(nullptr == pSingleGlobalDiagramHelperFactory_svx
+           && "DiagramHelperFactory initialized multiple times (!)");
+
+    // directly assign created instance to global pointer in svx for access 
from there
+    if (nullptr == pSingleGlobalDiagramHelperFactory_svx)
+        pSingleGlobalDiagramHelperFactory_svx = this;
+}
+
+DiagramHelperFactory_oox::~DiagramHelperFactory_oox()
+{
+    if (this == pSingleGlobalDiagramHelperFactory_svx)
+        pSingleGlobalDiagramHelperFactory_svx = nullptr;
+}
+
+std::shared_ptr<svx::diagram::DiagramHelper_svx>
+DiagramHelperFactory_oox::createDiagramHelper_svx(boost::property_tree::ptree& 
rTarget) const
+{
+    // from here we can instantiate DiagramHelper_oox and return
+    return std::make_shared<DiagramHelper_oox>(rTarget);
+}
+
+// this is the global needed anchor in oox module for an instantiation of
+// DiagramHelperFactory_oox and thus for DiagramHelperFactory_svx. This
+// is needed since in svx where a Diagram has to be imported an instance
+// of DiagramHelper_oox needs to be instantiated, but svx cannot access oox
+static DiagramHelperFactory_oox aSingleGlobalDiagramHelperFactory_oox;
 }
 
 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/svx/source/diagram/DiagramHelper_svx.cxx 
b/svx/source/diagram/DiagramHelper_svx.cxx
index 66fce4a71f13..b4efc2b25402 100644
--- a/svx/source/diagram/DiagramHelper_svx.cxx
+++ b/svx/source/diagram/DiagramHelper_svx.cxx
@@ -467,6 +467,22 @@ void DiagramHelper_svx::AddAdditionalVisualization(const 
SdrObjGroup& rTarget, S
     rHdlList.AddHdl(std::move(pHdl));
 }
 
+DiagramHelperFactory_svx::DiagramHelperFactory_svx()
+{
+}
+
+DiagramHelperFactory_svx& 
DiagramHelperFactory_svx::getDiagramHelperFactory_svx()
+{
+    assert(nullptr != pSingleGlobalDiagramHelperFactory_svx && 
"DiagramHelperFactory not yet initialized (!)");
+    return *pSingleGlobalDiagramHelperFactory_svx;
+}
+
+// init gobal member var of DiagramHelperFactory_svx. This will then be set
+// by DiagramHelperFactory_oox::DiagramHelperFactory_oox when
+// aSingleGlobalDiagramHelperFactory_oox gets incarnated by oox library at
+// that librarys load time
+DiagramHelperFactory_svx* 
DiagramHelperFactory_svx::pSingleGlobalDiagramHelperFactory_svx = nullptr;
+
 }} // end of namespace
 
 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/svx/source/diagram/datamodel_svx.cxx 
b/svx/source/diagram/datamodel_svx.cxx
index 2619313c5a71..1f8fb44b1599 100644
--- a/svx/source/diagram/datamodel_svx.cxx
+++ b/svx/source/diagram/datamodel_svx.cxx
@@ -29,44 +29,111 @@
 #include <utility>
 #include <sax/fastattribs.hxx>
 #include <com/sun/star/text/XText.hpp>
+#include <xmloff/xmltoken.hxx>
 
 using namespace ::oox;
 using namespace ::com::sun::star;
 
 namespace svx::diagram {
 
-void addTypeConstantToFastAttributeList(TypeConstant aTypeConstant, 
rtl::Reference<sax_fastparser::FastAttributeList>& rAttributeList, bool bPoint)
+TypeConstant getTypeConstantForName(std::u16string_view aName)
 {
-    if (TypeConstant::XML_none != aTypeConstant)
+        if (u"Type" == aName) return TypeConstant::XML_type;
+        if (u"asst" == aName) return TypeConstant::XML_asst;
+        if (u"doc" == aName) return TypeConstant::XML_doc;
+        if (u"node" == aName) return TypeConstant::XML_node;
+        if (u"norm" == aName) return TypeConstant::XML_norm;
+        if (u"parOf" == aName) return TypeConstant::XML_parOf;
+        if (u"parTrans" == aName) return TypeConstant::XML_parTrans;
+        if (u"pres" == aName) return TypeConstant::XML_pres;
+        if (u"presOf" == aName) return TypeConstant::XML_presOf;
+        if (u"presParOf" == aName) return TypeConstant::XML_presParOf;
+        if (u"rel" == aName) return TypeConstant::XML_rel;
+        if (u"sibTrans" == aName) return TypeConstant::XML_sibTrans;
+        return TypeConstant::XML_none;
+}
+
+std::u16string_view getNameForTypeConstant(TypeConstant aTypeConstant)
+{
+    switch (aTypeConstant)
     {
-        switch (aTypeConstant)
-        {
-            // *CAUTION!* here '::XML_type' is *not* the same as 'XML_type' 
which would
-            // namespace expand to oox::XML_type as in enum TypeConstant 
definitions (!)
-            case TypeConstant::XML_type: rAttributeList->add(::XML_type, 
"Type"); break;
-            case TypeConstant::XML_asst: rAttributeList->add(::XML_type, 
"asst"); break;
-            case TypeConstant::XML_doc: rAttributeList->add(::XML_type, 
"doc"); break;
-            case TypeConstant::XML_node: if(!bPoint) 
rAttributeList->add(::XML_type, "node"); break;
-            case TypeConstant::XML_norm: rAttributeList->add(::XML_type, 
"norm"); break;
-            case TypeConstant::XML_parOf: if(bPoint) 
rAttributeList->add(::XML_type, "parOf"); break;
-            case TypeConstant::XML_parTrans: rAttributeList->add(::XML_type, 
"parTrans"); break;
-            case TypeConstant::XML_pres: rAttributeList->add(::XML_type, 
"pres"); break;
-            case TypeConstant::XML_presOf: rAttributeList->add(::XML_type, 
"presOf"); break;
-            case TypeConstant::XML_presParOf: rAttributeList->add(::XML_type, 
"presParOf"); break;
-            case TypeConstant::XML_rel: rAttributeList->add(::XML_type, 
"rel"); break;
-            case TypeConstant::XML_sibTrans: rAttributeList->add(::XML_type, 
"sibTrans"); break;
-            default: break; // XML_none
-        }
+        case TypeConstant::XML_type: return u"Type"; break;
+        case TypeConstant::XML_asst: return u"asst"; break;
+        case TypeConstant::XML_doc: return u"doc"; break;
+        case TypeConstant::XML_node: return u"node"; break;
+        case TypeConstant::XML_norm: return u"norm"; break;
+        case TypeConstant::XML_parOf: return u"parOf"; break;
+        case TypeConstant::XML_parTrans: return u"parTrans"; break;
+        case TypeConstant::XML_pres: return u"pres"; break;
+        case TypeConstant::XML_presOf: return u"presOf"; break;
+        case TypeConstant::XML_presParOf: return u"presParOf"; break;
+        case TypeConstant::XML_rel: return u"rel"; break;
+        case TypeConstant::XML_sibTrans: return u"sibTrans"; break;
+        case TypeConstant::XML_none: break;
     }
+
+    return u"";
+}
+
+void addTypeConstantToFastAttributeList(TypeConstant aTypeConstant, 
rtl::Reference<sax_fastparser::FastAttributeList>& rAttributeList, bool bPoint)
+{
+    if (TypeConstant::XML_none == aTypeConstant)
+        return;
+    if (TypeConstant::XML_node == aTypeConstant && bPoint)
+        return;
+    if (TypeConstant::XML_parOf == aTypeConstant && !bPoint)
+        return;
+
+    const std::u16string_view aName(getNameForTypeConstant(aTypeConstant));
+    // *CAUTION!* here '::XML_type' is *not* the same as 'XML_type' which would
+    // namespace expand to oox::XML_type as in enum TypeConstant definitions 
(!)
+    if (!aName.empty())
+        rAttributeList->add(::XML_type, aName);
+}
+
+void addTypeConstantToDiagramModelData(TypeConstant aTypeConstant, 
boost::property_tree::ptree& rTarget, bool bPoint)
+{
+    if (TypeConstant::XML_none == aTypeConstant)
+        return;
+    if (TypeConstant::XML_node == aTypeConstant && bPoint)
+        return;
+    if (TypeConstant::XML_parOf == aTypeConstant && !bPoint)
+        return;
+
+    const std::u16string_view aName(getNameForTypeConstant(aTypeConstant));
+    if (!aName.empty())
+        rTarget.put("XMLType", OUString(aName));
 }
 
 Connection::Connection()
 : mnXMLType( XML_parOf )
+, msModelId()
+, msSourceId()
+, msDestId()
+, msPresId()
+, msSibTransId()
+, msParTransId()
 , mnSourceOrder( 0 )
 , mnDestOrder( 0 )
 {
 }
 
+Connection::Connection(const boost::property_tree::ptree& rConnectionData)
+: mnXMLType( XML_parOf )
+, msModelId(OUString::fromUtf8(rConnectionData.get("modelId", "")))
+, msSourceId(OUString::fromUtf8(rConnectionData.get("srcId", "")))
+, msDestId(OUString::fromUtf8(rConnectionData.get("destId", "")))
+, msPresId(OUString::fromUtf8(rConnectionData.get("presId", "")))
+, msSibTransId(OUString::fromUtf8(rConnectionData.get("sibTransId", "")))
+, msParTransId(OUString::fromUtf8(rConnectionData.get("parTransId", "")))
+, mnSourceOrder(rConnectionData.get("srcOrd", 0))
+, mnDestOrder(rConnectionData.get("destOrd", 0))
+{
+    const OUString aXMLType(OUString::fromUtf8(rConnectionData.get("XMLType", 
"")));
+    if (!aXMLType.isEmpty())
+        mnXMLType = getTypeConstantForName(aXMLType);
+}
+
 void Connection::writeDiagramData(sax_fastparser::FSHelperPtr& rTarget)
 {
     if (!rTarget)
@@ -93,6 +160,19 @@ void 
Connection::writeDiagramData(sax_fastparser::FSHelperPtr& rTarget)
     rTarget->singleElementNS(XML_dgm, XML_cxn, pAttributeList);
 }
 
+void Connection::addDiagramModelData(boost::property_tree::ptree& rTarget) 
const
+{
+    addTypeConstantToDiagramModelData(mnXMLType, rTarget, false); // XML_type
+    if (!msModelId.isEmpty()) rTarget.put("modelId", msModelId); // XML_modelId
+    if (!msSourceId.isEmpty()) rTarget.put("srcId", msSourceId); // XML_srcId
+    if (!msDestId.isEmpty()) rTarget.put("destId", msDestId); // XML_destId
+    if (!msPresId.isEmpty()) rTarget.put("presId", msPresId); // XML_presId
+    if (!msSibTransId.isEmpty()) rTarget.put("sibTransId", msSibTransId); // 
XML_sibTransId
+    if (!msParTransId.isEmpty()) rTarget.put("parTransId", msParTransId); // 
XML_parTransId
+    if (0 != mnSourceOrder) rTarget.put("srcOrd", mnSourceOrder); // XML_srcOrd
+    if (0 != mnDestOrder) rTarget.put("destOrd", mnDestOrder); // XML_destOrd
+}
+
 Point::Point()
 : mnXMLType(XML_node)
 , mnMaxChildren(-1)
@@ -121,6 +201,55 @@ Point::Point()
 {
 }
 
+Point::Point(const boost::property_tree::ptree& rPointData)
+: msCnxId(OUString::fromUtf8(rPointData.get("cxnId", "")))
+, msModelId(OUString::fromUtf8(rPointData.get("modelId", "")))
+, msColorTransformCategoryId(OUString::fromUtf8(rPointData.get("csCatId", "")))
+, msColorTransformTypeId(OUString::fromUtf8(rPointData.get("csTypeId", "")))
+, msLayoutCategoryId(OUString::fromUtf8(rPointData.get("loCatId", "")))
+, msLayoutTypeId(OUString::fromUtf8(rPointData.get("loTypeId", "")))
+, msPlaceholderText(OUString::fromUtf8(rPointData.get("phldrT", "")))
+, msPresentationAssociationId(OUString::fromUtf8(rPointData.get("presAssocID", 
"")))
+, msPresentationLayoutName(OUString::fromUtf8(rPointData.get("presName", "")))
+, 
msPresentationLayoutStyleLabel(OUString::fromUtf8(rPointData.get("presStyleLbl",
 "")))
+, msQuickStyleCategoryId(OUString::fromUtf8(rPointData.get("qsCatId", "")))
+, msQuickStyleTypeId(OUString::fromUtf8(rPointData.get("qsTypeId", "")))
+, msResizeHandles(OUString::fromUtf8(rPointData.get("resizeHandles", "")))
+, mnXMLType(XML_node)
+, mnMaxChildren(rPointData.get("chMax", -1))
+, mnPreferredChildren(rPointData.get("chPref", -1))
+, mnDirection(rPointData.get<int>("dir", XML_norm))
+, moHierarchyBranch()
+, mnCustomAngle(rPointData.get("custAng", -1))
+, mnPercentageNeighbourWidth(rPointData.get("custLinFactNeighborX", -1))
+, mnPercentageNeighbourHeight(rPointData.get("custLinFactNeighborY", -1))
+, mnPercentageOwnWidth(rPointData.get("custLinFactX", -1))
+, mnPercentageOwnHeight(rPointData.get("custLinFactY", -1))
+, mnIncludeAngleScale(rPointData.get("custRadScaleInc", -1))
+, mnRadiusScale(rPointData.get("custRadScaleRad", -1))
+, mnWidthScale(rPointData.get("custScaleX", -1))
+, mnHeightScale(rPointData.get("custScaleY", -1))
+, mnWidthOverride(rPointData.get("custSzX", -1))
+, mnHeightOverride(rPointData.get("custSzY", -1))
+, mnLayoutStyleCount(rPointData.get("presStyleCnt", -1))
+, mnLayoutStyleIndex(rPointData.get("presStyleIdx", -1))
+, mbOrgChartEnabled(rPointData.get("orgChart", false))
+, mbBulletEnabled(rPointData.get("bulletEnabled", false))
+, mbCoherent3DOffset(rPointData.get("coherent3DOff", false))
+, mbCustomHorizontalFlip(rPointData.get("custFlipHor", false))
+, mbCustomVerticalFlip(rPointData.get("custFlipVert", false))
+, mbCustomText(rPointData.get("custT", false))
+, mbIsPlaceholder(rPointData.get("phldr", false))
+{
+    const OUString aXMLType(OUString::fromUtf8(rPointData.get("XMLType", "")));
+    if (!aXMLType.isEmpty())
+        mnXMLType = getTypeConstantForName(aXMLType);
+
+    const boost::optional<sal_Int32> 
aBranch(rPointData.get_optional<int>("hierBranch"));
+    if (aBranch.has_value())
+        moHierarchyBranch = aBranch.value();
+}
+
 void Point::writeDiagramData_data(sax_fastparser::FSHelperPtr& rTarget)
 {
     rtl::Reference<sax_fastparser::FastAttributeList> 
pAttributeList(sax_fastparser::FastSerializerHelper::createAttrList());
@@ -151,11 +280,11 @@ void 
Point::writeDiagramData_data(sax_fastparser::FSHelperPtr& rTarget)
     if (-1 != mnLayoutStyleIndex) pAttributeList->add(XML_presStyleIdx, 
OUString::number(mnLayoutStyleIndex));
 
     static constexpr OUString aStrTrue = u"1"_ustr; // this uses "1", not 
"true"
-    if (true == mbCoherent3DOffset) pAttributeList->add(XML_coherent3DOff, 
aStrTrue);
-    if (true == mbCustomHorizontalFlip) pAttributeList->add(XML_custFlipHor, 
aStrTrue);
-    if (true == mbCustomVerticalFlip) pAttributeList->add(XML_custFlipVert, 
aStrTrue);
-    if (true == mbCustomText) pAttributeList->add(XML_custT, aStrTrue);
-    if (true == mbIsPlaceholder) pAttributeList->add(XML_phldr, aStrTrue);
+    if (mbCoherent3DOffset) pAttributeList->add(XML_coherent3DOff, aStrTrue);
+    if (mbCustomHorizontalFlip) pAttributeList->add(XML_custFlipHor, aStrTrue);
+    if (mbCustomVerticalFlip) pAttributeList->add(XML_custFlipVert, aStrTrue);
+    if (mbCustomText) pAttributeList->add(XML_custT, aStrTrue);
+    if (mbIsPlaceholder) pAttributeList->add(XML_phldr, aStrTrue);
 
     const bool bNeed_presLayoutVars(mbBulletEnabled
         || -1 != mnMaxChildren
@@ -198,6 +327,51 @@ void 
Point::writeDiagramData_data(sax_fastparser::FSHelperPtr& rTarget)
         rTarget->singleElementNS(XML_dgm, XML_prSet, pAttributeList);
 }
 
+void Point::addDiagramModelData(boost::property_tree::ptree& rTarget) const
+{
+    if (!msCnxId.isEmpty()) rTarget.put("cxnId", msCnxId); // XML_cxnId
+    if (!msModelId.isEmpty()) rTarget.put("modelId", msModelId); // XML_modelId
+    if (!msColorTransformCategoryId.isEmpty()) rTarget.put("csCatId", 
msColorTransformCategoryId); // XML_csCatId
+    if (!msColorTransformTypeId.isEmpty()) rTarget.put("csTypeId", 
msColorTransformTypeId); // XML_csTypeId
+    if (!msLayoutCategoryId.isEmpty()) rTarget.put("loCatId", 
msLayoutCategoryId); // XML_loCatId
+    if (!msLayoutTypeId.isEmpty()) rTarget.put("loTypeId", msLayoutTypeId); // 
XML_loTypeId
+    if (!msPlaceholderText.isEmpty()) rTarget.put("phldrT", 
msPlaceholderText); // XML_phldrT
+    if (!msPresentationAssociationId.isEmpty()) rTarget.put("presAssocID", 
msPresentationAssociationId); // XML_presAssocID
+    if (!msPresentationLayoutName.isEmpty()) rTarget.put("presName", 
msPresentationLayoutName); // XML_presName
+    if (!msPresentationLayoutStyleLabel.isEmpty()) rTarget.put("presStyleLbl", 
msPresentationLayoutStyleLabel); // XML_presStyleLbl
+    if (!msQuickStyleCategoryId.isEmpty()) rTarget.put("qsCatId", 
msQuickStyleCategoryId); // XML_qsCatId
+    if (!msQuickStyleTypeId.isEmpty()) rTarget.put("qsTypeId", 
msQuickStyleTypeId); // XML_qsTypeId
+    if (!msResizeHandles.isEmpty()) rTarget.put("resizeHandles", 
msResizeHandles); // XML_resizeHandles
+
+    addTypeConstantToDiagramModelData(mnXMLType, rTarget, true); // XML_type
+    if (-1 != mnMaxChildren) rTarget.put("chMax", mnMaxChildren); // XML_chMax
+    if (-1 != mnPreferredChildren) rTarget.put("chPref", mnPreferredChildren); 
// XML_chPref
+    if (XML_norm != mnDirection) rTarget.put("dir", mnDirection); // XML_dir
+    if (moHierarchyBranch.has_value()) rTarget.put("hierBranch", 
moHierarchyBranch.value()); // XML_hierBranch
+
+    if (-1 != mnCustomAngle) rTarget.put("custAng", mnCustomAngle); // 
XML_custAng
+    if (-1 != mnPercentageNeighbourWidth) rTarget.put("custLinFactNeighborX", 
mnPercentageNeighbourWidth); // XML_custLinFactNeighborX
+    if (-1 != mnPercentageNeighbourHeight) rTarget.put("custLinFactNeighborY", 
mnPercentageNeighbourHeight); // XML_custLinFactNeighborY
+    if (-1 != mnPercentageOwnWidth) rTarget.put("custLinFactX", 
mnPercentageOwnWidth); // XML_custLinFactX
+    if (-1 != mnPercentageOwnHeight) rTarget.put("custLinFactY", 
mnPercentageOwnHeight); // XML_custLinFactY
+    if (-1 != mnIncludeAngleScale) rTarget.put("custRadScaleInc", 
mnIncludeAngleScale); // XML_custRadScaleInc
+    if (-1 != mnRadiusScale) rTarget.put("custRadScaleRad", mnRadiusScale); // 
XML_custRadScaleRad
+    if (-1 != mnWidthScale) rTarget.put("custScaleX", mnWidthScale); // 
XML_custScaleX
+    if (-1 != mnHeightScale) rTarget.put("custScaleY", mnHeightScale); // 
XML_custScaleY
+    if (-1 != mnWidthOverride) rTarget.put("custSzX", mnWidthOverride); // 
XML_custSzX
+    if (-1 != mnHeightOverride) rTarget.put("custSzY", mnHeightOverride); // 
XML_custSzY
+    if (-1 != mnLayoutStyleCount) rTarget.put("presStyleCnt", 
mnLayoutStyleCount); // XML_presStyleCnt
+    if (-1 != mnLayoutStyleIndex) rTarget.put("presStyleIdx", 
mnLayoutStyleIndex); // XML_presStyleIdx
+
+    if (mbOrgChartEnabled) rTarget.put("orgChart", mbOrgChartEnabled); // 
XML_orgChart
+    if (mbBulletEnabled) rTarget.put("bulletEnabled", mbBulletEnabled); // 
XML_bulletEnabled
+    if (mbCoherent3DOffset) rTarget.put("coherent3DOff", mbCoherent3DOffset); 
// XML_coherent3DOff
+    if (mbCustomHorizontalFlip) rTarget.put("custFlipHor", 
mbCustomHorizontalFlip); // XML_custFlipHor
+    if (mbCustomVerticalFlip) rTarget.put("custFlipVert", 
mbCustomVerticalFlip); // XML_custFlipVert
+    if (mbCustomText) rTarget.put("custT", mbCustomText); // XML_custT
+    if (mbIsPlaceholder) rTarget.put("phldr", mbIsPlaceholder); // XML_phldr
+}
+
 DiagramData_svx::DiagramData_svx()
 : mxRootShape()
 , maExtDrawings()
@@ -227,6 +401,34 @@ DiagramData_svx::DiagramData_svx(DiagramData_svx const& 
rSource)
 {
 }
 
+DiagramData_svx::DiagramData_svx(const boost::property_tree::ptree& 
rDiagramModel)
+: mxRootShape()
+, maExtDrawings()
+, maConnections()
+, maPoints()
+, mxThemeDocument()
+, maPointsPresNameMap()
+, maConnectionNameMap()
+, maPresOfNameMap()
+, 
msBackgroundShapeModelID(OUString::fromUtf8(rDiagramModel.get("BGShapeModelID", 
"")))
+{
+    const int nPtCnt(rDiagramModel.get_child("PtCnt").get_value<int>());
+    for (int a(0); a < nPtCnt; a++)
+    {
+        const OUString aName(OUString::Concat("Pt") + OUString::number(a));
+        boost::property_tree::ptree aPointData = 
rDiagramModel.get_child(aName.toUtf8().getStr());
+        maPoints.emplace_back(aPointData);
+    }
+
+    const int nConnCnt(rDiagramModel.get_child("ConnCnt").get_value<int>());
+    for (int a(0); a < nConnCnt; a++)
+    {
+        const OUString aName(OUString::Concat("Cn") + OUString::number(a));
+        boost::property_tree::ptree aConnectionData = 
rDiagramModel.get_child(aName.toUtf8().getStr());
+        maConnections.emplace_back(aConnectionData);
+    }
+}
+
 DiagramData_svx::~DiagramData_svx()
 {
 }
@@ -399,6 +601,44 @@ const Point* 
DiagramData_svx::getPointByModelID(std::u16string_view rModelID) co
     return nullptr;
 }
 
+void DiagramData_svx::addDiagramModelData(boost::property_tree::ptree& 
rTarget) const
+{
+    // write BGShapeModelID to boost::property_tree
+    rTarget.put("BGShapeModelID", getBackgroundShapeModelID());
+
+    // write points to boost::property_tree
+    const svx::diagram::Points& rPoints = getPoints();
+    if (!rPoints.empty())
+    {
+        rTarget.put("PtCnt", rPoints.size());
+        size_t count(0);
+
+        for (auto & point : rPoints)
+        {
+            boost::property_tree::ptree aPoints;
+            point.addDiagramModelData(aPoints);
+            const OUString aName(OUString::Concat("Pt") + 
OUString::number(count++));
+            rTarget.push_back(std::make_pair(aName.toUtf8().getStr(), 
aPoints));
+        }
+    }
+
+    // write connections to boost::property_tree
+    const svx::diagram::Connections& rConnections = getConnections();
+    if (!rConnections.empty())
+    {
+        rTarget.put("ConnCnt", rConnections.size());
+        size_t count(0);
+
+        for (auto & connection : rConnections)
+        {
+            boost::property_tree::ptree aConnections;
+            connection.addDiagramModelData(aConnections);
+            const OUString aName(OUString::Concat("Cn") + 
OUString::number(count++));
+            rTarget.push_back(std::make_pair(aName.toUtf8().getStr(), 
aConnections));
+        }
+    }
+}
+
 uno::Reference<drawing::XShape> DiagramData_svx::getMasterXShapeForPoint(const 
Point& rPoint) const
 {
     for (auto& rCandidate : getPoints())
diff --git a/svx/source/svdraw/svdogrp.cxx b/svx/source/svdraw/svdogrp.cxx
index 47518a5d1d76..3b4574cd0d65 100644
--- a/svx/source/svdraw/svdogrp.cxx
+++ b/svx/source/svdraw/svdogrp.cxx
@@ -33,6 +33,8 @@
 #include <libxml/xmlwriter.h>
 #include <vcl/canvastools.hxx>
 #include <svx/diagram/DiagramHelper_svx.hxx>
+#include <svx/diagram/DiagramHelper_svx.hxx>
+#include <boost/property_tree/info_parser.hpp>
 
 bool SdrObjGroup::isDiagram() const
 {
@@ -762,6 +764,88 @@ rtl::Reference<SdrObject> 
SdrObjGroup::DoConvertToPolyObj(bool bBezier, bool bAd
     return pGroup;
 }
 
+void SdrObjGroup::SetDescription(const OUString& rStr)
+{
+    static bool bActivateAdvancedDiagramFeatures(nullptr != 
std::getenv("ACTIVATE_ADVANCED_DIAGRAM_FEATURES"));
+    if (!bActivateAdvancedDiagramFeatures)
+    {
+        SdrObject::SetDescription(rStr);
+        return;
+    }
+
+    OUString aOrigDescription(rStr);
+
+    if (!rStr.isEmpty() && getSdrModelFromSdrObject().isLocked())
+    {
+        // we maybe importing a Diagram. Try to get the Diagram ModelData and
+        // add needed Diagram ModelData
+        // NOTE: currently isLocked() is used  to identify import, that *may* 
have
+        //       to be made more specific in SdXMLImport
+        OUString aModelData;
+
+        // check if the identifying token is there
+        if (rStr.startsWith(u"SmartArtModelData:", &aModelData) && 
!aModelData.isEmpty())
+        {
+            // import to boost::property_tree
+            boost::property_tree::ptree aDiagramModel;
+            std::stringstream aStream(aModelData.toUtf8().getStr());
+
+            // try to read data
+            boost::property_tree::read_info(aStream, aDiagramModel);
+
+            if (!aDiagramModel.empty())
+            {
+                // extract possibly existing original description and set as 
target value
+                aOrigDescription = 
OUString::fromUtf8(aDiagramModel.get("origDesc", ""));
+
+                // parse content to a new Diagram DataModel
+                std::shared_ptr<svx::diagram::DiagramHelper_svx> 
aNewHelper(svx::diagram::DiagramHelperFactory_svx::getDiagramHelperFactory_svx().createDiagramHelper_svx(aDiagramModel));
+
+                mp_DiagramHelper = aNewHelper;
+                mp_DiagramHelper->getRootShape() = getUnoShape();
+            }
+        }
+    }
+
+    // call parent to set evtl. original description
+    SdrObject::SetDescription(aOrigDescription);
+}
+
+OUString SdrObjGroup::GetDescription() const
+{
+    static bool bActivateAdvancedDiagramFeatures(nullptr != 
std::getenv("ACTIVATE_ADVANCED_DIAGRAM_FEATURES"));
+    if (!bActivateAdvancedDiagramFeatures)
+        return SdrObject::GetDescription();
+
+    // call parent to get original description
+    OUString aRetval(SdrObject::GetDescription());
+
+    if (mp_DiagramHelper && getSdrModelFromSdrObject().isLocked())
+    {
+        // we are a Diagram and are exporting. Get the Diagram ModelData and
+        // place it to the description
+        // NOTE: currently isLocked() is used  to identify export, that *may* 
have
+        //       to be made more specific in SdXMLExport
+        boost::property_tree::ptree aDiagramModel;
+
+        // get Diagram ModelData in property_tree
+        mp_DiagramHelper->addDiagramModelData(aDiagramModel);
+
+        // add original description if exists
+        if (!aRetval.isEmpty())
+            aDiagramModel.put("origDesc", aRetval);
+
+        // convert property_tree to OUString and return
+        std::stringstream aStream;
+        boost::property_tree::write_info(aStream, aDiagramModel);
+
+        // add identifying token at start
+        aRetval = u"SmartArtModelData:" + OUString::fromUtf8(aStream.str());
+    }
+
+    return aRetval;
+}
+
 void SdrObjGroup::dumpAsXml(xmlTextWriterPtr pWriter) const
 {
     (void)xmlTextWriterStartElement(pWriter, BAD_CAST("SdrObjGroup"));
diff --git a/svx/source/xml/xmlexport.cxx b/svx/source/xml/xmlexport.cxx
index 73ffdee3811f..3ac3596e105c 100644
--- a/svx/source/xml/xmlexport.cxx
+++ b/svx/source/xml/xmlexport.cxx
@@ -51,8 +51,9 @@ bool SvxDrawingLayerExport( SdrModel* pModel, const 
uno::Reference<io::XOutputSt
 
     Reference< document::XEmbeddedObjectResolver > xObjectResolver;
     rtl::Reference<SvXMLEmbeddedObjectHelper> xObjectHelper;
-
     Reference< lang::XComponent > xSourceDoc( xComponent );
+    Reference< frame::XModel > xSourceModel;
+
     try
     {
         if( !xSourceDoc.is() )
@@ -62,6 +63,10 @@ bool SvxDrawingLayerExport( SdrModel* pModel, const 
uno::Reference<io::XOutputSt
             pModel->setUnoModel( pDrawingModel );
         }
 
+        xSourceModel = Reference< frame::XModel >( xSourceDoc, UNO_QUERY );
+        if ( xSourceModel.is() )
+            xSourceModel->lockControllers();
+
         const uno::Reference< uno::XComponentContext>& xContext( 
::comphelper::getProcessComponentContext() );
 
         if( bDocRet )
@@ -124,6 +129,9 @@ bool SvxDrawingLayerExport( SdrModel* pModel, const 
uno::Reference<io::XOutputSt
     if( xObjectHelper.is() )
         xObjectHelper->dispose();
 
+    if ( xSourceModel.is() )
+        xSourceModel->unlockControllers();
+
     return bDocRet;
 }
 

Reply via email to