include/oox/drawingml/diagram/diagramhelper_oox.hxx    |   19 +--
 include/oox/drawingml/shape.hxx                        |    4 
 include/svx/diagram/DiagramHelper_svx.hxx              |    9 +
 include/svx/diagram/DomMapFlag.hxx                     |    3 
 include/svx/diagram/datamodel_svx.hxx                  |   92 +++++++++--------
 include/svx/svdobj.hxx                                 |    7 -
 oox/source/drawingml/diagram/datamodel_oox.cxx         |   52 +++++++--
 oox/source/drawingml/diagram/datamodel_oox.hxx         |    3 
 oox/source/drawingml/diagram/datamodelcontext.cxx      |    2 
 oox/source/drawingml/diagram/diagram.cxx               |   44 +++++---
 oox/source/drawingml/diagram/diagram.hxx               |   15 +-
 oox/source/drawingml/diagram/diagramhelper_oox.cxx     |   40 +++++--
 oox/source/drawingml/diagram/diagramlayoutatoms.hxx    |    6 -
 oox/source/drawingml/diagram/layoutatomvisitorbase.hxx |    6 -
 oox/source/drawingml/diagram/layoutatomvisitors.hxx    |    6 -
 oox/source/drawingml/graphicshapecontext.cxx           |    4 
 oox/source/drawingml/shape.cxx                         |    7 -
 oox/source/export/drawingml.cxx                        |   53 +++++----
 svx/source/diagram/DiagramHelper_svx.cxx               |    7 +
 svx/source/diagram/datamodel_svx.cxx                   |   64 ++++++++---
 svx/source/svdraw/svdobj.cxx                           |   16 ++
 svx/source/svdraw/svdogrp.cxx                          |   10 +
 22 files changed, 310 insertions(+), 159 deletions(-)

New commits:
commit 8353e8c98547c72ae943a219e4ff5046611869c8
Author:     Armin Le Grand (collabora) <[email protected]>
AuthorDate: Thu Feb 12 16:16:34 2026 +0100
Commit:     Armin Le Grand <[email protected]>
CommitDate: Fri Feb 13 10:59:15 2026 +0100

    SmartArt: Add basic Copy/Paste functionality
    
    Next thing we need copy/paste. That creates internally
    a new doc with the cloned selected object. Two cases:
    (a) If copy/paste is inside same instance, that gets
        cloned again to the target, done.
    (b) If target is other app (2nd office instance, ...)
        new doc is saved using ODF (or other), re-loaded
        by target LO instance and then cloned like (a)
    
    For (a) we need cloning functionality in LO core.
    For (b) we need support in ODF format. Thus (a) is
    less complext than (b) and a precondition for (b),
    too.
    
    This change mainly enables (a). It also contains deep
    check of correctness for DomTrees for Data and
    Drawing stuff, especially for Pint and Connection
    data.
    
    Also as a 1st step for (b) I moved the
    DiagramDataModelID to use the SdrObjectTitle - those
    Objects are encapsulated inside the hosting
    GroupObject anyways and we have that part of ODF
    im/export solved that way.
    NOTE: I first used SdrObjectName, but that gets
    *changed* when SdrObject is cloned to ensure
    unified ObjNames inside a Document.
    
    This is secured by ACTIVATE_ADVANCED_DIAGRAM_FEATURES
    as last commits for SmartArt since notg complete.
    
    Change-Id: Iff51ca56e559111cc8d205fc501d96b0a1d7c616
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/199287
    Reviewed-by: Armin Le Grand <[email protected]>
    Tested-by: Jenkins

diff --git a/include/oox/drawingml/diagram/diagramhelper_oox.hxx 
b/include/oox/drawingml/diagram/diagramhelper_oox.hxx
index 046e4e885ede..30367e0b2930 100644
--- a/include/oox/drawingml/diagram/diagramhelper_oox.hxx
+++ b/include/oox/drawingml/diagram/diagramhelper_oox.hxx
@@ -27,7 +27,7 @@
 
 namespace oox::drawingml {
 
-class Diagram;
+class SmartArtDiagram;
 class DrawingML;
 
 // Advanced DiagramHelper
@@ -45,19 +45,16 @@ class DrawingML;
 // - im/export Diagram model to other representations
 class DiagramHelper_oox final : public svx::diagram::DiagramHelper_svx
 {
-    const std::shared_ptr< Diagram >            mpDiagramPtr;
-    std::shared_ptr<::oox::drawingml::Theme>    mpThemePtr;
+    const std::shared_ptr< SmartArtDiagram >         mpDiagramPtr;
+    std::shared_ptr<::oox::drawingml::Theme>    mpDiagramThemePtr;
 
-    css::awt::Size maImportSize;
+    css::awt::Size maDiagramImportSize;
 
     // data values set by addDiagramNode to be used by next reLayout call
     // when a new ode gets added
     OUString msNewNodeId;
     OUString msNewNodeText;
 
-    // flag to remember if initial import had a DrawingDom at all
-    bool mbInitiallyNoDrawingDom;
-
     bool hasDiagramData() const;
 
     static void moveDiagramModelDataFromOldToNewXShape(
@@ -70,9 +67,10 @@ protected:
 
 public:
     DiagramHelper_oox(
-        std::shared_ptr< Diagram > xDiagramPtr,
+        std::shared_ptr< SmartArtDiagram > xDiagramPtr,
         std::shared_ptr<::oox::drawingml::Theme> xTheme,
         css::awt::Size aImportSize);
+    explicit DiagramHelper_oox(DiagramHelper_oox const& rSource);
     virtual ~DiagramHelper_oox();
 
     // re-create XShapes
@@ -110,9 +108,8 @@ 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;
 
-    // flag to remember if initial import had a DrawingDom at all
-    void setInitiallyNoDrawingDom(bool bNew) { mbInitiallyNoDrawingDom = bNew; 
}
-    bool getInitiallyNoDrawingDom() const { return mbInitiallyNoDrawingDom; }
+    // needed to create DiagramHelper_oox in svx' SdrObjGroup copy constructor
+    virtual DiagramHelper_oox* clone() const override;
 };
 
 }
diff --git a/include/oox/drawingml/shape.hxx b/include/oox/drawingml/shape.hxx
index a0f7af687d63..59f5e2a9e33d 100644
--- a/include/oox/drawingml/shape.hxx
+++ b/include/oox/drawingml/shape.hxx
@@ -98,7 +98,7 @@ struct LinkedTxbxAttr
     LinkedTxbxAttr(): id(0),seq(0){};
 };
 
-class Diagram;
+class SmartArtDiagram;
 
 class OOX_DLLPUBLIC Shape
     : public std::enable_shared_from_this< Shape >
@@ -277,7 +277,7 @@ public:
     // Allows preparation of a local Diagram helper && propagate an eventually
     // existing one to the data holder object later
     SAL_DLLPRIVATE void prepareDiagramHelper(
-        const std::shared_ptr< Diagram >& rDiagramPtr,
+        const std::shared_ptr< SmartArtDiagram >& rDiagramPtr,
         const std::shared_ptr<::oox::drawingml::Theme>& rTheme);
     SAL_DLLPRIVATE void propagateDiagramHelper();
 
diff --git a/include/svx/diagram/DiagramHelper_svx.hxx 
b/include/svx/diagram/DiagramHelper_svx.hxx
index 583964d7ac40..60bd7c37754b 100644
--- a/include/svx/diagram/DiagramHelper_svx.hxx
+++ b/include/svx/diagram/DiagramHelper_svx.hxx
@@ -84,8 +84,12 @@ protected:
     // access associated SdrObjGroup/XShape/RootShape
     virtual css::uno::Reference< css::drawing::XShape >& accessRootShape() = 0;
 
-public:
+    // Make constructor protected to signal that this anyway pure virtual class
+    // shall not be incarnated - target to use is 
oox::drawingml::DiagramHelper_oox
     DiagramHelper_svx();
+    explicit DiagramHelper_svx(DiagramHelper_svx const& rSource);
+
+public:
     virtual ~DiagramHelper_svx();
 
     // re-create XShapes
