diff options
author | Grzegorz Araminowicz <g.araminowicz@gmail.com> | 2017-08-09 15:29:05 +0200 |
---|---|---|
committer | Thorsten Behrens <Thorsten.Behrens@CIB.de> | 2017-08-23 01:11:18 +0200 |
commit | 7d42e4b4c4fc3813eeb0f72807ffd17f47a86a64 (patch) | |
tree | deec710179d621ce039884f41cfa8312b298974a /oox | |
parent | 4d60d96a22ef2f67db7c7e99981447bd81f776c4 (diff) |
SmartArt: basic support for layout constraints
Change-Id: Ie234bfd9760cdacb6a25c04d73a260e7e59ef7d6
Reviewed-on: https://gerrit.libreoffice.org/41273
Tested-by: Jenkins <ci@libreoffice.org>
Reviewed-by: Thorsten Behrens <Thorsten.Behrens@CIB.de>
Diffstat (limited to 'oox')
-rw-r--r-- | oox/source/drawingml/diagram/constraintlistcontext.cxx | 23 | ||||
-rw-r--r-- | oox/source/drawingml/diagram/diagramlayoutatoms.cxx | 81 | ||||
-rw-r--r-- | oox/source/drawingml/diagram/diagramlayoutatoms.hxx | 65 | ||||
-rwxr-xr-x | oox/source/drawingml/diagram/layoutatomvisitors.cxx | 29 | ||||
-rwxr-xr-x | oox/source/drawingml/diagram/layoutatomvisitors.hxx | 5 | ||||
-rw-r--r-- | oox/source/drawingml/shape.cxx | 1 |
6 files changed, 136 insertions, 68 deletions
diff --git a/oox/source/drawingml/diagram/constraintlistcontext.cxx b/oox/source/drawingml/diagram/constraintlistcontext.cxx index f7a10f617406..1e67f12b6615 100644 --- a/oox/source/drawingml/diagram/constraintlistcontext.cxx +++ b/oox/source/drawingml/diagram/constraintlistcontext.cxx @@ -53,17 +53,18 @@ ConstraintListContext::onCreateContext( ::sal_Int32 aElement, std::shared_ptr< ConstraintAtom > pNode( new ConstraintAtom(mpNode->getLayoutNode()) ); mpNode->addChild( pNode ); - pNode->setFor( rAttribs.getToken( XML_for, XML_none ) ); - pNode->setForName( rAttribs.getString( XML_forName, "" ) ); - pNode->setPointType( rAttribs.getToken( XML_ptType, XML_none ) ); - pNode->setType( rAttribs.getToken( XML_type, XML_none ) ); - pNode->setRefFor( rAttribs.getToken( XML_refFor, XML_none ) ); - pNode->setRefForName( rAttribs.getString( XML_refForName, "" ) ); - pNode->setRefType( rAttribs.getToken( XML_refType, XML_none ) ); - pNode->setRefPointType( rAttribs.getToken( XML_refPtType, XML_none ) ); - pNode->setFactor( rAttribs.getDouble( XML_fact, 1.0 ) ); - pNode->setValue( rAttribs.getDouble( XML_val, 0.0 ) ); - pNode->setOperator( rAttribs.getToken( XML_op, XML_none ) ); + Constraint& rConstraint = pNode->getConstraint(); + rConstraint.mnFor = rAttribs.getToken( XML_for, XML_none ); + rConstraint.msForName = rAttribs.getString( XML_forName, "" ); + rConstraint.mnPointType = rAttribs.getToken( XML_ptType, XML_none ); + rConstraint.mnType = rAttribs.getToken( XML_type, XML_none ); + rConstraint.mnRefFor = rAttribs.getToken( XML_refFor, XML_none ); + rConstraint.msRefForName = rAttribs.getString( XML_refForName, "" ); + rConstraint.mnRefType = rAttribs.getToken( XML_refType, XML_none ); + rConstraint.mnRefPointType = rAttribs.getToken( XML_refPtType, XML_none ); + rConstraint.mfFactor = rAttribs.getDouble( XML_fact, 1.0 ); + rConstraint.mfValue = rAttribs.getDouble( XML_val, 0.0 ); + rConstraint.mnOperator = rAttribs.getToken( XML_op, XML_none ); break; } default: diff --git a/oox/source/drawingml/diagram/diagramlayoutatoms.cxx b/oox/source/drawingml/diagram/diagramlayoutatoms.cxx index 07d018736c83..672cfee8aff9 100644 --- a/oox/source/drawingml/diagram/diagramlayoutatoms.cxx +++ b/oox/source/drawingml/diagram/diagramlayoutatoms.cxx @@ -182,23 +182,94 @@ void ConstraintAtom::accept( LayoutAtomVisitor& rVisitor ) rVisitor.visit(*this); } +void ConstraintAtom::parseConstraint(std::vector<Constraint>& rConstraints) const +{ + // accepting only basic equality constraints + if (!maConstraint.msForName.isEmpty() && + (maConstraint.mnOperator == XML_none || maConstraint.mnOperator == XML_equ) && + maConstraint.mnType != XML_none && + maConstraint.mfValue == 0) + { + rConstraints.push_back(maConstraint); + } +} + void AlgAtom::accept( LayoutAtomVisitor& rVisitor ) { rVisitor.visit(*this); } -void AlgAtom::layoutShape( const ShapePtr& rShape ) const +void AlgAtom::layoutShape( const ShapePtr& rShape, + const std::vector<Constraint>& rConstraints ) const { switch(mnType) { case XML_composite: { - // all shapes fill parent + // layout shapes using basic constraints + + 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 : rConstraints) + { + 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; + else + aProperties[rConstr.msForName][rConstr.mnType] = 0; // TODO: val + } + } for (auto & aCurrShape : rShape->getChildren()) { - aCurrShape->setSize(rShape->getSize()); - aCurrShape->setChildSize(rShape->getSize()); + awt::Size aSize = rShape->getSize(); + awt::Point aPos(0, 0); + + const LayoutPropertyMap::const_iterator aPropIt = aProperties.find(aCurrShape->getInternalName()); + if (aPropIt != aProperties.end()) + { + const LayoutProperty& rProp = aPropIt->second; + LayoutProperty::const_iterator it, it2; + + if ( (it = rProp.find(XML_w)) != rProp.end() ) + aSize.Width = it->second; + if ( (it = rProp.find(XML_h)) != rProp.end() ) + aSize.Height = it->second; + + if ( (it = rProp.find(XML_l)) != rProp.end() ) + aPos.X = it->second; + else if ( (it = rProp.find(XML_ctrX)) != rProp.end() ) + aPos.X = it->second - aSize.Width/2; + + if ( (it = rProp.find(XML_t)) != rProp.end()) + aPos.Y = it->second; + else if ( (it = rProp.find(XML_ctrY)) != rProp.end() ) + aPos.Y = it->second - aSize.Height/2; + + if ( (it = rProp.find(XML_l)) != rProp.end() && (it2 = rProp.find(XML_r)) != rProp.end() ) + aSize.Width = it2->second - it->second; + if ( (it = rProp.find(XML_t)) != rProp.end() && (it2 = rProp.find(XML_b)) != rProp.end() ) + aSize.Height = it2->second - it->second; + + aSize.Width = std::min(aSize.Width, rShape->getSize().Width - aPos.X); + aSize.Height = std::min(aSize.Height, rShape->getSize().Height - aPos.Y); + } + else + SAL_WARN("oox.drawingml", "composite layout properties not found for shape " << aCurrShape->getInternalName()); + + aCurrShape->setSize(aSize); + aCurrShape->setChildSize(aSize); + aCurrShape->setPosition(aPos); } break; } @@ -390,7 +461,7 @@ void AlgAtom::layoutShape( const ShapePtr& rShape ) const SAL_INFO( "oox.drawingml", - "Layouting shape " << mrLayoutNode.getName() << ", alg type: " << mnType << ", (" + "Layouting shape " << rShape->getInternalName() << ", alg type: " << mnType << ", (" << rShape->getPosition().X << "," << rShape->getPosition().Y << "," << rShape->getSize().Width << "," << rShape->getSize().Height << ")"); } diff --git a/oox/source/drawingml/diagram/diagramlayoutatoms.hxx b/oox/source/drawingml/diagram/diagramlayoutatoms.hxx index f7a059d9b2d3..a7ff21759174 100644 --- a/oox/source/drawingml/diagram/diagramlayoutatoms.hxx +++ b/oox/source/drawingml/diagram/diagramlayoutatoms.hxx @@ -64,6 +64,24 @@ struct ConditionAttr OUString msVal; }; +struct Constraint +{ + sal_Int32 mnFor; + OUString msForName; + sal_Int32 mnPointType; + sal_Int32 mnType; + sal_Int32 mnRefFor; + OUString msRefForName; + sal_Int32 mnRefType; + sal_Int32 mnRefPointType; + double mfFactor; + double mfValue; + sal_Int32 mnOperator; +}; + +typedef std::map<sal_Int32, sal_Int32> LayoutProperty; +typedef std::map<OUString, LayoutProperty> LayoutPropertyMap; + struct LayoutAtomVisitor; class LayoutAtom; class LayoutNode; @@ -107,47 +125,13 @@ class ConstraintAtom : public LayoutAtom { public: - ConstraintAtom(const LayoutNode& rLayoutNode) : LayoutAtom(rLayoutNode), - mnFor(-1), msForName(), mnPointType(-1), mnType(-1), mnRefFor(-1), msRefForName(), - mnRefType(-1), mnRefPointType(-1), mfFactor(1.0), mfValue(0.0), mnOperator(0) - {} - + ConstraintAtom(const LayoutNode& rLayoutNode) : LayoutAtom(rLayoutNode) {} virtual void accept( LayoutAtomVisitor& ) override; - - void setFor( sal_Int32 nToken ) - { mnFor = nToken; } - void setForName( const OUString & sName ) - { msForName = sName; } - void setPointType( sal_Int32 nToken ) - { mnPointType = nToken; } - void setType( sal_Int32 nToken ) - { mnType = nToken; } - void setRefFor( sal_Int32 nToken ) - { mnRefFor = nToken; } - void setRefForName( const OUString & sName ) - { msRefForName = sName; } - void setRefType( sal_Int32 nToken ) - { mnRefType = nToken; } - void setRefPointType( sal_Int32 nToken ) - { mnRefPointType = nToken; } - void setFactor( const double& fVal ) - { mfFactor = fVal; } - void setValue( const double& fVal ) - { mfValue = fVal; } - void setOperator( sal_Int32 nToken ) - { mnOperator = nToken; } + Constraint& getConstraint() + { return maConstraint; } + void parseConstraint(std::vector<Constraint>& rConstraints) const; private: - sal_Int32 mnFor; - OUString msForName; - sal_Int32 mnPointType; - sal_Int32 mnType; - sal_Int32 mnRefFor; - OUString msRefForName; - sal_Int32 mnRefType; - sal_Int32 mnRefPointType; - double mfFactor; - double mfValue; - sal_Int32 mnOperator; + Constraint maConstraint; }; class AlgAtom @@ -164,7 +148,8 @@ public: { mnType = nToken; } void addParam( sal_Int32 nType, sal_Int32 nVal ) { maMap[nType]=nVal; } - void layoutShape( const ShapePtr& rShape ) const; + void layoutShape( const ShapePtr& rShape, + const std::vector<Constraint>& rConstraints ) const; private: sal_Int32 mnType; ParamMap maMap; diff --git a/oox/source/drawingml/diagram/layoutatomvisitors.cxx b/oox/source/drawingml/diagram/layoutatomvisitors.cxx index 378f4cad2f44..f5580484b48e 100755 --- a/oox/source/drawingml/diagram/layoutatomvisitors.cxx +++ b/oox/source/drawingml/diagram/layoutatomvisitors.cxx @@ -36,7 +36,7 @@ void ShapeCreationVisitor::defaultVisit(LayoutAtom const & rAtom) void ShapeCreationVisitor::visit(ConstraintAtom& /*rAtom*/) { - // TODO: eval the constraints + // stop processing } void ShapeCreationVisitor::visit(AlgAtom& rAtom) @@ -112,8 +112,12 @@ void ShapeCreationVisitor::visit(LayoutNode& rAtom) if (rAtom.getExistingShape()) { // reuse existing shape - if (rAtom.setupShape(rAtom.getExistingShape(), pNewNode)) - rAtom.addNodeShape(rAtom.getExistingShape()); + ShapePtr pShape = rAtom.getExistingShape(); + if (rAtom.setupShape(pShape, pNewNode)) + { + pShape->setInternalName(rAtom.getName()); + rAtom.addNodeShape(pShape); + } } else { @@ -131,6 +135,7 @@ void ShapeCreationVisitor::visit(LayoutNode& rAtom) if (rAtom.setupShape(pShape, pNewNode)) { + pShape->setInternalName(rAtom.getName()); pCurrParent->addChild(pShape); pCurrParent = pShape; rAtom.addNodeShape(pShape); @@ -227,17 +232,18 @@ void ShapeLayoutingVisitor::defaultVisit(LayoutAtom const & rAtom) pAtom->accept(*this); } -void ShapeLayoutingVisitor::visit(ConstraintAtom& /*rAtom*/) +void ShapeLayoutingVisitor::visit(ConstraintAtom& rAtom) { - // stop processing + if (meLookFor == CONSTRAINT) + rAtom.parseConstraint(maConstraints); } void ShapeLayoutingVisitor::visit(AlgAtom& rAtom) { - if (mbLookForAlg) + if (meLookFor == ALGORITHM) { for (const auto& pShape : rAtom.getLayoutNode().getNodeShapes()) - rAtom.layoutShape(pShape); + rAtom.layoutShape(pShape, maConstraints); } } @@ -258,13 +264,16 @@ void ShapeLayoutingVisitor::visit(ChooseAtom& rAtom) void ShapeLayoutingVisitor::visit(LayoutNode& rAtom) { - if (mbLookForAlg) + if (meLookFor != LAYOUT_NODE) return; // process alg atoms first, nested layout nodes afterwards - mbLookForAlg = true; + meLookFor = CONSTRAINT; + defaultVisit(rAtom); + meLookFor = ALGORITHM; defaultVisit(rAtom); - mbLookForAlg = false; + maConstraints.clear(); + meLookFor = LAYOUT_NODE; defaultVisit(rAtom); } diff --git a/oox/source/drawingml/diagram/layoutatomvisitors.hxx b/oox/source/drawingml/diagram/layoutatomvisitors.hxx index 3c514ec15ae4..8151a5a5aec3 100755 --- a/oox/source/drawingml/diagram/layoutatomvisitors.hxx +++ b/oox/source/drawingml/diagram/layoutatomvisitors.hxx @@ -74,7 +74,8 @@ public: class ShapeLayoutingVisitor : public LayoutAtomVisitor { - bool mbLookForAlg; + std::vector<Constraint> maConstraints; + enum {LAYOUT_NODE, CONSTRAINT, ALGORITHM} meLookFor; void defaultVisit(LayoutAtom const & rAtom); virtual void visit(ConstraintAtom& rAtom) override; @@ -87,7 +88,7 @@ class ShapeLayoutingVisitor : public LayoutAtomVisitor public: ShapeLayoutingVisitor() : - mbLookForAlg(false) + meLookFor(LAYOUT_NODE) {} }; diff --git a/oox/source/drawingml/shape.cxx b/oox/source/drawingml/shape.cxx index 77730ecd2aff..ada0aa35476e 100644 --- a/oox/source/drawingml/shape.cxx +++ b/oox/source/drawingml/shape.cxx @@ -147,6 +147,7 @@ Shape::Shape( const ShapePtr& pSourceShape ) , mxShape() , msServiceName( pSourceShape->msServiceName ) , msName( pSourceShape->msName ) +, msInternalName( pSourceShape->msInternalName ) , msId( pSourceShape->msId ) , mnSubType( pSourceShape->mnSubType ) , moSubTypeIndex( pSourceShape->moSubTypeIndex ) |