include/xmloff/xmlnmspe.hxx | 7 include/xmloff/xmltoken.hxx | 1 offapi/com/sun/star/chart2/data/XPivotChartDataProvider.idl | 32 + sc/inc/PivotChartDataProvider.hxx | 33 +- sc/inc/servuno.hxx | 2 sc/inc/unonames.hxx | 1 sc/source/ui/drawfunc/fuins2.cxx | 9 sc/source/ui/unoobj/PivotChartDataProvider.cxx | 196 +++++++++--- sc/source/ui/unoobj/servuno.cxx | 7 xmloff/inc/SchXMLImport.hxx | 3 xmloff/source/chart/SchXMLChartContext.cxx | 80 ++++ xmloff/source/chart/SchXMLChartContext.hxx | 2 xmloff/source/chart/SchXMLExport.cxx | 8 xmloff/source/chart/SchXMLImport.cxx | 60 --- xmloff/source/chart/SchXMLSeries2Context.cxx | 50 ++- xmloff/source/chart/SchXMLTools.cxx | 21 - xmloff/source/core/xmltoken.cxx | 1 xmloff/source/token/tokens.txt | 3 18 files changed, 385 insertions(+), 131 deletions(-)
New commits: commit ca73bdd75d4eea277e1df2c89e4da141f320ae6f Author: Tomaž Vajngerl <tomaz.vajng...@collabora.co.uk> Date: Thu Mar 30 22:53:05 2017 +0200 xmloff: add ODF import/export for pivot charts This adds import and export for pivot charts: - Added loext:data-pilot-source attribute on chart:chart which is the internal name of the pivot table with which the pivot chart is associated with. If the element is present, then the it means the chart is a pivot chart, else it is a normal chart - Added service to create pivot chart data provider through UNO - Add new methods to XPivotChartDataProvider to create value and label data sequences separately from the data source, which is needed for pivot chart import - When importing defer setting the data provider until a later time when we know if we are creating a chart od a pivot chart Change-Id: I414203518a12d0f20ca17fe55c3af7bc683f60e2 diff --git a/include/xmloff/xmlnmspe.hxx b/include/xmloff/xmlnmspe.hxx index ae588d28eeac..17f490ff582c 100644 --- a/include/xmloff/xmlnmspe.hxx +++ b/include/xmloff/xmlnmspe.hxx @@ -23,11 +23,11 @@ #include <sal/types.h> #define XML_NAMESPACE( prefix, key ) \ -const sal_uInt16 XML_NAMESPACE_##prefix = key; \ -const sal_uInt16 XML_NAMESPACE_##prefix##_IDX = key; +constexpr sal_uInt16 XML_NAMESPACE_##prefix = key; \ +constexpr sal_uInt16 XML_NAMESPACE_##prefix##_IDX = key; #define XML_OLD_NAMESPACE( prefix, index ) \ -const sal_uInt16 XML_OLD_NAMESPACE_##prefix##_IDX = \ +constexpr sal_uInt16 XML_OLD_NAMESPACE_##prefix##_IDX = \ (XML_OLD_NAMESPACE_BASE+index); // current namespaces @@ -89,7 +89,6 @@ XML_NAMESPACE_EXT( LO, 42U ) // namespaces used in the technical preview (SO 5.2) XML_OLD_NAMESPACE( FO, 0U ) XML_OLD_NAMESPACE( XLINK, 1U ) - XML_OLD_NAMESPACE( OFFICE, 2U ) XML_OLD_NAMESPACE( STYLE, 3U ) XML_OLD_NAMESPACE( TEXT, 4U ) diff --git a/include/xmloff/xmltoken.hxx b/include/xmloff/xmltoken.hxx index 70b57d1b0f8d..4e1ddd4c4cda 100644 --- a/include/xmloff/xmltoken.hxx +++ b/include/xmloff/xmltoken.hxx @@ -545,6 +545,7 @@ namespace xmloff { namespace token { XML_DATA_LABEL_NUMBER, XML_DATA_LABEL_SYMBOL, XML_DATA_LABEL_TEXT, + XML_DATA_PILOT_SOURCE, XML_DATA_PILOT_FIELD, XML_DATA_PILOT_GRAND_TOTAL, XML_DATA_PILOT_LEVEL, diff --git a/offapi/com/sun/star/chart2/data/XPivotChartDataProvider.idl b/offapi/com/sun/star/chart2/data/XPivotChartDataProvider.idl index 284d7acbc253..60c76baf889e 100644 --- a/offapi/com/sun/star/chart2/data/XPivotChartDataProvider.idl +++ b/offapi/com/sun/star/chart2/data/XPivotChartDataProvider.idl @@ -46,11 +46,41 @@ interface XPivotChartDataProvider : com::sun::star::uno::XInterface */ sequence<com::sun::star::chart2::data::PivotTableFieldEntry> getDataFields(); - /** associated pivot table name + /** get the associated pivot table name * * @since LibreOffice 5.4 */ string getPivotTableName(); + + /** set the associated pivot table name + * + * @since LibreOffice 5.4 + */ + void setPivotTableName([in] string sPivotTableName); + + /** creates a single data sequence of values for the given data series index. + * + * @param nIndex + * index of the data series + * + * @since LibreOffice 5.4 + */ + XDataSequence createDataSequenceOfValuesByIndex([in] long nIndex); + + /** creates a single data sequence of label(s) for the given data series index. + * + * @param nIndex + * index of the data series + * + * @since LibreOffice 5.4 + */ + XDataSequence createDataSequenceOfLabelsByIndex([in] long nIndex); + + /** creates a single data sequence of categories. + * + * @since LibreOffice 5.4 + */ + XDataSequence createDataSequenceOfCategories(); }; };};};};}; diff --git a/sc/inc/PivotChartDataProvider.hxx b/sc/inc/PivotChartDataProvider.hxx index 80e37945f8b7..4f3859e74003 100644 --- a/sc/inc/PivotChartDataProvider.hxx +++ b/sc/inc/PivotChartDataProvider.hxx @@ -31,8 +31,6 @@ #include <rtl/ustring.hxx> #include <svl/itemprop.hxx> -#include "dpobject.hxx" - #include <memory> #include <vector> @@ -52,7 +50,7 @@ class PivotChartDataProvider : public PivotChartDataProvider_Base, public SfxLis { public: - explicit PivotChartDataProvider(ScDocument* pDoc, OUString const& sPivotTableName); + explicit PivotChartDataProvider(ScDocument* pDoc); virtual ~PivotChartDataProvider() override; virtual void Notify(SfxBroadcaster& rBC, const SfxHint& rHint) override; @@ -91,6 +89,14 @@ public: virtual OUString SAL_CALL getPivotTableName() override; + virtual void SAL_CALL setPivotTableName(const OUString& sPivotTableName) override; + + virtual css::uno::Reference<css::chart2::data::XDataSequence> SAL_CALL + createDataSequenceOfValuesByIndex(sal_Int32 nIndex); + virtual css::uno::Reference<css::chart2::data::XDataSequence> SAL_CALL + createDataSequenceOfLabelsByIndex(sal_Int32 nIndex); + virtual css::uno::Reference<css::chart2::data::XDataSequence> SAL_CALL + createDataSequenceOfCategories(); // XPropertySet virtual css::uno::Reference<css::beans::XPropertySetInfo> SAL_CALL getPropertySetInfo() override; @@ -135,12 +141,11 @@ public: private: css::uno::Reference<css::chart2::data::XDataSource> - createPivotChartDataSource(OUString const & aRangeRepresentation); + createPivotChartValuesDataSource(OUString const & aRangeRepresentation); css::uno::Reference<css::chart2::data::XDataSource> createPivotChartCategoriesDataSource(OUString const & aRangeRepresentation, bool bOrientCol); - css::uno::Reference<css::chart2::data::XLabeledDataSequence> - createLabeledDataSequence(css::uno::Reference<css::uno::XComponentContext>& rContext); + css::uno::Reference<css::chart2::data::XLabeledDataSequence> newLabeledDataSequence(); void setLabeledDataSequenceValues(css::uno::Reference<css::chart2::data::XLabeledDataSequence> & xResult, OUString const & sRoleValues, OUString const & sIdValues, @@ -151,12 +156,14 @@ private: std::vector<PivotChartItem> const & rValues, OUString const & sRoleLabel, OUString const & sIdLabel, std::vector<PivotChartItem> const & rLabel); - void createCategories( - ScDPSaveData* pSaveData, bool bOrientCol, - css::uno::Reference<css::uno::XComponentContext>& rContext, - std::vector<css::uno::Reference<css::chart2::data::XLabeledDataSequence>>& rOutLabeledSequences); - void collectPivotTableData(ScDPObject* pDPObject); + void assignLabelsToDataSequence(css::uno::Reference<css::chart2::data::XDataSequence> & rDataSequence, + size_t nIndex); + + void assignValuesToDataSequence(css::uno::Reference<css::chart2::data::XDataSequence> & rDataSequence, + size_t nIndex); + + void collectPivotTableData(); ScDocument* m_pDocument; OUString m_sPivotTableName; @@ -173,6 +180,10 @@ private: std::vector<css::chart2::data::PivotTableFieldEntry> m_aPageFields; std::vector<css::chart2::data::PivotTableFieldEntry> m_aDataFields; + bool m_bNeedsUpdate; + + css::uno::Reference<css::uno::XComponentContext> m_xContext; + std::vector<css::uno::Reference<css::util::XModifyListener>> m_aValueListeners; }; diff --git a/sc/inc/servuno.hxx b/sc/inc/servuno.hxx index 44049dd0f98e..e81463273c49 100644 --- a/sc/inc/servuno.hxx +++ b/sc/inc/servuno.hxx @@ -50,7 +50,7 @@ public: SHEETDOCSET , // BM - CHDATAPROV , + CHDATAPROV , CHART_PIVOTTABLE_DATAPROVIDER, // formula parser FORMULAPARS , OPCODEMAPPER , // VBA specific diff --git a/sc/inc/unonames.hxx b/sc/inc/unonames.hxx index 469183d18b78..6e104542f7dc 100644 --- a/sc/inc/unonames.hxx +++ b/sc/inc/unonames.hxx @@ -32,6 +32,7 @@ #define SC_SERVICENAME_CHDATAPROV "com.sun.star.chart2.data.DataProvider" #define SC_SERVICENAME_CHRANGEHILIGHT "com.sun.star.chart2.data.RangeHighlightListener" +#define SC_SERVICENAME_CHART_PIVOTTABLE_DATAPROVIDER "com.sun.star.chart2.data.PivotTableDataProvider" // document #define SC_UNO_AREALINKS "AreaLinks" diff --git a/sc/source/ui/drawfunc/fuins2.cxx b/sc/source/ui/drawfunc/fuins2.cxx index ba4a31f618fd..c2326abaa56f 100644 --- a/sc/source/ui/drawfunc/fuins2.cxx +++ b/sc/source/ui/drawfunc/fuins2.cxx @@ -78,6 +78,7 @@ #include "drawview.hxx" #include "markdata.hxx" #include "gridwin.hxx" +#include "dpobject.hxx" #include <memory> using namespace css; @@ -134,9 +135,15 @@ void lcl_ChartInit(const uno::Reference <embed::XEmbeddedObject>& xObj, ScViewDa { uno::Reference<chart2::data::XDataProvider> xDataProvider; if (bRangeIsPivotTable) - xDataProvider.set(new sc::PivotChartDataProvider(&rScDoc, aRangeString)); + { + std::unique_ptr<sc::PivotChartDataProvider> pPivotChartDataProvider(new sc::PivotChartDataProvider(&rScDoc)); + pPivotChartDataProvider->setPivotTableName(aRangeString); + xDataProvider.set(pPivotChartDataProvider.release()); + } else + { xDataProvider.set(new ScChart2DataProvider(&rScDoc)); + } xReceiver->attachDataProvider(xDataProvider); diff --git a/sc/source/ui/unoobj/PivotChartDataProvider.cxx b/sc/source/ui/unoobj/PivotChartDataProvider.cxx index c6fce89c4f4a..954453193387 100644 --- a/sc/source/ui/unoobj/PivotChartDataProvider.cxx +++ b/sc/source/ui/unoobj/PivotChartDataProvider.cxx @@ -70,17 +70,28 @@ uno::Reference<frame::XModel> lcl_GetXModel(ScDocument * pDoc) return xModel; } +OUString lcl_identifierForData(sal_Int32 index) +{ + return "Data@" + OUString::number(index + 1); +} + +OUString lcl_identifierForLabel(sal_Int32 index) +{ + return "Label@" + OUString::number(index + 1); +} + } // end anonymous namespace -SC_SIMPLE_SERVICE_INFO( PivotChartDataProvider, "PivotChartDataProvider", "com.sun.star.chart2.data.DataProvider") +SC_SIMPLE_SERVICE_INFO(PivotChartDataProvider, "PivotChartDataProvider", SC_SERVICENAME_CHART_PIVOTTABLE_DATAPROVIDER) // DataProvider ============================================================== -PivotChartDataProvider::PivotChartDataProvider(ScDocument* pDoc, OUString const& sPivotTableName) +PivotChartDataProvider::PivotChartDataProvider(ScDocument* pDoc) : m_pDocument(pDoc) - , m_sPivotTableName(sPivotTableName) , m_aPropSet(lcl_GetDataProviderPropertyMap()) , m_bIncludeHiddenCells(true) + , m_bNeedsUpdate(true) + , m_xContext(comphelper::getProcessComponentContext()) { if (m_pDocument) m_pDocument->AddUnoObject(*this); @@ -107,6 +118,7 @@ void PivotChartDataProvider::Notify(SfxBroadcaster& /*rBC*/, const SfxHint& rHin OUString sPivotTableName = static_cast<const ScDataPilotModifiedHint&>(rHint).GetName(); if (sPivotTableName == m_sPivotTableName) { + m_bNeedsUpdate = true; for (uno::Reference<util::XModifyListener> const & xListener : m_aValueListeners) { css::chart::ChartDataChangeEvent aEvent(static_cast<cppu::OWeakObject*>(this), @@ -124,7 +136,12 @@ sal_Bool SAL_CALL PivotChartDataProvider::createDataSourcePossible(const uno::Se SolarMutexGuard aGuard; if (!m_pDocument) return false; - return true; + + if (m_sPivotTableName.isEmpty()) + return false; + + ScDPCollection* pDPCollection = m_pDocument->GetDPCollection(); + return bool(pDPCollection->GetByName(m_sPivotTableName)); } uno::Reference<chart2::data::XDataSource> SAL_CALL @@ -174,16 +191,18 @@ uno::Reference<chart2::data::XDataSource> SAL_CALL if (aRangeRepresentation == "Categories") xResult = createPivotChartCategoriesDataSource(aRangeRepresentation, bOrientCol); else - xResult = createPivotChartDataSource(aRangeRepresentation); + xResult = createPivotChartValuesDataSource(aRangeRepresentation); return xResult; } uno::Reference<chart2::data::XLabeledDataSequence> -PivotChartDataProvider::createLabeledDataSequence(uno::Reference<uno::XComponentContext>& rContext) +PivotChartDataProvider::newLabeledDataSequence() { uno::Reference<chart2::data::XLabeledDataSequence> xResult; - xResult.set(chart2::data::LabeledDataSequence::create(rContext), uno::UNO_QUERY_THROW); + if (!m_xContext.is()) + return xResult; + xResult.set(chart2::data::LabeledDataSequence::create(m_xContext), uno::UNO_QUERY_THROW); return xResult; } @@ -215,19 +234,17 @@ uno::Reference<chart2::data::XDataSource> PivotChartDataProvider::createPivotCha OUString const & rRangeRepresentation, bool bOrientCol) { - uno::Reference<chart2::data::XDataSource> xDataSource; - uno::Reference<uno::XComponentContext> xContext(comphelper::getProcessComponentContext()); - - if (!xContext.is()) - return xDataSource; + if (m_bNeedsUpdate) + collectPivotTableData(); + uno::Reference<chart2::data::XDataSource> xDataSource; std::vector<uno::Reference<chart2::data::XLabeledDataSequence>> aLabeledSequences; if (bOrientCol) { for (std::vector<PivotChartItem> const & rCategories : m_aCategoriesColumnOrientation) { - uno::Reference<chart2::data::XLabeledDataSequence> xResult = createLabeledDataSequence(xContext); + uno::Reference<chart2::data::XLabeledDataSequence> xResult = newLabeledDataSequence(); setLabeledDataSequenceValues(xResult, "categories", "Categories", rCategories); aLabeledSequences.push_back(xResult); } @@ -236,7 +253,7 @@ uno::Reference<chart2::data::XDataSource> PivotChartDataProvider::createPivotCha { for (std::vector<PivotChartItem> const & rCategories : m_aCategoriesRowOrientation) { - uno::Reference<chart2::data::XLabeledDataSequence> xResult = createLabeledDataSequence(xContext); + uno::Reference<chart2::data::XLabeledDataSequence> xResult = newLabeledDataSequence(); setLabeledDataSequenceValues(xResult, "categories", "Categories", rCategories); aLabeledSequences.push_back(xResult); } @@ -246,8 +263,11 @@ uno::Reference<chart2::data::XDataSource> PivotChartDataProvider::createPivotCha return xDataSource; } -void PivotChartDataProvider::collectPivotTableData(ScDPObject* pDPObject) +void PivotChartDataProvider::collectPivotTableData() { + ScDPCollection* pDPCollection = m_pDocument->GetDPCollection(); + ScDPObject* pDPObject = pDPCollection->GetByName(m_sPivotTableName); + uno::Reference<sheet::XDataPilotResults> xDPResults(pDPObject->GetSource(), uno::UNO_QUERY); uno::Sequence<uno::Sequence<sheet::DataResult>> xDataResultsSequence = xDPResults->getResults(); @@ -320,9 +340,9 @@ void PivotChartDataProvider::collectPivotTableData(ScDPObject* pDPObject) uno::Reference<container::XIndexAccess> xLevels = new ScNameToIndexAccess(xLevelsSupplier->getLevels()); - for (long nLev = 0; nLev < xLevels->getCount(); nLev++) + for (long nLevel = 0; nLevel < xLevels->getCount(); nLevel++) { - uno::Reference<uno::XInterface> xLevel = ScUnoHelpFunctions::AnyToInterface(xLevels->getByIndex(nLev)); + uno::Reference<uno::XInterface> xLevel = ScUnoHelpFunctions::AnyToInterface(xLevels->getByIndex(nLevel)); uno::Reference<container::XNamed> xLevelName(xLevel, uno::UNO_QUERY); uno::Reference<sheet::XDataPilotMemberResults> xLevelResult(xLevel, uno::UNO_QUERY ); @@ -482,21 +502,65 @@ void PivotChartDataProvider::collectPivotTableData(ScDPObject* pDPObject) i++; } } + + m_bNeedsUpdate = false; } -uno::Reference<chart2::data::XDataSource> PivotChartDataProvider::createPivotChartDataSource(OUString const & aRangeRepresentation) +void PivotChartDataProvider::assignValuesToDataSequence( + uno::Reference<chart2::data::XDataSequence> & rDataSequence, + size_t nIndex) { - uno::Reference<chart2::data::XDataSource> xDataSource; - std::vector<uno::Reference<chart2::data::XLabeledDataSequence>> aLabeledSequences; + if (nIndex >= m_aDataRowVector.size()) + return; - uno::Reference<uno::XComponentContext> xContext(comphelper::getProcessComponentContext()); - if (!xContext.is()) - return xDataSource; + OUString sDataID = lcl_identifierForData(nIndex); - ScDPCollection* pDPCollection = m_pDocument->GetDPCollection(); - ScDPObject* pDPObject = pDPCollection->GetByName(m_sPivotTableName); + std::vector<PivotChartItem> const & rRowOfData = m_aDataRowVector[size_t(nIndex)]; + std::unique_ptr<PivotChartDataSequence> pSequence(new PivotChartDataSequence(m_pDocument, m_sPivotTableName, + sDataID, rRowOfData)); + pSequence->setRole("values-y"); + rDataSequence.set(uno::Reference<chart2::data::XDataSequence>(pSequence.release())); +} + +void PivotChartDataProvider::assignLabelsToDataSequence( + uno::Reference<chart2::data::XDataSequence> & rDataSequence, + size_t nIndex) +{ + if (nIndex >= m_aLabels.size()) + return; + + OUString sLabelID = lcl_identifierForLabel(nIndex); + + OUString aLabel; + bool bFirst = true; + for (PivotChartItem const & rItem : m_aLabels[size_t(nIndex)]) + { + if (bFirst) + { + aLabel += rItem.m_aString; + bFirst = false; + } + else + { + aLabel += " - " + rItem.m_aString; + } + } + + std::vector<PivotChartItem> aLabelVector { PivotChartItem(aLabel) }; + + std::unique_ptr<PivotChartDataSequence> pSequence(new PivotChartDataSequence(m_pDocument, m_sPivotTableName, + sLabelID, aLabelVector)); + pSequence->setRole("values-y"); + rDataSequence.set(uno::Reference<chart2::data::XDataSequence>(pSequence.release())); +} + +uno::Reference<chart2::data::XDataSource> PivotChartDataProvider::createPivotChartValuesDataSource(OUString const & rRangeRepresentation) +{ + if (m_bNeedsUpdate) + collectPivotTableData(); - collectPivotTableData(pDPObject); + uno::Reference<chart2::data::XDataSource> xDataSource; + std::vector<uno::Reference<chart2::data::XLabeledDataSequence>> aLabeledSequences; { std::vector<PivotChartItem> aFirstCategories; @@ -504,7 +568,7 @@ uno::Reference<chart2::data::XDataSource> PivotChartDataProvider::createPivotCha m_aCategoriesColumnOrientation[0].end(), std::back_inserter(aFirstCategories)); - uno::Reference<chart2::data::XLabeledDataSequence> xResult = createLabeledDataSequence(xContext); + uno::Reference<chart2::data::XLabeledDataSequence> xResult = newLabeledDataSequence(); setLabeledDataSequenceValues(xResult, "categories", "Categories", aFirstCategories); aLabeledSequences.push_back(xResult); } @@ -513,8 +577,8 @@ uno::Reference<chart2::data::XDataSource> PivotChartDataProvider::createPivotCha int i = 0; for (std::vector<PivotChartItem> const & rRowOfData : m_aDataRowVector) { - OUString aValuesId = "Data " + OUString::number(i + 1); - OUString aLabelsId = "Label " + OUString::number(i + 1); + OUString aValuesId = lcl_identifierForData(i); + OUString aLabelsId = lcl_identifierForLabel(i); OUString aLabel; bool bFirst = true; @@ -533,7 +597,7 @@ uno::Reference<chart2::data::XDataSource> PivotChartDataProvider::createPivotCha std::vector<PivotChartItem> aLabelVector { PivotChartItem(aLabel) }; - uno::Reference<chart2::data::XLabeledDataSequence> xResult = createLabeledDataSequence(xContext); + uno::Reference<chart2::data::XLabeledDataSequence> xResult = newLabeledDataSequence(); setLabeledDataSequence(xResult, "values-y", aValuesId, rRowOfData, "values-y", aLabelsId, aLabelVector); aLabeledSequences.push_back(xResult); @@ -541,7 +605,7 @@ uno::Reference<chart2::data::XDataSource> PivotChartDataProvider::createPivotCha } } - xDataSource.set(new PivotChartDataSource(aRangeRepresentation, aLabeledSequences)); + xDataSource.set(new PivotChartDataSource(rRangeRepresentation, aLabeledSequences)); return xDataSource; } @@ -575,15 +639,14 @@ sal_Bool SAL_CALL PivotChartDataProvider::createDataSequenceByRangeRepresentatio { SolarMutexGuard aGuard; return false; - } uno::Reference< chart2::data::XDataSequence > SAL_CALL - PivotChartDataProvider::createDataSequenceByRangeRepresentation(const OUString& /*aRangeRepresentation*/) + PivotChartDataProvider::createDataSequenceByRangeRepresentation(const OUString& /*rRangeRepresentation*/) { SolarMutexGuard aGuard; - uno::Reference<chart2::data::XDataSequence> xResult; - return xResult; + uno::Reference<chart2::data::XDataSequence> xDataSequence; + return xDataSequence; } uno::Reference<chart2::data::XDataSequence> SAL_CALL @@ -629,6 +692,63 @@ OUString PivotChartDataProvider::getPivotTableName() return m_sPivotTableName; } +void PivotChartDataProvider::setPivotTableName(const OUString& sPivotTableName) +{ + ScDPCollection* pDPCollection = m_pDocument->GetDPCollection(); + ScDPObject* pDPObject = pDPCollection->GetByName(sPivotTableName); + if (pDPObject) + m_sPivotTableName = sPivotTableName; +} + +uno::Reference<chart2::data::XDataSequence> +PivotChartDataProvider::createDataSequenceOfValuesByIndex(sal_Int32 nIndex) +{ + SolarMutexGuard aGuard; + + if (m_bNeedsUpdate) + collectPivotTableData(); + + uno::Reference<chart2::data::XDataSequence> xDataSequence; + assignValuesToDataSequence(xDataSequence, size_t(nIndex)); + return xDataSequence; +} + +uno::Reference<css::chart2::data::XDataSequence> +PivotChartDataProvider::createDataSequenceOfLabelsByIndex(sal_Int32 nIndex) +{ + SolarMutexGuard aGuard; + + if (m_bNeedsUpdate) + collectPivotTableData(); + + uno::Reference<chart2::data::XDataSequence> xDataSequence; + assignLabelsToDataSequence(xDataSequence, size_t(nIndex)); + return xDataSequence; +} + +uno::Reference<css::chart2::data::XDataSequence> +PivotChartDataProvider::createDataSequenceOfCategories() +{ + SolarMutexGuard aGuard; + + if (m_bNeedsUpdate) + collectPivotTableData(); + + uno::Reference<chart2::data::XDataSequence> xDataSequence; + + if (m_aCategoriesColumnOrientation.empty()) + return xDataSequence; + + std::vector<PivotChartItem> const & rCategories = m_aCategoriesColumnOrientation[0]; + + std::unique_ptr<PivotChartDataSequence> pSequence(new PivotChartDataSequence(m_pDocument, m_sPivotTableName, + "Categories", rCategories)); + pSequence->setRole("categories"); + xDataSequence.set(uno::Reference<chart2::data::XDataSequence>(pSequence.release())); + + return xDataSequence; +} + // XModifyBroadcaster ======================================================== void SAL_CALL PivotChartDataProvider::addModifyListener( const uno::Reference< util::XModifyListener >& aListener ) @@ -643,10 +763,10 @@ void SAL_CALL PivotChartDataProvider::removeModifyListener( const uno::Reference SolarMutexGuard aGuard; sal_uInt16 nCount = m_aValueListeners.size(); - for (sal_uInt16 n = nCount; n--; ) + for (sal_uInt16 n = nCount; n--;) { - uno::Reference<util::XModifyListener>& rObj = m_aValueListeners[n]; - if (rObj == aListener) + uno::Reference<util::XModifyListener>& rObject = m_aValueListeners[n]; + if (rObject == aListener) { m_aValueListeners.erase(m_aValueListeners.begin() + n); } diff --git a/sc/source/ui/unoobj/servuno.cxx b/sc/source/ui/unoobj/servuno.cxx index 6b2fac6b79e8..032fdfa9f30c 100644 --- a/sc/source/ui/unoobj/servuno.cxx +++ b/sc/source/ui/unoobj/servuno.cxx @@ -44,6 +44,7 @@ #include "addruno.hxx" #include "chart2uno.hxx" #include "tokenuno.hxx" +#include "PivotChartDataProvider.hxx" // Support creation of GraphicObjectResolver and EmbeddedObjectResolver #include <svx/xmleohlp.hxx> @@ -292,6 +293,7 @@ const ProvNamesId_Type aProvNamesId[] = { "com.sun.star.sheet.DocumentSettings",Type::SHEETDOCSET }, { SC_SERVICENAME_CHDATAPROV, Type::CHDATAPROV }, + { SC_SERVICENAME_CHART_PIVOTTABLE_DATAPROVIDER, Type::CHART_PIVOTTABLE_DATAPROVIDER }, { SC_SERVICENAME_FORMULAPARS, Type::FORMULAPARS }, { SC_SERVICENAME_OPCODEMAPPER, Type::OPCODEMAPPER }, { "ooo.vba.VBAObjectModuleObjectProvider", Type::VBAOBJECTPROVIDER }, @@ -388,6 +390,7 @@ uno::Reference<uno::XInterface> ScServiceProvider::MakeInstance( Type nType, ScDocShell* pDocShell ) { uno::Reference<uno::XInterface> xRet; + switch (nType) { case Type::SHEET: @@ -523,6 +526,10 @@ uno::Reference<uno::XInterface> ScServiceProvider::MakeInstance( if (pDocShell) xRet = *new ScChart2DataProvider( &pDocShell->GetDocument() ); break; + case Type::CHART_PIVOTTABLE_DATAPROVIDER: + if (pDocShell) + xRet = *new sc::PivotChartDataProvider(&pDocShell->GetDocument()); + break; case Type::FORMULAPARS: if (pDocShell) xRet.set(static_cast<sheet::XFormulaParser*>(new ScFormulaParserObj( pDocShell ))); diff --git a/xmloff/inc/SchXMLImport.hxx b/xmloff/inc/SchXMLImport.hxx index 233ecde5b6c9..a1c3f698dca3 100644 --- a/xmloff/inc/SchXMLImport.hxx +++ b/xmloff/inc/SchXMLImport.hxx @@ -97,7 +97,8 @@ enum SchXMLChartAttrMap XML_TOK_CHART_HEIGHT, XML_TOK_CHART_STYLE_NAME, XML_TOK_CHART_COL_MAPPING, - XML_TOK_CHART_ROW_MAPPING + XML_TOK_CHART_ROW_MAPPING, + XML_TOK_CHART_DATA_PILOT_SOURCE, }; enum SchXMLPlotAreaAttrTokenMap diff --git a/xmloff/source/chart/SchXMLChartContext.cxx b/xmloff/source/chart/SchXMLChartContext.cxx index 4ce36805398c..79e07d4af36b 100644 --- a/xmloff/source/chart/SchXMLChartContext.cxx +++ b/xmloff/source/chart/SchXMLChartContext.cxx @@ -52,11 +52,15 @@ #include <com/sun/star/chart2/XChartDocument.hpp> #include <com/sun/star/chart2/data/XDataSink.hpp> +#include <com/sun/star/chart2/data/XPivotChartDataProvider.hpp> #include <com/sun/star/chart2/XDataSeriesContainer.hpp> #include <com/sun/star/chart2/XCoordinateSystemContainer.hpp> #include <com/sun/star/chart2/XChartTypeContainer.hpp> #include <com/sun/star/chart2/XTitled.hpp> +#include <com/sun/star/container/XChild.hpp> +#include <com/sun/star/chart2/data/XDataReceiver.hpp> + using namespace com::sun::star; using namespace ::xmloff::token; using com::sun::star::uno::Reference; @@ -237,10 +241,71 @@ SchXMLChartContext::SchXMLChartContext( SchXMLImportHelper& rImpHelper, SchXMLChartContext::~SchXMLChartContext() {} +void lcl_setDataProvider(uno::Reference<chart2::XChartDocument> xChartDoc, OUString const & sDataPilotSource) +{ + if (!xChartDoc.is()) + return; + + try + { + uno::Reference<container::XChild> xChild(xChartDoc, uno::UNO_QUERY); + uno::Reference<chart2::data::XDataReceiver> xDataReceiver(xChartDoc, uno::UNO_QUERY); + if (xChild.is() && xDataReceiver.is()) + { + bool bHasOwnData = true; + + Reference<lang::XMultiServiceFactory> xFact(xChild->getParent(), uno::UNO_QUERY); + if (xFact.is()) + { + //if the parent has a number formatter we will use the numberformatter of the parent + Reference<util::XNumberFormatsSupplier> xNumberFormatsSupplier(xFact, uno::UNO_QUERY); + xDataReceiver->attachNumberFormatsSupplier(xNumberFormatsSupplier); + + if (!xChartDoc->getDataProvider().is()) + { + bool bHasDataPilotSource = !sDataPilotSource.isEmpty(); + OUString aDataProviderServiceName("com.sun.star.chart2.data.DataProvider"); + if (bHasDataPilotSource) + aDataProviderServiceName = "com.sun.star.chart2.data.PivotTableDataProvider"; + + const uno::Sequence<OUString> aServiceNames(xFact->getAvailableServiceNames()); + + if (std::find(aServiceNames.begin(), aServiceNames.end(), aDataProviderServiceName) != aServiceNames.end()) + { + Reference<chart2::data::XDataProvider> xProvider(xFact->createInstance(aDataProviderServiceName), uno::UNO_QUERY); + + if (xProvider.is()) + { + xDataReceiver->attachDataProvider(xProvider); + if (bHasDataPilotSource) + { + Reference<chart2::data::XPivotChartDataProvider> xPivotChartProvider(xProvider, uno::UNO_QUERY); + xPivotChartProvider->setPivotTableName(sDataPilotSource); + } + bHasOwnData = false; + } + } + } + else + bHasOwnData = false; + } + // else we have no parent => we have our own data + + if (bHasOwnData && ! xChartDoc->hasInternalDataProvider()) + xChartDoc->createInternalDataProvider(false); + } + } + catch (const uno::Exception & rEx) + { + OString aBStr(OUStringToOString(rEx.Message, RTL_TEXTENCODING_ASCII_US)); + SAL_INFO("xmloff.chart", "SchXMLChartContext::StartElement(): Exception caught: " << aBStr); + } +} + void SchXMLChartContext::StartElement( const uno::Reference< xml::sax::XAttributeList >& xAttrList ) { // parse attributes - sal_Int16 nAttrCount = xAttrList.is()? xAttrList->getLength(): 0; + sal_Int16 nAttrCount = xAttrList.is() ? xAttrList->getLength() : 0; const SvXMLTokenMap& rAttrTokenMap = mrImportHelper.GetChartAttrTokenMap(); uno::Reference< embed::XVisualObject > xVisualObject( mrImportHelper.GetChartDocument(), uno::UNO_QUERY); @@ -264,10 +329,12 @@ void SchXMLChartContext::StartElement( const uno::Reference< xml::sax::XAttribut switch( rAttrTokenMap.Get( nPrefix, aLocalName )) { + case XML_TOK_CHART_DATA_PILOT_SOURCE: + msDataPilotSource = aValue; + break; case XML_TOK_CHART_HREF: m_aXLinkHRefAttributeToIndicateDataProvider = aValue; break; - case XML_TOK_CHART_CLASS: { OUString sClassName; @@ -328,6 +395,11 @@ void SchXMLChartContext::StartElement( const uno::Reference< xml::sax::XAttribut } } + uno::Reference<chart::XChartDocument> xDoc = mrImportHelper.GetChartDocument(); + uno::Reference<chart2::XChartDocument> xNewDoc(xDoc, uno::UNO_QUERY); + + lcl_setDataProvider(xNewDoc, msDataPilotSource); + if( aOldChartTypeName.isEmpty() ) { SAL_WARN("xmloff.chart", "need a charttype to create a diagram" ); @@ -660,6 +732,8 @@ static void lcl_ApplyDataFromRectangularRangeToDiagram( void SchXMLChartContext::EndElement() { + printf ("SchXMLChartContext::EndElement\n"); + uno::Reference< chart::XChartDocument > xDoc = mrImportHelper.GetChartDocument(); uno::Reference< beans::XPropertySet > xProp( xDoc, uno::UNO_QUERY ); uno::Reference< chart2::XChartDocument > xNewDoc( xDoc, uno::UNO_QUERY ); @@ -734,8 +808,10 @@ void SchXMLChartContext::EndElement() else bHasOwnData = !m_bHasRangeAtPlotArea; + printf ("bHasOwnData %d\n", bHasOwnData); if( xNewDoc->hasInternalDataProvider()) { + printf ("hasInternalDataProvider %d\n", xNewDoc->hasInternalDataProvider()); if( !m_bHasTableElement && m_aXLinkHRefAttributeToIndicateDataProvider != "." ) { //#i103147# ODF, workaround broken files with a missing table:cell-range-address at the plot-area diff --git a/xmloff/source/chart/SchXMLChartContext.hxx b/xmloff/source/chart/SchXMLChartContext.hxx index 649c9b6cc387..11b69987ac93 100644 --- a/xmloff/source/chart/SchXMLChartContext.hxx +++ b/xmloff/source/chart/SchXMLChartContext.hxx @@ -104,6 +104,8 @@ private: OUString msCategoriesAddress; OUString msChartAddress; + OUString msDataPilotSource; + SeriesDefaultsAndStyles maSeriesDefaultsAndStyles; tSchXMLLSequencesPerIndex maLSequencesPerIndex; diff --git a/xmloff/source/chart/SchXMLExport.cxx b/xmloff/source/chart/SchXMLExport.cxx index 9b8c205fa038..0edf9901b381 100644 --- a/xmloff/source/chart/SchXMLExport.cxx +++ b/xmloff/source/chart/SchXMLExport.cxx @@ -90,6 +90,7 @@ #include <com/sun/star/chart2/data/XDataReceiver.hpp> #include <com/sun/star/chart2/data/XDataProvider.hpp> #include <com/sun/star/chart2/data/XDatabaseDataProvider.hpp> +#include <com/sun/star/chart2/data/XPivotChartDataProvider.hpp> #include <com/sun/star/chart2/data/XRangeXMLConversion.hpp> #include <com/sun/star/chart2/data/XTextualDataSequence.hpp> #include <com/sun/star/chart2/data/XNumericalDataSequence.hpp> @@ -1213,6 +1214,13 @@ void SchXMLExportHelper_Impl::parseDocument( Reference< chart::XChartDocument > mrExport.AddAttribute( XML_NAMESPACE_XLINK, XML_TYPE, XML_SIMPLE ); } + Reference<chart2::data::XPivotChartDataProvider> xPivotChartDataProvider(xNewDoc->getDataProvider(), uno::UNO_QUERY); + if (xPivotChartDataProvider.is()) + { + OUString sPivotTableName = xPivotChartDataProvider->getPivotTableName(); + mrExport.AddAttribute(XML_NAMESPACE_LO_EXT, XML_DATA_PILOT_SOURCE, sPivotTableName); + } + OUString sChartType( xDiagram->getDiagramType() ); // attributes diff --git a/xmloff/source/chart/SchXMLImport.cxx b/xmloff/source/chart/SchXMLImport.cxx index 5d33fc69301b..a240a9344989 100644 --- a/xmloff/source/chart/SchXMLImport.cxx +++ b/xmloff/source/chart/SchXMLImport.cxx @@ -249,6 +249,7 @@ const SvXMLTokenMap& SchXMLImportHelper::GetChartAttrTokenMap() { XML_NAMESPACE_CHART, XML_STYLE_NAME, XML_TOK_CHART_STYLE_NAME }, { XML_NAMESPACE_CHART, XML_COLUMN_MAPPING, XML_TOK_CHART_COL_MAPPING }, { XML_NAMESPACE_CHART, XML_ROW_MAPPING, XML_TOK_CHART_ROW_MAPPING }, + { XML_NAMESPACE_LO_EXT, XML_DATA_PILOT_SOURCE, XML_TOK_CHART_DATA_PILOT_SOURCE }, XML_TOKEN_MAP_END }; @@ -574,65 +575,24 @@ SvXMLImportContext* SchXMLImport::CreateStylesContext( return pStylesCtxt; } -void SAL_CALL SchXMLImport::setTargetDocument( const uno::Reference< lang::XComponent >& xDoc ) +void SAL_CALL SchXMLImport::setTargetDocument(const uno::Reference<lang::XComponent>& xDoc) { - uno::Reference< chart2::XChartDocument > xOldDoc( GetModel(), uno::UNO_QUERY ); - if( xOldDoc.is() && xOldDoc->hasControllersLocked() ) + uno::Reference<chart2::XChartDocument> xOldDoc(GetModel(), uno::UNO_QUERY); + if (xOldDoc.is() && xOldDoc->hasControllersLocked()) xOldDoc->unlockControllers(); - SvXMLImport::setTargetDocument( xDoc ); + SvXMLImport::setTargetDocument(xDoc); - //set data provider and number formatter - // try to get an XDataProvider and set it - // @todo: if we have our own data, we must not use the parent as data provider - uno::Reference< chart2::XChartDocument > xChartDoc( GetModel(), uno::UNO_QUERY ); + uno::Reference<chart2::XChartDocument> xChartDoc(GetModel(), uno::UNO_QUERY); - if( xChartDoc.is() ) + if (xChartDoc.is()) try { - //prevent rebuild of view during load ( necesarry especially if loaded not via load api, which is the case for example if binary files are loaded ) + // prevent rebuild of view during load (necesarry especially if loaded not + // via load api, which is the case for example if binary files are loaded) xChartDoc->lockControllers(); - - uno::Reference< container::XChild > xChild( xChartDoc, uno::UNO_QUERY ); - uno::Reference< chart2::data::XDataReceiver > xDataReceiver( xChartDoc, uno::UNO_QUERY ); - if( xChild.is() && xDataReceiver.is()) - { - bool bHasOwnData = true; - - Reference< lang::XMultiServiceFactory > xFact( xChild->getParent(), uno::UNO_QUERY ); - if( xFact.is() ) - { - //if the parent has a number formatter we will use the numberformatter of the parent - Reference< util::XNumberFormatsSupplier > xNumberFormatsSupplier( xFact, uno::UNO_QUERY ); - xDataReceiver->attachNumberFormatsSupplier( xNumberFormatsSupplier ); - - if ( !xChartDoc->getDataProvider().is() ) - { - const OUString aDataProviderServiceName( "com.sun.star.chart2.data.DataProvider"); - const uno::Sequence< OUString > aServiceNames( xFact->getAvailableServiceNames()); - const OUString * pBegin = aServiceNames.getConstArray(); - const OUString * pEnd = pBegin + aServiceNames.getLength(); - if( ::std::find( pBegin, pEnd, aDataProviderServiceName ) != pEnd ) - { - Reference< chart2::data::XDataProvider > xProvider( - xFact->createInstance( aDataProviderServiceName ), uno::UNO_QUERY ); - if( xProvider.is()) - { - xDataReceiver->attachDataProvider( xProvider ); - bHasOwnData = false; - } - } - } - else - bHasOwnData = false; - } -// else we have no parent => we have our own data - - if( bHasOwnData && ! xChartDoc->hasInternalDataProvider() ) - xChartDoc->createInternalDataProvider( false ); - } } - catch( const uno::Exception & rEx ) + catch (const uno::Exception & rEx) { OString aBStr(OUStringToOString(rEx.Message, RTL_TEXTENCODING_ASCII_US)); SAL_INFO("xmloff.chart", "SchXMLChartContext::StartElement(): Exception caught: " << aBStr); diff --git a/xmloff/source/chart/SchXMLSeries2Context.cxx b/xmloff/source/chart/SchXMLSeries2Context.cxx index 70eda5253150..59676cd06014 100644 --- a/xmloff/source/chart/SchXMLSeries2Context.cxx +++ b/xmloff/source/chart/SchXMLSeries2Context.cxx @@ -30,6 +30,7 @@ #include <com/sun/star/chart2/XRegressionCurveContainer.hpp> #include <com/sun/star/chart2/data/XDataSink.hpp> #include <com/sun/star/chart2/data/XDataReceiver.hpp> +#include <com/sun/star/chart2/data/XPivotChartDataProvider.hpp> #include <com/sun/star/chart/ChartAxisAssign.hpp> #include <com/sun/star/chart/ChartSymbolType.hpp> @@ -407,20 +408,31 @@ void SchXMLSeries2Context::StartElement( const uno::Reference< xml::sax::XAttrib uno::makeAny( true )); } + Reference<chart2::data::XDataProvider> xDataProvider(mxNewDoc->getDataProvider()); + Reference<chart2::data::XPivotChartDataProvider> xPivotChartProvider(xDataProvider, uno::UNO_QUERY); + + Reference<chart2::data::XDataSequence> xSequenceValues; + // values - Reference< chart2::data::XDataSequence > xSeq; - if( bHasRange && !m_aSeriesRange.isEmpty() ) - xSeq = SchXMLTools::CreateDataSequence( m_aSeriesRange, mxNewDoc ); + if (xPivotChartProvider.is()) // is pivot chart + { + xSequenceValues.set(xPivotChartProvider->createDataSequenceOfValuesByIndex(mnSeriesIndex)); + } + else + { + if (bHasRange && !m_aSeriesRange.isEmpty()) + xSequenceValues = SchXMLTools::CreateDataSequence(m_aSeriesRange, mxNewDoc); + } - Reference< beans::XPropertySet > xSeqProp( xSeq, uno::UNO_QUERY ); - if( xSeqProp.is()) + Reference<beans::XPropertySet> xSeqProp(xSequenceValues, uno::UNO_QUERY); + if (xSeqProp.is()) { OUString aMainRole("values-y"); - if ( maSeriesChartTypeName == "com.sun.star.chart2.BubbleChartType" ) + if (maSeriesChartTypeName == "com.sun.star.chart2.BubbleChartType") aMainRole = "values-size"; - xSeqProp->setPropertyValue("Role", uno::makeAny( aMainRole )); + xSeqProp->setPropertyValue("Role", uno::makeAny(aMainRole)); } - xLabeledSeq->setValues( xSeq ); + xLabeledSeq->setValues(xSequenceValues); // register for setting local data if external data provider is not present maPostponedSequences.insert( @@ -428,18 +440,24 @@ void SchXMLSeries2Context::StartElement( const uno::Reference< xml::sax::XAttrib tSchXMLIndexWithPart( m_rGlobalSeriesImportInfo.nCurrentDataIndex, SCH_XML_PART_VALUES ), xLabeledSeq )); // label - if( !aSeriesLabelRange.isEmpty() ) + Reference<chart2::data::XDataSequence> xSequenceLabel; + + if (xPivotChartProvider.is()) { - Reference< chart2::data::XDataSequence > xLabelSequence = - SchXMLTools::CreateDataSequence( aSeriesLabelRange, mxNewDoc ); - xLabeledSeq->setLabel( xLabelSequence ); + xSequenceLabel.set(xPivotChartProvider->createDataSequenceOfLabelsByIndex(mnSeriesIndex)); } - else if( !aSeriesLabelString.isEmpty() ) + else { - Reference< chart2::data::XDataSequence > xLabelSequence = - SchXMLTools::CreateDataSequenceWithoutConvert( aSeriesLabelString, mxNewDoc ); - xLabeledSeq->setLabel( xLabelSequence ); + if (!aSeriesLabelRange.isEmpty()) + { + xSequenceLabel.set(SchXMLTools::CreateDataSequence(aSeriesLabelRange, mxNewDoc)); + } + else if (!aSeriesLabelString.isEmpty()) + { + xSequenceLabel.set(SchXMLTools::CreateDataSequenceWithoutConvert(aSeriesLabelString, mxNewDoc)); + } } + xLabeledSeq->setLabel(xSequenceLabel); // Note: Even if we have no label, we have to register the label // for creation, because internal data always has labels. If diff --git a/xmloff/source/chart/SchXMLTools.cxx b/xmloff/source/chart/SchXMLTools.cxx index 34b1a3e6b3b5..2767bdc8a7df 100644 --- a/xmloff/source/chart/SchXMLTools.cxx +++ b/xmloff/source/chart/SchXMLTools.cxx @@ -36,6 +36,7 @@ #include <com/sun/star/chart2/data/XDataProvider.hpp> #include <com/sun/star/chart2/data/XDataReceiver.hpp> #include <com/sun/star/chart2/data/XRangeXMLConversion.hpp> +#include <com/sun/star/chart2/data/XPivotChartDataProvider.hpp> #include <com/sun/star/chart2/XChartDocument.hpp> #include <com/sun/star/chart2/XCoordinateSystemContainer.hpp> #include <com/sun/star/chart2/XRegressionCurveContainer.hpp> @@ -490,11 +491,21 @@ void CreateCategories( bRangeConverted = true; } } - Reference< chart2::data::XDataSequence > xSeq( - xDataProvider->createDataSequenceByRangeRepresentation( aConvertedRange )); - xLabeledSeq->setValues( xSeq ); - if( bRangeConverted ) - setXMLRangePropertyAtDataSequence( xSeq, rRangeAddress ); + + Reference<chart2::data::XDataSequence> xSequence; + Reference<chart2::data::XPivotChartDataProvider> xPivotChartProvider(xDataProvider, uno::UNO_QUERY); + if (xPivotChartProvider.is()) + { + xSequence.set(xPivotChartProvider->createDataSequenceOfCategories()); + } + else + { + xSequence.set(xDataProvider->createDataSequenceByRangeRepresentation(aConvertedRange)); + if (bRangeConverted) + setXMLRangePropertyAtDataSequence(xSequence, rRangeAddress); + } + xLabeledSeq->setValues(xSequence); + } catch( const lang::IllegalArgumentException & ex ) { diff --git a/xmloff/source/core/xmltoken.cxx b/xmloff/source/core/xmltoken.cxx index 813c864ca264..b6918b5a90de 100644 --- a/xmloff/source/core/xmltoken.cxx +++ b/xmloff/source/core/xmltoken.cxx @@ -547,6 +547,7 @@ namespace xmloff { namespace token { TOKEN( "data-label-number", XML_DATA_LABEL_NUMBER ), TOKEN( "data-label-symbol", XML_DATA_LABEL_SYMBOL ), TOKEN( "data-label-text", XML_DATA_LABEL_TEXT ), + TOKEN( "data-pilot-source", XML_DATA_PILOT_SOURCE ), TOKEN( "data-pilot-field", XML_DATA_PILOT_FIELD ), TOKEN( "data-pilot-grand-total", XML_DATA_PILOT_GRAND_TOTAL ), TOKEN( "data-pilot-level", XML_DATA_PILOT_LEVEL ), diff --git a/xmloff/source/token/tokens.txt b/xmloff/source/token/tokens.txt index 3c9d08360b12..d44bb4383b8e 100644 --- a/xmloff/source/token/tokens.txt +++ b/xmloff/source/token/tokens.txt @@ -469,6 +469,7 @@ data-cell-range-address data-label-number data-label-symbol data-label-text +data-pilot-source data-pilot-field data-pilot-grand-total data-pilot-level @@ -3048,4 +3049,4 @@ max-numerator-digits zeros-numerator-digits zeros-denominator-digits integer-fraction-delimiter -TOKEN_END_DUMMY \ No newline at end of file +TOKEN_END_DUMMY
_______________________________________________ Libreoffice-commits mailing list libreoffice-comm...@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/libreoffice-commits