include/oox/drawingml/shape.hxx                |    9 --
 include/svx/diagram/IDiagramHelper.hxx         |    3 
 oox/source/drawingml/diagram/diagram.cxx       |   48 ++++++-------
 oox/source/drawingml/diagram/diagram.hxx       |   13 +--
 oox/source/drawingml/diagram/diagramhelper.cxx |   22 +++++-
 oox/source/drawingml/diagram/diagramhelper.hxx |    4 +
 oox/source/drawingml/shape.cxx                 |   52 ++------------
 oox/source/export/drawingml.cxx                |   41 +++++------
 oox/source/ppt/pptshape.cxx                    |    5 -
 oox/source/shape/ShapeContextHandler.cxx       |    5 -
 sc/source/filter/oox/drawingfragment.cxx       |    8 +-
 sd/qa/unit/import-tests-smartart.cxx           |   23 +++---
 svx/qa/unit/svdraw.cxx                         |   27 +++++--
 svx/source/diagram/IDiagramHelper.cxx          |    2 
 sw/qa/extras/ooxmlexport/ooxmlexport3.cxx      |   89 ++++++++++---------------
 15 files changed, 166 insertions(+), 185 deletions(-)

New commits:
commit c60be14f9c3b1d908ef1f5bf4bae2fb136002a82
Author:     Armin Le Grand (collabora) <[email protected]>
AuthorDate: Fri Dec 12 18:52:39 2025 +0100
Commit:     Armin Le Grand <[email protected]>
CommitDate: Wed Dec 17 15:26:44 2025 +0100

    SmartArt: Move Information from GrabBag to DiagramHelper
    
    Information about an imported Diagram was buffered at the
    SdrObject in the GrabBag, mainly the original imported DomTrees.
    This was done before a place like DiagramHelper existed and has
    no practical background.
    It is now held at the place where it belongs, at the
    DiagramHelper associated with the SdrObjGroup. It makes it
    easier to reset the no longer valid DomTrees when the Diagram
    model data changes, also automatically that info is removed
    when the SdrObjGroup is no Diagram anymore, together with the
    DiagramHelper.
    I also have and maybe will need UnitTests, so put this on
    gerrit early.
    
    ShapeContextHandler::getShape needed correction, it has to
    1st migrate the DiagramHelper and then use it.
    
    Had to correct testTextEditEmptyGrabBag. There are no
    GrabBag Items anymore for the Diagram, but still from
    OOX import, e.g. OOXRotationAngle. Not sure if these
    will be needed in the future, but for now had to reset
    GrabBag for changed attributes.
    
    Need to secure access to uno::Sequence when accessing
    xml::dom::XDocument in DrawingML::WriteDiagram to
    avoid access to non existing index if not used.
    
    I used the wrong name for the DiagramDataRels entries,
    corrected these to "OOXDiagramDataRels".
    
    Change-Id: I60b17e1211314ae50e7d1a9a43fd14a8b56c9d78
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/195579
    Tested-by: Jenkins
    Reviewed-by: Armin Le Grand <[email protected]>

diff --git a/include/oox/drawingml/shape.hxx b/include/oox/drawingml/shape.hxx
index ec3acb6cb0a7..2da7db183bb2 100644
--- a/include/oox/drawingml/shape.hxx
+++ b/include/oox/drawingml/shape.hxx
@@ -231,9 +231,9 @@ public:
     SAL_DLLPRIVATE void setWps(bool bWps);
     bool                getWps() const { return mbWps;}
     SAL_DLLPRIVATE void setTextBox(bool bTextBox);
-    const css::uno::Sequence<css::beans::PropertyValue> &
-                        getDiagramDoms() const { return maDiagramDoms; }
-    void                setDiagramDoms(const 
css::uno::Sequence<css::beans::PropertyValue>& rDiagramDoms) { maDiagramDoms = 
rDiagramDoms; }
+
+    // access to DiagramHelper
+    AdvancedDiagramHelper* getDiagramHelper() const { return mpDiagramHelper; }
     SAL_DLLPRIVATE css::uno::Sequence< css::uno::Sequence< css::uno::Any > 
>resolveRelationshipsOfTypeFromOfficeDoc(
                                                                           
core::XmlFilterBase& rFilter, const OUString& sFragment, std::u16string_view 
sType );
     void                setLinkedTxbxAttributes(const LinkedTxbxAttr& rhs){ 
maLinkedTxbxAttr = rhs; };
@@ -310,7 +310,6 @@ protected:
                             ShapeIdMap* pShapeMap,
                             const basegfx::B2DHomMatrix& aTransformation );
 
-    SAL_DLLPRIVATE void keepDiagramCompatibilityInfo();
     SAL_DLLPRIVATE void convertSmartArtToMetafile( ::oox::core::XmlFilterBase 
const& rFilterBase );
 
     SAL_DLLPRIVATE css::uno::Reference< css::drawing::XShape >
@@ -430,8 +429,6 @@ private:
     bool                            mbHasLinkedTxbx; // this text box has 
linked text box ?
     bool                            mbHasCustomPrompt; // indicates that it's 
not a generic placeholder
 
-    css::uno::Sequence<css::beans::PropertyValue> maDiagramDoms;
-
     /// Z-Order.
     sal_Int32 mnZOrder = 0;
 
