Kaydet (Commit) 5218009f authored tarafından Grzegorz Araminowicz's avatar Grzegorz Araminowicz Kaydeden (comit) Miklos Vajna

SmartArt: better detecting connector arrow type

* basing on provided conn alg params
* also moved setting arrow direction from getConnectorType() to algorithms

Change-Id: I76898a4ccad961edd389677c31e7d8c05bcdf5fe
Reviewed-on: https://gerrit.libreoffice.org/70598
Tested-by: Jenkins
Reviewed-by: 's avatarMiklos Vajna <vmiklos@collabora.com>
üst 504a9575
......@@ -84,56 +84,6 @@ sal_Int32 getPropertyFromConstraint(sal_Int32 nConstraint)
return 0;
}
/// Determines the connector shape type from a linear alg.
sal_Int32 getConnectorType(const oox::drawingml::LayoutNode* pNode)
{
sal_Int32 nType = oox::XML_rightArrow;
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());
if (!pAlgAtom)
continue;
switch (pAlgAtom->getType())
{
case oox::XML_lin:
{
sal_Int32 nDir = oox::XML_fromL;
if (pAlgAtom->getMap().count(oox::XML_linDir))
nDir = pAlgAtom->getMap().find(oox::XML_linDir)->second;
switch (nDir)
{
case oox::XML_fromL:
nType = oox::XML_rightArrow;
break;
case oox::XML_fromR:
nType = oox::XML_leftArrow;
break;
}
break;
}
case oox::XML_hierChild:
{
// TODO <dgm:param type="connRout" val="..."/> should be able
// to customize this.
nType = oox::XML_bentConnector3;
break;
}
}
}
return nType;
}
/**
* Determines if pShape is (or contains) a presentation of a data node of type
* nType.
......@@ -493,6 +443,30 @@ void AlgAtom::accept( LayoutAtomVisitor& rVisitor )
rVisitor.visit(*this);
}
sal_Int32 AlgAtom::getConnectorType()
{
sal_Int32 nConnRout = 0;
sal_Int32 nBegSty = 0;
sal_Int32 nEndSty = 0;
if (maMap.count(oox::XML_connRout))
nConnRout = maMap.find(oox::XML_connRout)->second;
if (maMap.count(oox::XML_begSty))
nBegSty = maMap.find(oox::XML_begSty)->second;
if (maMap.count(oox::XML_endSty))
nEndSty = maMap.find(oox::XML_endSty)->second;
if (nConnRout == oox::XML_bend)
return oox::XML_bentConnector3;
if (nBegSty == oox::XML_arr && nEndSty == oox::XML_arr)
return oox::XML_leftRightArrow;
if (nBegSty == oox::XML_arr)
return oox::XML_leftArrow;
if (nEndSty == oox::XML_arr)
return oox::XML_rightArrow;
return oox::XML_rightArrow;
}
void AlgAtom::layoutShape( const ShapePtr& rShape,
const std::vector<Constraint>& rOwnConstraints )
{
......@@ -624,7 +598,7 @@ void AlgAtom::layoutShape( const ShapePtr& rShape,
{
// There is no shape type "conn", replace it by an arrow based
// on the direction of the parent linear layout.
sal_Int32 nType = getConnectorType(pParent);
sal_Int32 nType = getConnectorType();
rShape->setSubType(nType);
rShape->getCustomShapeProperties()->setShapePresetType(nType);
......@@ -695,6 +669,7 @@ void AlgAtom::layoutShape( const ShapePtr& rShape,
(rShape->getSize().Width - aChildSize.Width) / 2,
(rShape->getSize().Height - aChildSize.Height) / 2);
const sal_Int32 nConnectorRadius = nRadius * cos(basegfx::deg2rad(nSpanAngle/nShapes));
const sal_Int32 nConnectorAngle = nSpanAngle > 0 ? 0 : 180;
sal_Int32 idx = 0;
for (auto & aCurrShape : rShape->getChildren())
......@@ -715,10 +690,13 @@ void AlgAtom::layoutShape( const ShapePtr& rShape,
aCurrShape->setSize(aCurrSize);
aCurrShape->setChildSize(aCurrSize);
if (nRotationPath == XML_alongPath)
aCurrShape->setRotation(fAngle * PER_DEGREE);
// connectors should be handled in conn, but we don't have
// reference to previous and next child, so it's easier here
if (nRotationPath == XML_alongPath || aCurrShape->getSubType() == XML_conn)
aCurrShape->setRotation(fAngle * PER_DEGREE);
if (aCurrShape->getSubType() == XML_conn)
aCurrShape->setRotation((nConnectorAngle + fAngle) * PER_DEGREE);
idx++;
}
......@@ -816,6 +794,14 @@ void AlgAtom::layoutShape( const ShapePtr& rShape,
sal_Int32 nCount = rShape->getChildren().size();
double fSpace = 0.3;
sal_Int32 nConnectorAngle = 0;
switch (nDir)
{
case XML_fromL: nConnectorAngle = 0; break;
case XML_fromR: nConnectorAngle = 180; break;
case XML_fromT: nConnectorAngle = 270; break;
case XML_fromB: nConnectorAngle = 90; break;
}
// Find out which constraint is relevant for which (internal) name.
LayoutPropertyMap aProperties;
......@@ -892,6 +878,11 @@ void AlgAtom::layoutShape( const ShapePtr& rShape,
aCurrShape->setChildSize(aSize);
aCurrPos.X += nIncX * (aSize.Width + fSpace*aSize.Width);
aCurrPos.Y += nIncY * (aChildSize.Height + fSpace*aChildSize.Height);
// connectors should be handled in conn, but we don't have
// reference to previous and next child, so it's easier here
if (aCurrShape->getSubType() == XML_conn)
aCurrShape->setRotation(nConnectorAngle * PER_DEGREE);
}
break;
}
......
......@@ -178,6 +178,9 @@ private:
ParamMap maMap;
/// Aspect ratio is not integer, so not part of maMap.
double mfAspectRatio = 0;
/// Determines the connector shape type for conn algorithm
sal_Int32 getConnectorType();
};
typedef std::shared_ptr< AlgAtom > AlgAtomPtr;
......
......@@ -420,6 +420,13 @@ void SdImportTestSmartArt::testCycle()
CPPUNIT_ASSERT(xShape0->getPosition().Y < xShapeConn->getPosition().Y && xShapeConn->getPosition().Y < xShape2->getPosition().Y);
uno::Reference<beans::XPropertySet> xPropSetConn(xShapeConn, uno::UNO_QUERY_THROW);
CPPUNIT_ASSERT_EQUAL(sal_Int32(32400), xPropSetConn->getPropertyValue("RotateAngle").get<sal_Int32>());
// Make sure that we have an arrow shape between the two shapes
comphelper::SequenceAsHashMap aCustomShapeGeometry(
xPropSetConn->getPropertyValue("CustomShapeGeometry"));
CPPUNIT_ASSERT(aCustomShapeGeometry["Type"].has<OUString>());
OUString aType = aCustomShapeGeometry["Type"].get<OUString>();
CPPUNIT_ASSERT_EQUAL(OUString("ooxml-rightArrow"), aType);
}
void SdImportTestSmartArt::testHierarchy()
......@@ -444,7 +451,23 @@ void SdImportTestSmartArt::testInvertedPyramid()
void SdImportTestSmartArt::testMultidirectional()
{
//FIXME : so far this only introduce the test document, but the actual importer was not fixed yet.
// similar document as cycle, but arrows are pointing in both directions
sd::DrawDocShellRef xDocShRef
= loadURL(m_directories.getURLFromSrc("/sd/qa/unit/data/pptx/smartart-multidirectional.pptx"), PPTX);
uno::Reference<drawing::XShapes> xGroup(getShapeFromPage(0, 0, xDocShRef), uno::UNO_QUERY);
CPPUNIT_ASSERT(xGroup.is());
// 6 children: 3 shapes, 3 connectors
CPPUNIT_ASSERT_EQUAL(static_cast<sal_Int32>(6), xGroup->getCount());
uno::Reference<drawing::XShape> xShapeConn(xGroup->getByIndex(1), uno::UNO_QUERY_THROW);
uno::Reference<beans::XPropertySet> xPropSetConn(xShapeConn, uno::UNO_QUERY_THROW);
comphelper::SequenceAsHashMap aCustomShapeGeometry(
xPropSetConn->getPropertyValue("CustomShapeGeometry"));
CPPUNIT_ASSERT(aCustomShapeGeometry["Type"].has<OUString>());
OUString aType = aCustomShapeGeometry["Type"].get<OUString>();
CPPUNIT_ASSERT_EQUAL(OUString("ooxml-leftRightArrow"), aType);
}
void SdImportTestSmartArt::testHorizontalBulletList()
......
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