svx/source/inc/StylesPreviewWindow.hxx | 7 +--- svx/source/tbxctrls/StylesPreviewWindow.cxx | 44 +++++++++------------------- 2 files changed, 18 insertions(+), 33 deletions(-)
New commits: commit 89a16ae49307662dbce3d609b4e178e61a905528 Author: Noel Grandin <noel.gran...@collabora.co.uk> AuthorDate: Thu Aug 14 19:45:58 2025 +0200 Commit: Noel Grandin <noel.gran...@collabora.co.uk> CommitDate: Fri Aug 15 08:09:53 2025 +0200 tdf#167956 crash opening a second document with tabbed notebookbar Revert commit 7359e9c742d35c999eb9add524052887805e7b26 Author: Noel Grandin <noelgran...@gmail.com> Date: Wed Jun 11 12:35:14 2025 +0200 tdf#166932 avoid O(n^2) loop in UpdateStylesList Rather surprising that the original patch worked at all, because SwStyleSheetIterator is returning a dummy SfxStyleSheetBase, which is updated on every call to SwStyleSheetIterator::Next and then freed when SwStyleSheetIterator destructs. Change-Id: I310731e659b5b1bf74f15918371fdd16934d4c3f Reviewed-on: https://gerrit.libreoffice.org/c/core/+/189634 Tested-by: Jenkins Reviewed-by: Noel Grandin <noel.gran...@collabora.co.uk> diff --git a/svx/source/inc/StylesPreviewWindow.hxx b/svx/source/inc/StylesPreviewWindow.hxx index 5e737b19d09d..9c66c66bf57d 100644 --- a/svx/source/inc/StylesPreviewWindow.hxx +++ b/svx/source/inc/StylesPreviewWindow.hxx @@ -64,10 +64,10 @@ class StyleItemController public: StyleItemController(std::pair<OUString, OUString> aStyleName); - void Paint(vcl::RenderContext& rRenderContext, SfxStyleSheetBase* pStyleHint = nullptr); + void Paint(vcl::RenderContext& rRenderContext); private: - void DrawEntry(vcl::RenderContext& rRenderContext, SfxStyleSheetBase* pStyleHint); + void DrawEntry(vcl::RenderContext& rRenderContext); void DrawText(vcl::RenderContext& rRenderContext); void DrawHighlight(vcl::RenderContext& rRenderContext, Color aFontBack); static void DrawContentBackground(vcl::RenderContext& rRenderContext, @@ -123,8 +123,7 @@ public: void Select(const OUString& rStyleName); void RequestStylesListUpdate(); - static Bitmap GetCachedPreview(const std::pair<OUString, OUString>& rStyle, - SfxStyleSheetBase* pStyleHint = nullptr); + static Bitmap GetCachedPreview(const std::pair<OUString, OUString>& rStyle); static OString GetCachedPreviewJson(const std::pair<OUString, OUString>& rStyle); private: diff --git a/svx/source/tbxctrls/StylesPreviewWindow.cxx b/svx/source/tbxctrls/StylesPreviewWindow.cxx index 0905fdd44371..037f2c9c4f23 100644 --- a/svx/source/tbxctrls/StylesPreviewWindow.cxx +++ b/svx/source/tbxctrls/StylesPreviewWindow.cxx @@ -180,12 +180,12 @@ StyleItemController::StyleItemController(std::pair<OUString, OUString> aStyleNam { } -void StyleItemController::Paint(vcl::RenderContext& rRenderContext, SfxStyleSheetBase* pStyleHint) +void StyleItemController::Paint(vcl::RenderContext& rRenderContext) { rRenderContext.Push(vcl::PushFlags::FILLCOLOR | vcl::PushFlags::FONT | vcl::PushFlags::TEXTCOLOR); - DrawEntry(rRenderContext, pStyleHint); + DrawEntry(rRenderContext); rRenderContext.Pop(); } @@ -304,29 +304,25 @@ static SvxFont GetFontFromItems(const SvxFontItem* pFontItem, Size aPixelFontSiz return aFont; } -void StyleItemController::DrawEntry(vcl::RenderContext& rRenderContext, - SfxStyleSheetBase* pStyleHint) +void StyleItemController::DrawEntry(vcl::RenderContext& rRenderContext) { SfxObjectShell* pShell = SfxObjectShell::Current(); if (!pShell) return; SfxStyleSheetBasePool* pPool = pShell->GetStyleSheetPool(); + SfxStyleSheetBase* pStyle = nullptr; + if (!pPool) return; - SfxStyleSheetBase* pStyle = nullptr; - if (pStyleHint) - pStyle = pStyleHint; - else - { - pStyle = pPool->First(m_eStyleFamily); - while (pStyle && pStyle->GetName() != m_aStyleName.first - && pStyle->GetName() != m_aStyleName.second) - pStyle = pPool->Next(); - if (!pStyle) - return; - } + pStyle = pPool->First(m_eStyleFamily); + while (pStyle && pStyle->GetName() != m_aStyleName.first + && pStyle->GetName() != m_aStyleName.second) + pStyle = pPool->Next(); + + if (!pStyle) + return; Size aSize(rRenderContext.GetOutputSizePixel()); tools::Rectangle aFullRect(Point(0, 0), aSize); @@ -581,8 +577,7 @@ IMPL_LINK(StylesPreviewWindow_Base, GetPreviewImage, const weld::encoded_image_q return true; } -Bitmap StylesPreviewWindow_Base::GetCachedPreview(const std::pair<OUString, OUString>& rStyle, - SfxStyleSheetBase* pStyleHint) +Bitmap StylesPreviewWindow_Base::GetCachedPreview(const std::pair<OUString, OUString>& rStyle) { auto aFound = StylePreviewCache::Get().find(rStyle.second); if (aFound != StylePreviewCache::Get().end()) @@ -594,7 +589,7 @@ Bitmap StylesPreviewWindow_Base::GetCachedPreview(const std::pair<OUString, OUSt pImg->SetOutputSizePixel(aSize); StyleItemController aStyleController(rStyle); - aStyleController.Paint(*pImg, pStyleHint); + aStyleController.Paint(*pImg); Bitmap aBitmap(pImg->GetBitmap(Point(0, 0), aSize)); StylePreviewCache::Get()[rStyle.second] = aBitmap; @@ -620,8 +615,6 @@ void StylesPreviewWindow_Base::UpdateStylesList() SfxObjectShell* pDocShell = SfxObjectShell::Current(); SfxStyleSheetBasePool* pStyleSheetPool = nullptr; - // avoid O(n^2) loop when filling a very large style list - std::map<sal_Int32, SfxStyleSheetBase*> aStylesHint; if (pDocShell) pStyleSheetPool = pDocShell->GetStyleSheetPool(); @@ -636,7 +629,6 @@ void StylesPreviewWindow_Base::UpdateStylesList() while (pStyle) { OUString sName(pStyle->GetName()); - aStylesHint[m_aAllStyles.size()] = pStyle; m_aAllStyles.push_back(std::pair<OUString, OUString>(sName, sName)); pStyle = xIter->Next(); } @@ -647,21 +639,15 @@ void StylesPreviewWindow_Base::UpdateStylesList() // for online we can skip inserting the preview into the IconView and rely // on DoJsonProperty to provide the image to clients const bool bNeedInsertPreview = !comphelper::LibreOfficeKit::isActive(); - sal_Int32 nIndex = 0; for (const auto& rStyle : m_aAllStyles) { if (bNeedInsertPreview) { - SfxStyleSheetBase* pStyleHint = nullptr; - auto it = aStylesHint.find(nIndex); - if (it != aStylesHint.end()) - pStyleHint = it->second; - Bitmap aPreview = GetCachedPreview(rStyle, pStyleHint); + Bitmap aPreview = GetCachedPreview(rStyle); m_xStylesView->append(rStyle.first, rStyle.second, &aPreview); } else m_xStylesView->append(rStyle.first, rStyle.second, nullptr); - ++nIndex; } m_xStylesView->thaw(); }