sc/inc/patattr.hxx | 1 + sc/inc/stlpool.hxx | 3 +++ sc/source/core/data/patattr.cxx | 27 +++++++++++++++++++++++++++ sc/source/core/data/stlpool.cxx | 11 +++++++++++ sc/source/filter/ftools/ftools.cxx | 2 +- 5 files changed, 43 insertions(+), 1 deletion(-)
New commits: commit 3ebb9ec474c47f3173bb19c4c6936a224893b22a Author: Caolán McNamara <caolan.mcnam...@collabora.com> AuthorDate: Mon Mar 10 14:45:22 2025 +0000 Commit: Caolán McNamara <caolan.mcnam...@collabora.com> CommitDate: Tue Mar 11 10:05:57 2025 +0100 crashtesting: crash on reimport of xlsx output of forum-pl-2758.ods also seen as a leak as nothing is erased by: maRegisteredCellAttributes.erase(&rCandidate); once the style names are changed and the std::set isn't ordered according to its predicate anymore. Easiest thing to do here seems to run the rename of a cell style through CellAttributeHelper so it can reinsert the affected ScPatternAttrs Change-Id: I13486701f378228792baa2b378709b7d530c3770 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/182744 Reviewed-by: Caolán McNamara <caolan.mcnam...@collabora.com> Tested-by: Jenkins Reviewed-by: Noel Grandin <noel.gran...@collabora.co.uk> diff --git a/sc/inc/patattr.hxx b/sc/inc/patattr.hxx index 67d2b9f2d9b3..8218bca676cb 100644 --- a/sc/inc/patattr.hxx +++ b/sc/inc/patattr.hxx @@ -92,6 +92,7 @@ public: void CellStyleDeleted(const ScStyleSheet& rStyle); void CellStyleCreated(ScDocument& rDoc, const OUString& rName); + void RenameCellStyle(ScStyleSheet& rStyle, const OUString& rNewName); void UpdateAllStyleSheets(ScDocument& rDoc); void AllStylesToNames(); void ReIndexRegistered(); diff --git a/sc/inc/stlpool.hxx b/sc/inc/stlpool.hxx index 206ec79dc507..6d62affe7b71 100644 --- a/sc/inc/stlpool.hxx +++ b/sc/inc/stlpool.hxx @@ -56,6 +56,9 @@ public: // Finds Para style with given name case-insensitively, or STR_STYLENAME_STANDARD ScStyleSheet* FindAutoStyle(const OUString& rName); + // Rename rStyle to rNewName, and update CellAttribute holder + SC_DLLPUBLIC void Rename(SfxStyleSheetBase& rStyle, const OUString& rNewName, SfxStyleFamily eFam); + SC_DLLPUBLIC virtual SfxStyleSheetBase& Make( const OUString&, SfxStyleFamily eFam, SfxStyleSearchBits nMask = SfxStyleSearchBits::All, const OUString& rParentStyleSheetName = u""_ustr) override; diff --git a/sc/source/core/data/patattr.cxx b/sc/source/core/data/patattr.cxx index 6f69739ed491..ae482de0becd 100644 --- a/sc/source/core/data/patattr.cxx +++ b/sc/source/core/data/patattr.cxx @@ -196,6 +196,33 @@ void CellAttributeHelper::CellStyleDeleted(const ScStyleSheet& rStyle) } } +void CellAttributeHelper::RenameCellStyle(ScStyleSheet& rStyle, const OUString& rNewName) +{ + std::vector<const ScPatternAttr*> aChanged; + + const OUString& rCandidateStyleName = rStyle.GetName(); + auto it = maRegisteredCellAttributes.lower_bound(&rCandidateStyleName); + while(it != maRegisteredCellAttributes.end()) + { + const ScPatternAttr* pCheck = *it; + if (CompareStringPtr(pCheck->GetStyleName(), &rCandidateStyleName) != 0) + break; + if (&rStyle == pCheck->GetStyleSheet()) + { + aChanged.push_back(pCheck); + // The name will change, we have to re-insert it + it = maRegisteredCellAttributes.erase(it); + } + else + ++it; + } + + rStyle.SetName(rNewName); + + for (const ScPatternAttr* p : aChanged) + maRegisteredCellAttributes.insert(p); +} + void CellAttributeHelper::CellStyleCreated(ScDocument& rDoc, const OUString& rName) { // If a style was created, don't keep any pattern with its name string in the pool, diff --git a/sc/source/core/data/stlpool.cxx b/sc/source/core/data/stlpool.cxx index aa4ae40dae1d..78a2a1339a63 100644 --- a/sc/source/core/data/stlpool.cxx +++ b/sc/source/core/data/stlpool.cxx @@ -114,6 +114,17 @@ rtl::Reference<SfxStyleSheetBase> ScStyleSheetPool::Create( const SfxStyleSheetB return new ScStyleSheet( static_cast<const ScStyleSheet&>(rStyle) ); } +void ScStyleSheetPool::Rename(SfxStyleSheetBase& rStyle, const OUString& rNewName, SfxStyleFamily eFamily) +{ + if (eFamily == SfxStyleFamily::Para) + { + assert(nullptr != pDoc); + pDoc->getCellAttributeHelper().RenameCellStyle(static_cast<ScStyleSheet&>(rStyle), rNewName); + return; + } + rStyle.SetName(rNewName); +} + void ScStyleSheetPool::Remove( SfxStyleSheetBase* pStyle ) { if ( pStyle ) diff --git a/sc/source/filter/ftools/ftools.cxx b/sc/source/filter/ftools/ftools.cxx index d3145e537429..3e8259339103 100644 --- a/sc/source/filter/ftools/ftools.cxx +++ b/sc/source/filter/ftools/ftools.cxx @@ -231,7 +231,7 @@ ScStyleSheet& lclMakeStyleSheet( ScStyleSheetPool& rPool, const OUString& rStyle // rename existing style if( pOldStyleSheet && bForceName ) { - pOldStyleSheet->SetName( aNewName ); + rPool.Rename(*pOldStyleSheet, aNewName, eFamily); aNewName = rStyleName; }