LibreOffice Module oox (master)  1
datamodelcontext.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 "datamodelcontext.hxx"
25 #include <oox/token/namespaces.hxx>
26 #include <oox/token/tokens.hxx>
27 
28 using namespace ::oox::core;
29 using namespace ::com::sun::star::xml::sax;
30 using namespace ::com::sun::star::uno;
31 
32 namespace oox::drawingml {
33 
34 namespace {
35 
36 // CT_CxnList
37 class CxnListContext
38  : public ContextHandler2
39 {
40 public:
41  CxnListContext( ContextHandler2Helper const & rParent,
42  svx::diagram::Connections & aConnections )
43  : ContextHandler2( rParent )
44  , mrConnection( aConnections )
45  {
46  }
47 
48  virtual ContextHandlerRef
49  onCreateContext( sal_Int32 aElementToken,
50  const AttributeList& rAttribs ) override
51  {
52  switch( aElementToken )
53  {
54  case DGM_TOKEN( cxn ):
55  {
56  mrConnection.emplace_back( );
57  svx::diagram::Connection& rConnection=mrConnection.back();
58 
59  rConnection.mnXMLType = static_cast<svx::diagram::TypeConstant>(rAttribs.getToken( XML_type, XML_parOf ));
60  rConnection.msModelId = rAttribs.getString( XML_modelId ).get();
61  rConnection.msSourceId = rAttribs.getString( XML_srcId ).get();
62  rConnection.msDestId = rAttribs.getString( XML_destId ).get();
63  rConnection.msPresId = rAttribs.getString( XML_presId ).get();
64  rConnection.msSibTransId = rAttribs.getString( XML_sibTransId ).get();
65  rConnection.msParTransId = rAttribs.getString( XML_parTransId ).get();
66  rConnection.mnSourceOrder = rAttribs.getInteger( XML_srcOrd, 0 );
67  rConnection.mnDestOrder = rAttribs.getInteger( XML_destOrd, 0 );
68 
69  // skip CT_extLst
70  return nullptr;
71  }
72  default:
73  break;
74  }
75 
76  return this;
77  }
78 private:
80 };
81 
82 // CT_presLayoutVars
83 class PresLayoutVarsContext
84  : public ContextHandler2
85 {
86 public:
87  PresLayoutVarsContext( ContextHandler2Helper const & rParent,
88  svx::diagram::Point & rPoint ) :
89  ContextHandler2( rParent ),
90  mrPoint( rPoint )
91  {
92  }
93  virtual ContextHandlerRef
94  onCreateContext( sal_Int32 aElementToken,
95  const AttributeList& rAttribs ) override
96  {
97  switch( aElementToken )
98  {
99  // TODO
100  case DGM_TOKEN( animLvl ):
101  case DGM_TOKEN( animOne ):
102  break;
103  case DGM_TOKEN( bulletEnabled ):
104  mrPoint.mbBulletEnabled = rAttribs.getBool( XML_val, false );
105  break;
106  case DGM_TOKEN( chMax ):
107  mrPoint.mnMaxChildren = rAttribs.getInteger( XML_val, -1 );
108  break;
109  case DGM_TOKEN( chPref ):
110  mrPoint.mnPreferredChildren = rAttribs.getInteger( XML_val, -1 );
111  break;
112  case DGM_TOKEN( dir ):
113  mrPoint.mnDirection = rAttribs.getToken( XML_val, XML_norm );
114  break;
115  case DGM_TOKEN( hierBranch ):
116  {
117  // need to convert from oox::OptValue to std::optional since 1st is not available in svx
118  const OptValue< sal_Int32 > aOptVal(rAttribs.getToken( XML_val ));
119  if(aOptVal.has_value())
120  mrPoint.moHierarchyBranch = aOptVal.get();
121  break;
122  }
123  case DGM_TOKEN( orgChart ):
124  mrPoint.mbOrgChartEnabled = rAttribs.getBool( XML_val, false );
125  break;
126  case DGM_TOKEN( resizeHandles ):
127  mrPoint.mnResizeHandles = rAttribs.getToken( XML_val, XML_rel );
128  break;
129  default:
130  break;
131  }
132 
133  return this;
134  }
135 
136 private:
138 };
139 
140 // CT_prSet
141 class PropertiesContext
142  : public ContextHandler2
143 {
144 public:
145  PropertiesContext( ContextHandler2Helper const & rParent,
146  svx::diagram::Point & rPoint,
147  const AttributeList& rAttribs ) :
148  ContextHandler2( rParent ),
149  mrPoint( rPoint )
150  {
151  mrPoint.msColorTransformCategoryId = rAttribs.getString( XML_csCatId, "" );
152  mrPoint.msColorTransformTypeId = rAttribs.getString( XML_csTypeId, "" );
153  mrPoint.msLayoutCategoryId = rAttribs.getString( XML_loCatId, "" );
154  mrPoint.msLayoutTypeId = rAttribs.getString( XML_loTypeId, "" );
155  mrPoint.msPlaceholderText = rAttribs.getString( XML_phldrT, "" );
156  mrPoint.msPresentationAssociationId = rAttribs.getString( XML_presAssocID, "" );
157  mrPoint.msPresentationLayoutName = rAttribs.getString( XML_presName, "" );
158  mrPoint.msPresentationLayoutStyleLabel = rAttribs.getString( XML_presStyleLbl, "" );
159  mrPoint.msQuickStyleCategoryId = rAttribs.getString( XML_qsCatId, "" );
160  mrPoint.msQuickStyleTypeId = rAttribs.getString( XML_qsTypeId, "" );
161 
162  mrPoint.mnCustomAngle = rAttribs.getInteger( XML_custAng, -1 );
163  mrPoint.mnPercentageNeighbourWidth = rAttribs.getInteger( XML_custLinFactNeighborX, -1 );
164  mrPoint.mnPercentageNeighbourHeight = rAttribs.getInteger( XML_custLinFactNeighborY, -1 );
165  mrPoint.mnPercentageOwnWidth = rAttribs.getInteger( XML_custLinFactX, -1 );
166  mrPoint.mnPercentageOwnHeight = rAttribs.getInteger( XML_custLinFactY, -1 );
167  mrPoint.mnIncludeAngleScale = rAttribs.getInteger( XML_custRadScaleInc, -1 );
168  mrPoint.mnRadiusScale = rAttribs.getInteger( XML_custRadScaleRad, -1 );
169  mrPoint.mnWidthScale = rAttribs.getInteger( XML_custScaleX, -1 );
170  mrPoint.mnHeightScale = rAttribs.getInteger( XML_custScaleY, -1 );
171  mrPoint.mnWidthOverride = rAttribs.getInteger( XML_custSzX, -1 );
172  mrPoint.mnHeightOverride = rAttribs.getInteger( XML_custSzY, -1 );
173  mrPoint.mnLayoutStyleCount = rAttribs.getInteger( XML_presStyleCnt, -1 );
174  mrPoint.mnLayoutStyleIndex = rAttribs.getInteger( XML_presStyleIdx, -1 );
175 
176  mrPoint.mbCoherent3DOffset = rAttribs.getBool( XML_coherent3DOff, false );
177  mrPoint.mbCustomHorizontalFlip = rAttribs.getBool( XML_custFlipHor, false );
178  mrPoint.mbCustomVerticalFlip = rAttribs.getBool( XML_custFlipVert, false );
179  mrPoint.mbCustomText = rAttribs.getBool( XML_custT, false );
180  mrPoint.mbIsPlaceholder = rAttribs.getBool( XML_phldr, false );
181  }
182 
183  virtual ContextHandlerRef
184  onCreateContext( sal_Int32 aElementToken,
185  const AttributeList& ) override
186  {
187  switch( aElementToken )
188  {
189  case DGM_TOKEN( presLayoutVars ):
190  return new PresLayoutVarsContext( *this, mrPoint );
191  case DGM_TOKEN( style ):
192  // skip CT_shapeStyle
193  return nullptr;
194  default:
195  break;
196  }
197  return this;
198  }
199 
200 private:
202 };
203 
204 // CL_Pt
205 class PtContext
206  : public ContextHandler2
207 {
208 public:
209  PtContext( ContextHandler2Helper const& rParent,
210  const AttributeList& rAttribs,
211  svx::diagram::Point& rPoint,
212  DiagramData& rDiagramData):
213  ContextHandler2( rParent ),
214  mrPoint( rPoint ),
215  mrDiagramData( rDiagramData )
216  {
217  mrPoint.msModelId = rAttribs.getString( XML_modelId ).get();
218 
219  // the default type is XML_node
220  const sal_Int32 nType = rAttribs.getToken( XML_type, XML_node );
221  mrPoint.mnXMLType = static_cast<svx::diagram::TypeConstant>(nType);
222 
223  // ignore the cxnId unless it is this type. See 5.15.3.1.3 in Primer
224  if( ( nType == XML_parTrans ) || ( nType == XML_sibTrans ) )
225  mrPoint.msCnxId = rAttribs.getString( XML_cxnId ).get();
226  }
227 
228  virtual ContextHandlerRef
229  onCreateContext( sal_Int32 aElementToken,
230  const AttributeList& rAttribs ) override
231  {
232  switch( aElementToken )
233  {
234  case DGM_TOKEN( extLst ):
235  return nullptr;
236  case DGM_TOKEN( prSet ):
237  return new PropertiesContext( *this, mrPoint, rAttribs );
238  case DGM_TOKEN( spPr ):
239  {
240  Shape* pShape(mrDiagramData.getOrCreateAssociatedShape(mrPoint, true));
241  return new ShapePropertiesContext( *this, *pShape );
242  }
243  case DGM_TOKEN( t ):
244  {
245  Shape* pShape(mrDiagramData.getOrCreateAssociatedShape(mrPoint, true));
246  TextBodyPtr xTextBody = std::make_shared<TextBody>();
247  pShape->setTextBody( xTextBody );
248  return new TextBodyContext( *this, *xTextBody );
249  }
250  default:
251  break;
252  }
253  return this;
254  }
255 
256 private:
258  DiagramData& mrDiagramData;
259 };
260 
261 // CT_PtList
262 class PtListContext
263  : public ContextHandler2
264 {
265 public:
266  PtListContext( ContextHandler2Helper const & rParent, svx::diagram::Points& rPoints, DiagramData& rDiagramData) :
267  ContextHandler2( rParent ),
268  mrPoints( rPoints ),
269  mrDiagramData( rDiagramData )
270  {}
271  virtual ContextHandlerRef
272  onCreateContext( sal_Int32 aElementToken,
273  const AttributeList& rAttribs ) override
274  {
275  switch( aElementToken )
276  {
277  case DGM_TOKEN( pt ):
278  {
279  // CT_Pt
280  mrPoints.emplace_back( );
281  return new PtContext( *this, rAttribs, mrPoints.back(), mrDiagramData );
282  }
283  default:
284  break;
285  }
286  return this;
287  }
288 
289 private:
291  DiagramData& mrDiagramData;
292 };
293 
294 // CT_BackgroundFormatting
295 class BackgroundFormattingContext
296  : public ContextHandler2
297 {
298 public:
299  BackgroundFormattingContext( ContextHandler2Helper const & rParent, OoxDiagramDataPtr const& pModel )
300  : ContextHandler2( rParent )
301  , mpDataModel( pModel )
302  {
303  assert( pModel && "the data model MUST NOT be NULL" );
304  }
305 
306  virtual ContextHandlerRef
307  onCreateContext( sal_Int32 aElementToken,
308  const AttributeList& rAttribs ) override
309  {
310  switch( aElementToken )
311  {
312  case A_TOKEN( blipFill ):
313  case A_TOKEN( gradFill ):
314  case A_TOKEN( grpFill ):
315  case A_TOKEN( noFill ):
316  case A_TOKEN( pattFill ):
317  case A_TOKEN( solidFill ):
318  // EG_FillProperties
319  return FillPropertiesContext::createFillContext(
320  *this, aElementToken, rAttribs, *mpDataModel->getBackgroundShapeFillProperties() );
321  case A_TOKEN( effectDag ):
322  case A_TOKEN( effectLst ):
323  // TODO
324  // EG_EffectProperties
325  break;
326  default:
327  break;
328  }
329  return this;
330  }
331 private:
333 };
334 
335 }
336 
338  const OoxDiagramDataPtr& pDataModel )
339  : ContextHandler2( rParent )
340  , mpDataModel( pDataModel )
341 {
342  assert( pDataModel && "Data Model must not be NULL" );
343 }
344 
346 {
347  // some debug
348  mpDataModel->dump();
349 }
350 
352 DataModelContext::onCreateContext( ::sal_Int32 aElement,
353  const AttributeList& rAttribs )
354 {
355  switch( aElement )
356  {
357  case DGM_TOKEN( cxnLst ):
358  // CT_CxnList
359  return new CxnListContext( *this, mpDataModel->getConnections() );
360  case DGM_TOKEN( ptLst ):
361  // CT_PtList
362  return new PtListContext( *this, mpDataModel->getPoints(), *mpDataModel );
363  case DGM_TOKEN( bg ):
364  // CT_BackgroundFormatting
365  return new BackgroundFormattingContext( *this, mpDataModel );
366  case DGM_TOKEN( whole ):
367  // CT_WholeE2oFormatting
368  // TODO
369  return nullptr;
370  case DGM_TOKEN( extLst ):
371  case A_TOKEN( ext ):
372  break;
373  case DSP_TOKEN( dataModelExt ):
374  mpDataModel->getExtDrawings().push_back( rAttribs.getString( XML_relId ).get() );
375  break;
376  default:
377  break;
378  }
379 
380  return this;
381 }
382 
383 }
384 
385 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
std::vector< Point > Points
sal_Int32 mnLayoutStyleCount
OUString msPresentationLayoutStyleLabel
OUString msPlaceholderText
sal_Int32 mnPercentageOwnWidth
sal_Int32 mnHeightScale
OUString msQuickStyleTypeId
sal_Int32 mnCustomAngle
OptValue< OUString > getString(sal_Int32 nAttrToken) const
Returns the string value of the specified attribute.
sal_Int32 mnPercentageOwnHeight
std::shared_ptr< DiagramData > OoxDiagramDataPtr
Definition: datamodel.hxx:74
TypeConstant mnXMLType
svx::diagram::Point & mrPoint
Shape
const Type & get() const
Definition: helper.hxx:184
svx::diagram::Points & mrPoints
sal_Int32 mnLayoutStyleIndex
sal_Int32 mnWidthScale
sal_Int32 mnHeightOverride
std::vector< Connection > Connections
sal_Int32 mnRadiusScale
OoxDiagramDataPtr mpDataModel
XML_norm
XML_sibTrans
Provides access to attribute values of an element.
DataModelContext(::oox::core::ContextHandler2Helper const &rParent, const OoxDiagramDataPtr &pDataModelPtr)
OUString msColorTransformCategoryId
OUString msColorTransformTypeId
svx::diagram::Connections & mrConnection
sal_Int32 mnPercentageNeighbourWidth
std::optional< sal_Int32 > moHierarchyBranch
OUString msLayoutCategoryId
OUString msPresentationAssociationId
::rtl::Reference< ContextHandler > ContextHandlerRef
QPRO_FUNC_TYPE nType
virtual ::oox::core::ContextHandlerRef onCreateContext(::sal_Int32 Element, const ::oox::AttributeList &rAttribs) override
sal_Int32 getToken(const Context &rContext, const char *pToken)
std::shared_ptr< TextBody > TextBodyPtr
OUString msPresentationLayoutName
DiagramData & mrDiagramData
Helper class that provides a context stack.
OUString msQuickStyleCategoryId
sal_Int32 mnIncludeAngleScale
sal_Int32 mnWidthOverride
sal_Int32 mnPercentageNeighbourHeight
bool m_bDetectedRangeSegmentation false
XML_rel