LibreOffice Module oox (master)  1
layoutnodecontext.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 "layoutnodecontext.hxx"
21 
26 #include "rulelistcontext.hxx"
27 #include <oox/token/namespaces.hxx>
28 #include <oox/token/tokens.hxx>
29 #include <sal/log.hxx>
30 
31 using namespace ::oox::core;
32 using namespace ::com::sun::star::uno;
33 using namespace ::com::sun::star::xml::sax;
34 
35 namespace oox::drawingml {
36 
37 namespace {
38 
39 class IfContext
40  : public LayoutNodeContext
41 {
42 public:
43  IfContext( ContextHandler2Helper const & rParent,
44  const AttributeList& rAttribs,
45  const ConditionAtomPtr& pAtom )
46  : LayoutNodeContext( rParent, rAttribs, pAtom )
47  {}
48 };
49 
50 class AlgorithmContext
51  : public ContextHandler2
52 {
53 public:
54  AlgorithmContext( ContextHandler2Helper const & rParent, const AttributeList& rAttribs, const AlgAtomPtr & pNode )
55  : ContextHandler2( rParent )
56  , mnRevision( 0 )
57  , mpNode( pNode )
58  {
59  mnRevision = rAttribs.getInteger( XML_rev, 0 );
60  pNode->setType(rAttribs.getToken(XML_type, 0));
61  }
62 
63  virtual ContextHandlerRef
64  onCreateContext( ::sal_Int32 aElement,
65  const AttributeList& rAttribs ) override
66  {
67  switch( aElement )
68  {
69  case DGM_TOKEN( param ):
70  {
71  sal_Int32 nType = rAttribs.getToken(XML_type, 0);
72  switch (nType)
73  {
74  case XML_ar:
75  mpNode->setAspectRatio(rAttribs.getDouble(XML_val, 0));
76  break;
77  default:
78  const sal_Int32 nValTok = rAttribs.getToken(XML_val, 0);
79  mpNode->addParam(nType, nValTok > 0 ? nValTok
80  : rAttribs.getInteger(XML_val, 0));
81  break;
82  }
83  break;
84  }
85  default:
86  break;
87  }
88 
89  return this;
90  }
91 
92 private:
93  sal_Int32 mnRevision;
95 };
96 
97 class ChooseContext
98  : public ContextHandler2
99 {
100 public:
101  ChooseContext( ContextHandler2Helper const & rParent, const AttributeList& rAttribs, const LayoutAtomPtr & pNode )
102  : ContextHandler2( rParent )
103  , mpNode( pNode )
104  {
105  msName = rAttribs.getString( XML_name ).get();
106  }
107 
108  virtual ContextHandlerRef
109  onCreateContext( ::sal_Int32 aElement,
110  const AttributeList& rAttribs ) override
111  {
112  switch( aElement )
113  {
114  case DGM_TOKEN( if ):
115  {
116  // CT_When
117  ConditionAtomPtr pNode = std::make_shared<ConditionAtom>(mpNode->getLayoutNode(), false, rAttribs.getFastAttributeList());
118  LayoutAtom::connect(mpNode, pNode);
119  return new IfContext( *this, rAttribs, pNode );
120  }
121  case DGM_TOKEN( else ):
122  {
123  // CT_Otherwise
124  ConditionAtomPtr pNode = std::make_shared<ConditionAtom>(mpNode->getLayoutNode(), true, rAttribs.getFastAttributeList());
125  LayoutAtom::connect(mpNode, pNode);
126  return new IfContext( *this, rAttribs, pNode );
127  }
128  default:
129  break;
130  }
131 
132  return this;
133  }
134 private:
135  OUString msName;
137 };
138 
139 class ForEachContext
140  : public LayoutNodeContext
141 {
142 public:
143  ForEachContext( ContextHandler2Helper const & rParent, const AttributeList& rAttribs, const ForEachAtomPtr& pAtom )
144  : LayoutNodeContext( rParent, rAttribs, pAtom )
145  {
146  pAtom->setRef(rAttribs.getString(XML_ref).get());
147  pAtom->iterator().loadFromXAttr( rAttribs.getFastAttributeList() );
148 
149  LayoutAtomMap& rLayoutAtomMap = pAtom->getLayoutNode().getDiagram().getLayout()->getLayoutAtomMap();
150  rLayoutAtomMap[pAtom->getName()] = pAtom;
151  }
152 };
153 
154 // CT_LayoutVariablePropertySet
155 class LayoutVariablePropertySetContext
156  : public ContextHandler2
157 {
158 public:
159  LayoutVariablePropertySetContext( ContextHandler2Helper const & rParent, LayoutNode::VarMap & aVar )
160  : ContextHandler2( rParent )
161  , mVariables( aVar )
162  {
163  }
164 
165  virtual ContextHandlerRef onCreateContext( ::sal_Int32 aElement, const AttributeList& rAttribs ) override
166  {
167  mVariables[ getBaseToken(aElement) ] = rAttribs.getString( XML_val ).get();
168  return this;
169  }
170 private:
172 };
173 
174 }
175 
176 // CT_LayoutNode
178  const AttributeList& rAttribs,
179  const LayoutAtomPtr& pAtom )
180  : ContextHandler2( rParent )
181  , mpNode( pAtom )
182 {
183  assert( pAtom && "Node must NOT be NULL" );
184  mpNode->setName( rAttribs.getString( XML_name ).get() );
185 }
186 
188 {
189 }
190 
193  const AttributeList& rAttribs )
194 {
195  switch( aElement )
196  {
197  case DGM_TOKEN( layoutNode ):
198  {
199  LayoutNodePtr pNode = std::make_shared<LayoutNode>(mpNode->getLayoutNode().getDiagram());
200  LayoutAtom::connect(mpNode, pNode);
201 
202  if (rAttribs.hasAttribute(XML_chOrder))
203  {
204  pNode->setChildOrder(rAttribs.getToken(XML_chOrder, XML_b));
205  }
206  else
207  {
208  for (LayoutAtomPtr pAtom = mpNode; pAtom; pAtom = pAtom->getParent())
209  {
210  auto pLayoutNode = dynamic_cast<LayoutNode*>(pAtom.get());
211  if (pLayoutNode)
212  {
213  pNode->setChildOrder(pLayoutNode->getChildOrder());
214  break;
215  }
216  }
217  }
218 
219  pNode->setMoveWith( rAttribs.getString( XML_moveWith ).get() );
220  pNode->setStyleLabel( rAttribs.getString( XML_styleLbl ).get() );
221  return new LayoutNodeContext( *this, rAttribs, pNode );
222  }
223  case DGM_TOKEN( shape ):
224  {
225  ShapePtr pShape;
226 
227  if( rAttribs.hasAttribute( XML_type ) )
228  {
229  pShape = std::make_shared<Shape>("com.sun.star.drawing.CustomShape");
230  if (!rAttribs.getBool(XML_hideGeom, false))
231  {
232  const sal_Int32 nType(rAttribs.getToken( XML_type, XML_obj ));
233  pShape->setSubType( nType );
234  pShape->getCustomShapeProperties()->setShapePresetType( nType );
235  }
236  }
237  else
238  {
239  pShape = std::make_shared<Shape>("com.sun.star.drawing.GroupShape");
240  }
241 
242  pShape->setDiagramRotation(rAttribs.getInteger(XML_rot, 0) * PER_DEGREE);
243 
244  pShape->setZOrderOff(rAttribs.getInteger(XML_zOrderOff, 0));
245 
246  ShapeAtomPtr pAtom = std::make_shared<ShapeAtom>(mpNode->getLayoutNode(), pShape);
247  LayoutAtom::connect(mpNode, pAtom);
248  return new ShapeContext( *this, ShapePtr(), pShape );
249  }
250  case DGM_TOKEN( extLst ):
251  return nullptr;
252  case DGM_TOKEN( alg ):
253  {
254  // CT_Algorithm
255  AlgAtomPtr pAtom = std::make_shared<AlgAtom>(mpNode->getLayoutNode());
256  LayoutAtom::connect(mpNode, pAtom);
257  return new AlgorithmContext( *this, rAttribs, pAtom );
258  }
259  case DGM_TOKEN( choose ):
260  {
261  // CT_Choose
262  LayoutAtomPtr pAtom = std::make_shared<ChooseAtom>(mpNode->getLayoutNode());
263  LayoutAtom::connect(mpNode, pAtom);
264  return new ChooseContext( *this, rAttribs, pAtom );
265  }
266  case DGM_TOKEN( forEach ):
267  {
268  // CT_ForEach
269  ForEachAtomPtr pAtom = std::make_shared<ForEachAtom>(mpNode->getLayoutNode(), rAttribs.getFastAttributeList());
270  LayoutAtom::connect(mpNode, pAtom);
271  return new ForEachContext( *this, rAttribs, pAtom );
272  }
273  case DGM_TOKEN( constrLst ):
274  // CT_Constraints
275  return new ConstraintListContext( *this, mpNode );
276  case DGM_TOKEN( presOf ):
277  {
278  // CT_PresentationOf
279  // TODO
280  IteratorAttr aIterator;
281  aIterator.loadFromXAttr(rAttribs.getFastAttributeList());
282  break;
283  }
284  case DGM_TOKEN( ruleLst ):
285  // CT_Rules
286  return new RuleListContext( *this, mpNode );
287  case DGM_TOKEN( varLst ):
288  {
289  LayoutNodePtr pNode(std::dynamic_pointer_cast<LayoutNode>(mpNode));
290  if( pNode )
291  {
292  return new LayoutVariablePropertySetContext( *this, pNode->variables() );
293  }
294  else
295  {
296  SAL_WARN("oox", "OOX: encountered a varLst in a non layoutNode context" );
297  }
298  break;
299  }
300  default:
301  break;
302  }
303 
304  return this;
305 }
306 
307 }
308 
309 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
std::shared_ptr< AlgAtom > AlgAtomPtr
OptValue< bool > getBool(sal_Int32 nAttrToken) const
Returns the boolean value of the specified attribute.
const sal_Int32 PER_DEGREE
std::map< sal_Int32, OUString > VarMap
AlgAtomPtr mpNode
OptValue< sal_Int32 > getInteger(sal_Int32 nAttrToken) const
Returns the 32-bit signed integer value of the specified attribute (decimal).
std::shared_ptr< ConditionAtom > ConditionAtomPtr
sal_Int32 mnRevision
static void connect(const LayoutAtomPtr &pParent, const LayoutAtomPtr &pChild)
LayoutNode::VarMap & mVariables
OptValue< OUString > getString(sal_Int32 nAttrToken) const
Returns the string value of the specified attribute.
bool hasAttribute(sal_Int32 nAttrToken) const
Returns true, if the specified attribute is present.
const Type & get() const
Definition: helper.hxx:185
LayoutNodeContext(::oox::core::ContextHandler2Helper const &rParent, const ::oox::AttributeList &rAttributes, const LayoutAtomPtr &pNode)
void setChildOrder(sal_Int32 nOrder)
std::map< OUString, LayoutAtomPtr > LayoutAtomMap
Provides access to attribute values of an element.
std::shared_ptr< LayoutNode > LayoutNodePtr
void loadFromXAttr(const css::uno::Reference< css::xml::sax::XFastAttributeList > &xAttributes)
std::shared_ptr< LayoutAtom > LayoutAtomPtr
::rtl::Reference< ContextHandler > ContextHandlerRef
std::shared_ptr< ShapeAtom > ShapeAtomPtr
const css::uno::Reference< css::xml::sax::XFastAttributeList > & getFastAttributeList() const
Returns the wrapped com.sun.star.xml.sax.XFastAttributeList object.
QPRO_FUNC_TYPE nType
#define SAL_WARN(area, stream)
std::shared_ptr< Shape > ShapePtr
Helper class that provides a context stack.
virtual ::oox::core::ContextHandlerRef onCreateContext(::sal_Int32 Element, const ::oox::AttributeList &rAttribs) override
OUString msName
OptValue< sal_Int32 > getToken(sal_Int32 nAttrToken) const
Returns the token identifier of the value of the specified attribute.
std::shared_ptr< ForEachAtom > ForEachAtomPtr