compilerplugins/clang/badstatics.cxx | 1 svx/source/inc/StylesPreviewWindow.hxx | 1 svx/source/tbxctrls/StylesPreviewWindow.cxx | 66 +++++++++++++++++++++++++--- 3 files changed, 61 insertions(+), 7 deletions(-)
New commits: commit d8b834a750a284ecd04cac1f4de4cb9cbf05c42c Author: Szymon Kłos <[email protected]> AuthorDate: Fri Jun 2 18:31:55 2023 +0200 Commit: Caolán McNamara <[email protected]> CommitDate: Sat Jun 3 17:44:01 2023 +0200 Styles preview cache cleanup on exit Change-Id: I28929d4137008ebcca1733837d0b2112b6859a89 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/152563 Reviewed-by: Caolán McNamara <[email protected]> Tested-by: Jenkins CollaboraOffice <[email protected]> Reviewed-by: Szymon Kłos <[email protected]> Reviewed-on: https://gerrit.libreoffice.org/c/core/+/152576 Tested-by: Jenkins diff --git a/compilerplugins/clang/badstatics.cxx b/compilerplugins/clang/badstatics.cxx index 7c604bc5ee66..f22dabac9b48 100644 --- a/compilerplugins/clang/badstatics.cxx +++ b/compilerplugins/clang/badstatics.cxx @@ -199,9 +199,8 @@ public: || name == "g_aWindowList" //vcl/unx/gtk3/a11y/atkutil.cxx, asserted empty at exit || name == "gFontPreviewVirDevs" - || (loplugin::DeclCheck(pVarDecl).Var("aPreviewCache") - .Class("StylesPreviewWindow_Base").GlobalNamespace()) // TODO: temp disable //svtools/source/control/ctrlbox.cxx, empty at exit + || name == "gStylePreviewCache" // svx/source/tbxctrls/StylesPreviewWindow.cxx || name == "aLogger" // FormulaLogger& FormulaLogger::get() in sc/source/core/tool/formulalogger.cxx || name == "s_aUncommittedRegistrations" // sw/source/uibase/dbui/dbmgr.cxx || (loplugin::DeclCheck(pVarDecl).Var("aAllListeners") diff --git a/svx/source/inc/StylesPreviewWindow.hxx b/svx/source/inc/StylesPreviewWindow.hxx index 47e21dcb4ca0..de4984e35968 100644 --- a/svx/source/inc/StylesPreviewWindow.hxx +++ b/svx/source/inc/StylesPreviewWindow.hxx @@ -127,8 +127,6 @@ private: void UpdateStylesList(); void UpdateSelection(); bool Command(const CommandEvent& rEvent); - - static std::map<OUString, VclPtr<VirtualDevice>> aPreviewCache; }; class StylesPreviewWindow_Impl final : public InterimItemWindow, public StylesPreviewWindow_Base diff --git a/svx/source/tbxctrls/StylesPreviewWindow.cxx b/svx/source/tbxctrls/StylesPreviewWindow.cxx index c1e3549fb54a..a51283d0d750 100644 --- a/svx/source/tbxctrls/StylesPreviewWindow.cxx +++ b/svx/source/tbxctrls/StylesPreviewWindow.cxx @@ -60,7 +60,36 @@ #include <vcl/commandevent.hxx> -std::map<OUString, VclPtr<VirtualDevice>> StylesPreviewWindow_Base::aPreviewCache; +namespace +{ +class StylePreviewCache +{ + static std::map<OUString, VclPtr<VirtualDevice>> gStylePreviewCache; + static int gStylePreviewCacheClients; + +public: + static std::map<OUString, VclPtr<VirtualDevice>>& Get() { return gStylePreviewCache; } + + static void ClearCache() + { + for (auto& aPreview : gStylePreviewCache) + aPreview.second.disposeAndClear(); + + gStylePreviewCache.clear(); + } + + static void RegisterClient() { gStylePreviewCacheClients++; } + static void UnregisterClient() + { + gStylePreviewCacheClients--; + if (!gStylePreviewCacheClients) + ClearCache(); + } +}; + +std::map<OUString, VclPtr<VirtualDevice>> StylePreviewCache::gStylePreviewCache; +int StylePreviewCache::gStylePreviewCacheClients; +} StyleStatusListener::StyleStatusListener( StylesPreviewWindow_Base* pPreviewControl, @@ -103,8 +132,10 @@ StylePoolChangeListener::~StylePoolChangeListener() EndListening(*m_pStyleSheetPool); } -void StylePoolChangeListener::Notify(SfxBroadcaster& /*rBC*/, const SfxHint& /*rHint*/) +void StylePoolChangeListener::Notify(SfxBroadcaster& /*rBC*/, const SfxHint& rHint) { + if (rHint.GetId() == SfxHintId::StyleSheetModified) + StylePreviewCache::ClearCache(); m_pPreviewControl->RequestStylesListUpdate(); } @@ -378,6 +409,8 @@ StylesPreviewWindow_Base::StylesPreviewWindow_Base( , m_aUpdateTask(*this) , m_aDefaultStyles(std::move(aDefaultStyles)) { + StylePreviewCache::RegisterClient(); + m_xStylesView->connect_selection_changed(LINK(this, StylesPreviewWindow_Base, Selected)); m_xStylesView->connect_item_activated(LINK(this, StylesPreviewWindow_Base, DoubleClick)); m_xStylesView->connect_command(LINK(this, StylesPreviewWindow_Base, DoCommand)); @@ -424,6 +457,8 @@ StylesPreviewWindow_Base::~StylesPreviewWindow_Base() m_aUpdateTask.Stop(); + StylePreviewCache::UnregisterClient(); + try { m_xStatusListener->dispose(); @@ -465,8 +500,9 @@ void StylesListUpdateTask::Invoke() VclPtr<VirtualDevice> StylesPreviewWindow_Base::GetCachedPreview(const std::pair<OUString, OUString>& rStyle) { - if (aPreviewCache.find(rStyle.second) != aPreviewCache.end()) - return aPreviewCache[rStyle.second]; + auto aFound = StylePreviewCache::Get().find(rStyle.second); + if (aFound != StylePreviewCache::Get().end()) + return StylePreviewCache::Get()[rStyle.second]; else { VclPtr<VirtualDevice> pImg = VclPtr<VirtualDevice>::Create(); @@ -475,7 +511,7 @@ StylesPreviewWindow_Base::GetCachedPreview(const std::pair<OUString, OUString>& StyleItemController aStyleController(rStyle); aStyleController.Paint(*pImg); - aPreviewCache[rStyle.second] = pImg; + StylePreviewCache::Get()[rStyle.second] = pImg; return pImg; } commit 5ad502af9cf3d49457082a12d36f8159b6c4ca11 Author: Szymon Kłos <[email protected]> AuthorDate: Fri Jun 2 14:07:03 2023 +0200 Commit: Caolán McNamara <[email protected]> CommitDate: Sat Jun 3 17:43:56 2023 +0200 Styles preview widget should cache images Change-Id: I3ee370e5d3ef4227681c4a973ac6f24f9aa241e1 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/152556 Tested-by: Caolán McNamara <[email protected]> Reviewed-by: Caolán McNamara <[email protected]> Reviewed-on: https://gerrit.libreoffice.org/c/core/+/152575 diff --git a/compilerplugins/clang/badstatics.cxx b/compilerplugins/clang/badstatics.cxx index 3b80278a2f4f..7c604bc5ee66 100644 --- a/compilerplugins/clang/badstatics.cxx +++ b/compilerplugins/clang/badstatics.cxx @@ -199,6 +199,8 @@ public: || name == "g_aWindowList" //vcl/unx/gtk3/a11y/atkutil.cxx, asserted empty at exit || name == "gFontPreviewVirDevs" + || (loplugin::DeclCheck(pVarDecl).Var("aPreviewCache") + .Class("StylesPreviewWindow_Base").GlobalNamespace()) // TODO: temp disable //svtools/source/control/ctrlbox.cxx, empty at exit || name == "aLogger" // FormulaLogger& FormulaLogger::get() in sc/source/core/tool/formulalogger.cxx || name == "s_aUncommittedRegistrations" // sw/source/uibase/dbui/dbmgr.cxx diff --git a/svx/source/inc/StylesPreviewWindow.hxx b/svx/source/inc/StylesPreviewWindow.hxx index 0295a0eeea7c..47e21dcb4ca0 100644 --- a/svx/source/inc/StylesPreviewWindow.hxx +++ b/svx/source/inc/StylesPreviewWindow.hxx @@ -121,11 +121,14 @@ public: void Select(const OUString& rStyleName); void RequestStylesListUpdate(); + static VclPtr<VirtualDevice> GetCachedPreview(const std::pair<OUString, OUString>& rStyle); private: void UpdateStylesList(); void UpdateSelection(); bool Command(const CommandEvent& rEvent); + + static std::map<OUString, VclPtr<VirtualDevice>> aPreviewCache; }; class StylesPreviewWindow_Impl final : public InterimItemWindow, public StylesPreviewWindow_Base diff --git a/svx/source/tbxctrls/StylesPreviewWindow.cxx b/svx/source/tbxctrls/StylesPreviewWindow.cxx index ff2f959d3406..c1e3549fb54a 100644 --- a/svx/source/tbxctrls/StylesPreviewWindow.cxx +++ b/svx/source/tbxctrls/StylesPreviewWindow.cxx @@ -60,6 +60,8 @@ #include <vcl/commandevent.hxx> +std::map<OUString, VclPtr<VirtualDevice>> StylesPreviewWindow_Base::aPreviewCache; + StyleStatusListener::StyleStatusListener( StylesPreviewWindow_Base* pPreviewControl, const css::uno::Reference<css::frame::XDispatchProvider>& xDispatchProvider) @@ -460,6 +462,25 @@ void StylesListUpdateTask::Invoke() m_rStylesList.UpdateSelection(); } +VclPtr<VirtualDevice> +StylesPreviewWindow_Base::GetCachedPreview(const std::pair<OUString, OUString>& rStyle) +{ + if (aPreviewCache.find(rStyle.second) != aPreviewCache.end()) + return aPreviewCache[rStyle.second]; + else + { + VclPtr<VirtualDevice> pImg = VclPtr<VirtualDevice>::Create(); + const Size aSize(100, 30); + pImg->SetOutputSizePixel(aSize); + + StyleItemController aStyleController(rStyle); + aStyleController.Paint(*pImg); + aPreviewCache[rStyle.second] = pImg; + + return pImg; + } +} + void StylesPreviewWindow_Base::UpdateStylesList() { m_aAllStyles = m_aDefaultStyles; @@ -487,12 +508,7 @@ void StylesPreviewWindow_Base::UpdateStylesList() m_xStylesView->clear(); for (const auto& rStyle : m_aAllStyles) { - ScopedVclPtr<VirtualDevice> pImg = VclPtr<VirtualDevice>::Create(); - const Size aSize(100, 30); - pImg->SetOutputSizePixel(aSize); - - StyleItemController aStyleController(rStyle); - aStyleController.Paint(*pImg); + VclPtr<VirtualDevice> pImg = GetCachedPreview(rStyle); m_xStylesView->append(rStyle.first, rStyle.second, pImg); }
