diff options
author | Grzegorz Araminowicz <grzegorz.araminowicz@collabora.com> | 2019-06-14 15:12:33 +0200 |
---|---|---|
committer | Grzegorz Araminowicz <grzegorz.araminowicz@collabora.com> | 2019-07-10 22:11:13 +0200 |
commit | 70f9f5fb2a724373742285ecc1e74393d5226421 (patch) | |
tree | b337be4940e07880ebfeb5d0df79e4fda6c62ae1 /oox | |
parent | ee1520bd4caf13200efa5456583ac8b4dc2e1640 (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>
Reviewed-on: https://gerrit.libreoffice.org/75366
Tested-by: Jenkins CollaboraOffice <jenkinscollaboraoffice@gmail.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 a4b80548e3dd..ad4e8962a4a4 100644 --- a/oox/source/drawingml/diagram/diagramlayoutatoms.cxx +++ b/oox/source/drawingml/diagram/diagramlayoutatoms.cxx @@ -159,12 +159,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]; @@ -499,7 +503,8 @@ void AlgAtom::accept( LayoutAtomVisitor& rVisitor ) } void AlgAtom::layoutShape( const ShapePtr& rShape, - const std::vector<Constraint>& rConstraints ) + const std::vector<Constraint>& rConstraints, + sal_Int32 nShapeLevel ) { switch(mnType) { @@ -743,7 +748,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 d70878e063aa..0291b87cc97a 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 ); /// Gives access to <dgm:alg type="..."/>. sal_Int32 getType() const { return mnType; } @@ -239,6 +240,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 @@ -256,10 +258,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; @@ -276,7 +278,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 4e1a3689e3e4..5b79dafbc46b 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) {} }; |