sc/Library_sc.mk                              |    2 
 sc/inc/Sparkline.hxx                          |    8 -
 sc/inc/SparklineCell.hxx                      |    4 
 sc/inc/SparklineData.hxx                      |   42 +++++
 sc/inc/SparklineGroup.hxx                     |   31 ++++
 sc/inc/clipcontext.hxx                        |    7 
 sc/inc/column.hxx                             |   11 +
 sc/inc/document.hxx                           |    2 
 sc/inc/globstr.hrc                            |    2 
 sc/inc/mtvcellfunc.hxx                        |    8 +
 sc/inc/table.hxx                              |    2 
 sc/qa/unit/SparklineImportExportTest.cxx      |   12 -
 sc/qa/unit/SparklineTest.cxx                  |  194 ++++++++++++++++++++++++--
 sc/source/core/data/clipcontext.cxx           |   21 ++
 sc/source/core/data/column.cxx                |    1 
 sc/source/core/data/column2.cxx               |   77 ++++++++++
 sc/source/core/data/column3.cxx               |   14 +
 sc/source/core/data/column4.cxx               |   41 +++++
 sc/source/core/data/document.cxx              |    4 
 sc/source/core/data/document10.cxx            |    3 
 sc/source/core/data/table2.cxx                |   11 -
 sc/source/ui/dialogs/SparklineDialog.cxx      |   95 +-----------
 sc/source/ui/docshell/docfunc.cxx             |   82 ++++++++++
 sc/source/ui/inc/cliputil.hxx                 |    6 
 sc/source/ui/inc/docfunc.hxx                  |    7 
 sc/source/ui/inc/undo/UndoInsertSparkline.hxx |   45 ++++++
 sc/source/ui/sparklines/SparklineData.cxx     |   30 ++++
 sc/source/ui/undo/UndoInsertSparkline.cxx     |   78 ++++++++++
 sc/source/ui/view/cellsh.cxx                  |    4 
 sc/source/ui/view/output.cxx                  |    4 
 30 files changed, 711 insertions(+), 137 deletions(-)

New commits:
commit 9a701051b5c81486e40c500ea9777700e734b421
Author:     Tomaž Vajngerl <tomaz.vajng...@collabora.co.uk>
AuthorDate: Sun Mar 20 20:49:18 2022 +0900
Commit:     Tomaž Vajngerl <tomaz.vajng...@collabora.co.uk>
CommitDate: Sun Mar 20 20:49:18 2022 +0900

    sc: add Undo/Redo for inserting Sparklines
    
    Move the code to insert a sparkline from the SparklineDialog to
    DocFunc and inside the UndoInsertSparkline, so there is no code
    duplication and the code can be tested.
    
    Change-Id: I85f4020190ae835b33e706ec9cb2cda9fd6fc752

