oox/source/drawingml/diagram/diagramlayoutatoms.cxx | 93 +++++++++++++++++++- oox/source/drawingml/diagram/diagramlayoutatoms.hxx | 9 + oox/source/drawingml/diagram/layoutatomvisitors.cxx | 2 sd/qa/unit/import-tests-smartart.cxx | 19 ++++ 4 files changed, 117 insertions(+), 6 deletions(-)
New commits: commit 967f2ac350330a28a3fc2ec0993cbaf976e6cf60 Author: Miklos Vajna <[email protected]> AuthorDate: Fri Nov 30 17:57:21 2018 +0100 Commit: Miklos Vajna <[email protected]> CommitDate: Mon Dec 17 15:39:55 2018 +0100 oox smartart, accent process: adjust size of connector from constraints The constraints explicitly said that the width should be larger than the height, but it was the opposite as constraints were not parsed. Unfortunately it would be too brave for globally start handling all constraints which lack a forName, so add a switch to opt in for this, and use that with the conn algorithm. All clients should migrate to bRequireForName=true at some stage, though. Change-Id: I24ae79b141c0f7a11e4d19f141759fc1dd2169b0 Reviewed-on: https://gerrit.libreoffice.org/64350 Reviewed-by: Miklos Vajna <[email protected]> Tested-by: Jenkins (cherry picked from commit ddc2786831367577967e806d603f337a2e42806a) Reviewed-on: https://gerrit.libreoffice.org/65252 diff --git a/oox/source/drawingml/diagram/diagramlayoutatoms.cxx b/oox/source/drawingml/diagram/diagramlayoutatoms.cxx index f5a7b410de03..74cd2ed7d06c 100644 --- a/oox/source/drawingml/diagram/diagramlayoutatoms.cxx +++ b/oox/source/drawingml/diagram/diagramlayoutatoms.cxx @@ -314,11 +314,14 @@ void ConstraintAtom::accept( LayoutAtomVisitor& rVisitor ) rVisitor.visit(*this); } -void ConstraintAtom::parseConstraint(std::vector<Constraint>& rConstraints) const +void ConstraintAtom::parseConstraint(std::vector<Constraint>& rConstraints, + bool bRequireForName) const { + if (bRequireForName && maConstraint.msForName.isEmpty()) + return; + // accepting only basic equality constraints - if (!maConstraint.msForName.isEmpty() - && (maConstraint.mnOperator == XML_none || maConstraint.mnOperator == XML_equ) + if ((maConstraint.mnOperator == XML_none || maConstraint.mnOperator == XML_equ) && maConstraint.mnType != XML_none) { rConstraints.push_back(maConstraint); @@ -342,7 +345,7 @@ void AlgAtom::layoutShape( const ShapePtr& rShape, { auto pConstraintAtom = dynamic_cast<ConstraintAtom*>(pChild.get()); if (pConstraintAtom) - pConstraintAtom->parseConstraint(aMergedConstraints); + pConstraintAtom->parseConstraint(aMergedConstraints, /*bRequireForName=*/true); } } aMergedConstraints.insert(aMergedConstraints.end(), rOwnConstraints.begin(), @@ -444,6 +447,42 @@ void AlgAtom::layoutShape( const ShapePtr& rShape, rShape->setSubType(nType); rShape->getCustomShapeProperties()->setShapePresetType(nType); } + + // Parse constraints to adjust the size. + std::vector<Constraint> aDirectConstraints; + const LayoutNode& rLayoutNode = getLayoutNode(); + for (const auto& pChild : rLayoutNode.getChildren()) + { + auto pConstraintAtom = dynamic_cast<ConstraintAtom*>(pChild.get()); + if (pConstraintAtom) + pConstraintAtom->parseConstraint(aDirectConstraints, /*bRequireForName=*/false); + } + + LayoutPropertyMap aProperties; + LayoutProperty& rParent = aProperties[""]; + rParent[XML_w] = rShape->getSize().Width; + rParent[XML_h] = rShape->getSize().Height; + rParent[XML_l] = 0; + rParent[XML_t] = 0; + rParent[XML_r] = rShape->getSize().Width; + rParent[XML_b] = rShape->getSize().Height; + for (const auto& rConstr : aDirectConstraints) + { + const LayoutPropertyMap::const_iterator aRef + = aProperties.find(rConstr.msRefForName); + if (aRef != aProperties.end()) + { + const LayoutProperty::const_iterator aRefType + = aRef->second.find(rConstr.mnRefType); + if (aRefType != aRef->second.end()) + aProperties[rConstr.msForName][rConstr.mnType] + = aRefType->second * rConstr.mfFactor; + } + } + awt::Size aSize; + aSize.Width = rParent[XML_w]; + aSize.Height = rParent[XML_h]; + rShape->setSize(aSize); break; } diff --git a/oox/source/drawingml/diagram/diagramlayoutatoms.hxx b/oox/source/drawingml/diagram/diagramlayoutatoms.hxx index 024cdaa1b61a..440db0ef21ed 100644 --- a/oox/source/drawingml/diagram/diagramlayoutatoms.hxx +++ b/oox/source/drawingml/diagram/diagramlayoutatoms.hxx @@ -141,7 +141,7 @@ public: virtual void accept( LayoutAtomVisitor& ) override; Constraint& getConstraint() { return maConstraint; } - void parseConstraint(std::vector<Constraint>& rConstraints) const; + void parseConstraint(std::vector<Constraint>& rConstraints, bool bRequireForName) const; private: Constraint maConstraint; }; diff --git a/oox/source/drawingml/diagram/layoutatomvisitors.cxx b/oox/source/drawingml/diagram/layoutatomvisitors.cxx index ced94784aff4..79af89808e36 100644 --- a/oox/source/drawingml/diagram/layoutatomvisitors.cxx +++ b/oox/source/drawingml/diagram/layoutatomvisitors.cxx @@ -283,7 +283,7 @@ void ShapeLayoutingVisitor::defaultVisit(LayoutAtom const & rAtom) void ShapeLayoutingVisitor::visit(ConstraintAtom& rAtom) { if (meLookFor == CONSTRAINT) - rAtom.parseConstraint(maConstraints); + rAtom.parseConstraint(maConstraints, /*bRequireForName=*/true); } void ShapeLayoutingVisitor::visit(AlgAtom& rAtom) diff --git a/sd/qa/unit/import-tests-smartart.cxx b/sd/qa/unit/import-tests-smartart.cxx index be8ac42d3b45..fe24ff486fa3 100644 --- a/sd/qa/unit/import-tests-smartart.cxx +++ b/sd/qa/unit/import-tests-smartart.cxx @@ -503,6 +503,12 @@ void SdImportTestSmartArt::testAccentProcess() OUString aType = aCustomShapeGeometry["Type"].get<OUString>(); CPPUNIT_ASSERT_EQUAL(OUString("ooxml-rightArrow"), aType); + // Make sure that height of the arrow is less than its width. + uno::Reference<drawing::XShape> xArrowShape(xArrow, uno::UNO_QUERY); + CPPUNIT_ASSERT(xArrowShape.is()); + awt::Size aArrowSize = xArrowShape->getSize(); + CPPUNIT_ASSERT_LESS(aArrowSize.Width, aArrowSize.Height); + uno::Reference<drawing::XShapes> xSecondPair(xGroup->getByIndex(2), uno::UNO_QUERY); CPPUNIT_ASSERT(xSecondPair.is()); CPPUNIT_ASSERT_EQUAL(static_cast<sal_Int32>(3), xSecondPair->getCount()); commit be78a50a883e646e9d4830e3024554395dd12b9e Author: Miklos Vajna <[email protected]> AuthorDate: Fri Nov 30 16:40:58 2018 +0100 Commit: Miklos Vajna <[email protected]> CommitDate: Mon Dec 17 15:39:44 2018 +0100 oox smartart, accent process: handle connector shape between pairs The shape was created, but we literally tried to create a "conn" type, while that has to be resolved to the relevant arrow type based on the context. This means now arrows show up between the parent-child pairs (but their size is not yet correct). Change-Id: I82594e46579e4ef723093e1dd0ba31bfcbbec4a0 Reviewed-on: https://gerrit.libreoffice.org/64348 Reviewed-by: Miklos Vajna <[email protected]> Tested-by: Jenkins (cherry picked from commit 7f66a340933339974b5c6d70af4ae3c17e4f001a) Reviewed-on: https://gerrit.libreoffice.org/65251 diff --git a/oox/source/drawingml/diagram/diagramlayoutatoms.cxx b/oox/source/drawingml/diagram/diagramlayoutatoms.cxx index 52a05ccdb53d..f5a7b410de03 100644 --- a/oox/source/drawingml/diagram/diagramlayoutatoms.cxx +++ b/oox/source/drawingml/diagram/diagramlayoutatoms.cxx @@ -64,6 +64,41 @@ bool isFontUnit(sal_Int32 nUnit) { return nUnit == oox::XML_primFontSz || nUnit == oox::XML_secFontSz; } + +/// 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; + + for (const auto& pChild : pNode->getChildren()) + { + auto pAlgAtom = dynamic_cast<oox::drawingml::AlgAtom*>(pChild.get()); + if (!pAlgAtom) + continue; + + if (pAlgAtom->getType() != oox::XML_lin) + continue; + + 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; + } + } + + return nType; +} } namespace oox { namespace drawingml { @@ -399,7 +434,18 @@ void AlgAtom::layoutShape( const ShapePtr& rShape, } case XML_conn: + { + if (rShape->getSubType() == XML_conn) + { + // 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); + + rShape->setSubType(nType); + rShape->getCustomShapeProperties()->setShapePresetType(nType); + } break; + } case XML_cycle: { diff --git a/oox/source/drawingml/diagram/diagramlayoutatoms.hxx b/oox/source/drawingml/diagram/diagramlayoutatoms.hxx index 50ff8a300ac5..024cdaa1b61a 100644 --- a/oox/source/drawingml/diagram/diagramlayoutatoms.hxx +++ b/oox/source/drawingml/diagram/diagramlayoutatoms.hxx @@ -162,6 +162,13 @@ public: { maMap[nType]=nVal; } void layoutShape( const ShapePtr& rShape, const std::vector<Constraint>& rConstraints ) const; + + /// Gives access to <dgm:alg type="..."/>. + sal_Int32 getType() const { return mnType; } + + /// Gives access to <dgm:param type="..." val="..."/>. + const ParamMap& getMap() const { return maMap; } + private: sal_Int32 mnType; ParamMap maMap; diff --git a/sd/qa/unit/import-tests-smartart.cxx b/sd/qa/unit/import-tests-smartart.cxx index aa8498b73ce9..be8ac42d3b45 100644 --- a/sd/qa/unit/import-tests-smartart.cxx +++ b/sd/qa/unit/import-tests-smartart.cxx @@ -14,6 +14,8 @@ #include <com/sun/star/style/ParagraphAdjust.hpp> #include <com/sun/star/text/XText.hpp> +#include <comphelper/sequenceashashmap.hxx> + using namespace ::com::sun::star; class SdImportTestSmartArt : public SdModelTestBase @@ -490,6 +492,17 @@ void SdImportTestSmartArt::testAccentProcess() // below xFirstParent (a good position is 9081). CPPUNIT_ASSERT_LESS(nFirstChildTop, nFirstParentTop); + // Make sure that we have an arrow shape between the two pairs. + uno::Reference<beans::XPropertySet> xArrow(xGroup->getByIndex(1), uno::UNO_QUERY); + CPPUNIT_ASSERT(xArrow.is()); + comphelper::SequenceAsHashMap aCustomShapeGeometry( + xArrow->getPropertyValue("CustomShapeGeometry")); + // Without the accompanying fix in place, this test would have failed, i.e. + // the custom shape lacked a type -> arrow was not visible. + CPPUNIT_ASSERT(aCustomShapeGeometry["Type"].has<OUString>()); + OUString aType = aCustomShapeGeometry["Type"].get<OUString>(); + CPPUNIT_ASSERT_EQUAL(OUString("ooxml-rightArrow"), aType); + uno::Reference<drawing::XShapes> xSecondPair(xGroup->getByIndex(2), uno::UNO_QUERY); CPPUNIT_ASSERT(xSecondPair.is()); CPPUNIT_ASSERT_EQUAL(static_cast<sal_Int32>(3), xSecondPair->getCount()); _______________________________________________ Libreoffice-commits mailing list [email protected] https://lists.freedesktop.org/mailman/listinfo/libreoffice-commits
