22 #include <rtl/ustrbuf.hxx>
33 #include <com/sun/star/beans/PropertyAttribute.hpp>
34 #include <com/sun/star/uno/XComponentContext.hpp>
35 #include <com/sun/star/chart2/data/LabeledDataSequence.hpp>
36 #include <com/sun/star/chart2/data/XDataProvider.hpp>
37 #include <com/sun/star/chart2/data/XDataReceiver.hpp>
38 #include <com/sun/star/chart2/data/XRangeXMLConversion.hpp>
39 #include <com/sun/star/chart2/data/XPivotTableDataProvider.hpp>
40 #include <com/sun/star/chart2/XChartDocument.hpp>
41 #include <com/sun/star/chart2/XCoordinateSystemContainer.hpp>
42 #include <com/sun/star/container/XChild.hpp>
43 #include <com/sun/star/document/XDocumentProperties.hpp>
44 #include <com/sun/star/document/XDocumentPropertiesSupplier.hpp>
45 #include <com/sun/star/lang/XMultiServiceFactory.hpp>
46 #include <com/sun/star/xml/sax/XDocumentHandler.hpp>
57 using ::com::sun::star::uno::Reference;
58 using ::com::sun::star::uno::Sequence;
63 OUString lcl_getGeneratorFromModel(
const uno::Reference< frame::XModel >& xChartModel )
66 uno::Reference< document::XDocumentPropertiesSupplier> xChartDocumentPropertiesSupplier( xChartModel, uno::UNO_QUERY );
67 if( xChartDocumentPropertiesSupplier.is() )
69 uno::Reference< document::XDocumentProperties > xChartDocumentProperties(
70 xChartDocumentPropertiesSupplier->getDocumentProperties());
71 if( xChartDocumentProperties.is() )
72 aGenerator = xChartDocumentProperties->getGenerator();
77 OUString lcl_getGeneratorFromModelOrItsParent(
const uno::Reference< frame::XModel >& xChartModel )
79 OUString aGenerator( lcl_getGeneratorFromModel(xChartModel) );
80 if( aGenerator.isEmpty() )
82 uno::Reference< container::XChild > xChild( xChartModel, uno::UNO_QUERY );
84 aGenerator = lcl_getGeneratorFromModel( uno::Reference< frame::XModel >( xChild->getParent(), uno::UNO_QUERY) );
89 sal_Int32 lcl_getBuildIDFromGenerator(
const OUString& rGenerator )
92 sal_Int32 nBuildId = -1;
93 const OUString sBuildCompare(
"$Build-" );
94 sal_Int32 nBegin = rGenerator.indexOf( sBuildCompare );
97 OUString sBuildId( rGenerator.copy( nBegin + sBuildCompare.getLength() ) );
98 nBuildId = sBuildId.toInt32();
103 OUString lcl_ConvertRange(
const OUString & rRange,
const Reference< chart2::data::XDataProvider >& xDataProvider )
105 OUString aResult = rRange;
106 Reference< chart2::data::XRangeXMLConversion > xRangeConversion( xDataProvider, uno::UNO_QUERY );
107 if( xRangeConversion.is())
108 aResult = xRangeConversion->convertRangeFromXML( rRange );
112 Reference< chart2::data::XDataSequence > lcl_createNewSequenceFromCachedXMLRange(
const Reference< chart2::data::XDataSequence >& xSeq,
const Reference< chart2::data::XDataProvider >& xDataProvider )
114 Reference< chart2::data::XDataSequence > xRet;
118 xRet.set( xDataProvider->createDataSequenceByRangeRepresentation(
119 lcl_ConvertRange( aRange, xDataProvider )) );
160 static const tMakeStringStringMap g_aChartTypeNameMap{
161 {
"com.sun.star.chart.LineDiagram",
162 "com.sun.star.chart2.LineChartType"},
163 {
"com.sun.star.chart.AreaDiagram",
164 "com.sun.star.chart2.AreaChartType"},
165 {
"com.sun.star.chart.BarDiagram",
166 "com.sun.star.chart2.ColumnChartType"},
167 {
"com.sun.star.chart.PieDiagram",
168 "com.sun.star.chart2.PieChartType"},
169 {
"com.sun.star.chart.DonutDiagram",
170 "com.sun.star.chart2.DonutChartType"},
171 {
"com.sun.star.chart.XYDiagram",
172 "com.sun.star.chart2.ScatterChartType"},
173 {
"com.sun.star.chart.NetDiagram",
174 "com.sun.star.chart2.NetChartType"},
175 {
"com.sun.star.chart.FilledNetDiagram",
176 "com.sun.star.chart2.FilledNetChartType"},
177 {
"com.sun.star.chart.StockDiagram",
178 "com.sun.star.chart2.CandleStickChartType"},
179 {
"com.sun.star.chart.BubbleDiagram",
180 "com.sun.star.chart2.BubbleChartType"}};
181 return g_aChartTypeNameMap;
186 OUString aNew(rOldChartTypeName);
189 tMakeStringStringMap::const_iterator aIt( rMap.find( rOldChartTypeName ));
190 if( aIt != rMap.end())
198 std::u16string_view rClassName,
bool bUseOldNames )
200 OUStringBuffer aResultBuffer;
201 bool bInternalType =
false;
204 aResultBuffer.append(
"com.sun.star.chart.");
206 aResultBuffer.append(
"com.sun.star.chart2.");
208 bInternalType =
true;
211 aResultBuffer.append(
"Line");
213 aResultBuffer.append(
"Area");
217 aResultBuffer.append(
"Bar");
220 aResultBuffer.append(
"Column");
225 aResultBuffer.append(
"Pie");
227 aResultBuffer.append(
"Donut");
231 aResultBuffer.append(
"XY");
233 aResultBuffer.append(
"Scatter");
237 aResultBuffer.append(
"Bubble");
239 aResultBuffer.append(
"Net");
241 aResultBuffer.append(
"FilledNet");
245 aResultBuffer.append(
"Stock");
247 aResultBuffer.append(
"CandleStick");
253 aResultBuffer.append(
"Bar");
255 aResultBuffer.append(
"Column");
258 bInternalType =
false;
260 if( ! bInternalType )
264 aResultBuffer.append(
"Diagram");
266 aResultBuffer.append(
"ChartType");
268 return aResultBuffer.makeStringAndClear();
273 const OUString & rChartTypeService,
bool bUseOldNames )
276 OUString aPrefix, aPostfix;
280 aPrefix =
"com.sun.star.chart.";
281 aPostfix =
"Diagram";
285 aPrefix =
"com.sun.star.chart2.";
286 aPostfix =
"ChartType";
289 if( rChartTypeService.match( aPrefix ))
291 sal_Int32 nSkip = aPrefix.getLength();
292 SAL_WARN_IF( rChartTypeService.getLength() < nSkip,
"xmloff.chart",
"ChartTypeService.getLength() < nSkip" );
293 sal_Int32 nTypeLength = rChartTypeService.getLength() - nSkip - aPostfix.getLength();
295 if( nTypeLength > 0 && rChartTypeService.match( aPostfix, nSkip + nTypeLength ))
297 OUString aServiceName( rChartTypeService.copy( nSkip, nTypeLength ));
299 if ( aServiceName ==
"Line" )
301 else if ( aServiceName ==
"Area" )
303 else if( aServiceName ==
"Bar" ||
304 (!bUseOldNames && aServiceName ==
"Column"))
306 else if ( aServiceName ==
"Pie" )
308 else if ( aServiceName ==
"Donut" )
310 else if( (bUseOldNames && aServiceName ==
"XY") ||
311 (!bUseOldNames && aServiceName ==
"Scatter"))
313 else if ( aServiceName ==
"Bubble" )
315 else if ( aServiceName ==
"Net" )
317 else if ( aServiceName ==
"FilledNet" )
319 else if( (bUseOldNames && aServiceName ==
"Stock") ||
320 (!bUseOldNames && aServiceName ==
"CandleStick"))
334 Reference< chart2::data::XLabeledDataSequence2 > xResult = chart2::data::LabeledDataSequence::create(xContext);
339 const OUString & rRange,
340 const Reference< chart2::XChartDocument >& xChartDoc )
342 Reference< chart2::data::XDataSequence > xRet;
344 if( !xChartDoc.is() )
346 SAL_WARN(
"xmloff.chart",
"need a chart document" );
350 Reference< chart2::data::XDataProvider > xDataProvider( xChartDoc->getDataProvider() );
351 if( !xDataProvider.is() )
353 SAL_WARN(
"xmloff.chart",
"need a data provider" );
357 bool bUseInternal =
false;
358 uno::Reference<beans::XPropertySet> xPropSet(xDataProvider, uno::UNO_QUERY);
364 uno::Any any = xPropSet->getPropertyValue(
"UseInternalDataProvider");
368 catch (
const beans::UnknownPropertyException&)
378 xRet.set( xDataProvider->createDataSequenceByRangeRepresentation( lcl_ConvertRange( rRange, xDataProvider )));
381 catch(
const lang::IllegalArgumentException & )
383 SAL_WARN(
"xmloff.chart",
"could not create data sequence" );
387 if( !xRet.is() && !xChartDoc->hasInternalDataProvider() && !rRange.isEmpty() )
390 xChartDoc->createInternalDataProvider(
true );
391 xDataProvider = xChartDoc->getDataProvider();
394 xRet.set( xDataProvider->createDataSequenceByRangeRepresentation( lcl_ConvertRange( rRange, xDataProvider )));
397 catch(
const lang::IllegalArgumentException & )
399 SAL_WARN(
"xmloff.chart",
"could not create data sequence" );
406 const OUString & rRange,
407 const Reference< chart2::XChartDocument >& xChartDoc )
409 Reference< chart2::data::XDataSequence > xRet;
411 if( !xChartDoc.is() )
413 SAL_WARN(
"xmloff.chart",
"need a chart document" );
417 Reference< chart2::data::XDataProvider > xDataProvider( xChartDoc->getDataProvider() );
418 if( !xDataProvider.is() )
420 SAL_WARN(
"xmloff.chart",
"need a data provider" );
426 xRet.set( xDataProvider->createDataSequenceByRangeRepresentation( rRange ) );
429 catch(
const lang::IllegalArgumentException & )
431 SAL_WARN(
"xmloff.chart",
"could not create data sequence" );
438 const uno::Reference< chart2::data::XDataProvider > & xDataProvider,
439 const uno::Reference< chart2::XChartDocument > & xNewDoc,
440 const OUString & rRangeAddress,
441 sal_Int32 nCooSysIndex,
442 sal_Int32 nDimensionIndex,
447 if( xNewDoc.is() && !rRangeAddress.isEmpty())
449 if( xDataProvider.is())
451 uno::Reference< chart2::XDiagram > xDia( xNewDoc->getFirstDiagram());
455 uno::Reference< chart2::XCoordinateSystemContainer > xCooSysCnt( xDia, uno::UNO_QUERY_THROW );
456 uno::Sequence< uno::Reference< chart2::XCoordinateSystem > >
457 aCooSysSeq( xCooSysCnt->getCoordinateSystems());
458 if( nCooSysIndex < aCooSysSeq.getLength())
460 uno::Reference< chart2::XCoordinateSystem > xCooSys( aCooSysSeq[nCooSysIndex] );
461 SAL_WARN_IF( !xCooSys.is(),
"xmloff.chart",
"xCooSys is NULL");
462 if( nDimensionIndex < xCooSys->getDimension() )
464 const sal_Int32 nMaxAxisIndex = xCooSys->getMaximumAxisIndexByDimension(nDimensionIndex);
465 for(sal_Int32 nI=0; nI<=nMaxAxisIndex; ++nI)
467 uno::Reference< chart2::XAxis > xAxis( xCooSys->getAxisByDimension( nDimensionIndex, nI ));
470 chart2::ScaleData
aData( xAxis->getScaleData());
471 uno::Reference< chart2::data::XLabeledDataSequence > xLabeledSeq(
475 OUString aConvertedRange( rRangeAddress );
476 bool bRangeConverted =
false;
477 if( ! (xNewDoc->hasInternalDataProvider() && aConvertedRange ==
"categories"))
479 Reference< chart2::data::XRangeXMLConversion > xXMLConv( xDataProvider, uno::UNO_QUERY );
482 aConvertedRange = xXMLConv->convertRangeFromXML( rRangeAddress );
483 bRangeConverted =
true;
487 Reference<chart2::data::XDataSequence> xSequence;
488 Reference<chart2::data::XPivotTableDataProvider> xPivotTableDataProvider(xDataProvider, uno::UNO_QUERY);
489 if (xPivotTableDataProvider.is())
491 xSequence.set(xPivotTableDataProvider->createDataSequenceOfCategories());
495 xSequence.set(xDataProvider->createDataSequenceByRangeRepresentation(aConvertedRange));
499 xLabeledSeq->setValues(xSequence);
502 catch(
const lang::IllegalArgumentException & )
506 aData.Categories.set( xLabeledSeq );
507 if( pLSequencesPerIndex )
510 pLSequencesPerIndex->emplace(
513 xAxis->setScaleData(
aData );
521 catch( uno::Exception & )
530 if( !pPropStyleContext || !pStylesCtxt )
532 const ::std::vector< XMLPropertyState >& rProperties = pPropStyleContext->
GetProperties();
534 for(
const auto& rProp : rProperties )
536 sal_Int32 nIdx = rProp.mnIndex;
539 OUString aPropName = rMapper->GetEntryAPIName( nIdx );
540 if(rPropertyName == aPropName)
541 return rProp.maValue;
552 if( bConvertTabsLFs )
554 sal_Int32 nStartPos = 0;
555 sal_Int32 nEndPos = rText.getLength();
560 cChar = rText[
nPos ];
565 if(
nPos > nStartPos )
566 rExport.
GetDocHandler()->characters( rText.copy( nStartPos, (
nPos - nStartPos)) );
567 nStartPos =
nPos + 1;
577 if(
nPos > nStartPos )
578 rExport.
GetDocHandler()->characters( rText.copy( nStartPos, (
nPos - nStartPos)) );
579 nStartPos =
nPos + 1;
588 if( nEndPos > nStartPos )
593 rExport.
GetDocHandler()->characters( rText.copy( nStartPos, (nEndPos - nStartPos)) );
626 const Reference< chart2::data::XDataSequence > & xDataSequence,
627 const OUString & rXMLRange )
629 if( !xDataSequence.is())
633 const OUString aXMLRangePropName(
"CachedXMLRange" );
636 if( xInfo.is() && xInfo->hasPropertyByName( aXMLRangePropName ))
637 xProp->setPropertyValue( aXMLRangePropName,
uno::makeAny( rXMLRange ));
639 catch(
const uno::Exception & )
646 const Reference< chart2::data::XDataSequence > & xDataSequence,
647 OUString & rOutXMLRange,
650 bool bResult =
false;
651 if( xDataSequence.is())
655 const OUString aXMLRangePropName(
"CachedXMLRange" );
659 ( xInfo.is() && xInfo->hasPropertyByName( aXMLRangePropName ) &&
660 ( xProp->getPropertyValue( aXMLRangePropName ) >>= rOutXMLRange ) &&
661 !rOutXMLRange.isEmpty());
663 if( bClearProp && bResult )
664 xProp->setPropertyValue( aXMLRangePropName,
uno::Any( OUString()));
666 catch(
const uno::Exception & )
678 if( ! (xSource.is() && xDestination.is()) )
688 OUString
aName( rProperty.Name);
689 if( xDestInfo->hasPropertyByName( aName ))
691 beans::Property aProp( xDestInfo->getPropertyByName( aName ));
692 if( (aProp.Attributes & beans::PropertyAttribute::READONLY) == 0 )
693 xDestination->setPropertyValue(
694 aName, xSource->getPropertyValue( aName ));
698 catch(
const uno::Exception & )
700 SAL_WARN(
"xmloff.chart",
"Copying property sets failed!" );
707 if( !xChartDoc.is() || !xChartDoc->hasInternalDataProvider() )
710 if( !xDataProviderFromParent.is() )
712 uno::Reference< chart2::data::XDataReceiver > xDataReceiver( xChartDoc, uno::UNO_QUERY );
713 if( !xDataReceiver.is() )
716 xDataReceiver->attachDataProvider( xDataProviderFromParent );
718 for(
const auto& rLSeq : rLSequencesPerIndex )
721 if( !xLabeledSeq.is() )
723 Reference< chart2::data::XDataSequence > xNewSeq;
724 xNewSeq = lcl_createNewSequenceFromCachedXMLRange( xLabeledSeq->getValues(), xDataProviderFromParent );
726 xLabeledSeq->setValues( xNewSeq );
727 xNewSeq = lcl_createNewSequenceFromCachedXMLRange( xLabeledSeq->getLabel(), xDataProviderFromParent );
729 xLabeledSeq->setLabel( xNewSeq );
736 OUString aGenerator( lcl_getGeneratorFromModelOrItsParent(xModel) );
737 if( !aGenerator.isEmpty() )
746 OUString aGenerator( lcl_getGeneratorFromModel(xChartModel) );
747 if( aGenerator.indexOf(
"OpenOffice.org_project/3" ) != -1 )
749 if( aGenerator.indexOf(
"OpenOffice.org_project/300m" ) != -1 )
751 sal_Int32 nBuilId = lcl_getBuildIDFromGenerator( lcl_getGeneratorFromModel(xChartModel) );
752 if( nBuilId>0 && nBuilId<9491 )
755 else if( aGenerator.indexOf(
"OpenOffice.org_project/310m" ) != -1 )
757 else if( aGenerator.indexOf(
"OpenOffice.org_project/320m" ) != -1 )
769 OUString aGenerator( lcl_getGeneratorFromModel(xChartModel) );
770 if( aGenerator.indexOf(
"OpenOffice.org_project/680m" ) != -1 )
783 sal_Int32 nBuilId = lcl_getBuildIDFromGenerator( lcl_getGeneratorFromModel(xChartModel) );
784 if( nBuilId>0 && nBuilId<=9238 )
792 bool bResult =
false;
793 OUString aGenerator( lcl_getGeneratorFromModel(xChartModel) );
795 if( aGenerator.isEmpty() )
798 uno::Reference< container::XChild > xChild( xChartModel, uno::UNO_QUERY );
801 aGenerator = lcl_getGeneratorFromModel( uno::Reference< frame::XModel >( xChild->getParent(), uno::UNO_QUERY) );
802 if( aGenerator.indexOf(
"OpenOffice.org_project" ) != -1 )
806 if( aGenerator.indexOf(
"OpenOffice.org_project/31" ) != -1 )
820 bool bResult =
false;
821 OUString aGenerator( lcl_getGeneratorFromModelOrItsParent(xChartModel) );
822 if( aGenerator.startsWith(
"OpenOffice.org 1" )
823 || aGenerator.startsWith(
"StarOffice 6" )
824 || aGenerator.startsWith(
"StarOffice 7" )
825 || aGenerator.startsWith(
"StarSuite 6" )
826 || aGenerator.startsWith(
"StarSuite 7" )
834 Reference< chart2::data::XDataProvider > xRet;
835 uno::Reference< container::XChild > xChild( xChartDoc, uno::UNO_QUERY );
838 Reference< lang::XMultiServiceFactory > xFact( xChild->getParent(), uno::UNO_QUERY );
841 const OUString aDataProviderServiceName(
"com.sun.star.chart2.data.DataProvider");
842 const uno::Sequence< OUString >
aServiceNames( xFact->getAvailableServiceNames());
845 if( ::std::find( pBegin, pEnd, aDataProviderServiceName ) != pEnd )
847 xRet.set( xFact->createInstance( aDataProviderServiceName ), uno::UNO_QUERY );
XmlStyleFamily GetFamily() const
Sequence< OUString > aServiceNames
bool IsXMLToken(std::u16string_view rString, enum XMLTokenEnum eToken)
compare eToken to the string
const css::uno::Reference< css::xml::sax::XDocumentHandler > & GetDocHandler() const
css::uno::Any const & rValue
PropertiesInfo aProperties
::std::pair< tSchXMLIndex, SchXMLLabeledSequencePart > tSchXMLIndexWithPart
constexpr sal_uInt16 XML_NAMESPACE_DRAW
XMLTokenEnum
The enumeration of all XML tokens.
constexpr OUStringLiteral aData
#define DBG_UNHANDLED_EXCEPTION(...)
virtual rtl::Reference< SvXMLImportPropertyMapper > GetImportPropertyMapper(XmlStyleFamily nFamily) const
constexpr sal_uInt16 XML_NAMESPACE_SVG
#define TOOLS_WARN_EXCEPTION(area, stream)
#define SCH_XML_CATEGORIES_INDEX
constexpr sal_uInt16 XML_NAMESPACE_TEXT
::std::vector< XMLPropertyState > & GetProperties()
Map an XMLTokenEnum to an enum value.
static void setBuildId(const OUString &rGenerator, const css::uno::Reference< css::beans::XPropertySet > &xImportInfo)
Any makeAny(Color const &value)
#define SAL_WARN_IF(condition, area, stream)
const OUString & GetXMLToken(enum XMLTokenEnum eToken)
return the OUString representation for eToken
Handling of tokens in XML:
static bool convertEnum(EnumT &rEnum, std::u16string_view rValue, const SvXMLEnumMapEntry< EnumT > *pMap)
convert string to enum using given enum map, if the enum is not found in the map, this method will re...
Reference< XComponentContext > getProcessComponentContext()
#define SAL_WARN(area, stream)
::std::multimap< tSchXMLIndexWithPart, css::uno::Reference< css::chart2::data::XLabeledDataSequence > > tSchXMLLSequencesPerIndex
css::uno::Any const SvXMLExport & rExport