diff --git a/sc/Library_sc.mk b/sc/Library_sc.mk
index f145d3a7fbf2..2a9c6f659a0a 100644
--- a/sc/Library_sc.mk
+++ b/sc/Library_sc.mk
@@ -512,6 +512,7 @@ $(eval $(call gb_Library_add_exception_objects,sc,\
     sc/source/ui/sidebar/NumberFormatControl \
     sc/source/ui/sidebar/NumberFormatPropertyPanel \
     sc/source/ui/sidebar/ScPanelFactory \
+    sc/source/ui/sparklines/SparklineData \
     sc/source/ui/StatisticsDialogs/AnalysisOfVarianceDialog \
     sc/source/ui/StatisticsDialogs/CorrelationDialog \
     sc/source/ui/StatisticsDialogs/CovarianceDialog \
@@ -549,6 +550,7 @@ $(eval $(call gb_Library_add_exception_objects,sc,\
     sc/source/ui/undo/undostyl \
     sc/source/ui/undo/undotab \
     sc/source/ui/undo/undoutil \
+    sc/source/ui/undo/UndoInsertSparkline \
     sc/source/ui/unoobj/ChartRangeSelectionListener \
     sc/source/ui/unoobj/addruno \
     sc/source/ui/unoobj/afmtuno \
diff --git a/sc/inc/SparklineData.hxx b/sc/inc/SparklineData.hxx
new file mode 100644
index 000000000000..80cc8a0329c2
--- /dev/null
+++ b/sc/inc/SparklineData.hxx
@@ -0,0 +1,42 @@
+/* -*- 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 "address.hxx"
+#include "scdllapi.h"
+
+namespace sc
+{
+struct SC_DLLPUBLIC SparklineData
+{
+    ScAddress maPosition;
+    ScRange maData;
+
+    SparklineData(ScAddress const& rPosition, ScRange const& rData)
+        : maPosition(rPosition)
+        , maData(rData)
+    {
+    }
+};
+
+enum class RangeOrientation
+{
+    Unknown,
+    Row,
+    Col
+};
+
+SC_DLLPUBLIC RangeOrientation calculateOrientation(sal_Int32 nOutputSize,
+                                                   ScRange const& rInputRange);
+
+} // end sc
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sc/inc/globstr.hrc b/sc/inc/globstr.hrc
index 793d3cb95d55..6ae26c9d4a0f 100644
--- a/sc/inc/globstr.hrc
+++ b/sc/inc/globstr.hrc
@@ -539,7 +539,7 @@
 #define STR_HYPHENATECELL_ON                    NC_("STR_HYPHENATECELL_ON", 
"Hyphenate: On")
 #define STR_HYPHENATECELL_OFF                   NC_("STR_HYPHENATECELL_OFF", 
"Hyphenate: Off")
 #define STR_INDENTCELL                          NC_("STR_INDENTCELL", "Indent: 
")
-
+#define STR_UNDO_INSERT_SPARKLINE_GROUP         
NC_("STR_UNDO_INSERT_SPARKLINE", "Insert Sparkline Group")
 #endif
 
 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sc/qa/unit/SparklineTest.cxx b/sc/qa/unit/SparklineTest.cxx
index 826638feb17c..987cc0bb452a 100644
--- a/sc/qa/unit/SparklineTest.cxx
+++ b/sc/qa/unit/SparklineTest.cxx
@@ -11,6 +11,8 @@
 #include <docsh.hxx>
 #include <tabvwsh.hxx>
 #include <cliputil.hxx>
+#include <docfunc.hxx>
+
 #include <Sparkline.hxx>
 #include <SparklineGroup.hxx>
 
@@ -21,8 +23,6 @@ class SparklineTest : public ScBootstrapFixture
 private:
     uno::Reference<uno::XInterface> m_xCalcComponent;
 
-    sc::Sparkline* createTestSparkline(ScDocument& rDocument);
-
 public:
     SparklineTest()
         : ScBootstrapFixture("sc/qa/unit/data")
@@ -50,29 +50,38 @@ public:
     void testDeleteSprkline();
     void testCopyPasteSparkline();
     void testCutPasteSparkline();
+    void testUndoRedoSparkline();
 
     CPPUNIT_TEST_SUITE(SparklineTest);
     CPPUNIT_TEST(testAddSparkline);
     CPPUNIT_TEST(testDeleteSprkline);
     CPPUNIT_TEST(testCopyPasteSparkline);
     CPPUNIT_TEST(testCutPasteSparkline);
+    CPPUNIT_TEST(testUndoRedoSparkline);
     CPPUNIT_TEST_SUITE_END();
 };
 
-sc::Sparkline* SparklineTest::createTestSparkline(ScDocument& rDocument)
+namespace
+{
+void insertTestData(ScDocument& rDocument)
 {
-    auto pSparklineGroup = std::make_shared<sc::SparklineGroup>();
-
-    sc::Sparkline* pSparkline = rDocument.CreateSparkline(ScAddress(0, 6, 0), 
pSparklineGroup);
-    if (!pSparkline)
-        return nullptr;
-
     rDocument.SetValue(0, 0, 0, 4);
     rDocument.SetValue(0, 1, 0, -2);
     rDocument.SetValue(0, 2, 0, 1);
     rDocument.SetValue(0, 3, 0, -3);
     rDocument.SetValue(0, 4, 0, 5);
     rDocument.SetValue(0, 5, 0, 3);
+}
+
+sc::Sparkline* createTestSparkline(ScDocument& rDocument)
+{
+    auto pSparklineGroup = std::make_shared<sc::SparklineGroup>();
+
+    sc::Sparkline* pSparkline = rDocument.CreateSparkline(ScAddress(0, 6, 0), 
pSparklineGroup);
+    if (!pSparkline)
+        return nullptr;
+
+    insertTestData(rDocument);
 
     ScRangeList aList;
     aList.push_back(ScRange(0, 0, 0, 0, 5, 0));
@@ -81,6 +90,8 @@ sc::Sparkline* SparklineTest::createTestSparkline(ScDocument& 
rDocument)
     return pSparkline;
 }
 
+} // end anonymous namespace
+
 void SparklineTest::testAddSparkline()
 {
     ScDocShellRef xDocSh = loadEmptyDocument();
@@ -228,6 +239,55 @@ void SparklineTest::testCutPasteSparkline()
     xDocSh->DoClose();
 }
 
+void SparklineTest::testUndoRedoSparkline()
+{
+    ScDocShellRef xDocSh = loadEmptyDocument();
+    CPPUNIT_ASSERT(xDocSh);
+
+    ScDocument& rDocument = xDocSh->GetDocument();
+    ScTabViewShell* pViewShell = xDocSh->GetBestViewShell(false);
+    CPPUNIT_ASSERT(pViewShell);
+
+    auto& rDocFunc = xDocSh->GetDocFunc();
+
+    // insert test data - A1:A6
+    insertTestData(rDocument);
+
+    // Sparkline range
+    ScRange aRange(0, 6, 0, 0, 6, 0);
+
+    // Check Sparkline at cell A7 doesn't exists
+    auto pSparkline = rDocument.GetSparkline(aRange.aStart);
+    CPPUNIT_ASSERT(!pSparkline);
+
+    auto pSparklineGroup = std::make_shared<sc::SparklineGroup>();
+    rDocFunc.InsertSparklines(ScRange(0, 0, 0, 0, 5, 0), aRange, 
pSparklineGroup);
+
+    // Check Sparkline at cell A7 exists
+    pSparkline = rDocument.GetSparkline(aRange.aStart);
+    CPPUNIT_ASSERT(pSparkline);
+    CPPUNIT_ASSERT_EQUAL(SCCOL(0), pSparkline->getColumn());
+    CPPUNIT_ASSERT_EQUAL(SCROW(6), pSparkline->getRow());
+
+    // Undo
+    rDocument.GetUndoManager()->Undo();
+
+    // Check Sparkline at cell A7 doesn't exists
+    pSparkline = rDocument.GetSparkline(aRange.aStart);
+    CPPUNIT_ASSERT(!pSparkline);
+
+    // Redo
+    rDocument.GetUndoManager()->Redo();
+
+    // Check Sparkline at cell A7 exists
+    pSparkline = rDocument.GetSparkline(aRange.aStart);
+    CPPUNIT_ASSERT(pSparkline);
+    CPPUNIT_ASSERT_EQUAL(SCCOL(0), pSparkline->getColumn());
+    CPPUNIT_ASSERT_EQUAL(SCROW(6), pSparkline->getRow());
+
+    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 fac1d8274be5..103582c25a6e 100644
--- a/sc/source/ui/dialogs/SparklineDialog.cxx
+++ b/sc/source/ui/dialogs/SparklineDialog.cxx
@@ -8,10 +8,13 @@
  */
 
 #include <SparklineDialog.hxx>
+#include <SparklineData.hxx>
 #include <SparklineGroup.hxx>
 #include <Sparkline.hxx>
 #include <reffact.hxx>
 
+#include <docfunc.hxx>
+
 #include <svx/colorbox.hxx>
 
 namespace sc
@@ -310,48 +313,24 @@ IMPL_LINK_NOARG(SparklineDialog, SelectSparklineType, 
weld::Toggleable&, void)
         mpLocalSparklineGroup->m_eType = sc::SparklineType::Stacked;
 }
 
-namespace
-{
-enum class RangeOrientation
-{
-    Unknown,
-    Row,
-    Col
-};
-
-RangeOrientation calculateOrientation(sal_Int32 nOutputSize, ScRange const& 
rInputRange)
-{
-    sal_Int32 nRowSize = rInputRange.aEnd.Row() - rInputRange.aStart.Row();
-    sal_Int32 nColSize = rInputRange.aEnd.Col() - rInputRange.aStart.Col();
-
-    auto eInputOrientation = RangeOrientation::Unknown;
-    if (nOutputSize == nRowSize)
-        eInputOrientation = RangeOrientation::Row;
-    else if (nOutputSize == nColSize)
-        eInputOrientation = RangeOrientation::Col;
-    return eInputOrientation;
-}
-
-} // end anonymous namespace
-
 bool SparklineDialog::checkValidInputOutput()
 {
     if (!maInputRange.IsValid() || !maOutputRange.IsValid())
         return false;
 
-    RangeOrientation eInputOrientation = RangeOrientation::Unknown;
+    sc::RangeOrientation eInputOrientation = sc::RangeOrientation::Unknown;
     if (maOutputRange.aStart.Col() == maOutputRange.aEnd.Col())
     {
         sal_Int32 nOutputRowSize = maOutputRange.aEnd.Row() - 
maOutputRange.aStart.Row();
-        eInputOrientation = calculateOrientation(nOutputRowSize, maInputRange);
+        eInputOrientation = sc::calculateOrientation(nOutputRowSize, 
maInputRange);
     }
     else if (maOutputRange.aStart.Row() == maOutputRange.aEnd.Row())
     {
         sal_Int32 nOutputColSize = maOutputRange.aEnd.Col() - 
maOutputRange.aStart.Col();
-        eInputOrientation = calculateOrientation(nOutputColSize, maInputRange);
+        eInputOrientation = sc::calculateOrientation(nOutputColSize, 
maInputRange);
     }
 
-    return eInputOrientation != RangeOrientation::Unknown;
+    return eInputOrientation != sc::RangeOrientation::Unknown;
 }
 
 void SparklineDialog::perform()
@@ -364,65 +343,9 @@ void SparklineDialog::perform()
     mpLocalSparklineGroup->m_aColorFirst = mxColorFirst->GetSelectEntryColor();
     mpLocalSparklineGroup->m_aColorLast = mxColorLast->GetSelectEntryColor();
 
-    if (maOutputRange.aStart.Col() == maOutputRange.aEnd.Col())
-    {
-        sal_Int32 nOutputRowSize = maOutputRange.aEnd.Row() - 
maOutputRange.aStart.Row();
-
-        auto eInputOrientation = calculateOrientation(nOutputRowSize, 
maInputRange);
-
-        if (eInputOrientation == RangeOrientation::Unknown)
-            return;
-
-        sal_Int32 nIndex = 0;
-        for (ScAddress aAddress = maOutputRange.aStart; aAddress.Row() <= 
maOutputRange.aEnd.Row();
-             aAddress.IncRow())
-        {
-            ScRange aInputRangeSlice = maInputRange;
-            if (eInputOrientation == RangeOrientation::Row)
-            {
-                aInputRangeSlice.aStart.SetRow(maInputRange.aStart.Row() + 
nIndex);
-                aInputRangeSlice.aEnd.SetRow(maInputRange.aStart.Row() + 
nIndex);
-            }
-            else
-            {
-                aInputRangeSlice.aStart.SetCol(maInputRange.aStart.Col() + 
nIndex);
-                aInputRangeSlice.aEnd.SetCol(maInputRange.aStart.Col() + 
nIndex);
-            }
-            auto* pCreated = mrDocument.CreateSparkline(aAddress, 
mpLocalSparklineGroup);
-            pCreated->setInputRange(aInputRangeSlice);
-            nIndex++;
-        }
-    }
-    else if (maOutputRange.aStart.Row() == maOutputRange.aEnd.Row())
-    {
-        sal_Int32 nOutputColSize = maOutputRange.aEnd.Col() - 
maOutputRange.aStart.Col();
-
-        auto eInputOrientation = calculateOrientation(nOutputColSize, 
maInputRange);
-
-        if (eInputOrientation == RangeOrientation::Unknown)
-            return;
+    auto& rDocFunc = mrViewData.GetDocShell()->GetDocFunc();
 
-        sal_Int32 nIndex = 0;
-
-        for (ScAddress aAddress = maOutputRange.aStart; aAddress.Col() <= 
maOutputRange.aEnd.Col();
-             aAddress.IncCol())
-        {
-            ScRange aInputRangeSlice = maInputRange;
-            if (eInputOrientation == RangeOrientation::Row)
-            {
-                aInputRangeSlice.aStart.SetRow(maInputRange.aStart.Row() + 
nIndex);
-                aInputRangeSlice.aEnd.SetRow(maInputRange.aStart.Row() + 
nIndex);
-            }
-            else
-            {
-                aInputRangeSlice.aStart.SetCol(maInputRange.aStart.Col() + 
nIndex);
-                aInputRangeSlice.aEnd.SetCol(maInputRange.aStart.Col() + 
nIndex);
-            }
-            auto* pCreated = mrDocument.CreateSparkline(aAddress, 
mpLocalSparklineGroup);
-            pCreated->setInputRange(aInputRangeSlice);
-            nIndex++;
-        }
-    }
+    rDocFunc.InsertSparklines(maInputRange, maOutputRange, 
mpLocalSparklineGroup);
 }
 }
 
diff --git a/sc/source/ui/docshell/docfunc.cxx 
b/sc/source/ui/docshell/docfunc.cxx
index b6c93a86cfc0..f28ca7e74344 100644
--- a/sc/source/ui/docshell/docfunc.cxx
+++ b/sc/source/ui/docshell/docfunc.cxx
@@ -94,6 +94,9 @@
 #include <conditio.hxx>
 #include <columnspanset.hxx>
 #include <validat.hxx>
+#include <SparklineGroup.hxx>
+#include <SparklineData.hxx>
+#include <undo/UndoInsertSparkline.hxx>
 #include <config_features.h>
 
 #include <memory>
@@ -5759,4 +5762,83 @@ void ScDocFunc::EndListAction()
     rDocShell.GetUndoManager()->LeaveListAction();
 }
 
