diff options
author | Armin Le Grand (Allotropia) <Armin.Le.Grand@me.com> | 2022-03-04 16:51:07 +0100 |
---|---|---|
committer | Armin Le Grand <Armin.Le.Grand@me.com> | 2022-03-04 22:10:10 +0100 |
commit | 9c526b557e264280cb0c9da704245494f5ec5af3 (patch) | |
tree | 2ea8393b8ea5a7e24088b116320fb9bfaeb1f136 /oox | |
parent | 35428625b70829ba56da99fafe205b24b0018ace (diff) |
Advanced Diagram support: Allow reLayout without keeping oox::Shape
Goal is to minimize dependencies on oox classes. For that pupose
I redesigned the Diagram class to work without remembering
an oox::Shape at all. For reLayout, a new temporary one is created
and used. That was a bit tricky, I needed to find out what
data at the oox::Shape is needed to sucessfully do that with
the not-originally-imported one.
Another necessary change was to move the DiagramFontHeights
adapting mechanism away from oox::Shape, too. It fits better
to Diagram class. That way it can also be used for reLayout
and the oox::Shape gets a little bit smaller, too.
This opens the path to move needed Mode-Data Diagam core
claasses to other libs where changing/im/exPorting them will
be possible.
Change-Id: I40bc4b190d2abc797f5c56f9e476d22155d21422
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/131004
Tested-by: Jenkins
Reviewed-by: Armin Le Grand <Armin.Le.Grand@me.com>
Diffstat (limited to 'oox')
-rw-r--r-- | oox/source/drawingml/diagram/diagram.cxx | 54 | ||||
-rw-r--r-- | oox/source/drawingml/diagram/diagram.hxx | 10 | ||||
-rw-r--r-- | oox/source/drawingml/diagram/diagramhelper.cxx | 87 | ||||
-rw-r--r-- | oox/source/drawingml/diagram/diagramhelper.hxx | 9 | ||||
-rw-r--r-- | oox/source/drawingml/diagram/diagramlayoutatoms.cxx | 4 | ||||
-rw-r--r-- | oox/source/drawingml/shape.cxx | 44 | ||||
-rw-r--r-- | oox/source/ppt/pptshape.cxx | 21 |
7 files changed, 106 insertions, 123 deletions
diff --git a/oox/source/drawingml/diagram/diagram.cxx b/oox/source/drawingml/diagram/diagram.cxx index 6c6578ae4067..481e56adec3c 100644 --- a/oox/source/drawingml/diagram/diagram.cxx +++ b/oox/source/drawingml/diagram/diagram.cxx @@ -137,8 +137,8 @@ void Diagram::addTo( const ShapePtr & pParentShape ) aChildren.insert(aChildren.begin(), pBackground); } -Diagram::Diagram(const ShapePtr& pShape) - : mpShape(pShape) +Diagram::Diagram() +: maDiagramFontHeights() { } @@ -168,9 +168,48 @@ uno::Sequence<beans::PropertyValue> Diagram::getDomsAsPropertyValues() const return aValue; } -void Diagram::newTargetShape(ShapePtr& pTarget) +using ShapePairs + = std::map<std::shared_ptr<drawingml::Shape>, css::uno::Reference<css::drawing::XShape>>; + +void Diagram::syncDiagramFontHeights() { - mpShape = pTarget; + // Each name represents a group of shapes, for which the font height should have the same + // scaling. + for (const auto& rNameAndPairs : maDiagramFontHeights) + { + // Find out the minimum scale within this group. + const ShapePairs& rShapePairs = rNameAndPairs.second; + sal_Int16 nMinScale = 100; + for (const auto& rShapePair : rShapePairs) + { + uno::Reference<beans::XPropertySet> xPropertySet(rShapePair.second, uno::UNO_QUERY); + if (xPropertySet.is()) + { + sal_Int16 nTextFitToSizeScale = 0; + xPropertySet->getPropertyValue("TextFitToSizeScale") >>= nTextFitToSizeScale; + if (nTextFitToSizeScale > 0 && nTextFitToSizeScale < nMinScale) + { + nMinScale = nTextFitToSizeScale; + } + } + } + + // Set that minimum scale for all members of the group. + if (nMinScale < 100) + { + for (const auto& rShapePair : rShapePairs) + { + uno::Reference<beans::XPropertySet> xPropertySet(rShapePair.second, uno::UNO_QUERY); + if (xPropertySet.is()) + { + xPropertySet->setPropertyValue("TextFitToSizeScale", uno::makeAny(nMinScale)); + } + } + } + } + + // no longer needed after processing + maDiagramFontHeights.clear(); } static uno::Reference<xml::dom::XDocument> loadFragment( @@ -257,7 +296,7 @@ void loadDiagram( ShapePtr const & pShape, const OUString& rColorStylePath, const oox::core::Relations& rRelations ) { - DiagramPtr pDiagram = std::make_shared<Diagram>(pShape); + DiagramPtr pDiagram = std::make_shared<Diagram>(); DiagramDataPtr pData = std::make_shared<DiagramData>(); pDiagram->setData( pData ); @@ -265,6 +304,9 @@ void loadDiagram( ShapePtr const & pShape, DiagramLayoutPtr pLayout = std::make_shared<DiagramLayout>(*pDiagram); pDiagram->setLayout( pLayout ); + // set DiagramFontHeights at filter + rFilter.setDiagramFontHeights(&pDiagram->getDiagramFontHeights()); + // data if( !rDataModelPath.isEmpty() ) { @@ -379,7 +421,7 @@ void loadDiagram(ShapePtr const& pShape, const uno::Reference<xml::dom::XDocument>& colorDom, core::XmlFilterBase& rFilter) { - DiagramPtr pDiagram = std::make_shared<Diagram>(pShape); + DiagramPtr pDiagram = std::make_shared<Diagram>(); pDiagram->setData(pDiagramData); diff --git a/oox/source/drawingml/diagram/diagram.hxx b/oox/source/drawingml/diagram/diagram.hxx index 3b42a834951a..1897a8ccfd01 100644 --- a/oox/source/drawingml/diagram/diagram.hxx +++ b/oox/source/drawingml/diagram/diagram.hxx @@ -130,7 +130,7 @@ typedef std::map<OUString,DiagramColor> DiagramColorMap; class Diagram { public: - explicit Diagram(const ShapePtr& pShape); + explicit Diagram(); void setData( const DiagramDataPtr & pData ) { mpData = pData; } const DiagramDataPtr& getData() const @@ -149,11 +149,13 @@ public: void addTo( const ShapePtr & pShape ); css::uno::Sequence<css::beans::PropertyValue> getDomsAsPropertyValues() const; - ShapePtr getShape() const { return mpShape.lock(); } - void newTargetShape(ShapePtr& pTarget); + oox::core::NamedShapePairs& getDiagramFontHeights() { return maDiagramFontHeights; } + void syncDiagramFontHeights(); private: - WeakShapePtr mpShape; + // This contains groups of shapes: automatic font size is the same in each group. + oox::core::NamedShapePairs maDiagramFontHeights; + DiagramDataPtr mpData; DiagramLayoutPtr mpLayout; DiagramQStyleMap maStyles; diff --git a/oox/source/drawingml/diagram/diagramhelper.cxx b/oox/source/drawingml/diagram/diagramhelper.cxx index d67d67b13064..8b54ff4e8a0f 100644 --- a/oox/source/drawingml/diagram/diagramhelper.cxx +++ b/oox/source/drawingml/diagram/diagramhelper.cxx @@ -23,6 +23,7 @@ #include <basegfx/matrix/b2dhommatrix.hxx> #include <oox/shape/ShapeFilterBase.hxx> #include <oox/ppt/pptimport.hxx> +#include <drawingml/fillproperties.hxx> #include <svx/svdmodel.hxx> #include <comphelper/processfactory.hxx> @@ -37,10 +38,13 @@ bool AdvancedDiagramHelper::hasDiagramData() const AdvancedDiagramHelper::AdvancedDiagramHelper( const std::shared_ptr< Diagram >& rDiagramPtr, - const std::shared_ptr<::oox::drawingml::Theme>& rTheme) + const std::shared_ptr<::oox::drawingml::Theme>& rTheme, + Shape& rSourceShape) : IDiagramHelper() , mpDiagramPtr(rDiagramPtr) , mpThemePtr(rTheme) +, maImportSize(rSourceShape.getSize()) +, maImportPosition(rSourceShape.getPosition()) { } @@ -48,44 +52,32 @@ AdvancedDiagramHelper::~AdvancedDiagramHelper() { } -void AdvancedDiagramHelper::reLayout() +void AdvancedDiagramHelper::reLayout(SdrObjGroup& rTarget) { if(!mpDiagramPtr) { return; } - // Get the oox::Shape that represents the Diagram GraphicObject - const ShapePtr & pParentShape = mpDiagramPtr->getShape(); - - if(!pParentShape) - { - return; - } - - // Remove it's children which represent the oox::Shapes created by - // the layout process as preparation to re-creation. These should - // already be cleared, but make sure. - pParentShape->getChildren().clear(); - - // Re-create the oox::Shapes for the diagram content - mpDiagramPtr->addTo(pParentShape); - - // Access the GroupObject representing the SmartArt in DrawingLayer - SdrObjGroup* pAnchorObj(dynamic_cast<SdrObjGroup*>(SdrObject::getSdrObjectFromXShape(pParentShape->getXShape()))); - if(!pAnchorObj) - { - SAL_WARN("oox", "missing SdrObjGroup"); - return; - } - // Rescue/remember geometric transformation of existing Diagram basegfx::B2DHomMatrix aTransformation; basegfx::B2DPolyPolygon aPolyPolygon; - pAnchorObj->TRGetBaseGeometry(aTransformation, aPolyPolygon); + rTarget.TRGetBaseGeometry(aTransformation, aPolyPolygon); + + // create temporary oox::Shape as target. No longer needed is to keep/remember + // the original oox::Shape to do that. Use original Size and Pos frrom initial import + // to get the same layout(s) + oox::drawingml::ShapePtr pShapePtr = std::make_shared<Shape>( "com.sun.star.drawing.GroupShape" ); + pShapePtr->setDiagramType(); + pShapePtr->setSize(maImportSize); + pShapePtr->setPosition(maImportPosition); + pShapePtr->getFillProperties() = *mpDiagramPtr->getData()->getFillProperties(); + + // Re-create the oox::Shapes for the diagram content + mpDiagramPtr->addTo(pShapePtr); // Delete all existing shapes in that group to prepare re-creation - pAnchorObj->getChildrenOfSdrObject()->ClearSdrObjList(); + rTarget.getChildrenOfSdrObject()->ClearSdrObjList(); // For re-creation we need to use ::addShape functionality from the // oox import filter since currently Shape import is very tightly @@ -105,7 +97,7 @@ void AdvancedDiagramHelper::reLayout() // NOTE: The incarnation of import filter (ShapeFilterBase) is only // used for XShape creation, no xml snippets/data gets imported // here. XShape creation may be isolated in the future. - SdrModel& rModel(pAnchorObj->getSdrModelFromSdrObject()); + SdrModel& rModel(rTarget.getSdrModelFromSdrObject()); uno::Reference< uno::XInterface > const & rUnoModel(rModel.getUnoModel()); css::uno::Reference<css::uno::XComponentContext> xContext(comphelper::getProcessComponentContext()); rtl::Reference<oox::shape::ShapeFilterBase> xFilter(new oox::shape::ShapeFilterBase(xContext)); @@ -113,10 +105,13 @@ void AdvancedDiagramHelper::reLayout() css::uno::Reference< css::lang::XComponent > aComponentModel( rUnoModel, uno::UNO_QUERY ); xFilter->setTargetDocument(aComponentModel); + // set DiagramFontHeights + xFilter->setDiagramFontHeights(&mpDiagramPtr->getDiagramFontHeights()); + // Prepare the target for the to-be-created XShapes - uno::Reference<drawing::XShapes> xShapes(pParentShape->getXShape(), uno::UNO_QUERY_THROW); + uno::Reference<drawing::XShapes> xShapes(rTarget.getUnoShape(), uno::UNO_QUERY_THROW); - for (auto const& child : pParentShape->getChildren()) + for (auto const& child : pShapePtr->getChildren()) { // Create all sub-shapes. This will recursively create needed geometry using // filter-internal ::createShapes @@ -125,17 +120,14 @@ void AdvancedDiagramHelper::reLayout() xFilter->getCurrentTheme(), xShapes, aTransformation, - pParentShape->getFillProperties()); + pShapePtr->getFillProperties()); } // Re-apply remembered geometry - pAnchorObj->TRSetBaseGeometry(aTransformation, aPolyPolygon); + rTarget.TRSetBaseGeometry(aTransformation, aPolyPolygon); - // Delete oox::Shapes that represented the content of the - // diagram. These were needed for creating the XShapes/SdrObjects - // (created by ::addTo above) but are no longer needed, so free - // the memory - pParentShape->getChildren().clear(); + // sync FontHeights + mpDiagramPtr->syncDiagramFontHeights(); } OUString AdvancedDiagramHelper::getString() const @@ -185,28 +177,11 @@ void AdvancedDiagramHelper::doAnchor(SdrObjGroup& rTarget) return; } - const ShapePtr& pParentShape(mpDiagramPtr->getShape()); - - if(pParentShape) - { - // The oox::Shapes children are not needed for holding the original data, - // free that memory - pParentShape->getChildren().clear(); - } + mpDiagramPtr->syncDiagramFontHeights(); anchorToSdrObjGroup(rTarget); } -void AdvancedDiagramHelper::newTargetShape(ShapePtr& pTarget) -{ - if(!mpDiagramPtr) - { - return; - } - - mpDiagramPtr->newTargetShape(pTarget); -} - } /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/oox/source/drawingml/diagram/diagramhelper.hxx b/oox/source/drawingml/diagram/diagramhelper.hxx index 9c4d4cfadb37..5f5632c3338a 100644 --- a/oox/source/drawingml/diagram/diagramhelper.hxx +++ b/oox/source/drawingml/diagram/diagramhelper.hxx @@ -46,16 +46,20 @@ class AdvancedDiagramHelper final : public IDiagramHelper const std::shared_ptr< Diagram > mpDiagramPtr; const std::shared_ptr<::oox::drawingml::Theme> mpThemePtr; + css::awt::Size maImportSize; + css::awt::Point maImportPosition; + bool hasDiagramData() const; public: AdvancedDiagramHelper( const std::shared_ptr< Diagram >& rDiagramPtr, - const std::shared_ptr<::oox::drawingml::Theme>& rTheme); + const std::shared_ptr<::oox::drawingml::Theme>& rTheme, + Shape& rSourceShape); virtual ~AdvancedDiagramHelper(); // re-create XShapes - virtual void reLayout() override; + virtual void reLayout(SdrObjGroup& rTarget) override; // get text representation of data tree virtual OUString getString() const override; @@ -70,7 +74,6 @@ public: virtual bool removeNode(const OUString& rNodeId) override; void doAnchor(SdrObjGroup& rTarget); - void newTargetShape(ShapePtr& pTarget); }; } diff --git a/oox/source/drawingml/diagram/diagramlayoutatoms.cxx b/oox/source/drawingml/diagram/diagramlayoutatoms.cxx index f5191b54408a..a91925b32376 100644 --- a/oox/source/drawingml/diagram/diagramlayoutatoms.cxx +++ b/oox/source/drawingml/diagram/diagramlayoutatoms.cxx @@ -701,7 +701,7 @@ void CompositeAlg::layoutShapeChildren(AlgAtom& rAlg, const ShapePtr& rShape, nVertMax = std::max(aPos.Y + aSize.Height, nVertMax); NamedShapePairs& rDiagramFontHeights - = rAlg.getLayoutNode().getDiagram().getShape()->getDiagramFontHeights(); + = rAlg.getLayoutNode().getDiagram().getDiagramFontHeights(); auto it = rDiagramFontHeights.find(aCurrShape->getInternalName()); if (it != rDiagramFontHeights.end()) { @@ -1421,7 +1421,7 @@ void AlgAtom::layoutShape(const ShapePtr& rShape, const std::vector<Constraint>& && rConstraint.mnOperator == XML_equ) { NamedShapePairs& rDiagramFontHeights - = getLayoutNode().getDiagram().getShape()->getDiagramFontHeights(); + = getLayoutNode().getDiagram().getDiagramFontHeights(); auto it = rDiagramFontHeights.find(rConstraint.msForName); if (it == rDiagramFontHeights.end()) { diff --git a/oox/source/drawingml/shape.cxx b/oox/source/drawingml/shape.cxx index 243a172e6e75..d0ab82501c71 100644 --- a/oox/source/drawingml/shape.cxx +++ b/oox/source/drawingml/shape.cxx @@ -191,7 +191,6 @@ Shape::Shape( const ShapePtr& pSourceShape ) , mnDataNodeType(pSourceShape->mnDataNodeType) , mfAspectRatio(pSourceShape->mfAspectRatio) , mbUseBgFill(pSourceShape->mbUseBgFill) -, maDiagramFontHeights(pSourceShape->maDiagramFontHeights) , mpDiagramHelper( nullptr ) {} @@ -209,7 +208,7 @@ void Shape::prepareDiagramHelper( // Prepare Diagam data collecting for this Shape if( nullptr == mpDiagramHelper && FRAMETYPE_DIAGRAM == meFrameType ) { - mpDiagramHelper = new AdvancedDiagramHelper(rDiagramPtr, rTheme); + mpDiagramHelper = new AdvancedDiagramHelper(rDiagramPtr, rTheme, *this); } } @@ -259,9 +258,6 @@ void Shape::migrateDiagramHelperToNewShape(ShapePtr& pTarget) pTarget->mpDiagramHelper = nullptr; } - // DiagramHelper has references to this, these need to be replaced - static_cast<AdvancedDiagramHelper*>(mpDiagramHelper)->newTargetShape(pTarget); - // exchange and reset to nullptr pTarget->mpDiagramHelper = mpDiagramHelper; mpDiagramHelper = nullptr; @@ -1857,44 +1853,6 @@ void Shape::keepDiagramCompatibilityInfo() } } -void Shape::syncDiagramFontHeights() -{ - // Each name represents a group of shapes, for which the font height should have the same - // scaling. - for (const auto& rNameAndPairs : maDiagramFontHeights) - { - // Find out the minimum scale within this group. - const ShapePairs& rShapePairs = rNameAndPairs.second; - sal_Int16 nMinScale = 100; - for (const auto& rShapePair : rShapePairs) - { - uno::Reference<beans::XPropertySet> xPropertySet(rShapePair.second, uno::UNO_QUERY); - if (xPropertySet.is()) - { - sal_Int16 nTextFitToSizeScale = 0; - xPropertySet->getPropertyValue("TextFitToSizeScale") >>= nTextFitToSizeScale; - if (nTextFitToSizeScale > 0 && nTextFitToSizeScale < nMinScale) - { - nMinScale = nTextFitToSizeScale; - } - } - } - - // Set that minimum scale for all members of the group. - if (nMinScale < 100) - { - for (const auto& rShapePair : rShapePairs) - { - uno::Reference<beans::XPropertySet> xPropertySet(rShapePair.second, uno::UNO_QUERY); - if (xPropertySet.is()) - { - xPropertySet->setPropertyValue("TextFitToSizeScale", uno::makeAny(nMinScale)); - } - } - } - } -} - void Shape::convertSmartArtToMetafile(XmlFilterBase const & rFilterBase) { try diff --git a/oox/source/ppt/pptshape.cxx b/oox/source/ppt/pptshape.cxx index d8ab4dfef7ca..581b85db0e0a 100644 --- a/oox/source/ppt/pptshape.cxx +++ b/oox/source/ppt/pptshape.cxx @@ -538,15 +538,19 @@ void PPTShape::addShape( Reference<XShapes> xShapes(xShape, UNO_QUERY); if (xShapes.is()) { - if (meFrameType == FRAMETYPE_DIAGRAM) - { - rFilterBase.setDiagramFontHeights(&getDiagramFontHeights()); - } - addChildren( rFilterBase, *this, pTheme, xShapes, pShapeMap, aTransformation ); - if (meFrameType == FRAMETYPE_DIAGRAM) - { + // tempoarily remember setting + NamedShapePairs* pDiagramFontHeights(rFilterBase.getDiagramFontHeights()); + + // for shapes unequal to FRAMETYPE_DIAGRAM do + // disable DiagramFontHeights recording + if (meFrameType != FRAMETYPE_DIAGRAM) rFilterBase.setDiagramFontHeights(nullptr); - } + + addChildren( rFilterBase, *this, pTheme, xShapes, pShapeMap, aTransformation ); + + // restore remembered setting + rFilterBase.setDiagramFontHeights(pDiagramFontHeights); + for (size_t i = 0; i < this->getChildren().size(); i++) { this->getChildren()[i]->getShapeProperties().getProperty(PROP_URL) >>= sURL; @@ -561,7 +565,6 @@ void PPTShape::addShape( if (meFrameType == FRAMETYPE_DIAGRAM) { keepDiagramCompatibilityInfo(); - syncDiagramFontHeights(); } // Support advanced DiagramHelper |