diff --git a/include/svx/diagram/IDiagramHelper.hxx 
b/include/svx/diagram/IDiagramHelper.hxx
index d36e5eb861d5..a7291561146e 100644
--- a/include/svx/diagram/IDiagramHelper.hxx
+++ b/include/svx/diagram/IDiagramHelper.hxx
@@ -136,6 +136,9 @@ public:
     virtual void TextInformationChange(const OUString& rDiagramDataModelID, 
SdrOutliner& rOutl) = 0;
 
     static void AddAdditionalVisualization(const SdrObjGroup& rTarget, 
SdrHdlList& rHdlList);
+
+    // access to PropertyValues
+    virtual css::beans::PropertyValue getDomPropertyValue(const OUString& 
rName) const = 0;
 };
 
 }} // end of namespace
diff --git a/oox/source/drawingml/diagram/diagram.cxx 
b/oox/source/drawingml/diagram/diagram.cxx
index 84cf631ec455..9901ec3a844b 100644
--- a/oox/source/drawingml/diagram/diagram.cxx
+++ b/oox/source/drawingml/diagram/diagram.cxx
@@ -149,30 +149,14 @@ Diagram::Diagram()
 {
 }
 
-uno::Sequence<beans::PropertyValue> Diagram::getDomsAsPropertyValues() const
+beans::PropertyValue Diagram::getDomPropertyValue(const OUString& rName) const
 {
-    sal_Int32 length = maMainDomMap.size();
+    const DiagramPRDomMap::const_iterator aHit = maDiagramPRDomMap.find(rName);
 
-    if (maDataRelsMap.hasElements())
-        ++length;
+    if (aHit != maDiagramPRDomMap.end())
+        return aHit->second;
 
-    uno::Sequence<beans::PropertyValue> aValue(length);
-    beans::PropertyValue* pValue = aValue.getArray();
-    for (auto const& mainDom : maMainDomMap)
-    {
-        pValue->Name = mainDom.first;
-        pValue->Value <<= mainDom.second;
-        ++pValue;
-    }
-
-    if (maDataRelsMap.hasElements())
-    {
-        pValue->Name = "OOXDiagramDataRels";
-        pValue->Value <<= maDataRelsMap;
-        ++pValue;
-    }
-
-    return aValue;
+    return beans::PropertyValue();
 }
 
 using ShapePairs
@@ -226,6 +210,12 @@ void Diagram::syncDiagramFontHeights()
     maDiagramFontHeights.clear();
 }
 
+void Diagram::addDomPropertyValue(beans::PropertyValue& aValue)
+{
+    if (!aValue.Name.isEmpty())
+        maDiagramPRDomMap[aValue.Name] = aValue;
+}
+
 static uno::Reference<xml::dom::XDocument> loadFragment(
     core::XmlFilterBase& rFilter,
     const OUString& rFragmentPath )
