1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
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 "SchXMLChartContext.hxx"
21 #include "SchXMLImport.hxx"
22 #include "SchXMLLegendContext.hxx"
23 #include "SchXMLPlotAreaContext.hxx"
24 #include "SchXMLParagraphContext.hxx"
25 #include "SchXMLTableContext.hxx"
26 #include "SchXMLSeries2Context.hxx"
27 #include "SchXMLTools.hxx"
28 #include <osl/diagnose.h>
29 #include <unotools/mediadescriptor.hxx>
30 #include <xmloff/xmlnmspe.hxx>
31 #include <xmloff/xmlement.hxx>
32 #include <xmloff/xmltoken.hxx>
33 #include <xmloff/nmspmap.hxx>
34 #include <xmloff/xmluconv.hxx>
35 #include <xmloff/xmlstyle.hxx>
36 #include <xmloff/prstylei.hxx>
37 #include <xmloff/SchXMLSeriesHelper.hxx>
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/util/XStringMapping.hpp>
45 #include <com/sun/star/drawing/XDrawPageSupplier.hpp>
46 #include <com/sun/star/drawing/XDrawPage.hpp>
47 #include <com/sun/star/chart/ChartDataRowSource.hpp>
48 #include <com/sun/star/chart/ChartSeriesAddress.hpp>
49 #include <com/sun/star/awt/PosSize.hpp>
50 #include <com/sun/star/embed/Aspects.hpp>
51 #include <com/sun/star/embed/XVisualObject.hpp>
53 #include <com/sun/star/chart2/XChartDocument.hpp>
54 #include <com/sun/star/chart2/data/XDataSink.hpp>
55 #include <com/sun/star/chart2/XDataSeriesContainer.hpp>
56 #include <com/sun/star/chart2/XCoordinateSystemContainer.hpp>
57 #include <com/sun/star/chart2/XChartTypeContainer.hpp>
58 #include <com/sun/star/chart2/XTitled.hpp>
60 using namespace com::sun::star
;
61 using namespace ::xmloff::token
;
62 using com::sun::star::uno::Reference
;
63 using namespace ::SchXMLTools
;
68 void lcl_setRoleAtLabeledSequence(
69 const uno::Reference
< chart2::data::XLabeledDataSequence
> & xLSeq
,
70 const OUString
&rRole
)
72 // set role of sequence
73 uno::Reference
< chart2::data::XDataSequence
> xValues( xLSeq
->getValues());
76 uno::Reference
< beans::XPropertySet
> xProp( xValues
, uno::UNO_QUERY
);
78 xProp
->setPropertyValue("Role", uno::makeAny( rRole
));
82 void lcl_MoveDataToCandleStickSeries(
83 const uno::Reference
< chart2::data::XDataSource
> & xDataSource
,
84 const uno::Reference
< chart2::XDataSeries
> & xDestination
,
85 const OUString
& rRole
)
89 uno::Sequence
< uno::Reference
< chart2::data::XLabeledDataSequence
> > aLabeledSeq(
90 xDataSource
->getDataSequences());
91 if( aLabeledSeq
.getLength())
93 lcl_setRoleAtLabeledSequence( aLabeledSeq
[0], rRole
);
96 uno::Reference
< chart2::data::XDataSource
> xSource( xDestination
, uno::UNO_QUERY_THROW
);
97 // @todo: realloc only once outside this function
98 uno::Sequence
< uno::Reference
< chart2::data::XLabeledDataSequence
> > aData( xSource
->getDataSequences());
99 aData
.realloc( aData
.getLength() + 1);
100 aData
[ aData
.getLength() - 1 ] = aLabeledSeq
[0];
101 uno::Reference
< chart2::data::XDataSink
> xSink( xDestination
, uno::UNO_QUERY_THROW
);
102 xSink
->setData( aData
);
105 catch(const uno::Exception
&)
107 SAL_WARN("xmloff.chart", "Exception caught while moving data to candlestick series" );
111 void lcl_setRoleAtFirstSequence(
112 const uno::Reference
< chart2::XDataSeries
> & xSeries
,
113 const OUString
& rRole
)
115 uno::Reference
< chart2::data::XDataSource
> xSource( xSeries
, uno::UNO_QUERY
);
118 uno::Sequence
< uno::Reference
< chart2::data::XLabeledDataSequence
> > aSeq( xSource
->getDataSequences());
119 if( aSeq
.getLength())
120 lcl_setRoleAtLabeledSequence( aSeq
[0], rRole
);
124 void lcl_removeEmptyChartTypeGroups( const uno::Reference
< chart2::XChartDocument
> & xDoc
)
129 uno::Reference
< chart2::XDiagram
> xDia( xDoc
->getFirstDiagram());
135 // count all charttype groups to be able to leave at least one
136 sal_Int32 nRemainingGroups
= 0;
137 uno::Reference
< chart2::XCoordinateSystemContainer
> xCooSysCnt( xDia
, uno::UNO_QUERY_THROW
);
138 uno::Sequence
< uno::Reference
< chart2::XCoordinateSystem
> >
139 aCooSysSeq( xCooSysCnt
->getCoordinateSystems());
140 for( sal_Int32 nI
= aCooSysSeq
.getLength(); nI
--; )
142 uno::Reference
< chart2::XChartTypeContainer
> xCTCnt( aCooSysSeq
[nI
], uno::UNO_QUERY_THROW
);
143 nRemainingGroups
+= xCTCnt
->getChartTypes().getLength();
146 // delete all empty groups, but leave at least group (empty or not)
147 for( sal_Int32 nI
= aCooSysSeq
.getLength(); nI
-- && (nRemainingGroups
> 1); )
149 uno::Reference
< chart2::XChartTypeContainer
> xCTCnt( aCooSysSeq
[nI
], uno::UNO_QUERY_THROW
);
150 uno::Sequence
< uno::Reference
< chart2::XChartType
> > aCTSeq( xCTCnt
->getChartTypes());
151 for( sal_Int32 nJ
=aCTSeq
.getLength(); nJ
-- && (nRemainingGroups
> 1); )
153 uno::Reference
< chart2::XDataSeriesContainer
> xDSCnt( aCTSeq
[nJ
], uno::UNO_QUERY_THROW
);
154 if( xDSCnt
->getDataSeries().getLength() == 0 )
156 // note: iterator stays valid as we have a local sequence
157 xCTCnt
->removeChartType( aCTSeq
[nJ
] );
163 catch(const uno::Exception
& ex
)
165 OString
aBStr(OUStringToOString(ex
.Message
, RTL_TEXTENCODING_ASCII_US
));
166 SAL_INFO("xmloff.chart", "Exception caught while removing empty chart types: " << aBStr
);
170 uno::Sequence
< sal_Int32
> lcl_getNumberSequenceFromString( const OUString
& rStr
, bool bAddOneToEachOldIndex
)
172 const sal_Unicode
aSpace( ' ' );
174 // count number of entries
175 ::std::vector
< sal_Int32
> aVec
;
176 sal_Int32 nLastPos
= 0;
180 nPos
= rStr
.indexOf( aSpace
, nLastPos
);
181 if( nPos
> nLastPos
)
183 aVec
.push_back( rStr
.copy( nLastPos
, (nPos
- nLastPos
) ).toInt32() );
190 rStr
.getLength() > nLastPos
)
192 aVec
.push_back( rStr
.copy( nLastPos
, (rStr
.getLength() - nLastPos
) ).toInt32() );
195 const sal_Int32 nVecSize
= aVec
.size();
196 uno::Sequence
< sal_Int32
> aSeq( nVecSize
);
198 if(!bAddOneToEachOldIndex
)
200 sal_Int32
* pSeqArr
= aSeq
.getArray();
201 for( nPos
= 0; nPos
< nVecSize
; ++nPos
)
203 pSeqArr
[ nPos
] = aVec
[ nPos
];
206 else if( bAddOneToEachOldIndex
)
208 aSeq
.realloc( nVecSize
+1 );
211 sal_Int32
* pSeqArr
= aSeq
.getArray();
212 for( nPos
= 0; nPos
< nVecSize
; ++nPos
)
214 pSeqArr
[ nPos
+1 ] = aVec
[ nPos
]+1;
221 } // anonymous namespace
223 SchXMLChartContext::SchXMLChartContext( SchXMLImportHelper
& rImpHelper
,
224 SvXMLImport
& rImport
, const OUString
& rLocalName
) :
225 SvXMLImportContext( rImport
, XML_NAMESPACE_CHART
, rLocalName
),
226 mrImportHelper( rImpHelper
),
227 m_bHasRangeAtPlotArea( false ),
228 m_bHasTableElement( false ),
229 mbAllRangeAddressesAvailable( true ),
230 mbColHasLabels( false ),
231 mbRowHasLabels( false ),
232 meDataRowSource( chart::ChartDataRowSource_COLUMNS
),
233 mbIsStockChart( false )
237 SchXMLChartContext::~SchXMLChartContext()
240 void SchXMLChartContext::StartElement( const uno::Reference
< xml::sax::XAttributeList
>& xAttrList
)
243 sal_Int16 nAttrCount
= xAttrList
.is()? xAttrList
->getLength(): 0;
244 const SvXMLTokenMap
& rAttrTokenMap
= mrImportHelper
.GetChartAttrTokenMap();
246 uno::Reference
< embed::XVisualObject
> xVisualObject( mrImportHelper
.GetChartDocument(), uno::UNO_QUERY
);
247 SAL_WARN_IF(!xVisualObject
.is(), "xmloff.chart", "need xVisualObject for page size");
248 if( xVisualObject
.is() )
249 maChartSize
= xVisualObject
->getVisualAreaSize( embed::Aspects::MSOLE_CONTENT
); //#i103460# take the size given from the parent frame as default
251 // this flag is necessary for pie charts in the core
252 bool bSetSwitchData
= false;
254 OUString sAutoStyleName
;
255 OUString aOldChartTypeName
;
256 bool bHasAddin
= false;
258 for( sal_Int16 i
= 0; i
< nAttrCount
; i
++ )
260 OUString sAttrName
= xAttrList
->getNameByIndex( i
);
262 OUString aValue
= xAttrList
->getValueByIndex( i
);
263 sal_uInt16 nPrefix
= GetImport().GetNamespaceMap().GetKeyByAttrName( sAttrName
, &aLocalName
);
265 switch( rAttrTokenMap
.Get( nPrefix
, aLocalName
))
267 case XML_TOK_CHART_HREF
:
268 m_aXLinkHRefAttributeToIndicateDataProvider
= aValue
;
271 case XML_TOK_CHART_CLASS
:
274 sal_uInt16 nClassPrefix
=
275 GetImport().GetNamespaceMap().GetKeyByAttrName(
276 aValue
, &sClassName
);
277 if( XML_NAMESPACE_CHART
== nClassPrefix
)
279 SchXMLChartTypeEnum eChartTypeEnum
= SchXMLTools::GetChartTypeEnum( sClassName
);
280 if( eChartTypeEnum
!= XML_CHART_CLASS_UNKNOWN
)
282 aOldChartTypeName
= SchXMLTools::GetChartTypeByClassName( sClassName
, true /* bUseOldNames */ );
283 maChartTypeServiceName
= SchXMLTools::GetChartTypeByClassName( sClassName
, false /* bUseOldNames */ );
284 switch( eChartTypeEnum
)
286 case XML_CHART_CLASS_CIRCLE
:
287 bSetSwitchData
= true;
289 case XML_CHART_CLASS_STOCK
:
290 mbIsStockChart
= true;
297 else if( XML_NAMESPACE_OOO
== nClassPrefix
)
299 // service is taken from add-in-name attribute
302 aOldChartTypeName
= sClassName
;
303 maChartTypeServiceName
= sClassName
;
308 case XML_TOK_CHART_WIDTH
:
309 GetImport().GetMM100UnitConverter().convertMeasureToCore(
310 maChartSize
.Width
, aValue
);
313 case XML_TOK_CHART_HEIGHT
:
314 GetImport().GetMM100UnitConverter().convertMeasureToCore(
315 maChartSize
.Height
, aValue
);
318 case XML_TOK_CHART_STYLE_NAME
:
319 sAutoStyleName
= aValue
;
322 case XML_TOK_CHART_COL_MAPPING
:
325 case XML_TOK_CHART_ROW_MAPPING
:
331 if( aOldChartTypeName
.isEmpty() )
333 SAL_WARN("xmloff.chart", "need a charttype to create a diagram" );
334 //set a fallback value:
335 const OUString
& aChartClass_Bar( GetXMLToken(XML_BAR
) );
336 aOldChartTypeName
= SchXMLTools::GetChartTypeByClassName( aChartClass_Bar
, true /* bUseOldNames */ );
337 maChartTypeServiceName
= SchXMLTools::GetChartTypeByClassName( aChartClass_Bar
, false /* bUseOldNames */ );
340 // Set the size of the draw page.
341 if( xVisualObject
.is() )
342 xVisualObject
->setVisualAreaSize( embed::Aspects::MSOLE_CONTENT
, maChartSize
);
344 InitChart( aOldChartTypeName
, bSetSwitchData
);
348 //correct charttype service name when having an addin
349 //and don't refresh addin during load
350 uno::Reference
< beans::XPropertySet
> xDocProp( mrImportHelper
.GetChartDocument(), uno::UNO_QUERY
);
355 xDocProp
->getPropertyValue("BaseDiagram") >>= aOldChartTypeName
;
356 maChartTypeServiceName
= SchXMLTools::GetNewChartTypeName( aOldChartTypeName
);
357 xDocProp
->setPropertyValue("RefreshAddInAllowed", uno::makeAny( false) );
359 catch(const uno::Exception
&)
361 SAL_WARN("xmloff.chart", "Exception during import SchXMLChartContext::StartElement" );
366 // set auto-styles for Area
367 uno::Reference
< beans::XPropertySet
> xProp( mrImportHelper
.GetChartDocument()->getArea(), uno::UNO_QUERY
);
370 const SvXMLStylesContext
* pStylesCtxt
= mrImportHelper
.GetAutoStylesContext();
373 const SvXMLStyleContext
* pStyle
= pStylesCtxt
->FindStyleChildContext(
374 SchXMLImportHelper::GetChartFamilyID(), sAutoStyleName
);
376 if( pStyle
&& dynamic_cast< const XMLPropStyleContext
*>(pStyle
) != nullptr)
377 const_cast<XMLPropStyleContext
*>( static_cast< const XMLPropStyleContext
* >( pStyle
) )->FillPropertySet( xProp
);
385 struct NewDonutSeries
387 css::uno::Reference
< css::chart2::XDataSeries
> m_xSeries
;
388 OUString msStyleName
;
389 sal_Int32 mnAttachedAxis
;
391 ::std::vector
< OUString
> m_aSeriesStyles
;
392 ::std::vector
< OUString
> m_aPointStyles
;
394 NewDonutSeries( const css::uno::Reference
< css::chart2::XDataSeries
>& xSeries
, sal_Int32 nPointCount
)
395 : m_xSeries( xSeries
)
396 , mnAttachedAxis( 1 )
398 m_aPointStyles
.resize(nPointCount
);
399 m_aSeriesStyles
.resize(nPointCount
);
402 void setSeriesStyleNameToPoint( const OUString
& rStyleName
, sal_Int32 nPointIndex
)
404 SAL_WARN_IF(nPointIndex
>= static_cast<sal_Int32
>(m_aSeriesStyles
.size()), "xmloff.chart", "donut point <-> series count mismatch");
405 if( nPointIndex
< static_cast<sal_Int32
>(m_aSeriesStyles
.size()) )
406 m_aSeriesStyles
[nPointIndex
]=rStyleName
;
409 void setPointStyleNameToPoint( const OUString
& rStyleName
, sal_Int32 nPointIndex
)
411 SAL_WARN_IF(nPointIndex
>= static_cast<sal_Int32
>(m_aPointStyles
.size()), "xmloff.chart", "donut point <-> series count mismatch");
412 if( nPointIndex
< static_cast<sal_Int32
>(m_aPointStyles
.size()) )
413 m_aPointStyles
[nPointIndex
]=rStyleName
;
416 ::std::list
< DataRowPointStyle
> creatStyleList()
418 ::std::list
< DataRowPointStyle
> aRet
;
420 DataRowPointStyle
aSeriesStyle( DataRowPointStyle::DATA_SERIES
421 , m_xSeries
, -1, 1, msStyleName
, mnAttachedAxis
);
422 aRet
.push_back( aSeriesStyle
);
424 sal_Int32 nPointIndex
=0;
425 ::std::vector
< OUString
>::iterator
aPointIt( m_aPointStyles
.begin() );
426 ::std::vector
< OUString
>::iterator
aPointEnd( m_aPointStyles
.end() );
427 while( aPointIt
!= aPointEnd
)
429 DataRowPointStyle
aPointStyle( DataRowPointStyle::DATA_POINT
430 , m_xSeries
, nPointIndex
, 1, *aPointIt
, mnAttachedAxis
);
431 if( nPointIndex
< static_cast<sal_Int32
>(m_aSeriesStyles
.size()) )
433 aPointStyle
.msSeriesStyleNameForDonuts
= m_aSeriesStyles
[nPointIndex
];
435 if( !aPointStyle
.msSeriesStyleNameForDonuts
.isEmpty()
436 || !aPointStyle
.msStyleName
.isEmpty() )
437 aRet
.push_back( aPointStyle
);
446 void lcl_swapPointAndSeriesStylesForDonutCharts( ::std::list
< DataRowPointStyle
>& rStyleList
447 , const ::std::map
< css::uno::Reference
< css::chart2::XDataSeries
> , sal_Int32
>& rSeriesMap
)
449 ::std::list
< DataRowPointStyle
>::iterator
aIt(rStyleList
.begin());
450 ::std::list
< DataRowPointStyle
>::iterator
aEnd(rStyleList
.end());
452 //detect old series count
453 //and add old series to aSeriesMap
454 ::std::map
< css::uno::Reference
<
455 css::chart2::XDataSeries
>, sal_Int32
> aSeriesMap(rSeriesMap
);
456 sal_Int32 nOldSeriesCount
= 0;
458 sal_Int32 nMaxOldSeriesIndex
= 0;
459 sal_Int32 nOldSeriesIndex
= 0;
460 for( aIt
= rStyleList
.begin(); aIt
!= aEnd
; ++aIt
)
462 DataRowPointStyle
aStyle(*aIt
);
463 if(aStyle
.meType
== DataRowPointStyle::DATA_SERIES
&&
464 aStyle
.m_xSeries
.is() )
466 nMaxOldSeriesIndex
= nOldSeriesIndex
;
468 if( aSeriesMap
.end() == aSeriesMap
.find(aStyle
.m_xSeries
) )
469 aSeriesMap
[aStyle
.m_xSeries
] = nOldSeriesIndex
;
474 nOldSeriesCount
= nMaxOldSeriesIndex
+1;
477 //initialize new series styles
478 ::std::map
< Reference
< chart2::XDataSeries
>, sal_Int32
>::const_iterator
aSeriesMapIt( aSeriesMap
.begin() );
479 ::std::map
< Reference
< chart2::XDataSeries
>, sal_Int32
>::const_iterator
aSeriesMapEnd( aSeriesMap
.end() );
482 ::std::vector
< NewDonutSeries
> aNewSeriesVector
;
484 ::std::map
< sal_Int32
, Reference
< chart2::XDataSeries
> > aIndexSeriesMap
;
485 for( ; aSeriesMapIt
!= aSeriesMapEnd
; ++aSeriesMapIt
)
486 aIndexSeriesMap
[aSeriesMapIt
->second
] = aSeriesMapIt
->first
;
488 ::std::map
< sal_Int32
, Reference
< chart2::XDataSeries
> >::const_iterator
aIndexIt( aIndexSeriesMap
.begin() );
489 ::std::map
< sal_Int32
, Reference
< chart2::XDataSeries
> >::const_iterator
aIndexEnd( aIndexSeriesMap
.end() );
491 for( ; aIndexIt
!= aIndexEnd
; ++aIndexIt
)
492 aNewSeriesVector
.push_back( NewDonutSeries(aIndexIt
->second
,nOldSeriesCount
) );
495 //overwrite attached axis information according to old series styles
496 for( aIt
= rStyleList
.begin(); aIt
!= aEnd
; ++aIt
)
498 DataRowPointStyle
aStyle(*aIt
);
499 if(aStyle
.meType
== DataRowPointStyle::DATA_SERIES
)
501 aSeriesMapIt
= aSeriesMap
.find( aStyle
.m_xSeries
);
502 if( aSeriesMapIt
!= aSeriesMapEnd
&& aSeriesMapIt
->second
< static_cast<sal_Int32
>(aNewSeriesVector
.size()) )
503 aNewSeriesVector
[aSeriesMapIt
->second
].mnAttachedAxis
= aStyle
.mnAttachedAxis
;
507 //overwrite new series style names with old series style name information
508 for( aIt
= rStyleList
.begin(); aIt
!= aEnd
; ++aIt
)
510 DataRowPointStyle
aStyle(*aIt
);
511 if( aStyle
.meType
== DataRowPointStyle::DATA_SERIES
)
513 aSeriesMapIt
= aSeriesMap
.find(aStyle
.m_xSeries
);
514 if( aSeriesMapEnd
!= aSeriesMapIt
)
516 sal_Int32 nNewPointIndex
= aSeriesMapIt
->second
;
518 ::std::vector
< NewDonutSeries
>::iterator
aNewSeriesIt( aNewSeriesVector
.begin() );
519 ::std::vector
< NewDonutSeries
>::iterator
aNewSeriesEnd( aNewSeriesVector
.end() );
521 for( ;aNewSeriesIt
!=aNewSeriesEnd
; ++aNewSeriesIt
)
522 aNewSeriesIt
->setSeriesStyleNameToPoint( aStyle
.msStyleName
, nNewPointIndex
);
527 //overwrite new series style names with point style name information
528 for( aIt
= rStyleList
.begin(); aIt
!= aEnd
; ++aIt
)
530 DataRowPointStyle
aStyle(*aIt
);
531 if( aStyle
.meType
== DataRowPointStyle::DATA_POINT
)
533 aSeriesMapIt
= aSeriesMap
.find(aStyle
.m_xSeries
);
534 if( aSeriesMapEnd
!= aSeriesMapIt
)
536 sal_Int32 nNewPointIndex
= aSeriesMapIt
->second
;
537 sal_Int32 nNewSeriesIndex
= aStyle
.m_nPointIndex
;
538 sal_Int32 nRepeatCount
= aStyle
.m_nPointRepeat
;
540 while( nRepeatCount
&& (nNewSeriesIndex
>=0) && (nNewSeriesIndex
< static_cast<sal_Int32
>(aNewSeriesVector
.size()) ) )
542 NewDonutSeries
& rNewSeries( aNewSeriesVector
[nNewSeriesIndex
] );
543 rNewSeries
.setPointStyleNameToPoint( aStyle
.msStyleName
, nNewPointIndex
);
552 //put information from aNewSeriesVector to output parameter rStyleList
555 ::std::vector
< NewDonutSeries
>::iterator
aNewSeriesIt( aNewSeriesVector
.begin() );
556 ::std::vector
< NewDonutSeries
>::iterator
aNewSeriesEnd( aNewSeriesVector
.end() );
557 for( ;aNewSeriesIt
!=aNewSeriesEnd
; ++aNewSeriesIt
)
559 ::std::list
< DataRowPointStyle
> aList( aNewSeriesIt
->creatStyleList() );
560 rStyleList
.insert(rStyleList
.end(),aList
.begin(),aList
.end());
564 bool lcl_SpecialHandlingForDonutChartNeeded(
565 const OUString
& rServiceName
,
566 const SvXMLImport
& rImport
)
568 bool bResult
= false;
569 if( rServiceName
== "com.sun.star.chart2.DonutChartType" )
571 bResult
= SchXMLTools::isDocumentGeneratedWithOpenOfficeOlderThan2_3( rImport
.GetModel() );
576 } // anonymous namespace
578 static void lcl_ApplyDataFromRectangularRangeToDiagram(
579 const uno::Reference
< chart2::XChartDocument
>& xNewDoc
580 , const OUString
& rRectangularRange
581 , css::chart::ChartDataRowSource eDataRowSource
582 , bool bRowHasLabels
, bool bColHasLabels
583 , bool bSwitchOnLabelsAndCategoriesForOwnData
584 , const OUString
& sColTrans
585 , const OUString
& sRowTrans
)
590 uno::Reference
< chart2::XDiagram
> xNewDia( xNewDoc
->getFirstDiagram());
591 uno::Reference
< chart2::data::XDataProvider
> xDataProvider( xNewDoc
->getDataProvider() );
592 if( !xNewDia
.is() || !xDataProvider
.is() )
595 bool bFirstCellAsLabel
=
596 (eDataRowSource
==chart::ChartDataRowSource_COLUMNS
)? bRowHasLabels
: bColHasLabels
;
598 (eDataRowSource
==chart::ChartDataRowSource_COLUMNS
)? bColHasLabels
: bRowHasLabels
;
600 if( bSwitchOnLabelsAndCategoriesForOwnData
)
602 bFirstCellAsLabel
= true;
603 bHasCateories
= true;
606 uno::Sequence
< beans::PropertyValue
> aArgs( 3 );
607 aArgs
[0] = beans::PropertyValue(
608 OUString( "CellRangeRepresentation" ),
609 -1, uno::makeAny( rRectangularRange
),
610 beans::PropertyState_DIRECT_VALUE
);
611 aArgs
[1] = beans::PropertyValue(
612 OUString( "DataRowSource" ),
613 -1, uno::makeAny( eDataRowSource
),
614 beans::PropertyState_DIRECT_VALUE
);
615 aArgs
[2] = beans::PropertyValue(
616 OUString( "FirstCellAsLabel" ),
617 -1, uno::makeAny( bFirstCellAsLabel
),
618 beans::PropertyState_DIRECT_VALUE
);
620 if( !sColTrans
.isEmpty() || !sRowTrans
.isEmpty() )
622 aArgs
.realloc( aArgs
.getLength() + 1 );
623 aArgs
[ sal::static_int_cast
<sal_uInt32
>(aArgs
.getLength()) - 1 ] = beans::PropertyValue(
624 OUString( "SequenceMapping" ),
625 -1, uno::makeAny( !sColTrans
.isEmpty()
626 ? lcl_getNumberSequenceFromString( sColTrans
, bHasCateories
&& !xNewDoc
->hasInternalDataProvider() )
627 : lcl_getNumberSequenceFromString( sRowTrans
, bHasCateories
&& !xNewDoc
->hasInternalDataProvider() ) ),
628 beans::PropertyState_DIRECT_VALUE
);
631 //work around wrong writer ranges ( see Issue 58464 )
633 OUString aChartOleObjectName
;
634 uno::Reference
< frame::XModel
> xModel(xNewDoc
, uno::UNO_QUERY
);
637 utl::MediaDescriptor
aMediaDescriptor( xModel
->getArgs() );
639 utl::MediaDescriptor::const_iterator
aIt(
640 aMediaDescriptor
.find( OUString( "HierarchicalDocumentName" )));
641 if( aIt
!= aMediaDescriptor
.end() )
643 aChartOleObjectName
= (*aIt
).second
.get
< OUString
>();
646 if( !aChartOleObjectName
.isEmpty() )
648 aArgs
.realloc( aArgs
.getLength() + 1 );
649 aArgs
[ sal::static_int_cast
<sal_uInt32
>(aArgs
.getLength()) - 1 ] = beans::PropertyValue(
650 OUString( "ChartOleObjectName" ),
651 -1, uno::makeAny( aChartOleObjectName
),
652 beans::PropertyState_DIRECT_VALUE
);
656 uno::Reference
< chart2::data::XDataSource
> xDataSource(
657 xDataProvider
->createDataSource( aArgs
));
659 aArgs
.realloc( aArgs
.getLength() + 2 );
660 aArgs
[ sal::static_int_cast
<sal_uInt32
>(aArgs
.getLength()) - 2 ] = beans::PropertyValue(
661 OUString( "HasCategories" ),
662 -1, uno::makeAny( bHasCateories
),
663 beans::PropertyState_DIRECT_VALUE
);
664 aArgs
[ sal::static_int_cast
<sal_uInt32
>(aArgs
.getLength()) - 1 ] = beans::PropertyValue(
665 OUString("UseCategoriesAsX"),
666 -1, uno::makeAny( false ),//categories in ODF files are not to be used as x values (independent from what is offered in our ui)
667 beans::PropertyState_DIRECT_VALUE
);
669 xNewDia
->setDiagramData( xDataSource
, aArgs
);
672 void SchXMLChartContext::EndElement()
674 uno::Reference
< chart::XChartDocument
> xDoc
= mrImportHelper
.GetChartDocument();
675 uno::Reference
< beans::XPropertySet
> xProp( xDoc
, uno::UNO_QUERY
);
676 uno::Reference
< chart2::XChartDocument
> xNewDoc( xDoc
, uno::UNO_QUERY
);
680 if( !maMainTitle
.isEmpty())
682 uno::Reference
< beans::XPropertySet
> xTitleProp( xDoc
->getTitle(), uno::UNO_QUERY
);
687 xTitleProp
->setPropertyValue("String", uno::Any(maMainTitle
) );
689 catch(const beans::UnknownPropertyException
&)
691 SAL_WARN("xmloff.chart", "Property String for Title not available" );
695 if( !maSubTitle
.isEmpty())
697 uno::Reference
< beans::XPropertySet
> xTitleProp( xDoc
->getSubTitle(), uno::UNO_QUERY
);
702 xTitleProp
->setPropertyValue("String", uno::Any(maSubTitle
) );
704 catch(const beans::UnknownPropertyException
&)
706 SAL_WARN("xmloff.chart", "Property String for Title not available" );
712 // cleanup: remove empty chart type groups
713 lcl_removeEmptyChartTypeGroups( xNewDoc
);
715 // set stack mode before a potential chart type detection (in case we have a rectangular range)
716 uno::Reference
< chart::XDiagram
> xDiagram( xDoc
->getDiagram() );
717 uno::Reference
< beans::XPropertySet
> xDiaProp( xDiagram
, uno::UNO_QUERY
);
720 if( maSeriesDefaultsAndStyles
.maStackedDefault
.hasValue())
721 xDiaProp
->setPropertyValue("Stacked",maSeriesDefaultsAndStyles
.maStackedDefault
);
722 if( maSeriesDefaultsAndStyles
.maPercentDefault
.hasValue())
723 xDiaProp
->setPropertyValue("Percent",maSeriesDefaultsAndStyles
.maPercentDefault
);
724 if( maSeriesDefaultsAndStyles
.maDeepDefault
.hasValue())
725 xDiaProp
->setPropertyValue("Deep",maSeriesDefaultsAndStyles
.maDeepDefault
);
726 if( maSeriesDefaultsAndStyles
.maStackedBarsConnectedDefault
.hasValue())
727 xDiaProp
->setPropertyValue("StackedBarsConnected",maSeriesDefaultsAndStyles
.maStackedBarsConnectedDefault
);
730 //the OOo 2.0 implementation and older has a bug with donuts
731 bool bSpecialHandlingForDonutChart
= lcl_SpecialHandlingForDonutChartNeeded(
732 maChartTypeServiceName
, GetImport());
738 bool bHasOwnData
= false;
739 if( m_aXLinkHRefAttributeToIndicateDataProvider
== "." ) //data comes from the chart itself
741 else if( m_aXLinkHRefAttributeToIndicateDataProvider
== ".." ) //data comes from the parent application
743 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
744 bHasOwnData
= m_bHasTableElement
;
746 bHasOwnData
= !m_bHasRangeAtPlotArea
;
748 if( xNewDoc
->hasInternalDataProvider())
750 if( !m_bHasTableElement
&& m_aXLinkHRefAttributeToIndicateDataProvider
!= "." )
752 //#i103147# ODF, workaround broken files with a missing table:cell-range-address at the plot-area
753 bool bSwitchSuccessful
= SchXMLTools::switchBackToDataProviderFromParent( xNewDoc
, maLSequencesPerIndex
);
754 bHasOwnData
= !bSwitchSuccessful
;
757 bHasOwnData
= true;//e.g. in case of copy->paste from calc to impress
759 else if( bHasOwnData
)
761 xNewDoc
->createInternalDataProvider( false /* bCloneExistingData */ );
764 msChartAddress
= "all";
766 bool bSwitchRangesFromOuterToInternalIfNecessary
= false;
767 if( !bHasOwnData
&& mbAllRangeAddressesAvailable
)
769 // special handling for stock chart (merge series together)
771 MergeSeriesForStockChart();
773 else if( !msChartAddress
.isEmpty() )
775 //own data or only rectangular range available
777 if( xNewDoc
->hasInternalDataProvider() )
778 SchXMLTableHelper::applyTableToInternalDataProvider( maTable
, xNewDoc
);
780 bool bOlderThan2_3
= SchXMLTools::isDocumentGeneratedWithOpenOfficeOlderThan2_3( Reference
< frame::XModel
>( xNewDoc
, uno::UNO_QUERY
));
781 bool bOldFileWithOwnDataFromRows
= (bOlderThan2_3
&& bHasOwnData
&& (meDataRowSource
==chart::ChartDataRowSource_ROWS
)); // in this case there are range addresses that are simply wrong.
783 if( mbAllRangeAddressesAvailable
&& !bSpecialHandlingForDonutChart
&& !mbIsStockChart
&&
784 !bOldFileWithOwnDataFromRows
)
786 //bHasOwnData is true in this case!
787 //e.g. for normal files with own data or also in case of copy paste scenario (e.g. calc to impress)
788 bSwitchRangesFromOuterToInternalIfNecessary
= true;
792 //apply data from rectangular range
794 // create datasource from data provider with rectangular range parameters and change the diagram setDiagramData
797 if( bOlderThan2_3
&& xDiaProp
.is() )//for older charts the hidden cells were removed by calc on the fly
798 xDiaProp
->setPropertyValue("IncludeHiddenCells",uno::makeAny(false));
800 // note: mbRowHasLabels means the first row contains labels, that means we have "column-descriptions",
801 // (analogously mbColHasLabels means we have "row-descriptions")
802 lcl_ApplyDataFromRectangularRangeToDiagram( xNewDoc
, msChartAddress
, meDataRowSource
, mbRowHasLabels
, mbColHasLabels
, bHasOwnData
, msColTrans
, msRowTrans
);
804 catch(const uno::Exception
&)
806 //try to fallback to internal data
807 SAL_WARN("xmloff.chart", "Exception during import SchXMLChartContext::lcl_ApplyDataFromRectangularRangeToDiagram try to fallback to internal data" );
811 msChartAddress
= "all";
812 if( !xNewDoc
->hasInternalDataProvider() )
814 xNewDoc
->createInternalDataProvider( false /* bCloneExistingData */ );
815 SchXMLTableHelper::applyTableToInternalDataProvider( maTable
, xNewDoc
);
818 lcl_ApplyDataFromRectangularRangeToDiagram( xNewDoc
, msChartAddress
, meDataRowSource
, mbRowHasLabels
, mbColHasLabels
, bHasOwnData
, msColTrans
, msRowTrans
);
820 catch(const uno::Exception
&)
822 SAL_WARN("xmloff.chart", "Exception during import SchXMLChartContext::lcl_ApplyDataFromRectangularRangeToDiagram fallback to internal data failed also" );
831 SAL_WARN("xmloff.chart", "Must not get here" );
834 // now all series and data point properties are available and can be set
836 if( bSpecialHandlingForDonutChart
)
838 uno::Reference
< chart2::XDiagram
> xNewDiagram( xNewDoc
->getFirstDiagram() );
839 lcl_swapPointAndSeriesStylesForDonutCharts( maSeriesDefaultsAndStyles
.maSeriesStyleList
840 , SchXMLSeriesHelper::getDataSeriesIndexMapFromDiagram(xNewDiagram
) );
843 SchXMLSeries2Context::initSeriesPropertySets( maSeriesDefaultsAndStyles
, uno::Reference
< frame::XModel
>(xDoc
, uno::UNO_QUERY
) );
845 //set defaults from diagram to the new series:
846 //check whether we need to remove lines from symbol only charts
847 bool bSwitchOffLinesForScatter
= false;
849 bool bLinesOn
= true;
850 if( (maSeriesDefaultsAndStyles
.maLinesOnProperty
>>= bLinesOn
) && !bLinesOn
)
852 if( maChartTypeServiceName
== "com.sun.star.chart2.ScatterChartType" )
854 bSwitchOffLinesForScatter
= true;
855 SchXMLSeries2Context::switchSeriesLinesOff( maSeriesDefaultsAndStyles
.maSeriesStyleList
);
859 SchXMLSeries2Context::setDefaultsToSeries( maSeriesDefaultsAndStyles
);
861 // set autostyles for series and data points
862 const SvXMLStylesContext
* pStylesCtxt
= mrImportHelper
.GetAutoStylesContext();
863 const SvXMLStyleContext
* pStyle
= nullptr;
864 OUString sCurrStyleName
;
868 //iterate over data-series first
869 //don't set series styles for donut charts
870 if( !bSpecialHandlingForDonutChart
)
872 SchXMLSeries2Context::setStylesToSeries(
873 maSeriesDefaultsAndStyles
, pStylesCtxt
, pStyle
,
874 sCurrStyleName
, mrImportHelper
, GetImport(),
875 mbIsStockChart
, maLSequencesPerIndex
);
876 // ... then set attributes for statistics (after their existence was set in the series)
877 SchXMLSeries2Context::setStylesToStatisticsObjects(
878 maSeriesDefaultsAndStyles
, pStylesCtxt
,
879 pStyle
, sCurrStyleName
);
881 SchXMLSeries2Context::setStylesToRegressionCurves(
882 maSeriesDefaultsAndStyles
, pStylesCtxt
,
883 pStyle
, sCurrStyleName
);
887 //#i98319# call switchRangesFromOuterToInternalIfNecessary before the data point styles are applied, otherwise in copy->paste scenario the data point styles do get lost
888 if( bSwitchRangesFromOuterToInternalIfNecessary
)
890 if( xNewDoc
->hasInternalDataProvider() )
891 SchXMLTableHelper::switchRangesFromOuterToInternalIfNecessary( maTable
, maLSequencesPerIndex
, xNewDoc
, meDataRowSource
);
896 // ... then iterate over data-point attributes, so the latter are not overwritten
897 SchXMLSeries2Context::setStylesToDataPoints( maSeriesDefaultsAndStyles
898 , pStylesCtxt
, pStyle
, sCurrStyleName
, mrImportHelper
, GetImport(), mbIsStockChart
, bSpecialHandlingForDonutChart
, bSwitchOffLinesForScatter
);
903 xProp
->setPropertyValue("RefreshAddInAllowed", uno::makeAny( true) );
906 void SchXMLChartContext::MergeSeriesForStockChart()
908 OSL_ASSERT( mbIsStockChart
);
911 uno::Reference
< chart::XChartDocument
> xOldDoc( mrImportHelper
.GetChartDocument());
912 uno::Reference
< chart2::XChartDocument
> xDoc( xOldDoc
, uno::UNO_QUERY_THROW
);
913 uno::Reference
< chart2::XDiagram
> xDiagram( xDoc
->getFirstDiagram());
917 bool bHasJapaneseCandlestick
= true;
918 uno::Reference
< chart2::XDataSeriesContainer
> xDSContainer
;
919 uno::Reference
< chart2::XCoordinateSystemContainer
> xCooSysCnt( xDiagram
, uno::UNO_QUERY_THROW
);
920 uno::Sequence
< uno::Reference
< chart2::XCoordinateSystem
> > aCooSysSeq( xCooSysCnt
->getCoordinateSystems());
921 for( sal_Int32 nCooSysIdx
=0; nCooSysIdx
<aCooSysSeq
.getLength(); ++nCooSysIdx
)
923 uno::Reference
< chart2::XChartTypeContainer
> xCTCnt( aCooSysSeq
[nCooSysIdx
], uno::UNO_QUERY_THROW
);
924 uno::Sequence
< uno::Reference
< chart2::XChartType
> > aChartTypes( xCTCnt
->getChartTypes());
925 for( sal_Int32 nCTIdx
=0; nCTIdx
<aChartTypes
.getLength(); ++nCTIdx
)
927 if( aChartTypes
[nCTIdx
]->getChartType() == "com.sun.star.chart2.CandleStickChartType" )
929 xDSContainer
.set( aChartTypes
[nCTIdx
], uno::UNO_QUERY_THROW
);
930 uno::Reference
< beans::XPropertySet
> xCTProp( aChartTypes
[nCTIdx
], uno::UNO_QUERY_THROW
);
931 xCTProp
->getPropertyValue("Japanese") >>= bHasJapaneseCandlestick
;
937 if( xDSContainer
.is())
939 // with japanese candlesticks: open, low, high, close
940 // otherwise: low, high, close
941 uno::Sequence
< uno::Reference
< chart2::XDataSeries
> > aSeriesSeq( xDSContainer
->getDataSeries());
942 const sal_Int32
nSeriesCount( aSeriesSeq
.getLength());
943 const sal_Int32 nSeriesPerCandleStick
= bHasJapaneseCandlestick
? 4: 3;
944 sal_Int32 nCandleStickCount
= nSeriesCount
/ nSeriesPerCandleStick
;
945 OSL_ASSERT( nSeriesPerCandleStick
* nCandleStickCount
== nSeriesCount
);
946 uno::Sequence
< uno::Reference
< chart2::XDataSeries
> > aNewSeries( nCandleStickCount
);
947 for( sal_Int32 i
=0; i
<nCandleStickCount
; ++i
)
949 sal_Int32 nSeriesIndex
= i
*nSeriesPerCandleStick
;
950 if( bHasJapaneseCandlestick
)
953 lcl_setRoleAtFirstSequence( aSeriesSeq
[ nSeriesIndex
], "values-first");
954 aNewSeries
[i
] = aSeriesSeq
[ nSeriesIndex
];
956 lcl_MoveDataToCandleStickSeries(
957 uno::Reference
< chart2::data::XDataSource
>( aSeriesSeq
[ ++nSeriesIndex
], uno::UNO_QUERY_THROW
),
958 aNewSeries
[i
], "values-min");
963 lcl_setRoleAtFirstSequence( aSeriesSeq
[ nSeriesIndex
], "values-min");
964 aNewSeries
[i
] = aSeriesSeq
[ nSeriesIndex
];
967 lcl_MoveDataToCandleStickSeries(
968 uno::Reference
< chart2::data::XDataSource
>( aSeriesSeq
[ ++nSeriesIndex
], uno::UNO_QUERY_THROW
),
969 aNewSeries
[i
], "values-max");
971 lcl_MoveDataToCandleStickSeries(
972 uno::Reference
< chart2::data::XDataSource
>( aSeriesSeq
[ ++nSeriesIndex
], uno::UNO_QUERY_THROW
),
973 aNewSeries
[i
], "values-last");
975 xDSContainer
->setDataSeries( aNewSeries
);
978 catch(const uno::Exception
&)
980 SAL_WARN("xmloff.chart", "Exception while merging series for stock chart" );
984 SvXMLImportContext
* SchXMLChartContext::CreateChildContext(
986 const OUString
& rLocalName
,
987 const uno::Reference
< xml::sax::XAttributeList
>& xAttrList
)
989 SvXMLImportContext
* pContext
= nullptr;
990 const SvXMLTokenMap
& rTokenMap
= mrImportHelper
.GetChartElemTokenMap();
991 uno::Reference
< chart::XChartDocument
> xDoc
= mrImportHelper
.GetChartDocument();
992 uno::Reference
< beans::XPropertySet
> xProp( xDoc
, uno::UNO_QUERY
);
994 switch( rTokenMap
.Get( nPrefix
, rLocalName
))
996 case XML_TOK_CHART_PLOT_AREA
:
997 pContext
= new SchXMLPlotAreaContext( mrImportHelper
, GetImport(), rLocalName
,
998 m_aXLinkHRefAttributeToIndicateDataProvider
,
1000 msChartAddress
, m_bHasRangeAtPlotArea
, mbAllRangeAddressesAvailable
,
1001 mbColHasLabels
, mbRowHasLabels
,
1003 maSeriesDefaultsAndStyles
,
1004 maChartTypeServiceName
,
1005 maLSequencesPerIndex
, maChartSize
);
1008 case XML_TOK_CHART_TITLE
:
1013 xProp
->setPropertyValue("HasMainTitle", uno::makeAny(true) );
1015 uno::Reference
< drawing::XShape
> xTitleShape( xDoc
->getTitle(), uno::UNO_QUERY
);
1016 pContext
= new SchXMLTitleContext( mrImportHelper
, GetImport(),
1017 rLocalName
, maMainTitle
, xTitleShape
);
1021 case XML_TOK_CHART_SUBTITLE
:
1026 xProp
->setPropertyValue("HasSubTitle", uno::makeAny(true) );
1028 uno::Reference
< drawing::XShape
> xTitleShape( xDoc
->getSubTitle(), uno::UNO_QUERY
);
1029 pContext
= new SchXMLTitleContext( mrImportHelper
, GetImport(),
1030 rLocalName
, maSubTitle
, xTitleShape
);
1034 case XML_TOK_CHART_LEGEND
:
1035 pContext
= new SchXMLLegendContext( mrImportHelper
, GetImport(), rLocalName
);
1038 case XML_TOK_CHART_TABLE
:
1040 SchXMLTableContext
* pTableContext
=
1041 new SchXMLTableContext( mrImportHelper
, GetImport(), rLocalName
, maTable
);
1042 m_bHasTableElement
= true;
1043 // #i85913# take into account column- and row- mapping for
1044 // charts with own data only for those which were not copied
1045 // from a place where they got data from the container. Note,
1046 // that this requires the plot-area been read before the table
1047 // (which is required in the ODF spec)
1048 // Note: For stock charts and donut charts with special handling
1049 // the mapping must not be applied!
1050 if( msChartAddress
.isEmpty() && !mbIsStockChart
&&
1051 !lcl_SpecialHandlingForDonutChartNeeded(
1052 maChartTypeServiceName
, GetImport()))
1054 if( !msColTrans
.isEmpty() )
1056 OSL_ASSERT( msRowTrans
.isEmpty() );
1057 pTableContext
->setColumnPermutation( lcl_getNumberSequenceFromString( msColTrans
, true ));
1060 else if( !msRowTrans
.isEmpty() )
1062 pTableContext
->setRowPermutation( lcl_getNumberSequenceFromString( msRowTrans
, true ));
1066 pContext
= pTableContext
;
1071 // try importing as an additional shape
1072 if( ! mxDrawPage
.is())
1074 uno::Reference
< drawing::XDrawPageSupplier
> xSupp( xDoc
, uno::UNO_QUERY
);
1076 mxDrawPage
.set( xSupp
->getDrawPage(), uno::UNO_QUERY
);
1078 SAL_WARN_IF( !mxDrawPage
.is(), "xmloff.chart", "Invalid Chart Page" );
1080 if( mxDrawPage
.is())
1081 pContext
= GetImport().GetShapeImport()->CreateGroupChildContext(
1082 GetImport(), nPrefix
, rLocalName
, xAttrList
, mxDrawPage
);
1087 pContext
= new SvXMLImportContext( GetImport(), nPrefix
, rLocalName
);
1093 With a locked controller the following is done here:
1094 1. Hide title, subtitle, and legend.
1095 2. Set the size of the draw page.
1096 3. Set a (logically) empty data set.
1097 4. Set the chart type.
1099 void SchXMLChartContext::InitChart(
1100 const OUString
& rChartTypeServiceName
, // currently the old service name
1101 bool /* bSetSwitchData */ )
1103 uno::Reference
< chart::XChartDocument
> xDoc
= mrImportHelper
.GetChartDocument();
1104 SAL_WARN_IF( !xDoc
.is(), "xmloff.chart", "No valid document!" );
1105 uno::Reference
< frame::XModel
> xModel (xDoc
, uno::UNO_QUERY
);
1107 // Remove Title and Diagram ("De-InitNew")
1108 uno::Reference
< chart2::XChartDocument
> xNewDoc( mrImportHelper
.GetChartDocument(), uno::UNO_QUERY
);
1111 xNewDoc
->setFirstDiagram( nullptr );
1112 uno::Reference
< chart2::XTitled
> xTitled( xNewDoc
, uno::UNO_QUERY
);
1114 xTitled
->setTitleObject( nullptr );
1117 // Set the chart type via setting the diagram.
1118 if( !rChartTypeServiceName
.isEmpty() && xDoc
.is())
1120 uno::Reference
< lang::XMultiServiceFactory
> xFact( xDoc
, uno::UNO_QUERY
);
1123 uno::Reference
< chart::XDiagram
> xDia( xFact
->createInstance( rChartTypeServiceName
), uno::UNO_QUERY
);
1125 xDoc
->setDiagram( xDia
);
1130 SchXMLTitleContext::SchXMLTitleContext( SchXMLImportHelper
& rImpHelper
, SvXMLImport
& rImport
,
1131 const OUString
& rLocalName
,
1133 uno::Reference
< drawing::XShape
>& xTitleShape
) :
1134 SvXMLImportContext( rImport
, XML_NAMESPACE_CHART
, rLocalName
),
1135 mrImportHelper( rImpHelper
),
1137 mxTitleShape( xTitleShape
)
1141 SchXMLTitleContext::~SchXMLTitleContext()
1144 void SchXMLTitleContext::StartElement( const uno::Reference
< xml::sax::XAttributeList
>& xAttrList
)
1146 sal_Int16 nAttrCount
= xAttrList
.is()? xAttrList
->getLength(): 0;
1148 css::awt::Point aPosition
;
1149 bool bHasXPosition
=false;
1150 bool bHasYPosition
=false;
1152 for( sal_Int16 i
= 0; i
< nAttrCount
; i
++ )
1154 OUString sAttrName
= xAttrList
->getNameByIndex( i
);
1155 OUString aLocalName
;
1156 OUString aValue
= xAttrList
->getValueByIndex( i
);
1157 sal_uInt16 nPrefix
= GetImport().GetNamespaceMap().GetKeyByAttrName( sAttrName
, &aLocalName
);
1159 if( nPrefix
== XML_NAMESPACE_SVG
)
1161 if( IsXMLToken( aLocalName
, XML_X
) )
1163 GetImport().GetMM100UnitConverter().convertMeasureToCore(
1164 aPosition
.X
, aValue
);
1165 bHasXPosition
= true;
1167 else if( IsXMLToken( aLocalName
, XML_Y
) )
1169 GetImport().GetMM100UnitConverter().convertMeasureToCore(
1170 aPosition
.Y
, aValue
);
1171 bHasYPosition
= true;
1174 else if( nPrefix
== XML_NAMESPACE_CHART
)
1176 if( IsXMLToken( aLocalName
, XML_STYLE_NAME
) )
1177 msAutoStyleName
= aValue
;
1181 if( mxTitleShape
.is())
1183 if( bHasXPosition
&& bHasYPosition
)
1184 mxTitleShape
->setPosition( aPosition
);
1186 uno::Reference
< beans::XPropertySet
> xProp( mxTitleShape
, uno::UNO_QUERY
);
1189 const SvXMLStylesContext
* pStylesCtxt
= mrImportHelper
.GetAutoStylesContext();
1192 const SvXMLStyleContext
* pStyle
= pStylesCtxt
->FindStyleChildContext(
1193 SchXMLImportHelper::GetChartFamilyID(), msAutoStyleName
);
1195 if( pStyle
&& dynamic_cast< const XMLPropStyleContext
*>(pStyle
) != nullptr)
1196 const_cast<XMLPropStyleContext
*>( static_cast< const XMLPropStyleContext
* >( pStyle
) )->FillPropertySet( xProp
);
1202 SvXMLImportContext
* SchXMLTitleContext::CreateChildContext(
1204 const OUString
& rLocalName
,
1205 const uno::Reference
< xml::sax::XAttributeList
>& )
1207 SvXMLImportContext
* pContext
= nullptr;
1209 if( (nPrefix
== XML_NAMESPACE_TEXT
||
1210 nPrefix
== XML_NAMESPACE_LO_EXT
) &&
1211 IsXMLToken( rLocalName
, XML_P
) )
1213 pContext
= new SchXMLParagraphContext( GetImport(), rLocalName
, mrTitle
);
1216 pContext
= new SvXMLImportContext( GetImport(), nPrefix
, rLocalName
);
1221 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */