From 203eaefb4ac012c36a1ecdd3753e1cb2c5876efc Mon Sep 17 00:00:00 2001 From: Tomaž Vajngerl Date: Fri, 29 Jul 2022 15:57:42 +0200 Subject: xmloff: import and export for the chart data table MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This change adds import and export code for the the chart's data table properties to the ODF format for chart documents. The data table properties are exported to a new element "data-table", which then references a auto style with all the properties of a data table + new data table specific properties: HBorder, VBorder, Outline, Keys which are mapped to "show-horizontal-border", "show-vertical-border", "show-outline" and "show-keys" chart attributes. Also adds a test for the import and export: imports xlsx -> exports to ods -> imports ods Change-Id: Id45d9369fd619959e4d6eba7ca51c8ddce9c8f56 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/138260 Tested-by: Jenkins Reviewed-by: Tomaž Vajngerl --- chart2/qa/extras/chart2export2.cxx | 52 ++++++++++ chart2/qa/extras/data/xlsx/ChartDataTable.xlsx | Bin 0 -> 8142 bytes include/xmloff/xmltoken.hxx | 7 +- .../OpenDocument-v1.3+libreoffice-schema.rng | 113 ++++++++++++++++----- xmloff/Library_xo.mk | 1 + xmloff/source/chart/PropertyMaps.cxx | 6 ++ xmloff/source/chart/SchXMLChartContext.cxx | 4 + xmloff/source/chart/SchXMLDataTableContext.cxx | 87 ++++++++++++++++ xmloff/source/chart/SchXMLDataTableContext.hxx | 40 ++++++++ xmloff/source/chart/SchXMLExport.cxx | 38 ++++++- xmloff/source/core/xmltoken.cxx | 11 +- xmloff/source/token/tokens.txt | 5 + 12 files changed, 330 insertions(+), 34 deletions(-) create mode 100644 chart2/qa/extras/data/xlsx/ChartDataTable.xlsx create mode 100644 xmloff/source/chart/SchXMLDataTableContext.cxx create mode 100644 xmloff/source/chart/SchXMLDataTableContext.hxx diff --git a/chart2/qa/extras/chart2export2.cxx b/chart2/qa/extras/chart2export2.cxx index be2902cbb15c..b9b77c0bd112 100644 --- a/chart2/qa/extras/chart2export2.cxx +++ b/chart2/qa/extras/chart2export2.cxx @@ -93,6 +93,7 @@ public: void testNameRangeXLSX(); void testTdf143942(); void testDateCategoriesPPTX(); + void testDataTableImportExport(); CPPUNIT_TEST_SUITE(Chart2ExportTest2); CPPUNIT_TEST(testSetSeriesToSecondaryAxisXLSX); @@ -158,6 +159,7 @@ public: CPPUNIT_TEST(testNameRangeXLSX); CPPUNIT_TEST(testTdf143942); CPPUNIT_TEST(testDateCategoriesPPTX); + CPPUNIT_TEST(testDataTableImportExport); CPPUNIT_TEST_SUITE_END(); }; @@ -1630,6 +1632,56 @@ void Chart2ExportTest2::testDateCategoriesPPTX() } } +void Chart2ExportTest2::testDataTableImportExport() +{ + load(u"/chart2/qa/extras/data/xlsx/", u"ChartDataTable.xlsx"); + { + uno::Reference xChartDoc = getChartDocFromSheet(0, mxComponent); + CPPUNIT_ASSERT(xChartDoc.is()); + auto xDiagram = xChartDoc->getFirstDiagram(); + CPPUNIT_ASSERT(xDiagram.is()); + auto xDataTable = xDiagram->getDataTable(); + CPPUNIT_ASSERT(xDataTable.is()); + uno::Reference xPropertySet(xDataTable, uno::UNO_QUERY); + CPPUNIT_ASSERT(xPropertySet.is()); + bool bHBorder; + CPPUNIT_ASSERT(xPropertySet->getPropertyValue("HBorder") >>= bHBorder); + CPPUNIT_ASSERT_EQUAL(true, bHBorder); + bool bVBorder; + CPPUNIT_ASSERT(xPropertySet->getPropertyValue("VBorder") >>= bVBorder); + CPPUNIT_ASSERT_EQUAL(true, bVBorder); + bool bOutline; + CPPUNIT_ASSERT(xPropertySet->getPropertyValue("Outline") >>= bOutline); + CPPUNIT_ASSERT_EQUAL(false, bOutline); + bool bKeys; + CPPUNIT_ASSERT(xPropertySet->getPropertyValue("Keys") >>= bKeys); + CPPUNIT_ASSERT_EQUAL(false, bKeys); + } + reload("calc8"); + { + uno::Reference xChartDoc = getChartDocFromSheet(0, mxComponent); + CPPUNIT_ASSERT(xChartDoc.is()); + auto xDiagram = xChartDoc->getFirstDiagram(); + CPPUNIT_ASSERT(xDiagram.is()); + auto xDataTable = xDiagram->getDataTable(); + CPPUNIT_ASSERT(xDataTable.is()); + uno::Reference xPropertySet(xDataTable, uno::UNO_QUERY); + CPPUNIT_ASSERT(xPropertySet.is()); + bool bHBorder; + CPPUNIT_ASSERT(xPropertySet->getPropertyValue("HBorder") >>= bHBorder); + CPPUNIT_ASSERT_EQUAL(true, bHBorder); + bool bVBorder; + CPPUNIT_ASSERT(xPropertySet->getPropertyValue("VBorder") >>= bVBorder); + CPPUNIT_ASSERT_EQUAL(true, bVBorder); + bool bOutline; + CPPUNIT_ASSERT(xPropertySet->getPropertyValue("Outline") >>= bOutline); + CPPUNIT_ASSERT_EQUAL(false, bOutline); + bool bKeys; + CPPUNIT_ASSERT(xPropertySet->getPropertyValue("Keys") >>= bKeys); + CPPUNIT_ASSERT_EQUAL(false, bKeys); + } +} + CPPUNIT_TEST_SUITE_REGISTRATION(Chart2ExportTest2); CPPUNIT_PLUGIN_IMPLEMENT(); diff --git a/chart2/qa/extras/data/xlsx/ChartDataTable.xlsx b/chart2/qa/extras/data/xlsx/ChartDataTable.xlsx new file mode 100644 index 000000000000..fff4f00aeafa Binary files /dev/null and b/chart2/qa/extras/data/xlsx/ChartDataTable.xlsx differ diff --git a/include/xmloff/xmltoken.hxx b/include/xmloff/xmltoken.hxx index 3a13ef6ff1d4..da0e0b83c879 100644 --- a/include/xmloff/xmltoken.hxx +++ b/include/xmloff/xmltoken.hxx @@ -605,6 +605,7 @@ namespace xmloff::token { XML_DATA_STREAM_SOURCE, XML_DATA_STYLE, XML_DATA_STYLE_NAME, + XML_DATA_TABLE, XML_DATA_TYPE, XML_DATABASE_DISPLAY, XML_DATABASE_NAME, @@ -1747,12 +1748,16 @@ namespace xmloff::token { XML_SHOW_CHANGES_BY_DATETIME_SECOND_DATETIME, XML_SHOW_CHANGES_BY_RANGES, XML_SHOW_CHANGES_BY_RANGES_LIST, + XML_SHOW_HORIZONTAL_BORDER, + XML_SHOW_KEYS, XML_SHOW_LOGO, XML_SHOW_REJECTED_CHANGES, XML_SHOW_SHAPE, XML_SHOW_TEXT, XML_SHOW_UNIT, XML_SHOW_VALUE, + XML_SHOW_VERTICAL_BORDER, + XML_SHOW_OUTLINE, XML_SHOWS, XML_SIDE_BY_SIDE, XML_SILVER, @@ -3421,7 +3426,7 @@ namespace xmloff::token { XML_RFC_LANGUAGE_TAG, XML_RFC_LANGUAGE_TAG_ASIAN, XML_RFC_LANGUAGE_TAG_COMPLEX, - // Chart data table properties + // (Obsolete) Chart data table properties XML_DATA_TABLE_SHOW_HORZ_BORDER, XML_DATA_TABLE_SHOW_VERT_BORDER, XML_DATA_TABLE_SHOW_OUTLINE, diff --git a/schema/libreoffice/OpenDocument-v1.3+libreoffice-schema.rng b/schema/libreoffice/OpenDocument-v1.3+libreoffice-schema.rng index c524533fd178..fe5c94a45ee4 100644 --- a/schema/libreoffice/OpenDocument-v1.3+libreoffice-schema.rng +++ b/schema/libreoffice/OpenDocument-v1.3+libreoffice-schema.rng @@ -2,34 +2,34 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -2423,6 +2453,39 @@ xmlns:loext="urn:org:documentfoundation:names:experimental:office:xmlns:loext:1. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/xmloff/Library_xo.mk b/xmloff/Library_xo.mk index 50d268b470b1..2c59632c8537 100644 --- a/xmloff/Library_xo.mk +++ b/xmloff/Library_xo.mk @@ -74,6 +74,7 @@ $(eval $(call gb_Library_add_exception_objects,xo,\ xmloff/source/chart/SchXMLAxisContext \ xmloff/source/chart/SchXMLCalculationSettingsContext \ xmloff/source/chart/SchXMLChartContext \ + xmloff/source/chart/SchXMLDataTableContext \ xmloff/source/chart/SchXMLEnumConverter \ xmloff/source/chart/SchXMLExport \ xmloff/source/chart/SchXMLImport \ diff --git a/xmloff/source/chart/PropertyMaps.cxx b/xmloff/source/chart/PropertyMaps.cxx index e40ac207a284..09a580512199 100644 --- a/xmloff/source/chart/PropertyMaps.cxx +++ b/xmloff/source/chart/PropertyMaps.cxx @@ -130,6 +130,12 @@ const XMLPropertyMapEntry aXMLChartPropMap[] = MAP_ENTRY_ODF_EXT( "LabelFillBackground", LO_EXT, XML_FILL_HATCH_SOLID, XML_TYPE_BOOL ), MAP_ENTRY_ODF_EXT( "LabelFillHatchName", LO_EXT, XML_FILL_HATCH_NAME, XML_TYPE_STYLENAME), + // Data table + MAP_ENTRY_ODF_EXT( "HBorder", LO_EXT, XML_SHOW_HORIZONTAL_BORDER, XML_TYPE_BOOL ), + MAP_ENTRY_ODF_EXT( "VBorder", LO_EXT, XML_SHOW_VERTICAL_BORDER, XML_TYPE_BOOL ), + MAP_ENTRY_ODF_EXT( "Outline", LO_EXT, XML_SHOW_OUTLINE, XML_TYPE_BOOL ), + MAP_ENTRY_ODF_EXT( "Keys", LO_EXT, XML_SHOW_KEYS, XML_TYPE_BOOL ), + MAP_ENTRY( "ScaleText", CHART, XML_SCALE_TEXT, XML_TYPE_BOOL ), // spline settings diff --git a/xmloff/source/chart/SchXMLChartContext.cxx b/xmloff/source/chart/SchXMLChartContext.cxx index 7d1a767e784f..d8be7470d013 100644 --- a/xmloff/source/chart/SchXMLChartContext.cxx +++ b/xmloff/source/chart/SchXMLChartContext.cxx @@ -20,6 +20,7 @@ #include "SchXMLChartContext.hxx" #include #include "SchXMLLegendContext.hxx" +#include "SchXMLDataTableContext.hxx" #include "SchXMLPlotAreaContext.hxx" #include "SchXMLParagraphContext.hxx" #include "SchXMLTableContext.hxx" @@ -1070,6 +1071,9 @@ css::uno::Reference< css::xml::sax::XFastContextHandler > SchXMLChartContext::cr case XML_ELEMENT(CHART, XML_LEGEND): pContext = new SchXMLLegendContext( mrImportHelper, GetImport() ); break; + case XML_ELEMENT(LO_EXT, XML_DATA_TABLE): + pContext = new SchXMLDataTableContext(mrImportHelper, GetImport()); + break; case XML_ELEMENT(TABLE, XML_TABLE): { SchXMLTableContext * pTableContext = diff --git a/xmloff/source/chart/SchXMLDataTableContext.cxx b/xmloff/source/chart/SchXMLDataTableContext.cxx new file mode 100644 index 000000000000..4271221ed71f --- /dev/null +++ b/xmloff/source/chart/SchXMLDataTableContext.cxx @@ -0,0 +1,87 @@ +/* -*- 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/. + * + * This file incorporates work covered by the following license notice: + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed + * with this work for additional information regarding copyright + * ownership. The ASF licenses this file to you under the Apache + * License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.apache.org/licenses/LICENSE-2.0 . + */ + +#include "SchXMLDataTableContext.hxx" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +using namespace ::xmloff::token; +using namespace css; + +SchXMLDataTableContext::SchXMLDataTableContext(SchXMLImportHelper& rImpHelper, SvXMLImport& rImport) + : SvXMLImportContext(rImport) + , mrImportHelper(rImpHelper) +{ +} + +void SchXMLDataTableContext::startFastElement( + sal_Int32 /*nElement*/, const uno::Reference& xAttrList) +{ + printf("SchXMLDataTableContext::startFastElement\n"); + auto xChartDocument = mrImportHelper.GetChartDocument(); + if (!xChartDocument.is()) + return; + + uno::Reference xNewChartDocument(xChartDocument, uno::UNO_QUERY); + if (!xNewChartDocument.is()) + return; + + uno::Reference xDiagram(xNewChartDocument->getFirstDiagram()); + if (!xDiagram.is()) + return; + + uno::Reference xFactory = comphelper::getProcessServiceFactory(); + uno::Reference xDataTable( + xFactory->createInstance("com.sun.star.chart2.DataTable"), uno::UNO_QUERY); + if (!xDataTable.is()) + return; + + xDiagram->setDataTable(xDataTable); + + OUString sAutoStyleName; + + for (auto& aIter : sax_fastparser::castToFastAttributeList(xAttrList)) + { + if (aIter.getToken() == XML_ELEMENT(CHART, XML_STYLE_NAME)) + sAutoStyleName = aIter.toString(); + else + XMLOFF_WARN_UNKNOWN("xmloff", aIter); + } + + // set properties + uno::Reference xPropertySet(xDataTable, uno::UNO_QUERY); + + if (!sAutoStyleName.isEmpty() && xPropertySet.is()) + { + mrImportHelper.FillAutoStyle(sAutoStyleName, xPropertySet); + } +} + +SchXMLDataTableContext::~SchXMLDataTableContext() {} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/xmloff/source/chart/SchXMLDataTableContext.hxx b/xmloff/source/chart/SchXMLDataTableContext.hxx new file mode 100644 index 000000000000..716f445ed61e --- /dev/null +++ b/xmloff/source/chart/SchXMLDataTableContext.hxx @@ -0,0 +1,40 @@ +/* -*- 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/. + * + * This file incorporates work covered by the following license notice: + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed + * with this work for additional information regarding copyright + * ownership. The ASF licenses this file to you under the Apache + * License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.apache.org/licenses/LICENSE-2.0 . + */ +#pragma once + +#include + +#include +#include + +class SchXMLDataTableContext : public SvXMLImportContext +{ +public: + SchXMLDataTableContext(SchXMLImportHelper& rImpHelper, SvXMLImport& rImport); + virtual ~SchXMLDataTableContext() override; + + virtual void SAL_CALL startFastElement( + sal_Int32 nElement, + const css::uno::Reference& xAttrList) override; + +private: + SchXMLImportHelper& mrImportHelper; +}; + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/xmloff/source/chart/SchXMLExport.cxx b/xmloff/source/chart/SchXMLExport.cxx index 533fcb569c33..0ed2683944ec 100644 --- a/xmloff/source/chart/SchXMLExport.cxx +++ b/xmloff/source/chart/SchXMLExport.cxx @@ -1147,6 +1147,8 @@ void SchXMLExportHelper_Impl::parseDocument( Reference< chart::XChartDocument > return; } + const SvtSaveOptions::ODFSaneDefaultVersion nCurrentODFVersion(mrExport.getSaneDefaultVersion()); + mxExpPropMapper->setChartDoc(xNewDoc); awt::Size aPageSize( getPageSize( xNewDoc )); @@ -1232,8 +1234,6 @@ void SchXMLExportHelper_Impl::parseDocument( Reference< chart::XChartDocument > if( bExportContent ) { //export data provider in xlink:href attribute - const SvtSaveOptions::ODFSaneDefaultVersion nCurrentODFVersion( - mrExport.getSaneDefaultVersion()); if (nCurrentODFVersion >= SvtSaveOptions::ODFSVER_012) { @@ -1407,9 +1407,6 @@ void SchXMLExportHelper_Impl::parseDocument( Reference< chart::XChartDocument > Reference< beans::XPropertySet > xProp( rChartDoc->getLegend(), uno::UNO_QUERY ); if( xProp.is()) { - const SvtSaveOptions::ODFSaneDefaultVersion nCurrentODFVersion( - mrExport.getSaneDefaultVersion()); - // export legend anchor position try { @@ -1496,6 +1493,37 @@ void SchXMLExportHelper_Impl::parseDocument( Reference< chart::XChartDocument > aPropertyStates.clear(); } + // Data table + if (xNewDiagram.is() && nCurrentODFVersion & SvtSaveOptions::ODFSVER_EXTENDED) + { + auto xDataTable = xNewDiagram->getDataTable(); + + if (xDataTable.is()) + { + // get property states for autostyles + if (mxExpPropMapper.is()) + { + uno::Reference xPropSet(xDataTable, uno::UNO_QUERY); + if (xPropSet.is()) + aPropertyStates = mxExpPropMapper->Filter(mrExport, xPropSet); + } + + if (bExportContent) + { + // add style name attribute + AddAutoStyleAttribute(aPropertyStates); + SvXMLElementExport aDataTableElement(mrExport, XML_NAMESPACE_LO_EXT, XML_DATA_TABLE, true, true); + } + else + { + CollectAutoStyle(std::move(aPropertyStates)); + } + } + + // remove property states for autostyles + aPropertyStates.clear(); + } + // plot-area element if( xDiagram.is()) exportPlotArea( xDiagram, xNewDiagram, aPageSize, bExportContent, bIncludeTable ); diff --git a/xmloff/source/core/xmltoken.cxx b/xmloff/source/core/xmltoken.cxx index 71d10f72d338..30158b20660e 100644 --- a/xmloff/source/core/xmltoken.cxx +++ b/xmloff/source/core/xmltoken.cxx @@ -617,6 +617,7 @@ namespace xmloff::token { TOKEN( "data-stream-source", XML_DATA_STREAM_SOURCE ), TOKEN( "data-style", XML_DATA_STYLE ), TOKEN( "data-style-name", XML_DATA_STYLE_NAME ), + TOKEN( "data-table", XML_DATA_TABLE ), TOKEN( "data-type", XML_DATA_TYPE ), TOKEN( "database-display", XML_DATABASE_DISPLAY ), TOKEN( "database-name", XML_DATABASE_NAME ), @@ -1760,12 +1761,16 @@ namespace xmloff::token { TOKEN( "show-changes-by-datetime-second-datetime", XML_SHOW_CHANGES_BY_DATETIME_SECOND_DATETIME ), TOKEN( "show-changes-by-ranges", XML_SHOW_CHANGES_BY_RANGES ), TOKEN( "show-changes-by-ranges-list", XML_SHOW_CHANGES_BY_RANGES_LIST ), + TOKEN( "show-horizontal-border", XML_SHOW_HORIZONTAL_BORDER ), + TOKEN( "show-keys", XML_SHOW_KEYS ), TOKEN( "show-logo", XML_SHOW_LOGO ), TOKEN( "show-rejected-changes", XML_SHOW_REJECTED_CHANGES ), TOKEN( "show-shape", XML_SHOW_SHAPE ), TOKEN( "show-text", XML_SHOW_TEXT ), TOKEN( "show-unit", XML_SHOW_UNIT ), TOKEN( "show-value", XML_SHOW_VALUE ), + TOKEN( "show-vertical-border", XML_SHOW_VERTICAL_BORDER ), + TOKEN( "show-outline", XML_SHOW_OUTLINE ), TOKEN( "shows", XML_SHOWS ), TOKEN( "side-by-side", XML_SIDE_BY_SIDE ), TOKEN( "silver", XML_SILVER ), @@ -3428,9 +3433,9 @@ namespace xmloff::token { TOKEN( "rfc-language-tag", XML_RFC_LANGUAGE_TAG ), TOKEN( "rfc-language-tag-asian", XML_RFC_LANGUAGE_TAG_ASIAN ), TOKEN( "rfc-language-tag-complex", XML_RFC_LANGUAGE_TAG_COMPLEX ), - TOKEN( "data-table-show-horz-border", XML_DATA_TABLE_SHOW_HORZ_BORDER ), - TOKEN( "data-table-show-vert-border", XML_DATA_TABLE_SHOW_VERT_BORDER ), - TOKEN( "data-table-show-outline", XML_DATA_TABLE_SHOW_OUTLINE ), + TOKEN( "data-table-show-horz-border", XML_DATA_TABLE_SHOW_HORZ_BORDER ), // obsolete - use XML_SHOW_HORIZONTAL_BORDER + TOKEN( "data-table-show-vert-border", XML_DATA_TABLE_SHOW_VERT_BORDER ), // obsolete - use XML_SHOW_VERTICAL_BORDER + TOKEN( "data-table-show-outline", XML_DATA_TABLE_SHOW_OUTLINE ), // obsolete - use XML_SHOW_OUTLINE TOKEN( "display-units", XML_CHART_DUNITS_DISPLAYUNITS ), TOKEN( "display-units-built-in-unit", XML_CHART_DUNITS_BUILTINUNIT ), TOKEN( "external-data", XML_EXTERNALDATA), diff --git a/xmloff/source/token/tokens.txt b/xmloff/source/token/tokens.txt index 0a3b256d2b99..918ab44981c4 100644 --- a/xmloff/source/token/tokens.txt +++ b/xmloff/source/token/tokens.txt @@ -522,6 +522,7 @@ data-range data-stream-source data-style data-style-name +data-table data-type database-display database-name @@ -1660,12 +1661,16 @@ show-changes-by-datetime-mode show-changes-by-datetime-second-datetime show-changes-by-ranges show-changes-by-ranges-list +show-horizontal-border +show-keys show-logo show-rejected-changes show-shape show-text show-unit show-value +show-vertical-border +show-outline shows side-by-side silver -- cgit