Rebased ref, commits from common ancestor:
commit 1c5d5eb6c25ec32166a8d38cfa3812bced00d5b3
Author: Tomaž Vajngerl <[email protected]>
AuthorDate: Fri Apr 1 17:06:18 2022 +0900
Commit: Tomaž Vajngerl <[email protected]>
CommitDate: Fri Apr 1 17:17:57 2022 +0900
sc: improve SparklineList to track added SparklineGroups
SparklineList used to only track added Sparklines for a sheet, but
usually (in an export) we want to start with SparklineGroups and
then search for all sparklines belonging to a group. This changes
to use that. Now there is a method getSparklineGroups() and then
another method getSparklineFor(), which returns all sparklines for
the input group.
Also added SparklineListTest, and refactored the export code for
OOXML and ODF.
Change-Id: I975e30f649788d41aab92a9a3220e38998e39670
diff --git a/sc/inc/Sparkline.hxx b/sc/inc/Sparkline.hxx
index 5cc079f8530e..0cdf7be9b55c 100644
--- a/sc/inc/Sparkline.hxx
+++ b/sc/inc/Sparkline.hxx
@@ -48,41 +48,6 @@ public:
SCROW getRow() const { 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
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sc/inc/SparklineList.hxx b/sc/inc/SparklineList.hxx
new file mode 100644
index 000000000000..2c51ab296a84
--- /dev/null
+++ b/sc/inc/SparklineList.hxx
@@ -0,0 +1,101 @@
+/* -*- 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 <memory>
+#include <map>
+
+#include "rangelst.hxx"
+#include <Sparkline.hxx>
+#include <SparklineGroup.hxx>
+
+namespace sc
+{
+/** Tracks and gathers all created sparklines and sparkline groups.
+ *
+ * All the collections of sparkline groups and sparklines don't take
+ * the ownership of the pointers.
+ */
+class SC_DLLPUBLIC SparklineList
+{
+private:
+ std::vector<std::weak_ptr<SparklineGroup>> m_aSparklineGroups;
+ std::map<std::weak_ptr<SparklineGroup>,
std::vector<std::weak_ptr<Sparkline>>,
+ std::owner_less<>>
+ m_aSparklineGroupMap;
+
+public:
+ SparklineList() {}
+
+ void addSparkline(std::shared_ptr<Sparkline> const& pSparkline)
+ {
+ auto pWeakGroup =
std::weak_ptr<SparklineGroup>(pSparkline->getSparklineGroup());
+
+ auto[iterator, bInserted]
+ = m_aSparklineGroupMap.try_emplace(pWeakGroup,
std::vector<std::weak_ptr<Sparkline>>());
+ iterator->second.push_back(std::weak_ptr<Sparkline>(pSparkline));
+ if (bInserted)
+ m_aSparklineGroups.push_back(pWeakGroup);
+ }
+
+ std::vector<std::shared_ptr<SparklineGroup>> getSparklineGroups()
+ {
+ std::vector<std::shared_ptr<SparklineGroup>> toReturn;
+
+ for (auto iterator = m_aSparklineGroups.begin(); iterator !=
m_aSparklineGroups.end();)
+ {
+ if (auto pSparklineGroup = iterator->lock())
+ {
+ toReturn.push_back(pSparklineGroup);
+ iterator++;
+ }
+ else
+ {
+ iterator = m_aSparklineGroups.erase(iterator);
+ }
+ }
+ return toReturn;
+ }
+
+ std::vector<std::shared_ptr<Sparkline>>
+ getSparklinesFor(std::shared_ptr<SparklineGroup> const& pSparklineGroup)
+ {
+ std::vector<std::shared_ptr<Sparkline>> toReturn;
+
+ std::weak_ptr<SparklineGroup> pWeakGroup(pSparklineGroup);
+ auto iteratorGroup = m_aSparklineGroupMap.find(pWeakGroup);
+
+ if (iteratorGroup == m_aSparklineGroupMap.end())
+ return toReturn;
+
+ auto& rWeakSparklines = iteratorGroup->second;
+
+ for (auto iterator = rWeakSparklines.begin(); iterator !=
rWeakSparklines.end();)
+ {
+ if (auto aSparkline = iterator->lock())
+ {
+ toReturn.push_back(aSparkline);
+ iterator++;
+ }
+ else
+ {
+ iterator = rWeakSparklines.erase(iterator);
+ }
+ }
+
+ return toReturn;
+ }
+};
+
+} // end sc
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sc/inc/table.hxx b/sc/inc/table.hxx
index ca099be7a0a0..7b3c01e67989 100644
--- a/sc/inc/table.hxx
+++ b/sc/inc/table.hxx
@@ -32,6 +32,7 @@
#include <formula/errorcodes.hxx>
#include "document.hxx"
#include "drwlayer.hxx"
+#include "SparklineList.hxx"
#include <algorithm>
#include <atomic>
diff --git a/sc/qa/unit/SparklineTest.cxx b/sc/qa/unit/SparklineTest.cxx
index 16381527adda..ff09564a972b 100644
--- a/sc/qa/unit/SparklineTest.cxx
+++ b/sc/qa/unit/SparklineTest.cxx
@@ -15,6 +15,7 @@
#include <Sparkline.hxx>
#include <SparklineGroup.hxx>
+#include <SparklineList.hxx>
using namespace css;
@@ -54,6 +55,7 @@ public:
void testUndoRedoDeleteSparkline();
void testUndoRedoClearContentForSparkline();
void testUndoRedoEditSparklineGroup();
+ void testSparklineList();
CPPUNIT_TEST_SUITE(SparklineTest);
CPPUNIT_TEST(testAddSparkline);
@@ -64,6 +66,7 @@ public:
CPPUNIT_TEST(testUndoRedoDeleteSparkline);
CPPUNIT_TEST(testUndoRedoClearContentForSparkline);
CPPUNIT_TEST(testUndoRedoEditSparklineGroup);
+ CPPUNIT_TEST(testSparklineList);
CPPUNIT_TEST_SUITE_END();
};
@@ -113,10 +116,12 @@ void SparklineTest::testAddSparkline()
CPPUNIT_ASSERT_EQUAL(pGetSparkline.get(), pSparkline);
- sc::SparklineList* pList = rDocument.GetSparklineList(0);
+ sc::SparklineList* pList = rDocument.GetSparklineList(SCTAB(0));
CPPUNIT_ASSERT(pList);
- std::vector<std::shared_ptr<sc::Sparkline>> aSparklineVector =
pList->getSparklines();
+ CPPUNIT_ASSERT_EQUAL(size_t(1), pList->getSparklineGroups().size());
+
+ auto const& aSparklineVector =
pList->getSparklinesFor(pGetSparkline->getSparklineGroup());
CPPUNIT_ASSERT_EQUAL(size_t(1), aSparklineVector.size());
CPPUNIT_ASSERT_EQUAL(aSparklineVector[0].get(), pSparkline);
@@ -496,6 +501,65 @@ void SparklineTest::testUndoRedoEditSparklineGroup()
xDocSh->DoClose();
}
+void SparklineTest::testSparklineList()
+{
+ ScDocShellRef xDocSh = loadEmptyDocument();
+ CPPUNIT_ASSERT(xDocSh);
+
+ ScDocument& rDocument = xDocSh->GetDocument();
+
+ auto pSparklineGroup = std::make_shared<sc::SparklineGroup>();
+
+ rDocument.CreateSparkline(ScAddress(0, 6, 0), pSparklineGroup);
+
+ {
+ auto* pSparklineList = rDocument.GetSparklineList(SCTAB(0));
+ auto pSparklineGroups = pSparklineList->getSparklineGroups();
+ CPPUNIT_ASSERT_EQUAL(size_t(1), pSparklineGroups.size());
+
+ auto pSparklines =
pSparklineList->getSparklinesFor(pSparklineGroups[0]);
+ CPPUNIT_ASSERT_EQUAL(size_t(1), pSparklines.size());
+ }
+ rDocument.CreateSparkline(ScAddress(1, 6, 0), pSparklineGroup);
+ rDocument.CreateSparkline(ScAddress(2, 6, 0), pSparklineGroup);
+
+ {
+ auto* pSparklineList = rDocument.GetSparklineList(SCTAB(0));
+ auto pSparklineGroups = pSparklineList->getSparklineGroups();
+ CPPUNIT_ASSERT_EQUAL(size_t(1), pSparklineGroups.size());
+
+ auto pSparklines =
pSparklineList->getSparklinesFor(pSparklineGroups[0]);
+ CPPUNIT_ASSERT_EQUAL(size_t(3), pSparklines.size());
+ }
+
+ {
+ auto pSparklineGroup2 = std::make_shared<sc::SparklineGroup>();
+ rDocument.CreateSparkline(ScAddress(3, 6, 0), pSparklineGroup2);
+
+ auto* pSparklineList = rDocument.GetSparklineList(SCTAB(0));
+
+ auto pSparklineGroups = pSparklineList->getSparklineGroups();
+ CPPUNIT_ASSERT_EQUAL(size_t(2), pSparklineGroups.size());
+
+ auto pSparklines2 = pSparklineList->getSparklinesFor(pSparklineGroup2);
+ CPPUNIT_ASSERT_EQUAL(size_t(1), pSparklines2.size());
+ }
+
+ rDocument.DeleteSparkline(ScAddress(3, 6, 0));
+
+ {
+ auto* pSparklineList = rDocument.GetSparklineList(SCTAB(0));
+
+ auto pSparklineGroups = pSparklineList->getSparklineGroups();
+ CPPUNIT_ASSERT_EQUAL(size_t(1), pSparklineGroups.size());
+
+ auto pSparklines =
pSparklineList->getSparklinesFor(pSparklineGroups[0]);
+ CPPUNIT_ASSERT_EQUAL(size_t(3), pSparklines.size());
+ }
+
+ xDocSh->DoClose();
+}
+
CPPUNIT_TEST_SUITE_REGISTRATION(SparklineTest);
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sc/source/core/data/document.cxx b/sc/source/core/data/document.cxx
index 351e795ac5da..3a93964024b8 100644
--- a/sc/source/core/data/document.cxx
+++ b/sc/source/core/data/document.cxx
@@ -87,6 +87,7 @@
#include <compressedarray.hxx>
#include <recursionhelper.hxx>
#include <SparklineGroup.hxx>
+#include <SparklineList.hxx>
#include <formula/vectortoken.hxx>
@@ -6588,13 +6589,12 @@ std::shared_ptr<sc::SparklineGroup>
ScDocument::SearchSparklineGroup(tools::Guid
{
for (auto const& rTable : maTabs)
{
- std::vector<std::shared_ptr<sc::SparklineGroup>> aSparklineGroupMap;
+ auto& rSparklineList = rTable->GetSparklineList();
- for (auto const& pSparkline :
rTable->GetSparklineList().getSparklines())
+ for (auto const& pSparklineGroup : rSparklineList.getSparklineGroups())
{
- auto const& pGroup = pSparkline->getSparklineGroup();
- if (pGroup->getID() == rGuid)
- return pGroup;
+ if (pSparklineGroup->getID() == rGuid)
+ return pSparklineGroup;
}
}
diff --git a/sc/source/filter/excel/export/SparklineExt.cxx
b/sc/source/filter/excel/export/SparklineExt.cxx
index 47e469a31ef0..986852f2e9c2 100644
--- a/sc/source/filter/excel/export/SparklineExt.cxx
+++ b/sc/source/filter/excel/export/SparklineExt.cxx
@@ -13,37 +13,28 @@
#include <oox/token/namespaces.hxx>
#include <oox/token/tokens.hxx>
#include <SparklineGroup.hxx>
+#include <SparklineList.hxx>
using namespace oox;
namespace xcl::exp
{
-SparklineExt::SparklineExt(const XclExpRoot& rRoot,
- std::vector<std::shared_ptr<sc::Sparkline>> const&
pSparklines)
+SparklineExt::SparklineExt(const XclExpRoot& rRoot)
: 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)
{
+ auto& rDocument = GetDoc();
+
+ auto* pSparklineList = rDocument.GetSparklineList(GetCurrScTab());
+ if (!pSparklineList)
+ return;
+
+ auto const& rSparklineGroups = pSparklineList->getSparklineGroups();
+
sax_fastparser::FSHelperPtr& rWorksheet = rStream.GetCurrentStream();
rWorksheet->startElement(XML_ext, FSNS(XML_xmlns, XML_x14),
rStream.getNamespaceURL(OOX_NS(xls14Lst)),
XML_uri, maURI);
@@ -51,8 +42,9 @@ void SparklineExt::SaveXml(XclExpXmlStream& rStream)
rWorksheet->startElementNS(XML_x14, XML_sparklineGroups, FSNS(XML_xmlns,
XML_xm),
rStream.getNamespaceURL(OOX_NS(xm)));
- for (auto const & [ pSparklineGroup, rSparklineVector ] :
m_aSparklineGroupMap)
+ for (auto const& pSparklineGroup : rSparklineGroups)
{
+ auto const& rSparklineVector =
pSparklineList->getSparklinesFor(pSparklineGroup);
addSparklineGroup(rStream, *pSparklineGroup, rSparklineVector);
}
@@ -238,14 +230,7 @@ void SparklineExt::addSparklineGroup(XclExpXmlStream&
rStream, sc::SparklineGrou
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));
- }
- }
+ xExtLst->AddRecord(new xcl::exp::SparklineExt(GetRoot()));
}
} // end namespace xcl::exp
diff --git a/sc/source/filter/inc/export/SparklineExt.hxx
b/sc/source/filter/inc/export/SparklineExt.hxx
index 7d26922f15db..e6a155360545 100644
--- a/sc/source/filter/inc/export/SparklineExt.hxx
+++ b/sc/source/filter/inc/export/SparklineExt.hxx
@@ -26,11 +26,8 @@ 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);
+ SparklineExt(const XclExpRoot& rRoot);
void SaveXml(XclExpXmlStream& rStream) override;
void addSparklineGroup(XclExpXmlStream& rStream, sc::SparklineGroup&
rSparklineGroup,
diff --git a/sc/source/filter/xml/SparklineGroupsExport.cxx
b/sc/source/filter/xml/SparklineGroupsExport.cxx
index 4de56fcfaf58..077d43beab60 100644
--- a/sc/source/filter/xml/SparklineGroupsExport.cxx
+++ b/sc/source/filter/xml/SparklineGroupsExport.cxx
@@ -11,6 +11,8 @@
#include "SparklineGroupsExport.hxx"
#include "xmlexprt.hxx"
#include <rangeutl.hxx>
+#include <SparklineList.hxx>
+#include <document.hxx>
#include <xmloff/xmluconv.hxx>
#include <xmloff/xmltoken.hxx>
@@ -25,27 +27,10 @@ using namespace xmloff::token;
namespace sc
{
-SparklineGroupsExport::SparklineGroupsExport(
- ScXMLExport& rExport, SCTAB nTable,
std::vector<std::shared_ptr<Sparkline>> const& rSparklines)
+SparklineGroupsExport::SparklineGroupsExport(ScXMLExport& rExport, SCTAB
nTable)
: m_rExport(rExport)
, m_nTable(nTable)
{
- for (auto const& pSparkline : rSparklines)
- {
- auto* pGroupPointer = pSparkline->getSparklineGroup().get();
- auto aIterator = m_aSparklineGroupMap.find(pGroupPointer);
- if (aIterator == m_aSparklineGroupMap.end())
- {
- m_aSparklineGroups.push_back(pGroupPointer);
- std::vector<std::shared_ptr<sc::Sparkline>> aSparklineVector;
- aSparklineVector.push_back(pSparkline);
- m_aSparklineGroupMap.emplace(pGroupPointer, aSparklineVector);
- }
- else
- {
- aIterator->second.push_back(pSparkline);
- }
- }
}
void SparklineGroupsExport::insertColor(Color aColor, XMLTokenEnum eToken)
@@ -183,7 +168,9 @@ void
SparklineGroupsExport::addSparklineGroupAttributes(SparklineAttributes cons
insertColor(rAttributes.getColorLow(), XML_COLOR_LOW);
}
-void SparklineGroupsExport::addSparklineGroup(SparklineGroup* pSparklineGroup)
+void SparklineGroupsExport::addSparklineGroup(
+ std::shared_ptr<SparklineGroup> const& pSparklineGroup,
+ std::vector<std::shared_ptr<Sparkline>> const& rSparklines)
{
auto const& rAttributes = pSparklineGroup->getAttributes();
@@ -197,7 +184,8 @@ void
SparklineGroupsExport::addSparklineGroup(SparklineGroup* pSparklineGroup)
SvXMLElementExport aElementSparklines(m_rExport, XML_NAMESPACE_CALC_EXT,
XML_SPARKLINES, true,
true);
- for (auto const& rSparkline : m_aSparklineGroupMap[pSparklineGroup])
+
+ for (auto const& rSparkline : rSparklines)
{
addSparklineAttributes(*rSparkline);
SvXMLElementExport aElementSparkline(m_rExport,
XML_NAMESPACE_CALC_EXT, XML_SPARKLINE, true,
@@ -207,13 +195,24 @@ void
SparklineGroupsExport::addSparklineGroup(SparklineGroup* pSparklineGroup)
void SparklineGroupsExport::write()
{
- SvXMLElementExport aElement(m_rExport, XML_NAMESPACE_CALC_EXT,
XML_SPARKLINE_GROUPS, true,
- true);
- for (auto* pSparklineGroup : m_aSparklineGroups)
+ auto* pDocument = m_rExport.GetDocument();
+ if (sc::SparklineList* pSparklineList =
pDocument->GetSparklineList(m_nTable))
{
- addSparklineGroup(pSparklineGroup);
+ auto const& aSparklineGroups = pSparklineList->getSparklineGroups();
+ if (!aSparklineGroups.empty())
+ {
+ SvXMLElementExport aElement(m_rExport, XML_NAMESPACE_CALC_EXT,
XML_SPARKLINE_GROUPS,
+ true, true);
+
+ for (auto const& pSparklineGroup : aSparklineGroups)
+ {
+ auto const& aSparklines =
pSparklineList->getSparklinesFor(pSparklineGroup);
+ addSparklineGroup(pSparklineGroup, aSparklines);
+ }
+ }
}
}
-}
+
+} // end sc
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sc/source/filter/xml/SparklineGroupsExport.hxx
b/sc/source/filter/xml/SparklineGroupsExport.hxx
index 4e49f585dbc7..b20fd8529574 100644
--- a/sc/source/filter/xml/SparklineGroupsExport.hxx
+++ b/sc/source/filter/xml/SparklineGroupsExport.hxx
@@ -25,21 +25,18 @@ namespace sc
class SparklineGroupsExport
{
ScXMLExport& m_rExport;
- std::vector<SparklineGroup*> m_aSparklineGroups;
- std::unordered_map<SparklineGroup*,
std::vector<std::shared_ptr<Sparkline>>>
- m_aSparklineGroupMap;
SCTAB m_nTable;
void addSparklineGroupAttributes(sc::SparklineAttributes const&
rAttributes);
- void addSparklineGroup(SparklineGroup* pSparklineGroup);
+ void addSparklineGroup(std::shared_ptr<SparklineGroup> const&
pSparklineGroup,
+ std::vector<std::shared_ptr<Sparkline>> const&
rSparklines);
void addSparklineAttributes(Sparkline const& rSparkline);
void insertColor(Color aColor, xmloff::token::XMLTokenEnum eToken);
void insertBool(bool bValue, xmloff::token::XMLTokenEnum eToken);
public:
- SparklineGroupsExport(ScXMLExport& rExport, SCTAB nTable,
- std::vector<std::shared_ptr<Sparkline>> const&
rSparklines);
+ SparklineGroupsExport(ScXMLExport& rExport, SCTAB nTable);
void write();
};
diff --git a/sc/source/filter/xml/xmlexprt.cxx
b/sc/source/filter/xml/xmlexprt.cxx
index 1b273a7b53d5..8644108589b4 100644
--- a/sc/source/filter/xml/xmlexprt.cxx
+++ b/sc/source/filter/xml/xmlexprt.cxx
@@ -68,6 +68,7 @@
#include <datamapper.hxx>
#include <datatransformation.hxx>
#include "SparklineGroupsExport.hxx"
+#include "SparklineList.hxx"
#include <xmloff/xmltoken.hxx>
#include <xmloff/xmlnamespace.hxx>
@@ -4516,15 +4517,8 @@ void ScXMLExport::WriteNamedRange(ScRangeName*
pRangeName)
void ScXMLExport::exportSparklineGroups(SCTAB nTable)
{
- if (sc::SparklineList* pSparklineList = pDoc->GetSparklineList(nTable))
- {
- auto pSparklines = pSparklineList->getSparklines();
- if (!pSparklines.empty())
- {
- sc::SparklineGroupsExport aSparklineGroupExport(*this, nTable,
pSparklines);
- aSparklineGroupExport.write();
- }
- }
+ sc::SparklineGroupsExport aSparklineGroupExport(*this, nTable);
+ aSparklineGroupExport.write();
}
namespace {
commit 24ef83390d53d95f9c3becdd3e23e0f534abad4d
Author: Tomaž Vajngerl <[email protected]>
AuthorDate: Thu Mar 31 23:07:44 2022 +0900
Commit: Tomaž Vajngerl <[email protected]>
CommitDate: Fri Apr 1 14:12:46 2022 +0900
sc: add SparklineGroup Undo/Redo
As SparklineAttributes are COW, we can just exchange them around
in the SparklineGroup when undoing and redoing.
This also changes SparklineDialog to work with a local copy of
SparklineAttributes when editing, or an empty initial copy when
inserting a new Sparkline into the sheet.
Change-Id: I36e9c887ca640f40266f381e98e57f027a5ca07f
diff --git a/sc/Library_sc.mk b/sc/Library_sc.mk
index e97f6e04b4c2..294c36b4578c 100644
--- a/sc/Library_sc.mk
+++ b/sc/Library_sc.mk
@@ -555,6 +555,7 @@ $(eval $(call gb_Library_add_exception_objects,sc,\
sc/source/ui/undo/undotab \
sc/source/ui/undo/undoutil \
sc/source/ui/undo/UndoInsertSparkline \
+ sc/source/ui/undo/UndoEditSparklineGroup \
sc/source/ui/undo/UndoDeleteSparkline \
sc/source/ui/unoobj/ChartRangeSelectionListener \
sc/source/ui/unoobj/addruno \
diff --git a/sc/inc/SparklineGroup.hxx b/sc/inc/SparklineGroup.hxx
index d6cb8cf4402d..f9e0f7784feb 100644
--- a/sc/inc/SparklineGroup.hxx
+++ b/sc/inc/SparklineGroup.hxx
@@ -28,11 +28,14 @@ public:
SparklineAttributes& getAttributes() { return m_aAttributes; }
SparklineAttributes const& getAttributes() const { return m_aAttributes; }
+ void setAttributes(SparklineAttributes const& rAttributes) { m_aAttributes
= rAttributes; };
+
tools::Guid& getID() { return m_aGUID; }
void setID(tools::Guid const& rGuid) { m_aGUID = rGuid; }
SparklineGroup();
+ SparklineGroup(SparklineAttributes const& rSparklineAttributes);
SparklineGroup(SparklineGroup const& pOtherSparkline);
diff --git a/sc/inc/globstr.hrc b/sc/inc/globstr.hrc
index bed2e10f9b51..adb02782122b 100644
--- a/sc/inc/globstr.hrc
+++ b/sc/inc/globstr.hrc
@@ -541,6 +541,7 @@
#define STR_INDENTCELL NC_("STR_INDENTCELL", "Indent:
")
#define STR_UNDO_INSERT_SPARKLINE_GROUP
NC_("STR_UNDO_INSERT_SPARKLINE", "Insert Sparkline Group")
#define STR_UNDO_DELETE_SPARKLINE
NC_("STR_UNDO_DELETE_SPARKLINE", "Delete Sparkline")
+#define STR_UNDO_EDIT_SPARKLINE_GROUP
NC_("STR_UNDO_EDIT_SPARKLINE_GROUP", "Edit Sparkline Group")
#endif
diff --git a/sc/qa/unit/SparklineTest.cxx b/sc/qa/unit/SparklineTest.cxx
index 64f05a703590..16381527adda 100644
--- a/sc/qa/unit/SparklineTest.cxx
+++ b/sc/qa/unit/SparklineTest.cxx
@@ -53,6 +53,7 @@ public:
void testUndoRedoInsertSparkline();
void testUndoRedoDeleteSparkline();
void testUndoRedoClearContentForSparkline();
+ void testUndoRedoEditSparklineGroup();
CPPUNIT_TEST_SUITE(SparklineTest);
CPPUNIT_TEST(testAddSparkline);
@@ -62,6 +63,7 @@ public:
CPPUNIT_TEST(testUndoRedoInsertSparkline);
CPPUNIT_TEST(testUndoRedoDeleteSparkline);
CPPUNIT_TEST(testUndoRedoClearContentForSparkline);
+ CPPUNIT_TEST(testUndoRedoEditSparklineGroup);
CPPUNIT_TEST_SUITE_END();
};
@@ -427,6 +429,73 @@ void SparklineTest::testUndoRedoClearContentForSparkline()
xDocSh->DoClose();
}
+void SparklineTest::testUndoRedoEditSparklineGroup()
+{
+ ScDocShellRef xDocSh = loadEmptyDocument();
+ CPPUNIT_ASSERT(xDocSh);
+
+ ScDocument& rDocument = xDocSh->GetDocument();
+ ScTabViewShell* pViewShell = xDocSh->GetBestViewShell(false);
+ CPPUNIT_ASSERT(pViewShell);
+
+ auto& rDocFunc = xDocSh->GetDocFunc();
+
+ auto pSparklineGroup = std::make_shared<sc::SparklineGroup>();
+ {
+ sc::SparklineAttributes& rAttibutes = pSparklineGroup->getAttributes();
+ rAttibutes.setType(sc::SparklineType::Column);
+ rAttibutes.setColorSeries(COL_YELLOW);
+ rAttibutes.setColorAxis(COL_GREEN);
+ }
+
+ rDocument.CreateSparkline(ScAddress(0, 6, 0), pSparklineGroup);
+
+ sc::SparklineAttributes aNewAttributes;
+ aNewAttributes.setType(sc::SparklineType::Stacked);
+ aNewAttributes.setColorSeries(COL_BLACK);
+ aNewAttributes.setColorAxis(COL_BLUE);
+
+ sc::SparklineAttributes
aInitialAttibutes(pSparklineGroup->getAttributes());
+
+ CPPUNIT_ASSERT(aNewAttributes != aInitialAttibutes);
+
+ CPPUNIT_ASSERT_EQUAL(true, aInitialAttibutes ==
pSparklineGroup->getAttributes());
+ CPPUNIT_ASSERT_EQUAL(false, aNewAttributes ==
pSparklineGroup->getAttributes());
+
+ CPPUNIT_ASSERT_EQUAL(sc::SparklineType::Column,
pSparklineGroup->getAttributes().getType());
+ CPPUNIT_ASSERT_EQUAL(COL_YELLOW,
pSparklineGroup->getAttributes().getColorSeries());
+ CPPUNIT_ASSERT_EQUAL(COL_GREEN,
pSparklineGroup->getAttributes().getColorAxis());
+
+ rDocFunc.ChangeSparklineGroupAttributes(pSparklineGroup, aNewAttributes);
+
+ CPPUNIT_ASSERT_EQUAL(false, aInitialAttibutes ==
pSparklineGroup->getAttributes());
+ CPPUNIT_ASSERT_EQUAL(true, aNewAttributes ==
pSparklineGroup->getAttributes());
+
+ CPPUNIT_ASSERT_EQUAL(sc::SparklineType::Stacked,
pSparklineGroup->getAttributes().getType());
+ CPPUNIT_ASSERT_EQUAL(COL_BLACK,
pSparklineGroup->getAttributes().getColorSeries());
+ CPPUNIT_ASSERT_EQUAL(COL_BLUE,
pSparklineGroup->getAttributes().getColorAxis());
+
+ rDocument.GetUndoManager()->Undo();
+
+ CPPUNIT_ASSERT_EQUAL(true, aInitialAttibutes ==
pSparklineGroup->getAttributes());
+ CPPUNIT_ASSERT_EQUAL(false, aNewAttributes ==
pSparklineGroup->getAttributes());
+
+ CPPUNIT_ASSERT_EQUAL(sc::SparklineType::Column,
pSparklineGroup->getAttributes().getType());
+ CPPUNIT_ASSERT_EQUAL(COL_YELLOW,
pSparklineGroup->getAttributes().getColorSeries());
+ CPPUNIT_ASSERT_EQUAL(COL_GREEN,
pSparklineGroup->getAttributes().getColorAxis());
+
+ rDocument.GetUndoManager()->Redo();
+
+ CPPUNIT_ASSERT_EQUAL(false, aInitialAttibutes ==
pSparklineGroup->getAttributes());
+ CPPUNIT_ASSERT_EQUAL(true, aNewAttributes ==
pSparklineGroup->getAttributes());
+
+ CPPUNIT_ASSERT_EQUAL(sc::SparklineType::Stacked,
pSparklineGroup->getAttributes().getType());
+ CPPUNIT_ASSERT_EQUAL(COL_BLACK,
pSparklineGroup->getAttributes().getColorSeries());
+ CPPUNIT_ASSERT_EQUAL(COL_BLUE,
pSparklineGroup->getAttributes().getColorAxis());
+
+ xDocSh->DoClose();
+}
+
CPPUNIT_TEST_SUITE_REGISTRATION(SparklineTest);
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sc/source/ui/dialogs/SparklineDialog.cxx
b/sc/source/ui/dialogs/SparklineDialog.cxx
index 59068077b969..4a7fa320a38e 100644
--- a/sc/source/ui/dialogs/SparklineDialog.cxx
+++ b/sc/source/ui/dialogs/SparklineDialog.cxx
@@ -163,7 +163,8 @@ void SparklineDialog::setupValues()
{
if (auto pSparkline = mrDocument.GetSparkline(aSelectionRange.aStart))
{
- mpLocalSparklineGroup = pSparkline->getSparklineGroup();
+ mpSparklineGroup = pSparkline->getSparklineGroup();
+ maAttributes = mpSparklineGroup->getAttributes();
mxFrameData->set_visible(false);
mbEditMode = true;
}
@@ -173,16 +174,9 @@ void SparklineDialog::setupValues()
maInputRange = aSelectionRange;
}
- if (!mpLocalSparklineGroup)
- {
- mpLocalSparklineGroup = std::make_shared<sc::SparklineGroup>();
- }
-
setInputSelection();
- auto const& rAttribute = mpLocalSparklineGroup->getAttributes();
-
- switch (rAttribute.getType())
+ switch (maAttributes.getType())
{
case sc::SparklineType::Line:
mxRadioLine->set_active(true);
@@ -195,7 +189,7 @@ void SparklineDialog::setupValues()
break;
}
- switch (rAttribute.getDisplayEmptyCellsAs())
+ switch (maAttributes.getDisplayEmptyCellsAs())
{
case sc::DisplayEmptyCellsAs::Gap:
mxRadioDisplayEmptyGap->set_active(true);
@@ -208,28 +202,28 @@ void SparklineDialog::setupValues()
break;
}
- mxColorSeries->SelectEntry(rAttribute.getColorSeries());
- mxColorNegative->SelectEntry(rAttribute.getColorNegative());
- mxColorMarker->SelectEntry(rAttribute.getColorMarkers());
- mxColorHigh->SelectEntry(rAttribute.getColorHigh());
- mxColorLow->SelectEntry(rAttribute.getColorLow());
- mxColorFirst->SelectEntry(rAttribute.getColorFirst());
- mxColorLast->SelectEntry(rAttribute.getColorLast());
+ mxColorSeries->SelectEntry(maAttributes.getColorSeries());
+ mxColorNegative->SelectEntry(maAttributes.getColorNegative());
+ mxColorMarker->SelectEntry(maAttributes.getColorMarkers());
+ mxColorHigh->SelectEntry(maAttributes.getColorHigh());
+ mxColorLow->SelectEntry(maAttributes.getColorLow());
+ mxColorFirst->SelectEntry(maAttributes.getColorFirst());
+ mxColorLast->SelectEntry(maAttributes.getColorLast());
- mxCheckButtonNegative->set_active(rAttribute.isNegative());
- mxCheckButtonMarker->set_active(rAttribute.isMarkers());
- mxCheckButtonHigh->set_active(rAttribute.isHigh());
- mxCheckButtonLow->set_active(rAttribute.isLow());
- mxCheckButtonFirst->set_active(rAttribute.isFirst());
- mxCheckButtonLast->set_active(rAttribute.isLast());
+ mxCheckButtonNegative->set_active(maAttributes.isNegative());
+ mxCheckButtonMarker->set_active(maAttributes.isMarkers());
+ mxCheckButtonHigh->set_active(maAttributes.isHigh());
+ mxCheckButtonLow->set_active(maAttributes.isLow());
+ mxCheckButtonFirst->set_active(maAttributes.isFirst());
+ mxCheckButtonLast->set_active(maAttributes.isLast());
- mxSpinLineWidth->set_value(sal_Int64(rAttribute.getLineWeight() * 100.0));
+ mxSpinLineWidth->set_value(sal_Int64(maAttributes.getLineWeight() *
100.0));
- mxCheckDisplayXAxis->set_active(rAttribute.shouldDisplayXAxis());
- mxCheckDisplayHidden->set_active(rAttribute.shouldDisplayHidden());
- mxCheckRightToLeft->set_active(rAttribute.isRightToLeft());
+ mxCheckDisplayXAxis->set_active(maAttributes.shouldDisplayXAxis());
+ mxCheckDisplayHidden->set_active(maAttributes.shouldDisplayHidden());
+ mxCheckRightToLeft->set_active(maAttributes.isRightToLeft());
- switch (rAttribute.getMinAxisType())
+ switch (maAttributes.getMinAxisType())
{
case sc::AxisType::Individual:
mxComboMinAxisType->set_active(0);
@@ -241,13 +235,13 @@ void SparklineDialog::setupValues()
break;
case sc::AxisType::Custom:
mxComboMinAxisType->set_active(2);
- if (rAttribute.getManualMin())
-
mxSpinCustomMin->GetFormatter().SetValue(*rAttribute.getManualMin());
+ if (maAttributes.getManualMin())
+
mxSpinCustomMin->GetFormatter().SetValue(*maAttributes.getManualMin());
break;
}
ComboValueChanged(*mxComboMinAxisType);
- switch (rAttribute.getMaxAxisType())
+ switch (maAttributes.getMaxAxisType())
{
case sc::AxisType::Individual:
mxComboMaxAxisType->set_active(0);
@@ -259,8 +253,8 @@ void SparklineDialog::setupValues()
break;
case sc::AxisType::Custom:
mxComboMaxAxisType->set_active(2);
- if (rAttribute.getManualMin())
-
mxSpinCustomMax->GetFormatter().SetValue(*rAttribute.getManualMax());
+ if (maAttributes.getManualMin())
+
mxSpinCustomMax->GetFormatter().SetValue(*maAttributes.getManualMax());
break;
}
ComboValueChanged(*mxComboMaxAxisType);
@@ -405,72 +399,63 @@ IMPL_LINK(SparklineDialog, ButtonClicked, weld::Button&,
rButton, void)
IMPL_LINK(SparklineDialog, ToggleHandler, weld::Toggleable&, rToggle, void)
{
- auto& rAttribute = mpLocalSparklineGroup->getAttributes();
-
if (mxCheckButtonNegative.get() == &rToggle)
- rAttribute.setNegative(mxCheckButtonNegative->get_active());
+ maAttributes.setNegative(mxCheckButtonNegative->get_active());
if (mxCheckButtonMarker.get() == &rToggle)
- rAttribute.setMarkers(mxCheckButtonMarker->get_active());
+ maAttributes.setMarkers(mxCheckButtonMarker->get_active());
if (mxCheckButtonHigh.get() == &rToggle)
- rAttribute.setHigh(mxCheckButtonHigh->get_active());
+ maAttributes.setHigh(mxCheckButtonHigh->get_active());
if (mxCheckButtonLow.get() == &rToggle)
- rAttribute.setLow(mxCheckButtonLow->get_active());
+ maAttributes.setLow(mxCheckButtonLow->get_active());
if (mxCheckButtonFirst.get() == &rToggle)
- rAttribute.setFirst(mxCheckButtonFirst->get_active());
+ maAttributes.setFirst(mxCheckButtonFirst->get_active());
if (mxCheckButtonLast.get() == &rToggle)
- rAttribute.setLast(mxCheckButtonLast->get_active());
+ maAttributes.setLast(mxCheckButtonLast->get_active());
if (mxCheckDisplayXAxis.get() == &rToggle)
- rAttribute.setDisplayXAxis(mxCheckDisplayXAxis->get_active());
+ maAttributes.setDisplayXAxis(mxCheckDisplayXAxis->get_active());
if (mxCheckDisplayHidden.get() == &rToggle)
- rAttribute.setDisplayHidden(mxCheckDisplayHidden->get_active());
+ maAttributes.setDisplayHidden(mxCheckDisplayHidden->get_active());
if (mxCheckRightToLeft.get() == &rToggle)
- rAttribute.setRightToLeft(mxCheckRightToLeft->get_active());
+ maAttributes.setRightToLeft(mxCheckRightToLeft->get_active());
}
IMPL_LINK_NOARG(SparklineDialog, SelectSparklineType, weld::Toggleable&, void)
{
- auto& rAttribute = mpLocalSparklineGroup->getAttributes();
-
if (mxRadioLine->get_active())
- rAttribute.setType(sc::SparklineType::Line);
+ maAttributes.setType(sc::SparklineType::Line);
else if (mxRadioColumn->get_active())
- rAttribute.setType(sc::SparklineType::Column);
+ maAttributes.setType(sc::SparklineType::Column);
else if (mxRadioStacked->get_active())
- rAttribute.setType(sc::SparklineType::Stacked);
+ maAttributes.setType(sc::SparklineType::Stacked);
if (mxRadioDisplayEmptyGap->get_active())
- rAttribute.setDisplayEmptyCellsAs(sc::DisplayEmptyCellsAs::Gap);
+ maAttributes.setDisplayEmptyCellsAs(sc::DisplayEmptyCellsAs::Gap);
else if (mxRadioDisplayEmptyZero->get_active())
- rAttribute.setDisplayEmptyCellsAs(sc::DisplayEmptyCellsAs::Zero);
+ maAttributes.setDisplayEmptyCellsAs(sc::DisplayEmptyCellsAs::Zero);
else if (mxRadioDisplayEmptySpan->get_active())
- rAttribute.setDisplayEmptyCellsAs(sc::DisplayEmptyCellsAs::Span);
+ maAttributes.setDisplayEmptyCellsAs(sc::DisplayEmptyCellsAs::Span);
}
IMPL_LINK_NOARG(SparklineDialog, SpinLineWidthChanged, weld::SpinButton&, void)
{
- auto& rAttribute = mpLocalSparklineGroup->getAttributes();
-
double value = mxSpinLineWidth->get_value() / 100.0;
- rAttribute.setLineWeight(value);
+ maAttributes.setLineWeight(value);
}
IMPL_LINK(SparklineDialog, SpinCustomChanged, weld::FormattedSpinButton&,
rFormatted, void)
{
- auto& rAttribute = mpLocalSparklineGroup->getAttributes();
-
if (mxSpinCustomMin.get() == &rFormatted)
{
- rAttribute.setManualMin(rFormatted.GetFormatter().GetValue());
+ maAttributes.setManualMin(rFormatted.GetFormatter().GetValue());
}
else if (mxSpinCustomMax.get() == &rFormatted)
{
- rAttribute.setManualMax(rFormatted.GetFormatter().GetValue());
+ maAttributes.setManualMax(rFormatted.GetFormatter().GetValue());
}
}
IMPL_LINK(SparklineDialog, ComboValueChanged, weld::ComboBox&, rComboBox, void)
{
- auto& rAttribute = mpLocalSparklineGroup->getAttributes();
int nActive = rComboBox.get_active();
if (mxComboMinAxisType.get() == &rComboBox)
@@ -478,15 +463,15 @@ IMPL_LINK(SparklineDialog, ComboValueChanged,
weld::ComboBox&, rComboBox, void)
switch (nActive)
{
case 0:
- rAttribute.setMinAxisType(sc::AxisType::Individual);
+ maAttributes.setMinAxisType(sc::AxisType::Individual);
mxSpinCustomMin->set_sensitive(false);
break;
case 1:
- rAttribute.setMinAxisType(sc::AxisType::Group);
+ maAttributes.setMinAxisType(sc::AxisType::Group);
mxSpinCustomMin->set_sensitive(false);
break;
case 2:
- rAttribute.setMinAxisType(sc::AxisType::Custom);
+ maAttributes.setMinAxisType(sc::AxisType::Custom);
mxSpinCustomMin->set_sensitive(true);
break;
default:
@@ -498,15 +483,15 @@ IMPL_LINK(SparklineDialog, ComboValueChanged,
weld::ComboBox&, rComboBox, void)
switch (nActive)
{
case 0:
- rAttribute.setMaxAxisType(sc::AxisType::Individual);
+ maAttributes.setMaxAxisType(sc::AxisType::Individual);
mxSpinCustomMax->set_sensitive(false);
break;
case 1:
- rAttribute.setMaxAxisType(sc::AxisType::Group);
+ maAttributes.setMaxAxisType(sc::AxisType::Group);
mxSpinCustomMax->set_sensitive(false);
break;
case 2:
- rAttribute.setMaxAxisType(sc::AxisType::Custom);
+ maAttributes.setMaxAxisType(sc::AxisType::Custom);
mxSpinCustomMax->set_sensitive(true);
break;
default:
@@ -540,20 +525,27 @@ bool SparklineDialog::checkValidInputOutput()
void SparklineDialog::perform()
{
- auto& rAttribute = mpLocalSparklineGroup->getAttributes();
-
- rAttribute.setColorSeries(mxColorSeries->GetSelectEntryColor());
- rAttribute.setColorNegative(mxColorNegative->GetSelectEntryColor());
- rAttribute.setColorMarkers(mxColorMarker->GetSelectEntryColor());
- rAttribute.setColorHigh(mxColorHigh->GetSelectEntryColor());
- rAttribute.setColorLow(mxColorLow->GetSelectEntryColor());
- rAttribute.setColorFirst(mxColorFirst->GetSelectEntryColor());
- rAttribute.setColorLast(mxColorLast->GetSelectEntryColor());
+ maAttributes.setColorSeries(mxColorSeries->GetSelectEntryColor());
+ maAttributes.setColorNegative(mxColorNegative->GetSelectEntryColor());
+ maAttributes.setColorMarkers(mxColorMarker->GetSelectEntryColor());
+ maAttributes.setColorHigh(mxColorHigh->GetSelectEntryColor());
+ maAttributes.setColorLow(mxColorLow->GetSelectEntryColor());
+ maAttributes.setColorFirst(mxColorFirst->GetSelectEntryColor());
+ maAttributes.setColorLast(mxColorLast->GetSelectEntryColor());
auto& rDocFunc = mrViewData.GetDocShell()->GetDocFunc();
- rDocFunc.InsertSparklines(maInputRange, maOutputRange,
mpLocalSparklineGroup);
-}
+ if (mpSparklineGroup)
+ {
+ rDocFunc.ChangeSparklineGroupAttributes(mpSparklineGroup,
maAttributes);
+ }
+ else
+ {
+ auto pNewSparklineGroup =
std::make_shared<sc::SparklineGroup>(maAttributes);
+ rDocFunc.InsertSparklines(maInputRange, maOutputRange,
pNewSparklineGroup);
+ }
}
+} // end sc
+
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sc/source/ui/docshell/docfunc.cxx
b/sc/source/ui/docshell/docfunc.cxx
index e5972d54b7af..265d65f79e28 100644
--- a/sc/source/ui/docshell/docfunc.cxx
+++ b/sc/source/ui/docshell/docfunc.cxx
@@ -95,9 +95,11 @@
#include <columnspanset.hxx>
#include <validat.hxx>
#include <SparklineGroup.hxx>
+#include <SparklineAttributes.hxx>
#include <SparklineData.hxx>
#include <undo/UndoInsertSparkline.hxx>
#include <undo/UndoDeleteSparkline.hxx>
+#include <undo/UndoEditSparklineGroup.hxx>
#include <config_features.h>
#include <memory>
@@ -5857,4 +5859,14 @@ bool ScDocFunc::DeleteSparkline(ScAddress const&
rAddress)
return true;
}
+bool
ScDocFunc::ChangeSparklineGroupAttributes(std::shared_ptr<sc::SparklineGroup>
const& pExistingSparklineGroup,
+ sc::SparklineAttributes const&
rNewAttributes)
+{
+ auto pUndo = std::make_unique<sc::UndoEditSparklneGroup>(rDocShell,
pExistingSparklineGroup, rNewAttributes);
+ // change sparkline group attributes by "redoing"
+ pUndo->Redo();
+ rDocShell.GetUndoManager()->AddUndoAction(std::move(pUndo));
+ return true;
+}
+
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sc/source/ui/inc/SparklineDialog.hxx
b/sc/source/ui/inc/SparklineDialog.hxx
index 776480b05fce..1be81e80f7d6 100644
--- a/sc/source/ui/inc/SparklineDialog.hxx
+++ b/sc/source/ui/inc/SparklineDialog.hxx
@@ -13,6 +13,9 @@
#include "anyrefdg.hxx"
#include <viewdata.hxx>
+#include <SparklineGroup.hxx>
+#include <SparklineAttributes.hxx>
+
class ColorListBox;
namespace sc
@@ -88,7 +91,8 @@ private:
DECL_LINK(SpinLineWidthChanged, weld::SpinButton&, void);
DECL_LINK(SpinCustomChanged, weld::FormattedSpinButton&, void);
- std::shared_ptr<sc::SparklineGroup> mpLocalSparklineGroup;
+ std::shared_ptr<sc::SparklineGroup> mpSparklineGroup;
+ sc::SparklineAttributes maAttributes;
bool mbEditMode;
diff --git a/sc/source/ui/inc/docfunc.hxx b/sc/source/ui/inc/docfunc.hxx
index 9ac438639585..72ac0fbcb9f0 100644
--- a/sc/source/ui/inc/docfunc.hxx
+++ b/sc/source/ui/inc/docfunc.hxx
@@ -54,6 +54,7 @@ enum class CreateNameFlags;
namespace sc
{
struct ColRowSpan;
+ class SparklineAttributes;
class SparklineGroup;
}
@@ -241,6 +242,9 @@ public:
SC_DLLPUBLIC bool DeleteSparkline(ScAddress const& rAddress);
+ SC_DLLPUBLIC bool
ChangeSparklineGroupAttributes(std::shared_ptr<sc::SparklineGroup> const&
pExistingSparklineGroup,
+ sc::SparklineAttributes
const& rNewAttributes);
+
private:
void ProtectDocument(const ScDocProtection& rProtect);
};
diff --git a/sc/source/ui/inc/undo/UndoEditSparklineGroup.hxx
b/sc/source/ui/inc/undo/UndoEditSparklineGroup.hxx
new file mode 100644
index 000000000000..373ebd35eb69
--- /dev/null
+++ b/sc/source/ui/inc/undo/UndoEditSparklineGroup.hxx
@@ -0,0 +1,44 @@
+/* -*- 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 "undobase.hxx"
+#include <memory>
+
+#include <SparklineAttributes.hxx>
+#include <SparklineGroup.hxx>
+
+namespace sc
+{
+/** Undo action for editing a Sparkline */
+class UndoEditSparklneGroup : public ScSimpleUndo
+{
+private:
+ std::shared_ptr<sc::SparklineGroup> m_pSparklineGroup;
+ sc::SparklineAttributes m_aNewAttributes;
+ sc::SparklineAttributes m_aOriginalAttributes;
+
+public:
+ UndoEditSparklneGroup(ScDocShell& rDocShell,
+ std::shared_ptr<sc::SparklineGroup> const&
rSparklineGroup,
+ sc::SparklineAttributes const& rAttributes);
+ virtual ~UndoEditSparklneGroup() override;
+
+ void Undo() override;
+ void Redo() override;
+ bool CanRepeat(SfxRepeatTarget& rTarget) const override;
+ void Repeat(SfxRepeatTarget& rTarget) override;
+ OUString GetComment() const override;
+};
+
+} // namespace sc
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sc/source/ui/sparklines/SparklineGroup.cxx
b/sc/source/ui/sparklines/SparklineGroup.cxx
index 9ef2c7044ab0..1ba235e75014 100644
--- a/sc/source/ui/sparklines/SparklineGroup.cxx
+++ b/sc/source/ui/sparklines/SparklineGroup.cxx
@@ -12,6 +12,12 @@
namespace sc
{
+SparklineGroup::SparklineGroup(SparklineAttributes const& rSparklineAttributes)
+ : m_aAttributes(rSparklineAttributes)
+ , m_aGUID(tools::Guid::Generate)
+{
+}
+
SparklineGroup::SparklineGroup()
: m_aGUID(tools::Guid::Generate)
{
diff --git a/sc/source/ui/undo/UndoEditSparklineGroup.cxx
b/sc/source/ui/undo/UndoEditSparklineGroup.cxx
new file mode 100644
index 000000000000..8136003d6b20
--- /dev/null
+++ b/sc/source/ui/undo/UndoEditSparklineGroup.cxx
@@ -0,0 +1,65 @@
+/* -*- 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 <undo/UndoEditSparklineGroup.hxx>
+
+#include <globstr.hrc>
+#include <scresid.hxx>
+
+#include <Sparkline.hxx>
+#include <SparklineGroup.hxx>
+#include <SparklineAttributes.hxx>
+
+namespace sc
+{
+UndoEditSparklneGroup::UndoEditSparklneGroup(
+ ScDocShell& rDocShell, std::shared_ptr<sc::SparklineGroup> const&
pSparklineGroup,
+ sc::SparklineAttributes const& rAttributes)
+ : ScSimpleUndo(&rDocShell)
+ , m_pSparklineGroup(pSparklineGroup)
+ , m_aNewAttributes(rAttributes)
+ , m_aOriginalAttributes(pSparklineGroup->getAttributes())
+{
+}
+
+UndoEditSparklneGroup::~UndoEditSparklneGroup() = default;
+
+void UndoEditSparklneGroup::Undo()
+{
+ BeginUndo();
+
+ m_pSparklineGroup->setAttributes(m_aOriginalAttributes);
+ pDocShell->PostPaintGridAll();
+
+ EndUndo();
+}
+
+void UndoEditSparklneGroup::Redo()
+{
+ BeginRedo();
+
+ m_pSparklineGroup->setAttributes(m_aNewAttributes);
+ pDocShell->PostPaintGridAll();
+
+ EndRedo();
+}
+
+void UndoEditSparklneGroup::Repeat(SfxRepeatTarget& /*rTarget*/) {}
+
+bool UndoEditSparklneGroup::CanRepeat(SfxRepeatTarget& /*rTarget*/) const {
return false; }
+
+OUString UndoEditSparklneGroup::GetComment() const
+{
+ return ScResId(STR_UNDO_EDIT_SPARKLINE_GROUP);
+}
+
+} // end sc namespace
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */