From f6850953dfd0ff0847e5a24bf921456a12ae47e4 Mon Sep 17 00:00:00 2001 From: Grzegorz Araminowicz Date: Wed, 23 Aug 2017 12:23:58 +0200 Subject: SmartArt: implement dir and maxDepth if node functions Change-Id: I4ef05b5bab1188cf349d1c7f5bbc9022bc79b21c Reviewed-on: https://gerrit.libreoffice.org/41452 Reviewed-by: Thorsten Behrens Tested-by: Thorsten Behrens --- oox/source/drawingml/diagram/diagram.cxx | 7 +- oox/source/drawingml/diagram/diagram.hxx | 5 ++ .../drawingml/diagram/diagramlayoutatoms.cxx | 71 ++++++++++++++++----- .../drawingml/diagram/diagramlayoutatoms.hxx | 6 +- sd/qa/unit/data/pptx/smartart-dir.pptx | Bin 0 -> 41593 bytes sd/qa/unit/data/pptx/smartart-maxdepth.pptx | Bin 0 -> 43256 bytes sd/qa/unit/import-tests.cxx | 31 +++++++++ 7 files changed, 102 insertions(+), 18 deletions(-) create mode 100755 sd/qa/unit/data/pptx/smartart-dir.pptx create mode 100755 sd/qa/unit/data/pptx/smartart-maxdepth.pptx diff --git a/oox/source/drawingml/diagram/diagram.cxx b/oox/source/drawingml/diagram/diagram.cxx index 2f33d9a79002..e0a8256e997d 100644 --- a/oox/source/drawingml/diagram/diagram.cxx +++ b/oox/source/drawingml/diagram/diagram.cxx @@ -65,8 +65,9 @@ void Point::dump() const } // dgm namespace -DiagramData::DiagramData() - : mpFillProperties( new FillProperties ) +DiagramData::DiagramData() : + mpFillProperties( new FillProperties ), + mnMaxDepth(0) { } @@ -298,6 +299,8 @@ void Diagram::build( ) const sal_Int32 nDepth=calcDepth(aPresOfNodeIterCalcLevel->first, getData()->getConnections()); aPresOfNodeIterCalcLevel->second = nDepth != 0 ? nDepth : -1; + if (nDepth > getData()->getMaxDepth()) + getData()->setMaxDepth(nDepth); ++aPresOfNodeIterCalcLevel; } diff --git a/oox/source/drawingml/diagram/diagram.hxx b/oox/source/drawingml/diagram/diagram.hxx index f31757f6ad91..3604d2607344 100644 --- a/oox/source/drawingml/diagram/diagram.hxx +++ b/oox/source/drawingml/diagram/diagram.hxx @@ -182,6 +182,10 @@ public: ::std::vector &getExtDrawings() { return maExtDrawings; } const dgm::Point* getRootPoint() const; + sal_Int32 getMaxDepth() const + { return mnMaxDepth; } + void setMaxDepth(sal_Int32 nDepth) + { mnMaxDepth = nDepth; } void dump() const; private: FillPropertiesPtr mpFillProperties; @@ -191,6 +195,7 @@ private: PointsNameMap maPointsPresNameMap; ConnectionNameMap maConnectionNameMap; StringMap maPresOfNameMap; + sal_Int32 mnMaxDepth; }; typedef std::shared_ptr< DiagramData > DiagramDataPtr; diff --git a/oox/source/drawingml/diagram/diagramlayoutatoms.cxx b/oox/source/drawingml/diagram/diagramlayoutatoms.cxx index 7bfe4996edef..791381ccda87 100644 --- a/oox/source/drawingml/diagram/diagramlayoutatoms.cxx +++ b/oox/source/drawingml/diagram/diagramlayoutatoms.cxx @@ -29,7 +29,6 @@ #include "drawingml/textparagraph.hxx" #include "drawingml/textrun.hxx" #include "drawingml/customshapeproperties.hxx" -#include "layoutnodecontext.hxx" using namespace ::com::sun::star; using namespace ::com::sun::star::uno; @@ -63,17 +62,17 @@ ConditionAttr::ConditionAttr() : mnFunc( 0 ) , mnArg( 0 ) , mnOp( 0 ) + , mnVal( 0 ) { - } void ConditionAttr::loadFromXAttr( const Reference< XFastAttributeList >& xAttr ) { mnFunc = xAttr->getOptionalValueToken( XML_func, 0 ); - // mnArg will be -1 for "none" or any other unknown value - mnArg = LayoutNodeContext::tagToVarIdx( xAttr->getOptionalValueToken( XML_arg, XML_none ) ); + mnArg = xAttr->getOptionalValueToken( XML_arg, XML_none ); mnOp = xAttr->getOptionalValueToken( XML_op, 0 ); msVal = xAttr->getOptionalValue( XML_val ); + mnVal = xAttr->getOptionalValueToken( XML_val, 0 ); } void LayoutAtom::dump(int level) @@ -123,15 +122,36 @@ bool ConditionAtom::compareResult(sal_Int32 nOperator, sal_Int32 nFirst, sal_Int } } -sal_Int32 ConditionAtom::getNodeCount() const +bool ConditionAtom::compareResult(sal_Int32 nOperator, const OUString& sFirst, const OUString& sSecond) +{ + switch (nOperator) + { + case XML_equ: return sFirst == sSecond; + case XML_neq: return sFirst != sSecond; + default: + SAL_WARN("oox.drawingml", "unsupported operator: " << nOperator); + return false; + } +} + +const dgm::Point* ConditionAtom::getPresNode() const { - sal_Int32 nCount = 0; const DiagramData::PointsNameMap& rPoints = mrLayoutNode.getDiagram().getData()->getPointsPresNameMap(); DiagramData::PointsNameMap::const_iterator aDataNode = rPoints.find(mrLayoutNode.getName()); if (aDataNode != rPoints.end()) { - SAL_WARN_IF(aDataNode->second.size() > 1, "oox.drawingml", "multiple nodes found; calculating cnt for first one"); - const dgm::Point* pPoint = aDataNode->second.front(); + SAL_WARN_IF(aDataNode->second.size() > 1, "oox.drawingml", "multiple nodes found; taking first one"); + return aDataNode->second.front(); + } + return nullptr; +} + +sal_Int32 ConditionAtom::getNodeCount() const +{ + sal_Int32 nCount = 0; + const dgm::Point* pPoint = getPresNode(); + if (pPoint) + { OUString sNodeId = ""; for (const auto& aCxn : mrLayoutNode.getDiagram().getData()->getConnections()) @@ -150,15 +170,31 @@ sal_Int32 ConditionAtom::getNodeCount() const const std::vector& ConditionAtom::getChildren() const { - bool bDecisionVar=true; - // HACK - if( maCond.mnFunc == XML_var && maCond.mnArg == XML_dir && maCond.mnOp == XML_equ && maCond.msVal != "norm" ) - bDecisionVar=false; + bool bDecisionVar = true; + switch (maCond.mnFunc) + { + case XML_var: + { + const dgm::Point* pPoint = getPresNode(); + if (pPoint && maCond.mnArg == XML_dir) + bDecisionVar = compareResult(maCond.mnOp, pPoint->mnDirection, maCond.mnVal); + break; + } - if (maCond.mnFunc == XML_cnt) + case XML_cnt: bDecisionVar = compareResult(maCond.mnOp, getNodeCount(), maCond.msVal.toInt32()); + break; + + case XML_maxDepth: + bDecisionVar = compareResult(maCond.mnOp, mrLayoutNode.getDiagram().getData()->getMaxDepth(), maCond.msVal.toInt32()); + break; + + default: + SAL_WARN("oox.drawingml", "unknown function " << maCond.mnFunc); + break; + } - if( bDecisionVar ) + if (bDecisionVar) return mpChildNodes; else return mpElseChildNodes; @@ -337,7 +373,12 @@ void AlgAtom::layoutShape( const ShapePtr& rShape, if (nIncY) aChildSize.Height /= (nCount + (nCount-1)*fSpace); - awt::Point aCurrPos = rShape->getChildren().front()->getPosition(); + awt::Point aCurrPos(0, 0); + if (nIncX == -1) + aCurrPos.X = rShape->getSize().Width - aChildSize.Width; + if (nIncY == -1) + aCurrPos.Y = rShape->getSize().Height - aChildSize.Height; + for (auto & aCurrShape : rShape->getChildren()) { aCurrShape->setPosition(aCurrPos); diff --git a/oox/source/drawingml/diagram/diagramlayoutatoms.hxx b/oox/source/drawingml/diagram/diagramlayoutatoms.hxx index cb7c84e9e532..92ef240e6785 100644 --- a/oox/source/drawingml/diagram/diagramlayoutatoms.hxx +++ b/oox/source/drawingml/diagram/diagramlayoutatoms.hxx @@ -60,6 +60,7 @@ struct ConditionAttr sal_Int32 mnArg; sal_Int32 mnOp; OUString msVal; + sal_Int32 mnVal; }; struct Constraint @@ -181,9 +182,12 @@ public: { mbElse=true; } virtual void addChild( const LayoutAtomPtr & pNode ) override; virtual const std::vector& getChildren() const override; +private: static bool compareResult(sal_Int32 nOperator, sal_Int32 nFirst, sal_Int32 nSecond); + static bool compareResult(sal_Int32 nOperator, const OUString& sFirst, const OUString& sSecond); + const dgm::Point* getPresNode() const; sal_Int32 getNodeCount() const; -private: + bool mbElse; IteratorAttr maIter; ConditionAttr maCond; diff --git a/sd/qa/unit/data/pptx/smartart-dir.pptx b/sd/qa/unit/data/pptx/smartart-dir.pptx new file mode 100755 index 000000000000..ab94459d262f Binary files /dev/null and b/sd/qa/unit/data/pptx/smartart-dir.pptx differ diff --git a/sd/qa/unit/data/pptx/smartart-maxdepth.pptx b/sd/qa/unit/data/pptx/smartart-maxdepth.pptx new file mode 100755 index 000000000000..545d744bd229 Binary files /dev/null and b/sd/qa/unit/data/pptx/smartart-maxdepth.pptx differ diff --git a/sd/qa/unit/import-tests.cxx b/sd/qa/unit/import-tests.cxx index e4258b161730..7546689852a5 100644 --- a/sd/qa/unit/import-tests.cxx +++ b/sd/qa/unit/import-tests.cxx @@ -166,6 +166,8 @@ public: void testSmartArtChildren(); void testSmartArtText(); void testSmartArtCnt(); + void testSmartArtDir(); + void testSmartArtMaxDepth(); void testSmartArtRotation(); void testTdf109223(); void testTdf109187(); @@ -243,6 +245,8 @@ public: CPPUNIT_TEST(testSmartArtChildren); CPPUNIT_TEST(testSmartArtText); CPPUNIT_TEST(testSmartArtCnt); + CPPUNIT_TEST(testSmartArtDir); + CPPUNIT_TEST(testSmartArtMaxDepth); CPPUNIT_TEST(testSmartArtRotation); CPPUNIT_TEST(testTdf109223); CPPUNIT_TEST(testTdf109187); @@ -2336,6 +2340,33 @@ void SdImportTest::testSmartArtCnt() xDocShRef->DoClose(); } +void SdImportTest::testSmartArtDir() +{ + sd::DrawDocShellRef xDocShRef = loadURL(m_directories.getURLFromSrc("sd/qa/unit/data/pptx/smartart-dir.pptx"), PPTX); + uno::Reference xShapeGroup(getShapeFromPage(0, 0, xDocShRef), uno::UNO_QUERY_THROW); + CPPUNIT_ASSERT_EQUAL(sal_Int32(2), xShapeGroup->getCount()); + + uno::Reference xShape0(xShapeGroup->getByIndex(0), uno::UNO_QUERY_THROW); + uno::Reference xShape1(xShapeGroup->getByIndex(1), uno::UNO_QUERY_THROW); + CPPUNIT_ASSERT(xShape0->getPosition().X > xShape1->getPosition().X); + + xDocShRef->DoClose(); +} + +void SdImportTest::testSmartArtMaxDepth() +{ + sd::DrawDocShellRef xDocShRef = loadURL(m_directories.getURLFromSrc("sd/qa/unit/data/pptx/smartart-maxdepth.pptx"), PPTX); + uno::Reference xShapeGroup(getShapeFromPage(0, 0, xDocShRef), uno::UNO_QUERY_THROW); + CPPUNIT_ASSERT_EQUAL(sal_Int32(2), xShapeGroup->getCount()); + + uno::Reference xText0(xShapeGroup->getByIndex(0), uno::UNO_QUERY_THROW); + CPPUNIT_ASSERT_EQUAL(OUString("first"), xText0->getString()); + uno::Reference xText1(xShapeGroup->getByIndex(1), uno::UNO_QUERY_THROW); + CPPUNIT_ASSERT_EQUAL(OUString("second"), xText1->getString()); + + xDocShRef->DoClose(); +} + void SdImportTest::testSmartArtRotation() { sd::DrawDocShellRef xDocShRef = loadURL(m_directories.getURLFromSrc("sd/qa/unit/data/pptx/smartart-rotation.pptx"), PPTX); -- cgit v1.2.3