summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGrzegorz Araminowicz <g.araminowicz@gmail.com>2017-08-09 15:29:05 +0200
committerThorsten Behrens <Thorsten.Behrens@CIB.de>2017-08-23 01:11:18 +0200
commit7d42e4b4c4fc3813eeb0f72807ffd17f47a86a64 (patch)
treedeec710179d621ce039884f41cfa8312b298974a
parent4d60d96a22ef2f67db7c7e99981447bd81f776c4 (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>
-rw-r--r--include/oox/drawingml/shape.hxx3
-rw-r--r--oox/source/drawingml/diagram/constraintlistcontext.cxx23
-rw-r--r--oox/source/drawingml/diagram/diagramlayoutatoms.cxx81
-rw-r--r--oox/source/drawingml/diagram/diagramlayoutatoms.hxx65
-rwxr-xr-xoox/source/drawingml/diagram/layoutatomvisitors.cxx29
-rwxr-xr-xoox/source/drawingml/diagram/layoutatomvisitors.hxx5
-rw-r--r--oox/source/drawingml/shape.cxx1
7 files changed, 139 insertions, 68 deletions
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 )