diff options
author | Miklos Vajna <vmiklos@collabora.com> | 2019-01-02 17:38:07 +0100 |
---|---|---|
committer | Miklos Vajna <vmiklos@collabora.com> | 2019-01-02 19:02:06 +0100 |
commit | dcd378bf614c99d705312259a0a0a25b40d88e2b (patch) | |
tree | d9a90face4a7e837fc09fed850ac75c082afef71 | |
parent | 0d79068307828c3e447611a52eb36cbf34ea1f23 (diff) |
oox smartart, org chart: handle multiple elements in hierChild
In case one manager has multiple employees, then we laid out only the
first one. Recognize non-assistant type as the node type (as a start) to
get the correct number of employees (when there are no assistants), and
also render employees on a horizontal (and not on a vertical) path.
With this, the 1 manager and multiple employees case looks reasonable.
Change-Id: I3bbe0413586b1a2c25f9094dbd44f1a86c799c0f
Reviewed-on: https://gerrit.libreoffice.org/65813
Reviewed-by: Miklos Vajna <vmiklos@collabora.com>
Tested-by: Jenkins
-rw-r--r-- | oox/source/drawingml/diagram/diagramlayoutatoms.cxx | 14 | ||||
-rw-r--r-- | oox/source/drawingml/diagram/layoutatomvisitors.cxx | 3 | ||||
-rw-r--r-- | sd/qa/unit/data/pptx/smartart-org-chart.pptx | bin | 51711 -> 52537 bytes | |||
-rw-r--r-- | sd/qa/unit/import-tests-smartart.cxx | 24 |
4 files changed, 38 insertions, 3 deletions
diff --git a/oox/source/drawingml/diagram/diagramlayoutatoms.cxx b/oox/source/drawingml/diagram/diagramlayoutatoms.cxx index 6af12ed4d26f..056164276283 100644 --- a/oox/source/drawingml/diagram/diagramlayoutatoms.cxx +++ b/oox/source/drawingml/diagram/diagramlayoutatoms.cxx @@ -524,6 +524,10 @@ void AlgAtom::layoutShape( const ShapePtr& rShape, case XML_hierChild: case XML_hierRoot: { + // hierRoot is the manager -> employees vertical linear path, + // hierChild is the first employee -> last employee horizontal + // linear path. + const sal_Int32 nDir = mnType == XML_hierRoot ? XML_fromT : XML_fromL; if (rShape->getChildren().empty() || rShape->getSize().Width == 0 || rShape->getSize().Height == 0) break; @@ -531,7 +535,10 @@ void AlgAtom::layoutShape( const ShapePtr& rShape, sal_Int32 nCount = rShape->getChildren().size(); awt::Size aChildSize = rShape->getSize(); - aChildSize.Height /= nCount; + if (nDir == XML_fromT) + aChildSize.Height /= nCount; + else + aChildSize.Width /= nCount; awt::Point aChildPos(0, 0); for (auto& pChild : rShape->getChildren()) @@ -539,7 +546,10 @@ void AlgAtom::layoutShape( const ShapePtr& rShape, pChild->setPosition(aChildPos); pChild->setSize(aChildSize); pChild->setChildSize(aChildSize); - aChildPos.Y += aChildSize.Height; + if (nDir == XML_fromT) + aChildPos.Y += aChildSize.Height; + else + aChildPos.X += aChildSize.Width; } break; diff --git a/oox/source/drawingml/diagram/layoutatomvisitors.cxx b/oox/source/drawingml/diagram/layoutatomvisitors.cxx index 79af89808e36..a73b6566bafe 100644 --- a/oox/source/drawingml/diagram/layoutatomvisitors.cxx +++ b/oox/source/drawingml/diagram/layoutatomvisitors.cxx @@ -59,7 +59,8 @@ void ShapeCreationVisitor::visit(ForEachAtom& rAtom) const std::vector<LayoutAtomPtr>& rChildren=rAtom.getChildren(); sal_Int32 nChildren=1; - if( rAtom.iterator().mnPtType == XML_node ) + // Approximate the non-assistant type with the node type. + if (rAtom.iterator().mnPtType == XML_node || rAtom.iterator().mnPtType == XML_nonAsst) { // count child data nodes - check all child Atoms for "name" // attribute that is contained in diagram's diff --git a/sd/qa/unit/data/pptx/smartart-org-chart.pptx b/sd/qa/unit/data/pptx/smartart-org-chart.pptx Binary files differindex 332d401fa641..3be3473fd6c4 100644 --- a/sd/qa/unit/data/pptx/smartart-org-chart.pptx +++ b/sd/qa/unit/data/pptx/smartart-org-chart.pptx diff --git a/sd/qa/unit/import-tests-smartart.cxx b/sd/qa/unit/import-tests-smartart.cxx index 3f644caa8278..98df02de2fc9 100644 --- a/sd/qa/unit/import-tests-smartart.cxx +++ b/sd/qa/unit/import-tests-smartart.cxx @@ -705,6 +705,14 @@ void SdImportTestSmartArt::testOrgChart() awt::Point aManagerPos = xManagerShape->getPosition(); + // Make sure that the manager has 2 employees. + // Without the accompanying fix in place, this test would have failed with + // 'Expected: 2; Actual : 1'. + uno::Reference<drawing::XShapes> xEmployees(getChildShape(getChildShape(xGroup, 0), 1), + uno::UNO_QUERY); + CPPUNIT_ASSERT(xEmployees.is()); + CPPUNIT_ASSERT_EQUAL(static_cast<sal_Int32>(2), xEmployees->getCount()); + uno::Reference<text::XText> xEmployee( getChildShape( getChildShape(getChildShape(getChildShape(getChildShape(xGroup, 0), 1), 0), 0), 0), @@ -723,6 +731,22 @@ void SdImportTestSmartArt::testOrgChart() // two shapes were overlapping, i.e. "manager" was not above "employee". CPPUNIT_ASSERT_GREATER(aManagerPos.Y, aEmployeePos.Y); + // Make sure that the second employee is on the right of the first one. + // Without the accompanying fix in place, this test would have failed, as + // the second employee was below the first one. + uno::Reference<text::XText> xEmployee2( + getChildShape( + getChildShape(getChildShape(getChildShape(getChildShape(xGroup, 0), 1), 1), 0), 0), + uno::UNO_QUERY); + CPPUNIT_ASSERT(xEmployee2.is()); + CPPUNIT_ASSERT_EQUAL(OUString("Employee2"), xEmployee2->getString()); + + uno::Reference<drawing::XShape> xEmployee2Shape(xEmployee2, uno::UNO_QUERY); + CPPUNIT_ASSERT(xEmployee2Shape.is()); + + awt::Point aEmployee2Pos = xEmployee2Shape->getPosition(); + CPPUNIT_ASSERT_GREATER(aEmployeePos.X, aEmployee2Pos.X); + xDocShRef->DoClose(); } |