LibreOffice Module oox (master)  1
layoutatomvisitors.cxx
Go to the documentation of this file.
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3  * This file is part of the LibreOffice project.
4  *
5  * This Source Code Form is subject to the terms of the Mozilla Public
6  * License, v. 2.0. If a copy of the MPL was not distributed with this
7  * file, You can obtain one at http://mozilla.org/MPL/2.0/.
8  *
9  * This file incorporates work covered by the following license notice:
10  *
11  * Licensed to the Apache Software Foundation (ASF) under one or more
12  * contributor license agreements. See the NOTICE file distributed
13  * with this work for additional information regarding copyright
14  * ownership. The ASF licenses this file to you under the Apache
15  * License, Version 2.0 (the "License"); you may not use this file
16  * except in compliance with the License. You may obtain a copy of
17  * the License at http://www.apache.org/licenses/LICENSE-2.0 .
18  */
19 
20 #include "layoutatomvisitors.hxx"
21 
23 
24 #include <sal/log.hxx>
25 
26 using namespace ::com::sun::star;
27 using namespace ::com::sun::star::uno;
28 using namespace ::com::sun::star::xml::sax;
29 using namespace ::oox::core;
30 
31 namespace oox::drawingml
32 {
34 {
35  // stop processing
36 }
37 
39 {
40  // stop processing
41 }
42 
44 {
45  if (meLookFor == ALGORITHM)
46  {
47  mpParentShape->setAspectRatio(rAtom.getAspectRatio());
48  mpParentShape->setVerticalShapesCount(rAtom.getVerticalShapesCount(mpParentShape));
49  }
50 }
51 
53 {
54  if (meLookFor != LAYOUT_NODE)
55  return;
56 
57  // stop processing if it's not a child of previous LayoutNode
58 
59  const DiagramData::PointsNameMap::const_iterator aDataNode
60  = mrDgm.getData()->getPointsPresNameMap().find(rAtom.getName());
61  if (aDataNode == mrDgm.getData()->getPointsPresNameMap().end()
62  || mnCurrIdx >= static_cast<sal_Int32>(aDataNode->second.size()))
63  return;
64 
65  const dgm::Point* pNewNode = aDataNode->second.at(mnCurrIdx);
66  if (!mpCurrentNode || !pNewNode)
67  return;
68 
69  bool bIsChild = false;
70  for (const auto& aConnection : mrDgm.getData()->getConnections())
71  if (aConnection.msSourceId == mpCurrentNode->msModelId
72  && aConnection.msDestId == pNewNode->msModelId)
73  bIsChild = true;
74 
75  if (!bIsChild)
76  return;
77 
78  ShapePtr pCurrParent(mpParentShape);
79 
80  if (rAtom.getExistingShape())
81  {
82  // reuse existing shape
83  ShapePtr pShape = rAtom.getExistingShape();
84  if (rAtom.setupShape(pShape, pNewNode, mnCurrIdx))
85  {
86  pShape->setInternalName(rAtom.getName());
87  rAtom.addNodeShape(pShape);
88  mrDgm.getLayout()->getPresPointShapeMap()[pNewNode] = pShape;
89  }
90  }
91  else
92  {
93  ShapeTemplateVisitor aTemplateVisitor(mrDgm, pNewNode);
94  aTemplateVisitor.defaultVisit(rAtom);
95  ShapePtr pShape = aTemplateVisitor.getShapeCopy();
96 
97  if (pShape)
98  {
99  SAL_INFO("oox.drawingml",
100  "processing shape type "
101  << (pShape->getCustomShapeProperties()->getShapePresetType()));
102 
103  if (rAtom.setupShape(pShape, pNewNode, mnCurrIdx))
104  {
105  pShape->setInternalName(rAtom.getName());
106  pCurrParent->addChild(pShape);
107  pCurrParent = pShape;
108  rAtom.addNodeShape(pShape);
109  mrDgm.getLayout()->getPresPointShapeMap()[pNewNode] = pShape;
110  }
111  }
112  else
113  {
114  SAL_WARN("oox.drawingml",
115  "ShapeCreationVisitor::visit: no shape set while processing layoutnode named "
116  << rAtom.getName());
117  }
118  }
119 
120  const dgm::Point* pPreviousNode = mpCurrentNode;
121  mpCurrentNode = pNewNode;
122 
123  // set new parent for children
124  ShapePtr pPreviousParent(mpParentShape);
125  mpParentShape = pCurrParent;
126 
127  // process children
129  defaultVisit(rAtom);
130 
132  defaultVisit(rAtom);
134 
135  // restore parent
136  mpParentShape = pPreviousParent;
137  mpCurrentNode = pPreviousNode;
138 }
139 
141 {
142  // stop processing
143 }
144 
146 {
147  // stop processing
148 }
149 
151 {
152  // stop processing
153 }
154 
156 {
157  // stop processing
158 }
159 
161 {
162  // stop processing
163 }
164 
166 {
167  // stop processing - only traverse Condition/Choose atoms
168 }
169 
171 {
172  if (mpShape)
173  {
174  SAL_WARN("oox.drawingml", "multiple shapes encountered inside LayoutNode");
175  return;
176  }
177 
178  const ShapePtr& pCurrShape(rAtom.getShapeTemplate());
179 
180  // TODO(F3): cloned shape shares all properties by reference,
181  // don't change them!
182  mpShape = std::make_shared<Shape>(pCurrShape);
183  // Fill properties have to be changed as sometimes only the presentation node contains the blip
184  // fill, unshare those.
185  mpShape->cloneFillProperties();
186 }
187 
189 {
190  if (meLookFor == CONSTRAINT)
191  rAtom.parseConstraint(maConstraints, /*bRequireForName=*/true);
192 }
193 
195 {
196  if (meLookFor == RULE)
197  rAtom.parseRule(maRules);
198 }
199 
201 {
202  if (meLookFor == ALGORITHM)
203  {
204  const PresPointShapeMap aMap
205  = rAtom.getLayoutNode().getDiagram().getLayout()->getPresPointShapeMap();
206  auto pShape = aMap.find(mpCurrentNode);
207  if (pShape != aMap.end())
208  rAtom.layoutShape(pShape->second, maConstraints, maRules);
209  }
210 }
211 
213 {
214  if (meLookFor != LAYOUT_NODE)
215  return;
216 
217  // stop processing if it's not a child of previous LayoutNode
218 
219  const DiagramData::PointsNameMap::const_iterator aDataNode
220  = mrDgm.getData()->getPointsPresNameMap().find(rAtom.getName());
221  if (aDataNode == mrDgm.getData()->getPointsPresNameMap().end()
222  || mnCurrIdx >= static_cast<sal_Int32>(aDataNode->second.size()))
223  return;
224 
225  const dgm::Point* pNewNode = aDataNode->second.at(mnCurrIdx);
226  if (!mpCurrentNode || !pNewNode)
227  return;
228 
229  bool bIsChild = false;
230  for (const auto& aConnection : mrDgm.getData()->getConnections())
231  if (aConnection.msSourceId == mpCurrentNode->msModelId
232  && aConnection.msDestId == pNewNode->msModelId)
233  bIsChild = true;
234 
235  if (!bIsChild)
236  return;
237 
238  size_t nParentConstraintsNumber = maConstraints.size();
239 
240  const dgm::Point* pPreviousNode = mpCurrentNode;
241  mpCurrentNode = pNewNode;
242 
243  // process alg atoms first, nested layout nodes afterwards
245  defaultVisit(rAtom);
246  meLookFor = RULE;
247  defaultVisit(rAtom);
249  defaultVisit(rAtom);
251  defaultVisit(rAtom);
252 
253  mpCurrentNode = pPreviousNode;
254 
255  // delete added constraints, keep parent constraints
256  maConstraints.erase(maConstraints.begin() + nParentConstraintsNumber, maConstraints.end());
257 }
258 
260 {
261  // stop processing
262 }
263 }
264 
265 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
const OUString & getName() const
void addNodeShape(const ShapePtr &pShape)
virtual void visit(ConstraintAtom &rAtom) override
std::map< const dgm::Point *, ShapePtr > PresPointShapeMap
Represents one element.
HashMap_OWString_Interface aMap
virtual void visit(ConstraintAtom &rAtom) override
const DiagramLayoutPtr & getLayout() const
void defaultVisit(LayoutAtom const &rAtom)
bool setupShape(const ShapePtr &rShape, const dgm::Point *pPresNode, sal_Int32 nCurrIdx) const
ShapePtr const & getShapeCopy() const
const DiagramDataPtr & getData() const
enum oox::drawingml::LayoutAtomVisitorBase::@1 meLookFor
void parseRule(std::vector< Rule > &rRules) const
#define SAL_INFO(area, stream)
sal_Int32 getVerticalShapesCount(const ShapePtr &rShape)
virtual void visit(ConstraintAtom &rAtom) override
#define SAL_WARN(area, stream)
std::shared_ptr< Shape > ShapePtr
void layoutShape(const ShapePtr &rShape, const std::vector< Constraint > &rConstraints, const std::vector< Rule > &rRules)
const ShapePtr & getShapeTemplate() const
void parseConstraint(std::vector< Constraint > &rConstraints, bool bRequireForName) const
const ShapePtr & getExistingShape() const