include/oox/drawingml/diagram/diagramhelper_oox.hxx       |    7 -
 include/svx/svdmodel.hxx                                  |    5 
 include/svx/svdogrp.hxx                                   |    3 
 oox/source/drawingml/diagram/diagram.cxx                  |   29 +++--
 oox/source/drawingml/diagram/diagram.hxx                  |    1 
 oox/source/drawingml/diagram/diagramdefinitioncontext.cxx |    8 -
 oox/source/drawingml/diagram/diagramdefinitioncontext.hxx |    3 
 oox/source/drawingml/diagram/diagramfragmenthandler.cxx   |    6 -
 oox/source/drawingml/diagram/diagramfragmenthandler.hxx   |    4 
 oox/source/drawingml/diagram/diagramhelper_oox.cxx        |   24 +++-
 oox/source/drawingml/diagram/diagramlayoutatoms.cxx       |   73 +++++++-------
 oox/source/drawingml/diagram/diagramlayoutatoms.hxx       |   48 ++++++---
 oox/source/drawingml/diagram/layoutatomvisitorbase.cxx    |    4 
 oox/source/drawingml/diagram/layoutatomvisitors.cxx       |    9 -
 oox/source/drawingml/diagram/layoutnodecontext.cxx        |   29 +++--
 oox/source/drawingml/diagram/layoutnodecontext.hxx        |    4 
 oox/source/drawingml/shape.cxx                            |    3 
 sc/source/ui/view/gridwin.cxx                             |   40 +++++++
 sd/source/filter/xml/sdxmlwrp.cxx                         |    7 +
 svx/source/diagram/DiagramHelper_svx.cxx                  |    2 
 svx/source/svdraw/svdmodel.cxx                            |    3 
 svx/source/svdraw/svdogrp.cxx                             |   54 +++++++++-
 svx/source/xml/xmlexport.cxx                              |    5 
 sw/source/uibase/docvw/edtwin.cxx                         |   32 ++++++
 24 files changed, 290 insertions(+), 113 deletions(-)

New commits:
commit 9e7549cd5adcb5d8b042dd60caee90b2df587db7
Author:     Armin Le Grand (collabora) <[email protected]>
AuthorDate: Tue Mar 3 10:39:41 2026 +0100
Commit:     Armin Le Grand <[email protected]>
CommitDate: Tue Mar 3 16:19:27 2026 +0100

    SmartArt: Diverse changes for SmartArt handling
    
    Changed the DiagramImportSize no longer be handled/held
    as part of the DiagramModel part, but with the change to
    use the XShapes/SdrObjects consequently use the
    transformation from there to be consistent.
    
    With that change also added own impls of
    TRGet/SetBaseGeometry to SdrObjGroup. There were none,
    thus the defaults from SdrObject were used. This is
    mainly correct, but since SdrObjGroup is based on
    GetSnapRect() it already contains the evtl. existing
    anchor offset (from SW), so the results were wrong
    for SW.
    
    Secured the knowledge if we are in Im/Export by adding
    methods for is/inc/decImportExport to SdrModel and using
    these. Locking the model was pretty safe, but e.g. missing
    for import. Still added it there to be consistent with
    other imports, may also bring some speedup.
    
    I have cleaned LayoutNode from the member
    'SmartArtDiagram& mrDgm' since LayoutNode is model data
    and with that in place it would have been necessary to
    deep-clone or re-import the complete DiagramLayout,
    just to make sure that those members of SmartArtDiagram&
    will reference the correct - newly created -
    SmartArtDiagram.
    That again would have been hard to keep under control
    due to LayoutNodes hosting a full hierarchy of LayoutNodes
    in it's base class LayoutAtom, so complicated deep-copy
    and need of virtual Clone method at LayoutAtom to do the
    right thing for all eight derivations of it.
    This is now no longer needed. It can just stay shared, thus
    the DiagramLayoutPtr gets just copied above. This reflects
    that the layout mechanism hosted by these atoms is not
    changed itself, but used (in some ForEach manner) to create
    the shapes, so does not need to be changed itself.
    It gets now just additionally referenced by the
    SmartArtDiagram copy costructor. That is for non-deep
    copy/paste where this copy operator is used.
    Instead of deep copy the SmartArtDiagram constructor with
    import from boost::property_tree has to be used which will
    have to re-import the layout model data to mpLayout anyways.
    Instead of having SmartArtDiagram as member it now will be
    handed as needed to import contexts (LayoutNodeContext and
    derivatives).
    All those classes are used temporarily and are not part of
    the model. It also gets handed over for shape re-creation
    in LayoutAtomVisitorBase and it's derivates. Also those
    classes are used temporarily and are not part of the model.
    
    Added detection of click on Diagram frame in SC and SW to
    get the Dialog working as in SW and SD to be able to test#
    some stuff.
    
    All still secured by ACTIVATE_ADVANCED_DIAGRAM_FEATURES
    and wirk in progress, but some stuff is looking better.
    
    Change-Id: I660b205155a4e317585035ec3cacddbc96db08c7
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/200875
    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 d6e31592d20d..9a7004a58fad 100644
--- a/include/oox/drawingml/diagram/diagramhelper_oox.hxx
+++ b/include/oox/drawingml/diagram/diagramhelper_oox.hxx
@@ -45,11 +45,9 @@ class DrawingML;
 // - im/export Diagram model to other representations
 class DiagramHelper_oox final : public svx::diagram::DiagramHelper_svx
 {
-    const std::shared_ptr< SmartArtDiagram >         mpDiagramPtr;
+    const std::shared_ptr< SmartArtDiagram >    mpDiagramPtr;
     std::shared_ptr<::oox::drawingml::Theme>    mpDiagramThemePtr;
 
-    css::awt::Size maDiagramImportSize;
-
     // data values set by addDiagramNode to be used by next reLayout call
     // when a new ode gets added
     OUString msNewNodeId;
@@ -68,8 +66,7 @@ protected:
 public:
     DiagramHelper_oox(
         std::shared_ptr< SmartArtDiagram > xDiagramPtr,
-        std::shared_ptr<::oox::drawingml::Theme> xTheme,
-        css::awt::Size aImportSize);
+        std::shared_ptr<::oox::drawingml::Theme> xTheme);
     explicit DiagramHelper_oox(DiagramHelper_oox const& rSource);
     explicit DiagramHelper_oox(const boost::property_tree::ptree& 
rDiagramModel);
     virtual ~DiagramHelper_oox();
diff --git a/include/svx/svdmodel.hxx b/include/svx/svdmodel.hxx
index c89054d49443..78914382fde0 100644
--- a/include/svx/svdmodel.hxx
+++ b/include/svx/svdmodel.hxx
@@ -151,6 +151,7 @@ class SVXCORE_DLLPUBLIC SdrModel : public SfxBroadcaster, 
public tools::WeakBase
     friend void impAddIncarnatedSdrObjectToSdrModel(SdrObject& rSdrObject, 
SdrModel& rSdrModel);
     friend void impRemoveIncarnatedSdrObjectToSdrModel(SdrObject& rSdrObject, 
SdrModel& rSdrModel);
     std::unordered_set< SdrObject* >  maAllIncarnatedObjects;
+    sal_uInt16 mnImExCnt;
 protected:
     std::vector<rtl::Reference<SdrPage>> maMasterPages;
     std::vector<rtl::Reference<SdrPage>> maPages;
