diff options
Diffstat (limited to 'oox/source/drawingml/diagram/layoutatomvisitors.cxx')
-rw-r--r-- | oox/source/drawingml/diagram/layoutatomvisitors.cxx | 48 |
1 files changed, 47 insertions, 1 deletions
diff --git a/oox/source/drawingml/diagram/layoutatomvisitors.cxx b/oox/source/drawingml/diagram/layoutatomvisitors.cxx index ce8e6ab72b9e..49a664c1e821 100644 --- a/oox/source/drawingml/diagram/layoutatomvisitors.cxx +++ b/oox/source/drawingml/diagram/layoutatomvisitors.cxx @@ -46,6 +46,14 @@ void ShapeCreationVisitor::visit(AlgAtom& rAtom) void ShapeCreationVisitor::visit(ForEachAtom& rAtom) { + if (rAtom.iterator().mnAxis == XML_followSib) + { + // If the axis is the follow sibling, then the last atom should not be + // visited. + if (mnCurrIdx + mnCurrStep >= mnCurrCnt) + return; + } + const std::vector<LayoutAtomPtr>& rChildren=rAtom.getChildren(); sal_Int32 nChildren=1; @@ -65,7 +73,11 @@ void ShapeCreationVisitor::visit(ForEachAtom& rAtom) rAtom.iterator().mnCnt==-1 ? nChildren : rAtom.iterator().mnCnt); const sal_Int32 nOldIdx=mnCurrIdx; + const sal_Int32 nOldStep = mnCurrStep; + const sal_Int32 nOldCnt = mnCurrCnt; const sal_Int32 nStep=rAtom.iterator().mnStep; + mnCurrStep = nStep; + mnCurrCnt = nCnt; for( mnCurrIdx=0; mnCurrIdx<nCnt && nStep>0; mnCurrIdx+=nStep ) { // TODO there is likely some conditions @@ -75,6 +87,8 @@ void ShapeCreationVisitor::visit(ForEachAtom& rAtom) // and restore idx mnCurrIdx = nOldIdx; + mnCurrStep = nOldStep; + mnCurrCnt = nOldCnt; } void ShapeCreationVisitor::visit(ConditionAtom& rAtom) @@ -166,6 +180,38 @@ void ShapeCreationVisitor::visit(LayoutNode& rAtom) std::remove_if(pCurrParent->getChildren().begin(), pCurrParent->getChildren().end(), [] (const ShapePtr & aChild) { return aChild->getServiceName() == "com.sun.star.drawing.GroupShape" && aChild->getChildren().empty(); }), pCurrParent->getChildren().end()); + + // Offset the children from their default z-order stacking, if necessary. + std::vector<ShapePtr>& rChildren = pCurrParent->getChildren(); + for (size_t i = 0; i < rChildren.size(); ++i) + rChildren[i]->setZOrder(i); + + for (size_t i = 0; i < rChildren.size(); ++i) + { + const ShapePtr& pChild = rChildren[i]; + sal_Int32 nZOrderOff = pChild->getZOrderOff(); + if (nZOrderOff <= 0) + continue; + + // Increase my ZOrder by nZOrderOff. + pChild->setZOrder(pChild->getZOrder() + nZOrderOff); + pChild->setZOrderOff(0); + + for (sal_Int32 j = 0; j < nZOrderOff; ++j) + { + size_t nIndex = i + j + 1; + if (nIndex >= rChildren.size()) + break; + + // Decrease the ZOrder of the next nZOrderOff elements by one. + const ShapePtr& pNext = rChildren[nIndex]; + pNext->setZOrder(pNext->getZOrder() - 1); + } + } + + // Now that the ZOrders are adjusted, sort the children. + std::sort(rChildren.begin(), rChildren.end(), + [](const ShapePtr& a, const ShapePtr& b) { return a->getZOrder() < b->getZOrder(); }); } void ShapeCreationVisitor::visit(ShapeAtom& /*rAtom*/) @@ -235,7 +281,7 @@ void ShapeLayoutingVisitor::defaultVisit(LayoutAtom const & rAtom) void ShapeLayoutingVisitor::visit(ConstraintAtom& rAtom) { if (meLookFor == CONSTRAINT) - rAtom.parseConstraint(maConstraints); + rAtom.parseConstraint(maConstraints, /*bRequireForName=*/true); } void ShapeLayoutingVisitor::visit(AlgAtom& rAtom) |