[Libreoffice-commits] core.git: 3 commits - oox/source
Grzegorz Araminowicz
g.araminowicz at gmail.com
Thu Jul 20 08:05:38 UTC 2017
oox/source/drawingml/diagram/diagram.cxx | 6
oox/source/drawingml/diagram/diagramfragmenthandler.cxx | 10
oox/source/drawingml/diagram/diagramlayoutatoms.cxx | 247 ++++++----------
oox/source/drawingml/diagram/diagramlayoutatoms.hxx | 24 +
oox/source/drawingml/diagram/layoutatomvisitors.cxx | 148 +++++++--
oox/source/drawingml/diagram/layoutatomvisitors.hxx | 35 +-
oox/source/drawingml/diagram/layoutnodecontext.cxx | 32 --
7 files changed, 286 insertions(+), 216 deletions(-)
New commits:
commit 558ded72d2a39fd0eac1f3f375b446c72b7141e5
Author: Grzegorz Araminowicz <g.araminowicz at gmail.com>
Date: Wed Jul 19 22:08:38 2017 +0200
SmartArt: shape styling
Change-Id: I7e9ab4c2286fd803cd518dd01ab8ebd5ac2d8428
diff --git a/oox/source/drawingml/diagram/diagramfragmenthandler.cxx b/oox/source/drawingml/diagram/diagramfragmenthandler.cxx
index a85fe611dd18..1ad24270477e 100644
--- a/oox/source/drawingml/diagram/diagramfragmenthandler.cxx
+++ b/oox/source/drawingml/diagram/diagramfragmenthandler.cxx
@@ -122,7 +122,7 @@ DiagramQStylesFragmentHandler::DiagramQStylesFragmentHandler( XmlFilterBase& rFi
const AttributeList& rAttribs )
{
// state-table like way of navigating the color fragment. we
- // currently ignore everything except styleLbl in the colorsDef
+ // currently ignore everything except styleLbl in the styleDef
// element
switch( getCurrentElement() )
{
@@ -136,16 +136,16 @@ DiagramQStylesFragmentHandler::DiagramQStylesFragmentHandler( XmlFilterBase& rFi
{
switch( nElement )
{
- case DGM_TOKEN(lnRef) : // CT_StyleMatrixReference
+ case A_TOKEN(lnRef): // CT_StyleMatrixReference
return createStyleMatrixContext(nElement,rAttribs,
maStyleEntry.maLineStyle);
- case DGM_TOKEN(fillRef) : // CT_StyleMatrixReference
+ case A_TOKEN(fillRef): // CT_StyleMatrixReference
return createStyleMatrixContext(nElement,rAttribs,
maStyleEntry.maFillStyle);
- case DGM_TOKEN(effectRef) : // CT_StyleMatrixReference
+ case A_TOKEN(effectRef): // CT_StyleMatrixReference
return createStyleMatrixContext(nElement,rAttribs,
maStyleEntry.maEffectStyle);
- case DGM_TOKEN(fontRef) : // CT_FontRe ference
+ case A_TOKEN(fontRef): // CT_FontReference
return createStyleMatrixContext(nElement,rAttribs,
maStyleEntry.maTextStyle);
}
diff --git a/oox/source/drawingml/diagram/diagramlayoutatoms.cxx b/oox/source/drawingml/diagram/diagramlayoutatoms.cxx
index 1bad1f0f4ece..fef4ad22e44a 100644
--- a/oox/source/drawingml/diagram/diagramlayoutatoms.cxx
+++ b/oox/source/drawingml/diagram/diagramlayoutatoms.cxx
@@ -320,15 +320,16 @@ bool LayoutNode::setupShape( const ShapePtr& rShape, const Diagram& rDgm, sal_uI
if( aDataNode != rDgm.getData()->getPointsPresNameMap().end() &&
aDataNode->second.size() > nIdx )
{
+ const dgm::Point* aPresNode = aDataNode->second.at(nIdx);
SAL_INFO(
"oox.drawingml",
"Filling content from " << nIdx << "th layout node named \""
<< msName << "\", modelId \""
- << aDataNode->second.at(nIdx)->msModelId << "\"");
+ << aPresNode->msModelId << "\"");
// got the presentation node - now, need the actual data node:
const DiagramData::StringMap::const_iterator aNodeName=rDgm.getData()->getPresOfNameMap().find(
- aDataNode->second.at(nIdx)->msModelId);
+ aPresNode->msModelId);
if( aNodeName != rDgm.getData()->getPresOfNameMap().end() )
{
DiagramData::StringMap::value_type::second_type::const_iterator aVecIter=aNodeName->second.begin();
@@ -404,22 +405,30 @@ bool LayoutNode::setupShape( const ShapePtr& rShape, const Diagram& rDgm, sal_uI
<< " for layout node named \"" << msName << "\"");
}
- // TODO(Q1): apply styling & coloring - taking
- // layout node's styleLbl for both style & color
- // now, but docs are a bit unclear on this
- if( !msStyleLabel.isEmpty() )
+ // TODO(Q1): apply styling & coloring - take presentation
+ // point's presStyleLbl for both style & color
+ // if not found use layout node's styleLbl
+ // however, docs are a bit unclear on this
+ OUString aStyleLabel = aPresNode->msPresentationLayoutStyleLabel;
+ if (aStyleLabel.isEmpty())
+ aStyleLabel = msStyleLabel;
+ if( !aStyleLabel.isEmpty() )
{
- const DiagramQStyleMap::const_iterator aStyle=rDgm.getStyles().find(msStyleLabel);
+ const DiagramQStyleMap::const_iterator aStyle = rDgm.getStyles().find(aStyleLabel);
if( aStyle != rDgm.getStyles().end() )
{
- rShape->getShapeStyleRefs()[XML_fillRef] = aStyle->second.maFillStyle;
- rShape->getShapeStyleRefs()[XML_lnRef] = aStyle->second.maLineStyle;
- rShape->getShapeStyleRefs()[XML_effectRef] = aStyle->second.maEffectStyle;
- rShape->getShapeStyleRefs()[XML_fontRef] = aStyle->second.maTextStyle;
- Color aColor=aStyle->second.maTextStyle.maPhClr;
+ const DiagramStyle& rStyle = aStyle->second;
+ rShape->getShapeStyleRefs()[XML_fillRef] = rStyle.maFillStyle;
+ rShape->getShapeStyleRefs()[XML_lnRef] = rStyle.maLineStyle;
+ rShape->getShapeStyleRefs()[XML_effectRef] = rStyle.maEffectStyle;
+ rShape->getShapeStyleRefs()[XML_fontRef] = rStyle.maTextStyle;
+ }
+ else
+ {
+ SAL_WARN("oox.drawingml", "Style " << aStyleLabel << " not found");
}
- const DiagramColorMap::const_iterator aColor=rDgm.getColors().find(msStyleLabel);
+ const DiagramColorMap::const_iterator aColor = rDgm.getColors().find(aStyleLabel);
if( aColor != rDgm.getColors().end() )
{
const DiagramColor& rColor=aColor->second;
@@ -433,12 +442,6 @@ bool LayoutNode::setupShape( const ShapePtr& rShape, const Diagram& rDgm, sal_uI
rShape->getShapeStyleRefs()[XML_fontRef].maPhClr = rColor.maTextFillColor;
}
}
- else
- {
- // if no style label apply at least some fill color
- rShape->getShapeStyleRefs()[XML_fillRef].maPhClr.setScrgbClr(0, 0, 0);
- rShape->getShapeStyleRefs()[XML_fillRef].mnThemedIdx = 2;
- }
// even if no data node found, successful anyway. it's
// contained at the layoutnode
commit 47e52b47845265ba126c30eba149e90689538b93
Author: Grzegorz Araminowicz <g.araminowicz at gmail.com>
Date: Thu Jul 13 18:39:42 2017 +0200
SmartArt: more layout work
* basic layout algorithms implementation
* change layouting order to "from top"
Change-Id: I8ef397fa0e39bb6d8cda2d1387b663980f134a59
diff --git a/oox/source/drawingml/diagram/diagram.cxx b/oox/source/drawingml/diagram/diagram.cxx
index 533156bbfb86..175df73e9420 100644
--- a/oox/source/drawingml/diagram/diagram.cxx
+++ b/oox/source/drawingml/diagram/diagram.cxx
@@ -328,7 +328,11 @@ void Diagram::addTo( const ShapePtr & pParentShape )
// create Shape hierarchy
ShapeCreationVisitor aCreationVisitor(pParentShape, *this);
mpLayout->getNode()->setExistingShape(pParentShape);
- mpLayout->getNode()->accept( aCreationVisitor );
+ mpLayout->getNode()->accept(aCreationVisitor);
+
+ // layout shapes - now all shapes are created
+ ShapeLayoutingVisitor aLayoutingVisitor;
+ mpLayout->getNode()->accept(aLayoutingVisitor);
}
pParentShape->setDiagramDoms( getDomsAsPropertyValues() );
}
diff --git a/oox/source/drawingml/diagram/diagramlayoutatoms.cxx b/oox/source/drawingml/diagram/diagramlayoutatoms.cxx
index daf0edf52c5a..1bad1f0f4ece 100644
--- a/oox/source/drawingml/diagram/diagramlayoutatoms.cxx
+++ b/oox/source/drawingml/diagram/diagramlayoutatoms.cxx
@@ -149,59 +149,13 @@ void AlgAtom::layoutShape( const ShapePtr& rShape,
{
case XML_composite:
{
- if( rShape->getChildren().empty() )
- {
- rShape->setSize(awt::Size(50,50));
- break;
- }
-
- // just put stuff below each other
- const sal_Int32 nIncX=0;
- const sal_Int32 nIncY=1;
-
- std::vector<ShapePtr>::const_iterator aCurrShape=rShape->getChildren().begin();
- const std::vector<ShapePtr>::const_iterator aLastShape=rShape->getChildren().end();
-
- // find biggest shape
- awt::Size aMaxSize;
- while( aCurrShape != aLastShape )
- {
- const awt::Size& sz=(*aCurrShape)->getSize();
-
- aMaxSize.Width = std::max(
- aMaxSize.Width,
- sz.Width);
- aMaxSize.Height = std::max(
- aMaxSize.Height,
- sz.Height);
+ // all shapes fill parent
- ++aCurrShape;
- }
-
- aCurrShape=rShape->getChildren().begin();
- const awt::Point aStartPos=(*aCurrShape)->getPosition();
- awt::Point aCurrPos=aStartPos;
- awt::Size aTotalSize;
- aTotalSize.Width = aMaxSize.Width;
- while( aCurrShape != aLastShape )
+ for (auto & aCurrShape : rShape->getChildren())
{
- const awt::Size& sz=(*aCurrShape)->getSize();
- (*aCurrShape)->setPosition(aCurrPos);
- (*aCurrShape)->setSize(
- awt::Size(aMaxSize.Width,
- sz.Height));
-
- aTotalSize.Height = std::max(
- aTotalSize.Height,
- aCurrPos.Y + sz.Height);
-
- aCurrPos.X += nIncX*sz.Width;
- aCurrPos.Y += nIncY*sz.Height;
-
- ++aCurrShape;
+ aCurrShape->setSize(rShape->getSize());
+ aCurrShape->setChildSize(rShape->getSize());
}
-
- rShape->setSize(aTotalSize);
break;
}
@@ -210,11 +164,8 @@ void AlgAtom::layoutShape( const ShapePtr& rShape,
case XML_cycle:
{
- if( rShape->getChildren().empty() )
- {
- rShape->setSize(awt::Size(50,50));
+ if (rShape->getChildren().empty())
break;
- }
const sal_Int32 nStartAngle=maMap.count(XML_stAng) ? maMap.find(XML_stAng)->second : 0;
const sal_Int32 nSpanAngle=maMap.count(XML_spanAng) ? maMap.find(XML_spanAng)->second : 360;
@@ -241,27 +192,15 @@ void AlgAtom::layoutShape( const ShapePtr& rShape,
// layout shapes
const sal_Int32 nMaxDim=std::max(aMaxSize.Width,aMaxSize.Height);
- awt::Size aTotalSize;
aCurrShape=rShape->getChildren().begin();
for( sal_Int32 i=0; i<nShapes; ++i, ++aCurrShape )
{
- const awt::Size& sz=(*aCurrShape)->getSize();
-
const double r=nShapes*nMaxDim/F_2PI * 360.0/nSpanAngle;
const awt::Point aCurrPos(
r + r*sin( (double(i)*nSpanAngle/nShapes + nStartAngle)*F_PI180 ),
r - r*cos( (double(i)*nSpanAngle/nShapes + nStartAngle)*F_PI180 ) );
(*aCurrShape)->setPosition(aCurrPos);
-
- aTotalSize.Width = std::max(
- aTotalSize.Width,
- aCurrPos.X + sz.Width);
- aTotalSize.Height = std::max(
- aTotalSize.Height,
- aCurrPos.Y + sz.Height);
}
-
- rShape->setSize(aTotalSize);
break;
}
@@ -270,97 +209,103 @@ void AlgAtom::layoutShape( const ShapePtr& rShape,
break;
case XML_lin:
- case XML_snake:
{
- if( rShape->getChildren().empty() )
- {
- rShape->setSize(awt::Size(50,50));
+ // spread childres evenly across one axis, strech across second
+
+ if (rShape->getChildren().empty() || rShape->getSize().Width == 0 || rShape->getSize().Height == 0)
break;
- }
- const sal_Int32 nDir=maMap.count(XML_linDir) ? maMap.find(XML_linDir)->second : XML_fromL;
- const sal_Int32 nIncX=nDir==XML_fromL ? 1 : (nDir==XML_fromR ? -1 : 0);
- const sal_Int32 nIncY=nDir==XML_fromT ? 1 : (nDir==XML_fromB ? -1 : 0);
+ const sal_Int32 nDir = maMap.count(XML_linDir) ? maMap.find(XML_linDir)->second : XML_fromL;
+ const sal_Int32 nIncX = nDir==XML_fromL ? 1 : (nDir==XML_fromR ? -1 : 0);
+ const sal_Int32 nIncY = nDir==XML_fromT ? 1 : (nDir==XML_fromB ? -1 : 0);
- std::vector<ShapePtr>::const_iterator aCurrShape=rShape->getChildren().begin();
- const std::vector<ShapePtr>::const_iterator aLastShape=rShape->getChildren().end();
- const awt::Point aStartPos=(*aCurrShape)->getPosition();
- awt::Point aCurrPos=aStartPos;
- awt::Size aTotalSize;
- while( aCurrShape != aLastShape )
- {
- const awt::Size& sz=(*aCurrShape)->getSize();
- (*aCurrShape)->setPosition(aCurrPos);
+ // TODO: get values from constraints
+ sal_Int32 nCount = rShape->getChildren().size();
+ double fSpace = 0.3;
- aTotalSize.Width = std::max(
- aTotalSize.Width,
- aCurrPos.X + sz.Width);
- aTotalSize.Height = std::max(
- aTotalSize.Height,
- aCurrPos.Y + sz.Height);
+ awt::Size aChildSize = rShape->getSize();
+ if (nIncX)
+ aChildSize.Width /= (nCount + (nCount-1)*fSpace);
+ if (nIncY)
+ aChildSize.Height /= (nCount + (nCount-1)*fSpace);
- // HACK: the spacing is arbitrary
- aCurrPos.X += nIncX*(sz.Width+5);
- aCurrPos.Y += nIncY*(sz.Height+5);
-
- ++aCurrShape;
+ awt::Point aCurrPos = rShape->getChildren().front()->getPosition();
+ for (auto & aCurrShape : rShape->getChildren())
+ {
+ aCurrShape->setPosition(aCurrPos);
+ aCurrShape->setSize(aChildSize);
+ aCurrShape->setChildSize(aChildSize);
+ aCurrPos.X += nIncX * (aChildSize.Width + fSpace*aChildSize.Width);
+ aCurrPos.Y += nIncY * (aChildSize.Height + fSpace*aChildSize.Height);
}
-
- rShape->setSize(aTotalSize);
break;
}
case XML_pyra:
break;
- case XML_sp:
- // HACK. Handled one level higher. Or rather, planned to
- break;
-
- case XML_tx:
+ case XML_snake:
{
- TextBodyPtr pTextBody=rShape->getTextBody();
- if( !pTextBody ||
- pTextBody->getParagraphs().empty() ||
- pTextBody->getParagraphs().front()->getRuns().empty() )
- {
- rShape->setSize(awt::Size(5,5));
+ // find optimal grid to layout children that have fixed aspect ratio
+
+ if (rShape->getChildren().empty() || rShape->getSize().Width == 0 || rShape->getSize().Height == 0)
break;
- }
- // HACK - count chars & paragraphs to come up with *some*
- // notion of necessary size
- const sal_Int32 nHackyFontHeight=50;
- const sal_Int32 nHackyFontWidth=20;
- awt::Size aTotalSize;
- for( size_t nPara=0; nPara<pTextBody->getParagraphs().size(); ++nPara )
+ // TODO: get values from constraints
+ sal_Int32 nCount = rShape->getChildren().size();
+ double fSpace = 0.3;
+ double fAspectRatio = 0.6;
+
+ sal_Int32 nCol = 1;
+ sal_Int32 nRow = 1;
+ for ( ; nCol<nCount; nCol++)
{
- aTotalSize.Height += nHackyFontHeight;
+ nRow = (nCount+nCol-1) / nCol;
+ if ((rShape->getSize().Height / nRow) / (rShape->getSize().Width / nCol) >= fAspectRatio)
+ break;
+ }
+ SAL_INFO("oox.drawingml", "Snake layout grid: " << nCol << "x" << nRow);
- sal_Int32 nLocalWidth=0;
- for( size_t nRun=0; nRun<pTextBody->getParagraphs().at(nPara)->getRuns().size(); ++nRun )
- nLocalWidth +=
- pTextBody->getParagraphs().at(nPara)->getRuns().at(nRun)->getText().getLength()
- * nHackyFontWidth;
+ sal_Int32 nWidth = rShape->getSize().Width / (nCol + (nCol-1)*fSpace);
+ const awt::Size aChildSize(nWidth, nWidth * fAspectRatio);
- aTotalSize.Width = std::max(
- aTotalSize.Width,
- nLocalWidth);
- }
+ awt::Point aStartPos = rShape->getChildren().front()->getPosition();
+ awt::Point aCurrPos = aStartPos;
+ sal_Int32 nColIdx = 0;
- rShape->setSize(aTotalSize);
+ for (auto & aCurrShape : rShape->getChildren())
+ {
+ aCurrShape->setPosition(aCurrPos);
+ aCurrShape->setSize(aChildSize);
+ aCurrShape->setChildSize(aChildSize);
+ aCurrPos.X += aChildSize.Width + fSpace*aChildSize.Width;
+ if (++nColIdx == nCol)
+ {
+ aStartPos.Y += aChildSize.Height + fSpace*aChildSize.Height;
+ aCurrPos = aStartPos;
+ nColIdx = 0;
+ }
+ }
break;
}
+ case XML_sp:
+ // HACK. Handled one level higher. Or rather, planned to
+ break;
+
+ case XML_tx:
+ // TODO: adjust text size to fit shape
+ break;
+
default:
break;
}
SAL_INFO(
"oox.drawingml",
- "Layouting shape " << rName << ": (" << rShape->getPosition().X << ","
- << rShape->getPosition().Y << "," << rShape->getSize().Width << ","
- << rShape->getSize().Height << ")");
+ "Layouting shape " << rName << ", alg type: " << mnType << ", ("
+ << rShape->getPosition().X << "," << rShape->getPosition().Y << ","
+ << rShape->getSize().Width << "," << rShape->getSize().Height << ")");
}
void LayoutNode::accept( LayoutAtomVisitor& rVisitor )
diff --git a/oox/source/drawingml/diagram/diagramlayoutatoms.hxx b/oox/source/drawingml/diagram/diagramlayoutatoms.hxx
index 7a168528c0ec..a6123ccbd62c 100644
--- a/oox/source/drawingml/diagram/diagramlayoutatoms.hxx
+++ b/oox/source/drawingml/diagram/diagramlayoutatoms.hxx
@@ -242,6 +242,8 @@ public:
{ mpExistingShape = pShape; }
const ShapePtr& getExistingShape() const
{ return mpExistingShape; }
+ std::vector<ShapePtr> & getNodeShapes()
+ { return mpNodeShapes; }
bool setupShape( const ShapePtr& rShape,
const Diagram& rDgm,
@@ -252,6 +254,7 @@ private:
OUString msMoveWith;
OUString msStyleLabel;
ShapePtr mpExistingShape;
+ std::vector<ShapePtr> mpNodeShapes;
sal_Int32 mnChildOrder;
};
diff --git a/oox/source/drawingml/diagram/layoutatomvisitors.cxx b/oox/source/drawingml/diagram/layoutatomvisitors.cxx
index ade7e4ccfec9..a580da73ff32 100755
--- a/oox/source/drawingml/diagram/layoutatomvisitors.cxx
+++ b/oox/source/drawingml/diagram/layoutatomvisitors.cxx
@@ -97,7 +97,9 @@ void ShapeCreationVisitor::visit(LayoutNode& rAtom)
if (rAtom.getExistingShape())
{
- rAtom.setupShape(rAtom.getExistingShape(), mrDgm, mnCurrIdx);
+ // reuse existing shape
+ if (rAtom.setupShape(rAtom.getExistingShape(), mrDgm, mnCurrIdx))
+ rAtom.getNodeShapes().push_back(rAtom.getExistingShape());
}
else
{
@@ -117,6 +119,7 @@ void ShapeCreationVisitor::visit(LayoutNode& rAtom)
{
pCurrParent->addChild(pShape);
pCurrParent = pShape;
+ rAtom.getNodeShapes().push_back(pShape);
}
}
else
@@ -135,10 +138,11 @@ void ShapeCreationVisitor::visit(LayoutNode& rAtom)
// restore parent
mpParentShape=pPreviousParent;
- // layout shapes - now all child shapes are created
- ShapeLayoutingVisitor aLayoutingVisitor(pCurrParent,
- rAtom.getName());
- aLayoutingVisitor.defaultVisit(rAtom);
+ // remove unneeded empty group shapes
+ pCurrParent->getChildren().erase(
+ std::remove_if(pCurrParent->getChildren().begin(), pCurrParent->getChildren().end(),
+ [] (const ShapePtr & aChild) { return aChild->getServiceName() == "com.sun.star.drawing.GroupShape" && aChild->getChildren().empty(); }),
+ pCurrParent->getChildren().end());
}
void ShapeCreationVisitor::visit(ShapeAtom& /*rAtom*/)
@@ -212,12 +216,16 @@ void ShapeLayoutingVisitor::visit(ConstraintAtom& /*rAtom*/)
void ShapeLayoutingVisitor::visit(AlgAtom& rAtom)
{
- rAtom.layoutShape(mpParentShape, maName);
+ if (mbLookForAlg && mpCurrentLayoutNode)
+ {
+ for (const auto& pShape : mpCurrentLayoutNode->getNodeShapes())
+ rAtom.layoutShape(pShape, mpCurrentLayoutNode->getName());
+ }
}
-void ShapeLayoutingVisitor::visit(ForEachAtom& /*rAtom*/)
+void ShapeLayoutingVisitor::visit(ForEachAtom& rAtom)
{
- // stop processing
+ defaultVisit(rAtom);
}
void ShapeLayoutingVisitor::visit(ConditionAtom& rAtom)
@@ -230,9 +238,21 @@ void ShapeLayoutingVisitor::visit(ChooseAtom& rAtom)
defaultVisit(rAtom);
}
-void ShapeLayoutingVisitor::visit(LayoutNode& /*rAtom*/)
+void ShapeLayoutingVisitor::visit(LayoutNode& rAtom)
{
- // stop processing - only traverse Condition/Choose atoms
+ if (mbLookForAlg)
+ return;
+
+ LayoutNode* pPreviousLayoutNode = mpCurrentLayoutNode;
+ mpCurrentLayoutNode = &rAtom;
+
+ // process alg atoms first, nested layout nodes afterwards
+ mbLookForAlg = true;
+ defaultVisit(rAtom);
+ mbLookForAlg = false;
+ defaultVisit(rAtom);
+
+ mpCurrentLayoutNode = pPreviousLayoutNode;
}
void ShapeLayoutingVisitor::visit(ShapeAtom& /*rAtom*/)
diff --git a/oox/source/drawingml/diagram/layoutatomvisitors.hxx b/oox/source/drawingml/diagram/layoutatomvisitors.hxx
index 28558f69bb24..3ffef36d8954 100755
--- a/oox/source/drawingml/diagram/layoutatomvisitors.hxx
+++ b/oox/source/drawingml/diagram/layoutatomvisitors.hxx
@@ -72,9 +72,10 @@ public:
class ShapeLayoutingVisitor : public LayoutAtomVisitor
{
- ShapePtr mpParentShape;
- OUString maName;
+ LayoutNode* mpCurrentLayoutNode;
+ bool mbLookForAlg;
+ void defaultVisit(LayoutAtom& rAtom);
virtual void visit(ConstraintAtom& rAtom) override;
virtual void visit(AlgAtom& rAtom) override;
virtual void visit(ForEachAtom& rAtom) override;
@@ -84,13 +85,10 @@ class ShapeLayoutingVisitor : public LayoutAtomVisitor
virtual void visit(ShapeAtom& rAtom) override;
public:
- ShapeLayoutingVisitor(const ShapePtr& rParentShape,
- const OUString& rName) :
- mpParentShape(rParentShape),
- maName(rName)
+ ShapeLayoutingVisitor() :
+ mpCurrentLayoutNode(nullptr),
+ mbLookForAlg(false)
{}
-
- void defaultVisit(LayoutAtom& rAtom);
};
class ShallowPresNameVisitor : public LayoutAtomVisitor
commit 21f28f94744b4378ba45b1361870592dd7cfabb2
Author: Grzegorz Araminowicz <g.araminowicz at gmail.com>
Date: Sat Jul 1 14:10:53 2017 +0200
SmartArt: add ShapeAtom to store shape template instead of LayoutNode
it allows to load shapes inside choose/if
Change-Id: I8040967d1f769796f6ad6b2d0c7b5ce698f89ee3
diff --git a/oox/source/drawingml/diagram/diagramlayoutatoms.cxx b/oox/source/drawingml/diagram/diagramlayoutatoms.cxx
index d32e2f963b59..daf0edf52c5a 100644
--- a/oox/source/drawingml/diagram/diagramlayoutatoms.cxx
+++ b/oox/source/drawingml/diagram/diagramlayoutatoms.cxx
@@ -511,6 +511,11 @@ bool LayoutNode::setupShape( const ShapePtr& rShape, const Diagram& rDgm, sal_uI
return false;
}
+void ShapeAtom::accept( LayoutAtomVisitor& rVisitor )
+{
+ rVisitor.visit(*this);
+}
+
} }
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/oox/source/drawingml/diagram/diagramlayoutatoms.hxx b/oox/source/drawingml/diagram/diagramlayoutatoms.hxx
index d5b9fcdf9e29..7a168528c0ec 100644
--- a/oox/source/drawingml/diagram/diagramlayoutatoms.hxx
+++ b/oox/source/drawingml/diagram/diagramlayoutatoms.hxx
@@ -238,12 +238,8 @@ public:
{ msStyleLabel = sLabel; }
void setChildOrder( sal_Int32 nOrder )
{ mnChildOrder = nOrder; }
- void setShapeTemplate( const ShapePtr& pShape )
- { mpShapeTemplate = pShape; }
void setExistingShape( const ShapePtr& pShape )
{ mpExistingShape = pShape; }
- const ShapePtr& getShapeTemplate() const
- { return mpShapeTemplate; }
const ShapePtr& getExistingShape() const
{ return mpExistingShape; }
@@ -255,13 +251,27 @@ private:
VarMap mVariables;
OUString msMoveWith;
OUString msStyleLabel;
- ShapePtr mpShapeTemplate;
ShapePtr mpExistingShape;
sal_Int32 mnChildOrder;
};
typedef std::shared_ptr< LayoutNode > LayoutNodePtr;
+class ShapeAtom
+ : public LayoutAtom
+{
+public:
+ ShapeAtom(const ShapePtr& pShape) : mpShapeTemplate(pShape) {}
+ virtual void accept( LayoutAtomVisitor& ) override;
+ const ShapePtr& getShapeTemplate() const
+ { return mpShapeTemplate; }
+
+private:
+ ShapePtr mpShapeTemplate;
+};
+
+typedef std::shared_ptr< ShapeAtom > ShapeAtomPtr;
+
struct LayoutAtomVisitor
{
virtual ~LayoutAtomVisitor() {}
@@ -271,6 +281,7 @@ struct LayoutAtomVisitor
virtual void visit(ConditionAtom& rAtom) = 0;
virtual void visit(ChooseAtom& rAtom) = 0;
virtual void visit(LayoutNode& rAtom) = 0;
+ virtual void visit(ShapeAtom& rAtom) = 0;
};
} }
diff --git a/oox/source/drawingml/diagram/layoutatomvisitors.cxx b/oox/source/drawingml/diagram/layoutatomvisitors.cxx
index fd6e9d7b7e1b..ade7e4ccfec9 100755
--- a/oox/source/drawingml/diagram/layoutatomvisitors.cxx
+++ b/oox/source/drawingml/diagram/layoutatomvisitors.cxx
@@ -94,34 +94,35 @@ void ShapeCreationVisitor::visit(ChooseAtom& rAtom)
void ShapeCreationVisitor::visit(LayoutNode& rAtom)
{
ShapePtr pCurrParent(mpParentShape);
- ShapePtr pCurrShape(rAtom.getShapeTemplate());
if (rAtom.getExistingShape())
{
rAtom.setupShape(rAtom.getExistingShape(), mrDgm, mnCurrIdx);
}
- else if( pCurrShape )
+ else
{
- SAL_INFO(
- "oox.drawingml",
- "processing shape type "
- << (pCurrShape->getCustomShapeProperties()
- ->getShapePresetType()));
-
- // TODO(F3): cloned shape shares all properties by reference,
- // don't change them!
- ShapePtr pClonedShape(
- new Shape( pCurrShape ));
-
- if( rAtom.setupShape(pClonedShape, mrDgm, mnCurrIdx) )
+ ShapeTemplateVisitor aTemplateVisitor;
+ aTemplateVisitor.defaultVisit(rAtom);
+ ShapePtr pShape = aTemplateVisitor.getShapeCopy();
+
+ if (pShape)
{
- pCurrParent->addChild(pClonedShape);
- pCurrParent = pClonedShape;
+ SAL_INFO(
+ "oox.drawingml",
+ "processing shape type "
+ << (pShape->getCustomShapeProperties()
+ ->getShapePresetType()));
+
+ if (rAtom.setupShape(pShape, mrDgm, mnCurrIdx))
+ {
+ pCurrParent->addChild(pShape);
+ pCurrParent = pShape;
+ }
+ }
+ else
+ {
+ SAL_WARN("oox.drawingml", "ShapeCreationVisitor::visit: no shape set while processing layoutnode named " << rAtom.getName());
}
- }
- else
- {
- SAL_WARN("oox.drawingml", "ShapeCreationVisitor::visit: no shape set while processing layoutnode named " << rAtom.getName() );
}
// set new parent for children
@@ -140,6 +141,63 @@ void ShapeCreationVisitor::visit(LayoutNode& rAtom)
aLayoutingVisitor.defaultVisit(rAtom);
}
+void ShapeCreationVisitor::visit(ShapeAtom& /*rAtom*/)
+{
+ // stop processing
+}
+
+void ShapeTemplateVisitor::defaultVisit(LayoutAtom& rAtom)
+{
+ // visit all children, one of them needs to be the layout algorithm
+ for (const auto& pAtom : rAtom.getChildren())
+ pAtom->accept(*this);
+}
+
+void ShapeTemplateVisitor::visit(ConstraintAtom& /*rAtom*/)
+{
+ // stop processing
+}
+
+void ShapeTemplateVisitor::visit(AlgAtom& /*rAtom*/)
+{
+ // stop processing
+}
+
+void ShapeTemplateVisitor::visit(ForEachAtom& /*rAtom*/)
+{
+ // stop processing
+}
+
+void ShapeTemplateVisitor::visit(ConditionAtom& rAtom)
+{
+ defaultVisit(rAtom);
+}
+
+void ShapeTemplateVisitor::visit(ChooseAtom& rAtom)
+{
+ defaultVisit(rAtom);
+}
+
+void ShapeTemplateVisitor::visit(LayoutNode& /*rAtom*/)
+{
+ // stop processing - only traverse Condition/Choose atoms
+}
+
+void ShapeTemplateVisitor::visit(ShapeAtom& rAtom)
+{
+ if (mpShape)
+ {
+ SAL_WARN("oox.drawingml", "multiple shapes encountered inside LayoutNode");
+ return;
+ }
+
+ ShapePtr pCurrShape(rAtom.getShapeTemplate());
+
+ // TODO(F3): cloned shape shares all properties by reference,
+ // don't change them!
+ mpShape.reset(new Shape(pCurrShape));
+}
+
void ShapeLayoutingVisitor::defaultVisit(LayoutAtom& rAtom)
{
// visit all children, one of them needs to be the layout algorithm
@@ -177,6 +235,11 @@ void ShapeLayoutingVisitor::visit(LayoutNode& /*rAtom*/)
// stop processing - only traverse Condition/Choose atoms
}
+void ShapeLayoutingVisitor::visit(ShapeAtom& /*rAtom*/)
+{
+ // stop processing
+}
+
void ShallowPresNameVisitor::defaultVisit(LayoutAtom& rAtom)
{
// visit all children, at least one of them needs to have proper
@@ -219,6 +282,11 @@ void ShallowPresNameVisitor::visit(LayoutNode& rAtom)
aDataNode->second.size());
}
+void ShallowPresNameVisitor::visit(ShapeAtom& /*rAtom*/)
+{
+ // stop processing
+}
+
} }
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/oox/source/drawingml/diagram/layoutatomvisitors.hxx b/oox/source/drawingml/diagram/layoutatomvisitors.hxx
index 9353f4ba0a4b..28558f69bb24 100755
--- a/oox/source/drawingml/diagram/layoutatomvisitors.hxx
+++ b/oox/source/drawingml/diagram/layoutatomvisitors.hxx
@@ -41,6 +41,7 @@ class ShapeCreationVisitor : public LayoutAtomVisitor
virtual void visit(ConditionAtom& rAtom) override;
virtual void visit(ChooseAtom& rAtom) override;
virtual void visit(LayoutNode& rAtom) override;
+ virtual void visit(ShapeAtom& rAtom) override;
public:
ShapeCreationVisitor(const ShapePtr& rParentShape,
@@ -51,6 +52,24 @@ public:
{}
};
+class ShapeTemplateVisitor : public LayoutAtomVisitor
+{
+ ShapePtr mpShape;
+
+ virtual void visit(ConstraintAtom& rAtom) override;
+ virtual void visit(AlgAtom& rAtom) override;
+ virtual void visit(ForEachAtom& rAtom) override;
+ virtual void visit(ConditionAtom& rAtom) override;
+ virtual void visit(ChooseAtom& rAtom) override;
+ virtual void visit(LayoutNode& rAtom) override;
+ virtual void visit(ShapeAtom& rAtom) override;
+
+public:
+ void defaultVisit(LayoutAtom& rAtom);
+ ShapePtr getShapeCopy() const
+ { return mpShape; }
+};
+
class ShapeLayoutingVisitor : public LayoutAtomVisitor
{
ShapePtr mpParentShape;
@@ -62,6 +81,7 @@ class ShapeLayoutingVisitor : public LayoutAtomVisitor
virtual void visit(ConditionAtom& rAtom) override;
virtual void visit(ChooseAtom& rAtom) override;
virtual void visit(LayoutNode& rAtom) override;
+ virtual void visit(ShapeAtom& rAtom) override;
public:
ShapeLayoutingVisitor(const ShapePtr& rParentShape,
@@ -85,6 +105,7 @@ class ShallowPresNameVisitor : public LayoutAtomVisitor
virtual void visit(ConditionAtom& rAtom) override;
virtual void visit(ChooseAtom& rAtom) override;
virtual void visit(LayoutNode& rAtom) override;
+ virtual void visit(ShapeAtom& rAtom) override;
public:
explicit ShallowPresNameVisitor(const Diagram& rDgm) :
diff --git a/oox/source/drawingml/diagram/layoutnodecontext.cxx b/oox/source/drawingml/diagram/layoutnodecontext.cxx
index 5d66de142c96..715e94d72eab 100644
--- a/oox/source/drawingml/diagram/layoutnodecontext.cxx
+++ b/oox/source/drawingml/diagram/layoutnodecontext.cxx
@@ -246,31 +246,23 @@ LayoutNodeContext::onCreateContext( ::sal_Int32 aElement,
}
case DGM_TOKEN( shape ):
{
- LayoutNodePtr pNode(std::dynamic_pointer_cast<LayoutNode>(mpNode));
- if( pNode )
- {
- ShapePtr pShape;
-
- if( rAttribs.hasAttribute( XML_type ) )
- {
- pShape.reset( new Shape("com.sun.star.drawing.CustomShape") );
- const sal_Int32 nType(rAttribs.getToken( XML_type, XML_obj ));
- pShape->setSubType( nType );
- pShape->getCustomShapeProperties()->setShapePresetType( nType );
- }
- else
- {
- pShape.reset( new Shape("com.sun.star.drawing.GroupShape") );
- }
+ ShapePtr pShape;
- pNode->setShapeTemplate( pShape );
- return new ShapeContext( *this, ShapePtr(), pShape );
+ if( rAttribs.hasAttribute( XML_type ) )
+ {
+ pShape.reset( new Shape("com.sun.star.drawing.CustomShape") );
+ const sal_Int32 nType(rAttribs.getToken( XML_type, XML_obj ));
+ pShape->setSubType( nType );
+ pShape->getCustomShapeProperties()->setShapePresetType( nType );
}
else
{
- SAL_WARN("oox", "OOX: encountered a shape in a non layoutNode context" );
+ pShape.reset( new Shape("com.sun.star.drawing.GroupShape") );
}
- break;
+
+ ShapeAtomPtr pAtom( new ShapeAtom(pShape) );
+ mpNode->addChild( pAtom );
+ return new ShapeContext( *this, ShapePtr(), pShape );
}
case DGM_TOKEN( extLst ):
return nullptr;
More information about the Libreoffice-commits
mailing list