sc/qa/unit/data/xlsx/tdf138601.xlsx       |binary
 sc/qa/unit/subsequent_filters_test.cxx    |   26 ++++++++++++++++++++++++++
 sc/source/filter/oox/condformatbuffer.cxx |   20 ++++++++++++++++++++
 3 files changed, 46 insertions(+)

New commits:
commit 90f4ea09cbe34e26e473ed2cf1c3457cf0f41e5e
Author:     Tibor Nagy <nagy.tib...@nisz.hu>
AuthorDate: Thu Feb 2 20:16:04 2023 +0100
Commit:     Xisco Fauli <xiscofa...@libreoffice.org>
CommitDate: Wed Feb 15 15:14:24 2023 +0000

    tdf#138601 XLSX import: fix priority of conditional formatting rules
    
    Multiple conditional formattings can intersect or have the same
    range of cell with different rules. Without sorting the rules
    by their priority, the cells got bad formatting, e.g. different
    colors than what was set in MSO.
    
    Change-Id: I619359877f1a3e55fc8f895d5ba6f0f4f30e07f2
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/146513
    Tested-by: Jenkins
    Tested-by: László Németh <nem...@numbertext.org>
    Reviewed-by: László Németh <nem...@numbertext.org>
    (cherry picked from commit 8c9a6abf30e9ff1ebd5647f7c271e0d64643860a)
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/147057
    Reviewed-by: Xisco Fauli <xiscofa...@libreoffice.org>

diff --git a/sc/qa/unit/data/xlsx/tdf138601.xlsx 
b/sc/qa/unit/data/xlsx/tdf138601.xlsx
new file mode 100644
index 000000000000..81107ee09c30
Binary files /dev/null and b/sc/qa/unit/data/xlsx/tdf138601.xlsx differ
diff --git a/sc/qa/unit/subsequent_filters_test.cxx 
b/sc/qa/unit/subsequent_filters_test.cxx
index fd0aa159467b..c080942d486d 100644
--- a/sc/qa/unit/subsequent_filters_test.cxx
+++ b/sc/qa/unit/subsequent_filters_test.cxx
@@ -78,6 +78,7 @@ public:
     ScFiltersTest();
 
     //ods, xls, xlsx filter tests
+    void testTdf138601_CondFormatXLSX();
     void testContentODS();
     void testContentXLS();
     void testContentXLSX();
@@ -209,6 +210,7 @@ public:
     void testForcepoint107();
 
     CPPUNIT_TEST_SUITE(ScFiltersTest);
+    CPPUNIT_TEST(testTdf138601_CondFormatXLSX);
     CPPUNIT_TEST(testContentODS);
     CPPUNIT_TEST(testContentXLS);
     CPPUNIT_TEST(testContentXLSX);
@@ -419,6 +421,30 @@ void testContentImpl(ScDocument& rDoc, bool 
bCheckMergedCells)
 }
 }
 
+void ScFiltersTest::testTdf138601_CondFormatXLSX()
+{
+    createScDoc("xlsx/tdf138601.xlsx");
+
+    ScDocument* pDoc = getScDoc();
+    ScConditionalFormat* pFormat1 = pDoc->GetCondFormat(0, 0, 0);
+    const ScFormatEntry* pEntry1 = pFormat1->GetEntry(0);
+    const ScColorScaleFormat* pColorScale1 = static_cast<const 
ScColorScaleFormat*>(pEntry1);
+    const ScColorScaleEntry* pColorScaleEntry1 = pColorScale1->GetEntry(0);
+    CPPUNIT_ASSERT_EQUAL(Color(255, 255, 201), pColorScaleEntry1->GetColor());
+
+    ScConditionalFormat* pFormat2 = pDoc->GetCondFormat(1, 0, 0);
+    const ScFormatEntry* pEntry2 = pFormat2->GetEntry(0);
+    const ScColorScaleFormat* pColorScale2 = static_cast<const 
ScColorScaleFormat*>(pEntry2);
+    const ScColorScaleEntry* pColorScaleEntry2 = pColorScale2->GetEntry(0);
+    CPPUNIT_ASSERT_EQUAL(Color(255, 139, 139), pColorScaleEntry2->GetColor());
+
+    ScConditionalFormat* pFormat3 = pDoc->GetCondFormat(0, 1, 0);
+    const ScFormatEntry* pEntry3 = pFormat3->GetEntry(0);
+    const ScColorScaleFormat* pColorScale3 = static_cast<const 
ScColorScaleFormat*>(pEntry3);
+    const ScColorScaleEntry* pColorScaleEntry3 = pColorScale3->GetEntry(0);
+    CPPUNIT_ASSERT_EQUAL(Color(255, 255, 201), pColorScaleEntry3->GetColor());
+}
+
 void ScFiltersTest::testContentODS()
 {
     createScDoc("ods/universal-content.ods");
diff --git a/sc/source/filter/oox/condformatbuffer.cxx 
b/sc/source/filter/oox/condformatbuffer.cxx
index 87b47456ab97..1abb3bf91938 100644
--- a/sc/source/filter/oox/condformatbuffer.cxx
+++ b/sc/source/filter/oox/condformatbuffer.cxx
@@ -1163,6 +1163,26 @@ void CondFormatBuffer::finalizeImport()
         ++nExtCFIndex;
     }
 
+    // tdf#138601 sort conditional formatting rules by their priority
+    if (maCondFormats.size() > 1)
+    {
+        size_t minIndex;
+        for (size_t i = 0; i < maCondFormats.size() - 1; ++i)
+        {
+            minIndex = i;
+            for (size_t j = i + 1; j < maCondFormats.size(); ++j)
+            {
+                if (maCondFormats[j]->maRules.begin()->first
+                    < maCondFormats[minIndex]->maRules.begin()->first)
+                {
+                    minIndex = j;
+                }
+            }
+            if (i != minIndex)
+                std::swap(maCondFormats[i], maCondFormats[minIndex]);
+        }
+    }
+
     for( const auto& rxCondFormat : maCondFormats )
     {
         if ( rxCondFormat)

Reply via email to