@@ -248,8 +238,10 @@ static void importFragment( core::XmlFilterBase& rFilter,
                      const DiagramPtr& pDiagram,
                      const rtl::Reference< core::FragmentHandler >& rxHandler )
 {
-    DiagramDomMap& rMainDomMap = pDiagram->getDomMap();
-    rMainDomMap[rDocName] = rXDom;
+    beans::PropertyValue aValue;
+    aValue.Name = rDocName;
+    aValue.Value <<= rXDom;
+    pDiagram->addDomPropertyValue(aValue);
 
     uno::Reference<xml::sax::XFastSAXSerializable> xSerializer(
         rXDom, uno::UNO_QUERY_THROW);
@@ -335,8 +327,13 @@ void loadDiagram( ShapePtr const & pShape,
                            pDiagram,
                            xRefDataModel);
 
-            pDiagram->getDataRelsMap() = 
pShape->resolveRelationshipsOfTypeFromOfficeDoc( rFilter,
-                    xRefDataModel->getFragmentPath(), u"image" );
+            uno::Sequence< uno::Sequence< uno::Any > > aDataRelsMap(
+                pShape->resolveRelationshipsOfTypeFromOfficeDoc( rFilter, 
xRefDataModel->getFragmentPath(), u"image" ));
+
+            beans::PropertyValue aValue;
+            aValue.Name = "OOXDiagramDataRels";
+            aValue.Value <<= aDataRelsMap;
+            pDiagram->addDomPropertyValue(aValue);
 
             // Pass the info to pShape
             for (auto const& extDrawing : pData->getExtDrawings())
@@ -431,7 +428,6 @@ void loadDiagram( ShapePtr const & pShape,
         // up
         const bool bCreate(pShape->getExtDrawings().empty());
         pDiagram->addTo(pShape, bCreate);
-        pShape->setDiagramDoms(pDiagram->getDomsAsPropertyValues());
 
         // Get the oox::Theme definition and - if available - move/secure the
         // original ImportData directly to the Diagram ModelData
diff --git a/oox/source/drawingml/diagram/diagram.hxx 
b/oox/source/drawingml/diagram/diagram.hxx
index 0a1a59336da9..c9f51bc675de 100644
--- a/oox/source/drawingml/diagram/diagram.hxx
+++ b/oox/source/drawingml/diagram/diagram.hxx
@@ -40,7 +40,6 @@ class LayoutNode;
 typedef std::shared_ptr< LayoutNode > LayoutNodePtr;
 class LayoutAtom;
 typedef std::shared_ptr< LayoutAtom > LayoutAtomPtr;
-typedef std::map< OUString, css::uno::Reference<css::xml::dom::XDocument> > 
DiagramDomMap;
 typedef std::map< OUString, LayoutAtomPtr > LayoutAtomMap;
 typedef std::map< const svx::diagram::Point*, ShapePtr > PresPointShapeMap;
 
@@ -124,6 +123,7 @@ struct DiagramColor
 };
 
 typedef std::map<OUString,DiagramColor> DiagramColorMap;
+typedef std::map<OUString,css::beans::PropertyValue> DiagramPRDomMap;
 
 class Diagram
 {
@@ -142,14 +142,16 @@ public:
     const DiagramQStyleMap& getStyles() const { return maStyles; }
     DiagramColorMap& getColors() { return maColors; }
     const DiagramColorMap& getColors() const { return maColors; }
-    DiagramDomMap & getDomMap() { return maMainDomMap; }
-    css::uno::Sequence< css::uno::Sequence< css::uno::Any > > & 
getDataRelsMap() { return maDataRelsMap; }
+    DiagramPRDomMap & getRPDomMap() { return maDiagramPRDomMap; }
     void addTo( const ShapePtr & pShape, bool bCreate );
 
-    css::uno::Sequence<css::beans::PropertyValue> getDomsAsPropertyValues() 
const;
     oox::core::NamedShapePairs& getDiagramFontHeights() { return 
maDiagramFontHeights; }
     void syncDiagramFontHeights();
 
+    void addDomPropertyValue(css::beans::PropertyValue& aValue);
+    css::beans::PropertyValue getDomPropertyValue(const OUString& rName) const;
+    void resetDomPropertyValues() { maDiagramPRDomMap.clear(); }
+
 private:
     // This contains groups of shapes: automatic font size is the same in each 
group.
     oox::core::NamedShapePairs maDiagramFontHeights;
@@ -158,8 +160,7 @@ private:
     DiagramLayoutPtr               mpLayout;
     DiagramQStyleMap               maStyles;
     DiagramColorMap                maColors;
-    DiagramDomMap                  maMainDomMap;
-    css::uno::Sequence< css::uno::Sequence< css::uno::Any > > maDataRelsMap;
+    DiagramPRDomMap                maDiagramPRDomMap;
 };
 
 typedef std::shared_ptr< Diagram > DiagramPtr;
diff --git a/oox/source/drawingml/diagram/diagramhelper.cxx 
b/oox/source/drawingml/diagram/diagramhelper.cxx
index d19e1a5e0bd7..5d590d3e14d7 100644
--- a/oox/source/drawingml/diagram/diagramhelper.cxx
+++ b/oox/source/drawingml/diagram/diagramhelper.cxx
@@ -244,9 +244,13 @@ void AdvancedDiagramHelper::TextInformationChange(const 
OUString& rDiagramDataMo
     // try text change for model part in DiagramData
     const bool 
bChanged(mpDiagramPtr->getData()->TextInformationChange(rDiagramDataModelID, 
rOutl));
 
-    if(bChanged && nullptr != mpAssociatedSdrObjGroup)
+    if(bChanged)
     {
-        // if change was done, reset GrabBagItem to delete buffered 
DiagramData which is no longer valid
+        // reset Dom properties at DiagramData
+        mpDiagramPtr->resetDomPropertyValues();
+
+        // still reset GrabBag at Associated SdrObjGroup object. There are no 
"OOX.*"
+        // entries anymore, but others like "mso-rotation-angle" and others
         
mpAssociatedSdrObjGroup->SetGrabBagItem(uno::Any(uno::Sequence<beans::PropertyValue>()));
 
         // also set self to modified to get correct exports
@@ -302,6 +306,20 @@ const std::shared_ptr< ::oox::drawingml::Theme >& 
AdvancedDiagramHelper::getOrCr
     return mpThemePtr;
 }
 
+void AdvancedDiagramHelper::addDomPropertyValue(beans::PropertyValue& aValue)
+{
+    if (mpDiagramPtr)
+        mpDiagramPtr->addDomPropertyValue(aValue);
+}
+
+beans::PropertyValue AdvancedDiagramHelper::getDomPropertyValue(const 
OUString& rName) const
+{
+    if (mpDiagramPtr)
+        return mpDiagramPtr->getDomPropertyValue(rName);
+
+    return beans::PropertyValue();
+}
+
 }
 
 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/oox/source/drawingml/diagram/diagramhelper.hxx 
b/oox/source/drawingml/diagram/diagramhelper.hxx
index 22915e7b87e2..f16d0f3e6e01 100644
--- a/oox/source/drawingml/diagram/diagramhelper.hxx
+++ b/oox/source/drawingml/diagram/diagramhelper.hxx
@@ -85,6 +85,10 @@ public:
 
     // react on changes to objects identified by DiagramDataModelID, returns 
true if a change was done
     virtual void TextInformationChange(const OUString& rDiagramDataModelID, 
SdrOutliner& rOutl) override;
+
+    // access to get/set PropertyValues
+    void addDomPropertyValue(css::beans::PropertyValue& aValue);
+    css::beans::PropertyValue getDomPropertyValue(const OUString& rName) const 
override;
 };
 
 }
