diff options
author | Grzegorz Araminowicz <grzegorz.araminowicz@collabora.com> | 2019-06-14 15:12:33 +0200 |
---|---|---|
committer | Grzegorz Araminowicz <grzegorz.araminowicz@collabora.com> | 2019-06-17 12:07:29 +0200 |
commit | 596a03b65e1b870be671ea1a44f4fba9fc66e4ae (patch) | |
tree | 4464ac7eff2804bf0bad82802304c2864a68b13e /oox | |
parent | 641e002743ddb74fff35a2c7942ac8d90cc1a9cd (diff) |
SmartArt: support multiple levels of shapes in LayoutNodes
it is needed for recurrent ForEach node, so that shapes on different levels
are divided and can be layouted separately
Change-Id: Iefbc82925078fe2346858748259680fa8ea252d6
Reviewed-on: https://gerrit.libreoffice.org/74043
Tested-by: Jenkins
Reviewed-by: Grzegorz Araminowicz <grzegorz.araminowicz@collabora.com>
Diffstat (limited to 'oox')
4 files changed, 38 insertions, 17 deletions
diff --git a/oox/source/drawingml/diagram/diagramlayoutatoms.cxx b/oox/source/drawingml/diagram/diagramlayoutatoms.cxx index 2c612233251d..f9c443c5d626 100644 --- a/oox/source/drawingml/diagram/diagramlayoutatoms.cxx +++ b/oox/source/drawingml/diagram/diagramlayoutatoms.cxx @@ -109,12 +109,16 @@ bool containsDataNodeType(const oox::drawingml::ShapePtr& pShape, sal_Int32 nTyp */ void calculateHierChildOffsetScale(const oox::drawingml::ShapePtr& pShape, const oox::drawingml::LayoutNode* pParent, sal_Int32& rXOffset, - double& rWidthScale) + double& rWidthScale, sal_Int32 nLevel) { if (!pParent) return; - const std::vector<oox::drawingml::ShapePtr>& rParents = pParent->getNodeShapes(); + auto pShapes = pParent->getNodeShapes().find(nLevel - 1); + if (pShapes == pParent->getNodeShapes().end()) + return; + + const std::vector<oox::drawingml::ShapePtr>& rParents = pShapes->second; for (size_t nParent = 0; nParent < rParents.size(); ++nParent) { const oox::drawingml::ShapePtr& pParentShape = rParents[nParent]; @@ -469,7 +473,8 @@ sal_Int32 AlgAtom::getConnectorType() } void AlgAtom::layoutShape( const ShapePtr& rShape, - const std::vector<Constraint>& rConstraints ) + const std::vector<Constraint>& rConstraints, + sal_Int32 nShapeLevel ) { switch(mnType) { @@ -752,7 +757,7 @@ void AlgAtom::layoutShape( const ShapePtr& rShape, sal_Int32 nXOffset = 0; double fWidthScale = 1.0; if (mnType == XML_hierChild) - calculateHierChildOffsetScale(rShape, getLayoutNode().getParentLayoutNode(), nXOffset, fWidthScale); + calculateHierChildOffsetScale(rShape, getLayoutNode().getParentLayoutNode(), nXOffset, fWidthScale, nShapeLevel); awt::Size aChildSize = rShape->getSize(); if (nDir == XML_fromT) diff --git a/oox/source/drawingml/diagram/diagramlayoutatoms.hxx b/oox/source/drawingml/diagram/diagramlayoutatoms.hxx index e56539eb8717..8a11ed5cbac8 100644 --- a/oox/source/drawingml/diagram/diagramlayoutatoms.hxx +++ b/oox/source/drawingml/diagram/diagramlayoutatoms.hxx @@ -161,7 +161,8 @@ public: void addParam( sal_Int32 nType, sal_Int32 nVal ) { maMap[nType]=nVal; } void layoutShape( const ShapePtr& rShape, - const std::vector<Constraint>& rConstraints ); + const std::vector<Constraint>& rConstraints, + sal_Int32 nShapeLevel ); void setAspectRatio(double fAspectRatio) { mfAspectRatio = fAspectRatio; } @@ -236,6 +237,7 @@ class LayoutNode { public: typedef std::map<sal_Int32, OUString> VarMap; + typedef std::map<sal_Int32, std::vector<ShapePtr>> ShapeLevelMap; LayoutNode(const Diagram& rDgm) : LayoutAtom(*this), mrDgm(rDgm), mnChildOrder(0) {} const Diagram& getDiagram() const @@ -253,10 +255,10 @@ public: { mpExistingShape = pShape; } const ShapePtr& getExistingShape() const { return mpExistingShape; } - const std::vector<ShapePtr> & getNodeShapes() const + const ShapeLevelMap& getNodeShapes() const { return mpNodeShapes; } - void addNodeShape(const ShapePtr& pShape) - { mpNodeShapes.push_back(pShape); } + void addNodeShape(const ShapePtr& pShape, sal_Int32 nLevel) + { mpNodeShapes[nLevel].push_back(pShape); } bool setupShape( const ShapePtr& rShape, const dgm::Point* pPresNode ) const; @@ -273,7 +275,7 @@ private: OUString msMoveWith; OUString msStyleLabel; ShapePtr mpExistingShape; - std::vector<ShapePtr> mpNodeShapes; + ShapeLevelMap mpNodeShapes; sal_Int32 mnChildOrder; std::weak_ptr<AlgAtom> mpAlgAtom; }; diff --git a/oox/source/drawingml/diagram/layoutatomvisitors.cxx b/oox/source/drawingml/diagram/layoutatomvisitors.cxx index c6532243ec6c..cd7b82aa9efd 100644 --- a/oox/source/drawingml/diagram/layoutatomvisitors.cxx +++ b/oox/source/drawingml/diagram/layoutatomvisitors.cxx @@ -135,7 +135,7 @@ void ShapeCreationVisitor::visit(LayoutNode& rAtom) pShape->setInternalName(rAtom.getName()); if (AlgAtomPtr pAlgAtom = rAtom.getAlgAtom()) pShape->setAspectRatio(pAlgAtom->getAspectRatio()); - rAtom.addNodeShape(pShape); + rAtom.addNodeShape(pShape, mnCurrLevel); } } else @@ -148,9 +148,8 @@ void ShapeCreationVisitor::visit(LayoutNode& rAtom) { SAL_INFO( "oox.drawingml", - "processing shape type " - << (pShape->getCustomShapeProperties() - ->getShapePresetType())); + "processing shape type " << (pShape->getCustomShapeProperties()->getShapePresetType()) + << " level " << mnCurrLevel); if (rAtom.setupShape(pShape, pNewNode)) { @@ -159,7 +158,7 @@ void ShapeCreationVisitor::visit(LayoutNode& rAtom) pShape->setAspectRatio(pAlgAtom->getAspectRatio()); pCurrParent->addChild(pShape); pCurrParent = pShape; - rAtom.addNodeShape(pShape); + rAtom.addNodeShape(pShape, mnCurrLevel); } } else @@ -174,11 +173,13 @@ void ShapeCreationVisitor::visit(LayoutNode& rAtom) // set new parent for children ShapePtr pPreviousParent(mpParentShape); mpParentShape=pCurrParent; + mnCurrLevel++; // process children defaultVisit(rAtom); // restore parent + mnCurrLevel--; mpParentShape=pPreviousParent; mpCurrentNode = pPreviousNode; @@ -266,8 +267,10 @@ void ShapeLayoutingVisitor::visit(AlgAtom& rAtom) { if (meLookFor == ALGORITHM) { - for (const auto& pShape : rAtom.getLayoutNode().getNodeShapes()) - rAtom.layoutShape(pShape, maConstraints); + auto pShapes = rAtom.getLayoutNode().getNodeShapes().find(mnCurrLevel); + if (pShapes != rAtom.getLayoutNode().getNodeShapes().end()) + for (const auto& pShape : pShapes->second) + rAtom.layoutShape(pShape, maConstraints, mnCurrLevel); } } @@ -291,6 +294,10 @@ void ShapeLayoutingVisitor::visit(LayoutNode& rAtom) if (meLookFor != LAYOUT_NODE) return; + // stop processing if there is no more shapes on this level + if (rAtom.getNodeShapes().empty() || mnCurrLevel > rAtom.getNodeShapes().rbegin()->first) + return; + size_t nParentConstraintsNumber = maConstraints.size(); // process alg atoms first, nested layout nodes afterwards @@ -298,8 +305,11 @@ void ShapeLayoutingVisitor::visit(LayoutNode& rAtom) defaultVisit(rAtom); meLookFor = ALGORITHM; defaultVisit(rAtom); + + mnCurrLevel++; meLookFor = LAYOUT_NODE; defaultVisit(rAtom); + mnCurrLevel--; // delete added constraints, keep parent constraints maConstraints.erase(maConstraints.begin() + nParentConstraintsNumber, maConstraints.end()); diff --git a/oox/source/drawingml/diagram/layoutatomvisitors.hxx b/oox/source/drawingml/diagram/layoutatomvisitors.hxx index f395f6a68668..4a61a75eb0f5 100644 --- a/oox/source/drawingml/diagram/layoutatomvisitors.hxx +++ b/oox/source/drawingml/diagram/layoutatomvisitors.hxx @@ -35,6 +35,7 @@ class ShapeCreationVisitor : public LayoutAtomVisitor sal_Int32 mnCurrIdx; sal_Int32 mnCurrStep = 0; sal_Int32 mnCurrCnt = 0; + sal_Int32 mnCurrLevel; const dgm::Point* mpCurrentNode; void defaultVisit(LayoutAtom const & rAtom); @@ -52,6 +53,7 @@ public: mpParentShape(rParentShape), mrDgm(rDgm), mnCurrIdx(0), + mnCurrLevel(0), mpCurrentNode(rDgm.getData()->getRootPoint()) {} }; @@ -78,6 +80,7 @@ class ShapeLayoutingVisitor : public LayoutAtomVisitor { std::vector<Constraint> maConstraints; enum {LAYOUT_NODE, CONSTRAINT, ALGORITHM} meLookFor; + sal_Int32 mnCurrLevel; void defaultVisit(LayoutAtom const & rAtom); virtual void visit(ConstraintAtom& rAtom) override; @@ -90,7 +93,8 @@ class ShapeLayoutingVisitor : public LayoutAtomVisitor public: ShapeLayoutingVisitor() : - meLookFor(LAYOUT_NODE) + meLookFor(LAYOUT_NODE), + mnCurrLevel(0) {} }; |