@@ -127,6 +131,9 @@ public:
 
     // access to RootShape - the GroupObject used to host this Diagram
     css::uno::Reference< css::drawing::XShape >& getRootShape() { return 
accessRootShape(); }
+
+    // needed to create DiagramHelper_oox in svx' SdrObjGroup copy constructor
+    virtual DiagramHelper_svx* clone() const = 0;
 };
 
 }} // end of namespace
diff --git a/include/svx/diagram/DomMapFlag.hxx 
b/include/svx/diagram/DomMapFlag.hxx
index 0ceb4186f7f3..e9673e1d990d 100644
--- a/include/svx/diagram/DomMapFlag.hxx
+++ b/include/svx/diagram/DomMapFlag.hxx
@@ -34,7 +34,8 @@ enum class SVXCORE_DLLPUBLIC DomMapFlag : sal_uInt16
     OOXStyle = 4,
     OOXColor = 5,
     OOXDrawing = 6,
-    OOXDrawingRels = 7
+    OOXDrawingImageRels = 7,
+    OOXDrawingHlinkRels = 8
 };
 
 typedef std::vector<DomMapFlag> DomMapFlags;
diff --git a/include/svx/diagram/datamodel_svx.hxx 
b/include/svx/diagram/datamodel_svx.hxx
index 357c63245894..352eae2104d0 100644
--- a/include/svx/diagram/datamodel_svx.hxx
+++ b/include/svx/diagram/datamodel_svx.hxx
@@ -60,7 +60,7 @@ struct SVXCORE_DLLPUBLIC Connection
 {
     Connection();
 
-    TypeConstant mnXMLType;
+    TypeConstant mnXMLType; // default is XML_parOf
     OUString msModelId;
     OUString msSourceId;
     OUString msDestId;
@@ -81,51 +81,56 @@ struct SVXCORE_DLLPUBLIC Point
 {
     Point();
 
-    OUString msCnxId;
-    OUString msModelId;
-    OUString msColorTransformCategoryId;
-    OUString msColorTransformTypeId;
-    OUString msLayoutCategoryId;
-    OUString msLayoutTypeId;
-    OUString msPlaceholderText;
-    OUString msPresentationAssociationId;
-    OUString msPresentationLayoutName;
-    OUString msPresentationLayoutStyleLabel;
-    OUString msQuickStyleCategoryId;
-    OUString msQuickStyleTypeId;
-    OUString msResizeHandles;
-
-    TypeConstant mnXMLType;
-    sal_Int32     mnMaxChildren;
-    sal_Int32     mnPreferredChildren;
-    sal_Int32     mnDirection;
-    std::optional<sal_Int32> moHierarchyBranch;
-    sal_Int32     mnCustomAngle;
-    sal_Int32     mnPercentageNeighbourWidth;
-    sal_Int32     mnPercentageNeighbourHeight;
-    sal_Int32     mnPercentageOwnWidth;
-    sal_Int32     mnPercentageOwnHeight;
-    sal_Int32     mnIncludeAngleScale;
-    sal_Int32     mnRadiusScale;
-    sal_Int32     mnWidthScale;
-    sal_Int32     mnHeightScale;
-    sal_Int32     mnWidthOverride;
-    sal_Int32     mnHeightOverride;
-    sal_Int32     mnLayoutStyleCount;
-    sal_Int32     mnLayoutStyleIndex;
-
-    bool          mbOrgChartEnabled;
-    bool          mbBulletEnabled;
-    bool          mbCoherent3DOffset;
-    bool          mbCustomHorizontalFlip;
-    bool          mbCustomVerticalFlip;
-    bool          mbCustomText;
-    bool          mbIsPlaceholder;
+    // 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;
 
     void writeDiagramData_data(sax_fastparser::FSHelperPtr& rTarget);
 };
 
-void SVXCORE_DLLPUBLIC addTypeConstantToFastAttributeList(TypeConstant 
aTypeConstant, rtl::Reference<sax_fastparser::FastAttributeList>& 
rAttributeList);
+void SVXCORE_DLLPUBLIC addTypeConstantToFastAttributeList(TypeConstant 
aTypeConstant, rtl::Reference<sax_fastparser::FastAttributeList>& 
rAttributeList, bool bPoint);
 typedef std::vector< Point >        Points;
 
 /** Snippet of Diagram ModelData for Diagram-defining data undo/redo
@@ -166,6 +171,7 @@ protected:
     // Make constructor protected to signal that this anyway pure virtual class
     // shall not be incarnated - target to use is 
oox::drawingml::DiagramData_oox
     DiagramData_svx();
+    explicit DiagramData_svx(DiagramData_svx const& rSource);
 
 public:
     // access associated SdrObjGroup/XShape/RootShape
@@ -178,7 +184,9 @@ public:
     virtual void buildDiagramDataModel(bool bClearOoxShapes);
 
     // dump to readable format
+#ifdef DBG_UTIL
     virtual void dump() const = 0;
+    #endif
 
     // read accesses
     Connections& getConnections() { return maConnections; }
diff --git a/include/svx/svdobj.hxx b/include/svx/svdobj.hxx
index af040b18d14c..4fd5a4773499 100644
--- a/include/svx/svdobj.hxx
+++ b/include/svx/svdobj.hxx
@@ -230,8 +230,8 @@ public:
     virtual bool isDiagram() const;
     virtual const std::shared_ptr< svx::diagram::DiagramHelper_svx >& 
getDiagramHelper() const;
     const std::shared_ptr< svx::diagram::DiagramHelper_svx >& 
getDiagramHelperFromDiagramOrMember() const;
-    void setDiagramDataModelID(const OUString& rID) { msDiagramDataModelID = 
rID; }
-    const OUString& getDiagramDataModelID() const { return 
msDiagramDataModelID; }
+    void setDiagramDataModelID(const OUString& rID);
+    const OUString& getDiagramDataModelID() const;
 
 private:
     friend class                SdrObjListIter;
@@ -993,9 +993,6 @@ private:
     // Hyperlink for the whole shape
     OUString msHyperlink;
 
-    // if this object is a representation of Diagram Sub-Data, hold the 
DataModelID
-    OUString msDiagramDataModelID;
-
     // only for internal use!
     SvxShape* getSvxShape();
 
diff --git a/oox/source/drawingml/diagram/datamodel_oox.cxx 
b/oox/source/drawingml/diagram/datamodel_oox.cxx
index 349656c71c34..9c9f4b085e12 100644
--- a/oox/source/drawingml/diagram/datamodel_oox.cxx
+++ b/oox/source/drawingml/diagram/datamodel_oox.cxx
@@ -129,7 +129,7 @@ void DiagramData_oox::writeDiagramData(DrawingML& 
rOriginalDrawingML, sax_fastpa
         rtl::Reference<sax_fastparser::FastAttributeList> 
pAttributeList(sax_fastparser::FastSerializerHelper::createAttrList());
 
         pAttributeList->add(XML_modelId, rPoint.msModelId);
-        addTypeConstantToFastAttributeList(rPoint.mnXMLType, pAttributeList);
+        addTypeConstantToFastAttributeList(rPoint.mnXMLType, pAttributeList, 
true);
         if (!rPoint.msCnxId.isEmpty())
             pAttributeList->add(XML_cxnId, rPoint.msCnxId);
         rTarget->startElementNS(XML_dgm, XML_pt, pAttributeList);
@@ -212,9 +212,13 @@ void DiagramData_oox::writeDiagramData(DrawingML& 
rOriginalDrawingML, sax_fastpa
 
         if (bWriteFill)
         {
+            rTarget->startElementNS(XML_dgm, XML_spPr);
+
             DrawingML aTempML(rTarget, pOriginalFB);
             aTempML.setDiagaramExport(true);
             aTempML.WriteFill( xProps, xAssociatedShape->getSize());
+
+            rTarget->endElementNS(XML_dgm, XML_spPr);
         }
         else
         {
@@ -274,7 +278,7 @@ void DiagramData_oox::writeDiagramData(DrawingML& 
rOriginalDrawingML, sax_fastpa
     {
         aDspLine += u"relId=\""_ustr + rDrawingRelId + u"\" "_ustr;
     }
-    aDspLine += u"minVer=\""_ustr + aNsDml + u"\"/>"_ustr;
+    aDspLine += u"minVer=\""_ustr + aNsDmlDiagram + u"\"/>"_ustr;
     rTarget->write(aDspLine);
     rTarget->endElementNS(XML_a, XML_ext);
     rTarget->endElementNS(XML_dgm, XML_extLst);
@@ -289,38 +293,64 @@ DiagramData_oox::DiagramData_oox()
 {
 }
 
+DiagramData_oox::DiagramData_oox(DiagramData_oox const& rSource)
+: svx::diagram::DiagramData_svx(rSource)
+, mpBackgroundShapeFillProperties()
+, maPointShapeMap()
+{
+}
+
 DiagramData_oox::~DiagramData_oox()
 {
 }
 
+#ifdef DBG_UTIL
 static void Connection_dump(const svx::diagram::Connection& rConnection)
 {
     SAL_INFO(
         "oox.drawingml",
-        "cnx modelId " << rConnection.msModelId << ", srcId " << 
rConnection.msSourceId << ", dstId "
+        "  CNX: modelId " << rConnection.msModelId << ", srcId " << 
rConnection.msSourceId << ", dstId "
             << rConnection.msDestId << ", parTransId " << 
rConnection.msParTransId << ", presId "
             << rConnection.msPresId << ", sibTransId " << 
rConnection.msSibTransId << ", srcOrd "
             << rConnection.mnSourceOrder << ", dstOrd " << 
rConnection.mnDestOrder);
 }
 
-static void Point_dump(const svx::diagram::Point& rPoint, const Shape* pShape)
+static void Point_dump(const svx::diagram::Point& rPoint, const 
uno::Reference<drawing::XShape>& rXShape)
 {
-    SAL_INFO(
-        "oox.drawingml",
-        "pt text " << pShape << ", cnxId " << rPoint.msCnxId << ", modelId "
-            << rPoint.msModelId << ", type " << rPoint.mnXMLType);
+    SAL_INFO("oox.drawingml", "PT: " << rXShape.is() << ", cnxId " << 
rPoint.msCnxId << ", modelId " << rPoint.msModelId << ", type " << 
rPoint.mnXMLType);
+
+    SAL_INFO("oox.drawingml", "  PRS_0: " << rPoint.msColorTransformCategoryId 
<< "," << rPoint.msColorTransformTypeId << "," << rPoint.msLayoutCategoryId << 
"," << rPoint.msLayoutTypeId << "," << rPoint.msPlaceholderText);
+    SAL_INFO("oox.drawingml", "  PRS_1: " << 
rPoint.msPresentationAssociationId << "," << rPoint.msPresentationLayoutName << 
"," << rPoint.msPresentationLayoutStyleLabel << "," << 
rPoint.msQuickStyleCategoryId << "," << rPoint.msQuickStyleTypeId);
+    SAL_INFO("oox.drawingml", "  PRS_2: " << rPoint.mnCustomAngle << "," << 
rPoint.mnPercentageNeighbourWidth << "," << rPoint.mnPercentageNeighbourHeight 
<< "," << rPoint.mnPercentageOwnWidth << "," << rPoint.mnPercentageOwnHeight);
+    SAL_INFO("oox.drawingml", "  PRS_3: " << rPoint.mnIncludeAngleScale<< 
rPoint.mnRadiusScale << "," << rPoint.mnWidthScale << "," << 
rPoint.mnHeightScale << "," << rPoint.mnWidthOverride << "," << 
rPoint.mnHeightOverride << "," <<  rPoint.mnLayoutStyleCount << "," << 
rPoint.mnLayoutStyleIndex);
+    SAL_INFO("oox.drawingml", "  PRS_4: " << rPoint.mbCoherent3DOffset << "," 
<< rPoint.mbCustomHorizontalFlip << "," << rPoint.mbCustomVerticalFlip << "," 
<< rPoint.mbCustomText << "," << rPoint.mbIsPlaceholder);
+
+    SAL_INFO("oox.drawingml", "  PLV_0: " << rPoint.msResizeHandles << "," << 
rPoint.mnMaxChildren << "," << rPoint.mnPreferredChildren << "," << 
rPoint.mnDirection << "," << rPoint.mbOrgChartEnabled << "," << 
rPoint.mbBulletEnabled);
+    SAL_INFO("oox.drawingml", "  PLV_1: " << 
(rPoint.moHierarchyBranch.has_value() ? rPoint.moHierarchyBranch.value() : 0));
+
 }
 
 void DiagramData_oox::dump() const
 {
-    SAL_INFO("oox.drawingml", "Dgm: DiagramData_oox # of cnx: " << 
maConnections.size() );
+    size_t a = maConnections.size();
+    SAL_INFO("oox.drawingml", "Dgm: DiagramData_oox # of cnx: " << a );
+    a = 0;
     for (const auto& rConnection : maConnections)
+    {
+        SAL_INFO("oox.drawingml", "cnx #" << a++ << ":");
         Connection_dump(rConnection);
+    }
 
-    SAL_INFO("oox.drawingml", "Dgm: DiagramData_oox # of pt: " << 
maPoints.size() );
+    a = maPoints.size();
+    SAL_INFO("oox.drawingml", "Dgm: DiagramData_oox # of pt: " << a );
+    a = 0;
     for (const auto& rPoint : maPoints)
-        Point_dump(rPoint, getOrCreateAssociatedShape(rPoint));
+    {
+        SAL_INFO("oox.drawingml", "pt #" << a++ << ":");
+        Point_dump(rPoint, getXShapeByModelID(rPoint.msModelId));
+    }
 }
+#endif
 
 void DiagramData_oox::buildDiagramDataModel(bool bClearOoxShapes)
 {
diff --git a/oox/source/drawingml/diagram/datamodel_oox.hxx 
b/oox/source/drawingml/diagram/datamodel_oox.hxx
index 75579681d2e0..9cede1263d90 100644
--- a/oox/source/drawingml/diagram/datamodel_oox.hxx
+++ b/oox/source/drawingml/diagram/datamodel_oox.hxx
@@ -42,13 +42,16 @@ public:
     typedef std::map< OUString, ShapePtr > PointShapeMap;
 
     DiagramData_oox();
+    explicit DiagramData_oox(DiagramData_oox const& rSource);
     virtual ~DiagramData_oox();
 
     // creates temporary processing data from model data
     virtual void buildDiagramDataModel(bool bClearOoxShapes);
 
     FillPropertiesPtr& getBackgroundShapeFillProperties() { return 
mpBackgroundShapeFillProperties; }
+#ifdef DBG_UTIL
     virtual void dump() const;
+#endif
 
     Shape* getOrCreateAssociatedShape(const svx::diagram::Point& rPoint, bool 
bCreateOnDemand = false) const;
 
diff --git a/oox/source/drawingml/diagram/datamodelcontext.cxx 
b/oox/source/drawingml/diagram/datamodelcontext.cxx
index 336c870a5659..34307b9d6d93 100644
--- a/oox/source/drawingml/diagram/datamodelcontext.cxx
+++ b/oox/source/drawingml/diagram/datamodelcontext.cxx
@@ -343,7 +343,9 @@ DataModelContext::DataModelContext( ContextHandler2Helper 
const& rParent,
 DataModelContext::~DataModelContext()
 {
     // some debug
+#ifdef DBG_UTIL
     mpDataModel->dump();
+#endif
 }
 
 ContextHandlerRef
diff --git a/oox/source/drawingml/diagram/diagram.cxx 
b/oox/source/drawingml/diagram/diagram.cxx
index 5e4089a9d8e2..dc78b6d46511 100644
--- a/oox/source/drawingml/diagram/diagram.cxx
+++ b/oox/source/drawingml/diagram/diagram.cxx
@@ -118,10 +118,10 @@ static void removeUnneededGroupShapes(const ShapePtr& 
pShape)
 }
 
 
-void Diagram::createShapeHierarchyFromModel( const ShapePtr & pParentShape, 
bool bCreate )
+void SmartArtDiagram::createShapeHierarchyFromModel( const ShapePtr & 
pParentShape, bool bCreate )
 {
     if (pParentShape->getSize().Width == 0 || pParentShape->getSize().Height 
== 0)
-        SAL_WARN("oox.drawingml", "Diagram cannot be correctly laid out. Size: 
"
+        SAL_WARN("oox.drawingml", "SmartArtDiagram cannot be correctly laid 
out. Size: "
             << pParentShape->getSize().Width << "x" << 
pParentShape->getSize().Height);
 
     pParentShape->setChildSize(pParentShape->getSize());
@@ -157,12 +157,27 @@ void Diagram::createShapeHierarchyFromModel( const 
ShapePtr & pParentShape, bool
     aChildren.insert(aChildren.begin(), pBackground);
 }
 
-Diagram::Diagram()
+SmartArtDiagram::SmartArtDiagram()
 : maDiagramFontHeights()
+, mpData()
+, mpLayout()
+, maStyles()
+, maColors()
+, maDiagramPRDomMap()
 {
 }
 
-uno::Any Diagram::getOOXDomValue(svx::diagram::DomMapFlag aDomMapFlag) const
+SmartArtDiagram::SmartArtDiagram(SmartArtDiagram const& rSource)
+: maDiagramFontHeights()
+, mpData(rSource.mpData ? new DiagramData_oox(*rSource.mpData) : nullptr)
+, mpLayout(rSource.mpLayout)
+, maStyles(rSource.maStyles)
+, maColors(rSource.maColors)
+, maDiagramPRDomMap(rSource.maDiagramPRDomMap)
+{
+}
+
+uno::Any SmartArtDiagram::getOOXDomValue(svx::diagram::DomMapFlag aDomMapFlag) 
const
 {
     const DiagramPRDomMap::const_iterator aHit = 
maDiagramPRDomMap.find(aDomMapFlag);
 
@@ -172,12 +187,12 @@ uno::Any Diagram::getOOXDomValue(svx::diagram::DomMapFlag 
aDomMapFlag) const
     return uno::Any();
 }
 
-void Diagram::setOOXDomValue(svx::diagram::DomMapFlag aDomMapFlag, const 
uno::Any& rValue)
+void SmartArtDiagram::setOOXDomValue(svx::diagram::DomMapFlag aDomMapFlag, 
const uno::Any& rValue)
 {
     maDiagramPRDomMap[aDomMapFlag] = rValue;
 }
 
-void Diagram::resetOOXDomValues(svx::diagram::DomMapFlags aDomMapFlags)
+void SmartArtDiagram::resetOOXDomValues(svx::diagram::DomMapFlags aDomMapFlags)
 {
     for (const auto& rEntry : aDomMapFlags)
     {
@@ -188,12 +203,12 @@ void Diagram::resetOOXDomValues(svx::diagram::DomMapFlags 
aDomMapFlags)
     }
 }
 
-bool Diagram::checkMinimalDataDoms() const
+bool SmartArtDiagram::checkMinimalDataDoms() const
 {
     // check if re-creation is activated
-    static bool bReCreateDiagramDataDoms(nullptr != 
std::getenv("ACTIVATE_RECREATE_DIAGRAM_DATADOMS"));
+    static bool bActivateAdvancedDiagramFeatures(nullptr != 
std::getenv("ACTIVATE_ADVANCED_DIAGRAM_FEATURES"));
 
-    if (!bReCreateDiagramDataDoms && maDiagramPRDomMap.end() == 
maDiagramPRDomMap.find(svx::diagram::DomMapFlag::OOXData))
+    if (!bActivateAdvancedDiagramFeatures && maDiagramPRDomMap.end() == 
maDiagramPRDomMap.find(svx::diagram::DomMapFlag::OOXData))
         return false;
 
     if (maDiagramPRDomMap.end() == 
maDiagramPRDomMap.find(svx::diagram::DomMapFlag::OOXLayout))
@@ -208,7 +223,7 @@ bool Diagram::checkMinimalDataDoms() const
     return true;
 }
 
-void Diagram::writeDiagramOOXData(DrawingML& rOriginalDrawingML, 
uno::Reference<io::XOutputStream>& xOutputStream, std::u16string_view 
rDrawingRelId) const
+void SmartArtDiagram::writeDiagramOOXData(DrawingML& rOriginalDrawingML, 
uno::Reference<io::XOutputStream>& xOutputStream, std::u16string_view 
rDrawingRelId) const
 {
     if (!xOutputStream)
         return;
@@ -247,7 +262,7 @@ void Diagram::writeDiagramOOXData(DrawingML& 
rOriginalDrawingML, uno::Reference<
 #endif
 }
 
-void Diagram::writeDiagramOOXDrawing(DrawingML& rOriginalDrawingML, 
uno::Reference<io::XOutputStream>& xOutputStream) const
+void SmartArtDiagram::writeDiagramOOXDrawing(DrawingML& rOriginalDrawingML, 
uno::Reference<io::XOutputStream>& xOutputStream) const
 {
     if (!xOutputStream)
         return;
@@ -290,7 +305,7 @@ void Diagram::writeDiagramOOXDrawing(DrawingML& 
rOriginalDrawingML, uno::Referen
 using ShapePairs
     = std::map<std::shared_ptr<drawingml::Shape>, 
uno::Reference<drawing::XShape>>;
 
-void Diagram::syncDiagramFontHeights()
+void SmartArtDiagram::syncDiagramFontHeights()
 {
     // Each name represents a group of shapes, for which the font height 
should have the same
     // scaling.
@@ -421,7 +436,7 @@ void loadDiagram( ShapePtr const & pShape,
                   const OUString& rColorStylePath,
                   const oox::core::Relations& rRelations )
 {
-    DiagramPtr pDiagram = std::make_shared<Diagram>();
+    DiagramPtr pDiagram = std::make_shared<SmartArtDiagram>();
 
     OoxDiagramDataPtr pData = std::make_shared<DiagramData_oox>();
     pDiagram->setData( pData );
@@ -540,6 +555,9 @@ void loadDiagram( ShapePtr const & pShape,
         // collect data, init maps
         // for Diagram import, do - for now - NOT clear all 
oox::drawingml::Shape
         pData->buildDiagramDataModel(false);
+#ifdef DBG_UTIL
+        pData->dump();
+#endif
 
         // diagram loaded. now lump together & attach to shape
         // create own geometry if extLst is not present (no geometric
diff --git a/oox/source/drawingml/diagram/diagram.hxx 
b/oox/source/drawingml/diagram/diagram.hxx
index 4d2008dd9a33..c63e806866c8 100644
--- a/oox/source/drawingml/diagram/diagram.hxx
+++ b/oox/source/drawingml/diagram/diagram.hxx
@@ -35,7 +35,7 @@ namespace com::sun::star {
 
 namespace oox::drawingml {
 
-class Diagram;
+class SmartArtDiagram;
 class LayoutNode;
 typedef std::shared_ptr< LayoutNode > LayoutNodePtr;
 class LayoutAtom;
@@ -46,7 +46,7 @@ typedef std::map< const svx::diagram::Point*, ShapePtr > 
PresPointShapeMap;
 class DiagramLayout
 {
 public:
-    DiagramLayout(Diagram& rDgm)
+    DiagramLayout(SmartArtDiagram& rDgm)
         : mrDgm(rDgm)
     {
     }
@@ -60,7 +60,7 @@ public:
         { msTitle = sTitle; }
     void setDesc( const OUString & sDesc )
         { msDesc = sDesc; }
-    Diagram& getDiagram() { return mrDgm; }
+    SmartArtDiagram& getDiagram() { return mrDgm; }
     LayoutNodePtr & getNode()
         { return mpNode; }
     const LayoutNodePtr & getNode() const
@@ -79,7 +79,7 @@ public:
         { return maPresPointShapeMap; }
 
 private:
-    Diagram& mrDgm;
+    SmartArtDiagram& mrDgm;
     OUString msDefStyle;
     OUString msMinVer;
     OUString msUniqueId;
@@ -125,10 +125,11 @@ struct DiagramColor
 typedef std::map<OUString,DiagramColor> DiagramColorMap;
 typedef std::map<svx::diagram::DomMapFlag,css::uno::Any> DiagramPRDomMap;
 
-class Diagram
+class SmartArtDiagram
 {
 public:
-    explicit Diagram();
+    explicit SmartArtDiagram();
+    explicit SmartArtDiagram(SmartArtDiagram const& rSource);
     void setData( const OoxDiagramDataPtr& pData )
         { mpData = pData; }
     const OoxDiagramDataPtr& getData() const
@@ -169,7 +170,7 @@ private:
     DiagramPRDomMap                maDiagramPRDomMap;
 };
 
-typedef std::shared_ptr< Diagram > DiagramPtr;
+typedef std::shared_ptr< SmartArtDiagram > DiagramPtr;
 
 }
 
diff --git a/oox/source/drawingml/diagram/diagramhelper_oox.cxx 
b/oox/source/drawingml/diagram/diagramhelper_oox.cxx
index c77e2a0a73a5..4f3ad43d84fe 100644
--- a/oox/source/drawingml/diagram/diagramhelper_oox.cxx
+++ b/oox/source/drawingml/diagram/diagramhelper_oox.cxx
@@ -42,15 +42,24 @@ namespace oox::drawingml
 {
 bool DiagramHelper_oox::hasDiagramData() const { return mpDiagramPtr && 
mpDiagramPtr->getData(); }
 
-DiagramHelper_oox::DiagramHelper_oox(std::shared_ptr<Diagram> xDiagramPtr,
+DiagramHelper_oox::DiagramHelper_oox(std::shared_ptr<SmartArtDiagram> 
xDiagramPtr,
                                      std::shared_ptr<::oox::drawingml::Theme> 
xTheme,
                                      awt::Size aImportSize)
     : mpDiagramPtr(std::move(xDiagramPtr))
-    , mpThemePtr(std::move(xTheme))
-    , maImportSize(aImportSize)
+    , mpDiagramThemePtr(std::move(xTheme))
+    , maDiagramImportSize(aImportSize)
+    , msNewNodeId()
+    , msNewNodeText()
+{
+}
+
+DiagramHelper_oox::DiagramHelper_oox(DiagramHelper_oox const& rSource)
+    : DiagramHelper_svx(rSource)
+    , mpDiagramPtr(rSource.mpDiagramPtr ? new 
SmartArtDiagram(*rSource.mpDiagramPtr) : nullptr)
+    , mpDiagramThemePtr(rSource.mpDiagramThemePtr)
+    , maDiagramImportSize(rSource.maDiagramImportSize)
     , msNewNodeId()
     , msNewNodeText()
-    , mbInitiallyNoDrawingDom(false)
 {
 }
 
@@ -100,7 +109,7 @@ void DiagramHelper_oox::reLayout()
     // to get the same layout(s)
     oox::drawingml::ShapePtr pShapePtr = 
std::make_shared<Shape>("com.sun.star.drawing.GroupShape");
     pShapePtr->setDiagramType();
-    pShapePtr->setSize(maImportSize);
+    pShapePtr->setSize(maDiagramImportSize);
 
     // remember existing DrawingLayerModelData. Do this before 
createShapeHierarchyFromModel
     // below, that will create a new BackgroundShapeModelID and the BGShape 
would
@@ -374,7 +383,8 @@ void DiagramHelper_oox::TextInformationChange()
     aFlags.push_back(DomMapFlag::OOXDrawing);
     aFlags.push_back(DomMapFlag::OOXDataImageRels);
     aFlags.push_back(DomMapFlag::OOXDataHlinkRels);
-    aFlags.push_back(DomMapFlag::OOXDrawingRels);
+    aFlags.push_back(DomMapFlag::OOXDrawingImageRels);
+    aFlags.push_back(DomMapFlag::OOXDrawingHlinkRels);
     mpDiagramPtr->resetOOXDomValues(std::move(aFlags));
 
     // still reset GrabBag at Associated SdrObjGroup object. There are no 
"OOX.*"
@@ -424,7 +434,7 @@ const std::shared_ptr<::oox::drawingml::Theme>& 
DiagramHelper_oox::getOrCreateTh
 {
     // (Re-)Use already existing Theme if existing/imported if possible.
     // If not, re-import Theme if data is available and thus possible
-    if (hasDiagramData() && (ForceThemePtrRecreation() || !mpThemePtr))
+    if (hasDiagramData() && (ForceThemePtrRecreation() || !mpDiagramThemePtr))
     {
         // get the originally imported dom::XDocument
         const uno::Reference<xml::dom::XDocument>& xThemeDocument(
@@ -434,20 +444,20 @@ const std::shared_ptr<::oox::drawingml::Theme>& 
DiagramHelper_oox::getOrCreateTh
         {
             // reset local Theme ModelData *always* to get rid of former data 
that would
             // else be added additionally
-            const_cast<DiagramHelper_oox*>(this)->mpThemePtr
+            const_cast<DiagramHelper_oox*>(this)->mpDiagramThemePtr
                 = std::make_shared<oox::drawingml::Theme>();
             auto pTheme = std::make_shared<model::Theme>();
-            mpThemePtr->setTheme(pTheme);
+            mpDiagramThemePtr->setTheme(pTheme);
 
             // import Theme ModelData
             rxFilter->importFragment(
-                new ThemeFragmentHandler(*rxFilter, OUString(), *mpThemePtr, 
*pTheme),
+                new ThemeFragmentHandler(*rxFilter, OUString(), 
*mpDiagramThemePtr, *pTheme),
                 uno::Reference<xml::sax::XFastSAXSerializable>(xThemeDocument,
                                                                
uno::UNO_QUERY_THROW));
         }
     }
 
-    return mpThemePtr;
+    return mpDiagramThemePtr;
 }
 
 void DiagramHelper_oox::setOOXDomValue(DomMapFlag aDomMapFlag, const uno::Any& 
rValue)
@@ -490,6 +500,14 @@ void DiagramHelper_oox::writeDiagramOOXDrawing(
 
     mpDiagramPtr->writeDiagramOOXDrawing(rOriginalDrawingML, xOutputStream);
 }
+
+DiagramHelper_oox* DiagramHelper_oox::clone() const
+{
+    if (!mpDiagramPtr)
+        return nullptr;
+
+    return new DiagramHelper_oox(*this);
+}
 }
 
 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/oox/source/drawingml/diagram/diagramlayoutatoms.hxx 
b/oox/source/drawingml/diagram/diagramlayoutatoms.hxx
index f9ed4c46cc5c..da20dff4cf98 100644
--- a/oox/source/drawingml/diagram/diagramlayoutatoms.hxx
+++ b/oox/source/drawingml/diagram/diagramlayoutatoms.hxx
@@ -306,13 +306,13 @@ class LayoutNode
 public:
     typedef std::map<sal_Int32, OUString> VarMap;
 
-    LayoutNode(Diagram& rDgm)
+    LayoutNode(SmartArtDiagram& rDgm)
         : LayoutAtom(*this)
         , mrDgm(rDgm)
         , mnChildOrder(0)
     {
     }
-    Diagram& getDiagram() { return mrDgm; }
+    SmartArtDiagram& getDiagram() { return mrDgm; }
     virtual void accept( LayoutAtomVisitor& ) override;
     VarMap & variables()
         { return mVariables; }
@@ -339,7 +339,7 @@ public:
     const LayoutNode* getParentLayoutNode() const;
 
 private:
-    Diagram& mrDgm;
+    SmartArtDiagram& mrDgm;
     VarMap                       mVariables;
     OUString                     msMoveWith;
     OUString                     msStyleLabel;
diff --git a/oox/source/drawingml/diagram/layoutatomvisitorbase.hxx 
b/oox/source/drawingml/diagram/layoutatomvisitorbase.hxx
index 49c83f67455d..c202ff17ebdf 100644
--- a/oox/source/drawingml/diagram/layoutatomvisitorbase.hxx
+++ b/oox/source/drawingml/diagram/layoutatomvisitorbase.hxx
@@ -43,7 +43,7 @@ struct LayoutAtomVisitor
 class LayoutAtomVisitorBase : public LayoutAtomVisitor
 {
 public:
-    LayoutAtomVisitorBase(const Diagram& rDgm, const svx::diagram::Point* 
pRootPoint) :
+    LayoutAtomVisitorBase(const SmartArtDiagram& rDgm, const 
svx::diagram::Point* pRootPoint) :
         mrDgm(rDgm),
         mpCurrentNode(pRootPoint),
         mnCurrIdx(0),
@@ -61,7 +61,7 @@ public:
     virtual void visit(LayoutNode& rAtom) override;
 
 protected:
-    const Diagram& mrDgm;
+    const SmartArtDiagram& mrDgm;
     const svx::diagram::Point* mpCurrentNode;
     sal_Int32 mnCurrIdx;
     sal_Int32 mnCurrStep;
@@ -72,7 +72,7 @@ protected:
 class ShallowPresNameVisitor : public LayoutAtomVisitorBase
 {
 public:
-    explicit ShallowPresNameVisitor(const Diagram& rDgm, const 
svx::diagram::Point* pRootPoint) :
+    explicit ShallowPresNameVisitor(const SmartArtDiagram& rDgm, const 
svx::diagram::Point* pRootPoint) :
         LayoutAtomVisitorBase(rDgm, pRootPoint),
         mnCnt(0)
     {}
diff --git a/oox/source/drawingml/diagram/layoutatomvisitors.hxx 
b/oox/source/drawingml/diagram/layoutatomvisitors.hxx
index 7c10fc436d8c..e5911192c29a 100644
--- a/oox/source/drawingml/diagram/layoutatomvisitors.hxx
+++ b/oox/source/drawingml/diagram/layoutatomvisitors.hxx
@@ -31,7 +31,7 @@ namespace oox::drawingml {
 class ShapeCreationVisitor : public LayoutAtomVisitorBase
 {
 public:
-    ShapeCreationVisitor(const Diagram& rDgm,
+    ShapeCreationVisitor(const SmartArtDiagram& rDgm,
                          const svx::diagram::Point* pRootPoint,
                          ShapePtr xParentShape) :
         LayoutAtomVisitorBase(rDgm, pRootPoint),
@@ -52,7 +52,7 @@ private:
 class ShapeTemplateVisitor : public LayoutAtomVisitorBase
 {
 public:
-    ShapeTemplateVisitor(const Diagram& rDgm, const svx::diagram::Point* 
pRootPoint)
+    ShapeTemplateVisitor(const SmartArtDiagram& rDgm, const 
svx::diagram::Point* pRootPoint)
         : LayoutAtomVisitorBase(rDgm, pRootPoint)
     {}
 
@@ -74,7 +74,7 @@ private:
 class ShapeLayoutingVisitor : public LayoutAtomVisitorBase
 {
 public:
-    ShapeLayoutingVisitor(const Diagram& rDgm, const svx::diagram::Point* 
pRootPoint) :
+    ShapeLayoutingVisitor(const SmartArtDiagram& rDgm, const 
svx::diagram::Point* pRootPoint) :
         LayoutAtomVisitorBase(rDgm, pRootPoint)
     {}
 
diff --git a/oox/source/drawingml/graphicshapecontext.cxx 
b/oox/source/drawingml/graphicshapecontext.cxx
index e647d9db7855..3e82b9c956f0 100644
--- a/oox/source/drawingml/graphicshapecontext.cxx
+++ b/oox/source/drawingml/graphicshapecontext.cxx
@@ -40,7 +40,6 @@
 #include <oox/ppt/pptshapegroupcontext.hxx>
 #include <oox/token/namespaces.hxx>
 #include <oox/token/tokens.hxx>
-#include <oox/drawingml/diagram/diagramhelper_oox.hxx>
 
 using namespace ::com::sun::star;
 using namespace ::com::sun::star::io;
@@ -316,9 +315,6 @@ ContextHandlerRef 
DiagramGraphicDataContext::onCreateContext( ::sal_Int32 aEleme
         if (mpShapePtr->getExtDrawings().empty())
         {
             getFilter().setMissingExtDrawing();
-            DiagramHelper_oox* pHelper(mpShapePtr->getDiagramHelper());
-            if (nullptr != pHelper)
-                pHelper->setInitiallyNoDrawingDom(true);
         }
         else
         {
diff --git a/oox/source/drawingml/shape.cxx b/oox/source/drawingml/shape.cxx
index 1c9384f8f622..26d3a903aa1c 100644
--- a/oox/source/drawingml/shape.cxx
+++ b/oox/source/drawingml/shape.cxx
@@ -254,7 +254,7 @@ Shape::~Shape()
 }
 
 void Shape::prepareDiagramHelper(
-    const std::shared_ptr< Diagram >& rDiagramPtr,
+    const std::shared_ptr< SmartArtDiagram >& rDiagramPtr,
     const std::shared_ptr<::oox::drawingml::Theme>& rTheme)
 {
     // Prepare Diagram data collecting for this Shape
@@ -2417,8 +2417,11 @@ void Shape::keepDiagramDrawing(XmlFilterBase& 
rFilterBase, const OUString& rFrag
         svx::diagram::DomMapFlag::OOXDrawing,
         uno::Any(rFilterBase.importFragment(rFragmentPath)));
     pAdvancedDiagramHelper->setOOXDomValue(
-        svx::diagram::DomMapFlag::OOXDrawingRels,
+        svx::diagram::DomMapFlag::OOXDrawingImageRels,
         uno::Any(resolveRelationshipsOfTypeFromOfficeDoc(rFilterBase, 
rFragmentPath, u"image")));
+    pAdvancedDiagramHelper->setOOXDomValue(
+        svx::diagram::DomMapFlag::OOXDrawingHlinkRels,
+        uno::Any(resolveRelationshipsOfTypeFromOfficeDoc(rFilterBase, 
rFragmentPath, u"hlink")));
 }
 
 void Shape::convertSmartArtToMetafile(XmlFilterBase const & rFilterBase)
diff --git a/oox/source/export/drawingml.cxx b/oox/source/export/drawingml.cxx
index 8b0c8989f766..837043b948d8 100644
--- a/oox/source/export/drawingml.cxx
+++ b/oox/source/export/drawingml.cxx
@@ -6848,10 +6848,8 @@ void DrawingML::WriteDiagram(const 
css::uno::Reference<css::drawing::XShape>& rX
     // from original import. it needs a drawingRelId that is referenced inside 
dataDom
     uno::Reference<xml::dom::XDocument> drawingDom;
     rIDiagramHelper->getOOXDomValue(svx::diagram::DomMapFlag::OOXDrawing) >>= 
drawingDom;
-    const OUString drawingFileName("diagrams/drawing" + 
OUString::number(nDiagramId) + ".xml");
-    const OUString sRelationCompPrefix(GetRelationCompPrefix());
-    const OUString sDir(GetComponentDir());
     static bool bForceAlwaysReCreate(nullptr != 
std::getenv("FORCE_RECREATE_DIAGRAM_DATADOMS"));
+    static bool bActivateAdvancedDiagramFeatures(nullptr != 
std::getenv("ACTIVATE_ADVANCED_DIAGRAM_FEATURES"));
 
     // check if re-creation is forced (for test purposes)
     if (drawingDom && bForceAlwaysReCreate)
@@ -6865,10 +6863,13 @@ void DrawingML::WriteDiagram(const 
css::uno::Reference<css::drawing::XShape>& rX
     // that do not originally have a drawingDom at all. The test mentions
     // that this file was created in ms word 2007. In those cases we might
     // try in the future to 'repair' stuff by writing a DrawingDom, but for
-    // now just do as version before did - write no DrawingSDom at all
-    const bool 
bWriteNoDrawingDomAtAll(pAdvancedDiagramHelper->getInitiallyNoDrawingDom());
+    // now just do as version before did - write no DrawingDom at all if new
+    // features are not activated
+    const OUString drawingFileName("diagrams/drawing" + 
OUString::number(nDiagramId) + ".xml");
+    const OUString sRelationCompPrefix(GetRelationCompPrefix());
+    const OUString sDir(GetComponentDir());
 
-    if (!bWriteNoDrawingDomAtAll)
+    if (bActivateAdvancedDiagramFeatures || drawingDom.is())
     {
         // only add Relation if we write a DrawingDom
         drawingRelId = mpFB->addRelation(
@@ -6876,7 +6877,7 @@ void DrawingML::WriteDiagram(const 
css::uno::Reference<css::drawing::XShape>& rX
             Concat2View(sRelationCompPrefix + drawingFileName));
     }
 
-    if (!drawingDom && !bWriteNoDrawingDomAtAll)
+    if (!drawingDom && bActivateAdvancedDiagramFeatures)
     {
         // no drawingDom exists, so it was either not originally imported or 
the
         // Diagram was changed, so it got deleted. write drawingDom directly as
@@ -6897,11 +6898,17 @@ void DrawingML::WriteDiagram(const 
css::uno::Reference<css::drawing::XShape>& rX
     if (dataDom && bForceAlwaysReCreate)
         dataDom.clear();
 
+    // add data relation
+    const OUString dataFileName = "diagrams/data" + 
OUString::number(nDiagramId) + ".xml";
+    const OUString dataRelId =
+        mpFB->addRelation(mpFS->getOutputStream(), 
oox::getRelationship(Relationship::DIAGRAMDATA),
+                          Concat2View(sRelationCompPrefix + dataFileName));
+
     if (!dataDom)
     {
         // no dataDom exists, so  the  Diagram was changed, so it got deleted.
         // write dataDom directly as sub-content
-        OUString dataFileName = u"diagrams/data"_ustr + 
OUString::number(nDiagramId) + u".xml"_ustr;
+        // OUString dataFileName = u"diagrams/data"_ustr + 
OUString::number(nDiagramId) + u".xml"_ustr;
         uno::Reference<io::XOutputStream> xOutputStream = 
mpFB->openFragmentStream(
             sDir + u"/"_ustr + dataFileName,
             
u"application/vnd.openxmlformats-officedocument.drawingml.diagramData+xml"_ustr);
@@ -6971,12 +6978,6 @@ void DrawingML::WriteDiagram(const 
css::uno::Reference<css::drawing::XShape>& rX
     mpFS->startElementNS(XML_a, XML_graphicData, XML_uri,
                          
"http://schemas.openxmlformats.org/drawingml/2006/diagram";);
 
-    // add data relation
-    OUString dataFileName = "diagrams/data" + OUString::number(nDiagramId) + 
".xml";
-    OUString dataRelId =
-        mpFB->addRelation(mpFS->getOutputStream(), 
oox::getRelationship(Relationship::DIAGRAMDATA),
-                          Concat2View(sRelationCompPrefix + dataFileName));
-
     // add layout relation
     OUString layoutFileName = "diagrams/layout" + OUString::number(nDiagramId) 
+ ".xml";
     OUString layoutRelId = mpFB->addRelation(mpFS->getOutputStream(),
@@ -7012,8 +7013,8 @@ void DrawingML::WriteDiagram(const 
css::uno::Reference<css::drawing::XShape>& rX
     {
         if (!drawingRelId.isEmpty())
         {
-            // NOTE: drawingRelId may be empty if bWriteNoDrawingDomAtAll is 
set, see
-            // comments above
+            // NOTE: drawingRelId may be empty if 
bActivateAdvancedDiagramFeatures is
+            // set, see comments above
             // the original and unchanged dataDom contains a reference to the 
drawing
             // relation. We need to update it with the new generated relation 
value
             // before writing the dom to the file
@@ -7092,11 +7093,19 @@ void DrawingML::WriteDiagram(const 
css::uno::Reference<css::drawing::XShape>& rX
             uno::Reference<xml::sax::XDocumentHandler>(writer, 
uno::UNO_QUERY_THROW),
             uno::Sequence<beans::StringPair>());
 
-        // write the associated Images and rels for drawing file
-        uno::Sequence<uno::Sequence<uno::Any>> xDrawingRelSeq;
-        
rIDiagramHelper->getOOXDomValue(svx::diagram::DomMapFlag::OOXDrawingRels) >>= 
xDrawingRelSeq;
-        writeDiagramImageRels(xDrawingRelSeq, xDrawingOutputStream, 
u"OOXDiagramDrawingRels",
-                            nDiagramId);
+        // get originally imported OOXDrawingImageRels
+        uno::Sequence<uno::Sequence<uno::Any>> xDrawingImageRelSeq;
+        
rIDiagramHelper->getOOXDomValue(svx::diagram::DomMapFlag::OOXDrawingImageRels)
+            >>= xDrawingImageRelSeq;
+
+                // get originally imported OOXDataHlinkRels
+        uno::Sequence<uno::Sequence<uno::Any>> xDrawingHlinkRelSeq;
+        
rIDiagramHelper->getOOXDomValue(svx::diagram::DomMapFlag::OOXDrawingHlinkRels)
+            >>= xDrawingHlinkRelSeq;
+
+        // write the associated Images and rels for data file
+        writeDiagramImageRels(xDrawingImageRelSeq, xDrawingOutputStream, 
u"OOXDiagramDrawingRels", nDiagramId);
+        writeDiagramHlinkRels(xDrawingHlinkRelSeq, xDrawingOutputStream);
     }
 }
 
@@ -7104,7 +7113,7 @@ void DrawingML::writeDiagramImageRels(const 
uno::Sequence<uno::Sequence<uno::Any
                                       const uno::Reference<io::XOutputStream>& 
xOutStream,
                                       std::u16string_view sGrabBagProperyName, 
int nDiagramId)
 {
-    // add image relationships of OOXData, OOXDiagram
+    // add image relationships of OOXData, SmartArtDiagram
     OUString sType(oox::getRelationship(Relationship::IMAGE));
     uno::Reference<xml::sax::XWriter> xWriter
         = xml::sax::Writer::create(comphelper::getProcessComponentContext());
diff --git a/svx/source/diagram/DiagramHelper_svx.cxx 
b/svx/source/diagram/DiagramHelper_svx.cxx
index e4ca89d73d4c..66fce4a71f13 100644
--- a/svx/source/diagram/DiagramHelper_svx.cxx
+++ b/svx/source/diagram/DiagramHelper_svx.cxx
@@ -412,6 +412,13 @@ DiagramHelper_svx::DiagramHelper_svx()
 {
 }
 
+DiagramHelper_svx::DiagramHelper_svx(DiagramHelper_svx const& rSource)
+: mbUseDiagramThemeData(rSource.mbUseDiagramThemeData)
+, mbUseDiagramModelData(rSource.mbUseDiagramModelData)
+, mbForceThemePtrRecreation(rSource.mbForceThemePtrRecreation)
+{
+}
+
 DiagramHelper_svx::~DiagramHelper_svx() {}
 
 void DiagramHelper_svx::disconnectFromSdrObjGroup()
diff --git a/svx/source/diagram/datamodel_svx.cxx 
b/svx/source/diagram/datamodel_svx.cxx
index b20188452d4b..a4fba56d989a 100644
--- a/svx/source/diagram/datamodel_svx.cxx
+++ b/svx/source/diagram/datamodel_svx.cxx
@@ -35,7 +35,7 @@ using namespace ::com::sun::star;
 
 namespace svx::diagram {
 
-void addTypeConstantToFastAttributeList(TypeConstant aTypeConstant, 
rtl::Reference<sax_fastparser::FastAttributeList>& rAttributeList)
+void addTypeConstantToFastAttributeList(TypeConstant aTypeConstant, 
rtl::Reference<sax_fastparser::FastAttributeList>& rAttributeList, bool bPoint)
 {
     if (TypeConstant::XML_none != aTypeConstant)
     {
@@ -46,9 +46,9 @@ void addTypeConstantToFastAttributeList(TypeConstant 
aTypeConstant, rtl::Referen
             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: /* XML_node is default, no need to 
write */ 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: rAttributeList->add(::XML_type, 
"parOf"); 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;
@@ -61,7 +61,7 @@ void addTypeConstantToFastAttributeList(TypeConstant 
aTypeConstant, rtl::Referen
 }
 
 Connection::Connection()
-: mnXMLType( XML_none )
+: mnXMLType( XML_parOf )
 , mnSourceOrder( 0 )
 , mnDestOrder( 0 )
 {
@@ -74,21 +74,27 @@ void 
Connection::writeDiagramData(sax_fastparser::FSHelperPtr& rTarget)
 
     rtl::Reference<sax_fastparser::FastAttributeList> 
pAttributeList(sax_fastparser::FastSerializerHelper::createAttrList());
 
-    addTypeConstantToFastAttributeList(mnXMLType, pAttributeList);
-    if (!msModelId.isEmpty()) pAttributeList->add(XML_modelId, msModelId);
-    if (!msSourceId.isEmpty()) pAttributeList->add(XML_srcId, msSourceId);
-    if (!msDestId.isEmpty()) pAttributeList->add(XML_destId, msDestId);
-    if (!msPresId.isEmpty()) pAttributeList->add(XML_presId, msPresId);
-    if (!msSibTransId.isEmpty()) pAttributeList->add(XML_sibTransId, 
msSibTransId);
-    if (!msParTransId.isEmpty()) pAttributeList->add(XML_parTransId, 
msParTransId);
-    if (0 != mnSourceOrder) pAttributeList->add(XML_srcOrd, 
OUString::number(mnSourceOrder));
-    if (0 != mnDestOrder) pAttributeList->add(XML_destOrd, 
OUString::number(mnDestOrder));
+    if (!msModelId.isEmpty())
+        pAttributeList->add(XML_modelId, msModelId);
+    addTypeConstantToFastAttributeList(mnXMLType, pAttributeList, false);
+    if (!msSourceId.isEmpty())
+        pAttributeList->add(XML_srcId, msSourceId);
+    if (!msDestId.isEmpty())
+        pAttributeList->add(XML_destId, msDestId);
+    pAttributeList->add(XML_srcOrd, OUString::number(mnSourceOrder));
+    pAttributeList->add(XML_destOrd, OUString::number(mnDestOrder));
+    if (!msPresId.isEmpty())
+        pAttributeList->add(XML_presId, msPresId);
+    if (!msParTransId.isEmpty())
+        pAttributeList->add(XML_parTransId, msParTransId);
+    if (!msSibTransId.isEmpty())
+        pAttributeList->add(XML_sibTransId, msSibTransId);
 
     rTarget->singleElementNS(XML_dgm, XML_cxn, pAttributeList);
 }
 
 Point::Point()
-: mnXMLType(XML_none)
+: mnXMLType(XML_node)
 , mnMaxChildren(-1)
 , mnPreferredChildren(-1)
 , mnDirection(XML_norm)
@@ -193,6 +199,30 @@ void 
Point::writeDiagramData_data(sax_fastparser::FSHelperPtr& rTarget)
 }
 
 DiagramData_svx::DiagramData_svx()
