LibreOffice Module oox (master)  1
datasourcecontext.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 
21 
23 
26 #include <oox/token/namespaces.hxx>
27 #include <oox/token/tokens.hxx>
28 #include <svl/numformat.hxx>
29 #include <svl/zforlist.hxx>
30 #include <osl/diagnose.h>
31 
32 namespace oox::drawingml::chart {
33 
34 using ::oox::core::ContextHandler2Helper;
36 
37 using namespace ::com::sun::star;
38 
40  DataSequenceContextBase( rParent, rModel ),
41  mnPtIndex( -1 )
42 {
43 }
44 
46 {
47 }
48 
50 {
51  switch( getCurrentElement() )
52  {
53  case C_TOKEN( numRef ):
54  switch( nElement )
55  {
56  case C_TOKEN( f ):
57  case C_TOKEN( numCache ):
58  return this;
59  }
60  break;
61 
62  case C_TOKEN( numCache ):
63  case C_TOKEN( numLit ):
64  switch( nElement )
65  {
66  case C_TOKEN( formatCode ):
67  return this;
68  case C_TOKEN( ptCount ):
69  mrModel.mnPointCount = rAttribs.getInteger( XML_val, -1 );
70  return nullptr;
71  case C_TOKEN( pt ):
72  mnPtIndex = rAttribs.getInteger( XML_idx, -1 );
73  return this;
74  }
75  break;
76 
77  case C_TOKEN( pt ):
78  switch( nElement )
79  {
80  case C_TOKEN( v ):
81  return this;
82  }
83  break;
84  }
85  return nullptr;
86 }
87 
88 void DoubleSequenceContext::onCharacters( const OUString& rChars )
89 {
90  switch( getCurrentElement() )
91  {
92  case C_TOKEN( f ):
93  mrModel.maFormula = rChars;
94  break;
95  case C_TOKEN( formatCode ):
96  mrModel.maFormatCode = rChars;
97  break;
98  case C_TOKEN( v ):
99  if( mnPtIndex >= 0 )
100  {
101  /* Import categories as String even though it could
102  * be values except when the format code indicates that they are dates.
103  * n#810508: xVal needs to be imported as double
104  * TODO: NumberFormat conversion, remove the check then.
105  */
106  if( isParentElement( C_TOKEN( cat ), 4 ) )
107  {
108  // workaround for bug n#889755
110  if( pNumFrmt )
111  {
112  sal_uInt32 nKey = pNumFrmt->GetEntryKey( mrModel.maFormatCode );
113  bool bNoKey = ( nKey == NUMBERFORMAT_ENTRY_NOT_FOUND );
114  if( bNoKey )
115  {
116  OUString aFormatCode = mrModel.maFormatCode;
117  sal_Int32 nCheckPos = 0;
119  pNumFrmt->PutEntry( aFormatCode, nCheckPos, nType, nKey );
120  bNoKey = (nCheckPos != 0);
121  if (!bNoKey)
122  mrModel.meFormatType = nType;
123  }
124  if( bNoKey )
125  {
126  mrModel.maData[ mnPtIndex ] <<= rChars;
127  }
128  else
129  {
130  double fValue = rChars.toDouble();
131  if (mrModel.meFormatType == SvNumFormatType::DATE)
132  mrModel.maData[ mnPtIndex ] <<= fValue;
133  else
134  {
135  const ::Color* pColor = nullptr;
136  OUString aFormattedValue;
137  // tdf#91250: use UNLIMITED_PRECISION in case of GENERAL Number Format of category axis labels
140  pNumFrmt->GetOutputString( fValue, nKey, aFormattedValue, &pColor );
141  mrModel.maData[ mnPtIndex ] <<= aFormattedValue;
142  }
143  }
144  }
145  else
146  {
147  mrModel.maData[ mnPtIndex ] <<= rChars;
148  }
149  }
150  else
151  {
152  mrModel.maData[ mnPtIndex ] <<= rChars.toDouble();
153  }
154  }
155  break;
156  }
157 }
158 
159 
161 {
162  if( mpNumberFormatter == nullptr )
163  {
164  uno::Reference<uno::XComponentContext> rContext =
166  mpNumberFormatter.reset(
167  new SvNumberFormatter(rContext, LANGUAGE_SYSTEM) );
168  }
169  return mpNumberFormatter.get();
170 }
171 
172 
174  : DataSequenceContextBase( rParent, rModel )
175  , mnPtIndex(-1)
176  , mbReadC15(false)
177 {
178 }
179 
181 {
182 }
183 
185 {
186  switch( getCurrentElement() )
187  {
188  case C_TOKEN( multiLvlStrRef ):
189  switch( nElement )
190  {
191  case C_TOKEN( f ):
192  case C_TOKEN( multiLvlStrCache ):
193  return this;
194  }
195  break;
196 
197  case C15_TOKEN( datalabelsRange ):
198  mbReadC15 = true;
199  switch( nElement )
200  {
201  case C15_TOKEN( f ):
202  case C15_TOKEN( dlblRangeCache ):
203  return this;
204  }
205  break;
206 
207  case C_TOKEN( strRef ):
208  switch( nElement )
209  {
210  case C_TOKEN( f ):
211  case C_TOKEN( strCache ):
212  return this;
213  }
214  break;
215 
216  case C_TOKEN( strCache ):
217  case C_TOKEN( strLit ):
218  case C15_TOKEN( dlblRangeCache ):
219  if (nElement == C15_TOKEN( dlblRangeCache ) && !mbReadC15)
220  break;
221 
222  switch( nElement )
223  {
224  case C_TOKEN( ptCount ):
225  mrModel.mnPointCount = rAttribs.getInteger( XML_val, -1 );
226  return nullptr;
227  case C_TOKEN( pt ):
228  mnPtIndex = rAttribs.getInteger( XML_idx, -1 );
229  return this;
230  }
231  break;
232 
233  case C_TOKEN( multiLvlStrCache ):
234  switch (nElement)
235  {
236  case C_TOKEN( ptCount ):
237  mrModel.mnPointCount = rAttribs.getInteger(XML_val, -1);
238  mrModel.mnLevelCount--; // normalize level count
239  return nullptr;
240  case C_TOKEN( lvl ):
241  mrModel.mnLevelCount++;
242  return this;
243  }
244  break;
245 
246  case C_TOKEN( lvl ):
247  switch (nElement)
248  {
249  case C_TOKEN(pt):
250  mnPtIndex = rAttribs.getInteger(XML_idx, -1);
251  return this;
252  }
253  break;
254 
255  case C_TOKEN( pt ):
256  switch( nElement )
257  {
258  case C_TOKEN( v ):
259  return this;
260  }
261  break;
262  }
263  return nullptr;
264 }
265 
266 void StringSequenceContext::onCharacters( const OUString& rChars )
267 {
268  switch( getCurrentElement() )
269  {
270  case C_TOKEN( f ):
271  mrModel.maFormula = rChars;
272  break;
273  case C15_TOKEN( f ):
274  if (mbReadC15)
275  mrModel.maFormula = rChars;
276  break;
277  case C_TOKEN( v ):
278  if( mnPtIndex >= 0 )
279  mrModel.maData[ (mrModel.mnLevelCount-1) * mrModel.mnPointCount + mnPtIndex ] <<= rChars;
280  break;
281  }
282 }
283 
285  ContextBase< DataSourceModel >( rParent, rModel )
286 {
287 }
288 
290 {
291 }
292 
294 {
295  switch( getCurrentElement() )
296  {
297  case C_TOKEN( cat ):
298  case C_TOKEN( xVal ):
299  case C_TOKEN( ext ):
300  switch( nElement )
301  {
302  case C_TOKEN( multiLvlStrRef ):
303  case C_TOKEN( strLit ):
304  case C_TOKEN( strRef ):
305  case C15_TOKEN( datalabelsRange ):
306  OSL_ENSURE( !mrModel.mxDataSeq, "DataSourceContext::onCreateContext - multiple data sequences" );
307  return new StringSequenceContext( *this, mrModel.mxDataSeq.create() );
308 
309  case C_TOKEN( numLit ):
310  case C_TOKEN( numRef ):
311  OSL_ENSURE( !mrModel.mxDataSeq, "DataSourceContext::onCreateContext - multiple data sequences" );
312  return new DoubleSequenceContext( *this, mrModel.mxDataSeq.create() );
313  }
314  break;
315 
316  case C_TOKEN( plus ):
317  case C_TOKEN( minus ):
318  case C_TOKEN( val ):
319  case C_TOKEN( yVal ):
320  case C_TOKEN( bubbleSize ):
321  switch( nElement )
322  {
323  case C_TOKEN( numLit ):
324  case C_TOKEN( numRef ):
325  OSL_ENSURE( !mrModel.mxDataSeq, "DataSourceContext::onCreateContext - multiple data sequences" );
326  return new DoubleSequenceContext( *this, mrModel.mxDataSeq.create() );
327  }
328  break;
329  }
330  return nullptr;
331 }
332 
333 } // namespace oox::drawingml::chart
334 
335 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
OptValue< sal_Int32 > getInteger(sal_Int32 nAttrToken) const
Returns the 32-bit signed integer value of the specified attribute (decimal).
virtual ::oox::core::ContextHandlerRef onCreateContext(sal_Int32 nElement, const AttributeList &rAttribs) override
Will be called to create a context handler for the passed element.
StringSequenceContext(::oox::core::ContextHandler2Helper &rParent, DataSequenceModel &rModel)
bool PutEntry(OUString &rString, sal_Int32 &nCheckPos, SvNumFormatType &nType, sal_uInt32 &nKey, LanguageType eLnge=LANGUAGE_DONTKNOW, bool bReplaceBooleanEquivalent=true)
constexpr sal_uInt32 NUMBERFORMAT_ENTRY_NOT_FOUND
sal_uInt16 GetStandardPrec() const
Handler for a double sequence context (c:numLit, c:numRef elements).
virtual void onCharacters(const OUString &rChars) override
Will be called before a new child element starts, or if the current element is about to be left...
virtual ::oox::core::ContextHandlerRef onCreateContext(sal_Int32 nElement, const AttributeList &rAttribs) override
Will be called to create a context handler for the passed element.
#define LANGUAGE_SYSTEM
sal_Int32 getCurrentElement() const
Returns the identifier of the currently processed element.
const css::uno::Reference< css::uno::XComponentContext > & getComponentContext() const
Returns the component context passed in the filter constructor (always existing). ...
Definition: filterbase.cxx:212
SvNumFormatType
sal_uInt32 GetEntryKey(std::u16string_view sStr, LanguageType eLnge=LANGUAGE_DONTKNOW)
Provides access to attribute values of an element.
bool isParentElement(sal_Int32 nElement, sal_Int32 nCountBack=1) const
Returns true, if nElement contains the identifier of the specified parent element.
static const sal_uInt16 UNLIMITED_PRECISION
float v
DataSourceContext(::oox::core::ContextHandler2Helper &rParent, DataSourceModel &rModel)
XmlFilterBase & getFilter() const
Returns the filter instance.
::rtl::Reference< ContextHandler > ContextHandlerRef
QPRO_FUNC_TYPE nType
virtual void onCharacters(const OUString &rChars) override
Will be called before a new child element starts, or if the current element is about to be left...
virtual ::oox::core::ContextHandlerRef onCreateContext(sal_Int32 nElement, const AttributeList &rAttribs) override
Will be called to create a context handler for the passed element.
std::unique_ptr< SvNumberFormatter > mpNumberFormatter
Current data point index.
void(* f)(TrueTypeTable *)
Handler for a string sequence context (c:multiLvlStrRef, c:strLit, c:strRef elements).
void ChangeStandardPrec(short nPrec)
Helper class that provides a context stack.
DoubleSequenceContext(::oox::core::ContextHandler2Helper &rParent, DataSequenceModel &rModel)
void GetOutputString(const double &fOutNumber, sal_uInt32 nFIndex, OUString &sOutString, const Color **ppColor, bool bUseStarFormat=false)