/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ /* * This file is part of the LibreOffice project. * * This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ #pragma once #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include using namespace css; using namespace css::uno; class ChartTest : public UnoApiXmlTest { public: ChartTest(OUString path) : UnoApiXmlTest(path) { } Reference getChartCompFromSheet(sal_Int32 nSheet, sal_Int32 nChart); Reference getChartDocFromSheet(sal_Int32 nSheet); uno::Reference getTablePivotChartsFromSheet(sal_Int32 nSheet); Reference getPivotChartDocFromSheet(sal_Int32 nSheet); uno::Reference getPivotChartDocFromSheet(uno::Reference const& xTablePivotCharts, sal_Int32 nIndex); Reference getChartTypeFromDoc(Reference const& xChartDoc, sal_Int32 nChartType, sal_Int32 nCooSys = 0); Reference getAxisFromDoc(const Reference& xChartDoc, sal_Int32 nCooSys, sal_Int32 nAxisDim, sal_Int32 nAxisIndex); sal_Int32 getNumberOfDataSeries(uno::Reference const& xChartDoc, sal_Int32 nChartType = 0, sal_Int32 nCooSys = 0); Reference getDataSeriesFromDoc(uno::Reference const& xChartDoc, sal_Int32 nDataSeries, sal_Int32 nChartType = 0, sal_Int32 nCooSys = 0); Reference getLabelDataSequenceFromDoc(Reference const& xChartDoc, sal_Int32 nDataSeries = 0, sal_Int32 nChartType = 0); Reference getDataSequenceFromDocByRole(Reference const& xChartDoc, std::u16string_view rRole, sal_Int32 nDataSeries = 0, sal_Int32 nChartType = 0); uno::Sequence getWriterChartColumnDescriptions(); std::vector> getDataSeriesYValuesFromChartType(const Reference& xCT); std::vector> getDataSeriesLabelsFromChartType(const Reference& xCT); uno::Reference getChartDocFromDrawImpress(sal_Int32 nPage, sal_Int32 nShape); uno::Reference getChartDocFromWriter(sal_Int32 nShape); OUString getTitleString(const Reference& xTitled); sal_Int32 getNumberFormatFromAxis(const Reference& xAxis); sal_Int16 getNumberFormatType(const Reference& xChartDoc, sal_Int32 nNumberFormat); uno::Reference getShapeByName(const uno::Reference& rShapes, const OUString& rName, const std::function&)>& pCondition = nullptr); }; Reference< lang::XComponent > ChartTest::getChartCompFromSheet( sal_Int32 nSheet, sal_Int32 nChart ) { // let us assume that we only have one chart per sheet uno::Reference< sheet::XSpreadsheetDocument > xDoc(mxComponent, UNO_QUERY_THROW); uno::Reference< container::XIndexAccess > xIA(xDoc->getSheets(), UNO_QUERY_THROW); uno::Reference< table::XTableChartsSupplier > xChartSupplier( xIA->getByIndex(nSheet), UNO_QUERY_THROW); uno::Reference< table::XTableCharts > xCharts = xChartSupplier->getCharts(); CPPUNIT_ASSERT(xCharts.is()); uno::Reference< container::XIndexAccess > xIACharts(xCharts, UNO_QUERY_THROW); uno::Reference< table::XTableChart > xChart( xIACharts->getByIndex(nChart), UNO_QUERY_THROW); uno::Reference< document::XEmbeddedObjectSupplier > xEmbObjectSupplier(xChart, UNO_QUERY_THROW); uno::Reference< lang::XComponent > xChartComp( xEmbObjectSupplier->getEmbeddedObject(), UNO_SET_THROW ); return xChartComp; } Reference< chart2::XChartDocument > ChartTest::getChartDocFromSheet( sal_Int32 nSheet ) { uno::Reference< chart2::XChartDocument > xChartDoc ( getChartCompFromSheet(nSheet, 0), UNO_QUERY_THROW ); // Update the chart view, so that its draw page is updated and ready for the test css::uno::Reference xModel(xChartDoc, css::uno::UNO_QUERY_THROW); ChartHelper::updateChart(xModel); return xChartDoc; } uno::Reference ChartTest::getTablePivotChartsFromSheet(sal_Int32 nSheet) { uno::Reference xDoc(mxComponent, UNO_QUERY_THROW); uno::Reference xIA(xDoc->getSheets(), UNO_QUERY_THROW); uno::Reference xChartSupplier(xIA->getByIndex(nSheet), UNO_QUERY_THROW); uno::Reference xTablePivotCharts = xChartSupplier->getPivotCharts(); CPPUNIT_ASSERT(xTablePivotCharts.is()); return xTablePivotCharts; } Reference ChartTest::getPivotChartDocFromSheet(sal_Int32 nSheet) { uno::Reference xTablePivotCharts = getTablePivotChartsFromSheet(nSheet); uno::Reference xIACharts(xTablePivotCharts, UNO_QUERY_THROW); uno::Reference xTablePivotChart(xIACharts->getByIndex(0), UNO_QUERY_THROW); uno::Reference xEmbObjectSupplier(xTablePivotChart, UNO_QUERY_THROW); uno::Reference xChartComp(xEmbObjectSupplier->getEmbeddedObject(), UNO_SET_THROW); uno::Reference xChartDoc(xChartComp, UNO_QUERY_THROW); return xChartDoc; } Reference ChartTest::getPivotChartDocFromSheet(uno::Reference const & xTablePivotCharts, sal_Int32 nIndex) { uno::Reference xIACharts(xTablePivotCharts, UNO_QUERY_THROW); uno::Reference xTablePivotChart(xIACharts->getByIndex(nIndex), UNO_QUERY_THROW); uno::Reference xEmbObjectSupplier(xTablePivotChart, UNO_QUERY_THROW); uno::Reference xChartComp(xEmbObjectSupplier->getEmbeddedObject(), UNO_SET_THROW); uno::Reference xChartDoc(xChartComp, UNO_QUERY_THROW); return xChartDoc; } Reference< chart2::XChartType > ChartTest::getChartTypeFromDoc( Reference< chart2::XChartDocument > const & xChartDoc, sal_Int32 nChartType, sal_Int32 nCooSys ) { CPPUNIT_ASSERT( xChartDoc.is() ); Reference xDiagram = xChartDoc->getFirstDiagram(); CPPUNIT_ASSERT( xDiagram.is() ); Reference< chart2::XCoordinateSystemContainer > xCooSysContainer( xDiagram, UNO_QUERY_THROW ); Sequence< Reference< chart2::XCoordinateSystem > > xCooSysSequence( xCooSysContainer->getCoordinateSystems()); CPPUNIT_ASSERT( xCooSysSequence.getLength() > nCooSys ); Reference< chart2::XChartTypeContainer > xChartTypeContainer( xCooSysSequence[nCooSys], UNO_QUERY_THROW ); Sequence< Reference< chart2::XChartType > > xChartTypeSequence( xChartTypeContainer->getChartTypes() ); CPPUNIT_ASSERT( xChartTypeSequence.getLength() > nChartType ); return xChartTypeSequence[nChartType]; } Reference ChartTest::getAxisFromDoc( const Reference& xChartDoc, sal_Int32 nCooSys, sal_Int32 nAxisDim, sal_Int32 nAxisIndex ) { Reference xDiagram = xChartDoc->getFirstDiagram(); CPPUNIT_ASSERT(xDiagram.is()); Reference xCooSysContainer(xDiagram, UNO_QUERY_THROW); Sequence > xCooSysSequence = xCooSysContainer->getCoordinateSystems(); CPPUNIT_ASSERT(xCooSysSequence.getLength() > nCooSys); Reference xCoord = xCooSysSequence[nCooSys]; CPPUNIT_ASSERT(xCoord.is()); Reference xAxis = xCoord->getAxisByDimension(nAxisDim, nAxisIndex); CPPUNIT_ASSERT(xAxis.is()); return xAxis; } sal_Int32 ChartTest::getNumberOfDataSeries(uno::Reference const & xChartDoc, sal_Int32 nChartType, sal_Int32 nCooSys) { Reference xChartType = getChartTypeFromDoc(xChartDoc, nChartType, nCooSys); Reference xDataSeriesContainer(xChartType, UNO_QUERY_THROW); uno::Sequence> xSeriesSequence(xDataSeriesContainer->getDataSeries()); return xSeriesSequence.getLength(); } Reference< chart2::XDataSeries > ChartTest::getDataSeriesFromDoc(uno::Reference const & xChartDoc, sal_Int32 nDataSeries, sal_Int32 nChartType, sal_Int32 nCooSys) { Reference< chart2::XChartType > xChartType = getChartTypeFromDoc( xChartDoc, nChartType, nCooSys ); Reference< chart2::XDataSeriesContainer > xDataSeriesContainer( xChartType, UNO_QUERY_THROW ); Sequence< Reference< chart2::XDataSeries > > xSeriesSequence( xDataSeriesContainer->getDataSeries() ); CPPUNIT_ASSERT( xSeriesSequence.getLength() > nDataSeries ); Reference< chart2::XDataSeries > xSeries = xSeriesSequence[nDataSeries]; return xSeries; } Reference< chart2::data::XDataSequence > ChartTest::getLabelDataSequenceFromDoc( Reference< chart2::XChartDocument > const & xChartDoc, sal_Int32 nDataSeries, sal_Int32 nChartType ) { Reference< chart2::XDataSeries > xDataSeries = getDataSeriesFromDoc( xChartDoc, nDataSeries, nChartType ); CPPUNIT_ASSERT(xDataSeries.is()); Reference< chart2::data::XDataSource > xDataSource( xDataSeries, uno::UNO_QUERY_THROW ); const Sequence< Reference< chart2::data::XLabeledDataSequence > > xDataSequences = xDataSource->getDataSequences(); for(auto const & lds : xDataSequences) { Reference< chart2::data::XDataSequence> xLabelSeq = lds->getLabel(); if(!xLabelSeq.is()) continue; return xLabelSeq; } CPPUNIT_FAIL("no Label sequence found"); } Reference< chart2::data::XDataSequence > ChartTest::getDataSequenceFromDocByRole( Reference< chart2::XChartDocument > const & xChartDoc, std::u16string_view rRole, sal_Int32 nDataSeries, sal_Int32 nChartType ) { Reference< chart2::XDataSeries > xDataSeries = getDataSeriesFromDoc( xChartDoc, nDataSeries, nChartType ); CPPUNIT_ASSERT(xDataSeries.is()); Reference< chart2::data::XDataSource > xDataSource( xDataSeries, uno::UNO_QUERY_THROW ); const Sequence< Reference< chart2::data::XLabeledDataSequence > > xDataSequences = xDataSource->getDataSequences(); for(auto const & lds : xDataSequences) { Reference< chart2::data::XDataSequence> xLabelSeq = lds->getValues(); uno::Reference< beans::XPropertySet > xProps(xLabelSeq, uno::UNO_QUERY); if(!xProps.is()) continue; OUString aRoleName = xProps->getPropertyValue(u"Role"_ustr).get(); if(aRoleName == rRole) return xLabelSeq; } return Reference< chart2::data::XDataSequence > (); } uno::Sequence < OUString > ChartTest::getWriterChartColumnDescriptions() { uno::Reference xDrawPageSupplier(mxComponent, uno::UNO_QUERY); uno::Reference xDrawPage = xDrawPageSupplier->getDrawPage(); uno::Reference xShape(xDrawPage->getByIndex(0), uno::UNO_QUERY); CPPUNIT_ASSERT( xShape.is() ); uno::Reference xPropertySet(xShape, uno::UNO_QUERY); uno::Reference< chart2::XChartDocument > xChartDoc; xChartDoc.set( xPropertySet->getPropertyValue( u"Model"_ustr ), uno::UNO_QUERY ); CPPUNIT_ASSERT( xChartDoc.is() ); CPPUNIT_ASSERT( xChartDoc->getDataProvider().is() ); uno::Reference< chart2::XAnyDescriptionAccess > xAnyDescriptionAccess ( xChartDoc->getDataProvider(), uno::UNO_QUERY_THROW ); uno::Sequence< OUString > seriesList = xAnyDescriptionAccess->getColumnDescriptions(); return seriesList; } std::vector > ChartTest::getDataSeriesYValuesFromChartType( const Reference& xCT ) { Reference xDSCont(xCT, uno::UNO_QUERY); CPPUNIT_ASSERT(xDSCont.is()); const Sequence > aDataSeriesSeq = xDSCont->getDataSeries(); std::vector > aRet; for (uno::Reference const & ds : aDataSeriesSeq) { uno::Reference xDSrc(ds, uno::UNO_QUERY); CPPUNIT_ASSERT(xDSrc.is()); const uno::Sequence > aDataSeqs = xDSrc->getDataSequences(); for (auto const & lds : aDataSeqs) { Reference xValues = lds->getValues(); CPPUNIT_ASSERT(xValues.is()); Reference xPropSet(xValues, uno::UNO_QUERY); if (!xPropSet.is()) continue; OUString aRoleName; xPropSet->getPropertyValue(u"Role"_ustr) >>= aRoleName; if (aRoleName == "values-y") { const uno::Sequence aData = xValues->getData(); std::vector aValues; aValues.reserve(aData.getLength()); for (uno::Any const & any : aData) { double fVal; if (any >>= fVal) aValues.push_back(fVal); else aValues.push_back(std::numeric_limits::quiet_NaN()); } aRet.push_back(aValues); } } } return aRet; } std::vector > ChartTest::getDataSeriesLabelsFromChartType( const Reference& xCT ) { OUString aLabelRole = xCT->getRoleOfSequenceForSeriesLabel(); Reference xDSCont(xCT, uno::UNO_QUERY); CPPUNIT_ASSERT(xDSCont.is()); const Sequence > aDataSeriesSeq = xDSCont->getDataSeries(); std::vector > aRet; for (auto const & ds : aDataSeriesSeq) { uno::Reference xDSrc(ds, uno::UNO_QUERY); CPPUNIT_ASSERT(xDSrc.is()); const uno::Sequence > aDataSeqs = xDSrc->getDataSequences(); for (auto const & lds : aDataSeqs) { Reference xValues = lds->getValues(); CPPUNIT_ASSERT(xValues.is()); Reference xPropSet(xValues, uno::UNO_QUERY); if (!xPropSet.is()) continue; OUString aRoleName; xPropSet->getPropertyValue(u"Role"_ustr) >>= aRoleName; if (aRoleName == aLabelRole) { Reference xLabel = lds; CPPUNIT_ASSERT(xLabel.is()); Reference xDS2 = xLabel->getLabel(); CPPUNIT_ASSERT(xDS2.is()); uno::Sequence aData = xDS2->getData(); aRet.push_back(aData); } } } return aRet; } uno::Reference ChartTest::getChartDocFromDrawImpress( sal_Int32 nPage, sal_Int32 nShape ) { uno::Reference xEmpty; uno::Reference xPages(mxComponent, uno::UNO_QUERY); if (!xPages.is()) return xEmpty; uno::Reference xPage( xPages->getDrawPages()->getByIndex(nPage), uno::UNO_QUERY_THROW); uno::Reference xShapeProps(xPage->getByIndex(nShape), uno::UNO_QUERY); if (!xShapeProps.is()) return xEmpty; uno::Reference xDocModel; xShapeProps->getPropertyValue(u"Model"_ustr) >>= xDocModel; if (!xDocModel.is()) return xEmpty; uno::Reference xChartDoc(xDocModel, uno::UNO_QUERY); return xChartDoc; } uno::Reference ChartTest::getChartDocFromWriter( sal_Int32 nShape ) { // DO NOT use XDrawPageSupplier since SwVirtFlyDrawObj are not created // during import, only in layout! Reference xEOS(mxComponent, uno::UNO_QUERY); CPPUNIT_ASSERT(xEOS.is()); Reference xEmbeddeds(xEOS->getEmbeddedObjects(), uno::UNO_QUERY); CPPUNIT_ASSERT(xEmbeddeds.is()); Reference xShapeProps(xEmbeddeds->getByIndex(nShape), uno::UNO_QUERY); CPPUNIT_ASSERT(xShapeProps.is()); Reference xDocModel; xShapeProps->getPropertyValue(u"Model"_ustr) >>= xDocModel; CPPUNIT_ASSERT(xDocModel.is()); uno::Reference xChartDoc(xDocModel, uno::UNO_QUERY); return xChartDoc; } OUString ChartTest::getTitleString( const Reference& xTitled ) { uno::Reference xTitle = xTitled->getTitleObject(); CPPUNIT_ASSERT(xTitle.is()); const uno::Sequence > aFSSeq = xTitle->getText(); OUString aText; for (auto const & fs : aFSSeq) aText += fs->getString(); return aText; } sal_Int32 ChartTest::getNumberFormatFromAxis( const Reference& xAxis ) { Reference xPS(xAxis, uno::UNO_QUERY); CPPUNIT_ASSERT(xPS.is()); sal_Int32 nNumberFormat = -1; bool bSuccess = xPS->getPropertyValue(CHART_UNONAME_NUMFMT) >>= nNumberFormat; CPPUNIT_ASSERT(bSuccess); return nNumberFormat; } sal_Int16 ChartTest::getNumberFormatType( const Reference& xChartDoc, sal_Int32 nNumberFormat ) { Reference xNFS(xChartDoc, uno::UNO_QUERY_THROW); Reference xNumberFormats = xNFS->getNumberFormats(); CPPUNIT_ASSERT(xNumberFormats.is()); Reference xNumPS = xNumberFormats->getByKey(nNumberFormat); CPPUNIT_ASSERT(xNumPS.is()); sal_Int16 nType = util::NumberFormat::UNDEFINED; xNumPS->getPropertyValue(u"Type"_ustr) >>= nType; return nType; } uno::Reference ChartTest::getShapeByName(const uno::Reference& rShapes, const OUString& rName, const std::function&)>& pCondition) { for (sal_Int32 i = 0; i < rShapes->getCount(); ++i) { uno::Reference xShapes(rShapes->getByIndex(i), uno::UNO_QUERY); if (xShapes.is()) { uno::Reference xRet = getShapeByName(xShapes, rName, pCondition); if (xRet.is()) return xRet; } uno::Reference xNamedShape(rShapes->getByIndex(i), uno::UNO_QUERY); if (xNamedShape->getName() == rName) { uno::Reference xShape(xNamedShape, uno::UNO_QUERY); if (pCondition == nullptr || pCondition(xShape)) return xShape; } } return uno::Reference(); } /* vim:set shiftwidth=4 softtabstop=4 expandtab: */