oox/source/drawingml/diagram/diagram.cxx | 42 +++++++++++++++++ oox/source/drawingml/diagram/layoutatomvisitors.cxx | 32 ------------ sd/qa/unit/data/pptx/smartart-vertical-block-list.pptx |binary sd/qa/unit/import-tests-smartart.cxx | 41 ++++++++++++++++ 4 files changed, 83 insertions(+), 32 deletions(-)
New commits: commit 2828e3c8ec3b336bc02e7e3b6d9b5c41fc5be306 Author: Grzegorz Araminowicz <grzegorz.araminow...@collabora.com> AuthorDate: Tue May 28 13:36:59 2019 +0200 Commit: Miklos Vajna <vmik...@collabora.com> CommitDate: Wed May 29 08:55:00 2019 +0200 SmartArt: sort shapes by Z order after layout algorithms so that they are laid out in correct order Change-Id: I82baa61311197880654d09f356decc666e6fa4c7 Reviewed-on: https://gerrit.libreoffice.org/73094 Tested-by: Jenkins Reviewed-by: Miklos Vajna <vmik...@collabora.com> diff --git a/oox/source/drawingml/diagram/diagram.cxx b/oox/source/drawingml/diagram/diagram.cxx index c3c28a84db23..7460c52f1fed 100644 --- a/oox/source/drawingml/diagram/diagram.cxx +++ b/oox/source/drawingml/diagram/diagram.cxx @@ -138,6 +138,46 @@ static sal_Int32 calcDepth( const OUString& rNodeName, return 0; } +static void sortChildrenByZOrder(const ShapePtr& pShape) +{ + std::vector<ShapePtr>& rChildren = pShape->getChildren(); + + // Offset the children from their default z-order stacking, if necessary. + 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(); }); + + // Apply also for children. + for (auto& rChild : rChildren) + sortChildrenByZOrder(rChild); +} + void Diagram::build( ) { // build name-object maps @@ -318,6 +358,8 @@ void Diagram::addTo( const ShapePtr & pParentShape ) // layout shapes - now all shapes are created ShapeLayoutingVisitor aLayoutingVisitor; mpLayout->getNode()->accept(aLayoutingVisitor); + + sortChildrenByZOrder(pParentShape); } ShapePtr pBackground(new Shape("com.sun.star.drawing.CustomShape")); diff --git a/oox/source/drawingml/diagram/layoutatomvisitors.cxx b/oox/source/drawingml/diagram/layoutatomvisitors.cxx index b93c06c6a636..d7d89d2968d0 100644 --- a/oox/source/drawingml/diagram/layoutatomvisitors.cxx +++ b/oox/source/drawingml/diagram/layoutatomvisitors.cxx @@ -187,38 +187,6 @@ 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*/) diff --git a/sd/qa/unit/data/pptx/smartart-vertical-block-list.pptx b/sd/qa/unit/data/pptx/smartart-vertical-block-list.pptx new file mode 100644 index 000000000000..923f03c0ee23 Binary files /dev/null and b/sd/qa/unit/data/pptx/smartart-vertical-block-list.pptx differ diff --git a/sd/qa/unit/import-tests-smartart.cxx b/sd/qa/unit/import-tests-smartart.cxx index f07cca532e1b..0267961f70cf 100644 --- a/sd/qa/unit/import-tests-smartart.cxx +++ b/sd/qa/unit/import-tests-smartart.cxx @@ -77,6 +77,7 @@ public: void testBackgroundDrawingmlFallback(); void testCenterCycle(); void testFontSize(); + void testVerticalBlockList(); CPPUNIT_TEST_SUITE(SdImportTestSmartArt); @@ -115,6 +116,7 @@ public: CPPUNIT_TEST(testBackgroundDrawingmlFallback); CPPUNIT_TEST(testCenterCycle); CPPUNIT_TEST(testFontSize); + CPPUNIT_TEST(testVerticalBlockList); CPPUNIT_TEST_SUITE_END(); }; @@ -1199,6 +1201,45 @@ void SdImportTestSmartArt::testFontSize() xDocShRef->DoClose(); } +void SdImportTestSmartArt::testVerticalBlockList() +{ + sd::DrawDocShellRef xDocShRef = loadURL( + m_directories.getURLFromSrc("/sd/qa/unit/data/pptx/smartart-vertical-block-list.pptx"), PPTX); + uno::Reference<drawing::XShapes> xGroup(getShapeFromPage(0, 0, xDocShRef), uno::UNO_QUERY); + CPPUNIT_ASSERT(xGroup.is()); + + uno::Reference<drawing::XShapes> xGroup1(xGroup->getByIndex(1), uno::UNO_QUERY); + CPPUNIT_ASSERT_EQUAL(static_cast<sal_Int32>(2), xGroup1->getCount()); + uno::Reference<drawing::XShape> xShapeA(xGroup1->getByIndex(1), uno::UNO_QUERY); + uno::Reference<drawing::XShape> xShapeBC(xGroup1->getByIndex(0), uno::UNO_QUERY); + uno::Reference<text::XText> xTextA(xShapeA, uno::UNO_QUERY); + uno::Reference<text::XText> xTextBC(xShapeBC, uno::UNO_QUERY); + CPPUNIT_ASSERT_EQUAL(OUString("a"), xTextA->getString()); + CPPUNIT_ASSERT_EQUAL(OUString("b\nc"), xTextBC->getString()); + + uno::Reference<beans::XPropertySet> xPropSetBC(xShapeBC, uno::UNO_QUERY); + CPPUNIT_ASSERT_EQUAL(sal_Int32(27000), xPropSetBC->getPropertyValue("RotateAngle").get<sal_Int32>()); + + // BC shape is rotated 90*, so width and height is swapped + CPPUNIT_ASSERT_GREATER(xShapeA->getSize().Width, xShapeBC->getSize().Height); + CPPUNIT_ASSERT_LESSEQUAL(xShapeA->getSize().Height, xShapeBC->getSize().Width); + CPPUNIT_ASSERT_GREATER(xShapeA->getPosition().X, xShapeBC->getPosition().X); + CPPUNIT_ASSERT_GREATEREQUAL(xShapeA->getPosition().Y, xShapeBC->getPosition().Y); + + uno::Reference<drawing::XShapes> xGroup3(xGroup->getByIndex(3), uno::UNO_QUERY); + CPPUNIT_ASSERT_EQUAL(static_cast<sal_Int32>(1), xGroup3->getCount()); + uno::Reference<drawing::XShape> xShapeEmpty(xGroup3->getByIndex(0), uno::UNO_QUERY); + uno::Reference<text::XText> xTextEmpty(xShapeEmpty, uno::UNO_QUERY); + CPPUNIT_ASSERT_EQUAL(OUString("empty"), xTextEmpty->getString()); + + CPPUNIT_ASSERT_EQUAL(xShapeA->getSize().Width, xShapeEmpty->getSize().Width); + CPPUNIT_ASSERT_EQUAL(xShapeA->getSize().Height, xShapeEmpty->getSize().Height); + CPPUNIT_ASSERT_EQUAL(xShapeA->getPosition().X, xShapeEmpty->getPosition().X); + CPPUNIT_ASSERT_GREATEREQUAL(xShapeA->getPosition().Y + 2*xShapeA->getSize().Height, xShapeEmpty->getPosition().Y); + + xDocShRef->DoClose(); +} + CPPUNIT_TEST_SUITE_REGISTRATION(SdImportTestSmartArt); CPPUNIT_PLUGIN_IMPLEMENT(); _______________________________________________ Libreoffice-commits mailing list libreoffice-comm...@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/libreoffice-commits