sc/qa/unit/cond_format.cxx | 14 ++++++++++++++ sc/qa/unit/data/xlsx/tdf169379.xlsx |binary sc/qa/unit/subsequent_export_test4.cxx | 5 +++-- sc/source/filter/oox/condformatbuffer.cxx | 17 +++++++++++++---- 4 files changed, 30 insertions(+), 6 deletions(-)
New commits: commit 204d7655010199bb1c70ce7dee5428f2f02d4808 Author: Noel Grandin <[email protected]> AuthorDate: Fri Nov 14 10:52:50 2025 +0200 Commit: Noel Grandin <[email protected]> CommitDate: Fri Nov 14 12:18:39 2025 +0100 tdf#169379 Conditional formats collapsed We were combining conditional formats that the user wanted kept separate. This is a regression from commit e2cc1f8a6bd27907800416a5396942a0c7ca56ce Author: Noel Grandin <[email protected]> Date: Fri Feb 28 10:51:44 2025 +0200 tdf#134864 speedup load of pathological conditional formats in XLS We lose some performance by doing less deduplication, but luckily not too much, the pathological document from tdf#134864 loads in about twice the time now. (but still much much faster than before the optimisation) Change-Id: Id8c5741ad69bec7ca43f1b0fb53022bc617fffdd Reviewed-on: https://gerrit.libreoffice.org/c/core/+/194009 Reviewed-by: Noel Grandin <[email protected]> Tested-by: Jenkins diff --git a/sc/qa/unit/cond_format.cxx b/sc/qa/unit/cond_format.cxx index b8effde2664a..44d5b11ae782 100644 --- a/sc/qa/unit/cond_format.cxx +++ b/sc/qa/unit/cond_format.cxx @@ -1166,4 +1166,18 @@ CPPUNIT_TEST_FIXTURE(CondFormatTest, testTdf79998) CPPUNIT_ASSERT_EQUAL(u"Utilities (FX Kurse, Kreditkart"_ustr, aTabNames2[1]); } +// Test that we do not deduplicate conditional formats more than we should. +CPPUNIT_TEST_FIXTURE(CondFormatTest, tdf169379) +{ + // previously, we were combining all of these into one conditional format. + createScDoc("xlsx/tdf169379.xlsx"); + ScDocument* pDoc = getScDoc(); + ScConditionalFormat* pFormat = pDoc->GetCondFormat(0, 0, 0); // first column + CPPUNIT_ASSERT_EQUAL(sal_uInt32(3), pFormat->GetKey()); + pFormat = pDoc->GetCondFormat(1, 0, 0); // second column + CPPUNIT_ASSERT_EQUAL(sal_uInt32(2), pFormat->GetKey()); + pFormat = pDoc->GetCondFormat(2, 0, 0); // third column + CPPUNIT_ASSERT_EQUAL(sal_uInt32(1), pFormat->GetKey()); +} + CPPUNIT_PLUGIN_IMPLEMENT(); diff --git a/sc/qa/unit/data/xlsx/tdf169379.xlsx b/sc/qa/unit/data/xlsx/tdf169379.xlsx new file mode 100644 index 000000000000..0fb819b83d7a Binary files /dev/null and b/sc/qa/unit/data/xlsx/tdf169379.xlsx differ diff --git a/sc/qa/unit/subsequent_export_test4.cxx b/sc/qa/unit/subsequent_export_test4.cxx index d9a6ab69945b..6d71550692b6 100644 --- a/sc/qa/unit/subsequent_export_test4.cxx +++ b/sc/qa/unit/subsequent_export_test4.cxx @@ -1513,10 +1513,11 @@ CPPUNIT_TEST_FIXTURE(ScExportTest4, testTdf148820) xmlDocUniquePtr pSheet = parseExport(u"xl/worksheets/sheet1.xml"_ustr); CPPUNIT_ASSERT(pSheet); - CPPUNIT_ASSERT_EQUAL(u"5"_ustr, + CPPUNIT_ASSERT_EQUAL(u"20"_ustr, getXPathContent(pSheet, "count(/x:worksheet/x:conditionalFormatting)")); CPPUNIT_ASSERT_EQUAL( - u"5"_ustr, getXPathContent(pSheet, "count(/x:worksheet/x:conditionalFormatting/x:cfRule)")); + u"20"_ustr, + getXPathContent(pSheet, "count(/x:worksheet/x:conditionalFormatting/x:cfRule)")); sal_Int32 nDxfIdCondFormatFirst = getXPath(pSheet, "/x:worksheet/x:conditionalFormatting[1]/x:cfRule", "dxfId").toInt32() + 1; diff --git a/sc/source/filter/oox/condformatbuffer.cxx b/sc/source/filter/oox/condformatbuffer.cxx index b4033f170652..20426cc4393f 100644 --- a/sc/source/filter/oox/condformatbuffer.cxx +++ b/sc/source/filter/oox/condformatbuffer.cxx @@ -1352,13 +1352,22 @@ private: static size_t hashCode(const CondFormat& r) { std::size_t seed(0); - // note that we deliberately skip the maRanges field, because, if necessary, we will merge - // new entries into that field. + o3tl::hash_combine(seed, hashCode(r.maModel.maRanges)); o3tl::hash_combine(seed, r.maModel.mbPivot); for (const auto & rPair : r.maRules) o3tl::hash_combine(seed, hashCode(*rPair.second)); return seed; } + static size_t hashCode(const ScRangeList& rRangeList) + { + std::size_t seed(0); + for (const ScRange & rRange : rRangeList) + { + o3tl::hash_combine(seed, rRange.aStart); + o3tl::hash_combine(seed, rRange.aEnd); + } + return seed; + } static size_t hashCode(const CondFormatRule& r) { std::size_t seed(0); @@ -1396,8 +1405,8 @@ struct CondFormatEquals { if (lhs.get() == rhs.get()) return true; - // note that we deliberately skip the maRanges field, because, if necessary, we will merge - // new entries into that field. + if (lhs->maModel.maRanges != rhs->maModel.maRanges) + return false; if (lhs->maModel.mbPivot != rhs->maModel.mbPivot) return false; auto it1 = lhs->maRules.begin();
