LibreOffice Module xmloff (master) 1
SchXMLChartContext.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#include <SchXMLImport.hxx>
27#include "SchXMLTools.hxx"
28#include <osl/diagnose.h>
29#include <sal/log.hxx>
30#include <tools/diagnose_ex.h>
33#include <xmloff/xmltoken.hxx>
35#include <xmloff/xmluconv.hxx>
36#include <xmloff/xmlstyle.hxx>
38
39#include <vector>
40#include <com/sun/star/lang/XMultiServiceFactory.hpp>
41#include <com/sun/star/chart/XChartDocument.hpp>
42#include <com/sun/star/chart/XDiagram.hpp>
43#include <com/sun/star/xml/sax/XAttributeList.hpp>
44#include <com/sun/star/drawing/XDrawPageSupplier.hpp>
45#include <com/sun/star/drawing/XDrawPage.hpp>
46#include <com/sun/star/chart/ChartDataRowSource.hpp>
47#include <com/sun/star/embed/Aspects.hpp>
48#include <com/sun/star/embed/XVisualObject.hpp>
49
50#include <com/sun/star/chart2/XChartDocument.hpp>
51#include <com/sun/star/chart2/data/XDataSink.hpp>
52#include <com/sun/star/chart2/data/XPivotTableDataProvider.hpp>
53#include <com/sun/star/chart2/XDataSeriesContainer.hpp>
54#include <com/sun/star/chart2/XCoordinateSystemContainer.hpp>
55#include <com/sun/star/chart2/XChartTypeContainer.hpp>
56#include <com/sun/star/chart2/XTitled.hpp>
57
58#include <com/sun/star/container/XChild.hpp>
59#include <com/sun/star/chart2/data/XDataReceiver.hpp>
60#include <o3tl/safeint.hxx>
61#include <o3tl/string_view.hxx>
62
63using namespace com::sun::star;
64using namespace ::xmloff::token;
66using namespace ::SchXMLTools;
67
68namespace
69{
70
71void lcl_setRoleAtLabeledSequence(
72 const uno::Reference< chart2::data::XLabeledDataSequence > & xLSeq,
73 const OUString &rRole )
74{
75 // set role of sequence
76 uno::Reference< chart2::data::XDataSequence > xValues( xLSeq->getValues());
77 if( xValues.is())
78 {
79 uno::Reference< beans::XPropertySet > xProp( xValues, uno::UNO_QUERY );
80 if( xProp.is())
81 xProp->setPropertyValue("Role", uno::Any( rRole ));
82 }
83}
84
85void lcl_MoveDataToCandleStickSeries(
86 const uno::Reference< chart2::data::XDataSource > & xDataSource,
87 const uno::Reference< chart2::XDataSeries > & xDestination,
88 const OUString & rRole )
89{
90 try
91 {
92 uno::Sequence< uno::Reference< chart2::data::XLabeledDataSequence > > aLabeledSeq(
93 xDataSource->getDataSequences());
94 if( aLabeledSeq.hasElements())
95 {
96 lcl_setRoleAtLabeledSequence( aLabeledSeq[0], rRole );
97
98 // add to data series
99 uno::Reference< chart2::data::XDataSource > xSource( xDestination, uno::UNO_QUERY_THROW );
100 // @todo: realloc only once outside this function
101 uno::Sequence< uno::Reference< chart2::data::XLabeledDataSequence > > aData( xSource->getDataSequences());
102 aData.realloc( aData.getLength() + 1);
103 aData.getArray()[ aData.getLength() - 1 ] = aLabeledSeq[0];
104 uno::Reference< chart2::data::XDataSink > xSink( xDestination, uno::UNO_QUERY_THROW );
105 xSink->setData( aData );
106 }
107 }
108 catch(const uno::Exception&)
109 {
110 TOOLS_WARN_EXCEPTION("xmloff.chart", "Exception caught while moving data to candlestick series" );
111 }
112}
113
114void lcl_setRoleAtFirstSequence(
115 const uno::Reference< chart2::XDataSeries > & xSeries,
116 const OUString & rRole )
117{
118 uno::Reference< chart2::data::XDataSource > xSource( xSeries, uno::UNO_QUERY );
119 if( xSource.is())
120 {
121 uno::Sequence< uno::Reference< chart2::data::XLabeledDataSequence > > aSeq( xSource->getDataSequences());
122 if( aSeq.hasElements())
123 lcl_setRoleAtLabeledSequence( aSeq[0], rRole );
124 }
125}
126
127void lcl_removeEmptyChartTypeGroups( const uno::Reference< chart2::XChartDocument > & xDoc )
128{
129 if( ! xDoc.is())
130 return;
131
132 uno::Reference< chart2::XDiagram > xDia( xDoc->getFirstDiagram());
133 if( ! xDia.is())
134 return;
135
136 try
137 {
138 // count all charttype groups to be able to leave at least one
139 sal_Int32 nRemainingGroups = 0;
140 uno::Reference< chart2::XCoordinateSystemContainer > xCooSysCnt( xDia, uno::UNO_QUERY_THROW );
141 const uno::Sequence< uno::Reference< chart2::XCoordinateSystem > >
142 aCooSysSeq( xCooSysCnt->getCoordinateSystems());
143 for( auto const & i : aCooSysSeq )
144 {
145 uno::Reference< chart2::XChartTypeContainer > xCTCnt( i, uno::UNO_QUERY_THROW );
146 nRemainingGroups += xCTCnt->getChartTypes().getLength();
147 }
148
149 // delete all empty groups, but leave at least group (empty or not)
150 for( sal_Int32 nI = aCooSysSeq.getLength(); nI-- && (nRemainingGroups > 1); )
151 {
152 uno::Reference< chart2::XChartTypeContainer > xCTCnt( aCooSysSeq[nI], uno::UNO_QUERY_THROW );
153 uno::Sequence< uno::Reference< chart2::XChartType > > aCTSeq( xCTCnt->getChartTypes());
154 for( sal_Int32 nJ=aCTSeq.getLength(); nJ-- && (nRemainingGroups > 1); )
155 {
156 uno::Reference< chart2::XDataSeriesContainer > xDSCnt( aCTSeq[nJ], uno::UNO_QUERY_THROW );
157 if( !xDSCnt->getDataSeries().hasElements() )
158 {
159 // note: iterator stays valid as we have a local sequence
160 xCTCnt->removeChartType( aCTSeq[nJ] );
161 --nRemainingGroups;
162 }
163 }
164 }
165 }
166 catch(const uno::Exception&)
167 {
168 TOOLS_INFO_EXCEPTION("xmloff.chart", "Exception caught while removing empty chart types");
169 }
170}
171
172uno::Sequence< sal_Int32 > lcl_getNumberSequenceFromString( const OUString& rStr, bool bAddOneToEachOldIndex )
173{
174 const sal_Unicode aSpace( ' ' );
175
176 // count number of entries
177 ::std::vector< sal_Int32 > aVec;
178 sal_Int32 nLastPos = 0;
179 sal_Int32 nPos = 0;
180 while( nPos != -1 )
181 {
182 nPos = rStr.indexOf( aSpace, nLastPos );
183 if( nPos > nLastPos )
184 {
185 aVec.push_back( o3tl::toInt32(rStr.subView( nLastPos, (nPos - nLastPos) )) );
186 }
187 if( nPos != -1 )
188 nLastPos = nPos + 1;
189 }
190 // last entry
191 if( nLastPos != 0 &&
192 rStr.getLength() > nLastPos )
193 {
194 aVec.push_back( o3tl::toInt32(rStr.subView( nLastPos )) );
195 }
196
197 const sal_Int32 nVecSize = aVec.size();
198 uno::Sequence< sal_Int32 > aSeq( nVecSize );
199
200 if(!bAddOneToEachOldIndex)
201 {
202 sal_Int32* pSeqArr = aSeq.getArray();
203 for( nPos = 0; nPos < nVecSize; ++nPos )
204 {
205 pSeqArr[ nPos ] = aVec[ nPos ];
206 }
207 }
208 else if( bAddOneToEachOldIndex )
209 {
210 aSeq.realloc( nVecSize+1 );
211 auto pSeqArr = aSeq.getArray();
212 pSeqArr[0]=0;
213
214 for( nPos = 0; nPos < nVecSize; ++nPos )
215 {
216 pSeqArr[ nPos+1 ] = aVec[ nPos ]+1;
217 }
218 }
219
220 return aSeq;
221}
222
223} // anonymous namespace
224
226 SvXMLImport& rImport ) :
227 SvXMLImportContext( rImport ),
228 mrImportHelper( rImpHelper ),
229 m_bHasRangeAtPlotArea( false ),
230 m_bHasTableElement( false ),
231 mbAllRangeAddressesAvailable( true ),
232 mbColHasLabels( false ),
233 mbRowHasLabels( false ),
234 meDataRowSource( chart::ChartDataRowSource_COLUMNS ),
235 mbIsStockChart( false )
236{
237}
238
240{}
241
242static bool lcl_hasServiceName(Reference<lang::XMultiServiceFactory> const & xFactory, OUString const & rServiceName)
243{
244 const uno::Sequence<OUString> aServiceNames(xFactory->getAvailableServiceNames());
245
246 return std::find(aServiceNames.begin(), aServiceNames.end(), rServiceName) != aServiceNames.end();
247}
248
249void setDataProvider(uno::Reference<chart2::XChartDocument> const & xChartDoc, OUString const & sDataPilotSource)
250{
251 if (!xChartDoc.is())
252 return;
253
254 try
255 {
256 uno::Reference<container::XChild> xChild(xChartDoc, uno::UNO_QUERY);
257 uno::Reference<chart2::data::XDataReceiver> xDataReceiver(xChartDoc, uno::UNO_QUERY);
258 if (xChild.is() && xDataReceiver.is())
259 {
260 bool bHasOwnData = true;
261
262 Reference<lang::XMultiServiceFactory> xFact(xChild->getParent(), uno::UNO_QUERY);
263 if (xFact.is())
264 {
265 if (!xChartDoc->getDataProvider().is())
266 {
267 bool bHasDataPilotSource = !sDataPilotSource.isEmpty();
268 OUString aDataProviderServiceName("com.sun.star.chart2.data.DataProvider");
269 if (bHasDataPilotSource)
270 aDataProviderServiceName = "com.sun.star.chart2.data.PivotTableDataProvider";
271
272 if (lcl_hasServiceName(xFact, aDataProviderServiceName))
273 {
274 Reference<chart2::data::XDataProvider> xProvider(xFact->createInstance(aDataProviderServiceName), uno::UNO_QUERY);
275
276 if (xProvider.is())
277 {
278 if (bHasDataPilotSource)
279 {
280 Reference<chart2::data::XPivotTableDataProvider> xPivotTableDataProvider(xProvider, uno::UNO_QUERY);
281 xPivotTableDataProvider->setPivotTableName(sDataPilotSource);
282 xDataReceiver->attachDataProvider(xProvider);
283 bHasOwnData = !xPivotTableDataProvider->hasPivotTable();
284 }
285 else
286 {
287 xDataReceiver->attachDataProvider(xProvider);
288 bHasOwnData = false;
289 }
290 }
291 }
292 }
293 else
294 bHasOwnData = false;
295 }
296 // else we have no parent => we have our own data
297
298 if (bHasOwnData && ! xChartDoc->hasInternalDataProvider())
299 xChartDoc->createInternalDataProvider(false);
300 }
301 }
302 catch (const uno::Exception &)
303 {
304 TOOLS_INFO_EXCEPTION("xmloff.chart", "SchXMLChartContext::StartElement()");
305 }
306}
307
308void SchXMLChartContext::startFastElement( sal_Int32 /*nElement*/,
309 const css::uno::Reference< css::xml::sax::XFastAttributeList >& xAttrList )
310{
311 // parse attributes
312
313 uno::Reference< embed::XVisualObject > xVisualObject( mrImportHelper.GetChartDocument(), uno::UNO_QUERY);
314 SAL_WARN_IF(!xVisualObject.is(), "xmloff.chart", "need xVisualObject for page size");
315 if( xVisualObject.is() )
316 maChartSize = xVisualObject->getVisualAreaSize( embed::Aspects::MSOLE_CONTENT ); //#i103460# take the size given from the parent frame as default
317
318 OUString sAutoStyleName;
319 OUString aOldChartTypeName;
320 bool bHasAddin = false;
321
322 for( auto& aIter : sax_fastparser::castToFastAttributeList(xAttrList) )
323 {
324 switch( aIter.getToken() )
325 {
327 msDataPilotSource = aIter.toString();
328 break;
329 case XML_ELEMENT(XLINK, XML_HREF):
331 break;
333 {
334 OUString aValue = aIter.toString();
335 OUString sClassName;
336 sal_uInt16 nClassPrefix =
338 aValue, &sClassName );
339 if( XML_NAMESPACE_CHART == nClassPrefix )
340 {
341 SchXMLChartTypeEnum eChartTypeEnum = SchXMLTools::GetChartTypeEnum( sClassName );
342 if( eChartTypeEnum != XML_CHART_CLASS_UNKNOWN )
343 {
344 aOldChartTypeName = SchXMLTools::GetChartTypeByClassName( sClassName, true /* bUseOldNames */ );
345 maChartTypeServiceName = SchXMLTools::GetChartTypeByClassName( sClassName, false /* bUseOldNames */ );
346 switch( eChartTypeEnum )
347 {
349 mbIsStockChart = true;
350 break;
351 default:
352 break;
353 }
354 }
355 }
356 else if( XML_NAMESPACE_OOO == nClassPrefix )
357 {
358 // service is taken from add-in-name attribute
359 bHasAddin = true;
360
361 aOldChartTypeName = sClassName;
362 maChartTypeServiceName = sClassName;
363 }
364 }
365 break;
366
368 case XML_ELEMENT(SVG_COMPAT, XML_WIDTH):
370 maChartSize.Width, aIter.toView() );
371 break;
372
374 case XML_ELEMENT(SVG_COMPAT, XML_HEIGHT):
376 maChartSize.Height, aIter.toView() );
377 break;
378
380 sAutoStyleName = aIter.toString();
381 break;
382
384 msColTrans = aIter.toString();
385 break;
387 msRowTrans = aIter.toString();
388 break;
389 default:
390 XMLOFF_WARN_UNKNOWN("xmloff", aIter);
391 }
392 }
393
394 uno::Reference<chart::XChartDocument> xDoc = mrImportHelper.GetChartDocument();
395 uno::Reference<chart2::XChartDocument> xNewDoc(xDoc, uno::UNO_QUERY);
396
398
399 if( aOldChartTypeName.isEmpty() )
400 {
401 SAL_WARN("xmloff.chart", "need a charttype to create a diagram" );
402 //set a fallback value:
403 const OUString& aChartClass_Bar( GetXMLToken(XML_BAR ) );
404 aOldChartTypeName = SchXMLTools::GetChartTypeByClassName( aChartClass_Bar, true /* bUseOldNames */ );
405 maChartTypeServiceName = SchXMLTools::GetChartTypeByClassName( aChartClass_Bar, false /* bUseOldNames */ );
406 }
407
408 // Set the size of the draw page.
409 if( xVisualObject.is() )
410 xVisualObject->setVisualAreaSize( embed::Aspects::MSOLE_CONTENT, maChartSize );
411
412 InitChart( aOldChartTypeName);
413
414 if( bHasAddin )
415 {
416 //correct charttype service name when having an addin
417 //and don't refresh addin during load
418 uno::Reference< beans::XPropertySet > xDocProp( mrImportHelper.GetChartDocument(), uno::UNO_QUERY );
419 if( xDocProp.is() )
420 {
421 try
422 {
423 xDocProp->getPropertyValue("BaseDiagram") >>= aOldChartTypeName;
425 xDocProp->setPropertyValue("RefreshAddInAllowed", uno::Any( false) );
426 }
427 catch(const uno::Exception&)
428 {
429 TOOLS_WARN_EXCEPTION("xmloff.chart", "Exception during import SchXMLChartContext::StartElement" );
430 }
431 }
432 }
433
434 // set auto-styles for Area
435 uno::Reference<beans::XPropertySet> xProp = mrImportHelper.GetChartDocument()->getArea();
436 mrImportHelper.FillAutoStyle(sAutoStyleName, xProp);
437}
438
439namespace
440{
441
442struct NewDonutSeries
443{
444 css::uno::Reference< css::chart2::XDataSeries > m_xSeries;
445 OUString msStyleName;
446 sal_Int32 mnAttachedAxis;
447
448 ::std::vector< OUString > m_aSeriesStyles;
449 ::std::vector< OUString > m_aPointStyles;
450
451 NewDonutSeries( const css::uno::Reference< css::chart2::XDataSeries >& xSeries, sal_Int32 nPointCount )
452 : m_xSeries( xSeries )
453 , mnAttachedAxis( 1 )
454 {
455 m_aPointStyles.resize(nPointCount);
456 m_aSeriesStyles.resize(nPointCount);
457 }
458
459 void setSeriesStyleNameToPoint( const OUString& rStyleName, sal_Int32 nPointIndex )
460 {
461 SAL_WARN_IF(nPointIndex >= static_cast<sal_Int32>(m_aSeriesStyles.size()), "xmloff.chart", "donut point <-> series count mismatch");
462 if( nPointIndex < static_cast<sal_Int32>(m_aSeriesStyles.size()) )
463 m_aSeriesStyles[nPointIndex]=rStyleName;
464 }
465
466 void setPointStyleNameToPoint( const OUString& rStyleName, sal_Int32 nPointIndex )
467 {
468 SAL_WARN_IF(nPointIndex >= static_cast<sal_Int32>(m_aPointStyles.size()), "xmloff.chart", "donut point <-> series count mismatch");
469 if( nPointIndex < static_cast<sal_Int32>(m_aPointStyles.size()) )
470 m_aPointStyles[nPointIndex]=rStyleName;
471 }
472
473 ::std::vector< DataRowPointStyle > creatStyleVector()
474 {
475 ::std::vector< DataRowPointStyle > aRet;
476
478 , m_xSeries, -1, 1, msStyleName, mnAttachedAxis );
479 aRet.push_back( aSeriesStyle );
480
481 sal_Int32 nPointIndex=0;
482 for (auto const& pointStyle : m_aPointStyles)
483 {
485 , m_xSeries, nPointIndex, 1, pointStyle, mnAttachedAxis );
486 if( nPointIndex < static_cast<sal_Int32>(m_aSeriesStyles.size()) )
487 {
488 aPointStyle.msSeriesStyleNameForDonuts = m_aSeriesStyles[nPointIndex];
489 }
490 if( !aPointStyle.msSeriesStyleNameForDonuts.isEmpty()
491 || !aPointStyle.msStyleName.isEmpty() )
492 aRet.push_back( aPointStyle );
493 ++nPointIndex;
494 }
495
496 return aRet;
497 }
498};
499
500void lcl_swapPointAndSeriesStylesForDonutCharts( ::std::vector< DataRowPointStyle >& rStyleVector
501 , ::std::map< css::uno::Reference< css::chart2::XDataSeries> , sal_Int32 >&& aSeriesMap )
502{
503 //detect old series count
504 //and add old series to aSeriesMap
505 sal_Int32 nOldSeriesCount = 0;
506 {
507 sal_Int32 nMaxOldSeriesIndex = 0;
508 sal_Int32 nOldSeriesIndex = 0;
509 for (auto const& style : rStyleVector)
510 {
511 DataRowPointStyle aStyle(style);
512 if(aStyle.meType == DataRowPointStyle::DATA_SERIES &&
513 aStyle.m_xSeries.is() )
514 {
515 nMaxOldSeriesIndex = nOldSeriesIndex;
516
517 if( aSeriesMap.end() == aSeriesMap.find(aStyle.m_xSeries) )
518 aSeriesMap[aStyle.m_xSeries] = nOldSeriesIndex;
519
520 nOldSeriesIndex++;
521 }
522 }
523 nOldSeriesCount = nMaxOldSeriesIndex+1;
524 }
525
526 //initialize new series styles
527 ::std::map< Reference< chart2::XDataSeries >, sal_Int32 >::const_iterator aSeriesMapEnd( aSeriesMap.end() );
528
529 //sort by index
530 ::std::vector< NewDonutSeries > aNewSeriesVector;
531 {
532 ::std::map< sal_Int32, Reference< chart2::XDataSeries > > aIndexSeriesMap;
533 for (auto const& series : aSeriesMap)
534 aIndexSeriesMap[series.second] = series.first;
535
536 for (auto const& indexSeries : aIndexSeriesMap)
537 aNewSeriesVector.emplace_back(indexSeries.second,nOldSeriesCount );
538 }
539
540 //overwrite attached axis information according to old series styles
541 for (auto const& style : rStyleVector)
542 {
543 DataRowPointStyle aStyle(style);
544 if(aStyle.meType == DataRowPointStyle::DATA_SERIES )
545 {
546 auto aSeriesMapIt = aSeriesMap.find( aStyle.m_xSeries );
547 if( aSeriesMapIt != aSeriesMapEnd && aSeriesMapIt->second < static_cast<sal_Int32>(aNewSeriesVector.size()) )
548 aNewSeriesVector[aSeriesMapIt->second].mnAttachedAxis = aStyle.mnAttachedAxis;
549 }
550 }
551
552 //overwrite new series style names with old series style name information
553 for (auto const& style : rStyleVector)
554 {
555 DataRowPointStyle aStyle(style);
556 if( aStyle.meType == DataRowPointStyle::DATA_SERIES )
557 {
558 auto aSeriesMapIt = aSeriesMap.find(aStyle.m_xSeries);
559 if( aSeriesMapEnd != aSeriesMapIt )
560 {
561 sal_Int32 nNewPointIndex = aSeriesMapIt->second;
562
563 for (auto & newSeries : aNewSeriesVector)
564 newSeries.setSeriesStyleNameToPoint( aStyle.msStyleName, nNewPointIndex );
565 }
566 }
567 }
568
569 //overwrite new series style names with point style name information
570 for (auto const& style : rStyleVector)
571 {
572 DataRowPointStyle aStyle(style);
573 if( aStyle.meType == DataRowPointStyle::DATA_POINT )
574 {
575 auto aSeriesMapIt = aSeriesMap.find(aStyle.m_xSeries);
576 if( aSeriesMapEnd != aSeriesMapIt )
577 {
578 sal_Int32 nNewPointIndex = aSeriesMapIt->second;
579 sal_Int32 nNewSeriesIndex = aStyle.m_nPointIndex;
580 sal_Int32 nRepeatCount = aStyle.m_nPointRepeat;
581
582 while( nRepeatCount && (nNewSeriesIndex>=0) && (o3tl::make_unsigned(nNewSeriesIndex)< aNewSeriesVector.size() ) )
583 {
584 NewDonutSeries& rNewSeries( aNewSeriesVector[nNewSeriesIndex] );
585 rNewSeries.setPointStyleNameToPoint( aStyle.msStyleName, nNewPointIndex );
586
587 nRepeatCount--;
588 nNewSeriesIndex++;
589 }
590 }
591 }
592 }
593
594 //put information from aNewSeriesVector to output parameter rStyleVector
595 rStyleVector.clear();
596
597 for (auto & newSeries : aNewSeriesVector)
598 {
599 ::std::vector< DataRowPointStyle > aVector( newSeries.creatStyleVector() );
600 rStyleVector.insert(rStyleVector.end(),aVector.begin(),aVector.end());
601 }
602}
603
604bool lcl_SpecialHandlingForDonutChartNeeded(
605 std::u16string_view rServiceName,
606 const SvXMLImport & rImport )
607{
608 bool bResult = false;
609 if( rServiceName == u"com.sun.star.chart2.DonutChartType" )
610 {
612 }
613 return bResult;
614}
615
616} // anonymous namespace
617
619 const uno::Reference< chart2::XChartDocument >& xNewDoc
620 , const OUString& rRectangularRange
621 , css::chart::ChartDataRowSource eDataRowSource
622 , bool bRowHasLabels, bool bColHasLabels
623 , bool bSwitchOnLabelsAndCategoriesForOwnData
624 , const OUString& sColTrans
625 , const OUString& sRowTrans )
626{
627 if( !xNewDoc.is() )
628 return;
629
630 uno::Reference< chart2::XDiagram > xNewDia( xNewDoc->getFirstDiagram());
631 uno::Reference< chart2::data::XDataProvider > xDataProvider( xNewDoc->getDataProvider() );
632 if( !xNewDia.is() || !xDataProvider.is() )
633 return;
634
635 bool bFirstCellAsLabel =
636 (eDataRowSource==chart::ChartDataRowSource_COLUMNS)? bRowHasLabels : bColHasLabels;
637 bool bHasCateories =
638 (eDataRowSource==chart::ChartDataRowSource_COLUMNS)? bColHasLabels : bRowHasLabels;
639
640 if( bSwitchOnLabelsAndCategoriesForOwnData )
641 {
642 bFirstCellAsLabel = true;
643 bHasCateories = true;
644 }
645
646 uno::Sequence< beans::PropertyValue > aArgs{
647 beans::PropertyValue(
648 "CellRangeRepresentation",
649 -1, uno::Any( rRectangularRange ),
650 beans::PropertyState_DIRECT_VALUE ),
651 beans::PropertyValue(
652 "DataRowSource",
653 -1, uno::Any( eDataRowSource ),
654 beans::PropertyState_DIRECT_VALUE ),
655 beans::PropertyValue(
656 "FirstCellAsLabel",
657 -1, uno::Any( bFirstCellAsLabel ),
658 beans::PropertyState_DIRECT_VALUE )
659 };
660
661 if( !sColTrans.isEmpty() || !sRowTrans.isEmpty() )
662 {
663 aArgs.realloc( aArgs.getLength() + 1 );
664 aArgs.getArray()[ sal::static_int_cast<sal_uInt32>(aArgs.getLength()) - 1 ] = beans::PropertyValue(
665 "SequenceMapping",
666 -1, uno::Any( !sColTrans.isEmpty()
667 ? lcl_getNumberSequenceFromString( sColTrans, bHasCateories && !xNewDoc->hasInternalDataProvider() )
668 : lcl_getNumberSequenceFromString( sRowTrans, bHasCateories && !xNewDoc->hasInternalDataProvider() ) ),
669 beans::PropertyState_DIRECT_VALUE );
670 }
671
672 //work around wrong writer ranges ( see Issue 58464 )
673 {
674 OUString aChartOleObjectName;
675 if( xNewDoc.is() )
676 {
677 utl::MediaDescriptor aMediaDescriptor( xNewDoc->getArgs() );
678
679 utl::MediaDescriptor::const_iterator aIt(
680 aMediaDescriptor.find( OUString( "HierarchicalDocumentName" )));
681 if( aIt != aMediaDescriptor.end() )
682 {
683 aChartOleObjectName = (*aIt).second.get< OUString >();
684 }
685 }
686 if( !aChartOleObjectName.isEmpty() )
687 {
688 aArgs.realloc( aArgs.getLength() + 1 );
689 aArgs.getArray()[ sal::static_int_cast<sal_uInt32>(aArgs.getLength()) - 1 ] = beans::PropertyValue(
690 "ChartOleObjectName",
691 -1, uno::Any( aChartOleObjectName ),
692 beans::PropertyState_DIRECT_VALUE );
693 }
694 }
695
696 uno::Reference< chart2::data::XDataSource > xDataSource(
697 xDataProvider->createDataSource( aArgs ));
698
699 aArgs.realloc( aArgs.getLength() + 2 );
700 auto pArgs = aArgs.getArray();
701 pArgs[ sal::static_int_cast<sal_uInt32>(aArgs.getLength()) - 2 ] = beans::PropertyValue(
702 "HasCategories",
703 -1, uno::Any( bHasCateories ),
704 beans::PropertyState_DIRECT_VALUE );
705 pArgs[ sal::static_int_cast<sal_uInt32>(aArgs.getLength()) - 1 ] = beans::PropertyValue(
706 "UseCategoriesAsX",
707 -1, uno::Any( false ),//categories in ODF files are not to be used as x values (independent from what is offered in our ui)
708 beans::PropertyState_DIRECT_VALUE );
709
710 xNewDia->setDiagramData( xDataSource, aArgs );
711}
712
714{
715 uno::Reference< chart::XChartDocument > xDoc = mrImportHelper.GetChartDocument();
716 uno::Reference< beans::XPropertySet > xProp( xDoc, uno::UNO_QUERY );
717 uno::Reference< chart2::XChartDocument > xNewDoc( xDoc, uno::UNO_QUERY );
718
719 if( xProp.is())
720 {
721 if( !maMainTitle.isEmpty())
722 {
723 uno::Reference< beans::XPropertySet > xTitleProp( xDoc->getTitle(), uno::UNO_QUERY );
724 if( xTitleProp.is())
725 {
726 try
727 {
728 xTitleProp->setPropertyValue("String", uno::Any(maMainTitle) );
729 }
730 catch(const beans::UnknownPropertyException&)
731 {
732 SAL_WARN("xmloff.chart", "Property String for Title not available" );
733 }
734 }
735 }
736 if( !maSubTitle.isEmpty())
737 {
738 uno::Reference< beans::XPropertySet > xTitleProp( xDoc->getSubTitle(), uno::UNO_QUERY );
739 if( xTitleProp.is())
740 {
741 try
742 {
743 xTitleProp->setPropertyValue("String", uno::Any(maSubTitle) );
744 }
745 catch(const beans::UnknownPropertyException&)
746 {
747 SAL_WARN("xmloff.chart", "Property String for Title not available" );
748 }
749 }
750 }
751 }
752
753 // cleanup: remove empty chart type groups
754 lcl_removeEmptyChartTypeGroups( xNewDoc );
755
756 // set stack mode before a potential chart type detection (in case we have a rectangular range)
757 uno::Reference< chart::XDiagram > xDiagram( xDoc->getDiagram() );
758 uno::Reference< beans::XPropertySet > xDiaProp( xDiagram, uno::UNO_QUERY );
759 if( xDiaProp.is())
760 {
762 xDiaProp->setPropertyValue("Stacked",maSeriesDefaultsAndStyles.maStackedDefault);
764 xDiaProp->setPropertyValue("Percent",maSeriesDefaultsAndStyles.maPercentDefault);
766 xDiaProp->setPropertyValue("Deep",maSeriesDefaultsAndStyles.maDeepDefault);
768 xDiaProp->setPropertyValue("StackedBarsConnected",maSeriesDefaultsAndStyles.maStackedBarsConnectedDefault);
769 }
770
771 //the OOo 2.0 implementation and older has a bug with donuts
772 bool bSpecialHandlingForDonutChart = lcl_SpecialHandlingForDonutChartNeeded(
774
775 // apply data
776 if(!xNewDoc.is())
777 return;
778
779 bool bHasOwnData = false;
780 if( m_aXLinkHRefAttributeToIndicateDataProvider == "." ) //data comes from the chart itself
781 bHasOwnData = true;
782 else if( m_aXLinkHRefAttributeToIndicateDataProvider == ".." ) //data comes from the parent application
783 bHasOwnData = false;
784 else if( !m_aXLinkHRefAttributeToIndicateDataProvider.isEmpty() ) //not supported so far to get the data by sibling objects -> fall back to chart itself if data are available
785 bHasOwnData = m_bHasTableElement;
786 else
787 bHasOwnData = !m_bHasRangeAtPlotArea;
788
789 if( xNewDoc->hasInternalDataProvider())
790 {
792 {
793 //#i103147# ODF, workaround broken files with a missing table:cell-range-address at the plot-area
795 bHasOwnData = !bSwitchSuccessful;
796 }
797 else
798 bHasOwnData = true;//e.g. in case of copy->paste from calc to impress
799 }
800 else if( bHasOwnData )
801 {
802 xNewDoc->createInternalDataProvider( false /* bCloneExistingData */ );
803 }
804 if( bHasOwnData )
805 msChartAddress = "all";
806
807 bool bSwitchRangesFromOuterToInternalIfNecessary = false;
808 if( !bHasOwnData && mbAllRangeAddressesAvailable )
809 {
810 // special handling for stock chart (merge series together)
811 if( mbIsStockChart )
813 }
814 else if( !msChartAddress.isEmpty() )
815 {
816 //own data or only rectangular range available
817
818 if( xNewDoc->hasInternalDataProvider() )
820
822 bool bOldFileWithOwnDataFromRows = (bOlderThan2_3 && bHasOwnData && (meDataRowSource==chart::ChartDataRowSource_ROWS)); // in this case there are range addresses that are simply wrong.
823
824 if( mbAllRangeAddressesAvailable && !bSpecialHandlingForDonutChart && !mbIsStockChart &&
825 !bOldFileWithOwnDataFromRows )
826 {
827 //bHasOwnData is true in this case!
828 //e.g. for normal files with own data or also in case of copy paste scenario (e.g. calc to impress)
829 bSwitchRangesFromOuterToInternalIfNecessary = true;
830 }
831 else
832 {
833 //apply data from rectangular range
834
835 // create datasource from data provider with rectangular range parameters and change the diagram setDiagramData
836 try
837 {
838 if( bOlderThan2_3 && xDiaProp.is() )//for older charts the hidden cells were removed by calc on the fly
839 xDiaProp->setPropertyValue("IncludeHiddenCells",uno::Any(false));
840
841 // note: mbRowHasLabels means the first row contains labels, that means we have "column-descriptions",
842 // (analogously mbColHasLabels means we have "row-descriptions")
844 }
845 catch(const uno::Exception&)
846 {
847 //try to fallback to internal data
848 TOOLS_WARN_EXCEPTION("xmloff.chart", "Exception during import SchXMLChartContext::lcl_ApplyDataFromRectangularRangeToDiagram try to fallback to internal data" );
849 if(!bHasOwnData)
850 {
851 bHasOwnData = true;
852 msChartAddress = "all";
853 if( !xNewDoc->hasInternalDataProvider() )
854 {
855 xNewDoc->createInternalDataProvider( false /* bCloneExistingData */ );
857 try
858 {
860 }
861 catch(const uno::Exception&)
862 {
863 TOOLS_WARN_EXCEPTION("xmloff.chart", "Exception during import SchXMLChartContext::lcl_ApplyDataFromRectangularRangeToDiagram fallback to internal data failed also" );
864 }
865 }
866 }
867 }
868 }
869 }
870 else
871 {
872 SAL_WARN("xmloff.chart", "Must not get here" );
873 }
874
875 // now all series and data point properties are available and can be set
876 {
877 if( bSpecialHandlingForDonutChart )
878 {
879 uno::Reference< chart2::XDiagram > xNewDiagram( xNewDoc->getFirstDiagram() );
880 lcl_swapPointAndSeriesStylesForDonutCharts( maSeriesDefaultsAndStyles.maSeriesStyleVector
882 }
883
885
886 //set defaults from diagram to the new series:
887 //check whether we need to remove lines from symbol only charts
888 bool bSwitchOffLinesForScatter = false;
889 {
890 bool bLinesOn = true;
891 if( (maSeriesDefaultsAndStyles.maLinesOnProperty >>= bLinesOn) && !bLinesOn )
892 {
893 if( maChartTypeServiceName == "com.sun.star.chart2.ScatterChartType" )
894 {
895 bSwitchOffLinesForScatter = true;
897 }
898 }
899 }
901
902 // set autostyles for series and data points
904 const SvXMLStyleContext* pStyle = nullptr;
905 OUString sCurrStyleName;
906
907 if( pStylesCtxt )
908 {
909 //iterate over data-series first
910 //don't set series styles for donut charts
911 if( !bSpecialHandlingForDonutChart )
912 {
914 maSeriesDefaultsAndStyles, pStylesCtxt, pStyle,
915 sCurrStyleName, mrImportHelper, GetImport(),
917 // ... then set attributes for statistics (after their existence was set in the series)
919 maSeriesDefaultsAndStyles, pStylesCtxt,
920 pStyle, sCurrStyleName );
921
923 maSeriesDefaultsAndStyles, pStylesCtxt,
924 pStyle, sCurrStyleName );
925 }
926 }
927
928 //#i98319# call switchRangesFromOuterToInternalIfNecessary before the data point styles are applied, otherwise in copy->paste scenario the data point styles do get lost
929 if( bSwitchRangesFromOuterToInternalIfNecessary )
930 {
931 if( xNewDoc->hasInternalDataProvider() )
933 }
934
935 if( pStylesCtxt )
936 {
937 // ... then iterate over data-point attributes, so the latter are not overwritten
939 , pStylesCtxt, pStyle, sCurrStyleName, mrImportHelper, GetImport(), mbIsStockChart, bSpecialHandlingForDonutChart, bSwitchOffLinesForScatter );
940 }
941 }
942
943 if( xProp.is())
944 xProp->setPropertyValue("RefreshAddInAllowed", uno::Any( true) );
945}
946
948{
949 OSL_ASSERT( mbIsStockChart );
950 try
951 {
952 uno::Reference< chart::XChartDocument > xOldDoc( mrImportHelper.GetChartDocument());
953 uno::Reference< chart2::XChartDocument > xDoc( xOldDoc, uno::UNO_QUERY_THROW );
954 uno::Reference< chart2::XDiagram > xDiagram( xDoc->getFirstDiagram());
955 if( ! xDiagram.is())
956 return;
957
958 bool bHasJapaneseCandlestick = true;
959 uno::Reference< chart2::XDataSeriesContainer > xDSContainer;
960 uno::Reference< chart2::XCoordinateSystemContainer > xCooSysCnt( xDiagram, uno::UNO_QUERY_THROW );
961 const uno::Sequence< uno::Reference< chart2::XCoordinateSystem > > aCooSysSeq( xCooSysCnt->getCoordinateSystems());
962 for( const auto& rCooSys : aCooSysSeq )
963 {
964 uno::Reference< chart2::XChartTypeContainer > xCTCnt( rCooSys, uno::UNO_QUERY_THROW );
965 const uno::Sequence< uno::Reference< chart2::XChartType > > aChartTypes( xCTCnt->getChartTypes());
966 auto pChartType = std::find_if(aChartTypes.begin(), aChartTypes.end(),
967 [](const auto& rChartType) { return rChartType->getChartType() == "com.sun.star.chart2.CandleStickChartType"; });
968 if (pChartType != aChartTypes.end())
969 {
970 xDSContainer.set( *pChartType, uno::UNO_QUERY_THROW );
971 uno::Reference< beans::XPropertySet > xCTProp( *pChartType, uno::UNO_QUERY_THROW );
972 xCTProp->getPropertyValue("Japanese") >>= bHasJapaneseCandlestick;
973 }
974 }
975
976 if( xDSContainer.is())
977 {
978 // with japanese candlesticks: open, low, high, close
979 // otherwise: low, high, close
980 uno::Sequence< uno::Reference< chart2::XDataSeries > > aSeriesSeq( xDSContainer->getDataSeries());
981 const sal_Int32 nSeriesCount( aSeriesSeq.getLength());
982 const sal_Int32 nSeriesPerCandleStick = bHasJapaneseCandlestick ? 4: 3;
983 sal_Int32 nCandleStickCount = nSeriesCount / nSeriesPerCandleStick;
984 OSL_ASSERT( nSeriesPerCandleStick * nCandleStickCount == nSeriesCount );
985 uno::Sequence< uno::Reference< chart2::XDataSeries > > aNewSeries( nCandleStickCount );
986 auto aNewSeriesRange = asNonConstRange(aNewSeries);
987 for( sal_Int32 i=0; i<nCandleStickCount; ++i )
988 {
989 sal_Int32 nSeriesIndex = i*nSeriesPerCandleStick;
990 if( bHasJapaneseCandlestick )
991 {
992 // open values
993 lcl_setRoleAtFirstSequence( aSeriesSeq[ nSeriesIndex ], "values-first");
994 aNewSeriesRange[i] = aSeriesSeq[ nSeriesIndex ];
995 // low values
996 lcl_MoveDataToCandleStickSeries(
997 uno::Reference< chart2::data::XDataSource >( aSeriesSeq[ ++nSeriesIndex ], uno::UNO_QUERY_THROW ),
998 aNewSeries[i], "values-min");
999 }
1000 else
1001 {
1002 // low values
1003 lcl_setRoleAtFirstSequence( aSeriesSeq[ nSeriesIndex ], "values-min");
1004 aNewSeriesRange[i] = aSeriesSeq[ nSeriesIndex ];
1005 }
1006 // high values
1007 lcl_MoveDataToCandleStickSeries(
1008 uno::Reference< chart2::data::XDataSource >( aSeriesSeq[ ++nSeriesIndex ], uno::UNO_QUERY_THROW ),
1009 aNewSeries[i], "values-max");
1010 // close values
1011 lcl_MoveDataToCandleStickSeries(
1012 uno::Reference< chart2::data::XDataSource >( aSeriesSeq[ ++nSeriesIndex ], uno::UNO_QUERY_THROW ),
1013 aNewSeries[i], "values-last");
1014 }
1015 xDSContainer->setDataSeries( aNewSeries );
1016 }
1017 }
1018 catch(const uno::Exception&)
1019 {
1020 TOOLS_WARN_EXCEPTION("xmloff.chart", "Exception while merging series for stock chart" );
1021 }
1022}
1023
1024css::uno::Reference< css::xml::sax::XFastContextHandler > SchXMLChartContext::createFastChildContext(
1025 sal_Int32 nElement,
1026 const css::uno::Reference< css::xml::sax::XFastAttributeList >& xAttrList )
1027{
1028 SvXMLImportContext* pContext = nullptr;
1029 uno::Reference< chart::XChartDocument > xDoc = mrImportHelper.GetChartDocument();
1030 uno::Reference< beans::XPropertySet > xProp( xDoc, uno::UNO_QUERY );
1031
1032 switch(nElement)
1033 {
1044 break;
1046 if( xDoc.is())
1047 {
1048 if( xProp.is())
1049 {
1050 xProp->setPropertyValue("HasMainTitle", uno::Any(true) );
1051 }
1052 uno::Reference< drawing::XShape > xTitleShape = xDoc->getTitle();
1053 pContext = new SchXMLTitleContext( mrImportHelper, GetImport(),
1054 maMainTitle, xTitleShape );
1055 }
1056 break;
1058 if( xDoc.is())
1059 {
1060 if( xProp.is())
1061 {
1062 xProp->setPropertyValue("HasSubTitle", uno::Any(true) );
1063 }
1064 uno::Reference< drawing::XShape > xTitleShape = xDoc->getSubTitle();
1065 pContext = new SchXMLTitleContext( mrImportHelper, GetImport(),
1066 maSubTitle, xTitleShape );
1067 }
1068 break;
1070 pContext = new SchXMLLegendContext( mrImportHelper, GetImport() );
1071 break;
1073 {
1074 SchXMLTableContext * pTableContext =
1076 m_bHasTableElement = true;
1077 // #i85913# take into account column- and row- mapping for
1078 // charts with own data only for those which were not copied
1079 // from a place where they got data from the container. Note,
1080 // that this requires the plot-area been read before the table
1081 // (which is required in the ODF spec)
1082 // Note: For stock charts and donut charts with special handling
1083 // the mapping must not be applied!
1084 if( msChartAddress.isEmpty() && !mbIsStockChart &&
1085 !lcl_SpecialHandlingForDonutChartNeeded(
1087 {
1088 if( !msColTrans.isEmpty() )
1089 {
1090 OSL_ASSERT( msRowTrans.isEmpty() );
1091 pTableContext->setColumnPermutation( lcl_getNumberSequenceFromString( msColTrans, true ));
1092 msColTrans.clear();
1093 }
1094 else if( !msRowTrans.isEmpty() )
1095 {
1096 pTableContext->setRowPermutation( lcl_getNumberSequenceFromString( msRowTrans, true ));
1097 msRowTrans.clear();
1098 }
1099 }
1100 pContext = pTableContext;
1101 }
1102 break;
1103
1104 default:
1105 // try importing as an additional shape
1106 if( ! mxDrawPage.is())
1107 {
1108 uno::Reference< drawing::XDrawPageSupplier > xSupp( xDoc, uno::UNO_QUERY );
1109 if( xSupp.is())
1110 mxDrawPage = xSupp->getDrawPage();
1111
1112 SAL_WARN_IF( !mxDrawPage.is(), "xmloff.chart", "Invalid Chart Page" );
1113 }
1114 if( mxDrawPage.is())
1116 GetImport(), nElement, xAttrList, mxDrawPage );
1117 break;
1118 }
1119
1120 return pContext;
1121}
1122
1123/*
1124 With a locked controller the following is done here:
1125 1. Hide title, subtitle, and legend.
1126 2. Set the size of the draw page.
1127 3. Set a (logically) empty data set.
1128 4. Set the chart type.
1129*/
1131 const OUString & rChartTypeServiceName // currently the old service name
1132 )
1133{
1134 uno::Reference< chart::XChartDocument > xDoc = mrImportHelper.GetChartDocument();
1135 SAL_WARN_IF( !xDoc.is(), "xmloff.chart", "No valid document!" );
1136
1137 // Remove Title and Diagram ("De-InitNew")
1138 uno::Reference< chart2::XChartDocument > xNewDoc( mrImportHelper.GetChartDocument(), uno::UNO_QUERY );
1139 if( xNewDoc.is())
1140 {
1141 xNewDoc->setFirstDiagram( nullptr );
1142 uno::Reference< chart2::XTitled > xTitled( xNewDoc, uno::UNO_QUERY );
1143 if( xTitled.is())
1144 xTitled->setTitleObject( nullptr );
1145 }
1146
1147 // Set the chart type via setting the diagram.
1148 if( !rChartTypeServiceName.isEmpty() && xDoc.is())
1149 {
1150 uno::Reference< lang::XMultiServiceFactory > xFact( xDoc, uno::UNO_QUERY );
1151 if( xFact.is())
1152 {
1153 uno::Reference< chart::XDiagram > xDia( xFact->createInstance( rChartTypeServiceName ), uno::UNO_QUERY );
1154 if( xDia.is())
1155 xDoc->setDiagram( xDia );
1156 }
1157 }
1158}
1159
1161 OUString& rTitle,
1162 uno::Reference< drawing::XShape > const & xTitleShape ) :
1163 SvXMLImportContext( rImport ),
1164 mrImportHelper( rImpHelper ),
1165 mrTitle( rTitle ),
1166 mxTitleShape( xTitleShape )
1167{
1168}
1169
1171{}
1172
1173void SchXMLTitleContext::startFastElement( sal_Int32 /*nElement*/,
1174 const css::uno::Reference< css::xml::sax::XFastAttributeList >& xAttrList )
1175{
1176 css::awt::Point aPosition;
1177 bool bHasXPosition=false;
1178 bool bHasYPosition=false;
1179
1180 for( auto& aIter : sax_fastparser::castToFastAttributeList(xAttrList) )
1181 {
1182 switch (aIter.getToken())
1183 {
1184 case XML_ELEMENT(SVG, XML_X):
1185 case XML_ELEMENT(SVG_COMPAT, XML_X):
1186 {
1188 aPosition.X, aIter.toView() );
1189 bHasXPosition = true;
1190 break;
1191 }
1192 case XML_ELEMENT(SVG, XML_Y):
1193 case XML_ELEMENT(SVG_COMPAT, XML_Y):
1194 {
1196 aPosition.Y, aIter.toView() );
1197 bHasYPosition = true;
1198 break;
1199 }
1201 msAutoStyleName = aIter.toString();
1202 break;
1203 default:
1204 XMLOFF_WARN_UNKNOWN("xmloff", aIter);
1205 }
1206 }
1207
1208 if( mxTitleShape.is())
1209 {
1210 if( bHasXPosition && bHasYPosition )
1211 mxTitleShape->setPosition( aPosition );
1212
1213 uno::Reference<beans::XPropertySet> xProp(mxTitleShape, uno::UNO_QUERY);
1215 }
1216}
1217
1218css::uno::Reference< css::xml::sax::XFastContextHandler > SchXMLTitleContext::createFastChildContext(
1219 sal_Int32 nElement,
1220 const css::uno::Reference< css::xml::sax::XFastAttributeList >& /*xAttrList*/ )
1221{
1222 SvXMLImportContext* pContext = nullptr;
1223
1224 if( nElement == XML_ELEMENT(TEXT, XML_P) ||
1225 nElement == XML_ELEMENT(LO_EXT, XML_P) )
1226 {
1227 pContext = new SchXMLParagraphContext( GetImport(), mrTitle );
1228 }
1229 else
1230 XMLOFF_WARN_UNKNOWN_ELEMENT("xmloff", nElement);
1231
1232 return pContext;
1233}
1234
1235/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
rtl::Reference< ::chart::DataSeries > m_xSeries
OUString msStyleName
void setDataProvider(uno::Reference< chart2::XChartDocument > const &xChartDoc, OUString const &sDataPilotSource)
static void lcl_ApplyDataFromRectangularRangeToDiagram(const uno::Reference< chart2::XChartDocument > &xNewDoc, const OUString &rRectangularRange, css::chart::ChartDataRowSource eDataRowSource, bool bRowHasLabels, bool bColHasLabels, bool bSwitchOnLabelsAndCategoriesForOwnData, const OUString &sColTrans, const OUString &sRowTrans)
static bool lcl_hasServiceName(Reference< lang::XMultiServiceFactory > const &xFactory, OUString const &rServiceName)
virtual css::uno::Reference< css::xml::sax::XFastContextHandler > SAL_CALL createFastChildContext(sal_Int32 nElement, const css::uno::Reference< css::xml::sax::XFastAttributeList > &AttrList) override
css::uno::Reference< css::drawing::XShapes > mxDrawPage
css::awt::Size maChartSize
css::chart::ChartDataRowSource meDataRowSource
void InitChart(const OUString &rChartTypeServiceName)
@descr This method bundles some settings to the chart model and executes them with a locked controlle...
virtual void SAL_CALL startFastElement(sal_Int32 nElement, const css::uno::Reference< css::xml::sax::XFastAttributeList > &xAttrList) override
SchXMLChartContext(SchXMLImportHelper &rImpHelper, SvXMLImport &rImport)
OUString m_aXLinkHRefAttributeToIndicateDataProvider
tSchXMLLSequencesPerIndex maLSequencesPerIndex
SchXMLImportHelper & mrImportHelper
virtual ~SchXMLChartContext() override
SeriesDefaultsAndStyles maSeriesDefaultsAndStyles
virtual void SAL_CALL endFastElement(sal_Int32 nElement) override
endFastElement is called before a context will be destructed, but after an elements context has been ...
With this class you can import a <chart:chart> element containing its data as <table:table> element o...
const css::uno::Reference< css::chart::XChartDocument > & GetChartDocument() const
SvXMLStylesContext * GetAutoStylesContext() const
void FillAutoStyle(const OUString &rAutoStyleName, const css::uno::Reference< css::beans::XPropertySet > &rProp)
Fill in the autostyle.
static void initSeriesPropertySets(SeriesDefaultsAndStyles &rSeriesDefaultsAndStyles, const css::uno::Reference< css::frame::XModel > &xChartModel)
static void setDefaultsToSeries(SeriesDefaultsAndStyles &rSeriesDefaultsAndStyles)
static void switchSeriesLinesOff(::std::vector< DataRowPointStyle > &rSeriesStyleVector)
static void setStylesToSeries(SeriesDefaultsAndStyles &rSeriesDefaultsAndStyles, const SvXMLStylesContext *pStylesCtxt, const SvXMLStyleContext *&rpStyle, OUString &rCurrStyleName, const SchXMLImportHelper &rImportHelper, const SvXMLImport &rImport, bool bIsStockChart, tSchXMLLSequencesPerIndex &rInOutLSequencesPerIndex)
static void setStylesToRegressionCurves(SeriesDefaultsAndStyles &rSeriesDefaultsAndStyles, const SvXMLStylesContext *pStylesCtxt, const SvXMLStyleContext *&rpStyle, OUString const &rCurrStyleName)
static void setStylesToStatisticsObjects(SeriesDefaultsAndStyles &rSeriesDefaultsAndStyles, const SvXMLStylesContext *pStylesCtxt, const SvXMLStyleContext *&rpStyle, OUString &rCurrStyleName)
static void setStylesToDataPoints(SeriesDefaultsAndStyles &rSeriesDefaultsAndStyles, const SvXMLStylesContext *pStylesCtxt, const SvXMLStyleContext *&rpStyle, OUString &rCurrStyleName, const SchXMLImportHelper &rImportHelper, const SvXMLImport &rImport, bool bIsStockChart, bool bIsDonutChart, bool bSwitchOffLinesForScatter)
static ::std::map< css::uno::Reference< css::chart2::XDataSeries >, sal_Int32 > getDataSeriesIndexMapFromDiagram(const css::uno::Reference< css::chart2::XDiagram > &xDiagram)
void setRowPermutation(const css::uno::Sequence< sal_Int32 > &rPermutation)
void setColumnPermutation(const css::uno::Sequence< sal_Int32 > &rPermutation)
static void applyTableToInternalDataProvider(const SchXMLTable &rTable, const css::uno::Reference< css::chart2::XChartDocument > &xChartDoc)
static void switchRangesFromOuterToInternalIfNecessary(const SchXMLTable &rTable, const tSchXMLLSequencesPerIndex &rLSequencesPerIndex, const css::uno::Reference< css::chart2::XChartDocument > &xChartDoc, css::chart::ChartDataRowSource eDataRowSource)
This function reorders local data to fit the correct data structure.
virtual void SAL_CALL startFastElement(sal_Int32 nElement, const css::uno::Reference< css::xml::sax::XFastAttributeList > &xAttrList) override
css::uno::Reference< css::drawing::XShape > mxTitleShape
SchXMLImportHelper & mrImportHelper
virtual css::uno::Reference< css::xml::sax::XFastContextHandler > SAL_CALL createFastChildContext(sal_Int32 nElement, const css::uno::Reference< css::xml::sax::XFastAttributeList > &AttrList) override
virtual ~SchXMLTitleContext() override
SchXMLTitleContext(SchXMLImportHelper &rImpHelper, SvXMLImport &rImport, OUString &rTitle, css::uno::Reference< css::drawing::XShape > const &xTitleShape)
This class deliberately does not support XWeak, to improve performance when loading large documents.
Definition: xmlictxt.hxx:48
SvXMLImport & GetImport()
Definition: xmlictxt.hxx:60
const SvXMLUnitConverter & GetMM100UnitConverter() const
Definition: xmlimp.hxx:400
SvXMLNamespaceMap & GetNamespaceMap()
Definition: xmlimp.hxx:398
const css::uno::Reference< css::frame::XModel > & GetModel() const
Definition: xmlimp.hxx:404
sal_uInt16 GetKeyByAttrValueQName(const OUString &rAttrName, OUString *pLocalName) const
bool convertMeasureToCore(sal_Int32 &rValue, std::u16string_view rString, sal_Int32 nMin=SAL_MIN_INT32, sal_Int32 nMax=SAL_MAX_INT32) const
convert string to measure with meCoreMeasureUnit, using optional min and max values
Definition: xmluconv.cxx:186
static SvXMLShapeContext * CreateGroupChildContext(SvXMLImport &rImport, sal_Int32 nElement, const css::uno::Reference< css::xml::sax::XFastAttributeList > &xAttrList, css::uno::Reference< css::drawing::XShapes > const &rShapes, bool bTemporaryShape=false)
#define TOOLS_WARN_EXCEPTION(area, stream)
#define TOOLS_INFO_EXCEPTION(area, stream)
Reference< XSingleServiceFactory > xFactory
Sequence< OUString > aServiceNames
tools::SvRef< SvBaseLink > xSink
sal_uInt16 nPos
Sequence< sal_Int8 > aSeq
#define SAL_WARN_IF(condition, area, stream)
#define SAL_WARN(area, stream)
constexpr OUStringLiteral aData
SchXMLChartTypeEnum GetChartTypeEnum(std::u16string_view rClassName)
bool isDocumentGeneratedWithOpenOfficeOlderThan2_3(const uno::Reference< frame::XModel > &xChartModel)
@ XML_CHART_CLASS_STOCK
Definition: SchXMLTools.hxx:63
@ XML_CHART_CLASS_UNKNOWN
Definition: SchXMLTools.hxx:66
OUString GetChartTypeByClassName(std::u16string_view rClassName, bool bUseOldNames)
bool switchBackToDataProviderFromParent(const Reference< chart2::XChartDocument > &xChartDoc, const tSchXMLLSequencesPerIndex &rLSequencesPerIndex)
OUString GetNewChartTypeName(const OUString &rOldChartTypeName)
int i
constexpr std::enable_if_t< std::is_signed_v< T >, std::make_unsigned_t< T > > make_unsigned(T value)
sal_Int32 toInt32(std::u16string_view str, sal_Int16 radix=10)
FastAttributeList & castToFastAttributeList(const css::uno::Reference< css::xml::sax::XFastAttributeList > &xAttrList)
Handling of tokens in XML:
@ XML_DATA_PILOT_SOURCE
Definition: xmltoken.hxx:593
const OUString & GetXMLToken(enum XMLTokenEnum eToken)
return the OUString representation for eToken
Definition: xmltoken.cxx:3517
::std::vector< DataRowPointStyle > maSeriesStyleVector
css::uno::Any maStackedBarsConnectedDefault
TEXT
sal_uInt16 sal_Unicode
TABLE
#define XMLOFF_WARN_UNKNOWN_ELEMENT(area, token)
Definition: xmlictxt.hxx:120
#define XMLOFF_WARN_UNKNOWN(area, rIter)
Definition: xmlictxt.hxx:114
#define XML_ELEMENT(prefix, name)
Definition: xmlimp.hxx:97
constexpr sal_uInt16 XML_NAMESPACE_CHART
constexpr sal_uInt16 XML_NAMESPACE_OOO