+bool ScDocFunc::InsertSparklines(ScRange const& rDataRange, ScRange const& 
rSparklineRange,
+                                std::shared_ptr<sc::SparklineGroup> 
pSparklineGroup)
+{
+    std::vector<sc::SparklineData> aSparklineDataVector;
+
+    if (rSparklineRange.aStart.Col() == rSparklineRange.aEnd.Col())
+    {
+        sal_Int32 nOutputRowSize = rSparklineRange.aEnd.Row() - 
rSparklineRange.aStart.Row();
+
+        auto eInputOrientation = sc::calculateOrientation(nOutputRowSize, 
rDataRange);
+
+        if (eInputOrientation == sc::RangeOrientation::Unknown)
+            return false;
+
+        sal_Int32 nIndex = 0;
+
+        for (ScAddress aAddress = rSparklineRange.aStart; aAddress.Row() <= 
rSparklineRange.aEnd.Row();
+             aAddress.IncRow())
+        {
+            ScRange aInputRangeSlice = rDataRange;
+            if (eInputOrientation == sc::RangeOrientation::Row)
+            {
+                aInputRangeSlice.aStart.SetRow(rDataRange.aStart.Row() + 
nIndex);
+                aInputRangeSlice.aEnd.SetRow(rDataRange.aStart.Row() + nIndex);
+            }
+            else
+            {
+                aInputRangeSlice.aStart.SetCol(rDataRange.aStart.Col() + 
nIndex);
+                aInputRangeSlice.aEnd.SetCol(rDataRange.aStart.Col() + nIndex);
+            }
+
+            aSparklineDataVector.emplace_back(aAddress, aInputRangeSlice);
+
+            nIndex++;
+        }
+    }
+    else if (rSparklineRange.aStart.Row() == rSparklineRange.aEnd.Row())
+    {
+        sal_Int32 nOutputColSize = rSparklineRange.aEnd.Col() - 
rSparklineRange.aStart.Col();
+
+        auto eInputOrientation = sc::calculateOrientation(nOutputColSize, 
rDataRange);
+
+        if (eInputOrientation == sc::RangeOrientation::Unknown)
+            return false;
+
+        sal_Int32 nIndex = 0;
+
+        for (ScAddress aAddress = rSparklineRange.aStart; aAddress.Col() <= 
rSparklineRange.aEnd.Col();
+             aAddress.IncCol())
+        {
+            ScRange aInputRangeSlice = rDataRange;
+            if (eInputOrientation == sc::RangeOrientation::Row)
+            {
+                aInputRangeSlice.aStart.SetRow(rDataRange.aStart.Row() + 
nIndex);
+                aInputRangeSlice.aEnd.SetRow(rDataRange.aStart.Row() + nIndex);
+            }
+            else
+            {
+                aInputRangeSlice.aStart.SetCol(rDataRange.aStart.Col() + 
nIndex);
+                aInputRangeSlice.aEnd.SetCol(rDataRange.aStart.Col() + nIndex);
+            }
+
+            aSparklineDataVector.emplace_back(aAddress, aInputRangeSlice);
+
+            nIndex++;
+        }
+    }
+
+    if (aSparklineDataVector.empty())
+        return false;
+
+    auto pUndoInsertSparkline = 
std::make_unique<sc::UndoInsertSparkline>(rDocShell, aSparklineDataVector, 
pSparklineGroup);
+    // insert the sparkline by "redoing"
+    pUndoInsertSparkline->Redo();
+    rDocShell.GetUndoManager()->AddUndoAction(std::move(pUndoInsertSparkline));
+
+    return true;
+}
+
 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sc/source/ui/inc/docfunc.hxx b/sc/source/ui/inc/docfunc.hxx
index 8b0ea7d7c16a..52d61cb2e86e 100644
--- a/sc/source/ui/inc/docfunc.hxx
+++ b/sc/source/ui/inc/docfunc.hxx
@@ -51,8 +51,10 @@ class ScPostIt;
 
 enum class TransliterationFlags;
 enum class CreateNameFlags;
-namespace sc {
+namespace sc
+{
     struct ColRowSpan;
+    class SparklineGroup;
 }
 
 class ScDocFunc
@@ -234,6 +236,9 @@ public:
 
     void ConvertFormulaToValue( const ScRange& rRange, bool bInteraction );
 
+    SC_DLLPUBLIC bool InsertSparklines(ScRange const& rDataRange, ScRange 
const& rSparklineRange,
+                                       std::shared_ptr<sc::SparklineGroup> 
pSparklineGroup);
+
 private:
     void ProtectDocument(const ScDocProtection& rProtect);
 };
diff --git a/sc/source/ui/inc/undo/UndoInsertSparkline.hxx 
b/sc/source/ui/inc/undo/UndoInsertSparkline.hxx
new file mode 100644
index 000000000000..3c2fa6d17977
--- /dev/null
+++ b/sc/source/ui/inc/undo/UndoInsertSparkline.hxx
@@ -0,0 +1,45 @@
+/* -*- 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 <address.hxx>
+#include <memory>
+
+namespace sc
+{
+class SparklineGroup;
+class SparklineData;
+
+/** Undo action for inserting a Sparkline */
+class UndoInsertSparkline : public ScSimpleUndo
+{
+private:
+    std::vector<sc::SparklineData> maSparklineDataVector;
+    std::shared_ptr<sc::SparklineGroup> mpSparklineGroup;
+
+public:
+    UndoInsertSparkline(ScDocShell& rDocShell,
+                        std::vector<SparklineData> const& rSparklineDataVector,
+                        std::shared_ptr<sc::SparklineGroup> pSparklineGroup);
+
+    virtual ~UndoInsertSparkline() 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/SparklineData.cxx 
b/sc/source/ui/sparklines/SparklineData.cxx
new file mode 100644
index 000000000000..a126acc10b0a
--- /dev/null
+++ b/sc/source/ui/sparklines/SparklineData.cxx
@@ -0,0 +1,30 @@
+/* -*- 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 <SparklineData.hxx>
+
+namespace sc
+{
+RangeOrientation calculateOrientation(sal_Int32 nOutputSize, ScRange const& 
rInputRange)
+{
+    sal_Int32 nRowSize = rInputRange.aEnd.Row() - rInputRange.aStart.Row();
+    sal_Int32 nColSize = rInputRange.aEnd.Col() - rInputRange.aStart.Col();
+
+    auto eInputOrientation = RangeOrientation::Unknown;
+    if (nOutputSize == nRowSize)
+        eInputOrientation = RangeOrientation::Row;
+    else if (nOutputSize == nColSize)
+        eInputOrientation = RangeOrientation::Col;
+    return eInputOrientation;
+}
+
+} // end sc
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sc/source/ui/undo/UndoInsertSparkline.cxx 
b/sc/source/ui/undo/UndoInsertSparkline.cxx
new file mode 100644
index 000000000000..c35cc3f6dc03
--- /dev/null
+++ b/sc/source/ui/undo/UndoInsertSparkline.cxx
@@ -0,0 +1,78 @@
+/* -*- 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/UndoInsertSparkline.hxx>
+#include <globstr.hrc>
+#include <scresid.hxx>
+
+#include <Sparkline.hxx>
+#include <SparklineGroup.hxx>
+#include <SparklineData.hxx>
+
+namespace sc
+{
+UndoInsertSparkline::UndoInsertSparkline(ScDocShell& rDocShell,
+                                         std::vector<SparklineData> const& 
rSparklineDataVector,
+                                         std::shared_ptr<sc::SparklineGroup> 
pSparklineGroup)
+    : ScSimpleUndo(&rDocShell)
+    , maSparklineDataVector(rSparklineDataVector)
+    , mpSparklineGroup(pSparklineGroup)
+{
+}
+
+UndoInsertSparkline::~UndoInsertSparkline() {}
+
+void UndoInsertSparkline::Undo()
+{
+    BeginUndo();
+
+    ScDocument& rDocument = pDocShell->GetDocument();
+    ScRangeList aRanges;
+    for (auto const& rSparklineData : maSparklineDataVector)
+    {
+        rDocument.DeleteSparkline(rSparklineData.maPosition);
+        aRanges.push_back(ScRange(rSparklineData.maPosition));
+    }
+
+    pDocShell->PostPaint(aRanges, PaintPartFlags::All);
+
+    EndUndo();
+}
+
+void UndoInsertSparkline::Redo()
+{
+    BeginRedo();
+
+    ScDocument& rDocument = pDocShell->GetDocument();
+    ScRangeList aRanges;
+    for (auto const& rSparklineData : maSparklineDataVector)
+    {
+        auto* pCreated = rDocument.CreateSparkline(rSparklineData.maPosition, 
mpSparklineGroup);
+        pCreated->setInputRange(rSparklineData.maData);
+        aRanges.push_back(ScRange(rSparklineData.maPosition));
+    }
+
+    pDocShell->PostPaint(aRanges, PaintPartFlags::All);
+
+    EndRedo();
+}
+
+void UndoInsertSparkline::Repeat(SfxRepeatTarget& /*rTarget*/) {}
+
+bool UndoInsertSparkline::CanRepeat(SfxRepeatTarget& /*rTarget*/) const { 
return false; }
+
+OUString UndoInsertSparkline::GetComment() const
+{
+    return ScResId(STR_UNDO_INSERT_SPARKLINE_GROUP);
+}
+
+} // end sc namespace
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
commit 62055d98dd2e6676aa20855a6dfe15234cde65b8
Author:     Tomaž Vajngerl <tomaz.vajng...@collabora.co.uk>
AuthorDate: Sat Mar 19 12:52:21 2022 +0900
Commit:     Tomaž Vajngerl <tomaz.vajng...@collabora.co.uk>
CommitDate: Sat Mar 19 12:52:21 2022 +0900

    sc: add support for copy/cut and paster of Sparklines
    
    Currently cut,copy and paste will copy the Sparkline and create
    a new SparklineGroup for each cell in the new cell range. This
    probably need to be adjusted so the SparklineGroup is shared.
    
    Change-Id: I6f86bb026753b2b4b5bfa46aca4ca9794721f311