+: mxRootShape()
+, maExtDrawings()
+, maConnections()
+, maPoints()
+, mxThemeDocument()
+, maPointNameMap()
+, maPointsPresNameMap()
+, maConnectionNameMap()
+, maPresOfNameMap()
+, msBackgroundShapeModelID()
+{
+}
+
+DiagramData_svx::DiagramData_svx(DiagramData_svx const& rSource)
+: mxRootShape()
+, maExtDrawings()
+, maConnections(rSource.maConnections)
+, maPoints(rSource.maPoints)
+, mxThemeDocument()
+, maPointNameMap()
+, maPointsPresNameMap()
+, maConnectionNameMap()
+, maPresOfNameMap()
+, msBackgroundShapeModelID()
 {
 }
 
@@ -271,7 +301,8 @@ DomMapFlags DiagramData_svx::removeDiagramNode(const 
OUString& rNodeId)
     aRetval.push_back(DomMapFlag::OOXDrawing);
     aRetval.push_back(DomMapFlag::OOXDataImageRels);
     aRetval.push_back(DomMapFlag::OOXDataHlinkRels);
-    aRetval.push_back(DomMapFlag::OOXDrawingRels);
+    aRetval.push_back(DomMapFlag::OOXDrawingImageRels);
+    aRetval.push_back(DomMapFlag::OOXDrawingHlinkRels);
 
     return aRetval;
 }
