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 #include #include +#include #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 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 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 3c8993bd687d..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 findProperty(const oox::drawingml::LayoutPropertyMap& rProperties, + const OUString& rInternalName, sal_Int32 nProperty) +{ + oox::OptValue 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& rConstraints ) const + const std::vector& rOwnConstraints ) const { + // Algorithm result may depend on the parent constraints as well. + std::vector aParentConstraints; + const LayoutNode* pParent = getLayoutNode().getParentLayoutNode(); + if (pParent) + { + for (const auto& pChild : pParent->getChildren()) + { + auto pConstraintAtom = dynamic_cast(pChild.get()); + if (pConstraintAtom) + pConstraintAtom->parseConstraint(aParentConstraints); + } + } + const std::vector& rConstraints = rOwnConstraints.empty() ? aParentConstraints : rOwnConstraints; + switch(mnType) { case XML_composite: @@ -356,9 +433,9 @@ void AlgAtom::layoutShape( const ShapePtr& rShape, double fSpace = 0.3; awt::Size aChildSize = rShape->getSize(); - if (nIncX) + if (nDir == XML_fromL || nDir == XML_fromR) aChildSize.Width /= (nCount + (nCount-1)*fSpace); - if (nIncY) + else if (nDir == XML_fromT || nDir == XML_fromB) aChildSize.Height /= (nCount + (nCount-1)*fSpace); awt::Point aCurrPos(0, 0); @@ -367,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 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 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; @@ -402,18 +531,19 @@ void AlgAtom::layoutShape( const ShapePtr& rShape, // TODO: get values from constraints sal_Int32 nCount = rShape->getChildren().size(); double fSpace = 0.3; - double fAspectRatio = 0.6; + double fAspectRatio = 0.54; // diagram should not spill outside, earlier it was 0.6 sal_Int32 nCol = 1; sal_Int32 nRow = 1; - for ( ; nColgetSize().Height; const double fShapeWidth = rShape->getSize().Width; - if ((fShapeHeight / nRow) / (fShapeWidth / nCol) >= fAspectRatio) + if ((fShapeHeight / nCol) / (fShapeWidth / nRow) >= fAspectRatio) break; } + SAL_INFO("oox.drawingml", "Snake layout grid: " << nCol << "x" << nRow); sal_Int32 nWidth = rShape->getSize().Width / (nCol + (nCol-1)*fSpace); @@ -426,20 +556,89 @@ void AlgAtom::layoutShape( const ShapePtr& rShape, aCurrPos.Y = rShape->getSize().Height - aChildSize.Height; sal_Int32 nStartX = aCurrPos.X; - sal_Int32 nColIdx = 0; + sal_Int32 nColIdx = 0,index = 0; - for (auto & aCurrShape : rShape->getChildren()) + sal_Int32 num = rShape->getChildren().size(); + + const sal_Int32 aContDir = maMap.count(XML_contDir) ? maMap.find(XML_contDir)->second : XML_sameDir; + + switch(aContDir) { - aCurrShape->setPosition(aCurrPos); - aCurrShape->setSize(aChildSize); - aCurrShape->setChildSize(aChildSize); - aCurrPos.X += nIncX * (aChildSize.Width + fSpace*aChildSize.Width); - if (++nColIdx == nCol) + case XML_sameDir: + for (auto & aCurrShape : rShape->getChildren()) { - aCurrPos.X = nStartX; - aCurrPos.Y += nIncY * (aChildSize.Height + fSpace*aChildSize.Height); - nColIdx = 0; + aCurrShape->setPosition(aCurrPos); + aCurrShape->setSize(aChildSize); + aCurrShape->setChildSize(aChildSize); + + index++; // counts index of child, helpful for positioning. + + if(index%nCol==0 || ((index/nCol)+1)!=nRow) + aCurrPos.X += nIncX * (aChildSize.Width + fSpace*aChildSize.Width); + + if(++nColIdx == nCol) // condition for next row + { + // if last row, then position children according to number of shapes. + if((index+1)%nCol!=0 && (index+1)>=3 && ((index+1)/nCol+1)==nRow && num!=nRow*nCol) + // position first child of last row + aCurrPos.X = nStartX + (nIncX * (aChildSize.Width + fSpace*aChildSize.Width))/2; + else + // if not last row, positions first child of that row + aCurrPos.X = nStartX; + aCurrPos.Y += nIncY * (aChildSize.Height + fSpace*aChildSize.Height); + nColIdx = 0; + } + + // positions children in the last row. + if(index%nCol!=0 && index>=3 && ((index/nCol)+1)==nRow) + aCurrPos.X += (nIncX * (aChildSize.Width + fSpace*aChildSize.Width)); } + break; + case XML_revDir: + for (auto & aCurrShape : rShape->getChildren()) + { + aCurrShape->setPosition(aCurrPos); + aCurrShape->setSize(aChildSize); + aCurrShape->setChildSize(aChildSize); + + index++; // counts index of child, helpful for positioning. + + /* + index%col -> tests node is at last column + ((index/nCol)+1)!=nRow) -> tests node is at last row or not + ((index/nCol)+1)%2!=0 -> tests node is at row which is multiple of 2, important for revDir + num!=nRow*nCol -> tests how last row nodes should be spread. + */ + + if((index%nCol==0 || ((index/nCol)+1)!=nRow) && ((index/nCol)+1)%2!=0) + aCurrPos.X += (aChildSize.Width + fSpace*aChildSize.Width); + else if( index%nCol!=0 && ((index/nCol)+1)!=nRow) // child other than placed at last column + aCurrPos.X -= (aChildSize.Width + fSpace*aChildSize.Width); + + if(++nColIdx == nCol) // condition for next row + { + // if last row, then position children according to number of shapes. + if((index+1)%nCol!=0 && (index+1)>=4 && ((index+1)/nCol+1)==nRow && num!=nRow*nCol && ((index/nCol)+1)%2==0) + // position first child of last row + aCurrPos.X -= aChildSize.Width*3/2; + else if((index+1)%nCol!=0 && (index+1)>=4 && ((index+1)/nCol+1)==nRow && num!=nRow*nCol && ((index/nCol)+1)%2!=0) + aCurrPos.X = nStartX + (nIncX * (aChildSize.Width + fSpace*aChildSize.Width))/2; + else if(((index/nCol)+1)%2!=0) + aCurrPos.X = nStartX; + + aCurrPos.Y += nIncY * (aChildSize.Height + fSpace*aChildSize.Height); + nColIdx = 0; + } + + // positions children in the last row. + if(index%nCol!=0 && index>=3 && ((index/nCol)+1)==nRow && ((index/nCol)+1)%2==0) + //if row%2=0 then start from left else + aCurrPos.X -= (nIncX * (aChildSize.Width + fSpace*aChildSize.Width)); + else if(index%nCol!=0 && index>=3 && ((index/nCol)+1)==nRow && ((index/nCol)+1)%2!=0) + // start from right + aCurrPos.X += (nIncX * (aChildSize.Width + fSpace*aChildSize.Width)); + } + break; } break; } @@ -456,7 +655,6 @@ void AlgAtom::layoutShape( const ShapePtr& rShape, { // adjust text alignment // TODO: adjust text size to fit shape - TextBodyPtr pTextBody = rShape->getTextBody(); if (!pTextBody || pTextBody->getParagraphs().empty() || @@ -465,12 +663,44 @@ void AlgAtom::layoutShape( const ShapePtr& rShape, break; } - if (rShape->getRotation()) - pTextBody->getTextProperties().moRotation = -rShape->getRotation(); + const sal_Int32 nautoTxRot = maMap.count(XML_autoTxRot) ? maMap.find(XML_autoTxRot)->second : XML_upr; + + switch(nautoTxRot) + { + case XML_upr: + { + if (rShape->getRotation()) + pTextBody->getTextProperties().moRotation = -F_PI180*90*rShape->getRotation(); + } + break; + case XML_grav: + { + if (rShape->getRotation()==90*F_PI180 || rShape->getRotation()==180*F_PI180) + pTextBody->getTextProperties().moRotation = 180*F_PI180; + } + break; + case XML_none: + break; + } + + const sal_Int32 atxAnchorVert = maMap.count(XML_txAnchorVert) ? maMap.find(XML_txAnchorVert)->second : XML_mid; + + switch(atxAnchorVert) + { + case XML_t: + pTextBody->getTextProperties().meVA = css::drawing::TextVerticalAdjust_TOP; + break; + case XML_b: + pTextBody->getTextProperties().meVA = css::drawing::TextVerticalAdjust_BOTTOM; + break; + case XML_mid: + // text centered vertically by default + default: + pTextBody->getTextProperties().meVA = css::drawing::TextVerticalAdjust_CENTER; + break; + } - // text centered vertically by default - pTextBody->getTextProperties().meVA = css::drawing::TextVerticalAdjust_CENTER; - pTextBody->getTextProperties().maPropertyMap.setProperty(PROP_TextVerticalAdjust, css::drawing::TextVerticalAdjust_CENTER); + pTextBody->getTextProperties().maPropertyMap.setProperty(PROP_TextVerticalAdjust, pTextBody->getTextProperties().meVA); // normalize list level sal_Int32 nBaseLevel = pTextBody->getParagraphs().front()->getProperties().getLevel(); @@ -653,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(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& 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 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 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;