1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: SchXMLTools.cxx,v $
12 * This file is part of OpenOffice.org.
14 * OpenOffice.org is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU Lesser General Public License version 3
16 * only, as published by the Free Software Foundation.
18 * OpenOffice.org is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Lesser General Public License version 3 for more details
22 * (a copy is included in the LICENSE file that accompanied this code).
24 * You should have received a copy of the GNU Lesser General Public License
25 * version 3 along with OpenOffice.org. If not, see
26 * <http://www.openoffice.org/license.html>
27 * for a copy of the LGPLv3 License.
29 ************************************************************************/
31 // MARKER(update_precomp.py): autogen include statement, do not remove
32 #include "precompiled_xmloff.hxx"
34 #include "SchXMLTools.hxx"
37 #include <tools/debug.hxx>
39 #include <rtl/ustrbuf.hxx>
40 #include <comphelper/InlineContainer.hxx>
41 // header for class SvXMLUnitConverter
42 #include <xmloff/xmluconv.hxx>
43 // header for struct SvXMLEnumMapEntry
44 #include <xmloff/xmlement.hxx>
45 // header for define __FAR_DATA
46 #include <tools/solar.h>
48 // header for class SvXMLImportPropertyMapper
49 #include <xmloff/xmlimppr.hxx>
50 // header for class XMLPropStyleContext
51 #include <xmloff/prstylei.hxx>
52 // header for class XMLPropertySetMapper
53 #include <xmloff/xmlprmap.hxx>
54 #include <xmloff/xmlexp.hxx>
55 #include "xmlnmspe.hxx"
56 #include <xmloff/xmlmetai.hxx>
58 #include <com/sun/star/beans/PropertyAttribute.hpp>
59 #include <com/sun/star/uno/XComponentContext.hpp>
60 #include <com/sun/star/chart2/data/XDataProvider.hpp>
61 #include <com/sun/star/chart2/data/XDataReceiver.hpp>
62 #include <com/sun/star/chart2/data/XRangeXMLConversion.hpp>
63 #include <com/sun/star/chart2/XChartDocument.hpp>
64 #include <com/sun/star/chart2/XCoordinateSystemContainer.hpp>
65 #include <com/sun/star/chart2/XRegressionCurveContainer.hpp>
66 #include <com/sun/star/container/XChild.hpp>
67 #include <com/sun/star/document/XDocumentProperties.hpp>
68 #include <com/sun/star/document/XDocumentPropertiesSupplier.hpp>
69 #include <com/sun/star/lang/XServiceName.hpp>
71 #include <comphelper/processfactory.hxx>
73 using namespace com::sun::star
;
74 using namespace ::xmloff::token
;
76 using ::rtl::OUString
;
77 using ::rtl::OUStringBuffer
;
78 using ::com::sun::star::uno::Reference
;
79 using ::com::sun::star::uno::Sequence
;
83 Reference
< uno::XComponentContext
> lcl_getComponentContext()
85 Reference
< uno::XComponentContext
> xContext
;
88 Reference
< beans::XPropertySet
> xFactProp( comphelper::getProcessServiceFactory(), uno::UNO_QUERY
);
90 xFactProp
->getPropertyValue(OUString::createFromAscii("DefaultContext")) >>= xContext
;
92 catch( uno::Exception
& )
98 rtl::OUString
lcl_getGeneratorFromModel( const uno::Reference
< frame::XModel
>& xChartModel
)
100 ::rtl::OUString aGenerator
;
101 uno::Reference
< document::XDocumentPropertiesSupplier
> xChartDocumentPropertiesSupplier( xChartModel
, uno::UNO_QUERY
);
102 if( xChartDocumentPropertiesSupplier
.is() )
104 uno::Reference
< document::XDocumentProperties
> xChartDocumentProperties(
105 xChartDocumentPropertiesSupplier
->getDocumentProperties());
106 if( xChartDocumentProperties
.is() )
107 aGenerator
= xChartDocumentProperties
->getGenerator();
112 rtl::OUString
lcl_getGeneratorFromModelOrItsParent( const uno::Reference
< frame::XModel
>& xChartModel
)
114 ::rtl::OUString
aGenerator( lcl_getGeneratorFromModel(xChartModel
) );
115 if( !aGenerator
.getLength() ) //try to get the missing info from the parent document
117 uno::Reference
< container::XChild
> xChild( xChartModel
, uno::UNO_QUERY
);
119 aGenerator
= lcl_getGeneratorFromModel( uno::Reference
< frame::XModel
>( xChild
->getParent(), uno::UNO_QUERY
) );
124 sal_Int32
lcl_getBuildIDFromGenerator( const ::rtl::OUString
& rGenerator
)
126 //returns -1 if nothing found
127 sal_Int32 nBuildId
= -1;
128 const OUString
sBuildCompare( RTL_CONSTASCII_USTRINGPARAM( "$Build-" ) );
130 sal_Int32 nBegin
= rGenerator
.indexOf( sBuildCompare
, nEnd
);
133 OUString
sBuildId( rGenerator
.copy( nBegin
+ sBuildCompare
.getLength() ) );
134 nBuildId
= sBuildId
.toInt32();
139 Reference
< chart2::data::XDataSequence
> lcl_createNewSequenceFromCachedXMLRange( const Reference
< chart2::data::XDataSequence
>& xSeq
, const Reference
< chart2::data::XDataProvider
>& xDataProvider
)
141 Reference
< chart2::data::XDataSequence
> xRet
;
143 Reference
< chart2::data::XRangeXMLConversion
> xRangeConversion( xDataProvider
, uno::UNO_QUERY
);
144 if( xRangeConversion
.is() )
146 if( xSeq
.is() && SchXMLTools::getXMLRangePropertyFromDataSequence( xSeq
, aRange
, /* bClearProp = */ true ) )
148 xRet
.set( xDataProvider
->createDataSequenceByRangeRepresentation(
149 xRangeConversion
->convertRangeFromXML( aRange
)) );
150 SchXMLTools::copyProperties( Reference
< beans::XPropertySet
>( xSeq
, uno::UNO_QUERY
),
151 Reference
< beans::XPropertySet
>( xRet
, uno::UNO_QUERY
));
157 } // anonymous namespace
159 // ----------------------------------------
161 namespace SchXMLTools
164 static __FAR_DATA SvXMLEnumMapEntry aXMLChartClassMap
[] =
166 { XML_LINE
, XML_CHART_CLASS_LINE
},
167 { XML_AREA
, XML_CHART_CLASS_AREA
},
168 { XML_CIRCLE
, XML_CHART_CLASS_CIRCLE
},
169 { XML_RING
, XML_CHART_CLASS_RING
},
170 { XML_SCATTER
, XML_CHART_CLASS_SCATTER
},
171 { XML_RADAR
, XML_CHART_CLASS_RADAR
},
172 { XML_FILLED_RADAR
, XML_CHART_CLASS_FILLED_RADAR
},
173 { XML_BAR
, XML_CHART_CLASS_BAR
},
174 { XML_STOCK
, XML_CHART_CLASS_STOCK
},
175 { XML_BUBBLE
, XML_CHART_CLASS_BUBBLE
},
176 { XML_ADD_IN
, XML_CHART_CLASS_ADDIN
},
177 { XML_TOKEN_INVALID
, XML_CHART_CLASS_UNKNOWN
}
180 SchXMLChartTypeEnum
GetChartTypeEnum( const OUString
& rClassName
)
182 USHORT nEnumVal
= XML_CHART_CLASS_UNKNOWN
;
183 if( !SvXMLUnitConverter::convertEnum(
184 nEnumVal
, rClassName
, aXMLChartClassMap
) )
185 nEnumVal
= XML_CHART_CLASS_UNKNOWN
;
186 return SchXMLChartTypeEnum(nEnumVal
);
189 typedef ::comphelper::MakeMap
< ::rtl::OUString
, ::rtl::OUString
> tMakeStringStringMap
;
191 const tMakeStringStringMap
& lcl_getChartTypeNameMap()
193 //shape property -- chart model object property
194 static tMakeStringStringMap g_aChartTypeNameMap
=
196 ( ::rtl::OUString::createFromAscii( "com.sun.star.chart.LineDiagram" )
197 , ::rtl::OUString::createFromAscii( "com.sun.star.chart2.LineChartType" ) )
199 ( ::rtl::OUString::createFromAscii( "com.sun.star.chart.AreaDiagram" )
200 , ::rtl::OUString::createFromAscii( "com.sun.star.chart2.AreaChartType" ) )
202 ( ::rtl::OUString::createFromAscii( "com.sun.star.chart.BarDiagram" )
203 , ::rtl::OUString::createFromAscii( "com.sun.star.chart2.ColumnChartType" ) )
205 ( ::rtl::OUString::createFromAscii( "com.sun.star.chart.PieDiagram" )
206 , ::rtl::OUString::createFromAscii( "com.sun.star.chart2.PieChartType" ) )
208 ( ::rtl::OUString::createFromAscii( "com.sun.star.chart.DonutDiagram" )
209 , ::rtl::OUString::createFromAscii( "com.sun.star.chart2.DonutChartType" ) )
211 ( ::rtl::OUString::createFromAscii( "com.sun.star.chart.XYDiagram" )
212 , ::rtl::OUString::createFromAscii( "com.sun.star.chart2.ScatterChartType" ) )
214 ( ::rtl::OUString::createFromAscii( "com.sun.star.chart.NetDiagram" )
215 , ::rtl::OUString::createFromAscii( "com.sun.star.chart2.NetChartType" ) )
217 ( ::rtl::OUString::createFromAscii( "com.sun.star.chart.FilledNetDiagram" )
218 , ::rtl::OUString::createFromAscii( "com.sun.star.chart2.FilledNetChartType" ) )
220 ( ::rtl::OUString::createFromAscii( "com.sun.star.chart.StockDiagram" )
221 , ::rtl::OUString::createFromAscii( "com.sun.star.chart2.CandleStickChartType" ) )
223 ( ::rtl::OUString::createFromAscii( "com.sun.star.chart.BubbleDiagram" )
224 , ::rtl::OUString::createFromAscii( "com.sun.star.chart2.BubbleChartType" ) )
227 return g_aChartTypeNameMap
;
231 OUString
GetNewChartTypeName( const OUString
& rOldChartTypeName
)
233 OUString
aNew(rOldChartTypeName
);
235 const tMakeStringStringMap
& rMap
= lcl_getChartTypeNameMap();
236 tMakeStringStringMap::const_iterator
aIt( rMap
.find( rOldChartTypeName
));
237 if( aIt
!= rMap
.end())
244 OUString
GetChartTypeByClassName(
245 const OUString
& rClassName
, bool bUseOldNames
)
247 OUStringBuffer aResultBuffer
;
248 bool bInternalType
= false;
251 aResultBuffer
.appendAscii( RTL_CONSTASCII_STRINGPARAM("com.sun.star.chart."));
253 aResultBuffer
.appendAscii( RTL_CONSTASCII_STRINGPARAM("com.sun.star.chart2."));
255 bInternalType
= true;
257 if( IsXMLToken( rClassName
, XML_LINE
))
258 aResultBuffer
.appendAscii( RTL_CONSTASCII_STRINGPARAM("Line"));
259 else if( IsXMLToken( rClassName
, XML_AREA
))
260 aResultBuffer
.appendAscii( RTL_CONSTASCII_STRINGPARAM("Area"));
261 else if( IsXMLToken( rClassName
, XML_BAR
))
264 aResultBuffer
.appendAscii( RTL_CONSTASCII_STRINGPARAM("Bar"));
267 aResultBuffer
.appendAscii( RTL_CONSTASCII_STRINGPARAM("Column"));
268 // @todo: might be Bar
271 else if( IsXMLToken( rClassName
, XML_CIRCLE
))
272 aResultBuffer
.appendAscii( RTL_CONSTASCII_STRINGPARAM("Pie"));
273 else if( IsXMLToken( rClassName
, XML_RING
))
274 aResultBuffer
.appendAscii( RTL_CONSTASCII_STRINGPARAM("Donut"));
275 else if( IsXMLToken( rClassName
, XML_SCATTER
))
278 aResultBuffer
.appendAscii( RTL_CONSTASCII_STRINGPARAM("XY"));
280 aResultBuffer
.appendAscii( RTL_CONSTASCII_STRINGPARAM("Scatter"));
283 else if( IsXMLToken( rClassName
, XML_BUBBLE
))
284 aResultBuffer
.appendAscii( RTL_CONSTASCII_STRINGPARAM("Bubble"));
285 else if( IsXMLToken( rClassName
, XML_RADAR
))
286 aResultBuffer
.appendAscii( RTL_CONSTASCII_STRINGPARAM("Net"));
287 else if( IsXMLToken( rClassName
, XML_FILLED_RADAR
))
288 aResultBuffer
.appendAscii( RTL_CONSTASCII_STRINGPARAM("FilledNet"));
289 else if( IsXMLToken( rClassName
, XML_STOCK
))
292 aResultBuffer
.appendAscii( RTL_CONSTASCII_STRINGPARAM("Stock"));
294 aResultBuffer
.appendAscii( RTL_CONSTASCII_STRINGPARAM("CandleStick"));
297 bInternalType
= false;
299 if( ! bInternalType
)
303 aResultBuffer
.appendAscii( RTL_CONSTASCII_STRINGPARAM("Diagram"));
305 aResultBuffer
.appendAscii( RTL_CONSTASCII_STRINGPARAM("ChartType"));
307 return aResultBuffer
.makeStringAndClear();
311 XMLTokenEnum
getTokenByChartType(
312 const OUString
& rChartTypeService
, bool bUseOldNames
)
314 XMLTokenEnum eResult
= XML_TOKEN_INVALID
;
315 OUString aPrefix
, aPostfix
;
319 aPrefix
= OUString( RTL_CONSTASCII_USTRINGPARAM("com.sun.star.chart."));
320 aPostfix
= OUString( RTL_CONSTASCII_USTRINGPARAM("Diagram"));
324 aPrefix
= OUString( RTL_CONSTASCII_USTRINGPARAM("com.sun.star.chart2."));
325 aPostfix
= OUString( RTL_CONSTASCII_USTRINGPARAM("ChartType"));
328 if( rChartTypeService
.match( aPrefix
))
330 sal_Int32 nSkip
= aPrefix
.getLength();
331 OSL_ASSERT( rChartTypeService
.getLength() >= nSkip
);
332 sal_Int32 nTypeLength
= rChartTypeService
.getLength() - nSkip
- aPostfix
.getLength();
333 // if postfix matches and leaves a non-empty type
334 if( nTypeLength
> 0 && rChartTypeService
.match( aPostfix
, nSkip
+ nTypeLength
))
336 OUString
aServiceName( rChartTypeService
.copy( nSkip
, nTypeLength
));
338 if( aServiceName
.equalsAscii("Line"))
340 else if( aServiceName
.equalsAscii("Area"))
342 else if( aServiceName
.equalsAscii("Bar") ||
343 (!bUseOldNames
&& aServiceName
.equalsAscii("Column")))
345 else if( aServiceName
.equalsAscii("Pie"))
346 eResult
= XML_CIRCLE
;
347 else if( aServiceName
.equalsAscii("Donut"))
349 else if( (bUseOldNames
&& aServiceName
.equalsAscii("XY")) ||
350 (!bUseOldNames
&& aServiceName
.equalsAscii("Scatter")))
351 eResult
= XML_SCATTER
;
352 else if( aServiceName
.equalsAscii("Bubble"))
353 eResult
= XML_BUBBLE
;
354 else if( aServiceName
.equalsAscii("Net"))
356 else if( aServiceName
.equalsAscii("FilledNet"))
357 eResult
= XML_FILLED_RADAR
;
358 else if( (bUseOldNames
&& aServiceName
.equalsAscii("Stock")) ||
359 (!bUseOldNames
&& aServiceName
.equalsAscii("CandleStick")))
364 if( eResult
== XML_TOKEN_INVALID
&& rChartTypeService
.getLength() > 0 )
365 eResult
= XML_ADD_IN
;
370 Reference
< chart2::data::XLabeledDataSequence
> GetNewLabeledDataSequence()
372 Reference
< chart2::data::XLabeledDataSequence
> xResult
;
373 Reference
< uno::XComponentContext
> xContext( lcl_getComponentContext());
376 xContext
->getServiceManager()->createInstanceWithContext(
377 OUString::createFromAscii("com.sun.star.chart2.data.LabeledDataSequence"),
378 xContext
), uno::UNO_QUERY_THROW
);
382 void CreateCategories(
383 const uno::Reference
< chart2::data::XDataProvider
> & xDataProvider
,
384 const uno::Reference
< chart2::XChartDocument
> & xNewDoc
,
385 const OUString
& rRangeAddress
,
386 sal_Int32 nCooSysIndex
,
387 sal_Int32 nDimensionIndex
,
388 tSchXMLLSequencesPerIndex
* pLSequencesPerIndex
)
392 if( xNewDoc
.is() && rRangeAddress
.getLength())
394 if( xDataProvider
.is())
396 uno::Reference
< chart2::XDiagram
> xDia( xNewDoc
->getFirstDiagram());
400 uno::Reference
< chart2::XCoordinateSystemContainer
> xCooSysCnt( xDia
, uno::UNO_QUERY_THROW
);
401 uno::Sequence
< uno::Reference
< chart2::XCoordinateSystem
> >
402 aCooSysSeq( xCooSysCnt
->getCoordinateSystems());
403 if( nCooSysIndex
< aCooSysSeq
.getLength())
405 uno::Reference
< chart2::XCoordinateSystem
> xCooSys( aCooSysSeq
[nCooSysIndex
] );
406 OSL_ASSERT( xCooSys
.is());
407 if( nDimensionIndex
< xCooSys
->getDimension() )
409 const sal_Int32 nMaxAxisIndex
= xCooSys
->getMaximumAxisIndexByDimension(nDimensionIndex
);
410 for(sal_Int32 nI
=0; nI
<=nMaxAxisIndex
; ++nI
)
412 uno::Reference
< chart2::XAxis
> xAxis( xCooSys
->getAxisByDimension( nDimensionIndex
, nI
));
415 chart2::ScaleData
aData( xAxis
->getScaleData());
416 uno::Reference
< chart2::data::XLabeledDataSequence
> xLabeledSeq(
417 GetNewLabeledDataSequence());
420 OUString
aConvertedRange( rRangeAddress
);
421 bool bRangeConverted
= false;
422 if( ! (xNewDoc
->hasInternalDataProvider() &&
423 aConvertedRange
.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM("categories"))))
425 Reference
< chart2::data::XRangeXMLConversion
> xXMLConv( xDataProvider
, uno::UNO_QUERY
);
428 aConvertedRange
= xXMLConv
->convertRangeFromXML( rRangeAddress
);
429 bRangeConverted
= true;
432 Reference
< chart2::data::XDataSequence
> xSeq(
433 xDataProvider
->createDataSequenceByRangeRepresentation( aConvertedRange
));
434 xLabeledSeq
->setValues( xSeq
);
435 if( bRangeConverted
)
436 setXMLRangePropertyAtDataSequence( xSeq
, rRangeAddress
);
438 catch( const lang::IllegalArgumentException
& ex
)
440 (void)ex
; // avoid warning for pro build
441 OSL_ENSURE( false, ::rtl::OUStringToOString(
442 ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "IllegalArgumentException caught, Message: " )) +
443 ex
.Message
, RTL_TEXTENCODING_ASCII_US
).getStr());
445 aData
.Categories
.set( xLabeledSeq
);
446 if( pLSequencesPerIndex
)
448 // register for setting local data if external data provider is not present
449 pLSequencesPerIndex
->insert(
450 tSchXMLLSequencesPerIndex::value_type(
451 tSchXMLIndexWithPart( SCH_XML_CATEGORIES_INDEX
, SCH_XML_PART_VALUES
), xLabeledSeq
));
453 xAxis
->setScaleData( aData
);
461 catch( uno::Exception
& )
463 OSL_ENSURE( false, "Exception caught while creating Categories" );
468 uno::Any
getPropertyFromContext( const rtl::OUString
& rPropertyName
, const XMLPropStyleContext
* pPropStyleContext
, const SvXMLStylesContext
* pStylesCtxt
)
471 if( !pPropStyleContext
|| !pStylesCtxt
)
473 const ::std::vector
< XMLPropertyState
>& rProperties
= pPropStyleContext
->GetProperties();
474 const UniReference
< XMLPropertySetMapper
>& rMapper
= pStylesCtxt
->GetImportPropertyMapper( pPropStyleContext
->GetFamily()/*XML_STYLE_FAMILY_SCH_CHART_ID*/ )->getPropertySetMapper();
475 ::std::vector
< XMLPropertyState
>::const_iterator
aEnd( rProperties
.end() );
476 ::std::vector
< XMLPropertyState
>::const_iterator
aPropIter( rProperties
.begin() );
477 for( aPropIter
= rProperties
.begin(); aPropIter
!= aEnd
; ++aPropIter
)
479 sal_Int32 nIdx
= aPropIter
->mnIndex
;
482 OUString aPropName
= rMapper
->GetEntryAPIName( nIdx
);
483 if(rPropertyName
.equals(aPropName
))
484 return aPropIter
->maValue
;
489 void exportText( SvXMLExport
& rExport
, const OUString
& rText
, bool bConvertTabsLFs
)
491 SvXMLElementExport
aPara( rExport
, XML_NAMESPACE_TEXT
,
492 ::xmloff::token::GetXMLToken( ::xmloff::token::XML_P
),
493 sal_True
, sal_False
);
495 if( bConvertTabsLFs
)
497 sal_Int32 nStartPos
= 0;
498 sal_Int32 nEndPos
= rText
.getLength();
501 for( sal_Int32 nPos
= 0; nPos
< nEndPos
; nPos
++ )
503 cChar
= rText
[ nPos
];
506 case 0x0009: // tabulator
508 if( nPos
> nStartPos
)
509 rExport
.GetDocHandler()->characters( rText
.copy( nStartPos
, (nPos
- nStartPos
)) );
510 nStartPos
= nPos
+ 1;
512 SvXMLElementExport
aElem( rExport
, XML_NAMESPACE_TEXT
,
513 ::xmloff::token::GetXMLToken( ::xmloff::token::XML_TAB_STOP
),
514 sal_False
, sal_False
);
518 case 0x000A: // linefeed
520 if( nPos
> nStartPos
)
521 rExport
.GetDocHandler()->characters( rText
.copy( nStartPos
, (nPos
- nStartPos
)) );
522 nStartPos
= nPos
+ 1;
524 SvXMLElementExport
aElem( rExport
, XML_NAMESPACE_TEXT
,
525 ::xmloff::token::GetXMLToken( ::xmloff::token::XML_LINE_BREAK
),
526 sal_False
, sal_False
);
531 if( nEndPos
> nStartPos
)
534 rExport
.GetDocHandler()->characters( rText
);
536 rExport
.GetDocHandler()->characters( rText
.copy( nStartPos
, (nEndPos
- nStartPos
)) );
539 else // do not convert tabs and linefeeds (eg for numbers coming from unit converter)
541 rExport
.GetDocHandler()->characters( rText
);
545 Reference
< chart2::XRegressionCurve
> getRegressionCurve(
546 const Reference
< chart2::XDataSeries
> & xDataSeries
)
548 Reference
< chart2::XRegressionCurve
> xResult
;
550 Reference
< chart2::XRegressionCurveContainer
> xRegCurveCnt( xDataSeries
, uno::UNO_QUERY
);
551 if( xRegCurveCnt
.is())
553 // find equation properties of first regression curve
554 Sequence
< Reference
< chart2::XRegressionCurve
> > aCurveSeq(
555 xRegCurveCnt
->getRegressionCurves() );
556 for( sal_Int32 nI
=0; nI
<aCurveSeq
.getLength(); ++nI
)
558 // skip mean-value line
559 Reference
< lang::XServiceName
> xServiceName( aCurveSeq
[nI
], uno::UNO_QUERY
);
560 if( xServiceName
.is())
562 OUString
aServiceName( xServiceName
->getServiceName());
563 if( aServiceName
.equalsAsciiL(
564 RTL_CONSTASCII_STRINGPARAM( "com.sun.star.chart2.MeanValueRegressionCurve" )))
567 // take first non-empty curve
568 if( aCurveSeq
[nI
].is())
570 xResult
.set( aCurveSeq
[nI
] );
578 void setXMLRangePropertyAtDataSequence(
579 const Reference
< chart2::data::XDataSequence
> & xDataSequence
,
580 const OUString
& rXMLRange
)
582 if( !xDataSequence
.is())
586 const OUString
aXMLRangePropName( RTL_CONSTASCII_USTRINGPARAM( "CachedXMLRange" ));
587 Reference
< beans::XPropertySet
> xProp( xDataSequence
, uno::UNO_QUERY_THROW
);
588 Reference
< beans::XPropertySetInfo
> xInfo( xProp
->getPropertySetInfo());
589 if( xInfo
.is() && xInfo
->hasPropertyByName( aXMLRangePropName
))
590 xProp
->setPropertyValue( aXMLRangePropName
, uno::makeAny( rXMLRange
));
592 catch( const uno::Exception
& ex
)
594 (void)ex
; // avoid warning for pro build
595 OSL_ENSURE( false, ::rtl::OUStringToOString(
596 ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Exception caught, Message: " )) +
597 ex
.Message
, RTL_TEXTENCODING_ASCII_US
).getStr());
601 bool getXMLRangePropertyFromDataSequence(
602 const Reference
< chart2::data::XDataSequence
> & xDataSequence
,
603 OUString
& rOutXMLRange
,
604 bool bClearProp
/* = false */)
606 bool bResult
= false;
607 if( xDataSequence
.is())
611 const OUString
aXMLRangePropName( RTL_CONSTASCII_USTRINGPARAM( "CachedXMLRange" ));
612 Reference
< beans::XPropertySet
> xProp( xDataSequence
, uno::UNO_QUERY_THROW
);
613 Reference
< beans::XPropertySetInfo
> xInfo( xProp
->getPropertySetInfo());
615 ( xInfo
.is() && xInfo
->hasPropertyByName( aXMLRangePropName
) &&
616 ( xProp
->getPropertyValue( aXMLRangePropName
) >>= rOutXMLRange
) &&
617 rOutXMLRange
.getLength());
618 // clear the property after usage
619 if( bClearProp
&& bResult
)
620 xProp
->setPropertyValue( aXMLRangePropName
, uno::Any( OUString()));
622 catch( const uno::Exception
& ex
)
624 (void)ex
; // avoid warning for pro build
625 OSL_ENSURE( false, ::rtl::OUStringToOString(
626 ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Exception caught, Message: " )) +
627 ex
.Message
, RTL_TEXTENCODING_ASCII_US
).getStr());
634 const Reference
< beans::XPropertySet
> & xSource
,
635 const Reference
< beans::XPropertySet
> & xDestination
)
637 if( ! (xSource
.is() && xDestination
.is()) )
642 Reference
< beans::XPropertySetInfo
> xSrcInfo( xSource
->getPropertySetInfo(), uno::UNO_QUERY_THROW
);
643 Reference
< beans::XPropertySetInfo
> xDestInfo( xDestination
->getPropertySetInfo(), uno::UNO_QUERY_THROW
);
644 Sequence
< beans::Property
> aProperties( xSrcInfo
->getProperties());
645 const sal_Int32 nLength
= aProperties
.getLength();
646 for( sal_Int32 i
= 0; i
< nLength
; ++i
)
648 OUString
aName( aProperties
[i
].Name
);
649 if( xDestInfo
->hasPropertyByName( aName
))
651 beans::Property
aProp( xDestInfo
->getPropertyByName( aName
));
652 if( (aProp
.Attributes
& beans::PropertyAttribute::READONLY
) == 0 )
653 xDestination
->setPropertyValue(
654 aName
, xSource
->getPropertyValue( aName
));
658 catch( const uno::Exception
& )
660 OSL_ENSURE( false, "Copying property sets failed!" );
664 bool switchBackToDataProviderFromParent( const Reference
< chart2::XChartDocument
>& xChartDoc
, const tSchXMLLSequencesPerIndex
& rLSequencesPerIndex
)
666 //return whether the switch is successful
667 if( !xChartDoc
.is() || !xChartDoc
->hasInternalDataProvider() )
669 Reference
< chart2::data::XDataProvider
> xDataProviderFromParent( SchXMLTools::getDataProviderFromParent( xChartDoc
) );
670 if( !xDataProviderFromParent
.is() )
672 uno::Reference
< chart2::data::XDataReceiver
> xDataReceiver( xChartDoc
, uno::UNO_QUERY
);
673 if( !xDataReceiver
.is() )
676 xDataReceiver
->attachDataProvider( xDataProviderFromParent
);
678 for( tSchXMLLSequencesPerIndex::const_iterator
aLSeqIt( rLSequencesPerIndex
.begin() );
679 aLSeqIt
!= rLSequencesPerIndex
.end(); ++aLSeqIt
)
681 Reference
< chart2::data::XLabeledDataSequence
> xLabeledSeq( aLSeqIt
->second
);
682 if( !xLabeledSeq
.is() )
684 Reference
< chart2::data::XDataSequence
> xNewSeq
;
685 xNewSeq
= lcl_createNewSequenceFromCachedXMLRange( xLabeledSeq
->getValues(), xDataProviderFromParent
);
687 xLabeledSeq
->setValues( xNewSeq
);
688 xNewSeq
= lcl_createNewSequenceFromCachedXMLRange( xLabeledSeq
->getLabel(), xDataProviderFromParent
);
690 xLabeledSeq
->setLabel( xNewSeq
);
695 void setBuildIDAtImportInfo( uno::Reference
< frame::XModel
> xModel
, Reference
< beans::XPropertySet
> xImportInfo
)
697 ::rtl::OUString
aGenerator( lcl_getGeneratorFromModelOrItsParent(xModel
) );
698 if( aGenerator
.getLength() )
699 SvXMLMetaDocumentContext::setBuildId( aGenerator
, xImportInfo
);
702 bool isDocumentGeneratedWithOpenOfficeOlderThan3_0( const uno::Reference
< frame::XModel
>& xChartModel
)
704 bool bResult
= isDocumentGeneratedWithOpenOfficeOlderThan2_3( xChartModel
);
707 ::rtl::OUString
aGenerator( lcl_getGeneratorFromModel(xChartModel
) );
708 if( aGenerator
.indexOf( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("OpenOffice.org_project/680m") ) ) != -1 )
714 bool isDocumentGeneratedWithOpenOfficeOlderThan2_4( const uno::Reference
< frame::XModel
>& xChartModel
)
716 if( isDocumentGeneratedWithOpenOfficeOlderThan2_3( xChartModel
) )
719 if( isDocumentGeneratedWithOpenOfficeOlderThan3_0( xChartModel
) )
721 sal_Int32 nBuilId
= lcl_getBuildIDFromGenerator( lcl_getGeneratorFromModel(xChartModel
) );
722 if( nBuilId
>0 && nBuilId
<=9238 ) //9238 is build id of OpenOffice.org 2.3.1
728 bool isDocumentGeneratedWithOpenOfficeOlderThan2_3( const uno::Reference
< frame::XModel
>& xChartModel
)
730 bool bResult
= false;
731 ::rtl::OUString
aGenerator( lcl_getGeneratorFromModel(xChartModel
) );
732 //if there is a meta stream at the chart object it was not written with an older OpenOffice version < 2.3
733 if( !aGenerator
.getLength() )
735 //if there is no meta stream at the chart object we need to check whether the parent document is OpenOffice at all
736 uno::Reference
< container::XChild
> xChild( xChartModel
, uno::UNO_QUERY
);
739 aGenerator
= lcl_getGeneratorFromModel( uno::Reference
< frame::XModel
>( xChild
->getParent(), uno::UNO_QUERY
) );
740 if( aGenerator
.indexOf( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("OpenOffice.org_project") ) ) != -1 )
742 //the chart application has not created files without a meta stream since OOo 2.3 (OOo 2.3 has written a metastream already)
743 //only the report builder extension has created some files with OOo 3.1 that do not have a meta stream
744 if( aGenerator
.indexOf( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("OpenOffice.org_project/31") ) ) != -1 )
745 bResult
= false;//#i100102# probably generated with OOo 3.1 by the report designer
747 bResult
= true; //in this case the OLE chart was created by an older version, as OLE objects are sometimes stream copied the version can differ from the parents version, so the parents version is not a reliable indicator
749 else if( isDocumentGeneratedWithOpenOfficeOlderThan2_0(xChartModel
) )
756 bool isDocumentGeneratedWithOpenOfficeOlderThan2_0( const ::com::sun::star::uno::Reference
< ::com::sun::star::frame::XModel
>& xChartModel
)
758 bool bResult
= false;
759 ::rtl::OUString
aGenerator( lcl_getGeneratorFromModelOrItsParent(xChartModel
) );
760 if( ( aGenerator
.indexOf( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("OpenOffice.org 1") ) ) == 0 )
761 || ( aGenerator
.indexOf( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("StarOffice 6") ) ) == 0 )
762 || ( aGenerator
.indexOf( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("StarOffice 7") ) ) == 0 )
763 || ( aGenerator
.indexOf( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("StarSuite 6") ) ) == 0 )
764 || ( aGenerator
.indexOf( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("StarSuite 7") ) ) == 0 )
770 Reference
< chart2::data::XDataProvider
> getDataProviderFromParent( const Reference
< chart2::XChartDocument
>& xChartDoc
)
772 Reference
< chart2::data::XDataProvider
> xRet
;
773 uno::Reference
< container::XChild
> xChild( xChartDoc
, uno::UNO_QUERY
);
776 Reference
< lang::XMultiServiceFactory
> xFact( xChild
->getParent(), uno::UNO_QUERY
);
779 const OUString
aDataProviderServiceName( RTL_CONSTASCII_USTRINGPARAM("com.sun.star.chart2.data.DataProvider"));
780 const uno::Sequence
< OUString
> aServiceNames( xFact
->getAvailableServiceNames());
781 const OUString
* pBegin
= aServiceNames
.getConstArray();
782 const OUString
* pEnd
= pBegin
+ aServiceNames
.getLength();
783 if( ::std::find( pBegin
, pEnd
, aDataProviderServiceName
) != pEnd
)
785 xRet
= Reference
< chart2::data::XDataProvider
>(
786 xFact
->createInstance( aDataProviderServiceName
), uno::UNO_QUERY
);
793 } // namespace SchXMLTools