summaryrefslogtreecommitdiffstats
path: root/oox
diff options
context:
space:
mode:
authorMiklos Vajna <vmiklos@collabora.com>2020-07-31 11:04:02 +0200
committerMiklos Vajna <vmiklos@collabora.com>2020-08-05 08:54:56 +0200
commita7e1a2c2bb6b02a41b9eb1d2dccbbd28e0eac49b (patch)
treedf24b4c82a8d76ba809b31a33bde36234cc05f0f /oox
parentoox smartart: start parsing rule lists (diff)
downloadcore-a7e1a2c2bb6b02a41b9eb1d2dccbbd28e0eac49b.tar.gz
core-a7e1a2c2bb6b02a41b9eb1d2dccbbd28e0eac49b.zip
oox smartart: consider rules when scaling in linear layout
The bugdoc has an arrow shape which is 100% wide, and there are multiple shapes before it, which also have a 100% wide constraint. The reason PowerPoint scales down the shapes (but not the arrow) is because rules declare it should happen this way. So start taking rules into account in linear layouts. (cherry picked from commit 0024c48b4822062995effed7db4f1281196384bb) Conflicts: sd/qa/unit/import-tests-smartart.cxx Change-Id: I352443277e88be0eb711659489587127727a258f Reviewed-on: https://gerrit.libreoffice.org/c/core/+/100110 Tested-by: Jenkins CollaboraOffice <jenkinscollaboraoffice@gmail.com> Reviewed-by: Miklos Vajna <vmiklos@collabora.com>
Diffstat (limited to 'oox')
-rw-r--r--oox/source/drawingml/diagram/diagram.cxx20
-rw-r--r--oox/source/drawingml/diagram/diagramlayoutatoms.cxx72
-rw-r--r--oox/source/drawingml/diagram/layoutatomvisitors.cxx6
3 files changed, 87 insertions, 11 deletions
diff --git a/oox/source/drawingml/diagram/diagram.cxx b/oox/source/drawingml/diagram/diagram.cxx
index a03a06c39125..509a1f845e25 100644
--- a/oox/source/drawingml/diagram/diagram.cxx
+++ b/oox/source/drawingml/diagram/diagram.cxx
@@ -82,6 +82,25 @@ static void sortChildrenByZOrder(const ShapePtr& pShape)
sortChildrenByZOrder(rChild);
}
+/// Removes empty group shapes, now that their spacing influenced the layout.
+static void removeUnneededGroupShapes(const ShapePtr& pShape)
+{
+ std::vector<ShapePtr>& rChildren = pShape->getChildren();
+
+ rChildren.erase(std::remove_if(rChildren.begin(), rChildren.end(),
+ [](const ShapePtr& aChild) {
+ return aChild->getServiceName()
+ == "com.sun.star.drawing.GroupShape"
+ && aChild->getChildren().empty();
+ }),
+ rChildren.end());
+
+ for (const auto& pChild : rChildren)
+ {
+ removeUnneededGroupShapes(pChild);
+ }
+}
+
void Diagram::addTo( const ShapePtr & pParentShape )
{
if (pParentShape->getSize().Width == 0 || pParentShape->getSize().Height == 0)
@@ -103,6 +122,7 @@ void Diagram::addTo( const ShapePtr & pParentShape )
mpLayout->getNode()->accept(aLayoutingVisitor);
sortChildrenByZOrder(pParentShape);
+ removeUnneededGroupShapes(pParentShape);
}
ShapePtr pBackground(new Shape("com.sun.star.drawing.CustomShape"));
diff --git a/oox/source/drawingml/diagram/diagramlayoutatoms.cxx b/oox/source/drawingml/diagram/diagramlayoutatoms.cxx
index 82e826da0dda..b748298f7c1c 100644
--- a/oox/source/drawingml/diagram/diagramlayoutatoms.cxx
+++ b/oox/source/drawingml/diagram/diagramlayoutatoms.cxx
@@ -19,6 +19,8 @@
#include "diagramlayoutatoms.hxx"
+#include <set>
+
#include "layoutatomvisitorbase.hxx"
#include <basegfx/numeric/ftools.hxx>
@@ -479,10 +481,21 @@ void ApplyConstraintToLayout(const Constraint& rConstraint, LayoutPropertyMap& r
}
}
-void AlgAtom::layoutShape( const ShapePtr& rShape,
- const std::vector<Constraint>& rConstraints,
- const std::vector<Rule>& /*rRules*/ )
+void AlgAtom::layoutShape(const ShapePtr& rShape, const std::vector<Constraint>& rConstraints,
+ const std::vector<Rule>& rRules)
{
+ if (mnType != XML_lin)
+ {
+ // TODO Handle spacing from constraints for non-lin algorithms as well.
+ rShape->getChildren().erase(
+ std::remove_if(rShape->getChildren().begin(), rShape->getChildren().end(),
+ [](const ShapePtr& aChild) {
+ return aChild->getServiceName() == "com.sun.star.drawing.GroupShape"
+ && aChild->getChildren().empty();
+ }),
+ rShape->getChildren().end());
+ }
+
switch(mnType)
{
case XML_composite:
@@ -929,6 +942,45 @@ void AlgAtom::layoutShape( const ShapePtr& rShape,
}
// first approximation of children size
+ std::set<OUString> aChildrenToShrink;
+ for (const auto& rRule : rRules)
+ {
+ // Consider rules: when scaling down, only change children where the rule allows
+ // doing so.
+ aChildrenToShrink.insert(rRule.msForName);
+ }
+
+ if (!aChildrenToShrink.empty())
+ {
+ // Have scaling info from rules: then only count scaled children.
+ for (auto& aCurrShape : rShape->getChildren())
+ {
+ if (aChildrenToShrink.find(aCurrShape->getInternalName())
+ == aChildrenToShrink.end())
+ {
+ if (nCount > 1)
+ {
+ --nCount;
+ }
+ }
+ }
+
+ // No manual spacing: spacings are children as well.
+ aSpaceSize = awt::Size();
+ }
+ else
+ {
+ // TODO Handle spacing from constraints without rules as well.
+ rShape->getChildren().erase(
+ std::remove_if(rShape->getChildren().begin(), rShape->getChildren().end(),
+ [](const ShapePtr& aChild) {
+ return aChild->getServiceName()
+ == "com.sun.star.drawing.GroupShape"
+ && aChild->getChildren().empty();
+ }),
+ rShape->getChildren().end());
+ nCount = rShape->getChildren().size();
+ }
awt::Size aChildSize = rShape->getSize();
if (nDir == XML_fromL || nDir == XML_fromR)
aChildSize.Width /= nCount;
@@ -980,8 +1032,18 @@ void AlgAtom::layoutShape( const ShapePtr& rShape,
aSize.Width = oWidth.get();
if (oHeight.has())
aSize.Height = oHeight.get();
- aSize.Width *= fWidthScale;
- aSize.Height *= fHeightScale;
+ if (aChildrenToShrink.empty()
+ || aChildrenToShrink.find(aCurrShape->getInternalName())
+ != aChildrenToShrink.end())
+ {
+ aSize.Width *= fWidthScale;
+ }
+ if (aChildrenToShrink.empty()
+ || aChildrenToShrink.find(aCurrShape->getInternalName())
+ != aChildrenToShrink.end())
+ {
+ aSize.Height *= fHeightScale;
+ }
aCurrShape->setSize(aSize);
aCurrShape->setChildSize(aSize);
diff --git a/oox/source/drawingml/diagram/layoutatomvisitors.cxx b/oox/source/drawingml/diagram/layoutatomvisitors.cxx
index 53c52a2ed3a5..ccea74c2efde 100644
--- a/oox/source/drawingml/diagram/layoutatomvisitors.cxx
+++ b/oox/source/drawingml/diagram/layoutatomvisitors.cxx
@@ -123,12 +123,6 @@ void ShapeCreationVisitor::visit(LayoutNode& rAtom)
meLookFor = LAYOUT_NODE;
defaultVisit(rAtom);
- // remove unneeded empty group shapes
- pCurrParent->getChildren().erase(
- std::remove_if(pCurrParent->getChildren().begin(), pCurrParent->getChildren().end(),
- [] (const ShapePtr & aChild) { return aChild->getServiceName() == "com.sun.star.drawing.GroupShape" && aChild->getChildren().empty(); }),
- pCurrParent->getChildren().end());
-
meLookFor = ALGORITHM;
defaultVisit(rAtom);
meLookFor = LAYOUT_NODE;