[Libreoffice-commits] core.git: Branch 'libreoffice-6-1' - oox/inc oox/source sd/qa

Libreoffice Gerrit user logerrit at kemper.freedesktop.org
Tue Nov 13 14:55:05 UTC 2018


 oox/inc/drawingml/diagram/diagram.hxx                  |    3 
 oox/source/drawingml/diagram/constraintlistcontext.cxx |    2 
 oox/source/drawingml/diagram/diagram.cxx               |   67 ++++++-
 oox/source/drawingml/diagram/diagramlayoutatoms.cxx    |  160 ++++++++++++++++-
 oox/source/drawingml/diagram/diagramlayoutatoms.hxx    |   15 +
 oox/source/drawingml/diagram/layoutnodecontext.cxx     |   14 -
 oox/source/drawingml/graphicshapecontext.cxx           |    3 
 oox/source/ppt/dgmimport.cxx                           |    4 
 sd/qa/unit/data/pptx/smartart-vertial-box-list.pptx    |binary
 sd/qa/unit/data/pptx/table-list.pptx                   |binary
 sd/qa/unit/data/pptx/vertical-bracket-list.pptx        |binary
 sd/qa/unit/import-tests-smartart.cxx                   |   91 +++++++++
 12 files changed, 336 insertions(+), 23 deletions(-)

New commits:
commit 4f727bb76b61648511112adb59439a99b5e27629
Author:     Miklos Vajna <vmiklos at collabora.co.uk>
AuthorDate: Thu Oct 18 14:43:23 2018 +0200
Commit:     Andras Timar <andras.timar at collabora.com>
CommitDate: Tue Nov 13 15:54:41 2018 +0100

    Related: tdf#117761 oox smartart: backport fixes related to list types
    
    This is a combination of 7 commits.
    
    This is the 1st commit:
    
    oox: ignore SmartArt "fallback" with empty shape list
    
    This way at least something shows up in the import result. Far from
    perfect, though.
    
    (cherry picked from commit a7e86beb00e9635ea4556ef4f8f8e24ff9965391)
    
    Conflicts:
            sd/qa/unit/import-tests-smartart.cxx
    
    This is the commit #2:
    
    oox smartart: fix width of shapes with agl=lin, linDir=fromT
    
    Smaller width only makes sense in the fromL/fromR cases, I think.
    
    (cherry picked from commit b61d2784271bf8b042642c378f50e8b446682548)
    
    This is the commit #3:
    
    oox smartart: work towards accessing parent constraints
    
    The "Vertical Box List" preset in PowerPoint contains two linear
    layouts, the inner one nested in the outer one. All the constraints are
    stated on the parent layout. This commit doesn't actually read those
    constraints yet, but adds infrastructure to look up parents of layout
    nodes and also to get the constraints of a layout node.
    
    No functional changes intended.
    
    (cherry picked from commit 923061d17d4b5b8bf0d4a8111b270c99a7c649a9)
    
    This is the commit #4:
    
    oox smartart, linear layout: take width from constraints
    
    Finally the "parent text" of the test document now has correct width.
    
    (cherry picked from commit b083b0808121d19f398a9f6ead195ae7e14ed047)
    
    This is the commit #5:
    
    oox smartart, linear layout: take horizontal position from constraints
    
    Both horizontal size and position looks sane now.
    
    (cherry picked from commit 397b64afc62a5632a6648598558a4d2c3ca0d283)
    
    This is the commit #6:
    
    oox smartart, vertical bracket list: fix node counter condition
    
    The visible effect of this was that the 2nd level text nodes were
    missing from the layout result.
    
    The cause is that when it comes to counting nodes of a condition, we
    assumed that the current layout node is a presentation of a model node,
    but this is not necessarily true.
    
    Fix the problem doing a "first presentation child of", then a "presentation
    of" navigation in that case, which leads us to the correct model node,
    so counting its children works.
    
    (An alternative way of getting non-zero children would be a
    "presentation parent of" navigation, followed by a "presentation of"
    navigation, but that would lead us to the document root, so we would
    count the number of 1st level elements, not the correct 2nd level
    elements.)
    
    (cherry picked from commit e49c42d17f50c8b0cac9db08dedc375dd5aa8a98)
    
    This is the commit #7:
    
    oox smartart, table list: fix too large width of children
    
    It's possible all children request 100% of space, need to scale down in
    that case. This means that children other than the first one is now
    readable in the layout result.
    
    (cherry picked from commit c753a896aa32577e780d531032a08a699b960229)
    
    Change-Id: Iae5a073d458598e7b5059ebdf435d50ce7c7df80
    Reviewed-on: https://gerrit.libreoffice.org/63115
    Tested-by: Jenkins
    Reviewed-by: Andras Timar <andras.timar at collabora.com>

