8a2ecbe6c0
- bsc#1112112 - LO-L3: [PPTX] SmartArt: Basic rendering of several list types * bsc1112112.patch OBS-URL: https://build.opensuse.org/request/show/648479 OBS-URL: https://build.opensuse.org/package/show/LibreOffice:Factory/libreoffice?expand=0&rev=725
670 lines
28 KiB
Diff
670 lines
28 KiB
Diff
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 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<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,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<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;
|
|
@@ -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 ( ; nCol<nCount; nCol++)
|
|
+ for ( ; nRow<nCount; nRow++)
|
|
{
|
|
- nRow = (nCount+nCol-1) / nCol;
|
|
+ nCol = (nCount+nRow-1) / nRow;
|
|
const double fShapeHeight = rShape->getSize().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<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;
|