summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMiklos Vajna <vmiklos@collabora.com>2019-01-21 10:34:19 +0100
committerMiklos Vajna <vmiklos@collabora.com>2019-01-21 13:11:28 +0100
commitacf8dec2aff423c6c4cfbd0e1ecb01ee052316cd (patch)
treef884c7750c63e3929bf4c36a3c8571964cbd8b47
parentfdc91f7493171ae600ecb293ad380df5fa77a277 (diff)
oox smartart, org chart: fix position and size of connector shapes
Finally the bugdoc rendering result is reasonable and even looks like a tree as it should. Change-Id: I4e7a729afd3d2c5af2e7f41903737bd56be406fa Reviewed-on: https://gerrit.libreoffice.org/66664 Reviewed-by: Miklos Vajna <vmiklos@collabora.com> Tested-by: Jenkins
-rw-r--r--oox/source/drawingml/diagram/diagramlayoutatoms.cxx38
-rw-r--r--sd/qa/unit/import-tests-smartart.cxx9
2 files changed, 46 insertions, 1 deletions
diff --git a/oox/source/drawingml/diagram/diagramlayoutatoms.cxx b/oox/source/drawingml/diagram/diagramlayoutatoms.cxx
index f7da2cc03515..edc87ca7b0ce 100644
--- a/oox/source/drawingml/diagram/diagramlayoutatoms.cxx
+++ b/oox/source/drawingml/diagram/diagramlayoutatoms.cxx
@@ -30,6 +30,7 @@
#include <drawingml/textparagraph.hxx>
#include <drawingml/textrun.hxx>
#include <drawingml/customshapeproperties.hxx>
+#include <tools/gen.hxx>
using namespace ::com::sun::star;
using namespace ::com::sun::star::uno;
@@ -73,6 +74,10 @@ sal_Int32 getConnectorType(const oox::drawingml::LayoutNode* pNode)
if (!pNode)
return nType;
+ // This is cheaper than visiting the whole sub-tree.
+ if (pNode->getName().startsWith("hierChild"))
+ return oox::XML_bentConnector3;
+
for (const auto& pChild : pNode->getChildren())
{
auto pAlgAtom = dynamic_cast<oox::drawingml::AlgAtom*>(pChild.get());
@@ -171,6 +176,28 @@ void calculateHierChildOffsetScale(const oox::drawingml::ShapePtr& pShape,
}
}
}
+
+/// Sets the position and size of a connector inside a hierChild algorithm.
+void setHierChildConnPosSize(const oox::drawingml::ShapePtr& pShape)
+{
+ // Connect to the top center of the child.
+ awt::Point aShapePoint = pShape->getPosition();
+ awt::Size aShapeSize = pShape->getSize();
+ tools::Rectangle aRectangle(Point(aShapePoint.X, aShapePoint.Y),
+ Size(aShapeSize.Width, aShapeSize.Height));
+ Point aTo = aRectangle.TopCenter();
+
+ // Connect from the bottom center of the parent.
+ Point aFrom = aTo;
+ aFrom.setY(aFrom.getY() - aRectangle.getHeight() * 0.3);
+
+ tools::Rectangle aRect(aFrom, aTo);
+ aRect.Justify();
+ aShapePoint = awt::Point(aRect.Left(), aRect.Top());
+ aShapeSize = awt::Size(aRect.getWidth(), aRect.getHeight());
+ pShape->setPosition(aShapePoint);
+ pShape->setSize(aShapeSize);
+}
}
namespace oox { namespace drawingml {
@@ -542,6 +569,12 @@ void AlgAtom::layoutShape( const ShapePtr& rShape,
rShape->setSubType(nType);
rShape->getCustomShapeProperties()->setShapePresetType(nType);
+
+ if (nType == XML_bentConnector3)
+ {
+ setHierChildConnPosSize(rShape);
+ break;
+ }
}
// Parse constraints to adjust the size.
@@ -629,7 +662,6 @@ void AlgAtom::layoutShape( const ShapePtr& rShape,
break;
sal_Int32 nCount = rShape->getChildren().size();
- double fSpace = 0.3;
if (mnType == XML_hierChild)
{
@@ -643,6 +675,10 @@ void AlgAtom::layoutShape( const ShapePtr& rShape,
// A manager node's height should be independent from if it has
// assistants and employees, compensate for that.
bool bTop = mnType == XML_hierRoot && rShape->getInternalName() == "hierRoot1";
+
+ // Add spacing, so connectors have a chance to be visible.
+ double fSpace = (nCount > 1 || bTop) ? 0.3 : 0;
+
double fHeightScale = 1.0;
if (mnType == XML_hierRoot && nCount < 3 && bTop)
fHeightScale = fHeightScale * nCount / 3;
diff --git a/sd/qa/unit/import-tests-smartart.cxx b/sd/qa/unit/import-tests-smartart.cxx
index ee25c47fbd8e..54dd57bc8615 100644
--- a/sd/qa/unit/import-tests-smartart.cxx
+++ b/sd/qa/unit/import-tests-smartart.cxx
@@ -778,6 +778,15 @@ void SdImportTestSmartArt::testOrgChart()
// assistant shape was below the employee shape.
CPPUNIT_ASSERT_GREATER(aAssistantPos.Y, aEmployeePos.Y);
+ // Make sure the connector of the assistant is above the shape.
+ uno::Reference<drawing::XShape> xAssistantConnector(
+ getChildShape(getChildShape(getChildShape(xGroup, 0), 1), 0), uno::UNO_QUERY);
+ CPPUNIT_ASSERT(xAssistantConnector.is());
+ awt::Point aAssistantConnectorPos = xAssistantConnector->getPosition();
+ // This failed, the vertical positions of the connector and the shape of
+ // the assistant were the same.
+ CPPUNIT_ASSERT_LESS(aAssistantPos.Y, aAssistantConnectorPos.Y);
+
// Make sure the height of xManager and xManager2 is the same.
uno::Reference<text::XText> xManager2(
getChildShape(getChildShape(getChildShape(xGroup, 1), 0), 0), uno::UNO_QUERY);