[Libreoffice-commits] core.git: Branch 'distro/collabora/cp-6.2' - 2 commits - oox/source sd/qa
Grzegorz Araminowicz (via logerrit)
logerrit at kemper.freedesktop.org
Wed Jul 10 20:11:52 UTC 2019
oox/source/drawingml/diagram/diagram.hxx | 10 ++++
oox/source/drawingml/diagram/diagramlayoutatoms.cxx | 27 ++++++++++--
oox/source/drawingml/diagram/diagramlayoutatoms.hxx | 18 ++++++--
oox/source/drawingml/diagram/layoutatomvisitors.cxx | 38 ++++++++++++++----
oox/source/drawingml/diagram/layoutatomvisitors.hxx | 6 ++
oox/source/drawingml/diagram/layoutnodecontext.cxx | 5 +-
sd/qa/unit/data/pptx/smartart-recursion.pptx |binary
sd/qa/unit/import-tests-smartart.cxx | 42 ++++++++++++++++++++
8 files changed, 128 insertions(+), 18 deletions(-)
New commits:
commit 674d58312a3682df6be2cf8680aab4e3d1528789
Author: Grzegorz Araminowicz <grzegorz.araminowicz at collabora.com>
AuthorDate: Tue Jun 11 08:31:18 2019 +0200
Commit: Grzegorz Araminowicz <grzegorz.araminowicz at collabora.com>
CommitDate: Wed Jul 10 22:11:24 2019 +0200
SmartArt: support ForEach references
ForEach 'ref' parameter causes specified ForEach node to be used instead.
Used to create recursive structures like organisation charts.
Change-Id: Iee61b2e103759355b59beb8d3f33eb3cce47c590
Reviewed-on: https://gerrit.libreoffice.org/74271
Tested-by: Jenkins
Reviewed-by: Grzegorz Araminowicz <grzegorz.araminowicz at collabora.com>
Reviewed-on: https://gerrit.libreoffice.org/75340
Tested-by: Jenkins CollaboraOffice <jenkinscollaboraoffice at gmail.com>
diff --git a/oox/source/drawingml/diagram/diagram.hxx b/oox/source/drawingml/diagram/diagram.hxx
index a0955b124230..c5b8ec10eaf6 100644
--- a/oox/source/drawingml/diagram/diagram.hxx
+++ b/oox/source/drawingml/diagram/diagram.hxx
@@ -149,6 +149,8 @@ typedef std::vector< Point > Points;
class Diagram;
class LayoutNode;
typedef std::shared_ptr< LayoutNode > LayoutNodePtr;
+class LayoutAtom;
+typedef std::shared_ptr<LayoutAtom> LayoutAtomPtr;
typedef std::map< OUString, css::uno::Reference<css::xml::dom::XDocument> > DiagramDomMap;
@@ -205,6 +207,8 @@ private:
typedef std::shared_ptr< DiagramData > DiagramDataPtr;
+typedef std::map<OUString, LayoutAtomPtr> LayoutAtomMap;
+
class DiagramLayout
{
public:
@@ -233,6 +237,8 @@ public:
{ return mpStyleData; }
const DiagramDataPtr & getStyleData() const
{ return mpStyleData; }
+ LayoutAtomMap & getLayoutAtomMap()
+ { return maLayoutAtomMap; }
private:
const Diagram& mrDgm;
@@ -248,6 +254,8 @@ private:
// TODO
// catLst
// clrData
+
+ LayoutAtomMap maLayoutAtomMap;
};
typedef std::shared_ptr< DiagramLayout > DiagramLayoutPtr;
@@ -283,6 +291,8 @@ public:
{ return mpData; }
void setLayout( const DiagramLayoutPtr & pLayout )
{ mpLayout = pLayout; }
+ const DiagramLayoutPtr& getLayout() const
+ { return mpLayout; }
DiagramQStyleMap& getStyles() { return maStyles; }
const DiagramQStyleMap& getStyles() const { return maStyles; }
diff --git a/oox/source/drawingml/diagram/diagramlayoutatoms.cxx b/oox/source/drawingml/diagram/diagramlayoutatoms.cxx
index ad4e8962a4a4..63aceb0df920 100644
--- a/oox/source/drawingml/diagram/diagramlayoutatoms.cxx
+++ b/oox/source/drawingml/diagram/diagramlayoutatoms.cxx
@@ -281,6 +281,20 @@ void ForEachAtom::accept( LayoutAtomVisitor& rVisitor )
rVisitor.visit(*this);
}
+LayoutAtomPtr ForEachAtom::getRefAtom()
+{
+ if (!msRef.isEmpty())
+ {
+ const LayoutAtomMap& rLayoutAtomMap = getLayoutNode().getDiagram().getLayout()->getLayoutAtomMap();
+ LayoutAtomMap::const_iterator pRefAtom = rLayoutAtomMap.find(msRef);
+ if (pRefAtom != rLayoutAtomMap.end())
+ return pRefAtom->second;
+ else
+ SAL_WARN("oox.drawingml", "ForEach reference \"" << msRef << "\" not found");
+ }
+ return LayoutAtomPtr();
+}
+
void ChooseAtom::accept( LayoutAtomVisitor& rVisitor )
{
rVisitor.visit(*this);
diff --git a/oox/source/drawingml/diagram/diagramlayoutatoms.hxx b/oox/source/drawingml/diagram/diagramlayoutatoms.hxx
index 0291b87cc97a..842acc0757f6 100644
--- a/oox/source/drawingml/diagram/diagramlayoutatoms.hxx
+++ b/oox/source/drawingml/diagram/diagramlayoutatoms.hxx
@@ -191,10 +191,16 @@ public:
IteratorAttr & iterator()
{ return maIter; }
+ void setRef(const OUString& rsRef)
+ { msRef = rsRef; }
+ const OUString& getRef() const
+ { return msRef; }
virtual void accept( LayoutAtomVisitor& ) override;
+ LayoutAtomPtr getRefAtom();
private:
IteratorAttr maIter;
+ OUString msRef;
};
typedef std::shared_ptr< ForEachAtom > ForEachAtomPtr;
diff --git a/oox/source/drawingml/diagram/layoutatomvisitors.cxx b/oox/source/drawingml/diagram/layoutatomvisitors.cxx
index 5b79dafbc46b..d7c8448666fb 100644
--- a/oox/source/drawingml/diagram/layoutatomvisitors.cxx
+++ b/oox/source/drawingml/diagram/layoutatomvisitors.cxx
@@ -48,6 +48,13 @@ void ShapeCreationVisitor::visit(AlgAtom& rAtom)
void ShapeCreationVisitor::visit(ForEachAtom& rAtom)
{
+ if (!rAtom.getRef().isEmpty())
+ {
+ if (LayoutAtomPtr pRefAtom = rAtom.getRefAtom())
+ pRefAtom->accept(*this);
+ return;
+ }
+
if (rAtom.iterator().mnAxis == XML_followSib)
{
// If the axis is the follow sibling, then the last atom should not be
@@ -276,6 +283,13 @@ void ShapeLayoutingVisitor::visit(AlgAtom& rAtom)
void ShapeLayoutingVisitor::visit(ForEachAtom& rAtom)
{
+ if (!rAtom.getRef().isEmpty())
+ {
+ if (LayoutAtomPtr pRefAtom = rAtom.getRefAtom())
+ pRefAtom->accept(*this);
+ return;
+ }
+
defaultVisit(rAtom);
}
diff --git a/oox/source/drawingml/diagram/layoutnodecontext.cxx b/oox/source/drawingml/diagram/layoutnodecontext.cxx
index 10070063c8ec..0d022ca41504 100644
--- a/oox/source/drawingml/diagram/layoutnodecontext.cxx
+++ b/oox/source/drawingml/diagram/layoutnodecontext.cxx
@@ -142,8 +142,11 @@ public:
ForEachContext( ContextHandler2Helper const & rParent, const AttributeList& rAttribs, const ForEachAtomPtr& pAtom )
: LayoutNodeContext( rParent, rAttribs, pAtom )
{
- rAttribs.getString( XML_ref );
+ pAtom->setRef(rAttribs.getString(XML_ref).get());
pAtom->iterator().loadFromXAttr( rAttribs.getFastAttributeList() );
+
+ LayoutAtomMap& rLayoutAtomMap = pAtom->getLayoutNode().getDiagram().getLayout()->getLayoutAtomMap();
+ rLayoutAtomMap[pAtom->getName()] = pAtom;
}
};
diff --git a/sd/qa/unit/data/pptx/smartart-recursion.pptx b/sd/qa/unit/data/pptx/smartart-recursion.pptx
new file mode 100644
index 000000000000..205db6b703de
Binary files /dev/null and b/sd/qa/unit/data/pptx/smartart-recursion.pptx differ
diff --git a/sd/qa/unit/import-tests-smartart.cxx b/sd/qa/unit/import-tests-smartart.cxx
index 930006fd3931..59d09a7d4204 100644
--- a/sd/qa/unit/import-tests-smartart.cxx
+++ b/sd/qa/unit/import-tests-smartart.cxx
@@ -76,6 +76,7 @@ public:
void testFontSize();
void testVerticalBlockList();
void testBulletList();
+ void testRecursion();
CPPUNIT_TEST_SUITE(SdImportTestSmartArt);
@@ -114,6 +115,7 @@ public:
CPPUNIT_TEST(testFontSize);
CPPUNIT_TEST(testVerticalBlockList);
CPPUNIT_TEST(testBulletList);
+ CPPUNIT_TEST(testRecursion);
CPPUNIT_TEST_SUITE_END();
};
@@ -1105,6 +1107,46 @@ void SdImportTestSmartArt::testBulletList()
xDocShRef->DoClose();
}
+void SdImportTestSmartArt::testRecursion()
+{
+ sd::DrawDocShellRef xDocShRef = loadURL(
+ m_directories.getURLFromSrc("/sd/qa/unit/data/pptx/smartart-recursion.pptx"), PPTX);
+
+ uno::Reference<drawing::XShapes> xGroup(getShapeFromPage(0, 0, xDocShRef), uno::UNO_QUERY);
+ uno::Reference<drawing::XShapes> xGroup1(xGroup->getByIndex(1), uno::UNO_QUERY);
+
+ uno::Reference<drawing::XShapes> xGroupA(xGroup1->getByIndex(0), uno::UNO_QUERY);
+ uno::Reference<text::XText> xTextA(xGroupA->getByIndex(0), uno::UNO_QUERY);
+ CPPUNIT_ASSERT_EQUAL(OUString("A"), xTextA->getString());
+
+ uno::Reference<drawing::XShapes> xGroupB(xGroup1->getByIndex(1), uno::UNO_QUERY);
+ // 5 connectors, B1 with children, B2 with children
+ CPPUNIT_ASSERT_EQUAL(static_cast<sal_Int32>(7), xGroupB->getCount());
+
+ uno::Reference<drawing::XShapes> xGroupB1(xGroupB->getByIndex(1), uno::UNO_QUERY);
+
+ uno::Reference<drawing::XShapes> xGroupB1a(xGroupB1->getByIndex(0), uno::UNO_QUERY);
+ uno::Reference<text::XText> xTextB1(xGroupB1a->getByIndex(0), uno::UNO_QUERY);
+ CPPUNIT_ASSERT_EQUAL(OUString("B1"), xTextB1->getString());
+
+ uno::Reference<drawing::XShape> xGroupC12(xGroupB1->getByIndex(1), uno::UNO_QUERY);
+ uno::Reference<text::XText> xTextC1(getChildShape(getChildShape(getChildShape(xGroupC12, 0), 0), 0), uno::UNO_QUERY);
+ CPPUNIT_ASSERT_EQUAL(OUString("C1"), xTextC1->getString());
+ uno::Reference<text::XText> xTextC2(getChildShape(getChildShape(getChildShape(xGroupC12, 1), 0), 0), uno::UNO_QUERY);
+ CPPUNIT_ASSERT_EQUAL(OUString("C2"), xTextC2->getString());
+
+ uno::Reference<drawing::XShapes> xGroupB2(xGroupB->getByIndex(5), uno::UNO_QUERY);
+
+ uno::Reference<drawing::XShapes> xGroupB2a(xGroupB2->getByIndex(0), uno::UNO_QUERY);
+ uno::Reference<text::XText> xTextB2(xGroupB2a->getByIndex(0), uno::UNO_QUERY);
+ CPPUNIT_ASSERT_EQUAL(OUString("B2"), xTextB2->getString());
+
+ uno::Reference<drawing::XShape> xGroupC3(xGroupB2->getByIndex(1), uno::UNO_QUERY);
+ uno::Reference<text::XText> xTextC3(getChildShape(getChildShape(getChildShape(xGroupC3, 0), 0), 0), uno::UNO_QUERY);
+ CPPUNIT_ASSERT_EQUAL(OUString("C3"), xTextC3->getString());
+
+ xDocShRef->DoClose();
+}
CPPUNIT_TEST_SUITE_REGISTRATION(SdImportTestSmartArt);
commit 70f9f5fb2a724373742285ecc1e74393d5226421
Author: Grzegorz Araminowicz <grzegorz.araminowicz at collabora.com>
AuthorDate: Fri Jun 14 15:12:33 2019 +0200
Commit: Grzegorz Araminowicz <grzegorz.araminowicz at collabora.com>
CommitDate: Wed Jul 10 22:11:13 2019 +0200
SmartArt: support multiple levels of shapes in LayoutNodes
it is needed for recurrent ForEach node, so that shapes on different levels
are divided and can be layouted separately
Change-Id: Iefbc82925078fe2346858748259680fa8ea252d6
Reviewed-on: https://gerrit.libreoffice.org/74043
Tested-by: Jenkins
Reviewed-by: Grzegorz Araminowicz <grzegorz.araminowicz at collabora.com>
Reviewed-on: https://gerrit.libreoffice.org/75366
Tested-by: Jenkins CollaboraOffice <jenkinscollaboraoffice at gmail.com>
diff --git a/oox/source/drawingml/diagram/diagramlayoutatoms.cxx b/oox/source/drawingml/diagram/diagramlayoutatoms.cxx
index a4b80548e3dd..ad4e8962a4a4 100644
--- a/oox/source/drawingml/diagram/diagramlayoutatoms.cxx
+++ b/oox/source/drawingml/diagram/diagramlayoutatoms.cxx
@@ -159,12 +159,16 @@ bool containsDataNodeType(const oox::drawingml::ShapePtr& pShape, sal_Int32 nTyp
*/
void calculateHierChildOffsetScale(const oox::drawingml::ShapePtr& pShape,
const oox::drawingml::LayoutNode* pParent, sal_Int32& rXOffset,
- double& rWidthScale)
+ double& rWidthScale, sal_Int32 nLevel)
{
if (!pParent)
return;
- const std::vector<oox::drawingml::ShapePtr>& rParents = pParent->getNodeShapes();
+ auto pShapes = pParent->getNodeShapes().find(nLevel - 1);
+ if (pShapes == pParent->getNodeShapes().end())
+ return;
+
+ const std::vector<oox::drawingml::ShapePtr>& rParents = pShapes->second;
for (size_t nParent = 0; nParent < rParents.size(); ++nParent)
{
const oox::drawingml::ShapePtr& pParentShape = rParents[nParent];
@@ -499,7 +503,8 @@ void AlgAtom::accept( LayoutAtomVisitor& rVisitor )
}
void AlgAtom::layoutShape( const ShapePtr& rShape,
- const std::vector<Constraint>& rConstraints )
+ const std::vector<Constraint>& rConstraints,
+ sal_Int32 nShapeLevel )
{
switch(mnType)
{
@@ -743,7 +748,7 @@ void AlgAtom::layoutShape( const ShapePtr& rShape,
sal_Int32 nXOffset = 0;
double fWidthScale = 1.0;
if (mnType == XML_hierChild)
- calculateHierChildOffsetScale(rShape, getLayoutNode().getParentLayoutNode(), nXOffset, fWidthScale);
+ calculateHierChildOffsetScale(rShape, getLayoutNode().getParentLayoutNode(), nXOffset, fWidthScale, nShapeLevel);
awt::Size aChildSize = rShape->getSize();
if (nDir == XML_fromT)
diff --git a/oox/source/drawingml/diagram/diagramlayoutatoms.hxx b/oox/source/drawingml/diagram/diagramlayoutatoms.hxx
index d70878e063aa..0291b87cc97a 100644
--- a/oox/source/drawingml/diagram/diagramlayoutatoms.hxx
+++ b/oox/source/drawingml/diagram/diagramlayoutatoms.hxx
@@ -161,7 +161,8 @@ public:
void addParam( sal_Int32 nType, sal_Int32 nVal )
{ maMap[nType]=nVal; }
void layoutShape( const ShapePtr& rShape,
- const std::vector<Constraint>& rConstraints );
+ const std::vector<Constraint>& rConstraints,
+ sal_Int32 nShapeLevel );
/// Gives access to <dgm:alg type="..."/>.
sal_Int32 getType() const { return mnType; }
@@ -239,6 +240,7 @@ class LayoutNode
{
public:
typedef std::map<sal_Int32, OUString> VarMap;
+ typedef std::map<sal_Int32, std::vector<ShapePtr>> ShapeLevelMap;
LayoutNode(const Diagram& rDgm) : LayoutAtom(*this), mrDgm(rDgm), mnChildOrder(0) {}
const Diagram& getDiagram() const
@@ -256,10 +258,10 @@ public:
{ mpExistingShape = pShape; }
const ShapePtr& getExistingShape() const
{ return mpExistingShape; }
- const std::vector<ShapePtr> & getNodeShapes() const
+ const ShapeLevelMap& getNodeShapes() const
{ return mpNodeShapes; }
- void addNodeShape(const ShapePtr& pShape)
- { mpNodeShapes.push_back(pShape); }
+ void addNodeShape(const ShapePtr& pShape, sal_Int32 nLevel)
+ { mpNodeShapes[nLevel].push_back(pShape); }
bool setupShape( const ShapePtr& rShape,
const dgm::Point* pPresNode ) const;
@@ -276,7 +278,7 @@ private:
OUString msMoveWith;
OUString msStyleLabel;
ShapePtr mpExistingShape;
- std::vector<ShapePtr> mpNodeShapes;
+ ShapeLevelMap mpNodeShapes;
sal_Int32 mnChildOrder;
std::weak_ptr<AlgAtom> mpAlgAtom;
};
diff --git a/oox/source/drawingml/diagram/layoutatomvisitors.cxx b/oox/source/drawingml/diagram/layoutatomvisitors.cxx
index 4e1a3689e3e4..5b79dafbc46b 100644
--- a/oox/source/drawingml/diagram/layoutatomvisitors.cxx
+++ b/oox/source/drawingml/diagram/layoutatomvisitors.cxx
@@ -135,7 +135,7 @@ void ShapeCreationVisitor::visit(LayoutNode& rAtom)
pShape->setInternalName(rAtom.getName());
if (AlgAtomPtr pAlgAtom = rAtom.getAlgAtom())
pShape->setAspectRatio(pAlgAtom->getAspectRatio());
- rAtom.addNodeShape(pShape);
+ rAtom.addNodeShape(pShape, mnCurrLevel);
}
}
else
@@ -148,9 +148,8 @@ void ShapeCreationVisitor::visit(LayoutNode& rAtom)
{
SAL_INFO(
"oox.drawingml",
- "processing shape type "
- << (pShape->getCustomShapeProperties()
- ->getShapePresetType()));
+ "processing shape type " << (pShape->getCustomShapeProperties()->getShapePresetType())
+ << " level " << mnCurrLevel);
if (rAtom.setupShape(pShape, pNewNode))
{
@@ -159,7 +158,7 @@ void ShapeCreationVisitor::visit(LayoutNode& rAtom)
pShape->setAspectRatio(pAlgAtom->getAspectRatio());
pCurrParent->addChild(pShape);
pCurrParent = pShape;
- rAtom.addNodeShape(pShape);
+ rAtom.addNodeShape(pShape, mnCurrLevel);
}
}
else
@@ -174,11 +173,13 @@ void ShapeCreationVisitor::visit(LayoutNode& rAtom)
// set new parent for children
ShapePtr pPreviousParent(mpParentShape);
mpParentShape=pCurrParent;
+ mnCurrLevel++;
// process children
defaultVisit(rAtom);
// restore parent
+ mnCurrLevel--;
mpParentShape=pPreviousParent;
mpCurrentNode = pPreviousNode;
@@ -266,8 +267,10 @@ void ShapeLayoutingVisitor::visit(AlgAtom& rAtom)
{
if (meLookFor == ALGORITHM)
{
- for (const auto& pShape : rAtom.getLayoutNode().getNodeShapes())
- rAtom.layoutShape(pShape, maConstraints);
+ auto pShapes = rAtom.getLayoutNode().getNodeShapes().find(mnCurrLevel);
+ if (pShapes != rAtom.getLayoutNode().getNodeShapes().end())
+ for (const auto& pShape : pShapes->second)
+ rAtom.layoutShape(pShape, maConstraints, mnCurrLevel);
}
}
@@ -291,6 +294,10 @@ void ShapeLayoutingVisitor::visit(LayoutNode& rAtom)
if (meLookFor != LAYOUT_NODE)
return;
+ // stop processing if there is no more shapes on this level
+ if (rAtom.getNodeShapes().empty() || mnCurrLevel > rAtom.getNodeShapes().rbegin()->first)
+ return;
+
size_t nParentConstraintsNumber = maConstraints.size();
// process alg atoms first, nested layout nodes afterwards
@@ -298,8 +305,11 @@ void ShapeLayoutingVisitor::visit(LayoutNode& rAtom)
defaultVisit(rAtom);
meLookFor = ALGORITHM;
defaultVisit(rAtom);
+
+ mnCurrLevel++;
meLookFor = LAYOUT_NODE;
defaultVisit(rAtom);
+ mnCurrLevel--;
// delete added constraints, keep parent constraints
maConstraints.erase(maConstraints.begin() + nParentConstraintsNumber, maConstraints.end());
diff --git a/oox/source/drawingml/diagram/layoutatomvisitors.hxx b/oox/source/drawingml/diagram/layoutatomvisitors.hxx
index f395f6a68668..4a61a75eb0f5 100644
--- a/oox/source/drawingml/diagram/layoutatomvisitors.hxx
+++ b/oox/source/drawingml/diagram/layoutatomvisitors.hxx
@@ -35,6 +35,7 @@ class ShapeCreationVisitor : public LayoutAtomVisitor
sal_Int32 mnCurrIdx;
sal_Int32 mnCurrStep = 0;
sal_Int32 mnCurrCnt = 0;
+ sal_Int32 mnCurrLevel;
const dgm::Point* mpCurrentNode;
void defaultVisit(LayoutAtom const & rAtom);
@@ -52,6 +53,7 @@ public:
mpParentShape(rParentShape),
mrDgm(rDgm),
mnCurrIdx(0),
+ mnCurrLevel(0),
mpCurrentNode(rDgm.getData()->getRootPoint())
{}
};
@@ -78,6 +80,7 @@ class ShapeLayoutingVisitor : public LayoutAtomVisitor
{
std::vector<Constraint> maConstraints;
enum {LAYOUT_NODE, CONSTRAINT, ALGORITHM} meLookFor;
+ sal_Int32 mnCurrLevel;
void defaultVisit(LayoutAtom const & rAtom);
virtual void visit(ConstraintAtom& rAtom) override;
@@ -90,7 +93,8 @@ class ShapeLayoutingVisitor : public LayoutAtomVisitor
public:
ShapeLayoutingVisitor() :
- meLookFor(LAYOUT_NODE)
+ meLookFor(LAYOUT_NODE),
+ mnCurrLevel(0)
{}
};
More information about the Libreoffice-commits
mailing list