diff --git a/sc/inc/SparklineGroup.hxx b/sc/inc/SparklineGroup.hxx
index ec3a8c8a971f..a045f8d659d1 100644
--- a/sc/inc/SparklineGroup.hxx
+++ b/sc/inc/SparklineGroup.hxx
@@ -101,7 +101,36 @@ public:
     {
     }
 
-    SparklineGroup(const SparklineGroup&) = delete;
+    SparklineGroup(SparklineGroup const& pOtherSparkline)
+        : m_aColorSeries(pOtherSparkline.m_aColorSeries)
+        , m_aColorNegative(pOtherSparkline.m_aColorNegative)
+        , m_aColorAxis(pOtherSparkline.m_aColorAxis)
+        , m_aColorMarkers(pOtherSparkline.m_aColorMarkers)
+        , m_aColorFirst(pOtherSparkline.m_aColorFirst)
+        , m_aColorLast(pOtherSparkline.m_aColorLast)
+        , m_aColorHigh(pOtherSparkline.m_aColorHigh)
+        , m_aColorLow(pOtherSparkline.m_aColorLow)
+        , m_eMinAxisType(pOtherSparkline.m_eMinAxisType)
+        , m_eMaxAxisType(pOtherSparkline.m_eMaxAxisType)
+        , m_fLineWeight(pOtherSparkline.m_fLineWeight)
+        , m_eType(pOtherSparkline.m_eType)
+        , m_bDateAxis(pOtherSparkline.m_bDateAxis)
+        , m_eDisplayEmptyCellsAs(pOtherSparkline.m_eDisplayEmptyCellsAs)
+        , m_bMarkers(pOtherSparkline.m_bMarkers)
+        , m_bHigh(pOtherSparkline.m_bHigh)
+        , m_bLow(pOtherSparkline.m_bLow)
+        , m_bFirst(pOtherSparkline.m_bFirst)
+        , m_bLast(pOtherSparkline.m_bLast)
+        , m_bNegative(pOtherSparkline.m_bNegative)
+        , m_bDisplayXAxis(pOtherSparkline.m_bDisplayXAxis)
+        , m_bDisplayHidden(pOtherSparkline.m_bDisplayHidden)
+        , m_bRightToLeft(pOtherSparkline.m_bRightToLeft)
+        , m_aManualMax(pOtherSparkline.m_aManualMax)
+        , m_aManualMin(pOtherSparkline.m_aManualMin)
+        , m_sUID(pOtherSparkline.m_sUID)
+    {
+    }
+
     SparklineGroup& operator=(const SparklineGroup&) = delete;
 };
 
diff --git a/sc/inc/clipcontext.hxx b/sc/inc/clipcontext.hxx
index 32e2dd97767a..b09e1be78761 100644
--- a/sc/inc/clipcontext.hxx
+++ b/sc/inc/clipcontext.hxx
@@ -12,6 +12,7 @@
 #include "address.hxx"
 #include "cellvalue.hxx"
 #include "celltextattr.hxx"
+#include "Sparkline.hxx"
 
 #include <memory>
 #include <vector>
@@ -60,11 +61,11 @@ class SC_DLLPUBLIC CopyFromClipContext final : public 
ClipContextBase
     std::vector<sc::CellTextAttr> maSingleCellAttrs;
     std::vector<const ScPatternAttr*> maSinglePatterns;
     std::vector<const ScPostIt*> maSingleNotes;
+    std::vector<std::shared_ptr<sc::Sparkline>> maSingleSparkline;
 
     ScConditionalFormatList* mpCondFormatList;
     bool mbAsLink:1;
     bool mbSkipEmptyCells:1;
-    bool mbCloneNotes:1;
     bool mbTableProtected:1;
 
 public:
@@ -119,6 +120,9 @@ public:
     const ScPostIt* getSingleCellNote( size_t nColOffset ) const;
     void setSingleCellNote( size_t nColOffset, const ScPostIt* pNote );
 
+    std::shared_ptr<sc::Sparkline> const& getSingleSparkline(size_t 
nColOffset) const;
+    void setSingleSparkline(size_t nColOffset, std::shared_ptr<sc::Sparkline> 
const& pSparkline);
+
     void setCondFormatList( ScConditionalFormatList* pCondFormatList );
     ScConditionalFormatList* getCondFormatList();
 
@@ -135,6 +139,7 @@ public:
      */
     bool isSkipEmptyCells() const;
     bool isCloneNotes() const;
+    bool isCloneSparklines() const;
     bool isDateCell( const ScColumn& rCol, SCROW nRow ) const;
 };
 
diff --git a/sc/inc/column.hxx b/sc/inc/column.hxx
index 91bb18b4813b..3da4a7bac798 100644
--- a/sc/inc/column.hxx
+++ b/sc/inc/column.hxx
@@ -168,6 +168,9 @@ friend class sc::CellStoreEvent;
         SCROW nRow, SCTAB nTab, const OUString& rString, 
formula::FormulaGrammar::AddressConvention eConv,
         const ScSetStringParam* pParam );
 
+    void duplicateSparkline(sc::CopyFromClipContext& rContext, 
sc::ColumnBlockPosition* pBlockPos,
+                            size_t nColOffset, size_t nDestSize, ScAddress 
aDestPosition);
+
 public:
 
     /** Broadcast mode for SetDirty(SCROW,SCROW,BroadcastMode). */
@@ -193,6 +196,8 @@ public:
     const sc::CellTextAttrStoreType& GetCellAttrStore() const { return 
maCellTextAttrs; }
     sc::CellNoteStoreType& GetCellNoteStore() { return maCellNotes; }
     const sc::CellNoteStoreType& GetCellNoteStore() const { return 
maCellNotes; }
+    sc::SparklineStoreType& GetSparklineStore() { return maSparklines; }
+    const sc::SparklineStoreType& GetSparklineStore() const { return 
maSparklines; }
 
     ScRefCellValue GetCellValue( SCROW nRow ) const;
     ScRefCellValue GetCellValue( sc::ColumnBlockPosition& rBlockPos, SCROW 
nRow );
@@ -621,6 +626,10 @@ public:
     void CreateSparklineCell(SCROW nRow, std::shared_ptr<sc::Sparkline> const& 
pSparkline);
     void DeleteSparklineCells(sc::ColumnBlockPosition& rBlockPos, SCROW nRow1, 
SCROW nRow2);
     bool DeleteSparkline(SCROW nRow);
+    bool IsSparklinesEmptyBlock(SCROW nStartRow, SCROW nEndRow) const;
+    void CopyCellSparklinesToDocument(SCROW nRow1, SCROW nRow2, ScColumn& 
rDestCol, SCROW nRowOffsetDest) const;
+    void DuplicateSparklines(SCROW nStartRow, size_t nDataSize, ScColumn& 
rDestCol,
+                             sc::ColumnBlockPosition& rDestBlockPos, SCROW 
nRowOffsetDest = 0) const;
 
     // cell notes
     ScPostIt* GetCellNote( SCROW nRow );
@@ -649,7 +658,7 @@ public:
         SCROW nRowOffsetDest = 0) const;
 
     void DuplicateNotes(SCROW nStartRow, size_t nDataSize, ScColumn& rDestCol,
-                            sc::ColumnBlockPosition& maDestBlockPos, bool 
bCloneCaption, SCROW nRowOffsetDest=0 ) const;
+                            sc::ColumnBlockPosition& rDestBlockPos, bool 
bCloneCaption, SCROW nRowOffsetDest = 0) const;
 
     void UpdateNoteCaptions( SCROW nRow1, SCROW nRow2 );
 
diff --git a/sc/inc/mtvcellfunc.hxx b/sc/inc/mtvcellfunc.hxx
index a2a708d5f8fc..89e41fb915fd 100644
--- a/sc/inc/mtvcellfunc.hxx
+++ b/sc/inc/mtvcellfunc.hxx
@@ -178,6 +178,14 @@ ProcessBroadcaster(
         BroadcasterStoreType, broadcaster_block, FuncElem, 
FuncElseNoOp<size_t> >(it, rStore, nRow1, nRow2, rFuncElem, aElse);
 }
 
+template<typename Functor>
+typename SparklineStoreType::const_iterator
+ParseSparkline(const SparklineStoreType::const_iterator& itPos, const 
SparklineStoreType& rStore, SCROW nStart, SCROW nEnd, Functor& rFunctor)
+{
+    FuncElseNoOp<size_t> aElse;
+    return ParseElements1<SparklineStoreType, sparkline_block, Functor, 
FuncElseNoOp<size_t> >(itPos, rStore, nStart, nEnd, rFunctor, aElse);
+}
+
 }
 
 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sc/qa/unit/SparklineTest.cxx b/sc/qa/unit/SparklineTest.cxx
index 74f40579d99f..826638feb17c 100644
--- a/sc/qa/unit/SparklineTest.cxx
+++ b/sc/qa/unit/SparklineTest.cxx
@@ -9,6 +9,8 @@
 
 #include "helper/qahelper.hxx"
 #include <docsh.hxx>
+#include <tabvwsh.hxx>
+#include <cliputil.hxx>
 #include <Sparkline.hxx>
 #include <SparklineGroup.hxx>
 
@@ -46,10 +48,14 @@ public:
 
     void testAddSparkline();
     void testDeleteSprkline();
+    void testCopyPasteSparkline();
+    void testCutPasteSparkline();
 
     CPPUNIT_TEST_SUITE(SparklineTest);
     CPPUNIT_TEST(testAddSparkline);
     CPPUNIT_TEST(testDeleteSprkline);
+    CPPUNIT_TEST(testCopyPasteSparkline);
+    CPPUNIT_TEST(testCutPasteSparkline);
     CPPUNIT_TEST_SUITE_END();
 };
 
@@ -85,10 +91,10 @@ void SparklineTest::testAddSparkline()
     sc::Sparkline* pSparkline = createTestSparkline(rDocument);
     CPPUNIT_ASSERT(pSparkline);
 
-    sc::Sparkline* pGetSparkline = rDocument.GetSparkline(ScAddress(0, 6, 0));
+    auto pGetSparkline = rDocument.GetSparkline(ScAddress(0, 6, 0));
     CPPUNIT_ASSERT(pGetSparkline);
 
-    CPPUNIT_ASSERT_EQUAL(pGetSparkline, pSparkline);
+    CPPUNIT_ASSERT_EQUAL(pGetSparkline.get(), pSparkline);
 
     sc::SparklineList* pList = rDocument.GetSparklineList(0);
     CPPUNIT_ASSERT(pList);
@@ -112,12 +118,116 @@ void SparklineTest::testDeleteSprkline()
 
     clearRange(&rDocument, ScRange(0, 6, 0, 0, 6, 0));
 
-    sc::Sparkline* pGetSparkline = rDocument.GetSparkline(ScAddress(0, 6, 0));
+    auto pGetSparkline = rDocument.GetSparkline(ScAddress(0, 6, 0));
     CPPUNIT_ASSERT(!pGetSparkline);
 
     xDocSh->DoClose();
 }
 
+void SparklineTest::testCopyPasteSparkline()
+{
+    ScDocShellRef xDocSh = loadEmptyDocument();
+    CPPUNIT_ASSERT(xDocSh);
+
+    ScDocument& rDocument = xDocSh->GetDocument();
+    ScTabViewShell* pViewShell = xDocSh->GetBestViewShell(false);
+    CPPUNIT_ASSERT(pViewShell);
+
+    auto* pCreatedSparkline = createTestSparkline(rDocument);
+    CPPUNIT_ASSERT(pCreatedSparkline);
+
+    ScRange aSourceRange(0, 6, 0, 0, 6, 0);
+    auto pSparkline = rDocument.GetSparkline(aSourceRange.aStart);
+
+    CPPUNIT_ASSERT(pSparkline);
+    CPPUNIT_ASSERT_EQUAL(SCCOL(0), pSparkline->getColumn());
+    CPPUNIT_ASSERT_EQUAL(SCROW(6), pSparkline->getRow());
+
+    // CopyToClip / CopyFromClip with a aClipDoc
+    {
+        ScDocument aClipDoc(SCDOCMODE_CLIP);
+        copyToClip(&rDocument, aSourceRange, &aClipDoc);
+
+        auto pClipSparkline = aClipDoc.GetSparkline(aSourceRange.aStart);
+        CPPUNIT_ASSERT(pClipSparkline);
+
+        ScRange aPasteRange(0, 7, 0, 0, 7, 0);
+
+        ScMarkData aMark(rDocument.GetSheetLimits());
+        aMark.SetMarkArea(aPasteRange);
+        rDocument.CopyFromClip(aPasteRange, aMark, InsertDeleteFlags::ALL, 
nullptr, &aClipDoc);
+
+        auto pSparklineCopy = rDocument.GetSparkline(aPasteRange.aStart);
+        CPPUNIT_ASSERT(pSparklineCopy);
+
+        CPPUNIT_ASSERT_EQUAL(SCCOL(0), pSparklineCopy->getColumn());
+        CPPUNIT_ASSERT_EQUAL(SCROW(7), pSparklineCopy->getRow());
+    }
+
+    // Copy / Paste with a ClipDoc
+    {
+        pViewShell->GetViewData().GetMarkData().SetMarkArea(aSourceRange);
+
+        // Copy
+        ScDocument aClipDoc(SCDOCMODE_CLIP);
+        pViewShell->GetViewData().GetView()->CopyToClip(&aClipDoc, false, 
false, false, false);
+
+        // Paste
+        ScRange aPasteRange(0, 8, 0, 0, 8, 0);
+
+        pViewShell->GetViewData().GetMarkData().SetMarkArea(aPasteRange);
+        
pViewShell->GetViewData().GetView()->PasteFromClip(InsertDeleteFlags::ALL, 
&aClipDoc);
+
+        auto pSparklineCopy = rDocument.GetSparkline(aPasteRange.aStart);
+        CPPUNIT_ASSERT(pSparklineCopy);
+
+        CPPUNIT_ASSERT_EQUAL(SCCOL(0), pSparklineCopy->getColumn());
+        CPPUNIT_ASSERT_EQUAL(SCROW(8), pSparklineCopy->getRow());
+    }
+
+    xDocSh->DoClose();
+}
+
+void SparklineTest::testCutPasteSparkline()
+{
+    ScDocShellRef xDocSh = loadEmptyDocument();
+    CPPUNIT_ASSERT(xDocSh);
+
+    ScDocument& rDocument = xDocSh->GetDocument();
+    ScTabViewShell* pViewShell = xDocSh->GetBestViewShell(false);
+    CPPUNIT_ASSERT(pViewShell);
+
+    auto* pCreatedSparkline = createTestSparkline(rDocument);
+    CPPUNIT_ASSERT(pCreatedSparkline);
+
+    ScRange aSourceRange(0, 6, 0, 0, 6, 0);
+    auto pSparkline = rDocument.GetSparkline(aSourceRange.aStart);
+
+    CPPUNIT_ASSERT(pSparkline);
+    CPPUNIT_ASSERT_EQUAL(SCCOL(0), pSparkline->getColumn());
+    CPPUNIT_ASSERT_EQUAL(SCROW(6), pSparkline->getRow());
+
+    // Mark source range
+    pViewShell->GetViewData().GetMarkData().SetMarkArea(aSourceRange);
+
+    // Cut
+    pViewShell->GetViewData().GetView()->CopyToClip(nullptr, true /*bCut*/, 
false, false, true);
+
+    // Paste
+    ScRange aPasteRange(0, 7, 0, 0, 7, 0);
+    pViewShell->GetViewData().GetMarkData().SetMarkArea(aPasteRange);
+    ScClipUtil::PasteFromClipboard(pViewShell->GetViewData(), pViewShell, 
false);
+
+    // Check
+    auto pSparklineCopy = rDocument.GetSparkline(aPasteRange.aStart);
+    CPPUNIT_ASSERT(pSparklineCopy);
+
+    CPPUNIT_ASSERT_EQUAL(SCCOL(0), pSparklineCopy->getColumn());
+    CPPUNIT_ASSERT_EQUAL(SCROW(7), pSparklineCopy->getRow());
+
+    xDocSh->DoClose();
+}
+
 CPPUNIT_TEST_SUITE_REGISTRATION(SparklineTest);
 
 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sc/source/core/data/clipcontext.cxx 
b/sc/source/core/data/clipcontext.cxx
index 02e2bcc86652..70f2319a185f 100644
--- a/sc/source/core/data/clipcontext.cxx
+++ b/sc/source/core/data/clipcontext.cxx
@@ -46,7 +46,6 @@ CopyFromClipContext::CopyFromClipContext(ScDocument& rDoc,
     mnInsertFlag(nInsertFlag), mnDeleteFlag(InsertDeleteFlags::NONE),
     mpCondFormatList(nullptr),
     mbAsLink(bAsLink), mbSkipEmptyCells(bSkipEmptyCells),
-    mbCloneNotes (mnInsertFlag & 
(InsertDeleteFlags::NOTE|InsertDeleteFlags::ADDNOTES)),
     mbTableProtected(false)
 {
 }
@@ -120,6 +119,7 @@ void CopyFromClipContext::setSingleCellColumnSize( size_t 
nSize )
     maSingleCellAttrs.resize(nSize);
     maSinglePatterns.resize(nSize, nullptr);
     maSingleNotes.resize(nSize, nullptr);
+    maSingleSparkline.resize(nSize);
 }
 
 ScCellValue& CopyFromClipContext::getSingleCell( size_t nColOffset )