@@ -622,6 +623,10 @@ public:
 
     bool IsVOCInvalidationIsReliable() const { return 
mbVOCInvalidationIsReliable; }
     void SetVOCInvalidationIsReliable(bool b) { mbVOCInvalidationIsReliable = 
b; }
+
+    bool isInImportExport() { return 0 != mnImExCnt; }
+    void incImportExport() { mnImExCnt++; }
+    void decImportExport() { if(mnImExCnt) mnImExCnt--; }
 };
 
 /*
diff --git a/include/svx/svdogrp.hxx b/include/svx/svdogrp.hxx
index 6f1478eeff12..f74c84f71382 100644
--- a/include/svx/svdogrp.hxx
+++ b/include/svx/svdogrp.hxx
@@ -119,6 +119,9 @@ public:
 
     virtual void dumpAsXml(xmlTextWriterPtr pWriter) const override;
     virtual void AddToHdlList(SdrHdlList& rHdlList) const override;
+
+    virtual bool TRGetBaseGeometry(basegfx::B2DHomMatrix& rMatrix, 
basegfx::B2DPolyPolygon& rPolyPolygon) const override;
+    virtual void TRSetBaseGeometry(const basegfx::B2DHomMatrix& rMatrix, const 
basegfx::B2DPolyPolygon& rPolyPolygon) override;
 };
 
 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/oox/source/drawingml/diagram/diagram.cxx 
b/oox/source/drawingml/diagram/diagram.cxx
index b196c61bbd53..05700c83112d 100644
--- a/oox/source/drawingml/diagram/diagram.cxx
+++ b/oox/source/drawingml/diagram/diagram.cxx
@@ -176,6 +176,16 @@ SmartArtDiagram::SmartArtDiagram()
 {
 }
 
+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)
+{
+}
+
 SmartArtDiagram::SmartArtDiagram(const boost::property_tree::ptree& 
rDiagramModel)
 : maDiagramFontHeights()
 , mpData(std::make_shared<DiagramData_oox>(rDiagramModel))
@@ -213,8 +223,15 @@ SmartArtDiagram::SmartArtDiagram(const 
boost::property_tree::ptree& rDiagramMode
 
             // 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));
+            rtl::Reference< core::FragmentHandler > xRefLayout(new 
DiagramLayoutFragmentHandler(*this, *xPPTImport, "internal", mpLayout));
             xPPTImport->importFragment(xRefLayout, xSerializer);
+
+            // Data is loaded, so we already have Points and Connections. Also
+            // need to rebuild buffers for layouting (maPointsPresNameMap,
+            // maConnectionNameMap, maPresOfNameMap). Call with false due to
+            // we are in ODF import and have no oox::Shapes to delete and do
+            // *not* want these to be created (would not hurt, but not needed)
+            // getData()->buildDiagramDataModel(false);
         }
 
         if (!aOOXStyleDOM.isEmpty())
@@ -259,13 +276,7 @@ SmartArtDiagram::SmartArtDiagram(const 
boost::property_tree::ptree& rDiagramMode
     }
 }
 
-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)
+SmartArtDiagram::~SmartArtDiagram()
 {
 }
 
@@ -654,7 +665,7 @@ void loadDiagram( ShapePtr const & pShape,
         if (!rLayoutPath.isEmpty())
         {
             rtl::Reference< core::FragmentHandler > xRefLayout(
-                    new DiagramLayoutFragmentHandler( rFilter, rLayoutPath,
+                    new DiagramLayoutFragmentHandler( *pDiagram, rFilter, 
rLayoutPath,
                                                       std::move(pLayout) ));
 
             importFragment(rFilter,
diff --git a/oox/source/drawingml/diagram/diagram.hxx 
b/oox/source/drawingml/diagram/diagram.hxx
index e4988aa70cc3..327787d9f0b5 100644
--- a/oox/source/drawingml/diagram/diagram.hxx
+++ b/oox/source/drawingml/diagram/diagram.hxx
@@ -131,6 +131,7 @@ public:
     explicit SmartArtDiagram();
     explicit SmartArtDiagram(SmartArtDiagram const& rSource);
     explicit SmartArtDiagram(const boost::property_tree::ptree& rDiagramModel);
+    ~SmartArtDiagram();
     void setData( const OoxDiagramDataPtr& pData )
         { mpData = pData; }
     const OoxDiagramDataPtr& getData() const
diff --git a/oox/source/drawingml/diagram/diagramdefinitioncontext.cxx 
b/oox/source/drawingml/diagram/diagramdefinitioncontext.cxx
index 25644c70d29a..8078d8d3c9a1 100644
--- a/oox/source/drawingml/diagram/diagramdefinitioncontext.cxx
+++ b/oox/source/drawingml/diagram/diagramdefinitioncontext.cxx
@@ -30,11 +30,13 @@ using namespace ::oox::core;
 namespace oox::drawingml {
 
 // CT_DiagramDefinition
-DiagramDefinitionContext::DiagramDefinitionContext( ContextHandler2Helper 
const & rParent,
+DiagramDefinitionContext::DiagramDefinitionContext( SmartArtDiagram& rDgm,
+                                                    ContextHandler2Helper 
const & rParent,
                                                     const AttributeList& 
rAttributes,
                                                     DiagramLayoutPtr pLayout )
     : ContextHandler2( rParent )
     , mpLayout(std::move( pLayout ))
+    , mrDgm(rDgm)
 {
     mpLayout->setDefStyle( rAttributes.getStringDefaulted( XML_defStyle ) );
     OUString sValue = rAttributes.getStringDefaulted( XML_minVer );
@@ -67,12 +69,12 @@ DiagramDefinitionContext::onCreateContext( ::sal_Int32 
aElement,
         break;
     case DGM_TOKEN( layoutNode ):
     {
-        LayoutNodePtr pNode = 
std::make_shared<LayoutNode>(mpLayout->getDiagram());
+        LayoutNodePtr pNode = std::make_shared<LayoutNode>();
         mpLayout->getNode() = pNode;
         pNode->setChildOrder( rAttribs.getToken( XML_chOrder, XML_b ) );
         pNode->setMoveWith( rAttribs.getStringDefaulted( XML_moveWith ) );
         pNode->setStyleLabel( rAttribs.getStringDefaulted( XML_styleLbl ) );
-        return new LayoutNodeContext( *this, rAttribs, pNode );
+        return new LayoutNodeContext(mrDgm, *this, rAttribs, pNode );
     }
      case DGM_TOKEN( clrData ):
         // TODO, does not matter for the UI. skip.
diff --git a/oox/source/drawingml/diagram/diagramdefinitioncontext.hxx 
b/oox/source/drawingml/diagram/diagramdefinitioncontext.hxx
index 022299852706..c206aad769b9 100644
--- a/oox/source/drawingml/diagram/diagramdefinitioncontext.hxx
+++ b/oox/source/drawingml/diagram/diagramdefinitioncontext.hxx
@@ -28,13 +28,14 @@ namespace oox::drawingml {
 class DiagramDefinitionContext : public ::oox::core::ContextHandler2
 {
 public:
-    DiagramDefinitionContext( ::oox::core::ContextHandler2Helper const & 
rParent, const ::oox::AttributeList& rAttributes, DiagramLayoutPtr pLayout );
+    DiagramDefinitionContext( SmartArtDiagram& rDgm, 
::oox::core::ContextHandler2Helper const & rParent, const ::oox::AttributeList& 
rAttributes, DiagramLayoutPtr pLayout );
     virtual ~DiagramDefinitionContext() override;
 
     virtual ::oox::core::ContextHandlerRef onCreateContext( ::sal_Int32 
Element, const ::oox::AttributeList& rAttribs ) override;
 
 private:
     DiagramLayoutPtr mpLayout;
+    SmartArtDiagram& mrDgm;
 };
 
 }
diff --git a/oox/source/drawingml/diagram/diagramfragmenthandler.cxx 
b/oox/source/drawingml/diagram/diagramfragmenthandler.cxx
index 71adf3dce612..0395da6a2cf5 100644
--- a/oox/source/drawingml/diagram/diagramfragmenthandler.cxx
+++ b/oox/source/drawingml/diagram/diagramfragmenthandler.cxx
@@ -63,11 +63,13 @@ DiagramDataFragmentHandler::onCreateContext( ::sal_Int32 
aElement,
     return this;
 }
 
-DiagramLayoutFragmentHandler::DiagramLayoutFragmentHandler( XmlFilterBase& 
rFilter,
+DiagramLayoutFragmentHandler::DiagramLayoutFragmentHandler( SmartArtDiagram& 
rDgm,
+                                                        XmlFilterBase& rFilter,
                                                         const OUString& 
rFragmentPath,
                                                         DiagramLayoutPtr 
xDataPtr )
     : FragmentHandler2( rFilter, rFragmentPath )
     , mpDataPtr(std::move( xDataPtr ))
+    , mrDgm(rDgm)
 {
 }
 
@@ -88,7 +90,7 @@ DiagramLayoutFragmentHandler::onCreateContext( ::sal_Int32 
aElement,
     switch( aElement )
     {
     case DGM_TOKEN( layoutDef ):
-        return new DiagramDefinitionContext( *this, rAttribs, mpDataPtr );
+        return new DiagramDefinitionContext( mrDgm, *this, rAttribs, mpDataPtr 
);
     default:
         break;
     }
diff --git a/oox/source/drawingml/diagram/diagramfragmenthandler.hxx 
b/oox/source/drawingml/diagram/diagramfragmenthandler.hxx
index caecb4886ae6..caa43c9bc634 100644
--- a/oox/source/drawingml/diagram/diagramfragmenthandler.hxx
+++ b/oox/source/drawingml/diagram/diagramfragmenthandler.hxx
@@ -43,15 +43,15 @@ private:
 class DiagramLayoutFragmentHandler : public ::oox::core::FragmentHandler2
 {
 public:
-    DiagramLayoutFragmentHandler(oox::core::XmlFilterBase& rFilter, const 
OUString& rFragmentPath, DiagramLayoutPtr xDataPtr);
+    DiagramLayoutFragmentHandler(SmartArtDiagram& rDgm, 
oox::core::XmlFilterBase& rFilter, const OUString& rFragmentPath, 
DiagramLayoutPtr xDataPtr);
     virtual ~DiagramLayoutFragmentHandler() noexcept override;
 
     virtual void SAL_CALL endDocument() override;
     virtual ::oox::core::ContextHandlerRef onCreateContext( ::sal_Int32 
Element, const ::oox::AttributeList& rAttribs ) override;
 
 private:
-
     DiagramLayoutPtr    mpDataPtr;
+    SmartArtDiagram& mrDgm;
 };
 
 class DiagramQStylesFragmentHandler : public ::oox::core::FragmentHandler2
diff --git a/oox/source/drawingml/diagram/diagramhelper_oox.cxx 
b/oox/source/drawingml/diagram/diagramhelper_oox.cxx
index 5beba10cc781..29294a3313bb 100644
--- a/oox/source/drawingml/diagram/diagramhelper_oox.cxx
+++ b/oox/source/drawingml/diagram/diagramhelper_oox.cxx
@@ -43,11 +43,9 @@ namespace oox::drawingml
 bool DiagramHelper_oox::hasDiagramData() const { return mpDiagramPtr && 
mpDiagramPtr->getData(); }
 
 DiagramHelper_oox::DiagramHelper_oox(std::shared_ptr<SmartArtDiagram> 
xDiagramPtr,
-                                     std::shared_ptr<::oox::drawingml::Theme> 
xTheme,
-                                     awt::Size aImportSize)
+                                     std::shared_ptr<::oox::drawingml::Theme> 
xTheme)
     : mpDiagramPtr(std::move(xDiagramPtr))
     , mpDiagramThemePtr(std::move(xTheme))
-    , maDiagramImportSize(aImportSize)
     , msNewNodeId()
     , msNewNodeText()
 {
@@ -57,7 +55,6 @@ 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()
 {
@@ -67,7 +64,6 @@ DiagramHelper_oox::DiagramHelper_oox(const 
boost::property_tree::ptree& rDiagram
     : DiagramHelper_svx()
     , mpDiagramPtr(new SmartArtDiagram(rDiagramModel))
     , mpDiagramThemePtr()
-    , maDiagramImportSize()
     , msNewNodeId()
     , msNewNodeText()
 {
@@ -115,11 +111,23 @@ void DiagramHelper_oox::reLayout()
     pTarget->TRGetBaseGeometry(aTransformation, aPolyPolygon);
 
     // create temporary oox::Shape as target. No longer needed is to 
keep/remember
-    // the original oox::Shape to do that. Use original Size and Pos from 
initial import
-    // to get the same layout(s)
+    // the original oox::Shape to do that. Use local model data from Diagram 
root
+    // shape to get the same layout(s)
     oox::drawingml::ShapePtr pShapePtr = 
std::make_shared<Shape>("com.sun.star.drawing.GroupShape");
     pShapePtr->setDiagramType();
-    pShapePtr->setSize(maDiagramImportSize);
+
+    // set the Size, this is important to let the layout mechanism work
+    // correctly. Since we use the XShape/SdrObject hierarchy as part of
+    // the model data, get size from there.
+    // Create bounding range using unit coordinates and the object
+    // transformation
+    const basegfx::B2DRange aRootRange(aTransformation * basegfx::B2DPoint(0, 
0), // top-left
+                                       aTransformation * basegfx::B2DPoint(1, 
1)); // bottom-right
+
+    // also need to convert to Emu used by mso and thus in oox::Shape stuff
+    pShapePtr->setSize(
+        
awt::Size(oox::drawingml::convertHmmToEmu(basegfx::fround(aRootRange.getWidth())),
+                  
oox::drawingml::convertHmmToEmu(basegfx::fround(aRootRange.getHeight()))));
 
     // remember existing DrawingLayerModelData. Do this before 
createShapeHierarchyFromModel
     // below, that will create a new BackgroundShapeModelID and the BGShape 
would
diff --git a/oox/source/drawingml/diagram/diagramlayoutatoms.cxx 
b/oox/source/drawingml/diagram/diagramlayoutatoms.cxx
index 1e1a17c14299..ca999d8e440e 100644
--- a/oox/source/drawingml/diagram/diagramlayoutatoms.cxx
+++ b/oox/source/drawingml/diagram/diagramlayoutatoms.cxx
@@ -547,7 +547,7 @@ void CompositeAlg::applyConstraintToLayout(const 
Constraint& rConstraint,
     }
 }
 
-void CompositeAlg::layoutShapeChildren(AlgAtom& rAlg, const ShapePtr& rShape,
+void CompositeAlg::layoutShapeChildren(const SmartArtDiagram& rDgm, AlgAtom& 
rAlg, const ShapePtr& rShape,
                                        const std::vector<Constraint>& 
rConstraints)
 {
     LayoutPropertyMap aProperties;
@@ -701,7 +701,7 @@ void CompositeAlg::layoutShapeChildren(AlgAtom& rAlg, const 
ShapePtr& rShape,
         nVertMax = std::max(aPos.Y + aSize.Height, nVertMax);
 
         NamedShapePairs& rDiagramFontHeights
-            = rAlg.getLayoutNode().getDiagram().getDiagramFontHeights();
+            = const_cast<SmartArtDiagram&>(rDgm).getDiagramFontHeights();
         auto it = rDiagramFontHeights.find(aCurrShape->getInternalName());
         if (it != rDiagramFontHeights.end())
         {
@@ -785,11 +785,11 @@ void ForEachAtom::accept( LayoutAtomVisitor& rVisitor )
     rVisitor.visit(*this);
 }
 
-LayoutAtomPtr ForEachAtom::getRefAtom()
+LayoutAtomPtr ForEachAtom::getRefAtom(const SmartArtDiagram& rDgm)
 {
     if (!msRef.isEmpty())
     {
-        const LayoutAtomMap& rLayoutAtomMap = 
getLayoutNode().getDiagram().getLayout()->getLayoutAtomMap();
+        const LayoutAtomMap& rLayoutAtomMap = 
rDgm.getLayout()->getLayoutAtomMap();
         LayoutAtomMap::const_iterator pRefAtom = rLayoutAtomMap.find(msRef);
         if (pRefAtom != rLayoutAtomMap.end())
             return pRefAtom->second;
@@ -834,10 +834,10 @@ namespace
  * Takes the connection list from rLayoutNode, navigates from rFrom on an edge
  * of type nType, using a direction determined by bSourceToDestination.
  */
