summaryrefslogtreecommitdiff
path: root/oox
diff options
context:
space:
mode:
authorArmin Le Grand (Allotropia) <Armin.Le.Grand@me.com>2022-04-19 11:37:57 +0200
committerArmin Le Grand <Armin.Le.Grand@me.com>2022-04-20 09:32:52 +0200
commitd9b3374b13108cf6b847f6eb92fb666194a68770 (patch)
treeeba87516cdef9e68a15ef85fa834b1e89eec54ca /oox
parentf22f83fbac3a0a419c2e95d7b725525fd02649e6 (diff)
Advanced Diagram support: Use better association Model<->XShape
To have a more direct and more reliable association between the XShape/oox::Shape and the model data svx::diagram::Point I added optional usage of the Model-UUID for that at the oox::Shape. Also added a 'fake' UUID to work with the BackgroundShape's attributes. Changed all preserve/rescue code to work based on that. Also cleanups/comments and preparations of some flags in the Diagram ModelData to steer behaviour on re-ceration. Change-Id: Ie30effdff34dcdbbc79a766de09157b2a3bd97d3 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/133168 Tested-by: Jenkins Reviewed-by: Armin Le Grand <Armin.Le.Grand@me.com>
Diffstat (limited to 'oox')
-rw-r--r--oox/source/drawingml/diagram/datamodel.cxx278
-rw-r--r--oox/source/drawingml/diagram/datamodel.hxx10
-rw-r--r--oox/source/drawingml/diagram/datamodelcontext.cxx2
-rw-r--r--oox/source/drawingml/diagram/diagram.cxx41
-rw-r--r--oox/source/drawingml/diagram/diagram.hxx4
-rw-r--r--oox/source/drawingml/diagram/diagramhelper.cxx17
-rw-r--r--oox/source/drawingml/diagram/diagramhelper.hxx2
-rw-r--r--oox/source/drawingml/diagram/layoutatomvisitors.cxx4
-rw-r--r--oox/source/drawingml/shape.cxx3
9 files changed, 302 insertions, 59 deletions
diff --git a/oox/source/drawingml/diagram/datamodel.cxx b/oox/source/drawingml/diagram/datamodel.cxx
index f0a3cef66903..bbe23041cf28 100644
--- a/oox/source/drawingml/diagram/datamodel.cxx
+++ b/oox/source/drawingml/diagram/datamodel.cxx
@@ -26,6 +26,10 @@
#include <drawingml/textparagraph.hxx>
#include <drawingml/textrun.hxx>
#include <oox/drawingml/shape.hxx>
+#include <com/sun/star/beans/XPropertyState.hpp>
+#include <com/sun/star/drawing/FillStyle.hpp>
+#include <com/sun/star/drawing/LineStyle.hpp>
+#include <editeng/unoprnms.hxx>
#include <unordered_set>
@@ -60,7 +64,7 @@ void DiagramData::restoreDataFromModelToShapeAfterReCreation(const svx::diagram:
// available data from the Diagram ModelData to it as preparation
// This is e.g. the Text, but may get more (styles?)
- if(rPoint.msTextBody && !rPoint.msTextBody->msText.isEmpty())
+ if(!rPoint.msTextBody->msText.isEmpty())
{
TextBodyPtr aNewTextBody(std::make_shared<TextBody>());
rNewShape.setTextBody(aNewTextBody);
@@ -82,8 +86,199 @@ void DiagramData::restoreDataFromModelToShapeAfterReCreation(const svx::diagram:
}
}
-void DiagramData::secureDataFromShapeToModelAfterDiagramImport()
+static void addProperty(const OUString& rName,
+ const css::uno::Reference< css::beans::XPropertySetInfo >& xInfo,
+ std::vector< std::pair< OUString, css::uno::Any >>& rTarget,
+ const css::uno::Reference< css::beans::XPropertySet >& xPropSet )
{
+ if(xInfo->hasPropertyByName(rName))
+ rTarget.push_back(std::pair(OUString(rName), xPropSet->getPropertyValue(rName)));
+}
+
+void DiagramData::secureStyleDataFromShapeToModel(::oox::drawingml::Shape& rShape)
+{
+ const std::vector< ShapePtr >& rChildren(rShape.getChildren());
+
+ if(!rChildren.empty())
+ {
+ // group shape
+ for (auto& child : rChildren)
+ {
+ secureStyleDataFromShapeToModel(*child);
+ }
+
+ // if group shape we are done. Do not secure properties for group shapes
+ return;
+ }
+
+ // we need a XShape
+ const css::uno::Reference< css::drawing::XShape > &rXShape(rShape.getXShape());
+ if(!rXShape)
+ return;
+
+ // we need a ModelID for association
+ if(rShape.getDiagramDataModelID().isEmpty())
+ return;
+
+ // define target to save to
+ svx::diagram::PointStyle* pTarget(nullptr);
+ const bool bIsBackgroundShape(rShape.getDiagramDataModelID() == msBackgroundShapeModelID);
+
+ if(bIsBackgroundShape)
+ {
+ // if BackgroundShape, create properties & set as target
+ if(!maBackgroundShapeStyle)
+ maBackgroundShapeStyle = std::make_shared< svx::diagram::PointStyle >();
+ pTarget = maBackgroundShapeStyle.get();
+ }
+ else
+ {
+ // if Shape, seek association
+ for (auto & point : maPoints)
+ {
+ if(point.msModelId == rShape.getDiagramDataModelID())
+ {
+ // found - create properties & set as target
+ pTarget = point.msPointStylePtr.get();
+
+ // we are done, there is no 2nd shape with the same ModelID by definition
+ break;
+ }
+ }
+ }
+
+ // no target -> nothing to do
+ if(nullptr == pTarget)
+ return;
+
+#ifdef DBG_UTIL
+ // to easier decide which additional properties may/should be preserved,
+ // create a full list of set properties to browse/decide (in debugger)
+ const css::uno::Reference< css::beans::XPropertyState > xAllPropStates(rXShape, css::uno::UNO_QUERY);
+ const css::uno::Reference< css::beans::XPropertySet > xAllPropSet( rXShape, css::uno::UNO_QUERY );
+ const css::uno::Sequence< css::beans::Property > allSequence(xAllPropSet->getPropertySetInfo()->getProperties());
+ std::vector< std::pair< OUString, css::uno::Any >> allSetProps;
+ for (auto& rProp : allSequence)
+ {
+ try
+ {
+ if (xAllPropStates->getPropertyState(rProp.Name) == css::beans::PropertyState::PropertyState_DIRECT_VALUE)
+ {
+ css::uno::Any aValue(xAllPropSet->getPropertyValue(rProp.Name));
+ if(aValue.hasValue())
+ allSetProps.push_back(std::pair(rProp.Name, aValue));
+ }
+ }
+ catch (...)
+ {
+ }
+ }
+#endif
+
+ const css::uno::Reference< css::beans::XPropertySet > xPropSet( rXShape, css::uno::UNO_QUERY );
+ if(!xPropSet)
+ return;
+
+ const css::uno::Reference< css::lang::XServiceInfo > xServiceInfo( rXShape, css::uno::UNO_QUERY );
+ if(!xServiceInfo)
+ return;
+
+ const css::uno::Reference< css::beans::XPropertySetInfo > xInfo(xPropSet->getPropertySetInfo());
+ if (!xInfo.is())
+ return;
+
+ // Note: The Text may also be secured here, so it may also be possible to
+ // secure/store it at PointStyle instead of at TextBody, same maybe evaluated
+ // for the text attributes - where when securing here the attributes would be
+ // in our UNO API format already.
+ // if(xServiceInfo->supportsService("com.sun.star.drawing.Text"))
+ // {
+ // css::uno::Reference< css::text::XText > xText(rXShape, css::uno::UNO_QUERY);
+ // const OUString aText(xText->getString());
+ //
+ // if(!aText.isEmpty())
+ // {
+ // }
+ // }
+
+ // Add all kinds of properties that are needed to re-create the XShape.
+ // For now this is a minimal example-selection, it will need to be extended
+ // over time for all kind of cases/properties
+
+ // text properties
+ if(!bIsBackgroundShape
+ && xServiceInfo->supportsService("com.sun.star.drawing.TextProperties"))
+ {
+ addProperty(UNO_NAME_CHAR_COLOR, xInfo, pTarget->maProperties, xPropSet);
+ addProperty(UNO_NAME_CHAR_HEIGHT, xInfo, pTarget->maProperties, xPropSet);
+ addProperty(UNO_NAME_CHAR_SHADOWED, xInfo, pTarget->maProperties, xPropSet);
+ addProperty(UNO_NAME_CHAR_WEIGHT, xInfo, pTarget->maProperties, xPropSet);
+ }
+
+ // fill properties
+ if(xServiceInfo->supportsService("com.sun.star.drawing.FillProperties"))
+ {
+ css::drawing::FillStyle eFillStyle(css::drawing::FillStyle_NONE);
+ if (xInfo->hasPropertyByName(UNO_NAME_FILLSTYLE))
+ xPropSet->getPropertyValue(UNO_NAME_FILLSTYLE) >>= eFillStyle;
+
+ if(css::drawing::FillStyle_NONE != eFillStyle)
+ {
+ addProperty(UNO_NAME_FILLSTYLE, xInfo, pTarget->maProperties, xPropSet);
+
+ switch(eFillStyle)
+ {
+ case css::drawing::FillStyle_SOLID:
+ {
+ addProperty(UNO_NAME_FILLCOLOR, xInfo, pTarget->maProperties, xPropSet);
+ break;
+ }
+ default:
+ case css::drawing::FillStyle_NONE:
+ case css::drawing::FillStyle_GRADIENT:
+ case css::drawing::FillStyle_HATCH:
+ case css::drawing::FillStyle_BITMAP:
+ break;
+ }
+ }
+ }
+
+ // line properties
+ if(!bIsBackgroundShape
+ && xServiceInfo->supportsService("com.sun.star.drawing.LineProperties"))
+ {
+ css::drawing::LineStyle eLineStyle(css::drawing::LineStyle_NONE);
+ if (xInfo->hasPropertyByName(UNO_NAME_LINESTYLE))
+ xPropSet->getPropertyValue(UNO_NAME_LINESTYLE) >>= eLineStyle;
+
+ if(css::drawing::LineStyle_NONE != eLineStyle)
+ {
+ addProperty(UNO_NAME_LINESTYLE, xInfo, pTarget->maProperties, xPropSet);
+ addProperty(UNO_NAME_LINECOLOR, xInfo, pTarget->maProperties, xPropSet);
+ addProperty(UNO_NAME_LINEWIDTH, xInfo, pTarget->maProperties, xPropSet);
+
+ switch(eLineStyle)
+ {
+ case css::drawing::LineStyle_SOLID:
+ break;
+ default:
+ case css::drawing::LineStyle_NONE:
+ case css::drawing::LineStyle_DASH:
+ break;
+ }
+ }
+ }
+}
+
+void DiagramData::secureDataFromShapeToModelAfterDiagramImport(::oox::drawingml::Shape& rRootShape)
+{
+ const std::vector< ShapePtr >& rChildren(rRootShape.getChildren());
+
+ for (auto& child : rChildren)
+ {
+ secureStyleDataFromShapeToModel(*child);
+ }
+
// After Diagram import, parts of the Diagram ModelData is at the
// oox::drawingml::Shape. Since these objects are temporary helpers,
// secure that data at the Diagram ModelData by copying.
@@ -97,7 +292,6 @@ void DiagramData::secureDataFromShapeToModelAfterDiagramImport()
{
if(pShapeCandidate->getTextBody() && !pShapeCandidate->getTextBody()->isEmpty())
{
- point.msTextBody = std::make_shared<svx::diagram::TextBody>();
point.msTextBody->msText = pShapeCandidate->getTextBody()->toString();
const uno::Sequence< beans::PropertyValue > aTextProps(
@@ -129,9 +323,85 @@ void DiagramData::secureDataFromShapeToModelAfterDiagramImport()
}
}
+void DiagramData::restoreStyleDataFromShapeToModel(::oox::drawingml::Shape& rShape)
+{
+ const std::vector< ShapePtr >& rChildren(rShape.getChildren());
+
+ if(!rChildren.empty())
+ {
+ // group shape
+ for (auto& child : rChildren)
+ {
+ restoreStyleDataFromShapeToModel(*child);
+ }
+
+ // if group shape we are done. Do not restore properties for group shapes
+ return;
+ }
+
+ // we need a XShape
+ const css::uno::Reference< css::drawing::XShape > &rXShape(rShape.getXShape());
+ if(!rXShape)
+ return;
+
+ // we need a ModelID for association
+ if(rShape.getDiagramDataModelID().isEmpty())
+ return;
+
+ // define source to save to
+ svx::diagram::PointStyle* pSource(nullptr);
+
+ if(rShape.getDiagramDataModelID() == msBackgroundShapeModelID)
+ {
+ // if BackgroundShape, set BackgroundShapeStyle as source
+ if(maBackgroundShapeStyle)
+ pSource = maBackgroundShapeStyle.get();
+ }
+ else
+ {
+ // if Shape, seek association
+ for (auto & point : maPoints)
+ {
+ if(point.msModelId == rShape.getDiagramDataModelID())
+ {
+ // found - create properties & set as source
+ pSource = point.msPointStylePtr.get();
+
+ // we are done, there is no 2nd shape with the same ModelID by definition
+ break;
+ }
+ }
+ }
+
+ // no source -> nothing to do
+ if(nullptr == pSource)
+ return;
+
+ // get target ProperySet of new XShape
+ css::uno::Reference<css::beans::XPropertySet> xPropSet(rXShape, css::uno::UNO_QUERY);
+ if(!xPropSet)
+ return;
+
+ // apply properties
+ for (auto const& prop : pSource->maProperties)
+ {
+ xPropSet->setPropertyValue(prop.first, prop.second);
+ }
+}
+
+void DiagramData::restoreDataFromShapeToModelAfterDiagramImport(::oox::drawingml::Shape& rRootShape)
+{
+ const std::vector< ShapePtr >& rChildren(rRootShape.getChildren());
+
+ for (auto& child : rChildren)
+ {
+ restoreStyleDataFromShapeToModel(*child);
+ }
+}
+
DiagramData::DiagramData()
: svx::diagram::DiagramData()
-, mpBackgroundFillProperties( std::make_shared<FillProperties>() )
+, mpBackgroundShapeFillProperties( std::make_shared<FillProperties>() )
{
}
diff --git a/oox/source/drawingml/diagram/datamodel.hxx b/oox/source/drawingml/diagram/datamodel.hxx
index f7402cb0681e..21137f6e05d2 100644
--- a/oox/source/drawingml/diagram/datamodel.hxx
+++ b/oox/source/drawingml/diagram/datamodel.hxx
@@ -44,21 +44,25 @@ public:
// creates temporary processing data from model data
virtual void buildDiagramDataModel(bool bClearOoxShapes);
- FillPropertiesPtr& getBackgroundFillProperties() { return mpBackgroundFillProperties; }
+ FillPropertiesPtr& getBackgroundShapeFillProperties() { return mpBackgroundShapeFillProperties; }
virtual void dump() const;
Shape* getOrCreateAssociatedShape(const svx::diagram::Point& rPoint, bool bCreateOnDemand = false) const;
// get/set data between Diagram DataModel and oox::drawingml::Shape
- void secureDataFromShapeToModelAfterDiagramImport();
+ void secureDataFromShapeToModelAfterDiagramImport(::oox::drawingml::Shape& rRootShape);
+ void restoreDataFromShapeToModelAfterDiagramImport(::oox::drawingml::Shape& rRootShape);
static void restoreDataFromModelToShapeAfterReCreation(const svx::diagram::Point& rPoint, Shape& rNewShape);
protected:
+ void secureStyleDataFromShapeToModel(::oox::drawingml::Shape& rShape);
+ void restoreStyleDataFromShapeToModel(::oox::drawingml::Shape& rShape);
+
// The model definition, the parts *only* available in oox. Also look for already
// defined ModelData in svx::diagram::DiagramData
// - FillStyle for Diagram Background (empty constructed, may stay empty)
- FillPropertiesPtr mpBackgroundFillProperties;
+ FillPropertiesPtr mpBackgroundShapeFillProperties;
// temporary processing data, deleted when using build(). Association
// map between oox::drawingml::Shape and svx::diagram::Point ModelData
diff --git a/oox/source/drawingml/diagram/datamodelcontext.cxx b/oox/source/drawingml/diagram/datamodelcontext.cxx
index 97484c992ad3..4f0e3f047233 100644
--- a/oox/source/drawingml/diagram/datamodelcontext.cxx
+++ b/oox/source/drawingml/diagram/datamodelcontext.cxx
@@ -317,7 +317,7 @@ public:
case A_TOKEN( solidFill ):
// EG_FillProperties
return FillPropertiesContext::createFillContext(
- *this, aElementToken, rAttribs, *mpDataModel->getBackgroundFillProperties() );
+ *this, aElementToken, rAttribs, *mpDataModel->getBackgroundShapeFillProperties() );
case A_TOKEN( effectDag ):
case A_TOKEN( effectLst ):
// TODO
diff --git a/oox/source/drawingml/diagram/diagram.cxx b/oox/source/drawingml/diagram/diagram.cxx
index 56b9b791e022..2ccc67805945 100644
--- a/oox/source/drawingml/diagram/diagram.cxx
+++ b/oox/source/drawingml/diagram/diagram.cxx
@@ -35,6 +35,7 @@
#include <basegfx/matrix/b2dhommatrix.hxx>
#include <svx/svdpage.hxx>
#include <oox/ppt/pptimport.hxx>
+#include <comphelper/xmltools.hxx>
#include "diagramlayoutatoms.hxx"
#include "layoutatomvisitors.hxx"
@@ -103,39 +104,6 @@ static void removeUnneededGroupShapes(const ShapePtr& pShape)
}
}
-void DiagramLayout::secureDataFromXShapeToModelAfterDiagramImport()
-{
- // maPresPointShapeMap types: < const svx::diagram::Point*, ShapePtr >
- for (const auto& pEntry : maPresPointShapeMap)
- {
- if(nullptr != pEntry.first && pEntry.second)
- {
- const css::uno::Reference< css::drawing::XShape >& rXShape(pEntry.second->getXShape());
-
- if(rXShape)
- {
- const_cast<svx::diagram::Point*>(pEntry.first)->securePropertiesFromXShape(rXShape);
- }
- }
- }
-}
-
-void DiagramLayout::restoreDataFromModelToXShapeAfterDiagramReCreate()
-{
- // maPresPointShapeMap types: < const svx::diagram::Point*, ShapePtr >
- for (const auto& pEntry : maPresPointShapeMap)
- {
- if(nullptr != pEntry.first && pEntry.second)
- {
- const css::uno::Reference< css::drawing::XShape >& rXShape(pEntry.second->getXShape());
-
- if(rXShape)
- {
- pEntry.first->restorePropertiesToXShape(rXShape);
- }
- }
- }
-}
void Diagram::addTo( const ShapePtr & pParentShape )
{
@@ -165,8 +133,13 @@ void Diagram::addTo( const ShapePtr & pParentShape )
pBackground->setSubType(XML_rect);
pBackground->getCustomShapeProperties()->setShapePresetType(XML_rect);
pBackground->setSize(pParentShape->getSize());
- pBackground->getFillProperties() = *mpData->getBackgroundFillProperties();
+ pBackground->getFillProperties() = *mpData->getBackgroundShapeFillProperties();
pBackground->setLocked(true);
+
+ // create and set ModelID for BackgroundShape to allow later association
+ getData()->setBackgroundShapeModelID(OStringToOUString(comphelper::xml::generateGUIDString(), RTL_TEXTENCODING_UTF8));
+ pBackground->setDiagramDataModelID(getData()->getBackgroundShapeModelID());
+
auto& aChildren = pParentShape->getChildren();
aChildren.insert(aChildren.begin(), pBackground);
}
diff --git a/oox/source/drawingml/diagram/diagram.hxx b/oox/source/drawingml/diagram/diagram.hxx
index 43516d4a270d..f58c762f6a1a 100644
--- a/oox/source/drawingml/diagram/diagram.hxx
+++ b/oox/source/drawingml/diagram/diagram.hxx
@@ -79,10 +79,6 @@ public:
PresPointShapeMap & getPresPointShapeMap()
{ return maPresPointShapeMap; }
- // get/set data between Diagram DataModel and oox::drawingml::Shape
- void secureDataFromXShapeToModelAfterDiagramImport();
- void restoreDataFromModelToXShapeAfterDiagramReCreate();
-
private:
Diagram& mrDgm;
OUString msDefStyle;
diff --git a/oox/source/drawingml/diagram/diagramhelper.cxx b/oox/source/drawingml/diagram/diagramhelper.cxx
index 6dc991149b01..2ee9e64f2535 100644
--- a/oox/source/drawingml/diagram/diagramhelper.cxx
+++ b/oox/source/drawingml/diagram/diagramhelper.cxx
@@ -103,8 +103,7 @@ void AdvancedDiagramHelper::reLayout(SdrObjGroup& rTarget)
// set oox::Theme at Filter. All LineStyle/FillStyle/Colors/Attributes
// will be taken from there
- static bool bUseDiagramThemeData(false);
- if(bUseDiagramThemeData)
+ if(UseDiagramThemeData())
xFilter->setCurrentTheme(getOrCreateThemePtr(xFilter));
css::uno::Reference< css::lang::XComponent > aComponentModel( rUnoModel, uno::UNO_QUERY );
@@ -132,9 +131,8 @@ void AdvancedDiagramHelper::reLayout(SdrObjGroup& rTarget)
mpDiagramPtr->syncDiagramFontHeights();
// re-apply secured data from ModelData
- static bool bUseDiagramModelData(true);
- if(bUseDiagramModelData)
- mpDiagramPtr->getLayout()->restoreDataFromModelToXShapeAfterDiagramReCreate();
+ if(UseDiagramModelData())
+ mpDiagramPtr->getData()->restoreDataFromShapeToModelAfterDiagramImport(*pShapePtr);
// Re-apply remembered geometry
rTarget.TRSetBaseGeometry(aTransformation, aPolyPolygon);
@@ -200,7 +198,7 @@ bool AdvancedDiagramHelper::removeNode(const OUString& rNodeId)
return bRetval;
}
-void AdvancedDiagramHelper::doAnchor(SdrObjGroup& rTarget)
+void AdvancedDiagramHelper::doAnchor(SdrObjGroup& rTarget, ::oox::drawingml::Shape& rRootShape)
{
if(!mpDiagramPtr)
{
@@ -212,8 +210,7 @@ void AdvancedDiagramHelper::doAnchor(SdrObjGroup& rTarget)
// After Diagram import, parts of the Diagram ModelData is at the
// oox::drawingml::Shape. Since these objects are temporary helpers,
// secure that data at the Diagram ModelData by copying.
- mpDiagramPtr->getData()->secureDataFromShapeToModelAfterDiagramImport();
- mpDiagramPtr->getLayout()->secureDataFromXShapeToModelAfterDiagramImport();
+ mpDiagramPtr->getData()->secureDataFromShapeToModelAfterDiagramImport(rRootShape);
anchorToSdrObjGroup(rTarget);
}
@@ -221,11 +218,9 @@ void AdvancedDiagramHelper::doAnchor(SdrObjGroup& rTarget)
std::shared_ptr< ::oox::drawingml::Theme > AdvancedDiagramHelper::getOrCreateThemePtr(
rtl::Reference< oox::shape::ShapeFilterBase >& rxFilter) const
{
- static bool bForceThemePtrReceation(false);
-
// (Re-)Use already existing Theme if existing/imported if possible.
// If not, re-import Theme if data is available and thus possible
- if(hasDiagramData() && (bForceThemePtrReceation || !mpThemePtr))
+ if(hasDiagramData() && (ForceThemePtrReceation() || !mpThemePtr))
{
// get the originally imported dom::XDocument
const uno::Reference< css::xml::dom::XDocument >& xThemeDocument(mpDiagramPtr->getData()->getThemeDocument());
diff --git a/oox/source/drawingml/diagram/diagramhelper.hxx b/oox/source/drawingml/diagram/diagramhelper.hxx
index d8fd46ce57a1..cede1aeeccf9 100644
--- a/oox/source/drawingml/diagram/diagramhelper.hxx
+++ b/oox/source/drawingml/diagram/diagramhelper.hxx
@@ -73,7 +73,7 @@ public:
virtual OUString addNode(const OUString& rText) override;
virtual bool removeNode(const OUString& rNodeId) override;
- void doAnchor(SdrObjGroup& rTarget);
+ void doAnchor(SdrObjGroup& rTarget, ::oox::drawingml::Shape& rRootShape);
std::shared_ptr< ::oox::drawingml::Theme > getOrCreateThemePtr(
rtl::Reference< oox::shape::ShapeFilterBase>& rxFilter ) const;
};
diff --git a/oox/source/drawingml/diagram/layoutatomvisitors.cxx b/oox/source/drawingml/diagram/layoutatomvisitors.cxx
index 927c869a9c38..45f85f808458 100644
--- a/oox/source/drawingml/diagram/layoutatomvisitors.cxx
+++ b/oox/source/drawingml/diagram/layoutatomvisitors.cxx
@@ -183,6 +183,10 @@ void ShapeTemplateVisitor::visit(ShapeAtom& rAtom)
// Fill properties have to be changed as sometimes only the presentation node contains the blip
// fill, unshare those.
mpShape->cloneFillProperties();
+
+ // add/set ModelID from currrent node to allow later association
+ if (mpCurrentNode)
+ mpShape->setDiagramDataModelID(mpCurrentNode->msModelId);
}
void ShapeLayoutingVisitor::visit(ConstraintAtom& rAtom)
diff --git a/oox/source/drawingml/shape.cxx b/oox/source/drawingml/shape.cxx
index 12eb72d40542..64ff93fc9bec 100644
--- a/oox/source/drawingml/shape.cxx
+++ b/oox/source/drawingml/shape.cxx
@@ -193,6 +193,7 @@ Shape::Shape( const ShapePtr& pSourceShape )
, mfAspectRatio(pSourceShape->mfAspectRatio)
, mbUseBgFill(pSourceShape->mbUseBgFill)
, mpDiagramHelper( nullptr )
+, msDiagramDataModelID(pSourceShape->msDiagramDataModelID)
{}
Shape::~Shape()
@@ -225,7 +226,7 @@ void Shape::propagateDiagramHelper()
if(pAnchorObj)
{
- static_cast<AdvancedDiagramHelper*>(mpDiagramHelper)->doAnchor(*pAnchorObj);
+ static_cast<AdvancedDiagramHelper*>(mpDiagramHelper)->doAnchor(*pAnchorObj, *this);
mpDiagramHelper = nullptr;
}
}