@@ -468,7 +499,8 @@ std::pair<OUString, DomMapFlags> 
DiagramData_svx::addDiagramNode()
     aRetval.push_back(DomMapFlag::OOXDrawing);
     aRetval.push_back(DomMapFlag::OOXDataImageRels);
     aRetval.push_back(DomMapFlag::OOXDataHlinkRels);
-    aRetval.push_back(DomMapFlag::OOXDrawingRels);
+    aRetval.push_back(DomMapFlag::OOXDrawingImageRels);
+    aRetval.push_back(DomMapFlag::OOXDrawingHlinkRels);
 
     return std::make_pair(sNewNodeId, aRetval);
 }
diff --git a/svx/source/svdraw/svdobj.cxx b/svx/source/svdraw/svdobj.cxx
index b8e0b1fb7212..625af3a3a664 100644
--- a/svx/source/svdraw/svdobj.cxx
+++ b/svx/source/svdraw/svdobj.cxx
@@ -202,6 +202,20 @@ struct SdrObject::Impl
         meRelativeHeightRelation(text::RelOrientation::PAGE_FRAME) {}
 };
 
+void SdrObject::setDiagramDataModelID(const OUString& rID)
+{
+    if (!m_pPlusData)
+        ImpForcePlusData();
+    m_pPlusData->aObjTitle = rID;
+}
+
+const OUString& SdrObject::getDiagramDataModelID() const
+{
+    if(m_pPlusData)
+        return m_pPlusData->aObjTitle;
+    return EMPTY_OUSTRING;
+}
+
 bool SdrObject::isDiagram() const
 {
     return false;
@@ -367,7 +381,6 @@ SdrObject::SdrObject(SdrModel& rSdrModel)
     , mpSvxShape( nullptr )
     , mbDoNotInsertIntoPageAutomatically(false)
     , msHyperlink()
-    , msDiagramDataModelID()
 {
     m_bVirtObj         =false;
     m_bSnapRectDirty   =true;
@@ -405,7 +418,6 @@ SdrObject::SdrObject(SdrModel& rSdrModel, SdrObject const & 
rSource)
     , mpSvxShape( nullptr )
     , mbDoNotInsertIntoPageAutomatically(false)
     , msHyperlink()
-    , msDiagramDataModelID()
 {
     m_bVirtObj         =false;
     m_bSnapRectDirty   =true;
diff --git a/svx/source/svdraw/svdogrp.cxx b/svx/source/svdraw/svdogrp.cxx
index 3f0f85534fb6..47518a5d1d76 100644
--- a/svx/source/svdraw/svdogrp.cxx
+++ b/svx/source/svdraw/svdogrp.cxx
@@ -89,6 +89,16 @@ SdrObjGroup::SdrObjGroup(SdrModel& rSdrModel, SdrObjGroup 
const & rSource)
 
     // copy local parameters
     maRefPoint  = rSource.maRefPoint;
+
+    static bool bActivateAdvancedDiagramFeatures(nullptr != 
std::getenv("ACTIVATE_ADVANCED_DIAGRAM_FEATURES"));
+    if (bActivateAdvancedDiagramFeatures && rSource.getDiagramHelper())
+    {
+        // create complete clone of current DiagramData
+        mp_DiagramHelper.reset(rSource.getDiagramHelper()->clone());
+
+        // need to set new RootShape to newly created associated XShape
+        mp_DiagramHelper->getRootShape() = getUnoShape();
+    }
 }
 
 void SdrObjGroup::AddToHdlList(SdrHdlList& rHdlList) const

Reply via email to