-OUString navigate(LayoutNode& rLayoutNode, svx::diagram::TypeConstant nType, 
std::u16string_view rFrom,
+OUString navigate(const SmartArtDiagram& rDgm, svx::diagram::TypeConstant 
nType, std::u16string_view rFrom,
                   bool bSourceToDestination)
 {
-    for (const auto& rConnection : 
rLayoutNode.getDiagram().getData()->getConnections())
+    for (const auto& rConnection : rDgm.getData()->getConnections())
     {
         if (rConnection.mnXMLType != nType)
             continue;
@@ -868,18 +868,18 @@ sal_Int32 calcMaxDepth(std::u16string_view rNodeName, 
const svx::diagram::Connec
 }
 }
 
-sal_Int32 ConditionAtom::getNodeCount(const svx::diagram::Point* pPresPoint) 
const
+sal_Int32 ConditionAtom::getNodeCount(const SmartArtDiagram& rDgm, const 
svx::diagram::Point* pPresPoint) const
 {
     sal_Int32 nCount = 0;
     OUString sNodeId = pPresPoint->msPresentationAssociationId;
 
     // HACK: special case - count children of first child
     if (maIter.maAxis.size() == 2 && maIter.maAxis[0] == XML_ch && 
maIter.maAxis[1] == XML_ch)
-        sNodeId = navigate(mrLayoutNode, 
svx::diagram::TypeConstant::XML_parOf, sNodeId, /*bSourceToDestination*/ true);
+        sNodeId = navigate(rDgm, svx::diagram::TypeConstant::XML_parOf, 
sNodeId, /*bSourceToDestination*/ true);
 
     if (!sNodeId.isEmpty())
     {
-        for (const auto& aCxn : 
mrLayoutNode.getDiagram().getData()->getConnections())
+        for (const auto& aCxn : rDgm.getData()->getConnections())
             if (aCxn.mnXMLType == svx::diagram::TypeConstant::XML_parOf && 
aCxn.msSourceId == sNodeId)
                 nCount++;
     }
@@ -887,7 +887,7 @@ sal_Int32 ConditionAtom::getNodeCount(const 
svx::diagram::Point* pPresPoint) con
     return nCount;
 }
 
-bool ConditionAtom::getDecision(const svx::diagram::Point* pPresPoint) const
+bool ConditionAtom::getDecision(const SmartArtDiagram& rDgm, const 
svx::diagram::Point* pPresPoint) const
 {
     if (mIsElse)
         return true;
@@ -907,9 +907,9 @@ bool ConditionAtom::getDecision(const svx::diagram::Point* 
pPresPoint) const
             {
                 // If <dgm:hierBranch> is missing in the current presentation
                 // point, ask the parent.
-                OUString aParent = navigate(mrLayoutNode, 
svx::diagram::TypeConstant::XML_presParOf, pPresPoint->msModelId,
+                OUString aParent = navigate(rDgm, 
svx::diagram::TypeConstant::XML_presParOf, pPresPoint->msModelId,
                                             /*bSourceToDestination*/ false);
-                const svx::diagram::Point* 
it(mrLayoutNode.getDiagram().getData()->getPointByModelID(aParent));
+                const svx::diagram::Point* 
it(rDgm.getData()->getPointByModelID(aParent));
                 if (nullptr != it)
                 {
                     const svx::diagram::Point* pParent = it;
@@ -923,11 +923,11 @@ bool ConditionAtom::getDecision(const 
svx::diagram::Point* pPresPoint) const
     }
 
     case XML_cnt:
-        return compareResult(maCond.mnOp, getNodeCount(pPresPoint), 
maCond.msVal.toInt32());
+        return compareResult(maCond.mnOp, getNodeCount(rDgm, pPresPoint), 
maCond.msVal.toInt32());
 
     case XML_maxDepth:
     {
-        sal_Int32 nMaxDepth = 
calcMaxDepth(pPresPoint->msPresentationAssociationId, 
mrLayoutNode.getDiagram().getData()->getConnections());
+        sal_Int32 nMaxDepth = 
calcMaxDepth(pPresPoint->msPresentationAssociationId, 
rDgm.getData()->getConnections());
         return compareResult(maCond.mnOp, nMaxDepth, maCond.msVal.toInt32());
     }
 
@@ -1069,12 +1069,10 @@ sal_Int32 AlgAtom::getVerticalShapesCount(const 
ShapePtr& rShape)
 namespace
 {
 /// Does the first data node of this shape have customized text properties?
-bool HasCustomText(const ShapePtr& rShape, LayoutNode& rLayoutNode)
+bool HasCustomText(const SmartArtDiagram& rDgm, const ShapePtr& rShape)
 {
-    const PresPointShapeMap& rPresPointShapeMap
-        = rLayoutNode.getDiagram().getLayout()->getPresPointShapeMap();
-    const DiagramData_oox::StringMap& rPresOfNameMap
-        = rLayoutNode.getDiagram().getData()->getPresOfNameMap();
+    const PresPointShapeMap& rPresPointShapeMap = 
rDgm.getLayout()->getPresPointShapeMap();
+    const DiagramData_oox::StringMap& rPresOfNameMap = 
rDgm.getData()->getPresOfNameMap();
     // Get the first presentation node of the shape.
     const svx::diagram::Point* pPresNode = nullptr;
     for (const auto& rPair : rPresPointShapeMap)
@@ -1095,7 +1093,7 @@ bool HasCustomText(const ShapePtr& rShape, LayoutNode& 
rLayoutNode)
             for (const auto& rPair : itPresToData->second)
             {
                 const DiagramData_oox::SourceIdAndDepth& rItem = rPair.second;
-                const svx::diagram::Point* 
it(rLayoutNode.getDiagram().getData()->getPointByModelID(rItem.msSourceId));
+                const svx::diagram::Point* 
it(rDgm.getData()->getPointByModelID(rItem.msSourceId));
                 if (nullptr != it)
                 {
                     pDataNode = it;
@@ -1115,7 +1113,7 @@ bool HasCustomText(const ShapePtr& rShape, LayoutNode& 
rLayoutNode)
 }
 }
 
-void AlgAtom::layoutShape(const ShapePtr& rShape, const 
std::vector<Constraint>& rConstraints,
+void AlgAtom::layoutShape(const SmartArtDiagram& rDgm, const ShapePtr& rShape, 
const std::vector<Constraint>& rConstraints,
                           const std::vector<Rule>& rRules)
 {
     if (mnType != XML_lin)
@@ -1133,7 +1131,7 @@ void AlgAtom::layoutShape(const ShapePtr& rShape, const 
std::vector<Constraint>&
     {
         case XML_composite:
         {
-            CompositeAlg::layoutShapeChildren(*this, rShape, rConstraints);
+            CompositeAlg::layoutShapeChildren(rDgm, *this, rShape, 
rConstraints);
             break;
         }
 
@@ -1415,8 +1413,7 @@ void AlgAtom::layoutShape(const ShapePtr& rShape, const 
std::vector<Constraint>&
                 if (rConstraint.mnType == XML_primFontSz && rConstraint.mnFor 
== XML_des
                     && rConstraint.mnOperator == XML_equ)
                 {
-                    NamedShapePairs& rDiagramFontHeights
-                        = getLayoutNode().getDiagram().getDiagramFontHeights();
+                    NamedShapePairs& rDiagramFontHeights = 
const_cast<SmartArtDiagram&>(rDgm).getDiagramFontHeights();
                     auto it = rDiagramFontHeights.find(rConstraint.msForName);
                     if (it == rDiagramFontHeights.end())
                     {
@@ -1723,7 +1720,7 @@ void AlgAtom::layoutShape(const ShapePtr& rShape, const 
std::vector<Constraint>&
                             aRun->getTextCharacterProperties().moHeight = 
fFontSize * 100;
             }
 
-            if (!HasCustomText(rShape, getLayoutNode()))
+            if (!HasCustomText(rDgm, rShape))
             {
                 // No customized text properties: enable autofit.
                 pTextBody->getTextProperties().maPropertyMap.setProperty(
@@ -1855,12 +1852,18 @@ void AlgAtom::layoutShape(const ShapePtr& rShape, const 
std::vector<Constraint>&
         << rShape->getSize().Width << "," << rShape->getSize().Height << ")");
 }
 
+LayoutNode::LayoutNode()
+    : LayoutAtom(*this)
+    , mnChildOrder(0)
+{
+}
+
 void LayoutNode::accept( LayoutAtomVisitor& rVisitor )
 {
     rVisitor.visit(*this);
 }
 
-bool LayoutNode::setupShape( const ShapePtr& rShape, const 
svx::diagram::Point* pPresNode, sal_Int32 nCurrIdx ) const
+bool LayoutNode::setupShape( const SmartArtDiagram& rDgm, const ShapePtr& 
rShape, const svx::diagram::Point* pPresNode, sal_Int32 nCurrIdx ) const
 {
     SAL_INFO(
         "oox.drawingml",
@@ -1868,9 +1871,9 @@ bool LayoutNode::setupShape( const ShapePtr& rShape, 
const svx::diagram::Point*
             << "\", modelId \"" << pPresNode->msModelId << "\"");
 
     // have the presentation node - now, need the actual data node:
-    const DiagramData_oox::StringMap::const_iterator aNodeName = 
mrDgm.getData()->getPresOfNameMap().find(
+    const DiagramData_oox::StringMap::const_iterator aNodeName = 
rDgm.getData()->getPresOfNameMap().find(
         pPresNode->msModelId);
-    if( aNodeName != mrDgm.getData()->getPresOfNameMap().end() )
+    if( aNodeName != rDgm.getData()->getPresOfNameMap().end() )
     {
         // Calculate the depth of what is effectively the topmost element.
         sal_Int32 nMinDepth = std::numeric_limits<sal_Int32>::max();
@@ -1884,14 +1887,14 @@ bool LayoutNode::setupShape( const ShapePtr& rShape, 
const svx::diagram::Point*
         {
             const DiagramData_oox::SourceIdAndDepth& rItem = rPair.second;
             // pPresNode is the presentation node of the aDataNode2 data node.
-            const svx::diagram::Point* 
pDataNode2(mrDgm.getData()->getPointByModelID(rItem.msSourceId));
+            const svx::diagram::Point* 
pDataNode2(rDgm.getData()->getPointByModelID(rItem.msSourceId));
             if (nullptr == pDataNode2)
             {
                 //busted, skip it
                 continue;
             }
 
-            Shape* 
pDataNode2Shape(mrDgm.getData()->getOrCreateAssociatedShape(*pDataNode2));
+            Shape* 
pDataNode2Shape(rDgm.getData()->getOrCreateAssociatedShape(*pDataNode2));
             if (nullptr == pDataNode2Shape)
             {
                 //busted, skip it
@@ -1968,7 +1971,7 @@ bool LayoutNode::setupShape( const ShapePtr& rShape, 
const svx::diagram::Point*
                 " processing shape type "
                 << rShape->getCustomShapeProperties()->getShapePresetType()
                 << " for layout node named \"" << msName << "\"");
-        Shape* 
pPresNodeShape(mrDgm.getData()->getOrCreateAssociatedShape(*pPresNode));
+        Shape* 
pPresNodeShape(rDgm.getData()->getOrCreateAssociatedShape(*pPresNode));
         if (nullptr != pPresNodeShape)
             
rShape->getFillProperties().assignUsed(pPresNodeShape->getFillProperties());
     }
@@ -1982,8 +1985,8 @@ bool LayoutNode::setupShape( const ShapePtr& rShape, 
const svx::diagram::Point*
         aStyleLabel = msStyleLabel;
     if( !aStyleLabel.isEmpty() )
     {
-        const DiagramQStyleMap::const_iterator aStyle = 
mrDgm.getStyles().find(aStyleLabel);
-        if( aStyle != mrDgm.getStyles().end() )
+        const DiagramQStyleMap::const_iterator aStyle = 
rDgm.getStyles().find(aStyleLabel);
+        if( aStyle != rDgm.getStyles().end() )
         {
             const DiagramStyle& rStyle = aStyle->second;
             rShape->getShapeStyleRefs()[XML_fillRef] = rStyle.maFillStyle;
@@ -1996,8 +1999,8 @@ bool LayoutNode::setupShape( const ShapePtr& rShape, 
const svx::diagram::Point*
             SAL_WARN("oox.drawingml", "Style " << aStyleLabel << " not found");
         }
 
-        const DiagramColorMap::const_iterator aColor = 
mrDgm.getColors().find(aStyleLabel);
-        if( aColor != mrDgm.getColors().end() )
+        const DiagramColorMap::const_iterator aColor = 
rDgm.getColors().find(aStyleLabel);
+        if( aColor != rDgm.getColors().end() )
         {
             // Take the nth color from the color list in case we are the nth 
shape in a
             // <dgm:forEach> loop.
diff --git a/oox/source/drawingml/diagram/diagramlayoutatoms.hxx 
b/oox/source/drawingml/diagram/diagramlayoutatoms.hxx
index da20dff4cf98..d4586586a828 100644
--- a/oox/source/drawingml/diagram/diagramlayoutatoms.hxx
+++ b/oox/source/drawingml/diagram/diagramlayoutatoms.hxx
@@ -182,7 +182,7 @@ public:
     void addParam( sal_Int32 nType, sal_Int32 nVal )
         { maMap[nType]=nVal; }
     sal_Int32 getVerticalShapesCount(const ShapePtr& rShape);
-    void layoutShape( const ShapePtr& rShape,
+    void layoutShape( const SmartArtDiagram& rDgm, const ShapePtr& rShape,
                       const std::vector<Constraint>& rConstraints,
                       const std::vector<Rule>& rRules );
 
@@ -226,7 +226,7 @@ public:
 class CompositeAlg
 {
 public:
-    static void layoutShapeChildren(AlgAtom& rAlg, const ShapePtr& rShape,
+    static void layoutShapeChildren(const SmartArtDiagram& rDgm, AlgAtom& 
rAlg, const ShapePtr& rShape,
                                     const std::vector<Constraint>& 
rConstraints);
 
 private:
@@ -261,7 +261,7 @@ public:
     const OUString& getRef() const
         { return msRef; }
     virtual void accept( LayoutAtomVisitor& ) override;
-    LayoutAtomPtr getRefAtom();
+    LayoutAtomPtr getRefAtom(const SmartArtDiagram& rDgm);
 
 private:
     IteratorAttr maIter;
@@ -276,11 +276,11 @@ class ConditionAtom
 public:
     explicit ConditionAtom(LayoutNode& rLayoutNode, bool isElse, const 
css::uno::Reference< css::xml::sax::XFastAttributeList >& xAttributes);
     virtual void accept( LayoutAtomVisitor& ) override;
-    bool getDecision(const svx::diagram::Point* pPresPoint) const;
+    bool getDecision(const SmartArtDiagram& rDgm, const svx::diagram::Point* 
pPresPoint) const;
 
 private:
     static bool compareResult(sal_Int32 nOperator, sal_Int32 nFirst, sal_Int32 
nSecond);
-    sal_Int32 getNodeCount(const svx::diagram::Point* pPresPoint) const;
+    sal_Int32 getNodeCount(const SmartArtDiagram& rDgm, const 
svx::diagram::Point* pPresPoint) const;
 
     bool          mIsElse;
     IteratorAttr  maIter;
@@ -300,19 +300,40 @@ public:
     virtual void accept( LayoutAtomVisitor& ) override;
 };
 
+// I have cleaned LayoutNode from the member 'SmartArtDiagram& mrDgm'
+// since LayoutNode is model data and with that in place it would have
+// been necessary to deep-clone or re-import the complete DiagramLayout,
+// just to make sure that those members of SmartArtDiagram& will
+// reference the correct - newly created - SmartArtDiagram.
+// That again would have been hard to keep under control due to
+// LayoutNodes hosting a full hierarchy of LayoutNodes in it's base
+// class LayoutAtom, so complicated deep-copy and need of virtual Clone
+// method at LayoutAtom to do the right thing for all eight derivations
+// of it.
+// This is now no longer needed. It can just stay shared, thus the
+// DiagramLayoutPtr gets just copied above. This reflects that the
+// layout mechanism hosted by these atoms is not changed itself, but
+// used (in some ForEach manner) to create the shapes, so does not
+// need to be changed itself.
+// It gets now just additionally referenced by the SmartArtDiagram copy
+// costructor. That is for non-deep copy/paste where this copy operator
+// is used.
+// For deep copy the SmartArtDiagram constructor with import from
+// boost::property_tree has to be used which will have to re-import
+// the layout model data to mpLayout anyways.
+// Instead of having SmartArtDiagram as member it now will be handed
+// as needed to import contexts (LayoutNodeContext and derivatives).
+// All those classes are used temporarily and are not part of the model.
+// It also gets handed over for shape re-creation in LayoutAtomVisitorBase
+// and it's derivates. Also those classes are used temporarily and are
+// not part of the model.
 class LayoutNode
     : public LayoutAtom
 {
 public:
     typedef std::map<sal_Int32, OUString> VarMap;
 
-    LayoutNode(SmartArtDiagram& rDgm)
-        : LayoutAtom(*this)
-        , mrDgm(rDgm)
-        , mnChildOrder(0)
-    {
-    }
-    SmartArtDiagram& getDiagram() { return mrDgm; }
+    LayoutNode();
     virtual void accept( LayoutAtomVisitor& ) override;
     VarMap & variables()
         { return mVariables; }
@@ -332,14 +353,13 @@ public:
     void addNodeShape(const ShapePtr& pShape)
         { mpNodeShapes.push_back(pShape); }
 
-    bool setupShape( const ShapePtr& rShape,
+    bool setupShape( const SmartArtDiagram& rDgm, const ShapePtr& rShape,
                      const svx::diagram::Point* pPresNode,
                      sal_Int32 nCurrIdx ) const;
 
     const LayoutNode* getParentLayoutNode() const;
 
 private:
-    SmartArtDiagram& mrDgm;
     VarMap                       mVariables;
     OUString                     msMoveWith;
     OUString                     msStyleLabel;
diff --git a/oox/source/drawingml/diagram/layoutatomvisitorbase.cxx 
b/oox/source/drawingml/diagram/layoutatomvisitorbase.cxx
index ead3836379ea..cc76b8a2a06d 100644
--- a/oox/source/drawingml/diagram/layoutatomvisitorbase.cxx
+++ b/oox/source/drawingml/diagram/layoutatomvisitorbase.cxx
@@ -36,7 +36,7 @@ void LayoutAtomVisitorBase::visit(ChooseAtom& rAtom)
     for (const auto& pChild : rAtom.getChildren())
     {
         const ConditionAtomPtr pCond = 
std::dynamic_pointer_cast<ConditionAtom>(pChild);
-        if (pCond && pCond->getDecision(mpCurrentNode))
+        if (pCond && pCond->getDecision(mrDgm, mpCurrentNode))
         {
             SAL_INFO("oox.drawingml", "Entering if node: " << 
pCond->getName());
             pCond->accept(*this);
@@ -54,7 +54,7 @@ void LayoutAtomVisitorBase::visit(ForEachAtom& rAtom)
 {
     if (!rAtom.getRef().isEmpty())
     {
-        if (LayoutAtomPtr pRefAtom = rAtom.getRefAtom())
+        if (LayoutAtomPtr pRefAtom = rAtom.getRefAtom(mrDgm))
             pRefAtom->accept(*this);
         return;
     }
diff --git a/oox/source/drawingml/diagram/layoutatomvisitors.cxx 
b/oox/source/drawingml/diagram/layoutatomvisitors.cxx
index 3fb520fca75b..43bf520ac951 100644
--- a/oox/source/drawingml/diagram/layoutatomvisitors.cxx
+++ b/oox/source/drawingml/diagram/layoutatomvisitors.cxx
@@ -79,7 +79,7 @@ void ShapeCreationVisitor::visit(LayoutNode& rAtom)
     {
         // reuse existing shape
         ShapePtr pShape = rAtom.getExistingShape();
-        if (rAtom.setupShape(pShape, pNewNode, mnCurrIdx))
+        if (rAtom.setupShape(mrDgm, pShape, pNewNode, mnCurrIdx))
         {
             pShape->setInternalName(rAtom.getName());
             rAtom.addNodeShape(pShape);
@@ -98,7 +98,7 @@ void ShapeCreationVisitor::visit(LayoutNode& rAtom)
                      "processing shape type "
                          << 
(pShape->getCustomShapeProperties()->getShapePresetType()));
 
-            if (rAtom.setupShape(pShape, pNewNode, mnCurrIdx))
+            if (rAtom.setupShape(mrDgm, pShape, pNewNode, mnCurrIdx))
             {
                 pShape->setInternalName(rAtom.getName());
                 xCurrParent->addChild(pShape);
@@ -203,11 +203,10 @@ void ShapeLayoutingVisitor::visit(AlgAtom& rAtom)
 {
     if (meLookFor == ALGORITHM)
     {
-        const PresPointShapeMap aMap
-            = 
rAtom.getLayoutNode().getDiagram().getLayout()->getPresPointShapeMap();
+        const PresPointShapeMap aMap = 
mrDgm.getLayout()->getPresPointShapeMap();
         auto pShape = aMap.find(mpCurrentNode);
         if (pShape != aMap.end())
-            rAtom.layoutShape(pShape->second, maConstraints, maRules);
+            rAtom.layoutShape(mrDgm, pShape->second, maConstraints, maRules);
     }
 }
 
diff --git a/oox/source/drawingml/diagram/layoutnodecontext.cxx 
b/oox/source/drawingml/diagram/layoutnodecontext.cxx
index d82dc881b844..fa3138190e5b 100644
--- a/oox/source/drawingml/diagram/layoutnodecontext.cxx
+++ b/oox/source/drawingml/diagram/layoutnodecontext.cxx
@@ -40,10 +40,10 @@ class IfContext
     : public LayoutNodeContext
 {
 public:
-    IfContext( ContextHandler2Helper const & rParent,
+    IfContext( SmartArtDiagram& rDgm, ContextHandler2Helper const & rParent,
                const AttributeList& rAttribs,
                const ConditionAtomPtr& pAtom )
-        : LayoutNodeContext( rParent, rAttribs, pAtom )
+        : LayoutNodeContext( rDgm, rParent, rAttribs, pAtom )
     {}
 };
 
@@ -98,9 +98,10 @@ class ChooseContext
     : public ContextHandler2
 {
 public:
-    ChooseContext( ContextHandler2Helper const & rParent, const AttributeList& 
rAttribs, LayoutAtomPtr pNode )
+    ChooseContext( SmartArtDiagram& rDgm, ContextHandler2Helper const & 
rParent, const AttributeList& rAttribs, LayoutAtomPtr pNode )
         : ContextHandler2( rParent )
         , mpNode(std::move( pNode ))
+        , mrDgm(rDgm)
         {
             msName = rAttribs.getStringDefaulted( XML_name );
         }
@@ -116,14 +117,14 @@ public:
                 // CT_When
                 ConditionAtomPtr pNode = 
std::make_shared<ConditionAtom>(mpNode->getLayoutNode(), false, 
rAttribs.getFastAttributeList());
                 LayoutAtom::connect(mpNode, pNode);
-                return new IfContext( *this, rAttribs, pNode );
+                return new IfContext( mrDgm, *this, rAttribs, pNode );
             }
             case DGM_TOKEN( else ):
             {
                 // CT_Otherwise
                 ConditionAtomPtr pNode = 
std::make_shared<ConditionAtom>(mpNode->getLayoutNode(), true, 
rAttribs.getFastAttributeList());
                 LayoutAtom::connect(mpNode, pNode);
-                return new IfContext( *this, rAttribs, pNode );
+                return new IfContext( mrDgm, *this, rAttribs, pNode );
             }
             default:
                 break;
@@ -134,19 +135,20 @@ public:
 private:
     OUString msName;
     LayoutAtomPtr mpNode;
+    SmartArtDiagram& mrDgm;
 };
 
 class ForEachContext
     : public LayoutNodeContext
 {
 public:
-    ForEachContext( ContextHandler2Helper const & rParent, const 
AttributeList& rAttribs, const ForEachAtomPtr& pAtom )
-        : LayoutNodeContext( rParent, rAttribs, pAtom )
+    ForEachContext( SmartArtDiagram& rDgm, ContextHandler2Helper const & 
rParent, const AttributeList& rAttribs, const ForEachAtomPtr& pAtom )
+        : LayoutNodeContext( rDgm, rParent, rAttribs, pAtom )
         {
             pAtom->setRef(rAttribs.getStringDefaulted(XML_ref));
             pAtom->iterator().loadFromXAttr( rAttribs.getFastAttributeList() );
 
-            LayoutAtomMap& rLayoutAtomMap = 
pAtom->getLayoutNode().getDiagram().getLayout()->getLayoutAtomMap();
+            LayoutAtomMap& rLayoutAtomMap = 
getDiagram().getLayout()->getLayoutAtomMap();
             rLayoutAtomMap[pAtom->getName()] = pAtom;
         }
 };
@@ -174,11 +176,12 @@ private:
 }
 
 // CT_LayoutNode
-LayoutNodeContext::LayoutNodeContext( ContextHandler2Helper const & rParent,
+LayoutNodeContext::LayoutNodeContext( SmartArtDiagram& rDgm, 
ContextHandler2Helper const & rParent,
                                       const AttributeList& rAttribs,
                                       const LayoutAtomPtr& pAtom )
     : ContextHandler2( rParent )
     , mpNode( pAtom )
+    , mrDgm(rDgm)
 {
     assert( pAtom && "Node must NOT be NULL" );
     mpNode->setName( rAttribs.getStringDefaulted( XML_name ) );
@@ -196,7 +199,7 @@ LayoutNodeContext::onCreateContext( ::sal_Int32 aElement,
     {
     case DGM_TOKEN( layoutNode ):
     {
-        LayoutNodePtr pNode = 
std::make_shared<LayoutNode>(mpNode->getLayoutNode().getDiagram());
+        LayoutNodePtr pNode = std::make_shared<LayoutNode>();
         LayoutAtom::connect(mpNode, pNode);
 
         if (rAttribs.hasAttribute(XML_chOrder))
@@ -218,7 +221,7 @@ LayoutNodeContext::onCreateContext( ::sal_Int32 aElement,
 
         pNode->setMoveWith( rAttribs.getStringDefaulted( XML_moveWith ) );
         pNode->setStyleLabel( rAttribs.getStringDefaulted( XML_styleLbl ) );
-        return new LayoutNodeContext( *this, rAttribs, pNode );
+        return new LayoutNodeContext( getDiagram(), *this, rAttribs, pNode );
     }
     case DGM_TOKEN( shape ):
     {
@@ -261,14 +264,14 @@ LayoutNodeContext::onCreateContext( ::sal_Int32 aElement,
         // CT_Choose
         LayoutAtomPtr pAtom = 
std::make_shared<ChooseAtom>(mpNode->getLayoutNode());
         LayoutAtom::connect(mpNode, pAtom);
-        return new ChooseContext( *this, rAttribs, std::move(pAtom) );
+        return new ChooseContext( getDiagram(), *this, rAttribs, 
std::move(pAtom) );
     }
     case DGM_TOKEN( forEach ):
     {
         // CT_ForEach
         ForEachAtomPtr pAtom = 
std::make_shared<ForEachAtom>(mpNode->getLayoutNode(), 
rAttribs.getFastAttributeList());
         LayoutAtom::connect(mpNode, pAtom);
-        return new ForEachContext( *this, rAttribs, pAtom );
+        return new ForEachContext( getDiagram(), *this, rAttribs, pAtom );
     }
     case DGM_TOKEN( constrLst ):
         // CT_Constraints
diff --git a/oox/source/drawingml/diagram/layoutnodecontext.hxx 
b/oox/source/drawingml/diagram/layoutnodecontext.hxx
index 3499f5704579..4b4bcff7e783 100644
--- a/oox/source/drawingml/diagram/layoutnodecontext.hxx
+++ b/oox/source/drawingml/diagram/layoutnodecontext.hxx
@@ -28,12 +28,14 @@ namespace oox::drawingml {
 class LayoutNodeContext : public ::oox::core::ContextHandler2
 {
 public:
-    LayoutNodeContext( ::oox::core::ContextHandler2Helper const & rParent, 
const ::oox::AttributeList& rAttributes, const LayoutAtomPtr &pNode );
+    LayoutNodeContext( SmartArtDiagram& rDgm, 
::oox::core::ContextHandler2Helper const & rParent, const ::oox::AttributeList& 
rAttributes, const LayoutAtomPtr &pNode );
     virtual ~LayoutNodeContext() override;
 
     virtual ::oox::core::ContextHandlerRef onCreateContext( ::sal_Int32 
Element, const ::oox::AttributeList& rAttribs ) override;
+    SmartArtDiagram& getDiagram() { return mrDgm; }
 private:
     LayoutAtomPtr mpNode;
+    SmartArtDiagram& mrDgm;
 };
 
 }
diff --git a/oox/source/drawingml/shape.cxx b/oox/source/drawingml/shape.cxx
index e34237c24eda..8298cbcca9c4 100644
--- a/oox/source/drawingml/shape.cxx
+++ b/oox/source/drawingml/shape.cxx
@@ -262,8 +262,7 @@ void Shape::prepareDiagramHelper(
     {
         mpDiagramHelper = new DiagramHelper_oox(
             rDiagramPtr,
-            rTheme,
-            getSize());
+            rTheme);
     }
 }
 
diff --git a/sc/source/ui/view/gridwin.cxx b/sc/source/ui/view/gridwin.cxx
index 34812da9b835..eac8888919d9 100644
--- a/sc/source/ui/view/gridwin.cxx
+++ b/sc/source/ui/view/gridwin.cxx
@@ -144,6 +144,7 @@
 #include <vcl/uitest/logger.hxx>
 #include <vcl/uitest/eventdescription.hxx>
 #include <svx/sdr/overlay/overlayselection.hxx>
+#include <svx/diagram/DiagramHelper_svx.hxx>
 #include <comphelper/lok.hxx>
 #include <sfx2/lokhelper.hxx>
 
@@ -2302,7 +2303,8 @@ void ScGridWindow::MouseButtonUp( const MouseEvent& rMEvt 
)
         return;
 
     SfxBindings& rBindings = mrViewData.GetBindings();
-    if (bEEMouse && mrViewData.HasEditView( eWhich ))
+    const bool bHasEditView(mrViewData.HasEditView( eWhich ));
+    if (bEEMouse && bHasEditView)
     {
         EditView*   pEditView;
         SCCOL       nEditCol;
@@ -2343,6 +2345,42 @@ void ScGridWindow::MouseButtonUp( const MouseEvent& 
rMEvt )
         return;
     }
 
+    if (!bHasEditView)
+    {
+        SdrView* pSdrView(mrViewData.GetView()->GetScDrawView());
+        if (nullptr != pSdrView)
+        {
+            const Point aDocPos(PixelToLogic(aCurMousePos));
+            SdrHdl* pHdl(pSdrView->PickHandle(aDocPos));
+
+            if (nullptr != pHdl)
+            {
+                SdrObject* pSingleObj(nullptr);
+                const SdrMarkList& rMarkList(pSdrView->GetMarkedObjectList());
+
+                if (1 == rMarkList.GetMarkCount())
+                    pSingleObj = rMarkList.GetMark(0)->GetMarkedSdrObj();
+
+                if (nullptr != pSingleObj)
+                {
+                    // Check for click on svx::diagram::DiagramFrameHdl
+                    // - if we hit a SdrHdl
+                    // - if single object is selected
+                    //   - and it is a Diagram
+                    if(pHdl && nullptr != pSingleObj && 
pSingleObj->isDiagram())
+                    {
+                        svx::diagram::DiagramFrameHdl* 
pDiagramFrameHdl(dynamic_cast<svx::diagram::DiagramFrameHdl*>(pHdl));
+                        if(nullptr != pDiagramFrameHdl)
+                        {
+                            // let the DiagramFrameHdl decide what to do
+                            svx::diagram::DiagramFrameHdl::clicked(aDocPos);
+                        }
+                    }
+                }
+            }
+        }
+    }
+
     if (bDPMouse)
     {
         DPMouseButtonUp( rMEvt );       // resets bDPMouse
diff --git a/sd/source/filter/xml/sdxmlwrp.cxx 
b/sd/source/filter/xml/sdxmlwrp.cxx
index 3672dce210cf..22fe0626ee4f 100644
--- a/sd/source/filter/xml/sdxmlwrp.cxx
+++ b/sd/source/filter/xml/sdxmlwrp.cxx
@@ -461,6 +461,7 @@ bool SdXMLFilter::Import( ErrCode& nError )
     pDoc->StopWorkStartupDelay();
 
     mxModel->lockControllers();
+    pDoc->incImportExport();
 
     /** property map for import info set */
     static PropertyMapEntry const aImportInfoMap[] =
@@ -647,6 +648,7 @@ bool SdXMLFilter::Import( ErrCode& nError )
 
     if( mxModel.is() )
         mxModel->unlockControllers();
+    pDoc->decImportExport();
 
     if( nRet == ERRCODE_NONE )
         pDoc->UpdateAllLinks();
@@ -768,9 +770,11 @@ bool SdXMLFilter::Export()
     }
 
     bool bLocked = mxModel->hasControllersLocked();
+    SdDrawDocument* pDoc = mrDocShell.GetDoc();
 
     try
     {
+        pDoc->incImportExport();
         mxModel->lockControllers();
 
         uno::Reference< lang::XServiceInfo > xServiceInfo( mxModel, 
uno::UNO_QUERY );
@@ -843,7 +847,7 @@ bool SdXMLFilter::Export()
             // create helper for graphic and ole export if we have a storage
             if( xStorage.is() )
             {
-                xObjectHelper = SvXMLEmbeddedObjectHelper::Create( xStorage, 
*mrDocShell.GetDoc()->GetPersist(), SvXMLEmbeddedObjectHelperMode::Write );
+                xObjectHelper = SvXMLEmbeddedObjectHelper::Create( xStorage, 
*pDoc->GetPersist(), SvXMLEmbeddedObjectHelperMode::Write );
                 xObjectResolver = xObjectHelper.get();
 
                 xGraphicHelper = SvXMLGraphicHelper::Create( xStorage, 
SvXMLGraphicHelperMode::Write );
@@ -981,6 +985,7 @@ bool SdXMLFilter::Export()
     }
     if ( !bLocked )
         mxModel->unlockControllers();
+    pDoc->decImportExport();
 
     if( xGraphicHelper )
         xGraphicHelper->dispose();
diff --git a/svx/source/diagram/DiagramHelper_svx.cxx 
b/svx/source/diagram/DiagramHelper_svx.cxx
index cdde569c7c63..185e6bf4c77e 100644
--- a/svx/source/diagram/DiagramHelper_svx.cxx
+++ b/svx/source/diagram/DiagramHelper_svx.cxx
@@ -453,7 +453,7 @@ void 
DiagramHelper_svx::connectToSdrObjGroup(css::uno::Reference< css::drawing::
     rxRootShape = rTarget;
     pGroupObject = 
dynamic_cast<SdrObjGroup*>(SdrObject::getSdrObjectFromXShape(rxRootShape));
     if (nullptr != pGroupObject)
-        pGroupObject->mp_DiagramHelper.reset(this);;
+        pGroupObject->mp_DiagramHelper.reset(this);
 }
 
 void DiagramHelper_svx::AddAdditionalVisualization(const SdrObjGroup& rTarget, 
SdrHdlList& rHdlList)
diff --git a/svx/source/svdraw/svdmodel.cxx b/svx/source/svdraw/svdmodel.cxx
index 048350ca0164..471f72e1c8f6 100644
--- a/svx/source/svdraw/svdmodel.cxx
+++ b/svx/source/svdraw/svdmodel.cxx
@@ -121,7 +121,8 @@ struct SdrModelImpl
 
 
 SdrModel::SdrModel(SfxItemPool* pPool, comphelper::IEmbeddedHelper* 
pEmbeddedHelper, bool bDisablePropertyFiles)
-    : m_eObjUnit(SdrEngineDefaults::GetMapUnit())
+    : mnImExCnt(0)
+    , m_eObjUnit(SdrEngineDefaults::GetMapUnit())
     , m_eUIUnit(FieldUnit::MM)
     , m_aUIScale(Fraction(1,1))
     , m_nUIUnitDecimalMark(0)
diff --git a/svx/source/svdraw/svdogrp.cxx b/svx/source/svdraw/svdogrp.cxx
index 782275f71dcf..de1fda977380 100644
--- a/svx/source/svdraw/svdogrp.cxx
+++ b/svx/source/svdraw/svdogrp.cxx
@@ -30,6 +30,7 @@
 #include <sdr/contact/viewcontactofgroup.hxx>
 #include <basegfx/range/b2drange.hxx>
 #include <basegfx/polygon/b2dpolygontools.hxx>
+#include <basegfx/matrix/b2dhommatrixtools.hxx>
 #include <libxml/xmlwriter.h>
 #include <vcl/canvastools.hxx>
 #include <svx/diagram/DiagramHelper_svx.hxx>
@@ -763,6 +764,51 @@ rtl::Reference<SdrObject> 
SdrObjGroup::DoConvertToPolyObj(bool bBezier, bool bAd
     return pGroup;
 }
 
+bool SdrObjGroup::TRGetBaseGeometry(basegfx::B2DHomMatrix& rMatrix, 
basegfx::B2DPolyPolygon& /*rPolyPolygon*/) const
+{
+    // has no geometry itself, so just use SnapRect to get from sub-content.
+    // note that this already *includes* possible offsets from Writer Anchor,
+    // so do not check for that and correct below
+    tools::Rectangle aRectangle(GetSnapRect());
+
+    // convert to transformation values
+    basegfx::B2DTuple aScale(aRectangle.GetWidth(), aRectangle.GetHeight());
+    basegfx::B2DTuple aTranslate(aRectangle.Left(), aRectangle.Top());
+
+    // build matrix
+    rMatrix = basegfx::utils::createScaleTranslateB2DHomMatrix(aScale, 
aTranslate);
+
+    return false;
+}
+
+void SdrObjGroup::TRSetBaseGeometry(const basegfx::B2DHomMatrix& rMatrix, 
const basegfx::B2DPolyPolygon& /*rPolyPolygon*/)
+{
+    // break up matrix
+    basegfx::B2DTuple aScale;
+    basegfx::B2DTuple aTranslate;
+    double fRotate, fShearX;
+    rMatrix.decompose(aScale, aTranslate, fRotate, fShearX);
+
+    // #i75086# Old DrawingLayer (GeoStat and geometry) does not support 
holding negative scalings
+    // in X and Y which equal a 180 degree rotation. Recognize it and react 
accordingly
+    if(aScale.getX() < 0.0 && aScale.getY() < 0.0)
+    {
+        aScale.setX(fabs(aScale.getX()));
+        aScale.setY(fabs(aScale.getY()));
+    }
+
+    // build BaseRect
+    Point aPoint(basegfx::fround<tools::Long>(aTranslate.getX()),
+                 basegfx::fround<tools::Long>(aTranslate.getY()));
+    tools::Rectangle aBaseRect(aPoint, 
Size(basegfx::fround<tools::Long>(aScale.getX()),
+                                            
basegfx::fround<tools::Long>(aScale.getY())));
+
+    // set BaseRect: Call to SetSnapRect works relative to GetSnapRect() where
+    // possible offsets from Writer Anchor is already included, it then does a
+    // relative change to new SnapRect
+    SetSnapRect(aBaseRect);
+}
+
 void SdrObjGroup::SetDescription(const OUString& rStr)
 {
     static bool bActivateAdvancedDiagramFeatures(nullptr != 
std::getenv("ACTIVATE_ADVANCED_DIAGRAM_FEATURES"));
@@ -774,12 +820,10 @@ void SdrObjGroup::SetDescription(const OUString& rStr)
 
     OUString aOrigDescription(rStr);
 
-    if (!rStr.isEmpty() && getSdrModelFromSdrObject().isLocked())
+    if (!rStr.isEmpty() && getSdrModelFromSdrObject().isInImportExport())
     {
         // 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
@@ -819,12 +863,10 @@ OUString SdrObjGroup::GetDescription() const
     // call parent to get original description
     OUString aRetval(SdrObject::GetDescription());
 
-    if (mp_DiagramHelper && getSdrModelFromSdrObject().isLocked())
+    if (mp_DiagramHelper && getSdrModelFromSdrObject().isInImportExport())
     {
         // 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
diff --git a/svx/source/xml/xmlexport.cxx b/svx/source/xml/xmlexport.cxx
index 3ac3596e105c..984ef05275a1 100644
--- a/svx/source/xml/xmlexport.cxx
+++ b/svx/source/xml/xmlexport.cxx
@@ -66,6 +66,7 @@ bool SvxDrawingLayerExport( SdrModel* pModel, const 
uno::Reference<io::XOutputSt
         xSourceModel = Reference< frame::XModel >( xSourceDoc, UNO_QUERY );
         if ( xSourceModel.is() )
             xSourceModel->lockControllers();
+        pModel->incImportExport();
 
         const uno::Reference< uno::XComponentContext>& xContext( 
::comphelper::getProcessComponentContext() );
 
@@ -131,6 +132,7 @@ bool SvxDrawingLayerExport( SdrModel* pModel, const 
uno::Reference<io::XOutputSt
 
     if ( xSourceModel.is() )
         xSourceModel->unlockControllers();
+    pModel->decImportExport();
 
     return bDocRet;
 }
@@ -175,7 +177,7 @@ bool SvxDrawingLayerImport( SdrModel* pModel, const 
uno::Reference<io::XInputStr
 
         if ( xTargetModel.is() )
             xTargetModel->lockControllers();
-
+        pModel->incImportExport();
 
         xGraphicHelper = SvXMLGraphicHelper::Create( 
SvXMLGraphicHelperMode::Read );
         xGraphicStorageHandler = xGraphicHelper.get();
@@ -236,6 +238,7 @@ bool SvxDrawingLayerImport( SdrModel* pModel, const 
uno::Reference<io::XInputStr
 
     if ( xTargetModel.is() )
         xTargetModel->unlockControllers();
+    pModel->decImportExport();
 
     return bRet;
 }
diff --git a/sw/source/uibase/docvw/edtwin.cxx 
b/sw/source/uibase/docvw/edtwin.cxx
index 90b8f5ebb73f..3dac31a29111 100644
--- a/sw/source/uibase/docvw/edtwin.cxx
+++ b/sw/source/uibase/docvw/edtwin.cxx
@@ -62,6 +62,7 @@
 #include <svx/svdview.hxx>
 #include <svx/svdhdl.hxx>
 #include <svx/svdoutl.hxx>
+#include <svx/diagram/DiagramHelper_svx.hxx>
 #include <editeng/editeng.hxx>
 #include <editeng/editview.hxx>
 #include <editeng/svxacorr.hxx>
@@ -4763,6 +4764,37 @@ void SwEditWin::MouseButtonUp(const MouseEvent& rMEvt)
             rSh.GetView().GetViewFrame().GetBindings().InvalidateAll(false);
             return; // SdrView's event evaluated
         }
+
+        const Point aDocPos(PixelToLogic(rMEvt.GetPosPixel()));
+        SdrHdl* pHdl(pSdrView->PickHandle(aDocPos));
+
+        if (nullptr != pHdl)
+        {
+            SdrObject* pSingleObj(nullptr);
+            const SdrMarkList& rMarkList(pSdrView->GetMarkedObjectList());
+
+            if (1 == rMarkList.GetMarkCount())
+                pSingleObj = rMarkList.GetMark(0)->GetMarkedSdrObj();
+
+            if (nullptr != pSingleObj)
+            {
+                // Check for click on svx::diagram::DiagramFrameHdl
+                // - if we hit a SdrHdl
+                // - if single object is selected
+                //   - and it is a Diagram
+                if(pHdl && nullptr != pSingleObj && pSingleObj->isDiagram())
+                {
+                    svx::diagram::DiagramFrameHdl* 
pDiagramFrameHdl(dynamic_cast<svx::diagram::DiagramFrameHdl*>(pHdl));
+                    if(nullptr != pDiagramFrameHdl)
+                    {
+                        // let the DiagramFrameHdl decide what to do
+                        svx::diagram::DiagramFrameHdl::clicked(aDocPos);
+                    }
+                }
+            }
+        }
+
+
     }
     // only process MouseButtonUp when the Down went to that windows as well.
     if ( !m_bMBPressed )

Reply via email to