@@ -300,6 +300,18 @@ void CopyFromClipContext::setSingleCellNote( size_t 
nColOffset, const ScPostIt*
     maSingleNotes[nColOffset] = pNote;
 }
 
+std::shared_ptr<sc::Sparkline> const& 
CopyFromClipContext::getSingleSparkline(size_t nColOffset) const
+{
+    assert(nColOffset < maSingleSparkline.size());
+    return maSingleSparkline[nColOffset];
+}
+
+void CopyFromClipContext::setSingleSparkline(size_t nColOffset, 
std::shared_ptr<sc::Sparkline> const& pSparkline)
+{
+    assert(nColOffset < maSingleSparkline.size());
+    maSingleSparkline[nColOffset] = pSparkline;
+}
+
 void CopyFromClipContext::setCondFormatList( ScConditionalFormatList* 
pCondFormatList )
 {
     mpCondFormatList = pCondFormatList;
@@ -332,7 +344,12 @@ bool CopyFromClipContext::isSkipEmptyCells() const
 
 bool CopyFromClipContext::isCloneNotes() const
 {
-    return mbCloneNotes;
+    return bool(mnInsertFlag & (InsertDeleteFlags::NOTE | 
InsertDeleteFlags::ADDNOTES));
+}
+
+bool CopyFromClipContext::isCloneSparklines() const
+{
+    return bool(mnInsertFlag & InsertDeleteFlags::SPARKLINES);
 }
 
 bool CopyFromClipContext::isDateCell( const ScColumn& rCol, SCROW nRow ) const
diff --git a/sc/source/core/data/column.cxx b/sc/source/core/data/column.cxx
index b66638336a11..12bfca27adcf 100644
--- a/sc/source/core/data/column.cxx
+++ b/sc/source/core/data/column.cxx
@@ -1019,6 +1019,7 @@ public:
             setDefaultAttrsToDest(nTopRow, nDataSize);
 
         mrSrcCol.DuplicateNotes(nTopRow, nDataSize, mrDestCol, maDestPos, 
false);
+        mrSrcCol.DuplicateSparklines(nTopRow, nDataSize, mrDestCol, maDestPos);
     }
 };
 
diff --git a/sc/source/core/data/column2.cxx b/sc/source/core/data/column2.cxx
index c7e2dd5d8006..24702e11d5a3 100644
--- a/sc/source/core/data/column2.cxx
+++ b/sc/source/core/data/column2.cxx
@@ -42,6 +42,7 @@
 #include <rowheightcontext.hxx>
 #include <tokenstringcontext.hxx>
 #include <sortparam.hxx>
+#include <SparklineGroup.hxx>
 
 #include <editeng/eeitem.hxx>
 #include <o3tl/safeint.hxx>
@@ -2005,6 +2006,82 @@ bool ScColumn::DeleteSparkline(SCROW nRow)
     return true;
 }
 
+bool ScColumn::IsSparklinesEmptyBlock(SCROW nStartRow, SCROW nEndRow) const
+{
+    std::pair<sc::SparklineStoreType::const_iterator,size_t> aPos = 
maSparklines.position(nStartRow);
+    sc::SparklineStoreType::const_iterator it = aPos.first;
+    if (it == maSparklines.end())
+        return false;
+
+    if (it->type != sc::element_type_empty)
+        return false;
+
+    // start position of next block which is not empty.
+    SCROW nNextRow = nStartRow + it->size - aPos.second;
+    return nEndRow < nNextRow;
+}
+
+namespace
+{
+
+class CopySparklinesHandler
+{
+    ScColumn& mrDestCol;
+    sc::SparklineStoreType& mrDestSparkline;
+    sc::SparklineStoreType::iterator miDestPosition;
+    SCTAB mnSrcTab;
+    SCCOL mnSrcCol;
+    SCTAB mnDestTab;
+    SCCOL mnDestCol;
+    SCROW mnDestOffset;
+
+public:
+    CopySparklinesHandler(const ScColumn& rSrcCol, ScColumn& rDestCol, SCROW 
nDestOffset)
+        : mrDestCol(rDestCol)
+        , mrDestSparkline(mrDestCol.GetSparklineStore())
+        , miDestPosition(mrDestSparkline.begin())
+        , mnSrcTab(rSrcCol.GetTab())
+        , mnSrcCol(rSrcCol.GetCol())
+        , mnDestTab(rDestCol.GetTab())
+        , mnDestCol(rDestCol.GetCol())
+        , mnDestOffset(nDestOffset)
+    {}
+
+    void operator() (size_t nRow, const sc::SparklineCell* pCell)
+    {
+        SCROW nDestRow = nRow + mnDestOffset;
+
+        auto const& pSparkline = pCell->getSparkline();
+        auto const& pGroup = pCell->getSparklineGroup();
+
+        auto pNewSparklineGroup = 
std::make_shared<sc::SparklineGroup>(*pGroup); // Copy the group
+        auto pNewSparkline = std::make_shared<sc::Sparkline>(mnDestCol, 
nDestRow, pNewSparklineGroup);
+
+        pNewSparkline->setInputRange(pSparkline->getInputRange());
+
+        miDestPosition = mrDestSparkline.set(miDestPosition, nDestRow, new 
sc::SparklineCell(pNewSparkline));
+    }
+};
+
+}
+
+void ScColumn::CopyCellSparklinesToDocument(SCROW nRow1, SCROW nRow2, 
ScColumn& rDestCol, SCROW nRowOffsetDest) const
+{
+    if (IsSparklinesEmptyBlock(nRow1, nRow2))
+        // The column has no cell sparklines to copy between specified rows.
+        return;
+
+    CopySparklinesHandler aFunctor(*this, rDestCol, nRowOffsetDest);
+    sc::ParseSparkline(maSparklines.begin(), maSparklines, nRow1, nRow2, 
aFunctor);
+}
+
+void ScColumn::DuplicateSparklines(SCROW nStartRow, size_t nDataSize, 
ScColumn& rDestCol,
+                             sc::ColumnBlockPosition& rDestBlockPos, SCROW 
nRowOffsetDest) const
+{
+    CopyCellSparklinesToDocument(nStartRow, nStartRow + nDataSize - 1, 
rDestCol, nRowOffsetDest);
+    rDestBlockPos.miSparklinePos = rDestCol.maSparklines.begin();
+}
+
 // Notes
 
 ScPostIt* ScColumn::GetCellNote(SCROW nRow)
diff --git a/sc/source/core/data/column3.cxx b/sc/source/core/data/column3.cxx
index dc6a68420a6f..a4c1e7ff57af 100644
--- a/sc/source/core/data/column3.cxx
+++ b/sc/source/core/data/column3.cxx
@@ -1117,6 +1117,11 @@ class CopyCellsFromClipHandler
         mrSrcCol.DuplicateNotes(nStartRow, nDataSize, mrDestCol, 
maDestBlockPos, bCloneCaption, mnRowOffset);
     }
 
+    void duplicateSparklines(SCROW nStartRow, size_t nDataSize)
+    {
+        mrSrcCol.DuplicateSparklines(nStartRow, nDataSize, mrDestCol, 
maDestBlockPos, mnRowOffset);
+    }
+
 public:
     CopyCellsFromClipHandler(sc::CopyFromClipContext& rCxt, ScColumn& rSrcCol, 
ScColumn& rDestCol, SCTAB nDestTab, SCCOL nDestCol, tools::Long nRowOffset, 
svl::SharedStringPool* pSharedStringPool) :
         mrCxt(rCxt),
@@ -1156,6 +1161,7 @@ public:
     {
         SCROW nSrcRow1 = node.position + nOffset;
         bool bCopyCellNotes = mrCxt.isCloneNotes();
+        bool bCopySparklines = mrCxt.isCloneSparklines();
 
         InsertDeleteFlags nFlags = mrCxt.getInsertFlag();
 
@@ -1166,6 +1172,10 @@ public:
                 bool bCloneCaption = (nFlags & InsertDeleteFlags::NOCAPTIONS) 
== InsertDeleteFlags::NONE;
                 duplicateNotes(nSrcRow1, nDataSize, bCloneCaption );
             }
+            if (bCopySparklines) // If there is a sparkline is it empty?
+            {
+                duplicateSparklines(nSrcRow1, nDataSize);
+            }
             return;
         }
 
@@ -1356,6 +1366,10 @@ public:
             bool bCloneCaption = (nFlags & InsertDeleteFlags::NOCAPTIONS) == 
InsertDeleteFlags::NONE;
             duplicateNotes(nSrcRow1, nDataSize, bCloneCaption );
         }
+        if (bCopySparklines)
+        {
+            duplicateSparklines(nSrcRow1, nDataSize);
+        }
     }
 };
 
diff --git a/sc/source/core/data/column4.cxx b/sc/source/core/data/column4.cxx
index e9b7d1d189dc..334652d86987 100644
--- a/sc/source/core/data/column4.cxx
+++ b/sc/source/core/data/column4.cxx
@@ -30,6 +30,8 @@
 #include <compiler.hxx>
 #include <recursionhelper.hxx>
 
+#include <SparklineGroup.hxx>
+
 #include <o3tl/safeint.hxx>
 #include <svl/sharedstringpool.hxx>
 #include <sal/log.hxx>
