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
32namespace oox::drawingml::chart {
33
34using ::oox::core::ContextHandler2Helper;
36
37using namespace ::com::sun::star;
38
39DoubleSequenceContext::DoubleSequenceContext( ContextHandler2Helper& rParent, DataSequenceModel& rModel ) :
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
88void 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
173StringSequenceContext::StringSequenceContext( ContextHandler2Helper& rParent, DataSequenceModel& rModel )
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
266void 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
284DataSourceContext::DataSourceContext( ContextHandler2Helper& rParent, DataSourceModel& rModel ) :
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: */
bool PutEntry(OUString &rString, sal_Int32 &nCheckPos, SvNumFormatType &nType, sal_uInt32 &nKey, LanguageType eLnge=LANGUAGE_DONTKNOW, bool bReplaceBooleanEquivalent=true)
sal_uInt16 GetStandardPrec() const
void GetOutputString(const double &fOutNumber, sal_uInt32 nFIndex, OUString &sOutString, const Color **ppColor, bool bUseStarFormat=false)
sal_uInt32 GetEntryKey(std::u16string_view sStr, LanguageType eLnge=LANGUAGE_DONTKNOW)
static const sal_uInt16 UNLIMITED_PRECISION
void ChangeStandardPrec(short nPrec)
Provides access to attribute values of an element.
std::optional< sal_Int32 > getInteger(sal_Int32 nAttrToken) const
Returns the 32-bit signed integer value of the specified attribute (decimal).
XmlFilterBase & getFilter() const
Returns the filter instance.
const css::uno::Reference< css::uno::XComponentContext > & getComponentContext() const
Returns the component context passed in the filter constructor (always existing).
Definition: filterbase.cxx:215
DataSourceContext(::oox::core::ContextHandler2Helper &rParent, DataSourceModel &rModel)
virtual ::oox::core::ContextHandlerRef onCreateContext(sal_Int32 nElement, const AttributeList &rAttribs) override
Handler for a double sequence context (c:numLit, c:numRef elements).
virtual ::oox::core::ContextHandlerRef onCreateContext(sal_Int32 nElement, const AttributeList &rAttribs) override
std::unique_ptr< SvNumberFormatter > mpNumberFormatter
Current data point index.
DoubleSequenceContext(::oox::core::ContextHandler2Helper &rParent, DataSequenceModel &rModel)
virtual void onCharacters(const OUString &rChars) override
Handler for a string sequence context (c:multiLvlStrRef, c:strLit, c:strRef elements).
virtual ::oox::core::ContextHandlerRef onCreateContext(sal_Int32 nElement, const AttributeList &rAttribs) override
StringSequenceContext(::oox::core::ContextHandler2Helper &rParent, DataSequenceModel &rModel)
virtual void onCharacters(const OUString &rChars) override
float v
#define LANGUAGE_SYSTEM
::rtl::Reference< ContextHandler > ContextHandlerRef
QPRO_FUNC_TYPE nType
SvNumFormatType
constexpr sal_uInt32 NUMBERFORMAT_ENTRY_NOT_FOUND