1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*************************************************************************
4 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
6 * Copyright 2000, 2010 Oracle and/or its affiliates.
8 * OpenOffice.org - a multi-platform office productivity suite
10 * This file is part of OpenOffice.org.
12 * OpenOffice.org is free software: you can redistribute it and/or modify
13 * it under the terms of the GNU Lesser General Public License version 3
14 * only, as published by the Free Software Foundation.
16 * OpenOffice.org is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 * GNU Lesser General Public License version 3 for more details
20 * (a copy is included in the LICENSE file that accompanied this code).
22 * You should have received a copy of the GNU Lesser General Public License
23 * version 3 along with OpenOffice.org. If not, see
24 * <http://www.openoffice.org/license.html>
25 * for a copy of the LGPLv3 License.
27 ************************************************************************/
30 #include "SchXMLChartContext.hxx"
31 #include "SchXMLImport.hxx"
32 #include "SchXMLLegendContext.hxx"
33 #include "SchXMLPlotAreaContext.hxx"
34 #include "SchXMLParagraphContext.hxx"
35 #include "SchXMLTableContext.hxx"
36 #include "SchXMLSeriesHelper.hxx"
37 #include "SchXMLSeries2Context.hxx"
38 #include "SchXMLTools.hxx"
39 #include <comphelper/mediadescriptor.hxx>
40 #include <tools/debug.hxx>
41 #include "xmloff/xmlnmspe.hxx"
42 #include <xmloff/xmlement.hxx>
43 #include <xmloff/xmltoken.hxx>
44 #include <xmloff/nmspmap.hxx>
45 #include <xmloff/xmluconv.hxx>
46 #include <xmloff/xmlstyle.hxx>
47 #include <xmloff/prstylei.hxx>
50 #include <com/sun/star/chart/XChartDocument.hpp>
51 #include <com/sun/star/chart/XDiagram.hpp>
52 #include <com/sun/star/xml/sax/XAttributeList.hpp>
53 #include <com/sun/star/util/XStringMapping.hpp>
54 #include <com/sun/star/drawing/XDrawPageSupplier.hpp>
55 #include <com/sun/star/drawing/XDrawPage.hpp>
56 #include <com/sun/star/chart/ChartDataRowSource.hpp>
57 #include <com/sun/star/awt/PosSize.hpp>
58 #include <com/sun/star/embed/Aspects.hpp>
59 #include <com/sun/star/embed/XVisualObject.hpp>
61 #include <com/sun/star/chart2/XChartDocument.hpp>
62 #include <com/sun/star/chart2/data/XDataSink.hpp>
63 #include <com/sun/star/chart2/XDataSeriesContainer.hpp>
64 #include <com/sun/star/chart2/XCoordinateSystemContainer.hpp>
65 #include <com/sun/star/chart2/XChartTypeContainer.hpp>
66 #include <com/sun/star/chart2/XTitled.hpp>
68 using namespace com::sun::star
;
69 using namespace ::xmloff::token
;
70 using ::rtl::OUString
;
71 using com::sun::star::uno::Reference
;
72 using namespace ::SchXMLTools
;
77 void lcl_setRoleAtLabeledSequence(
78 const uno::Reference
< chart2::data::XLabeledDataSequence
> & xLSeq
,
79 const ::rtl::OUString
&rRole
)
81 // set role of sequence
82 uno::Reference
< chart2::data::XDataSequence
> xValues( xLSeq
->getValues());
85 uno::Reference
< beans::XPropertySet
> xProp( xValues
, uno::UNO_QUERY
);
87 xProp
->setPropertyValue(OUString( "Role" ), uno::makeAny( rRole
));
91 void lcl_MoveDataToCandleStickSeries(
92 const uno::Reference
< chart2::data::XDataSource
> & xDataSource
,
93 const uno::Reference
< chart2::XDataSeries
> & xDestination
,
94 const OUString
& rRole
)
98 uno::Sequence
< uno::Reference
< chart2::data::XLabeledDataSequence
> > aLabeledSeq(
99 xDataSource
->getDataSequences());
100 if( aLabeledSeq
.getLength())
102 lcl_setRoleAtLabeledSequence( aLabeledSeq
[0], rRole
);
104 // add to data series
105 uno::Reference
< chart2::data::XDataSource
> xSource( xDestination
, uno::UNO_QUERY_THROW
);
106 // @todo: realloc only once outside this function
107 uno::Sequence
< uno::Reference
< chart2::data::XLabeledDataSequence
> > aData( xSource
->getDataSequences());
108 aData
.realloc( aData
.getLength() + 1);
109 aData
[ aData
.getLength() - 1 ] = aLabeledSeq
[0];
110 uno::Reference
< chart2::data::XDataSink
> xSink( xDestination
, uno::UNO_QUERY_THROW
);
111 xSink
->setData( aData
);
114 catch(const uno::Exception
&)
116 OSL_FAIL( "Exception caught while moving data to candlestick series" );
120 void lcl_setRoleAtFirstSequence(
121 const uno::Reference
< chart2::XDataSeries
> & xSeries
,
122 const ::rtl::OUString
& rRole
)
124 uno::Reference
< chart2::data::XDataSource
> xSource( xSeries
, uno::UNO_QUERY
);
127 uno::Sequence
< uno::Reference
< chart2::data::XLabeledDataSequence
> > aSeq( xSource
->getDataSequences());
128 if( aSeq
.getLength())
129 lcl_setRoleAtLabeledSequence( aSeq
[0], rRole
);
133 void lcl_removeEmptyChartTypeGroups( const uno::Reference
< chart2::XChartDocument
> & xDoc
)
138 uno::Reference
< chart2::XDiagram
> xDia( xDoc
->getFirstDiagram());
144 // count all charttype groups to be able to leave at least one
145 sal_Int32 nRemainingGroups
= 0;
146 uno::Reference
< chart2::XCoordinateSystemContainer
> xCooSysCnt( xDia
, uno::UNO_QUERY_THROW
);
147 uno::Sequence
< uno::Reference
< chart2::XCoordinateSystem
> >
148 aCooSysSeq( xCooSysCnt
->getCoordinateSystems());
149 for( sal_Int32 nI
= aCooSysSeq
.getLength(); nI
--; )
151 uno::Reference
< chart2::XChartTypeContainer
> xCTCnt( aCooSysSeq
[nI
], uno::UNO_QUERY_THROW
);
152 nRemainingGroups
+= xCTCnt
->getChartTypes().getLength();
155 // delete all empty groups, but leave at least group (empty or not)
156 for( sal_Int32 nI
= aCooSysSeq
.getLength(); nI
-- && (nRemainingGroups
> 1); )
158 uno::Reference
< chart2::XChartTypeContainer
> xCTCnt( aCooSysSeq
[nI
], uno::UNO_QUERY_THROW
);
159 uno::Sequence
< uno::Reference
< chart2::XChartType
> > aCTSeq( xCTCnt
->getChartTypes());
160 for( sal_Int32 nJ
=aCTSeq
.getLength(); nJ
-- && (nRemainingGroups
> 1); )
162 uno::Reference
< chart2::XDataSeriesContainer
> xDSCnt( aCTSeq
[nJ
], uno::UNO_QUERY_THROW
);
163 if( xDSCnt
->getDataSeries().getLength() == 0 )
165 // note: iterator stays valid as we have a local sequence
166 xCTCnt
->removeChartType( aCTSeq
[nJ
] );
172 catch(const uno::Exception
& ex
)
174 rtl::OString
aBStr(rtl::OUStringToOString(ex
.Message
, RTL_TEXTENCODING_ASCII_US
));
175 OSL_TRACE( "Exception caught while removing empty chart types: %s", aBStr
.getStr());
179 uno::Sequence
< sal_Int32
> lcl_getNumberSequenceFromString( const ::rtl::OUString
& rStr
, bool bAddOneToEachOldIndex
)
181 const sal_Unicode
aSpace( ' ' );
183 // count number of entries
184 ::std::vector
< sal_Int32
> aVec
;
185 sal_Int32 nLastPos
= 0;
189 nPos
= rStr
.indexOf( aSpace
, nLastPos
);
190 if( nPos
> nLastPos
)
192 aVec
.push_back( rStr
.copy( nLastPos
, (nPos
- nLastPos
) ).toInt32() );
199 rStr
.getLength() > nLastPos
)
201 aVec
.push_back( rStr
.copy( nLastPos
, (rStr
.getLength() - nLastPos
) ).toInt32() );
204 const sal_Int32 nVecSize
= aVec
.size();
205 uno::Sequence
< sal_Int32
> aSeq( nVecSize
);
207 if(!bAddOneToEachOldIndex
)
209 sal_Int32
* pSeqArr
= aSeq
.getArray();
210 for( nPos
= 0; nPos
< nVecSize
; ++nPos
)
212 pSeqArr
[ nPos
] = aVec
[ nPos
];
215 else if( bAddOneToEachOldIndex
)
217 aSeq
.realloc( nVecSize
+1 );
220 sal_Int32
* pSeqArr
= aSeq
.getArray();
221 for( nPos
= 0; nPos
< nVecSize
; ++nPos
)
223 pSeqArr
[ nPos
+1 ] = aVec
[ nPos
]+1;
230 } // anonymous namespace
232 // ----------------------------------------
234 SchXMLChartContext::SchXMLChartContext( SchXMLImportHelper
& rImpHelper
,
235 SvXMLImport
& rImport
, const rtl::OUString
& rLocalName
) :
236 SvXMLImportContext( rImport
, XML_NAMESPACE_CHART
, rLocalName
),
237 mrImportHelper( rImpHelper
),
238 m_bHasRangeAtPlotArea( false ),
239 m_bHasTableElement( false ),
240 mbAllRangeAddressesAvailable( sal_True
),
241 mbColHasLabels( sal_False
),
242 mbRowHasLabels( sal_False
),
243 meDataRowSource( chart::ChartDataRowSource_COLUMNS
),
244 mbIsStockChart( false )
248 SchXMLChartContext::~SchXMLChartContext()
251 void SchXMLChartContext::StartElement( const uno::Reference
< xml::sax::XAttributeList
>& xAttrList
)
254 sal_Int16 nAttrCount
= xAttrList
.is()? xAttrList
->getLength(): 0;
255 const SvXMLTokenMap
& rAttrTokenMap
= mrImportHelper
.GetChartAttrTokenMap();
257 uno::Reference
< embed::XVisualObject
> xVisualObject( mrImportHelper
.GetChartDocument(), uno::UNO_QUERY
);
258 DBG_ASSERT(xVisualObject
.is(),"need xVisualObject for page size");
259 if( xVisualObject
.is() )
260 maChartSize
= xVisualObject
->getVisualAreaSize( embed::Aspects::MSOLE_CONTENT
); //#i103460# take the size given from the parent frame as default
262 // this flag is necessarry for pie charts in the core
263 sal_Bool bSetSwitchData
= sal_False
;
265 ::rtl::OUString sAutoStyleName
;
266 ::rtl::OUString aOldChartTypeName
;
267 bool bHasAddin
= false;
269 for( sal_Int16 i
= 0; i
< nAttrCount
; i
++ )
271 rtl::OUString sAttrName
= xAttrList
->getNameByIndex( i
);
272 rtl::OUString aLocalName
;
273 rtl::OUString aValue
= xAttrList
->getValueByIndex( i
);
274 sal_uInt16 nPrefix
= GetImport().GetNamespaceMap().GetKeyByAttrName( sAttrName
, &aLocalName
);
276 switch( rAttrTokenMap
.Get( nPrefix
, aLocalName
))
278 case XML_TOK_CHART_HREF
:
279 m_aXLinkHRefAttributeToIndicateDataProvider
= aValue
;
282 case XML_TOK_CHART_CLASS
:
284 rtl::OUString sClassName
;
285 sal_uInt16 nClassPrefix
=
286 GetImport().GetNamespaceMap().GetKeyByAttrName(
287 aValue
, &sClassName
);
288 if( XML_NAMESPACE_CHART
== nClassPrefix
)
290 SchXMLChartTypeEnum eChartTypeEnum
= SchXMLTools::GetChartTypeEnum( sClassName
);
291 if( eChartTypeEnum
!= XML_CHART_CLASS_UNKNOWN
)
293 aOldChartTypeName
= SchXMLTools::GetChartTypeByClassName( sClassName
, true /* bUseOldNames */ );
294 maChartTypeServiceName
= SchXMLTools::GetChartTypeByClassName( sClassName
, false /* bUseOldNames */ );
295 switch( eChartTypeEnum
)
297 case XML_CHART_CLASS_CIRCLE
:
298 bSetSwitchData
= sal_True
;
300 case XML_CHART_CLASS_STOCK
:
301 mbIsStockChart
= true;
308 else if( XML_NAMESPACE_OOO
== nClassPrefix
)
310 // service is taken from add-in-name attribute
313 aOldChartTypeName
= sClassName
;
314 maChartTypeServiceName
= sClassName
;
319 case XML_TOK_CHART_WIDTH
:
320 GetImport().GetMM100UnitConverter().convertMeasureToCore(
321 maChartSize
.Width
, aValue
);
324 case XML_TOK_CHART_HEIGHT
:
325 GetImport().GetMM100UnitConverter().convertMeasureToCore(
326 maChartSize
.Height
, aValue
);
329 case XML_TOK_CHART_STYLE_NAME
:
330 sAutoStyleName
= aValue
;
333 case XML_TOK_CHART_COL_MAPPING
:
336 case XML_TOK_CHART_ROW_MAPPING
:
342 if( aOldChartTypeName
.isEmpty() )
344 OSL_FAIL( "need a charttype to create a diagram" );
345 //set a fallback value:
346 ::rtl::OUString
aChartClass_Bar( GetXMLToken(XML_BAR
) );
347 aOldChartTypeName
= SchXMLTools::GetChartTypeByClassName( aChartClass_Bar
, true /* bUseOldNames */ );
348 maChartTypeServiceName
= SchXMLTools::GetChartTypeByClassName( aChartClass_Bar
, false /* bUseOldNames */ );
351 // Set the size of the draw page.
352 if( xVisualObject
.is() )
353 xVisualObject
->setVisualAreaSize( embed::Aspects::MSOLE_CONTENT
, maChartSize
);
355 InitChart( aOldChartTypeName
, bSetSwitchData
);
359 //correct charttype serveice name when having an addin
360 //and don't refresh addin during load
361 uno::Reference
< beans::XPropertySet
> xDocProp( mrImportHelper
.GetChartDocument(), uno::UNO_QUERY
);
366 xDocProp
->getPropertyValue( ::rtl::OUString( "BaseDiagram" )) >>= aOldChartTypeName
;
367 maChartTypeServiceName
= SchXMLTools::GetNewChartTypeName( aOldChartTypeName
);
368 xDocProp
->setPropertyValue( rtl::OUString( "RefreshAddInAllowed" ) , uno::makeAny( sal_False
) );
370 catch(const uno::Exception
&)
372 OSL_FAIL( "Exception during import SchXMLChartContext::StartElement" );
377 // set auto-styles for Area
378 uno::Reference
< beans::XPropertySet
> xProp( mrImportHelper
.GetChartDocument()->getArea(), uno::UNO_QUERY
);
381 const SvXMLStylesContext
* pStylesCtxt
= mrImportHelper
.GetAutoStylesContext();
384 const SvXMLStyleContext
* pStyle
= pStylesCtxt
->FindStyleChildContext(
385 mrImportHelper
.GetChartFamilyID(), sAutoStyleName
);
387 if( pStyle
&& pStyle
->ISA( XMLPropStyleContext
))
388 (( XMLPropStyleContext
* )pStyle
)->FillPropertySet( xProp
);
396 struct NewDonutSeries
398 ::com::sun::star::uno::Reference
<
399 ::com::sun::star::chart2::XDataSeries
> m_xSeries
;
400 ::rtl::OUString msStyleName
;
401 sal_Int32 mnAttachedAxis
;
403 ::std::vector
< ::rtl::OUString
> m_aSeriesStyles
;
404 ::std::vector
< ::rtl::OUString
> m_aPointStyles
;
406 NewDonutSeries( const ::com::sun::star::uno::Reference
<
407 ::com::sun::star::chart2::XDataSeries
>& xSeries
, sal_Int32 nPointCount
)
408 : m_xSeries( xSeries
)
409 , mnAttachedAxis( 1 )
411 m_aPointStyles
.resize(nPointCount
);
412 m_aSeriesStyles
.resize(nPointCount
);
415 void setSeriesStyleNameToPoint( const ::rtl::OUString
& rStyleName
, sal_Int32 nPointIndex
)
417 DBG_ASSERT(nPointIndex
< static_cast<sal_Int32
>(m_aSeriesStyles
.size()),"donut point <-> series count mismatch");
418 if( nPointIndex
< static_cast<sal_Int32
>(m_aSeriesStyles
.size()) )
419 m_aSeriesStyles
[nPointIndex
]=rStyleName
;
422 void setPointStyleNameToPoint( const ::rtl::OUString
& rStyleName
, sal_Int32 nPointIndex
)
424 DBG_ASSERT(nPointIndex
< static_cast<sal_Int32
>(m_aPointStyles
.size()),"donut point <-> series count mismatch");
425 if( nPointIndex
< static_cast<sal_Int32
>(m_aPointStyles
.size()) )
426 m_aPointStyles
[nPointIndex
]=rStyleName
;
429 ::std::list
< DataRowPointStyle
> creatStyleList()
431 ::std::list
< DataRowPointStyle
> aRet
;
433 DataRowPointStyle
aSeriesStyle( DataRowPointStyle::DATA_SERIES
434 , m_xSeries
, -1, 1, msStyleName
, mnAttachedAxis
);
435 aRet
.push_back( aSeriesStyle
);
437 sal_Int32 nPointIndex
=0;
438 ::std::vector
< ::rtl::OUString
>::iterator
aPointIt( m_aPointStyles
.begin() );
439 ::std::vector
< ::rtl::OUString
>::iterator
aPointEnd( m_aPointStyles
.end() );
440 while( aPointIt
!= aPointEnd
)
442 DataRowPointStyle
aPointStyle( DataRowPointStyle::DATA_POINT
443 , m_xSeries
, nPointIndex
, 1, *aPointIt
, mnAttachedAxis
);
444 if( nPointIndex
< static_cast<sal_Int32
>(m_aSeriesStyles
.size()) )
446 aPointStyle
.msSeriesStyleNameForDonuts
= m_aSeriesStyles
[nPointIndex
];
448 if( !aPointStyle
.msSeriesStyleNameForDonuts
.isEmpty()
449 || !aPointStyle
.msStyleName
.isEmpty() )
450 aRet
.push_back( aPointStyle
);
459 void lcl_swapPointAndSeriesStylesForDonutCharts( ::std::list
< DataRowPointStyle
>& rStyleList
460 , const ::std::map
< ::com::sun::star::uno::Reference
<
461 ::com::sun::star::chart2::XDataSeries
> , sal_Int32
>& rSeriesMap
)
463 ::std::list
< DataRowPointStyle
>::iterator
aIt(rStyleList
.begin());
464 ::std::list
< DataRowPointStyle
>::iterator
aEnd(rStyleList
.end());
466 //detect old series count
467 //and add old series to aSeriesMap
468 ::std::map
< ::com::sun::star::uno::Reference
<
469 ::com::sun::star::chart2::XDataSeries
>, sal_Int32
> aSeriesMap(rSeriesMap
);
470 sal_Int32 nOldSeriesCount
= 0;
472 sal_Int32 nMaxOldSeriesIndex
= 0;
473 sal_Int32 nOldSeriesIndex
= 0;
474 for( aIt
= rStyleList
.begin(); aIt
!= aEnd
; ++aIt
)
476 DataRowPointStyle
aStyle(*aIt
);
477 if(aStyle
.meType
== DataRowPointStyle::DATA_SERIES
&&
478 aStyle
.m_xSeries
.is() )
480 nMaxOldSeriesIndex
= nOldSeriesIndex
;
482 if( aSeriesMap
.end() == aSeriesMap
.find(aStyle
.m_xSeries
) )
483 aSeriesMap
[aStyle
.m_xSeries
] = nOldSeriesIndex
;
488 nOldSeriesCount
= nMaxOldSeriesIndex
+1;
492 //initialize new series styles
493 ::std::map
< Reference
< chart2::XDataSeries
>, sal_Int32
>::const_iterator
aSeriesMapIt( aSeriesMap
.begin() );
494 ::std::map
< Reference
< chart2::XDataSeries
>, sal_Int32
>::const_iterator
aSeriesMapEnd( aSeriesMap
.end() );
497 ::std::vector
< NewDonutSeries
> aNewSeriesVector
;
499 ::std::map
< sal_Int32
, Reference
< chart2::XDataSeries
> > aIndexSeriesMap
;
500 for( ; aSeriesMapIt
!= aSeriesMapEnd
; ++aSeriesMapIt
)
501 aIndexSeriesMap
[aSeriesMapIt
->second
] = aSeriesMapIt
->first
;
503 ::std::map
< sal_Int32
, Reference
< chart2::XDataSeries
> >::const_iterator
aIndexIt( aIndexSeriesMap
.begin() );
504 ::std::map
< sal_Int32
, Reference
< chart2::XDataSeries
> >::const_iterator
aIndexEnd( aIndexSeriesMap
.end() );
506 for( ; aIndexIt
!= aIndexEnd
; ++aIndexIt
)
507 aNewSeriesVector
.push_back( NewDonutSeries(aIndexIt
->second
,nOldSeriesCount
) );
510 //overwrite attached axis information according to old series styles
511 for( aIt
= rStyleList
.begin(); aIt
!= aEnd
; ++aIt
)
513 DataRowPointStyle
aStyle(*aIt
);
514 if(aStyle
.meType
== DataRowPointStyle::DATA_SERIES
)
516 aSeriesMapIt
= aSeriesMap
.find( aStyle
.m_xSeries
);
517 if( aSeriesMapIt
!= aSeriesMapEnd
&& aSeriesMapIt
->second
< static_cast<sal_Int32
>(aNewSeriesVector
.size()) )
518 aNewSeriesVector
[aSeriesMapIt
->second
].mnAttachedAxis
= aStyle
.mnAttachedAxis
;
522 //overwrite new series style names with old series style name information
523 for( aIt
= rStyleList
.begin(); aIt
!= aEnd
; ++aIt
)
525 DataRowPointStyle
aStyle(*aIt
);
526 if( aStyle
.meType
== DataRowPointStyle::DATA_SERIES
)
528 aSeriesMapIt
= aSeriesMap
.find(aStyle
.m_xSeries
);
529 if( aSeriesMapEnd
!= aSeriesMapIt
)
531 sal_Int32 nNewPointIndex
= aSeriesMapIt
->second
;
533 ::std::vector
< NewDonutSeries
>::iterator
aNewSeriesIt( aNewSeriesVector
.begin() );
534 ::std::vector
< NewDonutSeries
>::iterator
aNewSeriesEnd( aNewSeriesVector
.end() );
536 for( ;aNewSeriesIt
!=aNewSeriesEnd
; ++aNewSeriesIt
)
537 aNewSeriesIt
->setSeriesStyleNameToPoint( aStyle
.msStyleName
, nNewPointIndex
);
542 //overwrite new series style names with point style name information
543 for( aIt
= rStyleList
.begin(); aIt
!= aEnd
; ++aIt
)
545 DataRowPointStyle
aStyle(*aIt
);
546 if( aStyle
.meType
== DataRowPointStyle::DATA_POINT
)
548 aSeriesMapIt
= aSeriesMap
.find(aStyle
.m_xSeries
);
549 if( aSeriesMapEnd
!= aSeriesMapIt
)
551 sal_Int32 nNewPointIndex
= aSeriesMapIt
->second
;
552 sal_Int32 nNewSeriesIndex
= aStyle
.m_nPointIndex
;
553 sal_Int32 nRepeatCount
= aStyle
.m_nPointRepeat
;
555 while( nRepeatCount
&& (nNewSeriesIndex
>=0) && (nNewSeriesIndex
< static_cast<sal_Int32
>(aNewSeriesVector
.size()) ) )
557 NewDonutSeries
& rNewSeries( aNewSeriesVector
[nNewSeriesIndex
] );
558 rNewSeries
.setPointStyleNameToPoint( aStyle
.msStyleName
, nNewPointIndex
);
567 //put information from aNewSeriesVector to output parameter rStyleList
570 ::std::vector
< NewDonutSeries
>::iterator
aNewSeriesIt( aNewSeriesVector
.begin() );
571 ::std::vector
< NewDonutSeries
>::iterator
aNewSeriesEnd( aNewSeriesVector
.end() );
572 for( ;aNewSeriesIt
!=aNewSeriesEnd
; ++aNewSeriesIt
)
574 ::std::list
< DataRowPointStyle
> aList( aNewSeriesIt
->creatStyleList() );
575 rStyleList
.insert(rStyleList
.end(),aList
.begin(),aList
.end());
579 bool lcl_SpecialHandlingForDonutChartNeeded(
580 const ::rtl::OUString
& rServiceName
,
581 const SvXMLImport
& rImport
)
583 bool bResult
= false;
584 if( rServiceName
== "com.sun.star.chart2.DonutChartType" )
586 bResult
= SchXMLTools::isDocumentGeneratedWithOpenOfficeOlderThan2_3( rImport
.GetModel() );
591 } // anonymous namespace
594 void lcl_ApplyDataFromRectangularRangeToDiagram(
595 const uno::Reference
< chart2::XChartDocument
>& xNewDoc
596 , const rtl::OUString
& rRectangularRange
597 , ::com::sun::star::chart::ChartDataRowSource eDataRowSource
598 , bool bRowHasLabels
, bool bColHasLabels
599 , bool bSwitchOnLabelsAndCategoriesForOwnData
600 , const rtl::OUString
& sColTrans
601 , const rtl::OUString
& sRowTrans
)
606 uno::Reference
< chart2::XDiagram
> xNewDia( xNewDoc
->getFirstDiagram());
607 uno::Reference
< chart2::data::XDataProvider
> xDataProvider( xNewDoc
->getDataProvider() );
608 if( !xNewDia
.is() || !xDataProvider
.is() )
611 sal_Bool bFirstCellAsLabel
=
612 (eDataRowSource
==chart::ChartDataRowSource_COLUMNS
)? bRowHasLabels
: bColHasLabels
;
613 sal_Bool bHasCateories
=
614 (eDataRowSource
==chart::ChartDataRowSource_COLUMNS
)? bColHasLabels
: bRowHasLabels
;
616 if( bSwitchOnLabelsAndCategoriesForOwnData
)
618 bFirstCellAsLabel
= true;
619 bHasCateories
= true;
622 uno::Sequence
< beans::PropertyValue
> aArgs( 3 );
623 aArgs
[0] = beans::PropertyValue(
624 ::rtl::OUString( "CellRangeRepresentation" ),
625 -1, uno::makeAny( rRectangularRange
),
626 beans::PropertyState_DIRECT_VALUE
);
627 aArgs
[1] = beans::PropertyValue(
628 ::rtl::OUString( "DataRowSource" ),
629 -1, uno::makeAny( eDataRowSource
),
630 beans::PropertyState_DIRECT_VALUE
);
631 aArgs
[2] = beans::PropertyValue(
632 ::rtl::OUString( "FirstCellAsLabel" ),
633 -1, uno::makeAny( bFirstCellAsLabel
),
634 beans::PropertyState_DIRECT_VALUE
);
636 if( !sColTrans
.isEmpty() || !sRowTrans
.isEmpty() )
638 aArgs
.realloc( aArgs
.getLength() + 1 );
639 aArgs
[ aArgs
.getLength() - 1 ] = beans::PropertyValue(
640 ::rtl::OUString( "SequenceMapping" ),
641 -1, uno::makeAny( !sColTrans
.isEmpty()
642 ? lcl_getNumberSequenceFromString( sColTrans
, bHasCateories
&& !xNewDoc
->hasInternalDataProvider() )
643 : lcl_getNumberSequenceFromString( sRowTrans
, bHasCateories
&& !xNewDoc
->hasInternalDataProvider() ) ),
644 beans::PropertyState_DIRECT_VALUE
);
647 //work around wrong writer ranges ( see Issue 58464 )
649 rtl::OUString aChartOleObjectName
;
650 uno::Reference
< frame::XModel
> xModel(xNewDoc
, uno::UNO_QUERY
);
653 comphelper::MediaDescriptor
aMediaDescriptor( xModel
->getArgs() );
655 comphelper::MediaDescriptor::const_iterator
aIt(
656 aMediaDescriptor
.find( rtl::OUString( "HierarchicalDocumentName" )));
657 if( aIt
!= aMediaDescriptor
.end() )
659 aChartOleObjectName
= (*aIt
).second
.get
< ::rtl::OUString
>();
662 if( !aChartOleObjectName
.isEmpty() )
664 aArgs
.realloc( aArgs
.getLength() + 1 );
665 aArgs
[ aArgs
.getLength() - 1 ] = beans::PropertyValue(
666 ::rtl::OUString( "ChartOleObjectName" ),
667 -1, uno::makeAny( aChartOleObjectName
),
668 beans::PropertyState_DIRECT_VALUE
);
673 uno::Reference
< chart2::data::XDataSource
> xDataSource(
674 xDataProvider
->createDataSource( aArgs
));
676 aArgs
.realloc( aArgs
.getLength() + 2 );
677 aArgs
[ aArgs
.getLength() - 2 ] = beans::PropertyValue(
678 ::rtl::OUString( "HasCategories" ),
679 -1, uno::makeAny( bHasCateories
),
680 beans::PropertyState_DIRECT_VALUE
);
681 aArgs
[ aArgs
.getLength() - 1 ] = beans::PropertyValue(
682 ::rtl::OUString("UseCategoriesAsX"),
683 -1, uno::makeAny( sal_False
),//categories in ODF files are not to be used as x values (independent from what is offered in our ui)
684 beans::PropertyState_DIRECT_VALUE
);
686 xNewDia
->setDiagramData( xDataSource
, aArgs
);
689 void SchXMLChartContext::EndElement()
691 uno::Reference
< chart::XChartDocument
> xDoc
= mrImportHelper
.GetChartDocument();
692 uno::Reference
< beans::XPropertySet
> xProp( xDoc
, uno::UNO_QUERY
);
693 uno::Reference
< chart2::XChartDocument
> xNewDoc( xDoc
, uno::UNO_QUERY
);
697 if( !maMainTitle
.isEmpty())
699 uno::Reference
< beans::XPropertySet
> xTitleProp( xDoc
->getTitle(), uno::UNO_QUERY
);
705 aAny
<<= maMainTitle
;
706 xTitleProp
->setPropertyValue( rtl::OUString( "String" ), aAny
);
708 catch(const beans::UnknownPropertyException
&)
710 OSL_FAIL( "Property String for Title not available" );
714 if( !maSubTitle
.isEmpty())
716 uno::Reference
< beans::XPropertySet
> xTitleProp( xDoc
->getSubTitle(), uno::UNO_QUERY
);
723 xTitleProp
->setPropertyValue( rtl::OUString( "String" ), aAny
);
725 catch(const beans::UnknownPropertyException
&)
727 OSL_FAIL( "Property String for Title not available" );
733 // cleanup: remove empty chart type groups
734 lcl_removeEmptyChartTypeGroups( xNewDoc
);
736 // set stack mode before a potential chart type detection (in case we have a rectangular range)
737 uno::Reference
< chart::XDiagram
> xDiagram( xDoc
->getDiagram() );
738 uno::Reference
< beans::XPropertySet
> xDiaProp( xDiagram
, uno::UNO_QUERY
);
741 if( maSeriesDefaultsAndStyles
.maStackedDefault
.hasValue())
742 xDiaProp
->setPropertyValue(::rtl::OUString("Stacked"),maSeriesDefaultsAndStyles
.maStackedDefault
);
743 if( maSeriesDefaultsAndStyles
.maPercentDefault
.hasValue())
744 xDiaProp
->setPropertyValue(::rtl::OUString("Percent"),maSeriesDefaultsAndStyles
.maPercentDefault
);
745 if( maSeriesDefaultsAndStyles
.maDeepDefault
.hasValue())
746 xDiaProp
->setPropertyValue(::rtl::OUString("Deep"),maSeriesDefaultsAndStyles
.maDeepDefault
);
747 if( maSeriesDefaultsAndStyles
.maStackedBarsConnectedDefault
.hasValue())
748 xDiaProp
->setPropertyValue(::rtl::OUString("StackedBarsConnected"),maSeriesDefaultsAndStyles
.maStackedBarsConnectedDefault
);
751 //the OOo 2.0 implementation and older has a bug with donuts
752 bool bSpecialHandlingForDonutChart
= lcl_SpecialHandlingForDonutChartNeeded(
753 maChartTypeServiceName
, GetImport());
759 bool bHasOwnData
= false;
760 if( m_aXLinkHRefAttributeToIndicateDataProvider
== "." ) //data comes from the chart itself
762 else if( m_aXLinkHRefAttributeToIndicateDataProvider
== ".." ) //data comes from the parent application
764 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
765 bHasOwnData
= m_bHasTableElement
;
767 bHasOwnData
= !m_bHasRangeAtPlotArea
;
769 if( xNewDoc
->hasInternalDataProvider())
771 if( !m_bHasTableElement
&& m_aXLinkHRefAttributeToIndicateDataProvider
!= "." )
773 //#i103147# ODF, workaround broken files with a missing table:cell-range-address at the plot-area
774 bool bSwitchSuccessful
= SchXMLTools::switchBackToDataProviderFromParent( xNewDoc
, maLSequencesPerIndex
);
775 bHasOwnData
= !bSwitchSuccessful
;
778 bHasOwnData
= true;//e.g. in case of copy->paste from calc to impress
780 else if( bHasOwnData
)
782 xNewDoc
->createInternalDataProvider( sal_False
/* bCloneExistingData */ );
785 msChartAddress
= ::rtl::OUString( "all" );
787 bool bSwitchRangesFromOuterToInternalIfNecessary
= false;
788 if( !bHasOwnData
&& mbAllRangeAddressesAvailable
)
790 // special handling for stock chart (merge series together)
792 MergeSeriesForStockChart();
794 else if( !msChartAddress
.isEmpty() )
796 //own data or only rectangular range available
798 if( xNewDoc
->hasInternalDataProvider() )
799 SchXMLTableHelper::applyTableToInternalDataProvider( maTable
, xNewDoc
);
801 bool bOlderThan2_3
= SchXMLTools::isDocumentGeneratedWithOpenOfficeOlderThan2_3( Reference
< frame::XModel
>( xNewDoc
, uno::UNO_QUERY
));
802 bool bOldFileWithOwnDataFromRows
= (bOlderThan2_3
&& bHasOwnData
&& (meDataRowSource
==chart::ChartDataRowSource_ROWS
)); // in this case there are range addresses that are simply wrong.
804 if( mbAllRangeAddressesAvailable
&& !bSpecialHandlingForDonutChart
&& !mbIsStockChart
&&
805 !bOldFileWithOwnDataFromRows
)
807 //bHasOwnData is true in this case!
808 //e.g. for normal files with own data or also in case of copy paste scenario (e.g. calc to impress)
809 bSwitchRangesFromOuterToInternalIfNecessary
= true;
813 //apply data from rectangular range
815 // create datasource from data provider with rectangular range parameters and change the diagram setDiagramData
818 if( bOlderThan2_3
&& xDiaProp
.is() )//for older charts the hidden cells were removed by calc on the fly
819 xDiaProp
->setPropertyValue(::rtl::OUString("IncludeHiddenCells"),uno::makeAny(false));
821 // note: mbRowHasLabels means the first row contains labels, that means we have "column-descriptions",
822 // (analogously mbColHasLabels means we have "row-descriptions")
823 lcl_ApplyDataFromRectangularRangeToDiagram( xNewDoc
, msChartAddress
, meDataRowSource
, mbRowHasLabels
, mbColHasLabels
, bHasOwnData
, msColTrans
, msRowTrans
);
825 catch(const uno::Exception
&)
827 //try to fallback to internal data
828 OSL_FAIL( "Exception during import SchXMLChartContext::lcl_ApplyDataFromRectangularRangeToDiagram try to fallback to internal data" );
832 msChartAddress
= ::rtl::OUString( "all" );
833 if( !xNewDoc
->hasInternalDataProvider() )
835 xNewDoc
->createInternalDataProvider( sal_False
/* bCloneExistingData */ );
836 SchXMLTableHelper::applyTableToInternalDataProvider( maTable
, xNewDoc
);
839 lcl_ApplyDataFromRectangularRangeToDiagram( xNewDoc
, msChartAddress
, meDataRowSource
, mbRowHasLabels
, mbColHasLabels
, bHasOwnData
, msColTrans
, msRowTrans
);
841 catch(const uno::Exception
&)
843 OSL_FAIL( "Exception during import SchXMLChartContext::lcl_ApplyDataFromRectangularRangeToDiagram fallback to internal data failed also" );
852 OSL_FAIL( " Must not get here" );
855 // now all series and data point properties are available and can be set
857 if( bSpecialHandlingForDonutChart
)
859 uno::Reference
< chart2::XDiagram
> xNewDiagram( xNewDoc
->getFirstDiagram() );
860 lcl_swapPointAndSeriesStylesForDonutCharts( maSeriesDefaultsAndStyles
.maSeriesStyleList
861 , SchXMLSeriesHelper::getDataSeriesIndexMapFromDiagram(xNewDiagram
) );
864 SchXMLSeries2Context::initSeriesPropertySets( maSeriesDefaultsAndStyles
, uno::Reference
< frame::XModel
>(xDoc
, uno::UNO_QUERY
) );
866 //set defaults from diagram to the new series:
867 //check whether we need to remove lines from symbol only charts
868 bool bSwitchOffLinesForScatter
= false;
870 bool bLinesOn
= true;
871 if( (maSeriesDefaultsAndStyles
.maLinesOnProperty
>>= bLinesOn
) && !bLinesOn
)
873 if( 0 == maChartTypeServiceName
.reverseCompareToAsciiL( RTL_CONSTASCII_STRINGPARAM( "com.sun.star.chart2.ScatterChartType" ) ) )
875 bSwitchOffLinesForScatter
= true;
876 SchXMLSeries2Context::switchSeriesLinesOff( maSeriesDefaultsAndStyles
.maSeriesStyleList
);
880 SchXMLSeries2Context::setDefaultsToSeries( maSeriesDefaultsAndStyles
);
882 // set autostyles for series and data points
883 const SvXMLStylesContext
* pStylesCtxt
= mrImportHelper
.GetAutoStylesContext();
884 const SvXMLStyleContext
* pStyle
= NULL
;
885 ::rtl::OUString sCurrStyleName
;
889 //iterate over data-series first
890 //don't set series styles for donut charts
891 if( !bSpecialHandlingForDonutChart
)
893 SchXMLSeries2Context::setStylesToSeries( maSeriesDefaultsAndStyles
894 , pStylesCtxt
, pStyle
, sCurrStyleName
, mrImportHelper
, GetImport(), mbIsStockChart
, maLSequencesPerIndex
);
895 // ... then set attributes for statistics (after their existence was set in the series)
896 SchXMLSeries2Context::setStylesToStatisticsObjects( maSeriesDefaultsAndStyles
897 , pStylesCtxt
, pStyle
, sCurrStyleName
);
901 //#i98319# call switchRangesFromOuterToInternalIfNecessary before the data point styles are applied, otherwise in copy->paste scenario the data point styles do get lost
902 if( bSwitchRangesFromOuterToInternalIfNecessary
)
904 if( xNewDoc
->hasInternalDataProvider() )
905 SchXMLTableHelper::switchRangesFromOuterToInternalIfNecessary( maTable
, maLSequencesPerIndex
, xNewDoc
, meDataRowSource
);
910 // ... then iterate over data-point attributes, so the latter are not overwritten
911 SchXMLSeries2Context::setStylesToDataPoints( maSeriesDefaultsAndStyles
912 , pStylesCtxt
, pStyle
, sCurrStyleName
, mrImportHelper
, GetImport(), mbIsStockChart
, bSpecialHandlingForDonutChart
, bSwitchOffLinesForScatter
);
917 xProp
->setPropertyValue( rtl::OUString( "RefreshAddInAllowed" ) , uno::makeAny( sal_True
) );
920 void SchXMLChartContext::MergeSeriesForStockChart()
922 OSL_ASSERT( mbIsStockChart
);
925 uno::Reference
< chart::XChartDocument
> xOldDoc( mrImportHelper
.GetChartDocument());
926 uno::Reference
< chart2::XChartDocument
> xDoc( xOldDoc
, uno::UNO_QUERY_THROW
);
927 uno::Reference
< chart2::XDiagram
> xDiagram( xDoc
->getFirstDiagram());
931 bool bHasJapaneseCandlestick
= true;
932 uno::Reference
< chart2::XDataSeriesContainer
> xDSContainer
;
933 uno::Reference
< chart2::XCoordinateSystemContainer
> xCooSysCnt( xDiagram
, uno::UNO_QUERY_THROW
);
934 uno::Sequence
< uno::Reference
< chart2::XCoordinateSystem
> > aCooSysSeq( xCooSysCnt
->getCoordinateSystems());
935 for( sal_Int32 nCooSysIdx
=0; nCooSysIdx
<aCooSysSeq
.getLength(); ++nCooSysIdx
)
937 uno::Reference
< chart2::XChartTypeContainer
> xCTCnt( aCooSysSeq
[nCooSysIdx
], uno::UNO_QUERY_THROW
);
938 uno::Sequence
< uno::Reference
< chart2::XChartType
> > aChartTypes( xCTCnt
->getChartTypes());
939 for( sal_Int32 nCTIdx
=0; nCTIdx
<aChartTypes
.getLength(); ++nCTIdx
)
941 if( aChartTypes
[nCTIdx
]->getChartType() == "com.sun.star.chart2.CandleStickChartType" )
943 xDSContainer
.set( aChartTypes
[nCTIdx
], uno::UNO_QUERY_THROW
);
944 uno::Reference
< beans::XPropertySet
> xCTProp( aChartTypes
[nCTIdx
], uno::UNO_QUERY_THROW
);
945 xCTProp
->getPropertyValue( ::rtl::OUString( "Japanese" )) >>= bHasJapaneseCandlestick
;
951 if( xDSContainer
.is())
953 // with japanese candlesticks: open, low, high, close
954 // otherwise: low, high, close
955 uno::Sequence
< uno::Reference
< chart2::XDataSeries
> > aSeriesSeq( xDSContainer
->getDataSeries());
956 const sal_Int32
nSeriesCount( aSeriesSeq
.getLength());
957 const sal_Int32 nSeriesPerCandleStick
= bHasJapaneseCandlestick
? 4: 3;
958 sal_Int32 nCandleStickCount
= nSeriesCount
/ nSeriesPerCandleStick
;
959 OSL_ASSERT( nSeriesPerCandleStick
* nCandleStickCount
== nSeriesCount
);
960 uno::Sequence
< uno::Reference
< chart2::XDataSeries
> > aNewSeries( nCandleStickCount
);
961 for( sal_Int32 i
=0; i
<nCandleStickCount
; ++i
)
963 sal_Int32 nSeriesIndex
= i
*nSeriesPerCandleStick
;
964 if( bHasJapaneseCandlestick
)
967 lcl_setRoleAtFirstSequence( aSeriesSeq
[ nSeriesIndex
], OUString( "values-first" ));
968 aNewSeries
[i
] = aSeriesSeq
[ nSeriesIndex
];
970 lcl_MoveDataToCandleStickSeries(
971 uno::Reference
< chart2::data::XDataSource
>( aSeriesSeq
[ ++nSeriesIndex
], uno::UNO_QUERY_THROW
),
972 aNewSeries
[i
], OUString( "values-min" ));
977 lcl_setRoleAtFirstSequence( aSeriesSeq
[ nSeriesIndex
], OUString( "values-min" ));
978 aNewSeries
[i
] = aSeriesSeq
[ nSeriesIndex
];
981 lcl_MoveDataToCandleStickSeries(
982 uno::Reference
< chart2::data::XDataSource
>( aSeriesSeq
[ ++nSeriesIndex
], uno::UNO_QUERY_THROW
),
983 aNewSeries
[i
], OUString( "values-max" ));
985 lcl_MoveDataToCandleStickSeries(
986 uno::Reference
< chart2::data::XDataSource
>( aSeriesSeq
[ ++nSeriesIndex
], uno::UNO_QUERY_THROW
),
987 aNewSeries
[i
], OUString( "values-last" ));
989 xDSContainer
->setDataSeries( aNewSeries
);
992 catch(const uno::Exception
&)
994 OSL_FAIL( "Exception while merging series for stock chart" );
998 SvXMLImportContext
* SchXMLChartContext::CreateChildContext(
1000 const rtl::OUString
& rLocalName
,
1001 const uno::Reference
< xml::sax::XAttributeList
>& xAttrList
)
1003 static const sal_Bool bTrue
= sal_True
;
1004 static const uno::Any
aTrueBool( &bTrue
, ::getBooleanCppuType());
1006 SvXMLImportContext
* pContext
= 0;
1007 const SvXMLTokenMap
& rTokenMap
= mrImportHelper
.GetChartElemTokenMap();
1008 uno::Reference
< chart::XChartDocument
> xDoc
= mrImportHelper
.GetChartDocument();
1009 uno::Reference
< beans::XPropertySet
> xProp( xDoc
, uno::UNO_QUERY
);
1011 switch( rTokenMap
.Get( nPrefix
, rLocalName
))
1013 case XML_TOK_CHART_PLOT_AREA
:
1014 pContext
= new SchXMLPlotAreaContext( mrImportHelper
, GetImport(), rLocalName
,
1015 m_aXLinkHRefAttributeToIndicateDataProvider
,
1016 maSeriesAddresses
, msCategoriesAddress
,
1017 msChartAddress
, m_bHasRangeAtPlotArea
, mbAllRangeAddressesAvailable
,
1018 mbColHasLabels
, mbRowHasLabels
,
1020 maSeriesDefaultsAndStyles
,
1021 maChartTypeServiceName
,
1022 maLSequencesPerIndex
, maChartSize
);
1025 case XML_TOK_CHART_TITLE
:
1030 xProp
->setPropertyValue( rtl::OUString( "HasMainTitle" ), aTrueBool
);
1032 uno::Reference
< drawing::XShape
> xTitleShape( xDoc
->getTitle(), uno::UNO_QUERY
);
1033 pContext
= new SchXMLTitleContext( mrImportHelper
, GetImport(),
1034 rLocalName
, maMainTitle
, xTitleShape
);
1038 case XML_TOK_CHART_SUBTITLE
:
1043 xProp
->setPropertyValue( rtl::OUString( "HasSubTitle" ), aTrueBool
);
1045 uno::Reference
< drawing::XShape
> xTitleShape( xDoc
->getSubTitle(), uno::UNO_QUERY
);
1046 pContext
= new SchXMLTitleContext( mrImportHelper
, GetImport(),
1047 rLocalName
, maSubTitle
, xTitleShape
);
1051 case XML_TOK_CHART_LEGEND
:
1052 pContext
= new SchXMLLegendContext( mrImportHelper
, GetImport(), rLocalName
);
1055 case XML_TOK_CHART_TABLE
:
1057 SchXMLTableContext
* pTableContext
=
1058 new SchXMLTableContext( mrImportHelper
, GetImport(), rLocalName
, maTable
);
1059 m_bHasTableElement
= true;
1060 // #i85913# take into account column- and row- mapping for
1061 // charts with own data only for those which were not copied
1062 // from a place where they got data from the container. Note,
1063 // that this requires the plot-area been read before the table
1064 // (which is required in the ODF spec)
1065 // Note: For stock charts and donut charts with special handling
1066 // the mapping must not be applied!
1067 if( msChartAddress
.isEmpty() && !mbIsStockChart
&&
1068 !lcl_SpecialHandlingForDonutChartNeeded(
1069 maChartTypeServiceName
, GetImport()))
1071 if( !msColTrans
.isEmpty() )
1073 OSL_ASSERT( msRowTrans
.isEmpty() );
1074 pTableContext
->setColumnPermutation( lcl_getNumberSequenceFromString( msColTrans
, true ));
1075 msColTrans
= OUString();
1077 else if( !msRowTrans
.isEmpty() )
1079 pTableContext
->setRowPermutation( lcl_getNumberSequenceFromString( msRowTrans
, true ));
1080 msRowTrans
= OUString();
1083 pContext
= pTableContext
;
1088 // try importing as an additional shape
1089 if( ! mxDrawPage
.is())
1091 uno::Reference
< drawing::XDrawPageSupplier
> xSupp( xDoc
, uno::UNO_QUERY
);
1093 mxDrawPage
= uno::Reference
< drawing::XShapes
>( xSupp
->getDrawPage(), uno::UNO_QUERY
);
1095 DBG_ASSERT( mxDrawPage
.is(), "Invalid Chart Page" );
1097 if( mxDrawPage
.is())
1098 pContext
= GetImport().GetShapeImport()->CreateGroupChildContext(
1099 GetImport(), nPrefix
, rLocalName
, xAttrList
, mxDrawPage
);
1104 pContext
= new SvXMLImportContext( GetImport(), nPrefix
, rLocalName
);
1111 With a locked controller the following is done here:
1112 1. Hide title, subtitle, and legend.
1113 2. Set the size of the draw page.
1114 3. Set a (logically) empty data set.
1115 4. Set the chart type.
1117 void SchXMLChartContext::InitChart(
1118 const OUString
& rChartTypeServiceName
, // currently the old service name
1119 sal_Bool
/* bSetSwitchData */ )
1121 uno::Reference
< chart::XChartDocument
> xDoc
= mrImportHelper
.GetChartDocument();
1122 DBG_ASSERT( xDoc
.is(), "No valid document!" );
1123 uno::Reference
< frame::XModel
> xModel (xDoc
, uno::UNO_QUERY
);
1125 // Remove Title and Diagram ("De-InitNew")
1126 uno::Reference
< chart2::XChartDocument
> xNewDoc( mrImportHelper
.GetChartDocument(), uno::UNO_QUERY
);
1129 xNewDoc
->setFirstDiagram( 0 );
1130 uno::Reference
< chart2::XTitled
> xTitled( xNewDoc
, uno::UNO_QUERY
);
1132 xTitled
->setTitleObject( 0 );
1135 // Set the chart type via setting the diagram.
1136 if( !rChartTypeServiceName
.isEmpty() && xDoc
.is())
1138 uno::Reference
< lang::XMultiServiceFactory
> xFact( xDoc
, uno::UNO_QUERY
);
1141 uno::Reference
< chart::XDiagram
> xDia( xFact
->createInstance( rChartTypeServiceName
), uno::UNO_QUERY
);
1143 xDoc
->setDiagram( xDia
);
1148 // ----------------------------------------
1150 SchXMLTitleContext::SchXMLTitleContext( SchXMLImportHelper
& rImpHelper
, SvXMLImport
& rImport
,
1151 const rtl::OUString
& rLocalName
,
1152 rtl::OUString
& rTitle
,
1153 uno::Reference
< drawing::XShape
>& xTitleShape
) :
1154 SvXMLImportContext( rImport
, XML_NAMESPACE_CHART
, rLocalName
),
1155 mrImportHelper( rImpHelper
),
1157 mxTitleShape( xTitleShape
)
1161 SchXMLTitleContext::~SchXMLTitleContext()
1164 void SchXMLTitleContext::StartElement( const uno::Reference
< xml::sax::XAttributeList
>& xAttrList
)
1166 sal_Int16 nAttrCount
= xAttrList
.is()? xAttrList
->getLength(): 0;
1168 com::sun::star::awt::Point maPosition
;
1169 bool bHasXPosition
=false;
1170 bool bHasYPosition
=false;
1172 for( sal_Int16 i
= 0; i
< nAttrCount
; i
++ )
1174 rtl::OUString sAttrName
= xAttrList
->getNameByIndex( i
);
1175 rtl::OUString aLocalName
;
1176 rtl::OUString aValue
= xAttrList
->getValueByIndex( i
);
1177 sal_uInt16 nPrefix
= GetImport().GetNamespaceMap().GetKeyByAttrName( sAttrName
, &aLocalName
);
1179 if( nPrefix
== XML_NAMESPACE_SVG
)
1181 if( IsXMLToken( aLocalName
, XML_X
) )
1183 GetImport().GetMM100UnitConverter().convertMeasureToCore(
1184 maPosition
.X
, aValue
);
1185 bHasXPosition
= true;
1187 else if( IsXMLToken( aLocalName
, XML_Y
) )
1189 GetImport().GetMM100UnitConverter().convertMeasureToCore(
1190 maPosition
.Y
, aValue
);
1191 bHasYPosition
= true;
1194 else if( nPrefix
== XML_NAMESPACE_CHART
)
1196 if( IsXMLToken( aLocalName
, XML_STYLE_NAME
) )
1197 msAutoStyleName
= aValue
;
1202 if( mxTitleShape
.is())
1204 if( bHasXPosition
&& bHasYPosition
)
1205 mxTitleShape
->setPosition( maPosition
);
1207 uno::Reference
< beans::XPropertySet
> xProp( mxTitleShape
, uno::UNO_QUERY
);
1210 const SvXMLStylesContext
* pStylesCtxt
= mrImportHelper
.GetAutoStylesContext();
1213 const SvXMLStyleContext
* pStyle
= pStylesCtxt
->FindStyleChildContext(
1214 mrImportHelper
.GetChartFamilyID(), msAutoStyleName
);
1216 if( pStyle
&& pStyle
->ISA( XMLPropStyleContext
))
1217 (( XMLPropStyleContext
* )pStyle
)->FillPropertySet( xProp
);
1223 SvXMLImportContext
* SchXMLTitleContext::CreateChildContext(
1225 const rtl::OUString
& rLocalName
,
1226 const uno::Reference
< xml::sax::XAttributeList
>& )
1228 SvXMLImportContext
* pContext
= 0;
1230 if( nPrefix
== XML_NAMESPACE_TEXT
&&
1231 IsXMLToken( rLocalName
, XML_P
) )
1233 pContext
= new SchXMLParagraphContext( GetImport(), rLocalName
, mrTitle
);
1236 pContext
= new SvXMLImportContext( GetImport(), nPrefix
, rLocalName
);
1241 // ----------------------------------------
1244 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */