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;
