Kaydet (Commit) acf8dec2 authored tarafından Miklos Vajna's avatar Miklos Vajna

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/66664Reviewed-by: 's avatarMiklos Vajna <vmiklos@collabora.com>
Tested-by: Jenkins
üst fdc91f74
...@@ -30,6 +30,7 @@ ...@@ -30,6 +30,7 @@
#include <drawingml/textparagraph.hxx> #include <drawingml/textparagraph.hxx>
#include <drawingml/textrun.hxx> #include <drawingml/textrun.hxx>
#include <drawingml/customshapeproperties.hxx> #include <drawingml/customshapeproperties.hxx>
#include <tools/gen.hxx>
using namespace ::com::sun::star; using namespace ::com::sun::star;
using namespace ::com::sun::star::uno; using namespace ::com::sun::star::uno;
...@@ -73,6 +74,10 @@ sal_Int32 getConnectorType(const oox::drawingml::LayoutNode* pNode) ...@@ -73,6 +74,10 @@ sal_Int32 getConnectorType(const oox::drawingml::LayoutNode* pNode)
if (!pNode) if (!pNode)
return nType; 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()) for (const auto& pChild : pNode->getChildren())
{ {
auto pAlgAtom = dynamic_cast<oox::drawingml::AlgAtom*>(pChild.get()); auto pAlgAtom = dynamic_cast<oox::drawingml::AlgAtom*>(pChild.get());
...@@ -171,6 +176,28 @@ void calculateHierChildOffsetScale(const oox::drawingml::ShapePtr& pShape, ...@@ -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 { namespace oox { namespace drawingml {
...@@ -542,6 +569,12 @@ void AlgAtom::layoutShape( const ShapePtr& rShape, ...@@ -542,6 +569,12 @@ void AlgAtom::layoutShape( const ShapePtr& rShape,
rShape->setSubType(nType); rShape->setSubType(nType);
rShape->getCustomShapeProperties()->setShapePresetType(nType); rShape->getCustomShapeProperties()->setShapePresetType(nType);
if (nType == XML_bentConnector3)
{
setHierChildConnPosSize(rShape);
break;
}
} }
// Parse constraints to adjust the size. // Parse constraints to adjust the size.
...@@ -629,7 +662,6 @@ void AlgAtom::layoutShape( const ShapePtr& rShape, ...@@ -629,7 +662,6 @@ void AlgAtom::layoutShape( const ShapePtr& rShape,
break; break;
sal_Int32 nCount = rShape->getChildren().size(); sal_Int32 nCount = rShape->getChildren().size();
double fSpace = 0.3;
if (mnType == XML_hierChild) if (mnType == XML_hierChild)
{ {
...@@ -643,6 +675,10 @@ void AlgAtom::layoutShape( const ShapePtr& rShape, ...@@ -643,6 +675,10 @@ void AlgAtom::layoutShape( const ShapePtr& rShape,
// A manager node's height should be independent from if it has // A manager node's height should be independent from if it has
// assistants and employees, compensate for that. // assistants and employees, compensate for that.
bool bTop = mnType == XML_hierRoot && rShape->getInternalName() == "hierRoot1"; 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; double fHeightScale = 1.0;
if (mnType == XML_hierRoot && nCount < 3 && bTop) if (mnType == XML_hierRoot && nCount < 3 && bTop)
fHeightScale = fHeightScale * nCount / 3; fHeightScale = fHeightScale * nCount / 3;
......
...@@ -778,6 +778,15 @@ void SdImportTestSmartArt::testOrgChart() ...@@ -778,6 +778,15 @@ void SdImportTestSmartArt::testOrgChart()
// assistant shape was below the employee shape. // assistant shape was below the employee shape.
CPPUNIT_ASSERT_GREATER(aAssistantPos.Y, aEmployeePos.Y); 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. // Make sure the height of xManager and xManager2 is the same.
uno::Reference<text::XText> xManager2( uno::Reference<text::XText> xManager2(
getChildShape(getChildShape(getChildShape(xGroup, 1), 0), 0), uno::UNO_QUERY); getChildShape(getChildShape(getChildShape(xGroup, 1), 0), 0), uno::UNO_QUERY);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment