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);
     }

Reply via email to