Version 7.6.3.2-android, tag libreoffice-7.6.3.2-android
[LibreOffice.git] / oox / source / drawingml / chart / datasourcecontext.cxx
blobf4660f5db708f5f1b230fbc4488e116b2e79b99b
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3 * This file is part of the LibreOffice project.
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/.
9 * This file incorporates work covered by the following license notice:
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 .
20 #include <drawingml/chart/datasourcecontext.hxx>
22 #include <oox/drawingml/chart/datasourcemodel.hxx>
24 #include <oox/core/xmlfilterbase.hxx>
25 #include <oox/helper/attributelist.hxx>
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>
32 namespace oox::drawingml::chart {
34 using ::oox::core::ContextHandler2Helper;
35 using ::oox::core::ContextHandlerRef;
37 using namespace ::com::sun::star;
39 DoubleSequenceContext::DoubleSequenceContext( ContextHandler2Helper& rParent, DataSequenceModel& rModel ) :
40 DataSequenceContextBase( rParent, rModel ),
41 mnPtIndex( -1 )
45 DoubleSequenceContext::~DoubleSequenceContext()
49 ContextHandlerRef DoubleSequenceContext::onCreateContext( sal_Int32 nElement, const AttributeList& rAttribs )
51 switch( getCurrentElement() )
53 case C_TOKEN( numRef ):
54 switch( nElement )
56 case C_TOKEN( f ):
57 case C_TOKEN( numCache ):
58 return this;
60 break;
62 case C_TOKEN( numCache ):
63 case C_TOKEN( numLit ):
64 switch( nElement )
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;
75 break;
77 case C_TOKEN( pt ):
78 switch( nElement )
80 case C_TOKEN( v ):
81 return this;
83 break;
85 return nullptr;
88 void DoubleSequenceContext::onCharacters( const OUString& rChars )
90 switch( getCurrentElement() )
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 )
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.
106 if( isParentElement( C_TOKEN( cat ), 4 ) )
108 // workaround for bug n#889755
109 SvNumberFormatter* pNumFrmt = getNumberFormatter();
110 if( pNumFrmt )
112 sal_uInt32 nKey = pNumFrmt->GetEntryKey( mrModel.maFormatCode );
113 bool bNoKey = ( nKey == NUMBERFORMAT_ENTRY_NOT_FOUND );
114 if( bNoKey )
116 OUString aFormatCode = mrModel.maFormatCode;
117 sal_Int32 nCheckPos = 0;
118 SvNumFormatType nType;
119 pNumFrmt->PutEntry( aFormatCode, nCheckPos, nType, nKey );
120 bNoKey = (nCheckPos != 0);
121 if (!bNoKey)
122 mrModel.meFormatType = nType;
124 if( bNoKey )
126 mrModel.maData[ mnPtIndex ] <<= rChars;
128 else
130 double fValue = rChars.toDouble();
131 if (mrModel.meFormatType == SvNumFormatType::DATE)
132 mrModel.maData[ mnPtIndex ] <<= fValue;
133 else
135 const ::Color* pColor = nullptr;
136 OUString aFormattedValue;
137 // tdf#91250: use UNLIMITED_PRECISION in case of GENERAL Number Format of category axis labels
138 if( pNumFrmt->GetStandardPrec() != SvNumberFormatter::UNLIMITED_PRECISION )
139 pNumFrmt->ChangeStandardPrec(SvNumberFormatter::UNLIMITED_PRECISION);
140 pNumFrmt->GetOutputString( fValue, nKey, aFormattedValue, &pColor );
141 mrModel.maData[ mnPtIndex ] <<= aFormattedValue;
145 else
147 mrModel.maData[ mnPtIndex ] <<= rChars;
150 else
152 mrModel.maData[ mnPtIndex ] <<= rChars.toDouble();
155 break;
160 SvNumberFormatter* DoubleSequenceContext::getNumberFormatter()
162 if( mpNumberFormatter == nullptr )
164 uno::Reference<uno::XComponentContext> rContext =
165 getFilter().getComponentContext();
166 mpNumberFormatter.reset(
167 new SvNumberFormatter(rContext, LANGUAGE_SYSTEM) );
169 return mpNumberFormatter.get();
173 StringSequenceContext::StringSequenceContext( ContextHandler2Helper& rParent, DataSequenceModel& rModel )
174 : DataSequenceContextBase( rParent, rModel )
175 , mnPtIndex(-1)
176 , mbReadC15(false)
180 StringSequenceContext::~StringSequenceContext()
184 ContextHandlerRef StringSequenceContext::onCreateContext( sal_Int32 nElement, const AttributeList& rAttribs )
186 switch( getCurrentElement() )
188 case C_TOKEN( multiLvlStrRef ):
189 switch( nElement )
191 case C_TOKEN( f ):
192 case C_TOKEN( multiLvlStrCache ):
193 return this;
195 break;
197 case C15_TOKEN( datalabelsRange ):
198 mbReadC15 = true;
199 switch( nElement )
201 case C15_TOKEN( f ):
202 case C15_TOKEN( dlblRangeCache ):
203 return this;
205 break;
207 case C_TOKEN( strRef ):
208 switch( nElement )
210 case C_TOKEN( f ):
211 case C_TOKEN( strCache ):
212 return this;
214 break;
216 case C_TOKEN( strCache ):
217 case C_TOKEN( strLit ):
218 case C15_TOKEN( dlblRangeCache ):
219 if (nElement == C15_TOKEN( dlblRangeCache ) && !mbReadC15)
220 break;
222 switch( nElement )
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;
231 break;
233 case C_TOKEN( multiLvlStrCache ):
234 switch (nElement)
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;
244 break;
246 case C_TOKEN( lvl ):
247 switch (nElement)
249 case C_TOKEN(pt):
250 mnPtIndex = rAttribs.getInteger(XML_idx, -1);
251 return this;
253 break;
255 case C_TOKEN( pt ):
256 switch( nElement )
258 case C_TOKEN( v ):
259 return this;
261 break;
263 return nullptr;
266 void StringSequenceContext::onCharacters( const OUString& rChars )
268 switch( getCurrentElement() )
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;
284 DataSourceContext::DataSourceContext( ContextHandler2Helper& rParent, DataSourceModel& rModel ) :
285 ContextBase< DataSourceModel >( rParent, rModel )
289 DataSourceContext::~DataSourceContext()
293 ContextHandlerRef DataSourceContext::onCreateContext( sal_Int32 nElement, const AttributeList& )
295 switch( getCurrentElement() )
297 case C_TOKEN( cat ):
298 case C_TOKEN( xVal ):
299 case C_TOKEN( ext ):
300 switch( nElement )
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() );
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() );
314 break;
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 )
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() );
328 break;
330 return nullptr;
333 } // namespace oox::drawingml::chart
335 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */