sc/inc/colorscale.hxx              |    2 +
 sc/qa/unit/ucalc_condformat.cxx    |   50 +++++++++++++++++++++++++++++++++++++
 sc/source/core/data/colorscale.cxx |   18 +++++++++++++
 3 files changed, 70 insertions(+)

New commits:
commit 3fa15dd614bd72ddb36dbe033abeef5609d31f38
Author:     Tibor Nagy <nagy.tib...@nisz.hu>
AuthorDate: Mon Apr 24 09:08:14 2023 +0200
Commit:     Nagy Tibor <nagy.tib...@nisz.hu>
CommitDate: Wed Apr 26 11:39:44 2023 +0200

    tdf#154906 tdf#129813 tdf#129814 sc: fix conditional format color scale
    
    This is a follow up to commit 3f614f431475e1bf3bb3bbeac59b0681309628b7
    (tdf#95295: don't add duplicate conditional formats)
    The above commit clearly describes how this fix works.
    
    Change-Id: I064fb3fe0443705553c6bbfcc34f2d717e0f6bd6
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/150899
    Tested-by: Jenkins
    Tested-by: László Németh <nem...@numbertext.org>
    Reviewed-by: László Németh <nem...@numbertext.org>

diff --git a/sc/inc/colorscale.hxx b/sc/inc/colorscale.hxx
index de74030dbc85..513eb11cf2f4 100644
--- a/sc/inc/colorscale.hxx
+++ b/sc/inc/colorscale.hxx
@@ -270,6 +270,8 @@ public:
     std::optional<Color> GetColor(const ScAddress& rAddr) const;
     void AddEntry(ScColorScaleEntry* pEntry);
 
+    bool IsEqual(const ScFormatEntry& r, bool bIgnoreSrcPos) const override;
+
     virtual void UpdateReference( sc::RefUpdateContext& rCxt ) override;
     virtual void UpdateInsertTab( sc::RefUpdateInsertTabContext& rCxt ) 
override;
     virtual void UpdateDeleteTab( sc::RefUpdateDeleteTabContext& rCxt ) 
override;
diff --git a/sc/qa/unit/ucalc_condformat.cxx b/sc/qa/unit/ucalc_condformat.cxx
index 811cd0d540d8..bfece1515a89 100644
--- a/sc/qa/unit/ucalc_condformat.cxx
+++ b/sc/qa/unit/ucalc_condformat.cxx
@@ -268,6 +268,56 @@ CPPUNIT_TEST_FIXTURE(TestCondformat, 
testCondFormatInsertDeleteSheets)
     m_pDoc->DeleteTab(0);
 }
 
+CPPUNIT_TEST_FIXTURE(TestCondformat, testColorScaleCondCopyPaste)
+{
+    m_pDoc->InsertTab(0, "Test");
+
+    auto pFormat = std::make_unique<ScConditionalFormat>(1, m_pDoc);
+    ScRange aCondFormatRange(0, 0, 0, 2, 0, 0);
+    ScRangeList aRangeList(aCondFormatRange);
+    pFormat->SetRange(aRangeList);
+
+    ScColorScaleFormat* pColorScaleFormat = new ScColorScaleFormat(m_pDoc);
+    ScColorScaleEntry* pEntryBlue = new ScColorScaleEntry(0, COL_BLUE);
+    ScColorScaleEntry* pEntryGreen = new ScColorScaleEntry(1, COL_GREEN);
+    ScColorScaleEntry* pEntryRed = new ScColorScaleEntry(2, COL_RED);
+    pColorScaleFormat->AddEntry(pEntryBlue);
+    pColorScaleFormat->AddEntry(pEntryGreen);
+    pColorScaleFormat->AddEntry(pEntryRed);
+
+    pFormat->AddEntry(pColorScaleFormat);
+    sal_uLong nIndex = m_pDoc->AddCondFormat(std::move(pFormat), 0);
+
+    ScDocument aClipDoc(SCDOCMODE_CLIP);
+    copyToClip(m_pDoc, aCondFormatRange, &aClipDoc);
+
+    ScRange aTargetRange(0, 3, 0, 2, 3, 0);
+    pasteFromClip(m_pDoc, aTargetRange, &aClipDoc);
+
+    // Pasting the same conditional format must modify existing format, making 
its range
+    // combined of previous range and newly pasted range having the 
conditional format.
+    // No new conditional formats must be created.
+    CPPUNIT_ASSERT_EQUAL(size_t(1), m_pDoc->GetCondFormList(0)->size());
+    aRangeList.Join(aTargetRange);
+    for (SCCOL nCol = 0; nCol < 3; ++nCol)
+    {
+        ScConditionalFormat* pPastedFormat = m_pDoc->GetCondFormat(nCol, 3, 0);
+        CPPUNIT_ASSERT(pPastedFormat);
+        CPPUNIT_ASSERT_EQUAL(aRangeList, pPastedFormat->GetRange());
+
+        sal_uLong nPastedKey = pPastedFormat->GetKey();
+        CPPUNIT_ASSERT_EQUAL(nIndex, nPastedKey);
+
+        const SfxPoolItem* pItem = m_pDoc->GetAttr(nCol, 3, 0, 
ATTR_CONDITIONAL);
+        const ScCondFormatItem* pCondFormatItem = static_cast<const 
ScCondFormatItem*>(pItem);
+        CPPUNIT_ASSERT(pCondFormatItem);
+        CPPUNIT_ASSERT_EQUAL(size_t(1), 
pCondFormatItem->GetCondFormatData().size());
+        CPPUNIT_ASSERT_EQUAL(sal_uInt32(nIndex), 
pCondFormatItem->GetCondFormatData().front());
+    }
+
+    m_pDoc->DeleteTab(0);
+}
+
 CPPUNIT_TEST_FIXTURE(TestCondformat, testCondCopyPaste)
 {
     m_pDoc->InsertTab(0, "Test");
diff --git a/sc/source/core/data/colorscale.cxx 
b/sc/source/core/data/colorscale.cxx
index 0a357828c61e..192dd1cea78c 100644
--- a/sc/source/core/data/colorscale.cxx
+++ b/sc/source/core/data/colorscale.cxx
@@ -404,6 +404,24 @@ void ScColorScaleFormat::AddEntry( ScColorScaleEntry* 
pEntry )
     maColorScales.back()->SetRepaintCallback(mpParent);
 }
 
+bool ScColorScaleFormat::IsEqual(const ScFormatEntry& rOther, bool 
/*bIgnoreSrcPos*/) const
+{
+    if (GetType() != rOther.GetType())
+        return false;
+
+    const ScColorScaleFormat& r = static_cast<const 
ScColorScaleFormat&>(rOther);
+
+    for (size_t i = 0; i < maColorScales.size(); ++i)
+    {
+        if 
(!maColorScales[i]->GetColor().IsRGBEqual(r.maColorScales[i]->GetColor().GetRGBColor())
+            || maColorScales[i]->GetType() != r.maColorScales[i]->GetType()
+            || maColorScales[i]->GetValue() != r.maColorScales[i]->GetValue())
+            return false;
+    }
+
+    return true;
+}
+
 double ScColorScaleFormat::GetMinValue() const
 {
     ScColorScaleEntries::const_iterator itr = maColorScales.begin();

Reply via email to