diff --git a/oox/inc/drawingml/diagram/diagram.hxx b/oox/inc/drawingml/diagram/diagram.hxx
index 5277d98d2dee..a528668c08b4 100644
--- a/oox/inc/drawingml/diagram/diagram.hxx
+++ b/oox/inc/drawingml/diagram/diagram.hxx
@@ -39,7 +39,8 @@ void loadDiagram( ShapePtr const & pShape,
                   const OUString& rDataModelPath,
                   const OUString& rLayoutPath,
                   const OUString& rQStylePath,
-                  const OUString& rColorStylePath );
+                  const OUString& rColorStylePath,
+                  const oox::core::Relations& rRelations );
 
 void loadDiagram( const ShapePtr& pShape,
                   core::XmlFilterBase& rFilter,
diff --git a/oox/source/drawingml/diagram/constraintlistcontext.cxx b/oox/source/drawingml/diagram/constraintlistcontext.cxx
index 99e3f3d10e72..cc71c89b226a 100644
--- a/oox/source/drawingml/diagram/constraintlistcontext.cxx
+++ b/oox/source/drawingml/diagram/constraintlistcontext.cxx
@@ -50,7 +50,7 @@ ConstraintListContext::onCreateContext( ::sal_Int32 aElement,
     case DGM_TOKEN( constr ):
     {
         std::shared_ptr< ConstraintAtom > pNode( new ConstraintAtom(mpNode->getLayoutNode()) );
-        mpNode->addChild( pNode );
+        LayoutAtom::connect(mpNode, pNode);
 
         Constraint& rConstraint = pNode->getConstraint();
         rConstraint.mnFor = rAttribs.getToken( XML_for, XML_none );
diff --git a/oox/source/drawingml/diagram/diagram.cxx b/oox/source/drawingml/diagram/diagram.cxx
index e7a2df78bd5e..4664a55e594c 100644
--- a/oox/source/drawingml/diagram/diagram.cxx
+++ b/oox/source/drawingml/diagram/diagram.cxx
@@ -30,6 +30,7 @@
 #include <drawingml/fillproperties.hxx>
 #include <oox/ppt/pptshapegroupcontext.hxx>
 #include <oox/ppt/pptshape.hxx>
+#include <oox/token/namespaces.hxx>
 
 #include "diagramlayoutatoms.hxx"
 #include "layoutatomvisitors.hxx"
@@ -375,12 +376,57 @@ void importFragment( core::XmlFilterBase& rFilter,
     rFilter.importFragment( rxHandler, xSerializer );
 }
 
+namespace
+{
+/**
+ * A fragment handler that just counts the number of <dsp:sp> elements in a
+ * fragment.
+ */
+class DiagramShapeCounter : public oox::core::FragmentHandler2
+{
+public:
+    DiagramShapeCounter(oox::core::XmlFilterBase& rFilter, const OUString& rFragmentPath,
+                        sal_Int32& nCounter);
+    oox::core::ContextHandlerRef onCreateContext(sal_Int32 nElement,
+                                                 const AttributeList& rAttribs) override;
+
+private:
+    sal_Int32& m_nCounter;
+};
+
+DiagramShapeCounter::DiagramShapeCounter(oox::core::XmlFilterBase& rFilter,
+                                         const OUString& rFragmentPath, sal_Int32& nCounter)
+    : FragmentHandler2(rFilter, rFragmentPath)
+    , m_nCounter(nCounter)
+{
+}
+
+oox::core::ContextHandlerRef DiagramShapeCounter::onCreateContext(sal_Int32 nElement,
+                                                                  const AttributeList& /*rAttribs*/)
+{
+    switch (nElement)
+    {
+        case DSP_TOKEN(drawing):
+        case DSP_TOKEN(spTree):
+            return this;
+        case DSP_TOKEN(sp):
+            ++m_nCounter;
+            break;
+        default:
+            break;
+    }
+
+    return nullptr;
+}
+}
+
 void loadDiagram( ShapePtr const & pShape,
                   core::XmlFilterBase& rFilter,
                   const OUString& rDataModelPath,
                   const OUString& rLayoutPath,
                   const OUString& rQStylePath,
-                  const OUString& rColorStylePath )
+                  const OUString& rColorStylePath,
+                  const oox::core::Relations& rRelations )
 {
     DiagramPtr pDiagram( new Diagram );
 
@@ -407,11 +453,26 @@ void loadDiagram( ShapePtr const & pShape,
 
         // Pass the info to pShape
         for (auto const& extDrawing : pData->getExtDrawings())
-                pShape->addExtDrawingRelId(extDrawing);
+        {
+            OUString aFragmentPath = rRelations.getFragmentPathFromRelId(extDrawing);
+            // Ignore RelIds which don't resolve to a fragment path.
+            if (aFragmentPath.isEmpty())
+                continue;
+
+            sal_Int32 nCounter = 0;
+            rtl::Reference<core::FragmentHandler> xCounter(
+                new DiagramShapeCounter(rFilter, aFragmentPath, nCounter));
+            rFilter.importFragment(xCounter);
+            // Ignore ext drawings which don't actually have any shapes.
+            if (nCounter == 0)
+                continue;
+
+            pShape->addExtDrawingRelId(extDrawing);
+        }
     }
 
     // extLst is present, lets bet on that and ignore the rest of the data from here
-    if( pData->getExtDrawings().empty() )
+    if( pShape->getExtDrawings().empty() )
     {
         // layout
         if( !rLayoutPath.isEmpty() )
diff --git a/oox/source/drawingml/diagram/diagramlayoutatoms.cxx b/oox/source/drawingml/diagram/diagramlayoutatoms.cxx
index e0fd7d246c60..c1aaf6e07025 100644
--- a/oox/source/drawingml/diagram/diagramlayoutatoms.cxx
+++ b/oox/source/drawingml/diagram/diagramlayoutatoms.cxx
@@ -35,6 +35,27 @@ using namespace ::com::sun::star::uno;
 using namespace ::com::sun::star::xml::sax;
 using namespace ::oox::core;
 
+namespace
+{
+/// Looks up the value of the rInternalName -> nProperty key in rProperties.
+oox::OptValue<sal_Int32> findProperty(const oox::drawingml::LayoutPropertyMap& rProperties,
+                                      const OUString& rInternalName, sal_Int32 nProperty)
+{
+    oox::OptValue<sal_Int32> oRet;
+
+    auto it = rProperties.find(rInternalName);
+    if (it != rProperties.end())
+    {
+        const oox::drawingml::LayoutProperty& rProperty = it->second;
+        auto itProperty = rProperty.find(nProperty);
+        if (itProperty != rProperty.end())
+            oRet = itProperty->second;
+    }
+
+    return oRet;
+}
+}
+
 namespace oox { namespace drawingml {
 
 IteratorAttr::IteratorAttr( )
@@ -145,6 +166,36 @@ const dgm::Point* ConditionAtom::getPresNode() const
     return nullptr;
 }
 
+namespace
+{
+/**
+ * Takes the connection list from rLayoutNode, navigates from rFrom on an edge
+ * of type nType, using a direction determined by bSourceToDestination.
+ */
+OUString navigate(const LayoutNode& rLayoutNode, sal_Int32 nType, const OUString& rFrom,
+                  bool bSourceToDestination)
+{
+    for (const auto& rConnection : rLayoutNode.getDiagram().getData()->getConnections())
+    {
+        if (rConnection.mnType != nType)
+            continue;
+
+        if (bSourceToDestination)
+        {
+            if (rConnection.msSourceId == rFrom)
+                return rConnection.msDestId;
+        }
+        else
+        {
+            if (rConnection.msDestId == rFrom)
+                return rConnection.msSourceId;
+        }
+    }
+
+    return OUString();
+}
+}
+
 sal_Int32 ConditionAtom::getNodeCount() const
 {
     sal_Int32 nCount = 0;
@@ -153,9 +204,21 @@ sal_Int32 ConditionAtom::getNodeCount() const
     {
         OUString sNodeId = "";
 
-        for (const auto& aCxn : mrLayoutNode.getDiagram().getData()->getConnections())
-            if (aCxn.mnType == XML_presOf && aCxn.msDestId == pPoint->msModelId)
-                sNodeId = aCxn.msSourceId;
+        sNodeId
+            = navigate(mrLayoutNode, XML_presOf, pPoint->msModelId, /*bSourceToDestination*/ false);
+
+        if (sNodeId.isEmpty())
+        {
+            // The current layout node is not a presentation of anything. Look
+            // up the first presentation child of the layout node.
+            OUString sFirstPresChildId = navigate(mrLayoutNode, XML_presParOf, pPoint->msModelId,
+                                                  /*bSourceToDestination*/ true);
+            if (!sFirstPresChildId.isEmpty())
+                // It has a presentation child: is that a presentation of a
+                // model node?
+                sNodeId = navigate(mrLayoutNode, XML_presOf, sFirstPresChildId,
+                                   /*bSourceToDestination*/ false);
+        }
 
         if (!sNodeId.isEmpty())
         {
@@ -224,8 +287,22 @@ void AlgAtom::accept( LayoutAtomVisitor& rVisitor )
 }
 
 void AlgAtom::layoutShape( const ShapePtr& rShape,
-                           const std::vector<Constraint>& rConstraints ) const
+                           const std::vector<Constraint>& rOwnConstraints ) const
 {
+    // Algorithm result may depend on the parent constraints as well.
+    std::vector<Constraint> aParentConstraints;
+    const LayoutNode* pParent = getLayoutNode().getParentLayoutNode();
+    if (pParent)
+    {
+        for (const auto& pChild : pParent->getChildren())
+        {
+            auto pConstraintAtom = dynamic_cast<ConstraintAtom*>(pChild.get());
+            if (pConstraintAtom)
+                pConstraintAtom->parseConstraint(aParentConstraints);
+        }
+    }
+    const std::vector<Constraint>& rConstraints = rOwnConstraints.empty() ? aParentConstraints : rOwnConstraints;
+
     switch(mnType)
     {
         case XML_composite:
@@ -356,9 +433,10 @@ void AlgAtom::layoutShape( const ShapePtr& rShape,
             double fSpace = 0.3;
 
             awt::Size aChildSize = rShape->getSize();
-
-            aChildSize.Width /= (nCount + (nCount-1)*fSpace);
-            aChildSize.Height /= (nCount + (nCount-1)*fSpace);
+            if (nDir == XML_fromL || nDir == XML_fromR)
+                aChildSize.Width /= (nCount + (nCount-1)*fSpace);
+            else if (nDir == XML_fromT || nDir == XML_fromB)
+                aChildSize.Height /= (nCount + (nCount-1)*fSpace);
 
             awt::Point aCurrPos(0, 0);
             if (nIncX == -1)
@@ -366,12 +444,64 @@ void AlgAtom::layoutShape( const ShapePtr& rShape,
             if (nIncY == -1)
                 aCurrPos.Y = rShape->getSize().Height - aChildSize.Height;
 
+            // Find out which contraint is relevant for which (internal) name.
+            LayoutPropertyMap aProperties;
+            for (const auto& rConstraint : rConstraints)
+            {
+                if (rConstraint.msForName.isEmpty())
+                    continue;
+
+                LayoutProperty& rProperty = aProperties[rConstraint.msForName];
+                if (rConstraint.mnType == XML_w)
+                    rProperty[XML_w] = rShape->getSize().Width * rConstraint.mfFactor;
+            }
+
+            // See if children requested more than 100% space in total: scale
+            // down in that case.
+            sal_Int32 nTotalWidth = 0;
+            bool bSpaceFromConstraints = false;
             for (auto & aCurrShape : rShape->getChildren())
             {
+                oox::OptValue<sal_Int32> oWidth
+                    = findProperty(aProperties, aCurrShape->getInternalName(), XML_w);
+
+                awt::Size aSize = aChildSize;
+                if (oWidth.has())
+                {
+                    aSize.Width = oWidth.get();
+                    bSpaceFromConstraints = true;
+                }
+                if (nDir == XML_fromL || nDir == XML_fromR)
+                    nTotalWidth += aSize.Width;
+            }
+
+            double fWidthScale = 1.0;
+            if (nTotalWidth > rShape->getSize().Width && nTotalWidth)
+            {
+                fWidthScale = rShape->getSize().Width;
+                fWidthScale /= nTotalWidth;
+            }
+
+            // Don't add automatic space if we take space from constraints.
+            if (bSpaceFromConstraints)
+                fSpace = 0;
+
+            for (auto& aCurrShape : rShape->getChildren())
+            {
+                // Extract properties relevant for this shape from constraints.
+                oox::OptValue<sal_Int32> oWidth
+                    = findProperty(aProperties, aCurrShape->getInternalName(), XML_w);
+
                 aCurrShape->setPosition(aCurrPos);
-                aCurrShape->setSize(aChildSize);
+
+                awt::Size aSize = aChildSize;
+                if (oWidth.has())
+                    aSize.Width = oWidth.get();
+                aSize.Width *= fWidthScale;
+                aCurrShape->setSize(aSize);
+
                 aCurrShape->setChildSize(aChildSize);
-                aCurrPos.X += nIncX * (aChildSize.Width + fSpace*aChildSize.Width);
+                aCurrPos.X += nIncX * (aSize.Width + fSpace*aSize.Width);
                 aCurrPos.Y += nIncY * (aChildSize.Height + fSpace*aChildSize.Height);
             }
             break;
@@ -753,6 +883,18 @@ bool LayoutNode::setupShape( const ShapePtr& rShape, const dgm::Point* pPresNode
     return true;
 }
 
+const LayoutNode* LayoutNode::getParentLayoutNode() const
+{
+    for (LayoutAtomPtr pAtom = getParent(); pAtom; pAtom = pAtom->getParent())
+    {
+        auto pLayoutNode = dynamic_cast<LayoutNode*>(pAtom.get());
+        if (pLayoutNode)
+            return pLayoutNode;
+    }
+
+    return nullptr;
+}
+
 void ShapeAtom::accept( LayoutAtomVisitor& rVisitor )
 {
     rVisitor.visit(*this);
diff --git a/oox/source/drawingml/diagram/diagramlayoutatoms.hxx b/oox/source/drawingml/diagram/diagramlayoutatoms.hxx
index 5ab34b042c86..3d4d9c05aae2 100644
--- a/oox/source/drawingml/diagram/diagramlayoutatoms.hxx
+++ b/oox/source/drawingml/diagram/diagramlayoutatoms.hxx
@@ -106,17 +106,30 @@ public:
     const OUString& getName() const
         { return msName; }
 
+private:
     void addChild( const LayoutAtomPtr & pNode )
         { mpChildNodes.push_back( pNode ); }
+    void setParent(const LayoutAtomPtr& pParent) { mpParent = pParent; }
+
+public:
     virtual const std::vector<LayoutAtomPtr>& getChildren() const
         { return mpChildNodes; }
 
+    LayoutAtomPtr getParent() const { return mpParent.lock(); }
+
+    static void connect(const LayoutAtomPtr& pParent, const LayoutAtomPtr& pChild)
+    {
+        pParent->addChild(pChild);
+        pChild->setParent(pParent);
+    }
+
     // dump for debug
     void dump(int level = 0);
 
 protected:
     const LayoutNode&            mrLayoutNode;
     std::vector< LayoutAtomPtr > mpChildNodes;
+    std::weak_ptr<LayoutAtom> mpParent;
     OUString                     msName;
 };
 
@@ -238,6 +251,8 @@ public:
     bool setupShape( const ShapePtr& rShape,
                      const dgm::Point* pPresNode ) const;
 
+    const LayoutNode* getParentLayoutNode() const;
+
 private:
     const Diagram&               mrDgm;
     VarMap                       mVariables;
diff --git a/oox/source/drawingml/diagram/layoutnodecontext.cxx b/oox/source/drawingml/diagram/layoutnodecontext.cxx
index 9bbe8b31421c..257f490f7c7c 100644
--- a/oox/source/drawingml/diagram/layoutnodecontext.cxx
+++ b/oox/source/drawingml/diagram/layoutnodecontext.cxx
@@ -105,14 +105,14 @@ public:
             {
                 // CT_When
                 ConditionAtomPtr pNode( new ConditionAtom(mpNode->getLayoutNode(), false, rAttribs.getFastAttributeList()) );
-                mpNode->addChild( pNode );
+                LayoutAtom::connect(mpNode, pNode);
                 return new IfContext( *this, rAttribs, pNode );
             }
             case DGM_TOKEN( else ):
             {
                 // CT_Otherwise
                 ConditionAtomPtr pNode( new ConditionAtom(mpNode->getLayoutNode(), true, rAttribs.getFastAttributeList()) );
-                mpNode->addChild( pNode );
+                LayoutAtom::connect(mpNode, pNode);
                 return new IfContext( *this, rAttribs, pNode );
             }
             default:
@@ -182,7 +182,7 @@ LayoutNodeContext::onCreateContext( ::sal_Int32 aElement,
     case DGM_TOKEN( layoutNode ):
     {
         LayoutNodePtr pNode( new LayoutNode(mpNode->getLayoutNode().getDiagram()) );
-        mpNode->addChild( pNode );
+        LayoutAtom::connect(mpNode, pNode);
         pNode->setChildOrder( rAttribs.getToken( XML_chOrder, XML_b ) );
         pNode->setMoveWith( rAttribs.getString( XML_moveWith ).get() );
         pNode->setStyleLabel( rAttribs.getString( XML_styleLbl ).get() );
@@ -210,7 +210,7 @@ LayoutNodeContext::onCreateContext( ::sal_Int32 aElement,
         pShape->setDiagramRotation(rAttribs.getInteger(XML_rot, 0) * PER_DEGREE);
 
         ShapeAtomPtr pAtom( new ShapeAtom(mpNode->getLayoutNode(), pShape) );
-        mpNode->addChild( pAtom );
+        LayoutAtom::connect(mpNode, pAtom);
         return new ShapeContext( *this, ShapePtr(), pShape );
     }
     case DGM_TOKEN( extLst ):
@@ -219,21 +219,21 @@ LayoutNodeContext::onCreateContext( ::sal_Int32 aElement,
     {
         // CT_Algorithm
         AlgAtomPtr pAtom( new AlgAtom(mpNode->getLayoutNode()) );
-        mpNode->addChild( pAtom );
+        LayoutAtom::connect(mpNode, pAtom);
         return new AlgorithmContext( *this, rAttribs, pAtom );
     }
     case DGM_TOKEN( choose ):
     {
         // CT_Choose
         LayoutAtomPtr pAtom( new ChooseAtom(mpNode->getLayoutNode()) );
-        mpNode->addChild( pAtom );
+        LayoutAtom::connect(mpNode, pAtom);
         return new ChooseContext( *this, rAttribs, pAtom );
     }
     case DGM_TOKEN( forEach ):
     {
         // CT_ForEach
         ForEachAtomPtr pAtom( new ForEachAtom(mpNode->getLayoutNode(), rAttribs.getFastAttributeList()) );
-        mpNode->addChild( pAtom );
+        LayoutAtom::connect(mpNode, pAtom);
         return new ForEachContext( *this, rAttribs, pAtom );
     }
     case DGM_TOKEN( constrLst ):
diff --git a/oox/source/drawingml/graphicshapecontext.cxx b/oox/source/drawingml/graphicshapecontext.cxx
index f8cfc0d40b0a..135966eee9b9 100644
--- a/oox/source/drawingml/graphicshapecontext.cxx
+++ b/oox/source/drawingml/graphicshapecontext.cxx
@@ -262,7 +262,8 @@ ContextHandlerRef DiagramGraphicDataContext::onCreateContext( ::sal_Int32 aEleme
                     getFragmentPathFromRelId( msDm ),
                     getFragmentPathFromRelId( msLo ),
                     getFragmentPathFromRelId( msQs ),
-                    getFragmentPathFromRelId( msCs ));
+                    getFragmentPathFromRelId( msCs ),
+                    getRelations());
         SAL_INFO("oox.drawingml", "DiagramGraphicDataContext::onCreateContext: added shape " << mpShapePtr->getName()
                  << " of type " << mpShapePtr->getServiceName()
                  << ", position: " << mpShapePtr->getPosition().X
diff --git a/oox/source/ppt/dgmimport.cxx b/oox/source/ppt/dgmimport.cxx
index c10dc48a72ef..191ec1771028 100644
--- a/oox/source/ppt/dgmimport.cxx
+++ b/oox/source/ppt/dgmimport.cxx
@@ -68,6 +68,7 @@ bool QuickDiagrammingImport::importDocument()
 
     Reference<drawing::XShapes> xParentShape(getParentShape(),
                                              UNO_QUERY_THROW);
+    oox::core::Relations aRelations("");
     oox::drawingml::ShapePtr pShape(
         new oox::drawingml::Shape( "com.sun.star.drawing.DiagramShape" ) );
     drawingml::loadDiagram(pShape,
@@ -75,7 +76,8 @@ bool QuickDiagrammingImport::importDocument()
                            "",
                            aFragmentPath,
                            "",
-                           "");
+                           "",
+                           aRelations);
     oox::drawingml::ThemePtr pTheme(
         new oox::drawingml::Theme());
     basegfx::B2DHomMatrix aMatrix;
diff --git a/sd/qa/unit/data/pptx/smartart-vertial-box-list.pptx b/sd/qa/unit/data/pptx/smartart-vertial-box-list.pptx
new file mode 100644
index 000000000000..b67d99e700c3
Binary files /dev/null and b/sd/qa/unit/data/pptx/smartart-vertial-box-list.pptx differ
diff --git a/sd/qa/unit/data/pptx/table-list.pptx b/sd/qa/unit/data/pptx/table-list.pptx
new file mode 100644
index 000000000000..bc5fe7418e02
Binary files /dev/null and b/sd/qa/unit/data/pptx/table-list.pptx differ
diff --git a/sd/qa/unit/data/pptx/vertical-bracket-list.pptx b/sd/qa/unit/data/pptx/vertical-bracket-list.pptx
new file mode 100644
index 000000000000..bef9d7481dfc
Binary files /dev/null and b/sd/qa/unit/data/pptx/vertical-bracket-list.pptx differ
diff --git a/sd/qa/unit/import-tests-smartart.cxx b/sd/qa/unit/import-tests-smartart.cxx
index e86dab7f4745..d561f138f16f 100644
--- a/sd/qa/unit/import-tests-smartart.cxx
+++ b/sd/qa/unit/import-tests-smartart.cxx
@@ -26,6 +26,9 @@ public:
     void testDir();
     void testMaxDepth();
     void testRotation();
+    void testVertialBoxList();
+    void testVertialBracketList();
+    void testTableList();
 
     CPPUNIT_TEST_SUITE(SdImportTestSmartArt);
 
@@ -36,6 +39,9 @@ public:
     CPPUNIT_TEST(testDir);
     CPPUNIT_TEST(testMaxDepth);
     CPPUNIT_TEST(testRotation);
+    CPPUNIT_TEST(testVertialBoxList);
+    CPPUNIT_TEST(testVertialBracketList);
+    CPPUNIT_TEST(testTableList);
 
     CPPUNIT_TEST_SUITE_END();
 };
@@ -185,6 +191,91 @@ void SdImportTestSmartArt::testRotation()
     xDocShRef->DoClose();
 }
 
+void SdImportTestSmartArt::testVertialBoxList()
+{
+    sd::DrawDocShellRef xDocShRef = loadURL(
+        m_directories.getURLFromSrc("/sd/qa/unit/data/pptx/smartart-vertial-box-list.pptx"), PPTX);
+    uno::Reference<drawing::XShapes> xShapeGroup(getShapeFromPage(0, 0, xDocShRef),
+                                                 uno::UNO_QUERY_THROW);
+    // Without the accompanying fix in place, this test would have failed with
+    // 'actual: 0'.
+    CPPUNIT_ASSERT_EQUAL(static_cast<sal_Int32>(2), xShapeGroup->getCount());
+
+    uno::Reference<drawing::XShapes> xFirstChild(xShapeGroup->getByIndex(0), uno::UNO_QUERY);
+    CPPUNIT_ASSERT(xFirstChild.is());
+    uno::Reference<drawing::XShape> xParentText(xFirstChild->getByIndex(1), uno::UNO_QUERY);
+    CPPUNIT_ASSERT(xParentText.is());
+    // Without the accompanying fix in place, this test would have failed with
+    // 'actual: 7361', i.e. the width was not the 70% of the parent as the
+    // constraint wanted.
+    CPPUNIT_ASSERT_EQUAL(static_cast<sal_Int32>(11852), xParentText->getSize().Width);
+
+    uno::Reference<drawing::XShape> xChildText(xShapeGroup->getByIndex(1), uno::UNO_QUERY);
+    CPPUNIT_ASSERT(xChildText.is());
+    // Without the accompanying fix in place, this test would have failed with
+    // 'actual: 7361' (and with the fix: 'actual: 16932', i.e. the width of the
+    // parent).
+    CPPUNIT_ASSERT_GREATER(static_cast<sal_Int32>(10000), xChildText->getSize().Width);
+
+    // Assert that the right edge of the parent text is closer to the slide
+    // boundary than the right edge of the parent text.
+    // Without the accompanying fix in place, this test would have failed with
+    // 'Expected greater than: 25656, Actual  : 21165'.
+    CPPUNIT_ASSERT_GREATER(xParentText->getPosition().X + xParentText->getSize().Width,
+                           xChildText->getPosition().X + xChildText->getSize().Width);
+
+    xDocShRef->DoClose();
+}
+
+void SdImportTestSmartArt::testVertialBracketList()
+{
+    sd::DrawDocShellRef xDocShRef = loadURL(
+        m_directories.getURLFromSrc("/sd/qa/unit/data/pptx/vertical-bracket-list.pptx"), PPTX);
+    uno::Reference<drawing::XShapes> xShapeGroup(getShapeFromPage(0, 0, xDocShRef),
+                                                 uno::UNO_QUERY_THROW);
+    CPPUNIT_ASSERT_EQUAL(static_cast<sal_Int32>(1), xShapeGroup->getCount());
+
+    uno::Reference<drawing::XShapes> xFirstChild(xShapeGroup->getByIndex(0), uno::UNO_QUERY);
+    CPPUNIT_ASSERT(xFirstChild.is());
+    // Without the accompanying fix in place, this test would have failed with
+    // 'actual: 2', i.e. one child shape (with its "A" text) was missing.
+    CPPUNIT_ASSERT_EQUAL(static_cast<sal_Int32>(3), xFirstChild->getCount());
+
+    xDocShRef->DoClose();
+}
+
+void SdImportTestSmartArt::testTableList()
+{
+    sd::DrawDocShellRef xDocShRef = loadURL(
+        m_directories.getURLFromSrc("/sd/qa/unit/data/pptx/table-list.pptx"), PPTX);
+    uno::Reference<drawing::XShapes> xShapeGroup(getShapeFromPage(0, 0, xDocShRef), uno::UNO_QUERY);
+    CPPUNIT_ASSERT(xShapeGroup.is());
+    CPPUNIT_ASSERT_EQUAL(static_cast<sal_Int32>(3), xShapeGroup->getCount());
+
+    uno::Reference<text::XText> xParentText(xShapeGroup->getByIndex(0), uno::UNO_QUERY);
+    CPPUNIT_ASSERT(xParentText.is());
+    CPPUNIT_ASSERT_EQUAL(OUString("Parent"), xParentText->getString());
+    uno::Reference<drawing::XShape> xParent(xParentText, uno::UNO_QUERY);
+    CPPUNIT_ASSERT(xParent.is());
+    int nParentRight = xParent->getPosition().X + xParent->getSize().Width;
+
+    uno::Reference<drawing::XShapes> xChildren(xShapeGroup->getByIndex(1), uno::UNO_QUERY);
+    CPPUNIT_ASSERT(xChildren.is());
+    uno::Reference<text::XText> xChild2Text(xChildren->getByIndex(1), uno::UNO_QUERY);
+    CPPUNIT_ASSERT(xChild2Text.is());
+    CPPUNIT_ASSERT_EQUAL(OUString("Child 2"), xChild2Text->getString());
+    uno::Reference<drawing::XShape> xChild2(xChild2Text, uno::UNO_QUERY);
+    CPPUNIT_ASSERT(xChild2.is());
+    int nChild2Right = xChild2->getPosition().X + xChild2->getSize().Width;
+
+    // Without the accompanying fix in place, this test would have failed with
+    // 'Expected less than: 100, Actual  : 22014', i.e. the second child was
+    // shifted to the right too much.
+    CPPUNIT_ASSERT_LESS(100, abs(nChild2Right - nParentRight));
+
+    xDocShRef->DoClose();
+}
+
 CPPUNIT_TEST_SUITE_REGISTRATION(SdImportTestSmartArt);
 
 CPPUNIT_PLUGIN_IMPLEMENT();


More information about the Libreoffice-commits mailing list