include/oox/drawingml/shape.hxx | 5 + include/svx/diagram/IDiagramHelper.hxx | 10 +++ oox/source/drawingml/diagram/diagram.cxx | 75 +++++++++++++------------ oox/source/drawingml/diagram/diagram.hxx | 2 oox/source/drawingml/diagram/diagramhelper.cxx | 28 +++++++-- oox/source/drawingml/diagram/diagramhelper.hxx | 3 - oox/source/drawingml/shape.cxx | 6 +- svx/source/diagram/IDiagramHelper.cxx | 3 - 8 files changed, 83 insertions(+), 49 deletions(-)
New commits: commit 97265258cc102def076f057857cef3022325ab8f Author: Armin Le Grand (allotropia) <armin.le.grand.ext...@allotropia.de> AuthorDate: Wed May 29 16:42:53 2024 +0200 Commit: Armin Le Grand <armin.le.gr...@me.com> CommitDate: Sat Jun 1 19:05:12 2024 +0200 Advanced Diagram support: Load fill DiagramModel In the case the input file does have a graphical representation of the Diagram as image file, the DiagramModel was not fully loaded. For being able to edit the Diagram in the future it is necessary to re-create the geometry, thus a full model is needed. Needed to know at recreation if this is the first time the geometry gets self-created using the layout/creation mechanism to decide if to apply the style or use the saved/reapplyable data from secure/restoreDataFromShapeToModelAfterDiagramImport mechanism, added that. Change-Id: Icb7590306ab59728e83b800b8637333e0d372de5 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/168223 Reviewed-by: Armin Le Grand <armin.le.gr...@me.com> Tested-by: Jenkins diff --git a/include/oox/drawingml/shape.hxx b/include/oox/drawingml/shape.hxx index 6937e9057b48..894d42ca89c3 100644 --- a/include/oox/drawingml/shape.hxx +++ b/include/oox/drawingml/shape.hxx @@ -266,7 +266,10 @@ public: // Allows preparation of a local Diagram helper && propagate an eventually // existing one to the data holder object later - SAL_DLLPRIVATE void prepareDiagramHelper(const std::shared_ptr< Diagram >& rDiagramPtr, const std::shared_ptr<::oox::drawingml::Theme>& rTheme); + SAL_DLLPRIVATE void prepareDiagramHelper( + const std::shared_ptr< Diagram >& rDiagramPtr, + const std::shared_ptr<::oox::drawingml::Theme>& rTheme, + bool bSelfCreated); SAL_DLLPRIVATE void propagateDiagramHelper(); // for Writer it is necessary to migrate an existing helper to a new Shape diff --git a/include/svx/diagram/IDiagramHelper.hxx b/include/svx/diagram/IDiagramHelper.hxx index e93056f70049..67142c26e2a7 100644 --- a/include/svx/diagram/IDiagramHelper.hxx +++ b/include/svx/diagram/IDiagramHelper.hxx @@ -80,11 +80,15 @@ private: // a newly created oox::drawingml::Theme object bool mbForceThemePtrRecreation; // false + // if true, content was self-created using addTo/addShape + // and the layouting stuff + bool mbSelfCreated; + protected: void anchorToSdrObjGroup(SdrObjGroup& rTarget); public: - IDiagramHelper(); + IDiagramHelper(bool bSelfCreated); virtual ~IDiagramHelper(); // re-create XShapes @@ -111,6 +115,10 @@ public: bool UseDiagramModelData() const { return mbUseDiagramModelData; } bool ForceThemePtrRecreation() const { return mbForceThemePtrRecreation; }; + // get/set SelfCreated flag + bool isSelfCreated() const { return mbSelfCreated; } + void setSelfCreated() { mbSelfCreated = true; } + static void AddAdditionalVisualization(const SdrObjGroup& rTarget, SdrHdlList& rHdlList); }; diff --git a/oox/source/drawingml/diagram/diagram.cxx b/oox/source/drawingml/diagram/diagram.cxx index a415cd33ffd8..ccff952e0576 100644 --- a/oox/source/drawingml/diagram/diagram.cxx +++ b/oox/source/drawingml/diagram/diagram.cxx @@ -104,7 +104,7 @@ static void removeUnneededGroupShapes(const ShapePtr& pShape) } -void Diagram::addTo( const ShapePtr & pParentShape ) +void Diagram::addTo( const ShapePtr & pParentShape, bool bCreate ) { if (pParentShape->getSize().Width == 0 || pParentShape->getSize().Height == 0) SAL_WARN("oox.drawingml", "Diagram cannot be correctly laid out. Size: " @@ -113,7 +113,7 @@ void Diagram::addTo( const ShapePtr & pParentShape ) pParentShape->setChildSize(pParentShape->getSize()); const svx::diagram::Point* pRootPoint = mpData->getRootPoint(); - if (mpLayout->getNode() && pRootPoint) + if (bCreate && mpLayout->getNode() && pRootPoint) { // create Shape hierarchy ShapeCreationVisitor aCreationVisitor(*this, pRootPoint, pParentShape); @@ -357,41 +357,38 @@ void loadDiagram( ShapePtr const & pShape, } } - // extLst is present, lets bet on that and ignore the rest of the data from here - if( pShape->getExtDrawings().empty() ) + // Layout: always import to allow editing in the future. It's needed for + // AdvancedDiagramHelper::reLayout to re-create the oox::Shape(s) for the + // model. Without importing these the diagram model will be not complete. + // NOTE: This also adds the DomMaps to rMainDomMap, so the lines + // DiagramDomMap& rMainDomMap = pDiagram->getDomMap(); + // rMainDomMap[u"OOXLayout"_ustr] = loadFragment(rFilter,rLayoutPath); + // rMainDomMap[u"OOXStyle"_ustr] = loadFragment(rFilter,rQStylePath); + // which were used before if !pShape->getExtDrawings().empty() are not + // needed + if (!rLayoutPath.isEmpty()) { - // layout - if( !rLayoutPath.isEmpty() ) - { - rtl::Reference< core::FragmentHandler > xRefLayout( - new DiagramLayoutFragmentHandler( rFilter, rLayoutPath, pLayout )); - - importFragment(rFilter, - loadFragment(rFilter,xRefLayout), - u"OOXLayout"_ustr, - pDiagram, - xRefLayout); - } + rtl::Reference< core::FragmentHandler > xRefLayout( + new DiagramLayoutFragmentHandler( rFilter, rLayoutPath, pLayout )); - // style - if( !rQStylePath.isEmpty() ) - { - rtl::Reference< core::FragmentHandler > xRefQStyle( - new DiagramQStylesFragmentHandler( rFilter, rQStylePath, pDiagram->getStyles() )); - - importFragment(rFilter, - loadFragment(rFilter,xRefQStyle), - u"OOXStyle"_ustr, - pDiagram, - xRefQStyle); - } + importFragment(rFilter, + loadFragment(rFilter,xRefLayout), + u"OOXLayout"_ustr, + pDiagram, + xRefLayout); } - else + + // Style: same as for Layout (above) + if( !rQStylePath.isEmpty() ) { - // We still want to add the XDocuments to the DiagramDomMap - DiagramDomMap& rMainDomMap = pDiagram->getDomMap(); - rMainDomMap[u"OOXLayout"_ustr] = loadFragment(rFilter,rLayoutPath); - rMainDomMap[u"OOXStyle"_ustr] = loadFragment(rFilter,rQStylePath); + rtl::Reference< core::FragmentHandler > xRefQStyle( + new DiagramQStylesFragmentHandler( rFilter, rQStylePath, pDiagram->getStyles() )); + + importFragment(rFilter, + loadFragment(rFilter,xRefQStyle), + u"OOXStyle"_ustr, + pDiagram, + xRefQStyle); } // colors @@ -423,7 +420,15 @@ void loadDiagram( ShapePtr const & pShape, pData->buildDiagramDataModel(false); // diagram loaded. now lump together & attach to shape - pDiagram->addTo(pShape); + // create own geometry if extLst is not present (no geometric + // representation is available in file). This will - if false - + // just create the BackgroundShape. + // NOTE: Need to use pShape->getExtDrawings() here, this is the + // already *filtered* version, see usage of DiagramShapeCounter + // above. Moving to local bool, there might more coditions show + // 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 @@ -433,7 +438,7 @@ void loadDiagram( ShapePtr const & pShape, pData->setThemeDocument(aTheme->getFragment()); //getTempFile()); // Prepare support for the advanced DiagramHelper using Diagram & Theme data - pShape->prepareDiagramHelper(pDiagram, rFilter.getCurrentThemePtr()); + pShape->prepareDiagramHelper(pDiagram, rFilter.getCurrentThemePtr(), bCreate); } catch (...) { diff --git a/oox/source/drawingml/diagram/diagram.hxx b/oox/source/drawingml/diagram/diagram.hxx index f58c762f6a1a..5eb82069b91b 100644 --- a/oox/source/drawingml/diagram/diagram.hxx +++ b/oox/source/drawingml/diagram/diagram.hxx @@ -144,7 +144,7 @@ public: const DiagramColorMap& getColors() const { return maColors; } DiagramDomMap & getDomMap() { return maMainDomMap; } css::uno::Sequence< css::uno::Sequence< css::uno::Any > > & getDataRelsMap() { return maDataRelsMap; } - void addTo( const ShapePtr & pShape ); + void addTo( const ShapePtr & pShape, bool bCreate ); css::uno::Sequence<css::beans::PropertyValue> getDomsAsPropertyValues() const; oox::core::NamedShapePairs& getDiagramFontHeights() { return maDiagramFontHeights; } diff --git a/oox/source/drawingml/diagram/diagramhelper.cxx b/oox/source/drawingml/diagram/diagramhelper.cxx index 3b25951bb910..37fe97e3cbd7 100644 --- a/oox/source/drawingml/diagram/diagramhelper.cxx +++ b/oox/source/drawingml/diagram/diagramhelper.cxx @@ -42,8 +42,9 @@ bool AdvancedDiagramHelper::hasDiagramData() const AdvancedDiagramHelper::AdvancedDiagramHelper( std::shared_ptr< Diagram > xDiagramPtr, std::shared_ptr<::oox::drawingml::Theme> xTheme, - css::awt::Size aImportSize) -: svx::diagram::IDiagramHelper() + css::awt::Size aImportSize, + bool bSelfCreated) +: svx::diagram::IDiagramHelper(bSelfCreated) , mpDiagramPtr(std::move(xDiagramPtr)) , mpThemePtr(std::move(xTheme)) , maImportSize(aImportSize) @@ -74,7 +75,7 @@ void AdvancedDiagramHelper::reLayout(SdrObjGroup& rTarget) pShapePtr->setSize(maImportSize); // Re-create the oox::Shapes for the diagram content - mpDiagramPtr->addTo(pShapePtr); + mpDiagramPtr->addTo(pShapePtr, true); // Delete all existing shapes in that group to prepare re-creation rTarget.getChildrenOfSdrObject()->ClearSdrObjList(); @@ -104,7 +105,8 @@ void AdvancedDiagramHelper::reLayout(SdrObjGroup& rTarget) // set oox::Theme at Filter. All LineStyle/FillStyle/Colors/Attributes // will be taken from there - if(UseDiagramThemeData()) + // also need to use theme when geometry gets self-created the first time + if(UseDiagramThemeData() || !isSelfCreated()) xFilter->setCurrentTheme(getOrCreateThemePtr(xFilter)); css::uno::Reference< css::lang::XComponent > aComponentModel( rUnoModel, uno::UNO_QUERY ); @@ -131,9 +133,21 @@ void AdvancedDiagramHelper::reLayout(SdrObjGroup& rTarget) // sync FontHeights mpDiagramPtr->syncDiagramFontHeights(); - // re-apply secured data from ModelData - if(UseDiagramModelData()) - mpDiagramPtr->getData()->restoreDataFromShapeToModelAfterDiagramImport(*pShapePtr); + if (isSelfCreated()) + { + // already secured at import, re-apply secured data from ModelData + if(UseDiagramModelData()) + mpDiagramPtr->getData()->restoreDataFromShapeToModelAfterDiagramImport(*pShapePtr); + } + else + { + // secure data from ModelData for the 1st time for shapes except BackgroundShape + if(UseDiagramModelData()) + mpDiagramPtr->getData()->secureDataFromShapeToModelAfterDiagramImport(*pShapePtr); + + // note that shapes are now self-created + setSelfCreated(); + } // Re-apply remembered geometry rTarget.TRSetBaseGeometry(aTransformation, aPolyPolygon); diff --git a/oox/source/drawingml/diagram/diagramhelper.hxx b/oox/source/drawingml/diagram/diagramhelper.hxx index 626d40382d7e..86a83926ec25 100644 --- a/oox/source/drawingml/diagram/diagramhelper.hxx +++ b/oox/source/drawingml/diagram/diagramhelper.hxx @@ -60,7 +60,8 @@ public: AdvancedDiagramHelper( std::shared_ptr< Diagram > xDiagramPtr, std::shared_ptr<::oox::drawingml::Theme> xTheme, - css::awt::Size aImportSize); + css::awt::Size aImportSize, + bool bSelfCreated); virtual ~AdvancedDiagramHelper(); // re-create XShapes diff --git a/oox/source/drawingml/shape.cxx b/oox/source/drawingml/shape.cxx index a32553c767a5..81abf10cf108 100644 --- a/oox/source/drawingml/shape.cxx +++ b/oox/source/drawingml/shape.cxx @@ -247,7 +247,8 @@ Shape::~Shape() void Shape::prepareDiagramHelper( const std::shared_ptr< Diagram >& rDiagramPtr, - const std::shared_ptr<::oox::drawingml::Theme>& rTheme) + const std::shared_ptr<::oox::drawingml::Theme>& rTheme, + bool bSelfCreated) { // Prepare Diagram data collecting for this Shape if( nullptr == mpDiagramHelper && FRAMETYPE_DIAGRAM == meFrameType ) @@ -255,7 +256,8 @@ void Shape::prepareDiagramHelper( mpDiagramHelper = new AdvancedDiagramHelper( rDiagramPtr, rTheme, - getSize()); + getSize(), + bSelfCreated); } } diff --git a/svx/source/diagram/IDiagramHelper.cxx b/svx/source/diagram/IDiagramHelper.cxx index d2ce6c4f6a31..5f17433a6181 100644 --- a/svx/source/diagram/IDiagramHelper.cxx +++ b/svx/source/diagram/IDiagramHelper.cxx @@ -403,10 +403,11 @@ DiagramFrameHdl::DiagramFrameHdl(const basegfx::B2DHomMatrix& rTransformation) { } -IDiagramHelper::IDiagramHelper() +IDiagramHelper::IDiagramHelper(bool bSelfCreated) : mbUseDiagramThemeData(false) , mbUseDiagramModelData(true) , mbForceThemePtrRecreation(false) +, mbSelfCreated(bSelfCreated) { }