diff --git a/oox/source/drawingml/shape.cxx b/oox/source/drawingml/shape.cxx
index d313d731075b..70849b637aa2 100644
--- a/oox/source/drawingml/shape.cxx
+++ b/oox/source/drawingml/shape.cxx
@@ -161,7 +161,6 @@ Shape::Shape()
 , mbTextBox( false )
 , mbHasLinkedTxbx( false )
 , mbHasCustomPrompt( false )
-, maDiagramDoms( 0 )
 , mpDiagramHelper( nullptr )
 {
     setDefaults(/*bDefaultHeight*/true);
@@ -195,7 +194,6 @@ Shape::Shape( const OUString& rServiceName, bool 
bDefaultHeight )
 , mbTextBox( false )
 , mbHasLinkedTxbx( false )
 , mbHasCustomPrompt( false )
-, maDiagramDoms( 0 )
 , mpDiagramHelper( nullptr )
 {
     msServiceName = rServiceName;
@@ -240,7 +238,6 @@ Shape::Shape( const ShapePtr& pSourceShape )
 , mbTextBox( pSourceShape->mbTextBox )
 , mbHasLinkedTxbx(false)
 , mbHasCustomPrompt( pSourceShape->mbHasCustomPrompt )
-, maDiagramDoms( pSourceShape->maDiagramDoms )
 , mnZOrder(pSourceShape->mnZOrder)
 , mnZOrderOff(pSourceShape->mnZOrderOff)
 , mnDataNodeType(pSourceShape->mnDataNodeType)
@@ -492,8 +489,6 @@ void Shape::addShape(
 
             if( meFrameType == FRAMETYPE_DIAGRAM )
             {
-                keepDiagramCompatibilityInfo();
-
                 // set DiagramHelper at SdrObjGroup
                 propagateDiagramHelper();
 
@@ -2412,9 +2407,9 @@ Reference< XShape > const & Shape::createAndInsert(
 
 void Shape::keepDiagramDrawing(XmlFilterBase& rFilterBase, const OUString& 
rFragmentPath)
 {
-
-    sal_Int32 length = maDiagramDoms.getLength();
-    maDiagramDoms.realloc(length + 1);
+    AdvancedDiagramHelper* pAdvancedDiagramHelper(getDiagramHelper());
+    if (nullptr == pAdvancedDiagramHelper)
+        return;
 
     // drawingValue[0] => dom, drawingValue[1] => Sequence of associated 
relationships
     uno::Sequence<uno::Any> diagramDrawing{
@@ -2422,40 +2417,10 @@ void Shape::keepDiagramDrawing(XmlFilterBase& 
rFilterBase, const OUString& rFrag
         uno::Any(resolveRelationshipsOfTypeFromOfficeDoc(rFilterBase, 
rFragmentPath, u"image"))
     };
 
-    beans::PropertyValue* pValue = maDiagramDoms.getArray();
-    pValue[length].Name = "OOXDrawing";
-    pValue[length].Value <<= diagramDrawing;
-}
-
-void Shape::keepDiagramCompatibilityInfo()
-{
-    try
-    {
-        if( !maDiagramDoms.hasElements() )
-            return;
-
-        Reference < XPropertySet > xSet( mxShape, UNO_QUERY_THROW );
-        Reference < XPropertySetInfo > xSetInfo( xSet->getPropertySetInfo() );
-        if ( !xSetInfo.is() )
-            return;
-
-        const OUString aGrabBagPropName = UNO_NAME_MISC_OBJ_INTEROPGRABBAG;
-        if( !xSetInfo->hasPropertyByName( aGrabBagPropName ) )
-            return;
-
-        Sequence < PropertyValue > aGrabBag;
-        xSet->getPropertyValue( aGrabBagPropName ) >>= aGrabBag;
-
-        // We keep the previous items, if present
-        if ( aGrabBag.hasElements() )
-            xSet->setPropertyValue( aGrabBagPropName, Any( 
comphelper::concatSequences(aGrabBag, maDiagramDoms) ) );
-        else
-            xSet->setPropertyValue( aGrabBagPropName, Any( maDiagramDoms ) );
-    }
-    catch( const Exception& )
-    {
-        TOOLS_WARN_EXCEPTION( "oox.drawingml", 
"Shape::keepDiagramCompatibilityInfo" );
-    }
+    beans::PropertyValue aValue;
+    aValue.Name = "OOXDrawing";
+    aValue.Value <<= diagramDrawing;
+    pAdvancedDiagramHelper->addDomPropertyValue(aValue);
 }
 
 void Shape::convertSmartArtToMetafile(XmlFilterBase const & rFilterBase)
@@ -2494,7 +2459,8 @@ Reference < XShape > Shape::renderDiagramToGraphic( 
XmlFilterBase const & rFilte
 
     try
     {
-        if( !maDiagramDoms.hasElements() )
+        if( nullptr != getDiagramHelper() )
+        // if( !maDiagramDoms.hasElements() )
             return xShape;
 
         // Stream in which to place the rendered shape
diff --git a/oox/source/export/drawingml.cxx b/oox/source/export/drawingml.cxx
index 226c2bc1e866..f3208353342e 100644
--- a/oox/source/export/drawingml.cxx
+++ b/oox/source/export/drawingml.cxx
@@ -139,6 +139,7 @@
 #include <drawingml/presetgeometrynames.hxx>
 #include <docmodel/uno/UnoGradientTools.hxx>
 #include <svx/svdpage.hxx>
+#include <svx/diagram/IDiagramHelper.hxx>
 
 using namespace ::css;
 using namespace ::css::beans;
@@ -6680,28 +6681,24 @@ void DrawingML::WriteDiagram(const 
css::uno::Reference<css::drawing::XShape>& rX
     uno::Sequence<uno::Sequence<uno::Any>> xDataRelSeq;
     uno::Sequence<uno::Any> diagramDrawing;
 
-    // retrieve the doms from the GrabBag
-    uno::Sequence<beans::PropertyValue> propList;
-    xPropSet->getPropertyValue(UNO_NAME_MISC_OBJ_INTEROPGRABBAG) >>= propList;
-    for (const auto& rProp : propList)
-    {
-        OUString propName = rProp.Name;
-        if (propName == "OOXData")
-            rProp.Value >>= dataDom;
-        else if (propName == "OOXLayout")
-            rProp.Value >>= layoutDom;
-        else if (propName == "OOXStyle")
-            rProp.Value >>= styleDom;
-        else if (propName == "OOXColor")
-            rProp.Value >>= colorDom;
-        else if (propName == "OOXDrawing")
-        {
-            rProp.Value >>= diagramDrawing;
-            diagramDrawing[0]
-                >>= drawingDom; // if there is OOXDrawing property then set 
drawingDom here only.
-        }
-        else if (propName == "OOXDiagramDataRels")
-            rProp.Value >>= xDataRelSeq;
+    SdrObject* pObj = SdrObject::getSdrObjectFromXShape(rXShape);
+
+    if (nullptr != pObj && pObj->isDiagram())
+    {
+        const std::shared_ptr< svx::diagram::IDiagramHelper >& 
rIDiagramHelper(pObj->getDiagramHelper());
+
+        if (rIDiagramHelper)
+        {
+            rIDiagramHelper->getDomPropertyValue("OOXData").Value >>= dataDom;
+            rIDiagramHelper->getDomPropertyValue("OOXLayout").Value >>= 
layoutDom;
+            rIDiagramHelper->getDomPropertyValue("OOXStyle").Value >>= 
styleDom;
+            rIDiagramHelper->getDomPropertyValue("OOXColor").Value >>= 
colorDom;
+            rIDiagramHelper->getDomPropertyValue("OOXDrawing").Value >>= 
diagramDrawing;
+            if (diagramDrawing.hasElements())
+                // if there is OOXDrawing property then set drawingDom here 
only.
+                diagramDrawing[0] >>= drawingDom;
+            rIDiagramHelper->getDomPropertyValue("OOXDiagramDataRels").Value 
>>= xDataRelSeq;
+        }
     }
 
     // check that we have the 4 mandatory XDocuments
diff --git a/oox/source/ppt/pptshape.cxx b/oox/source/ppt/pptshape.cxx
index 98385c78e115..c71bdf7a3714 100644
--- a/oox/source/ppt/pptshape.cxx
+++ b/oox/source/ppt/pptshape.cxx
@@ -603,11 +603,6 @@ void PPTShape::addShape(
                 }
             }
 
-            if (meFrameType == FRAMETYPE_DIAGRAM)
-            {
-                keepDiagramCompatibilityInfo();
-            }
-
             // Support advanced DiagramHelper
             if (FRAMETYPE_DIAGRAM == meFrameType)
             {
diff --git a/oox/source/shape/ShapeContextHandler.cxx 
b/oox/source/shape/ShapeContextHandler.cxx
index 2a9e96af7189..e23175e32cd5 100644
--- a/oox/source/shape/ShapeContextHandler.cxx
+++ b/oox/source/shape/ShapeContextHandler.cxx
@@ -474,8 +474,6 @@ ShapeContextHandler::getShape()
                     oox::drawingml::ShapePtr pShapePtr = 
std::make_shared<Shape>( "com.sun.star.drawing.GroupShape" );
                     pShapePtr->setDiagramType();
                     mxShapeFilterBase->importFragment(new 
ShapeDrawingFragmentHandler(*mxShapeFilterBase, aFragmentPath, pShapePtr));
-                    pShapePtr->setDiagramDoms(mpShape->getDiagramDoms());
-                    pShapePtr->keepDiagramDrawing(*mxShapeFilterBase, 
aFragmentPath);
 
                     if (mpShape->getFontRefColorForNodes().isUsed())
                         applyFontRefColor(pShapePtr, 
mpShape->getFontRefColorForNodes());
@@ -484,6 +482,9 @@ ShapeContextHandler::getShape()
                     // to pShapePtr where the geometry is now constructed)
                     mpShape->migrateDiagramHelperToNewShape(pShapePtr);
 
+                    // use now migrated AdvancedDiagramHelper
+                    pShapePtr->keepDiagramDrawing(*mxShapeFilterBase, 
aFragmentPath);
+
                     if (!mpShape->getChildren().empty())
                     {
                         // first child is diagram background - we want to keep 
it, as drawingML fallback doesn't contain it
diff --git a/sc/source/filter/oox/drawingfragment.cxx 
b/sc/source/filter/oox/drawingfragment.cxx
index 258c87fe71a2..ec75f6544a4c 100644
--- a/sc/source/filter/oox/drawingfragment.cxx
+++ b/sc/source/filter/oox/drawingfragment.cxx
@@ -318,9 +318,13 @@ void DrawingFragment::onEndElement()
                     // initial diagram import produces a background shape with 
zero size and no
                     // diagram shapes at all. Here the size has been 
determined from the anchor and
                     // thus repeating the import of diagram.xml gives the 
diagram shapes.
-                    if (mxShape->getDiagramDoms().getLength() > 0
+                    //
+                    // I have checked that mpDiagramHelper at mxShape is *not* 
resetted here
+                    // which is crucial to keep that stuff working. Also added 
a isDiagram
+                    // method to avoid indirect test for Diagram using former 
getDiagramDoms()
+                    if (nullptr != mxShape->getDiagramHelper()
                         && mxShape->getChildren().size() == 1
-                        && mxShape->getExtDrawings().size() == 1)
+                        && mxShape->getExtDrawings().size() != 0)
                     {
                         mxShape->getChildren()[0]->setSize(mxShape->getSize());
                         OUString sFragmentPath(
diff --git a/sd/qa/unit/import-tests-smartart.cxx 
b/sd/qa/unit/import-tests-smartart.cxx
index 102eda38675e..96efa91201fc 100644
--- a/sd/qa/unit/import-tests-smartart.cxx
+++ b/sd/qa/unit/import-tests-smartart.cxx
@@ -22,6 +22,7 @@
 #include <svx/svdogrp.hxx>
 #include <comphelper/sequenceashashmap.hxx>
 #include <oox/drawingml/drawingmltypes.hxx>
+#include <svx/diagram/IDiagramHelper.hxx>
 
 using namespace ::com::sun::star;
 
@@ -1062,15 +1063,19 @@ CPPUNIT_TEST_FIXTURE(SdImportTestSmartArt, 
testInteropGrabBag)
     uno::Reference<drawing::XShape> xGroup(getShapeFromPage(0, 0), 
uno::UNO_QUERY);
     CPPUNIT_ASSERT(xGroup.is());
 
-    uno::Reference<beans::XPropertySet> xPropertySet(xGroup, 
uno::UNO_QUERY_THROW);
-    uno::Sequence<beans::PropertyValue> aGrabBagSeq;
-    xPropertySet->getPropertyValue(u"InteropGrabBag"_ustr) >>= aGrabBagSeq;
-    comphelper::SequenceAsHashMap aGrabBag(aGrabBagSeq);
-    CPPUNIT_ASSERT(aGrabBag.find(u"OOXData"_ustr) != aGrabBag.end());
-    CPPUNIT_ASSERT(aGrabBag.find(u"OOXLayout"_ustr) != aGrabBag.end());
-    CPPUNIT_ASSERT(aGrabBag.find(u"OOXStyle"_ustr) != aGrabBag.end());
-    CPPUNIT_ASSERT(aGrabBag.find(u"OOXColor"_ustr) != aGrabBag.end());
-    CPPUNIT_ASSERT(aGrabBag.find(u"OOXDrawing"_ustr) != aGrabBag.end());
+    SdrObject* pObj = SdrObject::getSdrObjectFromXShape(xGroup);
+    CPPUNIT_ASSERT(nullptr != pObj);
+    CPPUNIT_ASSERT(pObj->isDiagram());
+
+    const std::shared_ptr<svx::diagram::IDiagramHelper>& 
rIDiagramHelper(pObj->getDiagramHelper());
+    // const AdvancedDiagramHelper* 
pHelper(dynamic_cast<AdvancedDiagramHelper*>(rIDiagramHelper.get()));
+    CPPUNIT_ASSERT(rIDiagramHelper);
+
+    
CPPUNIT_ASSERT(rIDiagramHelper->getDomPropertyValue("OOXData").Value.hasValue());
+    
CPPUNIT_ASSERT(rIDiagramHelper->getDomPropertyValue("OOXLayout").Value.hasValue());
+    
CPPUNIT_ASSERT(rIDiagramHelper->getDomPropertyValue("OOXStyle").Value.hasValue());
+    
CPPUNIT_ASSERT(rIDiagramHelper->getDomPropertyValue("OOXColor").Value.hasValue());
+    
CPPUNIT_ASSERT(rIDiagramHelper->getDomPropertyValue("OOXDrawing").Value.hasValue());
 }
 
 CPPUNIT_TEST_FIXTURE(SdImportTestSmartArt, testBackground)
diff --git a/svx/qa/unit/svdraw.cxx b/svx/qa/unit/svdraw.cxx
index b1f26780aea6..16b1107b1842 100644
--- a/svx/qa/unit/svdraw.cxx
+++ b/svx/qa/unit/svdraw.cxx
@@ -34,6 +34,7 @@
 #include <svx/svdview.hxx>
 #include <svx/xlineit0.hxx>
 #include <svx/xlnstwit.hxx>
+#include <svx/svdogrp.hxx>
 #include <comphelper/propertyvalue.hxx>
 #include <sfx2/viewsh.hxx>
 #include <svl/itempool.hxx>
@@ -257,11 +258,20 @@ CPPUNIT_TEST_FIXTURE(SvdrawTest, testTextEditEmptyGrabBag)
     uno::Reference<drawing::XShape> xShape(xDrawPage->getByIndex(0), 
uno::UNO_QUERY);
     uno::Reference<drawing::XShapes> xGroupShape(xShape, uno::UNO_QUERY);
 
-    // get the GrabBag. After import is *has* to be set, check that
+    // get the GrabBag. After import there may be values, but none anymore
+    // starting with 'OOX.*', these are now at the DiagramHelper
     uno::Sequence<beans::PropertyValue> aGrabBag;
     uno::Reference<beans::XPropertySet> xGroupProps(xGroupShape, 
uno::UNO_QUERY);
     xGroupProps->getPropertyValue(u"InteropGrabBag"_ustr) >>= aGrabBag;
-    CPPUNIT_ASSERT(aGrabBag.hasElements());
+
+    if (aGrabBag.hasElements())
+    {
+        for (sal_Int32 i = 0; i < aGrabBag.getLength(); ++i)
+        {
+            if (aGrabBag[i].Name.startsWith("OOX"))
+                CPPUNIT_ASSERT(false);
+        }
+    }
 
     // get the 1st text shape (containing 'A'). There is a BGShape and an Arrow
     // in indices before
@@ -277,15 +287,14 @@ CPPUNIT_TEST_FIXTURE(SvdrawTest, testTextEditEmptyGrabBag)
     rEditView.InsertText(u"X"_ustr);
     pSdrView->SdrEndTextEdit();
 
-    // Then make sure that grab-bag is empty to avoid losing the new text.
+    // make sure the grab-bag is empty after change
     xGroupProps->getPropertyValue(u"InteropGrabBag"_ustr) >>= aGrabBag;
-
-    // Without the accompanying fix in place, this test would have failed with:
-    // assertion failed
-    // - Expression: !aGrabBag.hasElements()
-    // i.e. the grab-bag was still around after modifying the shape, and that 
grab-bag contained the
-    // old text.
     CPPUNIT_ASSERT(!aGrabBag.hasElements());
+
+    // get SdrObjGroup and check, it should still be a Diagram
+    SdrObjGroup* pGroup = 
dynamic_cast<SdrObjGroup*>(SdrObject::getSdrObjectFromXShape(xShape));
+    CPPUNIT_ASSERT(nullptr != pGroup);
+    CPPUNIT_ASSERT(pGroup->isDiagram());
 }
 
 CPPUNIT_TEST_FIXTURE(SvdrawTest, testRectangleObject)
diff --git a/svx/source/diagram/IDiagramHelper.cxx 
b/svx/source/diagram/IDiagramHelper.cxx
index 3153b98e7687..8e4f8f847bc2 100644
--- a/svx/source/diagram/IDiagramHelper.cxx
+++ b/svx/source/diagram/IDiagramHelper.cxx
@@ -421,8 +421,6 @@ void IDiagramHelper::disconnectFromSdrObjGroup()
 {
     if (nullptr != mpAssociatedSdrObjGroup)
     {
-        // if change was done, reset GrabBagItem to delete buffered 
DiagramData which is no longer valid
-        
mpAssociatedSdrObjGroup->SetGrabBagItem(uno::Any(uno::Sequence<beans::PropertyValue>()));
         auto const p = mpAssociatedSdrObjGroup;
         mpAssociatedSdrObjGroup = nullptr;
         p->mp_DiagramHelper.reset();
diff --git a/sw/qa/extras/ooxmlexport/ooxmlexport3.cxx 
b/sw/qa/extras/ooxmlexport/ooxmlexport3.cxx
index 852e7900f1dd..8f0bbf5cb521 100644
--- a/sw/qa/extras/ooxmlexport/ooxmlexport3.cxx
+++ b/sw/qa/extras/ooxmlexport/ooxmlexport3.cxx
@@ -23,6 +23,8 @@
 #include <ftninfo.hxx>
 #include <docsh.hxx>
 #include <unotxdoc.hxx>
+#include <svx/svdobj.hxx>
+#include <svx/diagram/IDiagramHelper.hxx>
 
 class Test : public SwModelTestBase
 {
@@ -466,57 +468,42 @@ DECLARE_OOXMLEXPORT_TEST(testSmartart, "smartart.docx")
     uno::Reference<container::XIndexAccess> xGroup(getShape(1), 
uno::UNO_QUERY);
     CPPUNIT_ASSERT_EQUAL(sal_Int32(1), xGroup->getCount()); // 1 rendered 
bitmap from the original shapes
 
-    uno::Reference<beans::XPropertySet> xGroupPropertySet(getShape(1), 
uno::UNO_QUERY);
-    xGroupPropertySet->getPropertyValue(u"InteropGrabBag"_ustr) >>= aGrabBag;
-    CPPUNIT_ASSERT(aGrabBag.hasElements()); // Grab Bag not empty
-
-    bool bData = false, bLayout = false, bQStyle = false, bColor = false, 
bDrawing = false;
-    for (beans::PropertyValue const& prop : aGrabBag)
-    {
-      if (prop.Name == "OOXData")
-      {
-        bData = true;
-        uno::Reference<xml::dom::XDocument> aDataDom;
-        CPPUNIT_ASSERT(prop.Value >>= aDataDom); // PropertyValue of proper 
type
-        CPPUNIT_ASSERT(aDataDom); // Reference not empty
-      }
-      else if (prop.Name == "OOXLayout")
-      {
-        bLayout = true;
-        uno::Reference<xml::dom::XDocument> aLayoutDom;
-        CPPUNIT_ASSERT(prop.Value >>= aLayoutDom); // PropertyValue of proper 
type
-        CPPUNIT_ASSERT(aLayoutDom); // Reference not empty
-      }
-      else if (prop.Name == "OOXStyle")
-      {
-        bQStyle = true;
-        uno::Reference<xml::dom::XDocument> aStyleDom;
-        CPPUNIT_ASSERT(prop.Value >>= aStyleDom); // PropertyValue of proper 
type
-        CPPUNIT_ASSERT(aStyleDom); // Reference not empty
-      }
-      else if (prop.Name == "OOXColor")
-      {
-        bColor = true;
-        uno::Reference<xml::dom::XDocument> aColorDom;
-        CPPUNIT_ASSERT(prop.Value >>= aColorDom); // PropertyValue of proper 
type
-        CPPUNIT_ASSERT(aColorDom); // Reference not empty
-      }
-      else if (prop.Name == "OOXDrawing")
-      {
-        bDrawing = true;
-        uno::Sequence< uno::Any > diagramDrawing;
-        uno::Reference<xml::dom::XDocument> aDrawingDom;
-        CPPUNIT_ASSERT(prop.Value >>= diagramDrawing);
-        CPPUNIT_ASSERT(diagramDrawing[0] >>= aDrawingDom); // PropertyValue of 
proper type
-        CPPUNIT_ASSERT(aDrawingDom); // Reference not empty
-      }
-    }
-    // Grab Bag has all the expected elements:
-    CPPUNIT_ASSERT(bData);
-    CPPUNIT_ASSERT(bLayout);
-    CPPUNIT_ASSERT(bQStyle);
-    CPPUNIT_ASSERT(bColor);
-    CPPUNIT_ASSERT(bDrawing);
+    SdrObject* pObj = SdrObject::getSdrObjectFromXShape(xGroup);
+    CPPUNIT_ASSERT(nullptr != pObj);
+    CPPUNIT_ASSERT(pObj->isDiagram());
+
+    const std::shared_ptr< svx::diagram::IDiagramHelper >& 
rIDiagramHelper(pObj->getDiagramHelper());
+    CPPUNIT_ASSERT(rIDiagramHelper);
+
+    beans::PropertyValue aPropVal;
+    uno::Reference<xml::dom::XDocument> aDomTree;
+
+    aPropVal = rIDiagramHelper->getDomPropertyValue("OOXData");
+    CPPUNIT_ASSERT(aPropVal.Value.hasValue());
+    CPPUNIT_ASSERT(aPropVal.Value >>= aDomTree); // PropertyValue of proper 
type
+    CPPUNIT_ASSERT(aDomTree); // Reference not empty
+
+    aPropVal = rIDiagramHelper->getDomPropertyValue("OOXLayout");
+    CPPUNIT_ASSERT(aPropVal.Value.hasValue());
+    CPPUNIT_ASSERT(aPropVal.Value >>= aDomTree); // PropertyValue of proper 
type
+    CPPUNIT_ASSERT(aDomTree); // Reference not empty
+
+    aPropVal = rIDiagramHelper->getDomPropertyValue("OOXStyle");
+    CPPUNIT_ASSERT(aPropVal.Value.hasValue());
+    CPPUNIT_ASSERT(aPropVal.Value >>= aDomTree); // PropertyValue of proper 
type
+    CPPUNIT_ASSERT(aDomTree); // Reference not empty
+
+    aPropVal = rIDiagramHelper->getDomPropertyValue("OOXColor");
+    CPPUNIT_ASSERT(aPropVal.Value.hasValue());
+    CPPUNIT_ASSERT(aPropVal.Value >>= aDomTree); // PropertyValue of proper 
type
+    CPPUNIT_ASSERT(aDomTree); // Reference not empty
+
+    aPropVal = rIDiagramHelper->getDomPropertyValue("OOXDrawing");
+    CPPUNIT_ASSERT(aPropVal.Value.hasValue());
+    uno::Sequence< uno::Any > diagramDrawing;
+    CPPUNIT_ASSERT(aPropVal.Value >>= diagramDrawing);
+    CPPUNIT_ASSERT(diagramDrawing[0] >>= aDomTree); // PropertyValue of proper 
type
+    CPPUNIT_ASSERT(aDomTree); // Reference not empty
 
     uno::Reference<beans::XPropertySet> xPropertySet(xGroup->getByIndex(0), 
uno::UNO_QUERY);
     OUString nValue;

Reply via email to