@@ -120,6 +122,9 @@ void ScColumn::DeleteBeforeCopyFromClip(
         if (nDelFlag & InsertDeleteFlags::NOTE)
             DeleteCellNotes(*pBlockPos, aRange.mnRow1, aRange.mnRow2, false);
 
+        if (nDelFlag & InsertDeleteFlags::SPARKLINES)
+            DeleteSparklineCells(*pBlockPos, aRange.mnRow1, aRange.mnRow2);
+
         if (nDelFlag & InsertDeleteFlags::EDITATTR)
             RemoveEditAttribs(*pBlockPos, aRange.mnRow1, aRange.mnRow2);
 
@@ -208,6 +213,9 @@ void ScColumn::DeleteBeforeCopyFromClip(
         if (nDelFlag & InsertDeleteFlags::NOTE)
             DeleteCellNotes(*pBlockPos, nRow1, nRow2, false);
 
+        if (nDelFlag & InsertDeleteFlags::SPARKLINES)
+            DeleteSparklineCells(*pBlockPos, nRow1, nRow2);
+
         if (nDelFlag & InsertDeleteFlags::EDITATTR)
             RemoveEditAttribs(*pBlockPos, nRow1, nRow2);
 
@@ -325,6 +333,11 @@ void ScColumn::CopyOneCellFromClip( 
sc::CopyFromClipContext& rCxt, SCROW nRow1,
         }
     }
 
+    ScAddress aDestPosition(nCol, nRow1, nTab);
+
+    duplicateSparkline(rCxt, pBlockPos, nColOffset, nDestSize, aDestPosition);
+
+    // Notes
     const ScPostIt* pNote = rCxt.getSingleCellNote(nColOffset);
     if (!(pNote && (nFlags & (InsertDeleteFlags::NOTE | 
InsertDeleteFlags::ADDNOTES)) != InsertDeleteFlags::NONE))
         return;
@@ -334,13 +347,12 @@ void ScColumn::CopyOneCellFromClip( 
sc::CopyFromClipContext& rCxt, SCROW nRow1,
     ScDocument* pClipDoc = rCxt.getClipDoc();
     const ScAddress aSrcPos = pClipDoc->GetClipParam().getWholeRange().aStart;
     std::vector<ScPostIt*> aNotes;
-    ScAddress aDestPos(nCol, nRow1, nTab);
     aNotes.reserve(nDestSize);
     for (size_t i = 0; i < nDestSize; ++i)
     {
         bool bCloneCaption = (nFlags & InsertDeleteFlags::NOCAPTIONS) == 
InsertDeleteFlags::NONE;
-        aNotes.push_back(pNote->Clone(aSrcPos, rDocument, aDestPos, 
bCloneCaption).release());
-        aDestPos.IncRow();
+        aNotes.push_back(pNote->Clone(aSrcPos, rDocument, aDestPosition, 
bCloneCaption).release());
+        aDestPosition.IncRow();
     }
 
     pBlockPos->miCellNotePos =
@@ -348,6 +360,29 @@ void ScColumn::CopyOneCellFromClip( 
sc::CopyFromClipContext& rCxt, SCROW nRow1,
             pBlockPos->miCellNotePos, nRow1, aNotes.begin(), aNotes.end());
 }
 
+void ScColumn::duplicateSparkline(sc::CopyFromClipContext& rContext, 
sc::ColumnBlockPosition* pBlockPos,
+                                  size_t nColOffset, size_t nDestSize, 
ScAddress aDestPosition)
+{
+    if ((rContext.getInsertFlag() & InsertDeleteFlags::SPARKLINES) == 
InsertDeleteFlags::NONE)
+        return;
+
+    auto pSparkline = rContext.getSingleSparkline(nColOffset);
+    auto const& pSparklineGroup = pSparkline->getSparklineGroup();
+
+    std::vector<sc::SparklineCell*> aSparklines(nDestSize, nullptr);
+    ScAddress aCurrentPosition = aDestPosition;
+    for (size_t i = 0; i < nDestSize; ++i)
+    {
+        auto pNewSparklineGroup = 
std::make_shared<sc::SparklineGroup>(*pSparklineGroup);
+        auto pNewSparkline = 
std::make_shared<sc::Sparkline>(aCurrentPosition.Col(), aCurrentPosition.Row(), 
pNewSparklineGroup);
+        pNewSparkline->setInputRange(pSparkline->getInputRange());
+        aSparklines[i] = new sc::SparklineCell(pNewSparkline);
+        aCurrentPosition.IncRow();
+    }
+
+    pBlockPos->miSparklinePos = maSparklines.set(pBlockPos->miSparklinePos, 
aDestPosition.Row(), aSparklines.begin(), aSparklines.end());
+}
+
 void ScColumn::SetValues( const SCROW nRow, const std::vector<double>& rVals )
 {
     if (!GetDoc().ValidRow(nRow))
diff --git a/sc/source/core/data/document10.cxx 
b/sc/source/core/data/document10.cxx
index 2e839d80dba4..036e96bbc2fb 100644
--- a/sc/source/core/data/document10.cxx
+++ b/sc/source/core/data/document10.cxx
@@ -125,6 +125,9 @@ bool ScDocument::CopyOneCellFromClip(
         if ((rCxt.getInsertFlag() & (InsertDeleteFlags::NOTE | 
InsertDeleteFlags::ADDNOTES)) != InsertDeleteFlags::NONE)
             rCxt.setSingleCellNote(nColOffset, pClipDoc->GetNote(aSrcPos));
 
+        if ((rCxt.getInsertFlag() & InsertDeleteFlags::SPARKLINES) != 
InsertDeleteFlags::NONE)
+            rCxt.setSingleSparkline(nColOffset, 
pClipDoc->GetSparkline(aSrcPos));
+
         ScColumn* pSrcCol = pSrcTab->FetchColumn(aSrcPos.Col());
         assert(pSrcCol);
         // Determine the script type of the copied single cell.
diff --git a/sc/source/ui/inc/cliputil.hxx b/sc/source/ui/inc/cliputil.hxx
index 022b3586d241..e57f5281d922 100644
--- a/sc/source/ui/inc/cliputil.hxx
+++ b/sc/source/ui/inc/cliputil.hxx
@@ -10,6 +10,7 @@
 #pragma once
 
 #include <types.hxx>
+#include "scdllapi.h"
 
 class ScViewData;
 class ScTabViewShell;
@@ -19,9 +20,10 @@ class ScRangeList;
 
 namespace ScClipUtil
 {
-    void PasteFromClipboard( ScViewData& rViewData, ScTabViewShell* 
pTabViewShell, bool bShowDialog );
 
-    bool CheckDestRanges(
+SC_DLLPUBLIC void PasteFromClipboard( ScViewData& rViewData, ScTabViewShell* 
pTabViewShell, bool bShowDialog );
+
+bool CheckDestRanges(
         const ScDocument& rDoc, SCCOL nSrcCols, SCROW nSrcRows, const 
ScMarkData& rMark,
         const ScRangeList& rDest);
 }
commit 4032294a03dfa0432dae7ebcd392ce87f8dee680
Author:     Tomaž Vajngerl <tomaz.vajng...@collabora.co.uk>
AuthorDate: Sat Mar 19 10:56:27 2022 +0900
Commit:     Tomaž Vajngerl <tomaz.vajng...@collabora.co.uk>
CommitDate: Sat Mar 19 10:56:27 2022 +0900

    sc: change GetSparkline to return a shared_ptr instead of raw ptr
    
    Change-Id: If3d7b3ad4b96eb7d3b126ee8b130f8d5e684cd3c

diff --git a/sc/inc/document.hxx b/sc/inc/document.hxx
index c101612ab2dc..b5274c3533e0 100644
--- a/sc/inc/document.hxx
+++ b/sc/inc/document.hxx
@@ -1243,7 +1243,7 @@ public:
     sc::MultiDataCellState HasMultipleDataCells( const ScRange& rRange ) const;
 
     /** Spaklines */
-    SC_DLLPUBLIC sc::Sparkline* GetSparkline(ScAddress const & rPosition);
+    SC_DLLPUBLIC std::shared_ptr<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);
     SC_DLLPUBLIC bool DeleteSparkline(ScAddress const& rPosition);
diff --git a/sc/inc/table.hxx b/sc/inc/table.hxx
index 2393f8ace994..6c7053905f3a 100644
--- a/sc/inc/table.hxx
+++ b/sc/inc/table.hxx
@@ -475,7 +475,7 @@ public:
 
     // Sparklines
 
-    sc::Sparkline* GetSparkline(SCCOL nCol, SCROW nRow);
+    std::shared_ptr<sc::Sparkline> GetSparkline(SCCOL nCol, SCROW nRow);
     sc::Sparkline* CreateSparkline(SCCOL nCol, SCROW nRow, 
std::shared_ptr<sc::SparklineGroup> & pSparklineGroup);
     bool DeleteSparkline(SCCOL nCol, SCROW nRow);
 
diff --git a/sc/qa/unit/SparklineImportExportTest.cxx 
b/sc/qa/unit/SparklineImportExportTest.cxx
index 650a45b89c6f..cd0578e91418 100644
--- a/sc/qa/unit/SparklineImportExportTest.cxx
+++ b/sc/qa/unit/SparklineImportExportTest.cxx
@@ -57,7 +57,7 @@ void checkSparklines(ScDocument& rDocument)
 {
     // Sparkline at Sheet1:A2
     {
-        sc::Sparkline* pSparkline = rDocument.GetSparkline(ScAddress(0, 1, 
0)); // A2
+        auto pSparkline = rDocument.GetSparkline(ScAddress(0, 1, 0)); // A2
         CPPUNIT_ASSERT(pSparkline);
         auto pSparklineGroup = pSparkline->getSparklineGroup();
         CPPUNIT_ASSERT_EQUAL(sc::SparklineType::Line, 
pSparklineGroup->m_eType);
@@ -90,7 +90,7 @@ void checkSparklines(ScDocument& rDocument)
     }
     // Sparkline at Sheet1:A3
     {
-        sc::Sparkline* pSparkline = rDocument.GetSparkline(ScAddress(0, 2, 
0)); // A3
+        auto pSparkline = rDocument.GetSparkline(ScAddress(0, 2, 0)); // A3
         CPPUNIT_ASSERT(pSparkline);
         auto pSparklineGroup = pSparkline->getSparklineGroup();
         CPPUNIT_ASSERT_EQUAL(sc::SparklineType::Column, 
pSparklineGroup->m_eType);
@@ -123,28 +123,28 @@ void checkSparklines(ScDocument& rDocument)
     }
     // Sparkline at Sheet2:B1
     {
-        sc::Sparkline* pSparkline = rDocument.GetSparkline(ScAddress(1, 0, 
1)); //B1
+        auto 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
+        auto 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
+        auto 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
+        auto pSparkline = rDocument.GetSparkline(ScAddress(0, 3, 0)); //A4
         CPPUNIT_ASSERT(!pSparkline);
     }
 }
diff --git a/sc/source/core/data/document.cxx b/sc/source/core/data/document.cxx
index 03f468520a03..3a11c7a3d950 100644
--- a/sc/source/core/data/document.cxx
+++ b/sc/source/core/data/document.cxx
@@ -6506,7 +6506,7 @@ bool ScDocument::IsInVBAMode() const
 }
 
 // Sparklines
-sc::Sparkline* ScDocument::GetSparkline(ScAddress const& rPosition)
+std::shared_ptr<sc::Sparkline> ScDocument::GetSparkline(ScAddress const& 
rPosition)
 {
     SCTAB nTab = rPosition.Tab();
 
@@ -6514,7 +6514,7 @@ sc::Sparkline* ScDocument::GetSparkline(ScAddress const& 
rPosition)
     {
         return maTabs[nTab]->GetSparkline(rPosition.Col(), rPosition.Row());
     }
-    return nullptr;
+    return std::shared_ptr<sc::Sparkline>();
 }
 
 sc::Sparkline* ScDocument::CreateSparkline(ScAddress const & rPosition, 
std::shared_ptr<sc::SparklineGroup> & pSparklineGroup)
diff --git a/sc/source/core/data/table2.cxx b/sc/source/core/data/table2.cxx
index 88f9a4e8ee97..d92e651c03b6 100644
--- a/sc/source/core/data/table2.cxx
+++ b/sc/source/core/data/table2.cxx
@@ -1811,19 +1811,16 @@ ScFormulaCell* ScTable::GetFormulaCell( SCCOL nCol, 
SCROW nRow )
 
 // Sparklines
 
-sc::Sparkline* ScTable::GetSparkline(SCCOL nCol, SCROW nRow)
+std::shared_ptr<sc::Sparkline> ScTable::GetSparkline(SCCOL nCol, SCROW nRow)
 {
     if (!ValidCol(nCol) || nCol >= GetAllocatedColumnsCount())
-        return nullptr;
+        return std::shared_ptr<sc::Sparkline>();
 
     sc::SparklineCell* pSparklineCell = aCol[nCol].GetSparklineCell(nRow);
     if (!pSparklineCell)
-        return nullptr;
+        return std::shared_ptr<sc::Sparkline>();
 
-    std::shared_ptr<sc::Sparkline> pSparkline(pSparklineCell->getSparkline());
-    assert(pSparkline);
-
-    return pSparkline.get();
+    return pSparklineCell->getSparkline();
 }
 
 sc::Sparkline* ScTable::CreateSparkline(SCCOL nCol, SCROW nRow, 
std::shared_ptr<sc::SparklineGroup>& pSparklineGroup)
diff --git a/sc/source/ui/view/cellsh.cxx b/sc/source/ui/view/cellsh.cxx
index 72e4b3c74e1d..f1df448a1288 100644
--- a/sc/source/ui/view/cellsh.cxx
+++ b/sc/source/ui/view/cellsh.cxx
@@ -110,8 +110,8 @@ bool canShowDeleteSparkline(ScDocument& rDocument, ScRange 
const& rRange)
     {
         for (SCROW nY = rRange.aStart.Row(); nY <= rRange.aEnd.Row(); nY++)
         {
-            auto* pSparkline = rDocument.GetSparkline(ScAddress(nX, nY, nTab));
-            if (pSparkline == nullptr)
+            auto pSparkline = rDocument.GetSparkline(ScAddress(nX, nY, nTab));
+            if (!pSparkline)
             {
                 return false;
             }
diff --git a/sc/source/ui/view/output.cxx b/sc/source/ui/view/output.cxx
index 17903c3a23fd..a73989d848a8 100644
--- a/sc/source/ui/view/output.cxx
+++ b/sc/source/ui/view/output.cxx
@@ -2474,7 +2474,7 @@ void drawColumn(vcl::RenderContext& rRenderContext, 
tools::Rectangle const & rRe
     }
 }
 
-void drawSparkline(sc::Sparkline* pSparkline, vcl::RenderContext& 
rRenderContext, ScDocument* pDocument,
+void drawSparkline(std::shared_ptr<sc::Sparkline> const& pSparkline, 
vcl::RenderContext& rRenderContext, ScDocument* pDocument,
                                  tools::Rectangle const & rRectangle)
 {
     auto const & rRangeList = pSparkline->getInputRange();
@@ -2574,7 +2574,7 @@ void ScOutputData::DrawSparklines(vcl::RenderContext& 
rRenderContext)
                     mpDoc->ExtendOverlapped( nMergeX, nMergeY, nX, nY, nTab );
                 }
 
-                sc::Sparkline* pSparkline = nullptr;
+                std::shared_ptr<sc::Sparkline> pSparkline;
                 ScAddress aCurrentAddress(nX, pRowInfo[nArrY].nRowNo, nTab);
 
                 if (!mpDoc->ColHidden(nX, nTab) && (pSparkline = 
mpDoc->GetSparkline(aCurrentAddress))
commit bc4f48bd7e34fce2ab6c9338ce30c32c6ec7e716
Author:     Tomaž Vajngerl <tomaz.vajng...@collabora.co.uk>
AuthorDate: Sat Mar 19 10:39:20 2022 +0900
Commit:     Tomaž Vajngerl <tomaz.vajng...@collabora.co.uk>
CommitDate: Sat Mar 19 10:39:20 2022 +0900

    sc: make getters const in SparklineCell and Sparkline classes
    
    Change-Id: Ia0bc1d4bd7da834da3640f34bfdb744dd2ddeba2

diff --git a/sc/inc/Sparkline.hxx b/sc/inc/Sparkline.hxx
index 7b7785f3169a..5cc079f8530e 100644
--- a/sc/inc/Sparkline.hxx
+++ b/sc/inc/Sparkline.hxx
@@ -39,13 +39,13 @@ public:
 
     void setInputRange(ScRangeList const& rInputRange) { m_aInputRange = 
rInputRange; }
 
-    ScRangeList const& getInputRange() { return m_aInputRange; }
+    ScRangeList const& getInputRange() const { return m_aInputRange; }
 
-    std::shared_ptr<SparklineGroup> const& getSparklineGroup() { return 
m_pSparklineGroup; }
+    std::shared_ptr<SparklineGroup> const& getSparklineGroup() const { return 
m_pSparklineGroup; }
 
-    SCCOL getColumn() { return m_nColumn; }
+    SCCOL getColumn() const { return m_nColumn; }
 
-    SCROW getRow() { return m_nRow; }
+    SCROW getRow() const { return m_nRow; }
 };
 
 class SC_DLLPUBLIC SparklineList
diff --git a/sc/inc/SparklineCell.hxx b/sc/inc/SparklineCell.hxx
index 0aca857170c9..0588646866c4 100644
--- a/sc/inc/SparklineCell.hxx
+++ b/sc/inc/SparklineCell.hxx
@@ -34,12 +34,12 @@ public:
 
     ScRangeList const& getInputRange() { return m_pSparkline->getInputRange(); 
}
 
-    std::shared_ptr<SparklineGroup> const& getSparklineGroup()
+    std::shared_ptr<SparklineGroup> const& getSparklineGroup() const
     {
         return m_pSparkline->getSparklineGroup();
     }
 
-    std::shared_ptr<Sparkline> const& getSparkline() { return m_pSparkline; }
+    std::shared_ptr<Sparkline> const& getSparkline() const { return 
m_pSparkline; }
 };
 
 } // end sc

Reply via email to