[Libreoffice-commits] core.git: include/oox oox/source

Grzegorz Araminowicz g.araminowicz at gmail.com
Tue Aug 22 23:13:48 UTC 2017


 include/oox/drawingml/shape.hxx                        |    3 
 oox/source/drawingml/diagram/constraintlistcontext.cxx |   23 ++--
 oox/source/drawingml/diagram/diagramlayoutatoms.cxx    |   81 +++++++++++++++--
 oox/source/drawingml/diagram/diagramlayoutatoms.hxx    |   65 +++++--------
 oox/source/drawingml/diagram/layoutatomvisitors.cxx    |   29 +++---
 oox/source/drawingml/diagram/layoutatomvisitors.hxx    |    5 -
 oox/source/drawingml/shape.cxx                         |    1 
 7 files changed, 139 insertions(+), 68 deletions(-)

New commits:
commit 7d42e4b4c4fc3813eeb0f72807ffd17f47a86a64
Author: Grzegorz Araminowicz <g.araminowicz at gmail.com>
Date:   Wed Aug 9 15:29:05 2017 +0200

    SmartArt: basic support for layout constraints
    
    Change-Id: Ie234bfd9760cdacb6a25c04d73a260e7e59ef7d6
    Reviewed-on: https://gerrit.libreoffice.org/41273
    Tested-by: Jenkins <ci at libreoffice.org>
    Reviewed-by: Thorsten Behrens <Thorsten.Behrens at CIB.de>

diff --git a/include/oox/drawingml/shape.hxx b/include/oox/drawingml/shape.hxx
index 9f16113b2ac5..55675c190986 100644
--- a/include/oox/drawingml/shape.hxx
+++ b/include/oox/drawingml/shape.hxx
@@ -143,6 +143,8 @@ public:
 
     void                            setName( const OUString& rName ) { msName = rName; }
     const OUString&                 getName( ) { return msName; }
+    void                            setInternalName( const OUString& rInternalName ) { msInternalName = rInternalName; }
+    const OUString&                 getInternalName() const { return msInternalName; }
     void                            setId( const OUString& rId ) { msId = rId; }
     const OUString&                 getId() { return msId; }
     void                            setHidden( bool bHidden ) { mbHidden = bHidden; }
@@ -280,6 +282,7 @@ protected:
 
     OUString                    msServiceName;
     OUString                    msName;
+    OUString                    msInternalName; // used by diagram; not displayed in UI
     OUString                    msId;
     sal_Int32                   mnSubType;      // if this type is not zero, then the shape is a placeholder
     OptValue< sal_Int32 >       moSubTypeIndex;
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 )


More information about the Libreoffice-commits mailing list