Rebased ref, commits from common ancestor: commit ff5ca3c47e4bca3ed669655540adfeb9385a5dbd Author: Tomaž Vajngerl <tomaz.vajng...@collabora.co.uk> AuthorDate: Fri Mar 4 20:40:14 2022 +0900 Commit: Tomaž Vajngerl <tomaz.vajng...@collabora.co.uk> CommitDate: Fri Mar 4 20:40:14 2022 +0900
sc: Sparkline export for OOXML documents + roundtrip test Change-Id: I4ab93d7ad33867ae817aa98d13ea9bc724b7d710 diff --git a/sc/CppunitTest_sc_sparkline_test.mk b/sc/CppunitTest_sc_sparkline_test.mk index edf7a3cac7da..00db7396cdb0 100644 --- a/sc/CppunitTest_sc_sparkline_test.mk +++ b/sc/CppunitTest_sc_sparkline_test.mk @@ -32,6 +32,7 @@ $(eval $(call gb_CppunitTest_use_libraries,sc_sparkline_test, \ test \ tl \ unotest \ + utl \ vcl \ )) diff --git a/sc/Library_scfilt.mk b/sc/Library_scfilt.mk index 8e23db6662fa..84b6e5fd5edd 100644 --- a/sc/Library_scfilt.mk +++ b/sc/Library_scfilt.mk @@ -130,6 +130,7 @@ $(eval $(call gb_Library_add_exception_objects,scfilt,\ sc/source/filter/excel/xltools \ sc/source/filter/excel/xltracer \ sc/source/filter/excel/xlview \ + sc/source/filter/excel/export/SparklineExt \ sc/source/filter/ftools/fapihelper \ sc/source/filter/ftools/fprogressbar \ sc/source/filter/ftools/ftools \ diff --git a/sc/qa/extras/SparklineTest.cxx b/sc/qa/extras/SparklineTest.cxx index 122a6b23f5be..a217747899d2 100644 --- a/sc/qa/extras/SparklineTest.cxx +++ b/sc/qa/extras/SparklineTest.cxx @@ -10,19 +10,36 @@ #include <test/calc_unoapi_test.hxx> #include <com/sun/star/lang/XComponent.hpp> +#include <unotools/tempfile.hxx> +#include <comphelper/propertyvalue.hxx> #include <docsh.hxx> #include <Sparkline.hxx> using namespace css; -namespace sc_apitest -{ class SparklineTest : public CalcUnoApiTest { uno::Reference<lang::XComponent> mxComponent; public: - SparklineTest(); + SparklineTest() + : CalcUnoApiTest("sc/qa/extras/testdocuments") + { + } + + void saveAndReload(uno::Reference<lang::XComponent>& xComponent, const OUString& rFilter) + { + utl::TempFile aTempFile; + aTempFile.EnableKillingFile(); + // "calc8", "Calc Office Open XML", ... + uno::Sequence aArgs{ comphelper::makePropertyValue("FilterName", rFilter) }; + uno::Reference<frame::XStorable> xStorable(xComponent, uno::UNO_QUERY_THROW); + xStorable->storeAsURL(aTempFile.GetURL(), aArgs); + uno::Reference<util::XCloseable> xCloseable(xComponent, uno::UNO_QUERY_THROW); + xCloseable->close(true); + + xComponent = loadFromDesktop(aTempFile.GetURL(), "com.sun.star.sheet.SpreadsheetDocument"); + } void testSparklines(); @@ -31,121 +48,224 @@ public: CPPUNIT_TEST_SUITE_END(); }; -SparklineTest::SparklineTest() - : CalcUnoApiTest("sc/qa/extras/testdocuments") -{ -} - void SparklineTest::testSparklines() { OUString aFileURL; createFileURL(u"Sparklines.xlsx", aFileURL); mxComponent = loadFromDesktop(aFileURL); - SfxObjectShell* pFoundShell = SfxObjectShell::GetShellFromComponent(mxComponent); - CPPUNIT_ASSERT_MESSAGE("Failed to access document shell", pFoundShell); - ScDocShellRef xDocSh = dynamic_cast<ScDocShell*>(pFoundShell); - CPPUNIT_ASSERT(xDocSh); - - ScDocument& rDocument = xDocSh->GetDocument(); - // Sparkline at Sheet1:A2 - { - sc::Sparkline* pSparkline = rDocument.GetSparkline(ScAddress(0, 1, 0)); // A2 - CPPUNIT_ASSERT(pSparkline); - auto pSparklineGroup = pSparkline->getSparklineGroup(); - CPPUNIT_ASSERT_EQUAL(sc::SparklineType::Line, pSparklineGroup->m_eType); - - CPPUNIT_ASSERT_EQUAL(Color(0x376092), pSparklineGroup->m_aColorSeries); - CPPUNIT_ASSERT_EQUAL(Color(0x00b050), pSparklineGroup->m_aColorNegative); - CPPUNIT_ASSERT_EQUAL(Color(0x000000), pSparklineGroup->m_aColorAxis); - CPPUNIT_ASSERT_EQUAL(Color(0x000000), pSparklineGroup->m_aColorMarkers); - CPPUNIT_ASSERT_EQUAL(Color(0x7030a0), pSparklineGroup->m_aColorFirst); - CPPUNIT_ASSERT_EQUAL(Color(0xff0000), pSparklineGroup->m_aColorLast); - CPPUNIT_ASSERT_EQUAL(Color(0x92d050), pSparklineGroup->m_aColorHigh); - CPPUNIT_ASSERT_EQUAL(Color(0x00b0f0), pSparklineGroup->m_aColorLow); - - CPPUNIT_ASSERT_EQUAL(1.0, pSparklineGroup->m_fLineWeight); - CPPUNIT_ASSERT_EQUAL(false, pSparklineGroup->m_bDateAxis); - CPPUNIT_ASSERT_EQUAL(sc::DisplayEmptyCellAs::Gap, pSparklineGroup->m_eDisplayEmptyCellsAs); - - CPPUNIT_ASSERT_EQUAL(true, pSparklineGroup->m_bMarkers); - CPPUNIT_ASSERT_EQUAL(true, pSparklineGroup->m_bHigh); - CPPUNIT_ASSERT_EQUAL(true, pSparklineGroup->m_bLow); - CPPUNIT_ASSERT_EQUAL(true, pSparklineGroup->m_bFirst); - CPPUNIT_ASSERT_EQUAL(true, pSparklineGroup->m_bLast); - CPPUNIT_ASSERT_EQUAL(true, pSparklineGroup->m_bNegative); - CPPUNIT_ASSERT_EQUAL(true, pSparklineGroup->m_bDisplayXAxis); - CPPUNIT_ASSERT_EQUAL(false, pSparklineGroup->m_bDisplayHidden); - CPPUNIT_ASSERT_EQUAL(false, pSparklineGroup->m_bRightToLeft); - - CPPUNIT_ASSERT_EQUAL(false, bool(pSparklineGroup->m_aManualMax)); - CPPUNIT_ASSERT_EQUAL(false, bool(pSparklineGroup->m_aManualMin)); - } - // Sparkline at Sheet1:A3 - { - sc::Sparkline* pSparkline = rDocument.GetSparkline(ScAddress(0, 2, 0)); // A3 - CPPUNIT_ASSERT(pSparkline); - auto pSparklineGroup = pSparkline->getSparklineGroup(); - CPPUNIT_ASSERT_EQUAL(sc::SparklineType::Column, pSparklineGroup->m_eType); - - CPPUNIT_ASSERT_EQUAL(Color(0x376092), pSparklineGroup->m_aColorSeries); - CPPUNIT_ASSERT_EQUAL(Color(0xff0000), pSparklineGroup->m_aColorNegative); - CPPUNIT_ASSERT_EQUAL(Color(0x000000), pSparklineGroup->m_aColorAxis); - CPPUNIT_ASSERT_EQUAL(Color(0xd00000), pSparklineGroup->m_aColorMarkers); - CPPUNIT_ASSERT_EQUAL(Color(0x92d050), pSparklineGroup->m_aColorFirst); - CPPUNIT_ASSERT_EQUAL(Color(0x00b0f0), pSparklineGroup->m_aColorLast); - CPPUNIT_ASSERT_EQUAL(Color(0x7030a0), pSparklineGroup->m_aColorHigh); - CPPUNIT_ASSERT_EQUAL(Color(0xffc000), pSparklineGroup->m_aColorLow); - - CPPUNIT_ASSERT_EQUAL(0.75, pSparklineGroup->m_fLineWeight); - CPPUNIT_ASSERT_EQUAL(false, pSparklineGroup->m_bDateAxis); - CPPUNIT_ASSERT_EQUAL(sc::DisplayEmptyCellAs::Gap, pSparklineGroup->m_eDisplayEmptyCellsAs); - - CPPUNIT_ASSERT_EQUAL(false, pSparklineGroup->m_bMarkers); - CPPUNIT_ASSERT_EQUAL(true, pSparklineGroup->m_bHigh); - CPPUNIT_ASSERT_EQUAL(true, pSparklineGroup->m_bLow); - CPPUNIT_ASSERT_EQUAL(true, pSparklineGroup->m_bFirst); - CPPUNIT_ASSERT_EQUAL(true, pSparklineGroup->m_bLast); - CPPUNIT_ASSERT_EQUAL(true, pSparklineGroup->m_bNegative); - CPPUNIT_ASSERT_EQUAL(false, pSparklineGroup->m_bDisplayXAxis); - CPPUNIT_ASSERT_EQUAL(false, pSparklineGroup->m_bDisplayHidden); - CPPUNIT_ASSERT_EQUAL(false, pSparklineGroup->m_bRightToLeft); - - CPPUNIT_ASSERT_EQUAL(false, bool(pSparklineGroup->m_aManualMax)); - CPPUNIT_ASSERT_EQUAL(false, bool(pSparklineGroup->m_aManualMin)); - } - // Sparkline at Sheet2:B1 { - sc::Sparkline* pSparkline = rDocument.GetSparkline(ScAddress(1, 0, 1)); //B1 - CPPUNIT_ASSERT(pSparkline); - auto pSparklineGroup = pSparkline->getSparklineGroup(); - CPPUNIT_ASSERT_EQUAL(sc::SparklineType::Column, pSparklineGroup->m_eType); - } - // Sparkline at Sheet2:B2 - { - sc::Sparkline* pSparkline = rDocument.GetSparkline(ScAddress(1, 1, 1)); //B2 - CPPUNIT_ASSERT(pSparkline); - auto pSparklineGroup = pSparkline->getSparklineGroup(); - CPPUNIT_ASSERT_EQUAL(sc::SparklineType::Line, pSparklineGroup->m_eType); - } - // Sparkline at Sheet2:B2 - { - sc::Sparkline* pSparkline = rDocument.GetSparkline(ScAddress(1, 1, 1)); //B2 - CPPUNIT_ASSERT(pSparkline); - auto pSparklineGroup = pSparkline->getSparklineGroup(); - CPPUNIT_ASSERT_EQUAL(sc::SparklineType::Line, pSparklineGroup->m_eType); + SfxObjectShell* pFoundShell = SfxObjectShell::GetShellFromComponent(mxComponent); + CPPUNIT_ASSERT_MESSAGE("Failed to access document shell", pFoundShell); + ScDocShellRef xDocSh = dynamic_cast<ScDocShell*>(pFoundShell); + CPPUNIT_ASSERT(xDocSh); + + ScDocument& rDocument = xDocSh->GetDocument(); + // Sparkline at Sheet1:A2 + { + sc::Sparkline* pSparkline = rDocument.GetSparkline(ScAddress(0, 1, 0)); // A2 + CPPUNIT_ASSERT(pSparkline); + auto pSparklineGroup = pSparkline->getSparklineGroup(); + CPPUNIT_ASSERT_EQUAL(sc::SparklineType::Line, pSparklineGroup->m_eType); + + CPPUNIT_ASSERT_EQUAL(Color(0x376092), pSparklineGroup->m_aColorSeries); + CPPUNIT_ASSERT_EQUAL(Color(0x00b050), pSparklineGroup->m_aColorNegative); + CPPUNIT_ASSERT_EQUAL(Color(0x000000), pSparklineGroup->m_aColorAxis); + CPPUNIT_ASSERT_EQUAL(Color(0x000000), pSparklineGroup->m_aColorMarkers); + CPPUNIT_ASSERT_EQUAL(Color(0x7030a0), pSparklineGroup->m_aColorFirst); + CPPUNIT_ASSERT_EQUAL(Color(0xff0000), pSparklineGroup->m_aColorLast); + CPPUNIT_ASSERT_EQUAL(Color(0x92d050), pSparklineGroup->m_aColorHigh); + CPPUNIT_ASSERT_EQUAL(Color(0x00b0f0), pSparklineGroup->m_aColorLow); + + CPPUNIT_ASSERT_EQUAL(1.0, pSparklineGroup->m_fLineWeight); + CPPUNIT_ASSERT_EQUAL(false, pSparklineGroup->m_bDateAxis); + CPPUNIT_ASSERT_EQUAL(sc::DisplayEmptyCellAs::Gap, + pSparklineGroup->m_eDisplayEmptyCellsAs); + + CPPUNIT_ASSERT_EQUAL(true, pSparklineGroup->m_bMarkers); + CPPUNIT_ASSERT_EQUAL(true, pSparklineGroup->m_bHigh); + CPPUNIT_ASSERT_EQUAL(true, pSparklineGroup->m_bLow); + CPPUNIT_ASSERT_EQUAL(true, pSparklineGroup->m_bFirst); + CPPUNIT_ASSERT_EQUAL(true, pSparklineGroup->m_bLast); + CPPUNIT_ASSERT_EQUAL(true, pSparklineGroup->m_bNegative); + CPPUNIT_ASSERT_EQUAL(true, pSparklineGroup->m_bDisplayXAxis); + CPPUNIT_ASSERT_EQUAL(false, pSparklineGroup->m_bDisplayHidden); + CPPUNIT_ASSERT_EQUAL(false, pSparklineGroup->m_bRightToLeft); + + CPPUNIT_ASSERT_EQUAL(false, bool(pSparklineGroup->m_aManualMax)); + CPPUNIT_ASSERT_EQUAL(false, bool(pSparklineGroup->m_aManualMin)); + } + // Sparkline at Sheet1:A3 + { + sc::Sparkline* pSparkline = rDocument.GetSparkline(ScAddress(0, 2, 0)); // A3 + CPPUNIT_ASSERT(pSparkline); + auto pSparklineGroup = pSparkline->getSparklineGroup(); + CPPUNIT_ASSERT_EQUAL(sc::SparklineType::Column, pSparklineGroup->m_eType); + + CPPUNIT_ASSERT_EQUAL(Color(0x376092), pSparklineGroup->m_aColorSeries); + CPPUNIT_ASSERT_EQUAL(Color(0xff0000), pSparklineGroup->m_aColorNegative); + CPPUNIT_ASSERT_EQUAL(Color(0x000000), pSparklineGroup->m_aColorAxis); + CPPUNIT_ASSERT_EQUAL(Color(0xd00000), pSparklineGroup->m_aColorMarkers); + CPPUNIT_ASSERT_EQUAL(Color(0x92d050), pSparklineGroup->m_aColorFirst); + CPPUNIT_ASSERT_EQUAL(Color(0x00b0f0), pSparklineGroup->m_aColorLast); + CPPUNIT_ASSERT_EQUAL(Color(0x7030a0), pSparklineGroup->m_aColorHigh); + CPPUNIT_ASSERT_EQUAL(Color(0xffc000), pSparklineGroup->m_aColorLow); + + CPPUNIT_ASSERT_EQUAL(0.75, pSparklineGroup->m_fLineWeight); + CPPUNIT_ASSERT_EQUAL(false, pSparklineGroup->m_bDateAxis); + CPPUNIT_ASSERT_EQUAL(sc::DisplayEmptyCellAs::Gap, + pSparklineGroup->m_eDisplayEmptyCellsAs); + + CPPUNIT_ASSERT_EQUAL(false, pSparklineGroup->m_bMarkers); + CPPUNIT_ASSERT_EQUAL(true, pSparklineGroup->m_bHigh); + CPPUNIT_ASSERT_EQUAL(true, pSparklineGroup->m_bLow); + CPPUNIT_ASSERT_EQUAL(true, pSparklineGroup->m_bFirst); + CPPUNIT_ASSERT_EQUAL(true, pSparklineGroup->m_bLast); + CPPUNIT_ASSERT_EQUAL(true, pSparklineGroup->m_bNegative); + CPPUNIT_ASSERT_EQUAL(false, pSparklineGroup->m_bDisplayXAxis); + CPPUNIT_ASSERT_EQUAL(false, pSparklineGroup->m_bDisplayHidden); + CPPUNIT_ASSERT_EQUAL(false, pSparklineGroup->m_bRightToLeft); + + CPPUNIT_ASSERT_EQUAL(false, bool(pSparklineGroup->m_aManualMax)); + CPPUNIT_ASSERT_EQUAL(false, bool(pSparklineGroup->m_aManualMin)); + } + // Sparkline at Sheet2:B1 + { + sc::Sparkline* pSparkline = rDocument.GetSparkline(ScAddress(1, 0, 1)); //B1 + CPPUNIT_ASSERT(pSparkline); + auto pSparklineGroup = pSparkline->getSparklineGroup(); + CPPUNIT_ASSERT_EQUAL(sc::SparklineType::Column, pSparklineGroup->m_eType); + } + // Sparkline at Sheet2:B2 + { + sc::Sparkline* pSparkline = rDocument.GetSparkline(ScAddress(1, 1, 1)); //B2 + CPPUNIT_ASSERT(pSparkline); + auto pSparklineGroup = pSparkline->getSparklineGroup(); + CPPUNIT_ASSERT_EQUAL(sc::SparklineType::Line, pSparklineGroup->m_eType); + } + // Sparkline at Sheet2:B2 + { + sc::Sparkline* pSparkline = rDocument.GetSparkline(ScAddress(1, 1, 1)); //B2 + CPPUNIT_ASSERT(pSparkline); + auto pSparklineGroup = pSparkline->getSparklineGroup(); + CPPUNIT_ASSERT_EQUAL(sc::SparklineType::Line, pSparklineGroup->m_eType); + } + // Sparkline doesn't exists at A4 + { + sc::Sparkline* pSparkline = rDocument.GetSparkline(ScAddress(0, 3, 0)); //A4 + CPPUNIT_ASSERT(!pSparkline); + } } - // Sparkline doesn't exists at A4 + + saveAndReload(mxComponent, "Calc Office Open XML"); + { - sc::Sparkline* pSparkline = rDocument.GetSparkline(ScAddress(0, 3, 0)); //A4 - CPPUNIT_ASSERT(!pSparkline); + SfxObjectShell* pFoundShell = SfxObjectShell::GetShellFromComponent(mxComponent); + CPPUNIT_ASSERT_MESSAGE("Failed to access document shell", pFoundShell); + ScDocShellRef xDocSh = dynamic_cast<ScDocShell*>(pFoundShell); + CPPUNIT_ASSERT(xDocSh); + + ScDocument& rDocument = xDocSh->GetDocument(); + // Sparkline at Sheet1:A2 + { + sc::Sparkline* pSparkline = rDocument.GetSparkline(ScAddress(0, 1, 0)); // A2 + CPPUNIT_ASSERT(pSparkline); + auto pSparklineGroup = pSparkline->getSparklineGroup(); + CPPUNIT_ASSERT_EQUAL(sc::SparklineType::Line, pSparklineGroup->m_eType); + + CPPUNIT_ASSERT_EQUAL(Color(0x376092), pSparklineGroup->m_aColorSeries); + CPPUNIT_ASSERT_EQUAL(Color(0x00b050), pSparklineGroup->m_aColorNegative); + CPPUNIT_ASSERT_EQUAL(Color(0x000000), pSparklineGroup->m_aColorAxis); + CPPUNIT_ASSERT_EQUAL(Color(0x000000), pSparklineGroup->m_aColorMarkers); + CPPUNIT_ASSERT_EQUAL(Color(0x7030a0), pSparklineGroup->m_aColorFirst); + CPPUNIT_ASSERT_EQUAL(Color(0xff0000), pSparklineGroup->m_aColorLast); + CPPUNIT_ASSERT_EQUAL(Color(0x92d050), pSparklineGroup->m_aColorHigh); + CPPUNIT_ASSERT_EQUAL(Color(0x00b0f0), pSparklineGroup->m_aColorLow); + + CPPUNIT_ASSERT_EQUAL(1.0, pSparklineGroup->m_fLineWeight); + CPPUNIT_ASSERT_EQUAL(false, pSparklineGroup->m_bDateAxis); + CPPUNIT_ASSERT_EQUAL(sc::DisplayEmptyCellAs::Gap, + pSparklineGroup->m_eDisplayEmptyCellsAs); + + CPPUNIT_ASSERT_EQUAL(true, pSparklineGroup->m_bMarkers); + CPPUNIT_ASSERT_EQUAL(true, pSparklineGroup->m_bHigh); + CPPUNIT_ASSERT_EQUAL(true, pSparklineGroup->m_bLow); + CPPUNIT_ASSERT_EQUAL(true, pSparklineGroup->m_bFirst); + CPPUNIT_ASSERT_EQUAL(true, pSparklineGroup->m_bLast); + CPPUNIT_ASSERT_EQUAL(true, pSparklineGroup->m_bNegative); + CPPUNIT_ASSERT_EQUAL(true, pSparklineGroup->m_bDisplayXAxis); + CPPUNIT_ASSERT_EQUAL(false, pSparklineGroup->m_bDisplayHidden); + CPPUNIT_ASSERT_EQUAL(false, pSparklineGroup->m_bRightToLeft); + + CPPUNIT_ASSERT_EQUAL(false, bool(pSparklineGroup->m_aManualMax)); + CPPUNIT_ASSERT_EQUAL(false, bool(pSparklineGroup->m_aManualMin)); + } + // Sparkline at Sheet1:A3 + { + sc::Sparkline* pSparkline = rDocument.GetSparkline(ScAddress(0, 2, 0)); // A3 + CPPUNIT_ASSERT(pSparkline); + auto pSparklineGroup = pSparkline->getSparklineGroup(); + CPPUNIT_ASSERT_EQUAL(sc::SparklineType::Column, pSparklineGroup->m_eType); + + CPPUNIT_ASSERT_EQUAL(Color(0x376092), pSparklineGroup->m_aColorSeries); + CPPUNIT_ASSERT_EQUAL(Color(0xff0000), pSparklineGroup->m_aColorNegative); + CPPUNIT_ASSERT_EQUAL(Color(0x000000), pSparklineGroup->m_aColorAxis); + CPPUNIT_ASSERT_EQUAL(Color(0xd00000), pSparklineGroup->m_aColorMarkers); + CPPUNIT_ASSERT_EQUAL(Color(0x92d050), pSparklineGroup->m_aColorFirst); + CPPUNIT_ASSERT_EQUAL(Color(0x00b0f0), pSparklineGroup->m_aColorLast); + CPPUNIT_ASSERT_EQUAL(Color(0x7030a0), pSparklineGroup->m_aColorHigh); + CPPUNIT_ASSERT_EQUAL(Color(0xffc000), pSparklineGroup->m_aColorLow); + + CPPUNIT_ASSERT_EQUAL(0.75, pSparklineGroup->m_fLineWeight); + CPPUNIT_ASSERT_EQUAL(false, pSparklineGroup->m_bDateAxis); + CPPUNIT_ASSERT_EQUAL(sc::DisplayEmptyCellAs::Gap, + pSparklineGroup->m_eDisplayEmptyCellsAs); + + CPPUNIT_ASSERT_EQUAL(false, pSparklineGroup->m_bMarkers); + CPPUNIT_ASSERT_EQUAL(true, pSparklineGroup->m_bHigh); + CPPUNIT_ASSERT_EQUAL(true, pSparklineGroup->m_bLow); + CPPUNIT_ASSERT_EQUAL(true, pSparklineGroup->m_bFirst); + CPPUNIT_ASSERT_EQUAL(true, pSparklineGroup->m_bLast); + CPPUNIT_ASSERT_EQUAL(true, pSparklineGroup->m_bNegative); + CPPUNIT_ASSERT_EQUAL(false, pSparklineGroup->m_bDisplayXAxis); + CPPUNIT_ASSERT_EQUAL(false, pSparklineGroup->m_bDisplayHidden); + CPPUNIT_ASSERT_EQUAL(false, pSparklineGroup->m_bRightToLeft); + + CPPUNIT_ASSERT_EQUAL(false, bool(pSparklineGroup->m_aManualMax)); + CPPUNIT_ASSERT_EQUAL(false, bool(pSparklineGroup->m_aManualMin)); + } + // Sparkline at Sheet2:B1 + { + sc::Sparkline* pSparkline = rDocument.GetSparkline(ScAddress(1, 0, 1)); //B1 + CPPUNIT_ASSERT(pSparkline); + auto pSparklineGroup = pSparkline->getSparklineGroup(); + CPPUNIT_ASSERT_EQUAL(sc::SparklineType::Column, pSparklineGroup->m_eType); + } + // Sparkline at Sheet2:B2 + { + sc::Sparkline* pSparkline = rDocument.GetSparkline(ScAddress(1, 1, 1)); //B2 + CPPUNIT_ASSERT(pSparkline); + auto pSparklineGroup = pSparkline->getSparklineGroup(); + CPPUNIT_ASSERT_EQUAL(sc::SparklineType::Line, pSparklineGroup->m_eType); + } + // Sparkline at Sheet2:B2 + { + sc::Sparkline* pSparkline = rDocument.GetSparkline(ScAddress(1, 1, 1)); //B2 + CPPUNIT_ASSERT(pSparkline); + auto pSparklineGroup = pSparkline->getSparklineGroup(); + CPPUNIT_ASSERT_EQUAL(sc::SparklineType::Line, pSparklineGroup->m_eType); + } + // Sparkline doesn't exists at A4 + { + sc::Sparkline* pSparkline = rDocument.GetSparkline(ScAddress(0, 3, 0)); //A4 + CPPUNIT_ASSERT(!pSparkline); + } } closeDocument(mxComponent); } CPPUNIT_TEST_SUITE_REGISTRATION(SparklineTest); -} CPPUNIT_PLUGIN_IMPLEMENT(); diff --git a/sc/source/filter/excel/excdoc.cxx b/sc/source/filter/excel/excdoc.cxx index 6b02457f70f6..529e76971cbc 100644 --- a/sc/source/filter/excel/excdoc.cxx +++ b/sc/source/filter/excel/excdoc.cxx @@ -39,6 +39,7 @@ #include <xecontent.hxx> #include <xeescher.hxx> #include <xepivot.hxx> +#include <export/SparklineExt.hxx> #include <XclExpChangeTrack.hxx> #include <xepivotxml.hxx> #include <xedbdata.hxx> @@ -611,6 +612,8 @@ void ExcTable::FillAsTableXml() // conditional formats Add( new XclExpCondFormatBuffer( GetRoot(), xExtLst ) ); + Add(new xcl::exp::SparklineBuffer(GetRoot(), xExtLst)); + // data validation (DVAL and list of DV records), generated by the cell table aRecList.AppendRecord( mxCellTable->CreateRecord( EXC_ID_DVAL ) ); diff --git a/sc/source/filter/excel/export/SparklineExt.cxx b/sc/source/filter/excel/export/SparklineExt.cxx new file mode 100644 index 000000000000..f1e97b2c62ed --- /dev/null +++ b/sc/source/filter/excel/export/SparklineExt.cxx @@ -0,0 +1,246 @@ +/* -*- 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/. + */ + +#include "export/SparklineExt.hxx" + +#include <oox/export/utils.hxx> +#include <oox/token/namespaces.hxx> +#include <oox/token/tokens.hxx> + +using namespace oox; + +namespace xcl::exp +{ +SparklineExt::SparklineExt(const XclExpRoot& rRoot, + std::vector<std::shared_ptr<sc::Sparkline>> const& pSparklines) + : XclExpExt(rRoot) +{ + maURI = "{05C60535-1F16-4fd2-B633-F4F36F0B64E0}"; + + for (auto const& pSparkline : pSparklines) + { + auto* pGroupPointer = pSparkline->getSparklineGroup().get(); + + auto aIterator = m_aSparklineGroupMap.find(pGroupPointer); + if (aIterator == m_aSparklineGroupMap.end()) + { + std::vector<std::shared_ptr<sc::Sparkline>> aSparklineVector; + aSparklineVector.push_back(pSparkline); + m_aSparklineGroupMap.emplace(pGroupPointer, aSparklineVector); + } + else + { + aIterator->second.push_back(pSparkline); + } + } +} + +void SparklineExt::SaveXml(XclExpXmlStream& rStream) +{ + sax_fastparser::FSHelperPtr& rWorksheet = rStream.GetCurrentStream(); + rWorksheet->startElement(XML_ext, FSNS(XML_xmlns, XML_x14), + rStream.getNamespaceURL(OOX_NS(xls14Lst)), XML_uri, maURI); + + rWorksheet->startElementNS(XML_x14, XML_sparklineGroups, FSNS(XML_xmlns, XML_xm), + rStream.getNamespaceURL(OOX_NS(xm))); + + for (auto const & [ pSparklineGroup, rSparklineVector ] : m_aSparklineGroupMap) + { + addSparklineGroup(rStream, *pSparklineGroup, rSparklineVector); + } + + rWorksheet->endElementNS(XML_x14, XML_sparklineGroups); + rWorksheet->endElement(XML_ext); +} + +void SparklineExt::addSparklineGroupAttributes( + rtl::Reference<sax_fastparser::FastAttributeList>& pAttrList, + sc::SparklineGroup& rSparklineGroup) +{ + if (rSparklineGroup.m_fLineWeight != 0.75) + pAttrList->add(XML_lineWeight, OString::number(rSparklineGroup.m_fLineWeight)); + + if (rSparklineGroup.m_eType != sc::SparklineType::Line) + { + if (rSparklineGroup.m_eType == sc::SparklineType::Column) + pAttrList->add(XML_type, "column"); + else if (rSparklineGroup.m_eType == sc::SparklineType::Stacked) + pAttrList->add(XML_type, "stacked"); + } + + if (rSparklineGroup.m_bDateAxis) + pAttrList->add(XML_dateAxis, "1"); + + if (rSparklineGroup.m_eDisplayEmptyCellsAs != sc::DisplayEmptyCellAs::Zero) + { + if (rSparklineGroup.m_eDisplayEmptyCellsAs == sc::DisplayEmptyCellAs::Gap) + pAttrList->add(XML_displayEmptyCellsAs, "gap"); + else if (rSparklineGroup.m_eDisplayEmptyCellsAs == sc::DisplayEmptyCellAs::Span) + pAttrList->add(XML_displayEmptyCellsAs, "span"); + } + + if (rSparklineGroup.m_bMarkers) + pAttrList->add(XML_markers, "1"); + if (rSparklineGroup.m_bHigh) + pAttrList->add(XML_high, "1"); + if (rSparklineGroup.m_bLow) + pAttrList->add(XML_low, "1"); + if (rSparklineGroup.m_bFirst) + pAttrList->add(XML_first, "1"); + if (rSparklineGroup.m_bLast) + pAttrList->add(XML_last, "1"); + if (rSparklineGroup.m_bNegative) + pAttrList->add(XML_negative, "1"); + if (rSparklineGroup.m_bDisplayXAxis) + pAttrList->add(XML_displayXAxis, "1"); + if (rSparklineGroup.m_bDisplayHidden) + pAttrList->add(XML_displayHidden, "1"); + + if (rSparklineGroup.m_eMinAxisType != sc::AxisType::Individual) + { + if (rSparklineGroup.m_eMinAxisType == sc::AxisType::Group) + pAttrList->add(XML_minAxisType, "group"); + else if (rSparklineGroup.m_eMinAxisType == sc::AxisType::Custom) + pAttrList->add(XML_minAxisType, "custom"); + } + + if (rSparklineGroup.m_eMaxAxisType != sc::AxisType::Individual) + { + if (rSparklineGroup.m_eMaxAxisType == sc::AxisType::Group) + pAttrList->add(XML_maxAxisType, "group"); + else if (rSparklineGroup.m_eMaxAxisType == sc::AxisType::Custom) + pAttrList->add(XML_maxAxisType, "custom"); + } + + if (rSparklineGroup.m_bRightToLeft) + pAttrList->add(XML_rightToLeft, "1"); + + if (rSparklineGroup.m_aManualMax && rSparklineGroup.m_eMaxAxisType == sc::AxisType::Custom) + pAttrList->add(XML_manualMax, OString::number(*rSparklineGroup.m_aManualMax)); + + if (rSparklineGroup.m_aManualMin && rSparklineGroup.m_eMinAxisType == sc::AxisType::Custom) + pAttrList->add(XML_manualMin, OString::number(*rSparklineGroup.m_aManualMin)); +} + +void SparklineExt::addSparklineGroupColors(XclExpXmlStream& rStream, + sc::SparklineGroup& rSparklineGroup) +{ + sax_fastparser::FSHelperPtr& rWorksheet = rStream.GetCurrentStream(); + + rWorksheet->singleElementNS(XML_x14, XML_colorSeries, XML_rgb, + XclXmlUtils::ToOString(rSparklineGroup.m_aColorSeries)); + + if (rSparklineGroup.m_aColorSeries != COL_TRANSPARENT) + { + rWorksheet->singleElementNS(XML_x14, XML_colorNegative, XML_rgb, + XclXmlUtils::ToOString(rSparklineGroup.m_aColorNegative)); + } + + if (rSparklineGroup.m_aColorAxis != COL_TRANSPARENT) + { + rWorksheet->singleElementNS(XML_x14, XML_colorAxis, XML_rgb, + XclXmlUtils::ToOString(rSparklineGroup.m_aColorAxis)); + } + + if (rSparklineGroup.m_aColorMarkers != COL_TRANSPARENT) + { + rWorksheet->singleElementNS(XML_x14, XML_colorMarkers, XML_rgb, + XclXmlUtils::ToOString(rSparklineGroup.m_aColorMarkers)); + } + + if (rSparklineGroup.m_aColorFirst != COL_TRANSPARENT) + { + rWorksheet->singleElementNS(XML_x14, XML_colorFirst, XML_rgb, + XclXmlUtils::ToOString(rSparklineGroup.m_aColorFirst)); + } + + if (rSparklineGroup.m_aColorLast != COL_TRANSPARENT) + { + rWorksheet->singleElementNS(XML_x14, XML_colorLast, XML_rgb, + XclXmlUtils::ToOString(rSparklineGroup.m_aColorLast)); + } + + if (rSparklineGroup.m_aColorHigh != COL_TRANSPARENT) + { + rWorksheet->singleElementNS(XML_x14, XML_colorHigh, XML_rgb, + XclXmlUtils::ToOString(rSparklineGroup.m_aColorHigh)); + } + + if (rSparklineGroup.m_aColorLow != COL_TRANSPARENT) + { + rWorksheet->singleElementNS(XML_x14, XML_colorLow, XML_rgb, + XclXmlUtils::ToOString(rSparklineGroup.m_aColorLow)); + } +} + +void SparklineExt::addSparklineGroup(XclExpXmlStream& rStream, sc::SparklineGroup& rSparklineGroup, + std::vector<std::shared_ptr<sc::Sparkline>> const& rSparklines) +{ + sax_fastparser::FSHelperPtr& rWorksheet = rStream.GetCurrentStream(); + + // Sparkline Group Attributes + auto pAttrList = sax_fastparser::FastSerializerHelper::createAttrList(); + addSparklineGroupAttributes(pAttrList, rSparklineGroup); + + rWorksheet->startElementNS(XML_x14, XML_sparklineGroup, pAttrList); + + addSparklineGroupColors(rStream, rSparklineGroup); + + // Sparklines + + rWorksheet->startElementNS(XML_x14, XML_sparklines); + for (auto const& rSparkline : rSparklines) + { + rWorksheet->startElementNS(XML_x14, XML_sparkline); + + { + rWorksheet->startElementNS(XML_xm, XML_f); + + OUString sRangeFormula; + ScRefFlags eFlags = ScRefFlags::VALID | ScRefFlags::TAB_3D; + rSparkline->getInputRange().Format(sRangeFormula, eFlags, GetDoc(), + formula::FormulaGrammar::CONV_XL_OOX, ' ', true); + + rWorksheet->writeEscaped(sRangeFormula); + rWorksheet->endElementNS(XML_xm, XML_f); + } + + { + rWorksheet->startElementNS(XML_xm, XML_sqref); + + ScAddress::Details detailsXL(formula::FormulaGrammar::CONV_XL_OOX); + ScAddress aAddress(rSparkline->getColumn(), rSparkline->getRow(), GetCurrScTab()); + OUString sLocation = aAddress.Format(ScRefFlags::VALID, &GetDoc(), detailsXL); + + rWorksheet->writeEscaped(sLocation); + rWorksheet->endElementNS(XML_xm, XML_sqref); + } + + rWorksheet->endElementNS(XML_x14, XML_sparkline); + } + rWorksheet->endElementNS(XML_x14, XML_sparklines); + rWorksheet->endElementNS(XML_x14, XML_sparklineGroup); +} + +SparklineBuffer::SparklineBuffer(const XclExpRoot& rRoot, XclExtLstRef const& xExtLst) + : XclExpRoot(rRoot) +{ + if (sc::SparklineList* pSparklineList = GetDoc().GetSparklineList(GetCurrScTab())) + { + auto pSparklines = pSparklineList->getSparklines(); + if (!pSparklines.empty()) + { + xExtLst->AddRecord(new xcl::exp::SparklineExt(GetRoot(), pSparklines)); + } + } +} + +} // end namespace xcl::exp + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/sc/source/filter/inc/export/SparklineExt.hxx b/sc/source/filter/inc/export/SparklineExt.hxx new file mode 100644 index 000000000000..116462c5f3c4 --- /dev/null +++ b/sc/source/filter/inc/export/SparklineExt.hxx @@ -0,0 +1,52 @@ +/* -*- 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 <memory> +#include <vector> +#include <map> +#include <rangelst.hxx> +#include <Sparkline.hxx> + +#include <sax/fastattribs.hxx> + +#include "xerecord.hxx" +#include "xeroot.hxx" +#include "xeextlst.hxx" + +namespace xcl::exp +{ +class SparklineExt : public XclExpExt +{ + std::map<sc::SparklineGroup*, std::vector<std::shared_ptr<sc::Sparkline>>> m_aSparklineGroupMap; + +public: + SparklineExt(const XclExpRoot& rRoot, + std::vector<std::shared_ptr<sc::Sparkline>> const& pSparklines); + + void SaveXml(XclExpXmlStream& rStream) override; + void addSparklineGroup(XclExpXmlStream& rStream, sc::SparklineGroup& rSparklineGroup, + std::vector<std::shared_ptr<sc::Sparkline>> const& rSparklines); + void addSparklineGroupAttributes(rtl::Reference<sax_fastparser::FastAttributeList>& pAttrList, + sc::SparklineGroup& rSparklineGroup); + void addSparklineGroupColors(XclExpXmlStream& rStream, sc::SparklineGroup& rSparklineGroup); + + XclExpExtType GetType() override { return XclExpExtSparklineType; } +}; + +class SparklineBuffer : public XclExpRecordBase, protected XclExpRoot +{ +public: + explicit SparklineBuffer(const XclExpRoot& rRoot, const XclExtLstRef& xExtLst); +}; + +} // end namespace xcl::exp + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/sc/source/filter/inc/xeextlst.hxx b/sc/source/filter/inc/xeextlst.hxx index c5db5fcaff99..1770f9af191d 100644 --- a/sc/source/filter/inc/xeextlst.hxx +++ b/sc/source/filter/inc/xeextlst.hxx @@ -19,7 +19,8 @@ enum XclExpExtType { XclExpExtDataBarType, - XclExpExtDataFooType + XclExpExtDataFooType, + XclExpExtSparklineType, }; struct XclExpExtCondFormatData commit 2c5a429b2deb52c40340a59292079987336a5523 Author: Tomaž Vajngerl <tomaz.vajng...@collabora.co.uk> AuthorDate: Fri Mar 4 17:26:34 2022 +0900 Commit: Tomaž Vajngerl <tomaz.vajng...@collabora.co.uk> CommitDate: Fri Mar 4 17:26:34 2022 +0900 sc: set colors in SparklineGroup construction to COL_TRANSPARENT Change-Id: I67ceab2ffd723511fbf0616cca661992f0a8cf69 diff --git a/sc/inc/SparklineGroup.hxx b/sc/inc/SparklineGroup.hxx index 32e4b757378f..170ccee51539 100644 --- a/sc/inc/SparklineGroup.hxx +++ b/sc/inc/SparklineGroup.hxx @@ -74,7 +74,17 @@ public: std::optional<double> m_aManualMin; OUString m_sUID; - SparklineGroup() {} + SparklineGroup() + : m_aColorSeries(COL_TRANSPARENT) + , m_aColorNegative(COL_TRANSPARENT) + , m_aColorAxis(COL_TRANSPARENT) + , m_aColorMarkers(COL_TRANSPARENT) + , m_aColorFirst(COL_TRANSPARENT) + , m_aColorLast(COL_TRANSPARENT) + , m_aColorHigh(COL_TRANSPARENT) + , m_aColorLow(COL_TRANSPARENT) + { + } SparklineGroup(const SparklineGroup&) = delete; SparklineGroup& operator=(const SparklineGroup&) = delete; commit 3d357d5d4205cee25354f12c09d124e067c2d050 Author: Tomaž Vajngerl <tomaz.vajng...@collabora.co.uk> AuthorDate: Wed Mar 2 17:44:08 2022 +0900 Commit: Tomaž Vajngerl <tomaz.vajng...@collabora.co.uk> CommitDate: Fri Mar 4 12:45:25 2022 +0900 sc: refactor sparkline struture to store a list of sparklines We need to access a list of sparklines and sparkline groups for a sheet. To preven going through all the columns of a sheet, we need to store all the created sparklines in a list. For this it is necessary to change the model structrue a bit. A cell now has a container that stores a shared_ptr to the sparkline instead of storing the sparkline directly. With this we can store a list of weak_ptr to the sparklines in a list (vector), which can be accessed at any time and is quite fast. This is needed by the OOXML export. Change-Id: Iaca0a41e20912775f072ea6e8cab9c44367d6f30 diff --git a/sc/Library_sc.mk b/sc/Library_sc.mk index 11449217edd9..62ab22a797c4 100644 --- a/sc/Library_sc.mk +++ b/sc/Library_sc.mk @@ -185,7 +185,6 @@ $(eval $(call gb_Library_add_exception_objects,sc,\ sc/source/core/data/sheetevents \ sc/source/core/data/simpleformulacalc \ sc/source/core/data/sortparam \ - sc/source/core/data/Sparkline \ sc/source/core/data/stlpool \ sc/source/core/data/stlsheet \ sc/source/core/data/subtotalparam \ diff --git a/sc/inc/Sparkline.hxx b/sc/inc/Sparkline.hxx index 8969fa3bfd3e..ad4688f33a5e 100644 --- a/sc/inc/Sparkline.hxx +++ b/sc/inc/Sparkline.hxx @@ -19,20 +19,67 @@ namespace sc { class SC_DLLPUBLIC Sparkline { -private: + SCCOL m_nColumn; + SCROW m_nRow; + ScRangeList m_aInputRange; std::shared_ptr<SparklineGroup> m_pSparklineGroup; public: - Sparkline(std::shared_ptr<SparklineGroup>& pSparklineGroup); + Sparkline(SCCOL nColumn, SCROW nRow, std::shared_ptr<SparklineGroup> const& pSparklineGroup) + : m_nColumn(nColumn) + , m_nRow(nRow) + , m_pSparklineGroup(pSparklineGroup) + { + } Sparkline(const Sparkline&) = delete; Sparkline& operator=(const Sparkline&) = delete; void setInputRange(ScRangeList const& rInputRange) { m_aInputRange = rInputRange; } + ScRangeList const& getInputRange() { return m_aInputRange; } std::shared_ptr<SparklineGroup> const& getSparklineGroup() { return m_pSparklineGroup; } + + SCCOL getColumn() { return m_nColumn; } + + SCROW getRow() { return m_nRow; } +}; + +class SC_DLLPUBLIC SparklineList +{ +private: + std::vector<std::weak_ptr<Sparkline>> m_pSparklines; + +public: + SparklineList() {} + + void addSparkline(std::shared_ptr<Sparkline> const& pSparkline) + { + m_pSparklines.push_back(pSparkline); + } + + std::vector<std::shared_ptr<Sparkline>> getSparklines() + { + std::vector<std::shared_ptr<Sparkline>> toReturn; + + std::vector<std::weak_ptr<Sparkline>>::iterator aIter; + for (aIter = m_pSparklines.begin(); aIter != m_pSparklines.end();) + { + if (auto aSparkline = aIter->lock()) + { + toReturn.push_back(aSparkline); + aIter++; + } + else + { + aIter = m_pSparklines.erase(aIter); + } + } + + return toReturn; + } }; } // end sc diff --git a/sc/inc/SparklineCell.hxx b/sc/inc/SparklineCell.hxx new file mode 100644 index 000000000000..0aca857170c9 --- /dev/null +++ b/sc/inc/SparklineCell.hxx @@ -0,0 +1,47 @@ +/* -*- 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 "scdllapi.h" +#include "Sparkline.hxx" +#include <memory> + +namespace sc +{ +class SC_DLLPUBLIC SparklineCell +{ +private: + std::shared_ptr<Sparkline> m_pSparkline; + +public: + SparklineCell(std::shared_ptr<Sparkline> const& pSparkline) + : m_pSparkline(pSparkline) + { + } + + SparklineCell(const SparklineCell&) = delete; + SparklineCell& operator=(const SparklineCell&) = delete; + + void setInputRange(ScRangeList const& rInputRange) { m_pSparkline->setInputRange(rInputRange); } + + ScRangeList const& getInputRange() { return m_pSparkline->getInputRange(); } + + std::shared_ptr<SparklineGroup> const& getSparklineGroup() + { + return m_pSparkline->getSparklineGroup(); + } + + std::shared_ptr<Sparkline> const& getSparkline() { return m_pSparkline; } +}; + +} // end sc + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/sc/inc/column.hxx b/sc/inc/column.hxx index 4c711b9944dc..17e0d61f79c4 100644 --- a/sc/inc/column.hxx +++ b/sc/inc/column.hxx @@ -617,8 +617,8 @@ public: void BroadcastRows( SCROW nStartRow, SCROW nEndRow, SfxHintId nHint ); // Spaklines - sc::Sparkline* GetSparkline(SCROW nRow); - void SetSparkline(SCROW nRow, std::unique_ptr<sc::Sparkline> pSparkline); + sc::SparklineCell* GetSparklineCell(SCROW nRow); + void CreateSparklineCell(SCROW nRow, std::shared_ptr<sc::Sparkline> const& pSparkline); // cell notes ScPostIt* GetCellNote( SCROW nRow ); diff --git a/sc/inc/document.hxx b/sc/inc/document.hxx index d0ef2006846e..84ee8184d2e9 100644 --- a/sc/inc/document.hxx +++ b/sc/inc/document.hxx @@ -103,6 +103,7 @@ class ColumnIterator; class ExternalDataMapper; class Sparkline; class SparklineGroup; +class SparklineList; } @@ -1240,6 +1241,7 @@ public: /** Spaklines */ SC_DLLPUBLIC sc::Sparkline* GetSparkline(ScAddress const & rPosition); SC_DLLPUBLIC sc::Sparkline* CreateSparkline(ScAddress const & rPosition, std::shared_ptr<sc::SparklineGroup> & pSparklineGroup); + SC_DLLPUBLIC sc::SparklineList* GetSparklineList(SCTAB nTab); /** Notes **/ SC_DLLPUBLIC ScPostIt* GetNote(const ScAddress& rPos); diff --git a/sc/inc/mtvelements.hxx b/sc/inc/mtvelements.hxx index 979a09c641db..c60a8832c8df 100644 --- a/sc/inc/mtvelements.hxx +++ b/sc/inc/mtvelements.hxx @@ -15,7 +15,7 @@ #include <editeng/editobj.hxx> #include "calcmacros.hxx" #include "postit.hxx" -#include "Sparkline.hxx" +#include "SparklineCell.hxx" #include "celltextattr.hxx" #if DEBUG_COLUMN_STORAGE @@ -59,7 +59,7 @@ const mdds::mtv::element_t element_type_uint16 = mdds::mtv::element_type_uint16; /// Custom element blocks. -typedef mdds::mtv::noncopyable_managed_element_block<element_type_sparkline, sc::Sparkline> sparkline_block; +typedef mdds::mtv::noncopyable_managed_element_block<element_type_sparkline, sc::SparklineCell> sparkline_block; typedef mdds::mtv::noncopyable_managed_element_block<element_type_cellnote, ScPostIt> cellnote_block; typedef mdds::mtv::noncopyable_managed_element_block<element_type_broadcaster, SvtBroadcaster> broadcaster_block; typedef mdds::mtv::default_element_block<element_type_celltextattr, CellTextAttr> celltextattr_block; @@ -77,7 +77,7 @@ typedef mdds::mtv::uint16_element_block uint16_block; /// For example sc types like sc::CellTextAttr, ScFormulaCell in global namespace. namespace sc { MDDS_MTV_DEFINE_ELEMENT_CALLBACKS(CellTextAttr, element_type_celltextattr, CellTextAttr(), celltextattr_block) -MDDS_MTV_DEFINE_ELEMENT_CALLBACKS_PTR(Sparkline, sc::element_type_sparkline, nullptr, sc::sparkline_block) +MDDS_MTV_DEFINE_ELEMENT_CALLBACKS_PTR(SparklineCell, sc::element_type_sparkline, nullptr, sc::sparkline_block) } /// These need to be in global namespace just like their respective types are. diff --git a/sc/inc/table.hxx b/sc/inc/table.hxx index 30c92cd87520..534da038bf54 100644 --- a/sc/inc/table.hxx +++ b/sc/inc/table.hxx @@ -227,6 +227,7 @@ private: mutable std::unique_ptr<ScRangeName> mpRangeName; std::unique_ptr<ScConditionalFormatList> mpCondFormatList; + sc::SparklineList maSparklineList; ScAddress maLOKFreezeCell; @@ -472,6 +473,14 @@ public: void GetFirstDataPos(SCCOL& rCol, SCROW& rRow) const; void GetLastDataPos(SCCOL& rCol, SCROW& rRow) const; + // Sparklines + + sc::Sparkline* GetSparkline(SCCOL nCol, SCROW nRow); + sc::Sparkline* CreateSparkline(SCCOL nCol, SCROW nRow, std::shared_ptr<sc::SparklineGroup> & pSparklineGroup); + + sc::SparklineList& GetSparklineList(); + + // Notes / Comments std::unique_ptr<ScPostIt> ReleaseNote( SCCOL nCol, SCROW nRow ); ScPostIt* GetNote( SCCOL nCol, SCROW nRow ); void SetNote( SCCOL nCol, SCROW nRow, std::unique_ptr<ScPostIt> pNote ); diff --git a/sc/source/core/data/Sparkline.cxx b/sc/source/core/data/Sparkline.cxx deleted file mode 100644 index 301fda820ff2..000000000000 --- a/sc/source/core/data/Sparkline.cxx +++ /dev/null @@ -1,22 +0,0 @@ -/* -*- 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/. - * - */ - -#include <memory> -#include <Sparkline.hxx> - -namespace sc -{ -Sparkline::Sparkline(std::shared_ptr<SparklineGroup>& pSparklineGroup) - : m_pSparklineGroup(pSparklineGroup) -{ -} -} - -/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/sc/source/core/data/column2.cxx b/sc/source/core/data/column2.cxx index 9eb661e49d9d..d391c4baaeae 100644 --- a/sc/source/core/data/column2.cxx +++ b/sc/source/core/data/column2.cxx @@ -1977,14 +1977,14 @@ void ScColumn::PrepareBroadcastersForDestruction() } } -sc::Sparkline* ScColumn::GetSparkline(SCROW nRow) +sc::SparklineCell* ScColumn::GetSparklineCell(SCROW nRow) { - return maSparklines.get<sc::Sparkline*>(nRow); + return maSparklines.get<sc::SparklineCell*>(nRow); } -void ScColumn::SetSparkline(SCROW nRow, std::unique_ptr<sc::Sparkline> pSparkline) +void ScColumn::CreateSparklineCell(SCROW nRow, std::shared_ptr<sc::Sparkline> const& pSparkline) { - maSparklines.set(nRow, pSparkline.release()); + maSparklines.set(nRow, new sc::SparklineCell(pSparkline)); } ScPostIt* ScColumn::GetCellNote(SCROW nRow) diff --git a/sc/source/core/data/document.cxx b/sc/source/core/data/document.cxx index 7f1eeab2d12a..88b1d7ce12b9 100644 --- a/sc/source/core/data/document.cxx +++ b/sc/source/core/data/document.cxx @@ -6513,33 +6513,41 @@ bool ScDocument::IsInVBAMode() const return false; } +// Sparklines sc::Sparkline* ScDocument::GetSparkline(ScAddress const& rPosition) { SCTAB nTab = rPosition.Tab(); - SCCOL nCol = rPosition.Col(); - if (ValidTab(nTab) && nTab < SCTAB(maTabs.size()) && - nCol < maTabs[nTab]->GetAllocatedColumnsCount()) + if (ValidTab(nTab) && nTab < SCTAB(maTabs.size())) { - SCROW nRow = rPosition.Row(); - return maTabs[nTab]->aCol[nCol].GetSparkline(nRow); + return maTabs[nTab]->GetSparkline(rPosition.Col(), rPosition.Row()); } return nullptr; } sc::Sparkline* ScDocument::CreateSparkline(ScAddress const & rPosition, std::shared_ptr<sc::SparklineGroup> & pSparklineGroup) { - std::unique_ptr<sc::Sparkline> pSparkline(new sc::Sparkline(pSparklineGroup)); - sc::Sparkline* pCreated = pSparkline.get(); - SCTAB nTab = rPosition.Tab(); - SCCOL nCol = rPosition.Col(); - SCROW nRow = rPosition.Row(); - maTabs[nTab]->CreateColumnIfNotExists(nCol).SetSparkline(nRow, std::move(pSparkline)); - return pCreated; + if (ValidTab(nTab) && nTab < SCTAB(maTabs.size())) + { + return maTabs[nTab]->CreateSparkline(rPosition.Col(), rPosition.Row(), pSparklineGroup); + } + + return nullptr; +} + +sc::SparklineList* ScDocument::GetSparklineList(SCTAB nTab) +{ + if (ValidTab(nTab) && nTab < SCTAB(maTabs.size())) + { + return &maTabs[nTab]->GetSparklineList(); + } + return nullptr; } +// Notes + ScPostIt* ScDocument::GetNote(const ScAddress& rPos) { return GetNote(rPos.Col(), rPos.Row(), rPos.Tab()); diff --git a/sc/source/core/data/table2.cxx b/sc/source/core/data/table2.cxx index e0753b15d252..d79b3a910d28 100644 --- a/sc/source/core/data/table2.cxx +++ b/sc/source/core/data/table2.cxx @@ -1809,6 +1809,43 @@ ScFormulaCell* ScTable::GetFormulaCell( SCCOL nCol, SCROW nRow ) return aCol[nCol].GetFormulaCell(nRow); } +// Sparklines + +sc::Sparkline* ScTable::GetSparkline(SCCOL nCol, SCROW nRow) +{ + if (!ValidCol(nCol) || nCol >= GetAllocatedColumnsCount()) + return nullptr; + + sc::SparklineCell* pSparklineCell = aCol[nCol].GetSparklineCell(nRow); + if (!pSparklineCell) + return nullptr; + + std::shared_ptr<sc::Sparkline> pSparkline(pSparklineCell->getSparkline()); + assert(pSparkline); + + return pSparkline.get(); +} + +sc::Sparkline* ScTable::CreateSparkline(SCCOL nCol, SCROW nRow, std::shared_ptr<sc::SparklineGroup>& pSparklineGroup) +{ + if (!ValidCol(nCol)) + return nullptr; + + ScColumn& rColumn = CreateColumnIfNotExists(nCol); + + std::shared_ptr<sc::Sparkline> pSparkline(new sc::Sparkline(nCol, nRow, pSparklineGroup)); + maSparklineList.addSparkline(pSparkline); + rColumn.CreateSparklineCell(nRow, pSparkline); + return pSparkline.get(); +} + +sc::SparklineList& ScTable::GetSparklineList() +{ + return maSparklineList; +} + +// Notes + std::unique_ptr<ScPostIt> ScTable::ReleaseNote( SCCOL nCol, SCROW nRow ) { if (!ValidCol(nCol) || nCol >= GetAllocatedColumnsCount())